assign-homework.tsx 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519
  1. import {
  2. PropType,
  3. defineComponent,
  4. onMounted,
  5. reactive,
  6. ref,
  7. toRef
  8. } from 'vue';
  9. import styles from './index.module.less';
  10. import {
  11. NButton,
  12. NDatePicker,
  13. NForm,
  14. NFormItem,
  15. NInput,
  16. NModal,
  17. NScrollbar,
  18. NSelect,
  19. NSpace,
  20. useMessage
  21. } from 'naive-ui';
  22. import { lessonTrainingAdd } from '../../../api';
  23. import dayjs from 'dayjs';
  24. import { classGroupList } from '/src/views/home/api';
  25. import { gradeToCN } from '/src/utils/contants';
  26. import { usePrepareStore } from '/src/store/modules/prepareLessons';
  27. import AssignStudent from './assign-student';
  28. import useDrag from '@/hooks/useDrag';
  29. import Dragbom from '@/hooks/useDrag/dragbom';
  30. import { useUserStore } from '@/store/modules/users';
  31. import { api_getCurrentGradeYear } from '/src/views/studentList/api';
  32. import request from '/src/utils/request';
  33. export default defineComponent({
  34. name: 'assign-homework',
  35. props: {
  36. classGroupId: {
  37. type: String,
  38. default: ''
  39. },
  40. courseScheduleId: {
  41. type: String,
  42. default: ''
  43. },
  44. /** 课件编号 */
  45. chapterLessonCoursewareId: {
  46. type: String,
  47. default: ''
  48. },
  49. item: {
  50. type: Object,
  51. default: () => ({})
  52. },
  53. /** 初始数据 */
  54. trainList: {
  55. type: Array,
  56. default: () => []
  57. },
  58. homeworkType: {
  59. type: String as PropType<'CLASSWORK' | 'HOMEWORK'>,
  60. default: 'CLASSWORK'
  61. },
  62. from: {
  63. // 来自哪里
  64. type: String,
  65. default: ''
  66. }
  67. },
  68. emits: ['close', 'confirm'],
  69. setup(props, { emit }) {
  70. const message = useMessage();
  71. const prepareStore = usePrepareStore();
  72. const forms = reactive({
  73. gradeYear: '' as any,
  74. currentTime: dayjs(dayjs().format('YYYY-MM-DD')).valueOf(),
  75. homeworkObj: 'CLASS' as 'PERSON' | 'CLASS',
  76. homeworkType: props.homeworkType,
  77. workVisiable: false,
  78. id: null as any,
  79. uploading: false,
  80. title: props.item.title,
  81. courseScheduleId: props.courseScheduleId || null,
  82. chapterLessonCoursewareId: props.chapterLessonCoursewareId || null,
  83. gradeList: [] as any,
  84. classList: [] as any,
  85. currentGradeNum: null,
  86. expireDate: dayjs().add(7, 'day').format('YYYY-MM-DD HH:mm') as any, // 默认7天
  87. classGroupId: null as any,
  88. studentList: [] as any,
  89. selectIds: [] as any
  90. });
  91. const formsRef = ref();
  92. const maxDeadlineTime = ref(0);
  93. const pickerEndTime = ref<any>(null);
  94. // 获取年级班级
  95. const getClassGroupList = async () => {
  96. try {
  97. const defaultSelectClassGroupId =
  98. props.classGroupId || prepareStore.getClassGroupId;
  99. const { data } = await classGroupList({
  100. upgradeFlag: true,
  101. gradeYear: forms.gradeYear
  102. });
  103. const cList = data || [];
  104. const gradeList: any = [];
  105. cList.forEach((item: any) => {
  106. const classList: any = [];
  107. item.classGroupList.forEach((i: any) => {
  108. classList.push({
  109. label: i.currentClass + '班',
  110. value: i.id,
  111. lastStudy: i.lastStudy,
  112. preStudentNum: i.preStudentNum
  113. });
  114. if (i.id === defaultSelectClassGroupId) {
  115. forms.currentGradeNum = i.currentGradeNum;
  116. forms.classGroupId = [i.id];
  117. }
  118. });
  119. gradeList.push({
  120. label: gradeToCN[item.currentGradeNum],
  121. value: item.currentGradeNum,
  122. childrens: classList
  123. });
  124. });
  125. forms.gradeList = gradeList;
  126. if (forms.currentGradeNum) {
  127. getClassList();
  128. }
  129. } catch {
  130. //
  131. }
  132. };
  133. const getClassList = async () => {
  134. try {
  135. forms.gradeList.forEach((item: any) => {
  136. if (item.value === forms.currentGradeNum) {
  137. forms.classList = item.childrens;
  138. }
  139. });
  140. } catch {
  141. //
  142. }
  143. };
  144. const onSubmit = async () => {
  145. formsRef.value?.validate(async (err: any) => {
  146. if (err) {
  147. return;
  148. }
  149. forms.uploading = true;
  150. try {
  151. const trainList: any = props.item.lessonPreTrainingDetails || [];
  152. const details: any[] = [];
  153. trainList.forEach((item: any) => {
  154. details.push({
  155. trainingType: item.trainingType,
  156. musicId: item.musicId,
  157. trainingConfigJsonObject: item.trainingConfigJson
  158. });
  159. });
  160. const params = {
  161. name: forms.title,
  162. homeworkObj: forms.homeworkObj,
  163. homeworkType: forms.homeworkType,
  164. lessonTrainingDetails: details,
  165. expireDate: dayjs(forms.expireDate).format('YYYY-MM-DD HH:mm:ss'),
  166. classGroupId: forms.classGroupId
  167. ? forms.classGroupId.join(',')
  168. : null,
  169. studentIds: null as any,
  170. courseScheduleId: forms.courseScheduleId,
  171. chapterLessonCoursewareId: forms.chapterLessonCoursewareId // 课件编号
  172. };
  173. if (forms.homeworkObj === 'PERSON') {
  174. params.classGroupId = '';
  175. const ids: any[] = [];
  176. forms.studentList.forEach((item: any) => {
  177. ids.push(item.id);
  178. });
  179. params.studentIds = ids.join(',');
  180. }
  181. await lessonTrainingAdd(params);
  182. message.success('布置成功');
  183. emit('close');
  184. emit('confirm');
  185. } catch {
  186. //
  187. }
  188. forms.uploading = false;
  189. });
  190. };
  191. const getCurrentGradeYear = async () => {
  192. try {
  193. const { data } = await api_getCurrentGradeYear({});
  194. console.log(data);
  195. forms.gradeYear = data;
  196. } catch {
  197. //
  198. }
  199. };
  200. const getDefaultParamConfig = async () => {
  201. try {
  202. const { data } = await request.get(
  203. '/edu-app/open/paramConfig/queryByParamName',
  204. {
  205. params: {
  206. paramName: 'homework_max_deadline_time'
  207. }
  208. }
  209. );
  210. maxDeadlineTime.value = data.paramValue || 0;
  211. // 处理截止时间显示
  212. /**
  213. 1、当时间没有设置时,全部时间;
  214. 2、设置了时间,小于7天;
  215. 3、设置了时间,大于7天;
  216. */
  217. if (maxDeadlineTime.value > 0) {
  218. pickerEndTime.value = dayjs(
  219. dayjs()
  220. .add(Number(maxDeadlineTime.value) + 1, 'day')
  221. .format('YYYY-MM-DD')
  222. ).valueOf();
  223. if (Number(maxDeadlineTime.value) < 7) {
  224. forms.expireDate = dayjs()
  225. .add(Number(maxDeadlineTime.value), 'day')
  226. .format('YYYY-MM-DD HH:mm');
  227. }
  228. console.log(
  229. dayjs()
  230. .add(Number(maxDeadlineTime.value), 'day')
  231. .format('YYYY-MM-DD'),
  232. 'pickerEndTime.value'
  233. );
  234. // state.pickerEndTime =
  235. }
  236. } catch {
  237. //
  238. }
  239. };
  240. const dateDisabled = (ts: number): boolean => {
  241. /**
  242. 1、当时间没有设置时,全部时间;
  243. 2、设置了时间,小于7天;
  244. 3、设置了时间,大于7天;
  245. */
  246. let status = false;
  247. if (pickerEndTime.value) {
  248. status = ts < forms.currentTime || ts >= pickerEndTime.value;
  249. } else {
  250. status = ts < forms.currentTime;
  251. }
  252. console.log(
  253. status,
  254. '1212',
  255. ts > pickerEndTime.value,
  256. forms.currentTime,
  257. ts,
  258. pickerEndTime.value
  259. );
  260. // pickerEndTime.value && pickerEndTime.value > ts;
  261. return status;
  262. };
  263. onMounted(async () => {
  264. await getDefaultParamConfig();
  265. await getCurrentGradeYear();
  266. await getClassGroupList();
  267. });
  268. // 选择学生
  269. let assignHomeworkStuBoxDragData: any;
  270. let assignHomeworkStuBoxClass: string;
  271. if (props.from === 'class') {
  272. const users = useUserStore();
  273. assignHomeworkStuBoxClass = 'assignHomeworkStuBoxClass_drag';
  274. assignHomeworkStuBoxDragData = useDrag(
  275. [
  276. `${assignHomeworkStuBoxClass}>.n-card-header`,
  277. `${assignHomeworkStuBoxClass} .bom_drag`
  278. ],
  279. assignHomeworkStuBoxClass,
  280. toRef(forms, 'workVisiable'),
  281. users.info.id
  282. );
  283. }
  284. return () => (
  285. <div class={styles.assignHomeworkContainer}>
  286. <NForm
  287. ref={formsRef}
  288. model={forms}
  289. labelAlign="right"
  290. labelWidth={'80'}
  291. labelPlacement="left">
  292. <NFormItem
  293. label="布置方式"
  294. path="homeworkObj"
  295. rule={[{ required: true, message: '请选择布置方式' }]}>
  296. <NSpace>
  297. <NButton
  298. secondary
  299. class={[
  300. styles.switch,
  301. forms.homeworkObj === 'CLASS' ? styles.active : ''
  302. ]}
  303. onClick={() => (forms.homeworkObj = 'CLASS')}>
  304. 按班级布置
  305. </NButton>
  306. <NButton
  307. secondary
  308. class={[
  309. styles.switch,
  310. forms.homeworkObj === 'PERSON' ? styles.active : ''
  311. ]}
  312. onClick={() => (forms.homeworkObj = 'PERSON')}>
  313. 按学生布置
  314. </NButton>
  315. </NSpace>
  316. </NFormItem>
  317. <NFormItem
  318. label="作业标题"
  319. path="title"
  320. rule={[
  321. {
  322. required: true,
  323. message: '请输入作业标题',
  324. trigger: 'blur'
  325. }
  326. ]}>
  327. <NInput
  328. v-model:value={forms.title}
  329. placeholder="请选择作业标题"
  330. clearable
  331. />
  332. </NFormItem>
  333. <NFormItem
  334. label="年级"
  335. path="currentGradeNum"
  336. rule={[
  337. {
  338. required: true,
  339. message: '请选择年级',
  340. trigger: 'change',
  341. type: 'number'
  342. }
  343. ]}>
  344. <NSelect
  345. disabled={props.classGroupId ? true : false}
  346. v-model:value={forms.currentGradeNum}
  347. placeholder="请选择年级"
  348. options={forms.gradeList}
  349. clearable
  350. onUpdate:value={() => {
  351. forms.classGroupId = null;
  352. getClassList();
  353. }}
  354. />
  355. </NFormItem>
  356. {forms.homeworkObj === 'CLASS' ? (
  357. <NFormItem
  358. label="班级"
  359. path="classGroupId"
  360. rule={[
  361. {
  362. required: true,
  363. message: '请选择班级',
  364. trigger: 'change',
  365. type: 'array'
  366. }
  367. ]}>
  368. <NSelect
  369. disabled={props.classGroupId ? true : false}
  370. options={forms.classList}
  371. v-model:value={forms.classGroupId}
  372. placeholder="请选择班级"
  373. clearable
  374. multiple
  375. />
  376. </NFormItem>
  377. ) : (
  378. <NFormItem
  379. label="学生"
  380. path="studentList"
  381. rule={[
  382. {
  383. required: true,
  384. message: '请选择学生',
  385. trigger: 'change',
  386. type: 'array'
  387. }
  388. ]}
  389. class={styles.studentSection}>
  390. <span
  391. class={[
  392. styles.selectStudentBtn,
  393. !forms.currentGradeNum && styles.disabled
  394. ]}
  395. onClick={() => {
  396. if (!forms.currentGradeNum) {
  397. return;
  398. }
  399. const tempIds: any = [];
  400. forms.studentList.forEach((item: any) => {
  401. tempIds.push(item.id);
  402. });
  403. forms.selectIds = tempIds;
  404. forms.workVisiable = true;
  405. }}>
  406. 选择学生
  407. </span>
  408. {forms.studentList.length > 0 && (
  409. <NScrollbar class={styles.studentList}>
  410. <span class={styles.firstName}>
  411. 当前选中({forms.studentList.length || 0}):
  412. </span>
  413. {forms.studentList.map((item: any, index: number) => (
  414. <span class={styles.studentItem}>
  415. {item.name}{' '}
  416. <i
  417. class={styles.iconDelete}
  418. onClick={() => {
  419. forms.studentList.splice(index, 1);
  420. }}></i>
  421. </span>
  422. ))}
  423. </NScrollbar>
  424. )}
  425. </NFormItem>
  426. )}
  427. <NFormItem
  428. label="截止时间"
  429. path="expireDate"
  430. rule={[
  431. { required: true, message: '请选择截止时间', trigger: 'change' }
  432. ]}>
  433. <NDatePicker
  434. v-model:formatted-value={forms.expireDate}
  435. type="datetime"
  436. clearable
  437. // valueFormat="yyyy-MM-dd HH:mm"
  438. format="yyyy-MM-dd HH:mm"
  439. style={{ width: '100%' }}
  440. isDateDisabled={dateDisabled}
  441. />
  442. </NFormItem>
  443. {maxDeadlineTime.value > 0 && (
  444. <NFormItem label=" ">
  445. <div class={styles.expireDateTip}>
  446. <i class={styles.expireDateIcon}></i>
  447. <span>
  448. 作业截止{maxDeadlineTime.value}
  449. 天后,学生上传的文件将过期,请及时查看
  450. </span>
  451. </div>
  452. </NFormItem>
  453. )}
  454. <NSpace class={styles.updateBtnGroup}>
  455. <NButton strong type="default" round onClick={() => emit('close')}>
  456. 取消布置
  457. </NButton>
  458. <NButton
  459. strong
  460. type="primary"
  461. round
  462. disabled={forms.uploading}
  463. loading={forms.uploading}
  464. onClick={onSubmit}>
  465. 确认布置
  466. </NButton>
  467. </NSpace>
  468. </NForm>
  469. <NModal
  470. v-model:show={forms.workVisiable}
  471. style={
  472. props.from === 'class'
  473. ? {
  474. width: '640px',
  475. ...assignHomeworkStuBoxDragData.styleDrag.value
  476. }
  477. : {
  478. width: '640px'
  479. }
  480. }
  481. preset="card"
  482. showIcon={false}
  483. class={['modalTitle background', assignHomeworkStuBoxClass]}
  484. title={'选择学生'}
  485. blockScroll={false}>
  486. <AssignStudent
  487. classGroupId={props.classGroupId}
  488. currentGradeNum={forms.currentGradeNum as any}
  489. selectIds={forms.selectIds}
  490. studentList={forms.studentList}
  491. classList={forms.classList}
  492. onClose={() => (forms.workVisiable = false)}
  493. onConfirm={(val: any) => {
  494. forms.studentList = val || [];
  495. forms.workVisiable = false;
  496. }}
  497. />
  498. {props.from === 'class' && <Dragbom></Dragbom>}
  499. </NModal>
  500. </div>
  501. );
  502. }
  503. });