index.tsx 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  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.expireDate) {
  129. message.error('请选择截止日期');
  130. return;
  131. }
  132. if (trainForms.trainList.length <= 0) {
  133. message.error('训练内容不能为空');
  134. return;
  135. }
  136. trainForms.btnLoading = true;
  137. try {
  138. const trainList = trainForms.trainList || [];
  139. const details: any[] = [];
  140. trainList.forEach((item: any) => {
  141. details.push({
  142. trainingType: item.trainingType,
  143. musicId: item.musicId,
  144. trainingConfigJsonObject: item.trainingConfigJson
  145. });
  146. });
  147. const params = {
  148. lessonTrainingDetails: details,
  149. expireDate: trainForms.expireDate + ' 23:59:59',
  150. classGroupId: props.classGroupId
  151. };
  152. await lessonTrainingAdd(params);
  153. message.success('布置成功');
  154. emit('close');
  155. emit('confirm');
  156. } catch {
  157. //
  158. }
  159. trainForms.btnLoading = false;
  160. };
  161. onMounted(() => {
  162. // 判断是否有数据
  163. if (props.detailId && props.subjectId) {
  164. getList();
  165. }
  166. });
  167. return () => (
  168. <div class={styles.trainSettings}>
  169. <div class={styles.searchGroup}>
  170. <NButton
  171. onClick={() => {
  172. trainForms.selectMusicStatus = true;
  173. trainForms.type = 'add';
  174. }}>
  175. 添加作业
  176. </NButton>
  177. <div class={styles.datetime}>
  178. <label>截止时间:</label>
  179. <NDatePicker
  180. style={{ width: '200px' }}
  181. placeholder="请选择截止日期"
  182. v-model:formatted-value={trainForms.expireDate}
  183. type="date"
  184. valueFormat="yyyy-MM-dd"
  185. isDateDisabled={(ts: number) => {
  186. return ts < trainForms.currentTime;
  187. }}
  188. />
  189. </div>
  190. </div>
  191. <NScrollbar class={styles.trainList}>
  192. <NSpin show={trainForms.loadingStatus}>
  193. <div
  194. class={[
  195. styles.listSection,
  196. !trainForms.loadingStatus && trainForms.trainList.length <= 0
  197. ? styles.emptySection
  198. : ''
  199. ]}>
  200. {trainForms.trainList.length > 0 && (
  201. <div class={styles.list}>
  202. {trainForms.trainList.map((item: any) => (
  203. <TrainType
  204. item={item}
  205. type="homework"
  206. onEdit={(child: any) => {
  207. const { trainingConfigJson, id, musicId, ...res } =
  208. child;
  209. trainForms.editItem = {
  210. ...res,
  211. id: musicId,
  212. trainId: id,
  213. ...trainingConfigJson
  214. };
  215. console.log(trainForms.editItem);
  216. trainForms.type = 'update';
  217. trainForms.editStatus = true;
  218. }}
  219. onDelete={() => {
  220. // 删除
  221. const index = trainForms.trainList.findIndex(
  222. (c: any) => c.id === item.id
  223. );
  224. trainForms.trainList.splice(index, 1);
  225. }}
  226. />
  227. ))}
  228. </div>
  229. )}
  230. {!trainForms.loadingStatus &&
  231. trainForms.trainList.length <= 0 && (
  232. <TheEmpty description="暂无作业" />
  233. )}
  234. </div>
  235. </NSpin>
  236. </NScrollbar>
  237. <NSpace class={styles.trainBtnGroup}>
  238. <NButton strong type="default" round onClick={() => emit('close')}>
  239. 取消布置
  240. </NButton>
  241. <NButton
  242. strong
  243. type="primary"
  244. round
  245. disabled={trainForms.trainList.length <= 0 ? true : false}
  246. onClick={onSubmit}>
  247. 立即布置
  248. </NButton>
  249. </NSpace>
  250. <NModal
  251. v-model:show={trainForms.editStatus}
  252. class={['modalTitle background', styles.trainEditModal]}
  253. preset="card"
  254. title="作业设置">
  255. <TrainUpdate
  256. item={trainForms.editItem}
  257. type="homework"
  258. onClose={() => (trainForms.editStatus = false)}
  259. onConfirm={(item: any) => {
  260. console.log(item, 'update', trainForms);
  261. const tList = typeFormat(
  262. item.trainingType,
  263. item.trainingConfigJson
  264. );
  265. // 更新
  266. if (trainForms.type === 'update') {
  267. trainForms.trainList.forEach((train: any) => {
  268. if (train.id === item.id) {
  269. train.trainingType = item.trainingType;
  270. train.trainingConfigJson = item.trainingConfigJson;
  271. train.typeList = tList;
  272. }
  273. });
  274. } else {
  275. //
  276. trainForms.trainList.push({
  277. ...item,
  278. id: +new Date(),
  279. musicName: trainForms.editItem.title,
  280. typeList: tList
  281. });
  282. }
  283. trainForms.editItem = {};
  284. }}
  285. />
  286. </NModal>
  287. <NModal
  288. v-model:show={trainForms.selectMusicStatus}
  289. class={['modalTitle', styles.selectMusicModal]}
  290. preset="card"
  291. title={'选择曲目'}>
  292. <SelectMusic
  293. onAdd={(item: any) => {
  294. trainForms.selectMusicStatus = false;
  295. onAdd(item);
  296. }}
  297. />
  298. </NModal>
  299. </div>
  300. );
  301. }
  302. });