index.tsx 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. import { defineComponent, nextTick, onMounted, reactive, ref } from 'vue';
  2. import styles from './index.module.less';
  3. import {
  4. NButton,
  5. NForm,
  6. NFormItem,
  7. NInput,
  8. NInputGroup,
  9. NInputGroupLabel,
  10. NInputNumber,
  11. NSpace,
  12. useMessage
  13. } from 'naive-ui';
  14. import {
  15. lessonPreTrainingAdd,
  16. lessonPreTrainingUpdate
  17. } from '/src/views/prepare-lessons/api';
  18. export default defineComponent({
  19. name: 'train-update',
  20. props: {
  21. /** 初始数据 */
  22. item: {
  23. type: Object,
  24. default: () => ({})
  25. }
  26. },
  27. emits: ['close', 'confirm'],
  28. setup(props, { emit }) {
  29. // 'practice' | 'evaluation'
  30. const message = useMessage();
  31. const forms = reactive({
  32. id: null as any,
  33. uploading: false,
  34. baseMaxScore: 99,
  35. type: 'PRACTICE',
  36. musicId: '',
  37. coursewareKnowledgeDetailId: '', // 章节编号
  38. minScore: null as any,
  39. maxScore: null as any,
  40. subjectId: '',
  41. coverImg: '',
  42. practiceSpeed: null as any, // 练习速度
  43. practiceTimes: null as any, // 练习时长
  44. difficulty: 'BEGINNER', // 评测难度
  45. evaluationSpeed: null as any, // 评测速度
  46. evaluationScore: null as any // 评测分数
  47. });
  48. const formsRef = ref();
  49. const onSubmit = async () => {
  50. formsRef.value?.validate(async (err: any) => {
  51. if (err) {
  52. return;
  53. }
  54. forms.uploading = true;
  55. try {
  56. const params = {
  57. trainingType: forms.type,
  58. musicId: forms.musicId,
  59. coursewareKnowledgeDetailId: forms.coursewareKnowledgeDetailId,
  60. subjectId: forms.subjectId,
  61. id: forms.id,
  62. coverImg: forms.coverImg,
  63. trainingConfigJson: ''
  64. };
  65. const configJson: any = {};
  66. if (forms.type === 'PRACTICE') {
  67. configJson.practiceChapterBegin = forms.minScore;
  68. configJson.practiceChapterEnd = forms.maxScore;
  69. configJson.practiceSpeed = forms.practiceSpeed;
  70. configJson.trainingTimes = forms.practiceTimes;
  71. } else {
  72. configJson.evaluateDifficult = forms.difficulty;
  73. configJson.evaluateSpeed = forms.evaluationSpeed;
  74. configJson.trainingTimes = forms.evaluationScore;
  75. }
  76. configJson.practiceChapterMax = forms.baseMaxScore;
  77. params.trainingConfigJson = configJson;
  78. if (forms.id) {
  79. await lessonPreTrainingUpdate(params);
  80. message.success('修改成功');
  81. } else {
  82. await lessonPreTrainingAdd(params);
  83. message.success('添加成功');
  84. }
  85. emit('close');
  86. emit('confirm');
  87. } catch {
  88. //
  89. }
  90. forms.uploading = false;
  91. });
  92. };
  93. onMounted(() => {
  94. const item = props.item;
  95. if (item.trainId) {
  96. forms.id = item.trainId;
  97. forms.minScore = item.practiceChapterBegin;
  98. forms.maxScore = item.practiceChapterEnd;
  99. forms.practiceSpeed = item.practiceSpeed;
  100. if (item.trainingType === 'PRACTICE') {
  101. forms.practiceTimes = item.trainingTimes;
  102. } else {
  103. forms.evaluationScore = item.trainingTimes;
  104. }
  105. forms.difficulty = item.evaluateDifficult || 'BEGINNER';
  106. forms.evaluationSpeed = item.evaluateSpeed;
  107. } else {
  108. forms.minScore = 1;
  109. forms.maxScore = item.practiceChapterMax ? item.practiceChapterMax : 1;
  110. }
  111. forms.baseMaxScore = item.practiceChapterMax || 99;
  112. forms.musicId = item.id;
  113. forms.coursewareKnowledgeDetailId = item.coursewareKnowledgeDetailId;
  114. forms.subjectId = item.subjectId;
  115. forms.coverImg = item.coverImg;
  116. });
  117. return () => (
  118. <div class={styles.trainUpdate}>
  119. <NForm
  120. ref={formsRef}
  121. model={forms}
  122. labelAlign="right"
  123. labelPlacement="left">
  124. <NFormItem
  125. label="训练方式"
  126. path="type"
  127. rule={[{ required: true, message: '请选择训练方式' }]}>
  128. <NSpace>
  129. <NButton
  130. secondary
  131. class={[
  132. styles.switch,
  133. forms.type === 'PRACTICE' ? styles.active : ''
  134. ]}
  135. onClick={() => (forms.type = 'PRACTICE')}>
  136. 练习
  137. </NButton>
  138. <NButton
  139. secondary
  140. class={[
  141. styles.switch,
  142. forms.type === 'EVALUATION' ? styles.active : ''
  143. ]}
  144. onClick={() => (forms.type = 'EVALUATION')}>
  145. 评测
  146. </NButton>
  147. </NSpace>
  148. </NFormItem>
  149. {forms.type === 'PRACTICE' && (
  150. <>
  151. <div class={styles.scoreGroup}>
  152. <NFormItem
  153. label="练习小节"
  154. path="minScore"
  155. rule={[{ required: true, message: '请输入最小练习小节' }]}>
  156. <NInputNumber
  157. v-model:value={forms.minScore}
  158. showButton={false}
  159. min={1}
  160. max={forms.baseMaxScore}
  161. placeholder="最小练习小节"
  162. onUpdate:value={() => {
  163. forms.maxScore = null;
  164. }}
  165. clearable
  166. />
  167. </NFormItem>
  168. <div
  169. style={{
  170. '--n-feedback-height': '24px',
  171. display: 'flex',
  172. alignItems: 'center',
  173. margin: '-2px 2% 0 2%',
  174. marginBottom: 'var(--n-feedback-height)'
  175. }}>
  176. -
  177. </div>
  178. <NFormItem
  179. path="maxScore"
  180. rule={[{ required: true, message: '请输入最大练习小节' }]}>
  181. <NInputNumber
  182. v-model:value={forms.maxScore}
  183. showButton={false}
  184. min={forms.minScore || 1}
  185. max={forms.baseMaxScore}
  186. placeholder="最大练习小节"
  187. clearable
  188. />
  189. </NFormItem>
  190. </div>
  191. <NFormItem
  192. label="练习速度"
  193. path="practiceSpeed"
  194. rule={[{ required: true, message: '请输入练习速度' }]}>
  195. <NInputNumber
  196. min={60}
  197. max={270}
  198. showButton={false}
  199. style={{ width: '100%' }}
  200. v-model:value={forms.practiceSpeed}
  201. placeholder="练习速度范围60~270"
  202. clearable
  203. />
  204. </NFormItem>
  205. <NFormItem
  206. label="练习时长"
  207. path="practiceTimes"
  208. rule={[{ required: true, message: '请输入练习时长' }]}>
  209. <NInputGroup>
  210. <NInputNumber
  211. min={0}
  212. showButton={false}
  213. style={{ width: '100%' }}
  214. v-model:value={forms.practiceTimes}
  215. placeholder="请输入练习时长"
  216. clearable
  217. />
  218. <NInputGroupLabel>分钟</NInputGroupLabel>
  219. </NInputGroup>
  220. </NFormItem>
  221. </>
  222. )}
  223. {forms.type === 'EVALUATION' && (
  224. <>
  225. <NFormItem
  226. label="评测难度"
  227. path="type"
  228. rule={[{ required: true, message: '请选择评测难度' }]}>
  229. <NSpace>
  230. <NButton
  231. secondary
  232. class={[
  233. styles.switch,
  234. forms.difficulty === 'BEGINNER' ? styles.active : ''
  235. ]}
  236. onClick={() => (forms.difficulty = 'BEGINNER')}>
  237. 入门级
  238. </NButton>
  239. <NButton
  240. secondary
  241. class={[
  242. styles.switch,
  243. forms.difficulty === 'ADVANCED' ? styles.active : ''
  244. ]}
  245. onClick={() => (forms.difficulty = 'ADVANCED')}>
  246. 进阶级
  247. </NButton>
  248. <NButton
  249. secondary
  250. class={[
  251. styles.switch,
  252. forms.difficulty === 'PERFORMER' ? styles.active : ''
  253. ]}
  254. onClick={() => (forms.difficulty = 'PERFORMER')}>
  255. 大师级
  256. </NButton>
  257. </NSpace>
  258. </NFormItem>
  259. <NFormItem
  260. label="评测速度"
  261. path="evaluationSpeed"
  262. rule={[{ required: true, message: '请输入评测速度' }]}>
  263. <NInputNumber
  264. min={60}
  265. max={270}
  266. showButton={false}
  267. style={{ width: '100%' }}
  268. v-model:value={forms.evaluationSpeed}
  269. placeholder="评测速度范围60~270"
  270. clearable
  271. />
  272. </NFormItem>
  273. <NFormItem
  274. label="合格分数"
  275. path="evaluationScore"
  276. rule={[{ required: true, message: '请输入合格分数' }]}>
  277. <NInputGroup>
  278. <NInputNumber
  279. min={0}
  280. showButton={false}
  281. style={{ width: '100%' }}
  282. v-model:value={forms.evaluationScore}
  283. placeholder="请输入合格分数"
  284. clearable
  285. />
  286. <NInputGroupLabel>分</NInputGroupLabel>
  287. </NInputGroup>
  288. </NFormItem>
  289. </>
  290. )}
  291. <NSpace class={styles.updateBtnGroup}>
  292. <NButton strong type="default" round onClick={() => emit('close')}>
  293. 取消
  294. </NButton>
  295. <NButton strong type="primary" round onClick={() => onSubmit()}>
  296. 确认
  297. </NButton>
  298. </NSpace>
  299. </NForm>
  300. </div>
  301. );
  302. }
  303. });