index.tsx 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. import ColCropper from '@/components/col-cropper'
  2. import styles from './index.module.less'
  3. import request from '@/helpers/request'
  4. import { verifyNumberIntegerAndFloat } from '@/helpers/toolsValidate'
  5. import {
  6. ElButton,
  7. ElCol,
  8. ElForm,
  9. ElFormItem,
  10. ElImage,
  11. ElInput,
  12. ElOption,
  13. ElRadio,
  14. ElRadioGroup,
  15. ElRow,
  16. ElSelect,
  17. ElTabPane,
  18. ElTabs
  19. } from 'element-plus'
  20. import { defineComponent } from 'vue'
  21. import { createState } from '../createState'
  22. import { scrollAnimation } from '@/util/scroll'
  23. export default defineComponent({
  24. name: 'course-info',
  25. data() {
  26. return {
  27. url: '',
  28. calcRatePrice: 0 as any
  29. }
  30. },
  31. computed: {
  32. choiceSubjectIds() {
  33. // 选择的科目编号
  34. let ids = createState.lessonGroup.lessonSubject
  35. ? Number(createState.lessonGroup.lessonSubject)
  36. : null
  37. return ids ? [ids] : []
  38. },
  39. subjectList() {
  40. // 学科列表
  41. return createState.subjectList || []
  42. },
  43. lessonSubjectName() {
  44. // 选择的科目
  45. let tempStr = ''
  46. this.subjectList.forEach((item: any) => {
  47. if (this.choiceSubjectIds.includes(item.id)) {
  48. tempStr = item.name
  49. }
  50. })
  51. return tempStr
  52. }
  53. // calcRatePrice() {
  54. // // 计算手续费
  55. // let rate = createState.rate || 0
  56. // let price = createState.lessonGroup.lessonPrice || 0
  57. // return (price - (rate / 100) * price).toFixed(2)
  58. // }
  59. },
  60. async mounted() {
  61. try {
  62. if (createState.subjectList.length <= 0) {
  63. const res = await request.post('/api-website/teacher/querySubject')
  64. createState.subjectList = res.data || []
  65. }
  66. const rate = createState.rate || 0
  67. const price = createState.lessonGroup.lessonPrice || 0
  68. this.calcRatePrice = (price - (rate / 100) * price).toFixed(2)
  69. // setInterval(() => {
  70. // console.log(
  71. // createState.lessonGroup.lessonCoverTemplateUrl,
  72. // 'createState.lessonGroup.lessonCoverTemplateUrl'
  73. // )
  74. // }, 1000)
  75. } catch {
  76. //
  77. }
  78. },
  79. methods: {
  80. // onChoice(id: number) {
  81. // createState.lessonGroup.lessonSubject = id
  82. // this.subjectStatus = false
  83. // },
  84. onFormatter(e: any) {
  85. e.target.value = verifyNumberIntegerAndFloat(e.target.value)
  86. // 计算手续费
  87. let rate = createState.rate || 0
  88. let price = e.target.value || 0
  89. this.calcRatePrice = (price - (rate / 100) * price).toFixed(2)
  90. },
  91. tabChange(name: number) {
  92. ;(this as any).$refs.form.clearValidate('lessonCoverTemplateUrl')
  93. ;(this as any).$refs.form.clearValidate('lessonCoverUrl')
  94. createState.tabIndex = name
  95. },
  96. selectImg(val: string) {
  97. createState.lessonGroup.lessonCoverUrl = ''
  98. createState.lessonGroup.lessonCoverTemplateUrl = val
  99. }
  100. },
  101. render() {
  102. return (
  103. <div class={styles.courseInfo}>
  104. <ElForm
  105. class="px-6 pb-10 pt-7"
  106. size="large"
  107. ref="form"
  108. labelWidth={'120px'}
  109. labelPosition="left"
  110. model={createState.lessonGroup}
  111. >
  112. <ElFormItem
  113. label="课程名称"
  114. prop="lessonName"
  115. rules={[
  116. {
  117. required: true,
  118. message: '请输入课程名称'
  119. }
  120. ]}
  121. >
  122. <ElInput
  123. v-model={createState.lessonGroup.lessonName}
  124. maxlength={50}
  125. placeholder="请输入课程名称"
  126. />
  127. </ElFormItem>
  128. <ElFormItem
  129. label="课程声部"
  130. prop="lessonSubject"
  131. rules={[
  132. {
  133. required: true,
  134. message: '请选择课程声部'
  135. }
  136. ]}
  137. >
  138. <ElSelect
  139. class="w-full"
  140. v-model={createState.lessonGroup.lessonSubject}
  141. placeholder="请选择课程声部"
  142. >
  143. {createState.subjectList.map((item: any) => (
  144. <ElOption key={item.id} value={item.id} label={item.name} />
  145. ))}
  146. </ElSelect>
  147. </ElFormItem>
  148. <ElFormItem
  149. label="课程介绍"
  150. prop="lessonDesc"
  151. rules={[
  152. {
  153. required: true,
  154. message: '请输入课程介绍'
  155. }
  156. ]}
  157. >
  158. <ElInput
  159. placeholder="请输入课程介绍"
  160. v-model={createState.lessonGroup.lessonDesc}
  161. type="textarea"
  162. // @ts-ignore
  163. maxlength={200}
  164. rows={4}
  165. showWordLimit
  166. />
  167. </ElFormItem>
  168. <ElFormItem
  169. label="课程组售价"
  170. prop="lessonPrice"
  171. rules={[
  172. {
  173. required: true,
  174. message: '请输入课程组售价'
  175. }
  176. ]}
  177. >
  178. <ElInput
  179. placeholder="请输入课程组售价"
  180. v-model={createState.lessonGroup.lessonPrice}
  181. // @ts-ignore
  182. onKeyup={this.onFormatter}
  183. maxlength={9}
  184. v-slots={{
  185. suffix: () => <span class="text-base text-[#999]">元</span>
  186. }}
  187. />
  188. </ElFormItem>
  189. <div class="text-sm text-[#999] pl-[120px] leading-relaxed pb-2">
  190. <p>扣除手续费后您的课程预计收入为: </p>
  191. <p>
  192. 课程组总收入
  193. <span class="px-1 text-[#FF4E19]">{this.calcRatePrice}</span>元/人
  194. </p>
  195. <p>您的课程收入将在课程结束后结算到您的账户中 </p>
  196. </div>
  197. <ElFormItem label="课程封面" class="!mb-0" required>
  198. <ElTabs
  199. v-model={createState.tabIndex}
  200. class={styles.tabs}
  201. onTab-change={(name: any) => {
  202. this.tabChange(name)
  203. }}
  204. >
  205. <ElTabPane label="图片模板" name={1}></ElTabPane>
  206. <ElTabPane label="自定义模板" name={2}></ElTabPane>
  207. </ElTabs>
  208. </ElFormItem>
  209. {createState.tabIndex === 1 && (
  210. <ElFormItem
  211. prop="lessonCoverTemplateUrl"
  212. rules={[
  213. {
  214. required: true,
  215. message: '请上传课程封面'
  216. }
  217. ]}
  218. >
  219. <ElRadioGroup
  220. v-model={createState.lessonGroup.lessonCoverTemplateUrl}
  221. >
  222. <ElRow>
  223. {createState.templateList.map((item: any) => (
  224. <ElCol span={7} class="mb-3 cursor-pointer">
  225. <div
  226. class="w-[152px] relative rounded-xl overflow-hidden border"
  227. onClick={() => {
  228. this.selectImg(item)
  229. }}
  230. >
  231. <ElImage src={item} class="align-middle" />
  232. <ElRadio
  233. label={item}
  234. class="!absolute bottom-2 right-0 !h-auto z-10"
  235. >
  236. {''}
  237. </ElRadio>
  238. </div>
  239. </ElCol>
  240. ))}
  241. </ElRow>
  242. </ElRadioGroup>
  243. </ElFormItem>
  244. )}
  245. {createState.tabIndex === 2 && (
  246. <ElFormItem
  247. prop="lessonCoverUrl"
  248. rules={[
  249. {
  250. required: true,
  251. message: '请上传课程封面',
  252. trigger: 'change'
  253. }
  254. ]}
  255. >
  256. {/* <ColUpload
  257. v-model:modelValue={createState.lessonGroup.lessonCoverUrl}
  258. onChange={(value: any) => {
  259. createState.lessonGroup.lessonCoverTemplateUrl = ''
  260. }}
  261. /> */}
  262. <ColCropper
  263. modelValue={createState.lessonGroup.lessonCoverUrl}
  264. class={styles.imgCover}
  265. bucket="video-course"
  266. cropUploadSuccess={(data: any) => {
  267. createState.lessonGroup.lessonCoverUrl = data
  268. createState.lessonGroup.lessonCoverTemplateUrl = ''
  269. }}
  270. options={{
  271. // fixedNumber: [3, 2],
  272. // autoCropWidth: 300,
  273. // autoCropHeight: 200
  274. title: '课程封面',
  275. fixedNumber: [3.34, 2],
  276. autoCropWidth: 375,
  277. autoCropHeight: 212
  278. }}
  279. />
  280. </ElFormItem>
  281. )}
  282. </ElForm>
  283. <div class=" text-center pt-6 pb-7">
  284. <ElButton
  285. type="primary"
  286. round
  287. class="!w-44 !h-[48px] !text-base"
  288. onClick={() => {
  289. ;(this as any).$refs.form.validate(async (valid: boolean) => {
  290. if (valid) {
  291. createState.active = 1
  292. const currentY =
  293. document.documentElement.scrollTop ||
  294. document.body.scrollTop
  295. scrollAnimation(currentY, 0)
  296. } else {
  297. this.$nextTick(() => {
  298. let isError = document.getElementsByClassName('is-error')
  299. isError[0].scrollIntoView({
  300. block: 'center',
  301. behavior: 'smooth'
  302. })
  303. })
  304. return false
  305. }
  306. })
  307. }}
  308. >
  309. 下一步
  310. </ElButton>
  311. </div>
  312. </div>
  313. )
  314. }
  315. })