index.tsx 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. import { defineComponent, onMounted, reactive } from 'vue';
  2. import styles from './index.module.less';
  3. import {
  4. NButton,
  5. NDatePicker,
  6. NModal,
  7. NScrollbar,
  8. NSpace,
  9. NSpin,
  10. useMessage
  11. } from 'naive-ui';
  12. import TrainType from '@/views/attend-class/model/train-type';
  13. import TrainUpdate from '../train-update';
  14. import SelectMusic from '@/views/prepare-lessons/model/select-music';
  15. import {
  16. lessonPreTrainingPage,
  17. lessonTrainingAdd
  18. } from '/src/views/prepare-lessons/api';
  19. import { evaluateDifficult } from '/src/utils/contants';
  20. import dayjs from 'dayjs';
  21. import TheEmpty from '/src/components/TheEmpty';
  22. import requestOrigin from 'umi-request';
  23. export default defineComponent({
  24. name: 'train-settings',
  25. props: {
  26. /** 章节编号 */
  27. detailId: {
  28. type: String,
  29. default: ''
  30. },
  31. /** 声部编号 */
  32. subjectId: {
  33. type: String,
  34. default: ''
  35. },
  36. /** 班级编号 */
  37. classGroupId: {
  38. type: String,
  39. default: ''
  40. }
  41. },
  42. emits: ['close', 'confirm'],
  43. setup(props, { emit }) {
  44. const message = useMessage();
  45. const trainForms = reactive({
  46. type: 'add' as 'add' | 'update',
  47. btnLoading: false,
  48. loadingStatus: false,
  49. editStatus: false,
  50. editItem: {} as any,
  51. selectMusicStatus: false,
  52. trainList: [] as any,
  53. currentTime: dayjs(dayjs().format('YYYY-MM-DD')).valueOf(),
  54. expireDate: dayjs().add(7, 'day').format('YYYY-MM-DD') as any // 默认7天
  55. });
  56. const getList = async () => {
  57. trainForms.loadingStatus = true;
  58. try {
  59. // 判断是否有选择对应的课件
  60. const { data } = await lessonPreTrainingPage({
  61. coursewareKnowledgeDetailId: props.detailId,
  62. subjectId: props.subjectId,
  63. page: 1,
  64. rows: 99
  65. });
  66. const tempRows = data.rows || [];
  67. const temp: any = [];
  68. tempRows.forEach((row: any) => {
  69. const tList = typeFormat(row.trainingType, row.trainingConfigJson);
  70. temp.push({
  71. typeList: tList || [],
  72. ...row
  73. });
  74. });
  75. trainForms.trainList = temp || [];
  76. } catch {
  77. //
  78. }
  79. trainForms.loadingStatus = false;
  80. };
  81. const typeFormat = (trainingType: string, configJson: any) => {
  82. let tList: string[] = [];
  83. if (trainingType === 'EVALUATION') {
  84. tList = [
  85. `${evaluateDifficult[configJson.evaluateDifficult]}`,
  86. '全部小节',
  87. `速度${configJson.evaluateSpeed}`,
  88. `${configJson.trainingTimes}分钟`
  89. ];
  90. } else {
  91. tList = [
  92. `${configJson.practiceChapterBegin}-${configJson.practiceChapterEnd}小节`,
  93. `速度${configJson.practiceSpeed}`,
  94. `${configJson.trainingTimes}分钟`
  95. ];
  96. }
  97. return tList;
  98. };
  99. const onAdd = async (item: any) => {
  100. let xmlStatus = 'init';
  101. // 第一个声部小节
  102. let firstMeasures: any = null;
  103. try {
  104. // 获取文件
  105. const res = await requestOrigin.get(item.xmlFileUrl, {
  106. mode: 'cors'
  107. });
  108. const xmlParse = new DOMParser().parseFromString(res, 'text/xml');
  109. const parts = xmlParse.getElementsByTagName('part');
  110. firstMeasures = parts[0]?.getElementsByTagName('measure');
  111. xmlStatus = 'success';
  112. } catch (error) {
  113. xmlStatus = 'error';
  114. }
  115. // 判断读取小节数
  116. if (xmlStatus == 'success') {
  117. item.practiceChapterMax = firstMeasures.length;
  118. } else {
  119. item.practiceChapterMax = 0;
  120. }
  121. item.coursewareKnowledgeDetailId = props.detailId;
  122. item.subjectId = props.subjectId;
  123. trainForms.editItem = item;
  124. trainForms.editStatus = true;
  125. };
  126. const onSubmit = async () => {
  127. // 训练内容不能为空
  128. if (trainForms.trainList.length <= 0) {
  129. message.error('训练内容不能为空');
  130. return;
  131. }
  132. trainForms.btnLoading = true;
  133. try {
  134. const trainList = trainForms.trainList || [];
  135. const details: any[] = [];
  136. trainList.forEach((item: any) => {
  137. details.push({
  138. trainingType: item.trainingType,
  139. musicId: item.musicId,
  140. trainingConfigJsonObject: item.trainingConfigJson
  141. });
  142. });
  143. const params = {
  144. lessonTrainingDetails: details,
  145. expireDate: trainForms.expireDate + ' 23:59:59',
  146. classGroupId: props.classGroupId
  147. };
  148. await lessonTrainingAdd(params);
  149. message.success('布置成功');
  150. emit('close');
  151. emit('confirm');
  152. } catch {
  153. //
  154. }
  155. trainForms.btnLoading = false;
  156. };
  157. onMounted(() => {
  158. // 判断是否有数据
  159. if (props.detailId && props.subjectId) {
  160. getList();
  161. }
  162. });
  163. return () => (
  164. <div class={styles.trainSettings}>
  165. <div class={styles.searchGroup}>
  166. <NButton
  167. onClick={() => {
  168. trainForms.selectMusicStatus = true;
  169. trainForms.type = 'add';
  170. }}>
  171. 添加训练
  172. </NButton>
  173. <div class={styles.datetime}>
  174. <label>截止时间:</label>
  175. <NDatePicker
  176. style={{ width: '200px' }}
  177. placeholder="请选择截止日期"
  178. v-model:formatted-value={trainForms.expireDate}
  179. type="date"
  180. clearable
  181. valueFormat="yyyy-MM-dd"
  182. isDateDisabled={(ts: number) => {
  183. return ts < trainForms.currentTime;
  184. }}
  185. />
  186. </div>
  187. </div>
  188. <NScrollbar class={styles.trainList}>
  189. <NSpin show={trainForms.loadingStatus}>
  190. <div
  191. class={[
  192. styles.listSection,
  193. !trainForms.loadingStatus && trainForms.trainList.length <= 0
  194. ? styles.emptySection
  195. : ''
  196. ]}>
  197. {trainForms.trainList.length > 0 && (
  198. <div class={styles.list}>
  199. {trainForms.trainList.map((item: any) => (
  200. <TrainType
  201. item={item}
  202. type="homework"
  203. onEdit={(child: any) => {
  204. const { trainingConfigJson, id, musicId, ...res } =
  205. child;
  206. trainForms.editItem = {
  207. ...res,
  208. id: musicId,
  209. trainId: id,
  210. ...trainingConfigJson
  211. };
  212. console.log(trainForms.editItem);
  213. trainForms.type = 'update';
  214. trainForms.editStatus = true;
  215. }}
  216. onDelete={() => {
  217. // 删除
  218. const index = trainForms.trainList.findIndex(
  219. (c: any) => c.id === item.id
  220. );
  221. trainForms.trainList.splice(index, 1);
  222. }}
  223. />
  224. ))}
  225. </div>
  226. )}
  227. {!trainForms.loadingStatus &&
  228. trainForms.trainList.length <= 0 && (
  229. <TheEmpty description="暂无训练" />
  230. )}
  231. </div>
  232. </NSpin>
  233. </NScrollbar>
  234. <NSpace class={styles.trainBtnGroup}>
  235. <NButton strong type="default" round onClick={() => emit('close')}>
  236. 取消布置
  237. </NButton>
  238. <NButton
  239. strong
  240. type="primary"
  241. round
  242. disabled={trainForms.trainList.length <= 0 ? true : false}
  243. onClick={onSubmit}>
  244. 立即布置
  245. </NButton>
  246. </NSpace>
  247. <NModal
  248. v-model:show={trainForms.editStatus}
  249. class={['modalTitle background', styles.trainEditModal]}
  250. preset="card"
  251. title="训练设置">
  252. <TrainUpdate
  253. item={trainForms.editItem}
  254. type="homework"
  255. onClose={() => (trainForms.editStatus = false)}
  256. onConfirm={(item: any) => {
  257. const tList = typeFormat(
  258. item.trainingType,
  259. item.trainingConfigJson
  260. );
  261. // 更新
  262. if (trainForms.type === 'update') {
  263. trainForms.trainList.forEach((train: any) => {
  264. if (train.id === item.id) {
  265. train.trainingType = item.trainingType;
  266. train.typeList = tList;
  267. }
  268. });
  269. } else {
  270. //
  271. trainForms.trainList.push({
  272. ...item,
  273. id: +new Date(),
  274. musicName: trainForms.editItem.title,
  275. typeList: tList
  276. });
  277. }
  278. trainForms.editItem = {};
  279. }}
  280. />
  281. </NModal>
  282. <NModal
  283. v-model:show={trainForms.selectMusicStatus}
  284. class={['modalTitle', styles.selectMusicModal]}
  285. preset="card"
  286. title={'选择曲目'}>
  287. <SelectMusic
  288. onAdd={(item: any) => {
  289. trainForms.selectMusicStatus = false;
  290. onAdd(item);
  291. }}
  292. />
  293. </NModal>
  294. </div>
  295. );
  296. }
  297. });