course-start.tsx 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. import ColField from '@/components/col-field'
  2. import ColFieldGroup from '@/components/col-field-group'
  3. import {
  4. Button,
  5. Col,
  6. Field,
  7. Form,
  8. Radio,
  9. RadioGroup,
  10. Row,
  11. Sticky,
  12. Tab,
  13. Tabs,
  14. Image,
  15. Icon,
  16. Popup,
  17. DatetimePicker
  18. } from 'vant'
  19. import { defineComponent } from 'vue'
  20. import { createState } from './createState'
  21. import styles from './course-start.module.less'
  22. import ColUpload from '@/components/col-upload'
  23. import { verifiyNumberInteger } from '@/helpers/toolsValidate'
  24. import { formatterDate } from '@/helpers/utils'
  25. import activeButtonIcon from '@common/images/icon_checkbox.png'
  26. import inactiveButtonIcon from '@common/images/icon_checkbox_default.png'
  27. import dayjs from 'dayjs'
  28. import TheSticky from '@/components/the-sticky'
  29. export default defineComponent({
  30. name: 'course-start',
  31. data() {
  32. return {
  33. typeDateTime: 'start',
  34. dateStatus: false,
  35. currentDate: new Date(),
  36. minDate: dayjs().toDate(),
  37. maxDate: new Date()
  38. }
  39. },
  40. computed: {
  41. disabled() {
  42. return createState.live.courseGroupId ? true : false
  43. }
  44. },
  45. mounted() {
  46. if (createState.selectCourseList[0]?.startTime) {
  47. this.maxDate = dayjs(createState.selectCourseList[0].startTime)
  48. .subtract(1, 'day')
  49. .toDate()
  50. }
  51. createState.live.salesStartDate =
  52. createState.live.salesStartDate ||
  53. dayjs(this.minDate).format('YYYY-MM-DD')
  54. createState.live.salesEndDate =
  55. createState.live.salesEndDate || dayjs(this.maxDate).format('YYYY-MM-DD')
  56. },
  57. methods: {
  58. tabChange(name: number) {
  59. createState.tabIndex = name
  60. },
  61. selectImg(val: string) {
  62. createState.live.backgroundPic = ''
  63. createState.live.backgroundPicTemplate = val
  64. },
  65. onFormatterInt(val: any) {
  66. if (val) {
  67. if( Number(val) >= (Number(createState.live.maxStudentNum) || 5)) {
  68. return verifiyNumberInteger(createState.live.maxStudentNum || "5")
  69. }
  70. if(val >= 1) {
  71. return verifiyNumberInteger(val)
  72. }
  73. return ""
  74. } else {
  75. return ''
  76. }
  77. },
  78. onConfirm(val: any) {
  79. if (this.typeDateTime === 'start') {
  80. createState.live.salesStartDate = dayjs(val).format('YYYY-MM-DD')
  81. if (
  82. createState.live.salesEndDate &&
  83. dayjs(createState.live.salesStartDate).isAfter(
  84. dayjs(createState.live.salesEndDate)
  85. )
  86. ) {
  87. createState.live.salesEndDate = ''
  88. }
  89. } else if (this.typeDateTime === 'end') {
  90. createState.live.salesEndDate = dayjs(val).format('YYYY-MM-DD')
  91. }
  92. this.dateStatus = false
  93. }
  94. },
  95. render() {
  96. return (
  97. <Form
  98. class={styles.courseStart}
  99. onSubmit={() => (createState.active = 5)}
  100. scrollToError
  101. >
  102. <ColFieldGroup>
  103. <ColField title="开售日期" required>
  104. <Field
  105. v-model={createState.live.salesStartDate}
  106. name="salesStartDate"
  107. readonly
  108. isLink
  109. placeholder="请选择开售日期"
  110. disabled={this.disabled}
  111. onClick={() => {
  112. if (createState.live.courseGroupId) {
  113. return
  114. }
  115. this.minDate = dayjs().toDate()
  116. this.currentDate = dayjs(
  117. createState.live.salesStartDate
  118. ).toDate()
  119. this.typeDateTime = 'start'
  120. this.dateStatus = true
  121. }}
  122. rules={[{ required: true, message: '请选择开售日期' }]}
  123. />
  124. </ColField>
  125. <ColField title="停售日期" required>
  126. <Field
  127. v-model={createState.live.salesEndDate}
  128. name="salesEndDate"
  129. readonly
  130. isLink
  131. disabled={this.disabled}
  132. onClick={() => {
  133. if (createState.live.courseGroupId) {
  134. return
  135. }
  136. this.minDate = dayjs(createState.live.salesStartDate).toDate()
  137. this.currentDate = dayjs(createState.live.salesEndDate).toDate()
  138. this.typeDateTime = 'end'
  139. this.dateStatus = true
  140. }}
  141. rules={[{ required: true, message: '请选择停售日期' }]}
  142. placeholder="请选择停售日期"
  143. />
  144. </ColField>
  145. </ColFieldGroup>
  146. <ColFieldGroup>
  147. <ColField
  148. title="最低开课人数"
  149. required
  150. style={{
  151. marginBottom: '10px'
  152. }}
  153. >
  154. <Field
  155. v-model={createState.live.mixStudentNum}
  156. name="mixStudentNum"
  157. placeholder="请输入最低开课人数"
  158. type="number"
  159. maxlength={8}
  160. disabled={this.disabled}
  161. formatter={this.onFormatterInt}
  162. rules={[{ required: true, message: `1~${createState.live.maxStudentNum}` }]}
  163. v-slots={{
  164. button: () => <span>人</span>
  165. }}
  166. />
  167. </ColField>
  168. <div class={styles.stepTips}>
  169. 课程停售时,付费学员达到该人数可开课,若未达到该人数,则成课失败,已付费学员将自动退款。
  170. </div>
  171. </ColFieldGroup>
  172. <ColFieldGroup>
  173. <ColField
  174. required
  175. border={false}
  176. v-slots={{
  177. title: () => (
  178. <Tabs
  179. v-model:active={createState.tabIndex}
  180. class={styles.infoField}
  181. onChange={this.tabChange}
  182. shrink
  183. color="var(--van-primary)"
  184. lineWidth={20}
  185. >
  186. {/* <Tab title="图片模板" name={1}></Tab> */}
  187. <Tab title="自定义模板" name={2}></Tab>
  188. </Tabs>
  189. )
  190. }}
  191. >
  192. <p class={styles.photoTip}>模板图片将作为该课程封面为学员展示</p>
  193. {/* {createState.tabIndex === 1 ? ( */}
  194. <Field
  195. name="backgroundPicTemplate"
  196. border={false}
  197. v-show={createState.tabIndex === 1}
  198. rules={[
  199. {
  200. required:
  201. createState.tabIndex === 1 &&
  202. !createState.live.backgroundPic,
  203. message: '请选择图片模板'
  204. }
  205. ]}
  206. v-slots={{
  207. input: () => (
  208. <RadioGroup v-model={createState.live.backgroundPicTemplate}>
  209. <Row justify="space-between" style={{ width: '100%' }}>
  210. {createState.templateList.map((item: any) => (
  211. <Col
  212. span={12}
  213. class={styles.imgContainer}
  214. onClick={() => this.selectImg(item)}
  215. >
  216. <Image class={styles.imgContainer} src={item} />
  217. <Radio
  218. name={item}
  219. v-slots={{
  220. icon: (props: any) => (
  221. <Icon
  222. class={styles.boxStyle}
  223. name={
  224. props.checked
  225. ? activeButtonIcon
  226. : inactiveButtonIcon
  227. }
  228. size="18"
  229. />
  230. )
  231. }}
  232. />
  233. </Col>
  234. ))}
  235. </Row>
  236. </RadioGroup>
  237. )
  238. }}
  239. />
  240. {/* ) : null} */}
  241. {/* {createState.tabIndex == 2 ? ( */}
  242. <Field
  243. name="backgroundPic"
  244. border={false}
  245. v-show={createState.tabIndex == 2}
  246. rules={[
  247. {
  248. required: createState.tabIndex == 2,
  249. message: '请上传自定义模板'
  250. }
  251. ]}
  252. v-slots={{
  253. input: () => (
  254. <Row justify="space-between" style={{ width: '100%' }}>
  255. <Col span={12} class={styles.imgContainer}>
  256. <ColUpload
  257. cropper
  258. bucket="live-rewind"
  259. options={{
  260. fixedNumber: [1.77, 1],
  261. autoCropWidth: 750,
  262. autoCropHeight: 424
  263. }}
  264. onUploadChange={(val: any) => {
  265. if (val) {
  266. createState.live.backgroundPicTemplate = ''
  267. }
  268. }}
  269. v-model={createState.live.backgroundPic}
  270. class={styles.imgContainer}
  271. />
  272. </Col>
  273. <Col span={24}>
  274. <p
  275. class={styles.photoTip}
  276. style={{ color: '#ff4e19', padding: '0' }}
  277. >
  278. 图片尺寸为750*424能达到最佳显示效果
  279. </p>
  280. </Col>
  281. </Row>
  282. )
  283. }}
  284. />
  285. {/* // ) : null} */}
  286. </ColField>
  287. </ColFieldGroup>
  288. <TheSticky position="bottom">
  289. <div class={['btnGroup', 'btnMore']}>
  290. <Button
  291. block
  292. round
  293. type="primary"
  294. plain
  295. onClick={() => {
  296. createState.active = 3
  297. if (!createState.live.courseGroupId) {
  298. createState.live.salesStartDate = ''
  299. createState.live.salesEndDate = ''
  300. createState.live.backgroundPic = ''
  301. createState.live.backgroundPicTemplate = ''
  302. createState.live.mixStudentNum = null
  303. }
  304. }}
  305. >
  306. 上一步
  307. </Button>
  308. <Button block round type="primary" native-type="submit">
  309. 下一步
  310. </Button>
  311. </div>
  312. </TheSticky>
  313. <Popup show={this.dateStatus} position="bottom" round>
  314. <DatetimePicker
  315. type="date"
  316. v-model={this.currentDate}
  317. minDate={this.minDate}
  318. maxDate={this.maxDate}
  319. formatter={formatterDate}
  320. onCancel={() => {
  321. this.dateStatus = false
  322. }}
  323. onConfirm={this.onConfirm}
  324. />
  325. </Popup>
  326. </Form>
  327. )
  328. }
  329. })