index.tsx 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437
  1. import { defineComponent, onMounted, reactive, watch } from 'vue';
  2. import styles from './index.module.less';
  3. import {
  4. NButton,
  5. NModal,
  6. NScrollbar,
  7. NSelect,
  8. NSpace,
  9. NSpin,
  10. useMessage,
  11. useDialog
  12. } from 'naive-ui';
  13. import CardType from '/src/components/card-type';
  14. import AttendClass from '/src/views/prepare-lessons/model/attend-class';
  15. import { usePrepareStore } from '/src/store/modules/prepareLessons';
  16. import { useCatchStore } from '/src/store/modules/catchData';
  17. import TheEmpty from '/src/components/TheEmpty';
  18. import {
  19. queryCourseware,
  20. saveCourseware,
  21. teacherKnowledgeMaterialDelete
  22. } from '../../../api';
  23. import Draggable from 'vuedraggable';
  24. import iconDelete from '../../../images/icon-delete.png';
  25. import { useRouter } from 'vue-router';
  26. import deepClone from '/src/helpers/deep-clone';
  27. export default defineComponent({
  28. name: 'courseware-modal',
  29. setup() {
  30. const catchStore = useCatchStore();
  31. const prepareStore = usePrepareStore();
  32. const router = useRouter();
  33. const dialog = useDialog();
  34. const message = useMessage();
  35. const forms = reactive({
  36. coursewareList: [] as any,
  37. loadingStatus: false,
  38. showAttendClass: false,
  39. removeIds: [] as any, // 临时删除的编号
  40. drag: false,
  41. removeVisiable: false,
  42. removeVisiable1: false
  43. });
  44. // 获取列表
  45. const getList = async () => {
  46. forms.loadingStatus = true;
  47. try {
  48. // 判断是否有选择对应的课件 或声部
  49. if (!prepareStore.getSelectKey || !prepareStore.getSubjectId)
  50. return (forms.loadingStatus = false);
  51. const { data } = await queryCourseware({
  52. coursewareDetailKnowledgeId: prepareStore.getSelectKey,
  53. subjectId: prepareStore.getSubjectId,
  54. page: 1,
  55. rows: 99
  56. });
  57. const tempRows = data.rows || [];
  58. const temp: any = [];
  59. tempRows.forEach((row: any) => {
  60. temp.push({
  61. id: row.id,
  62. materialId: row.materialId,
  63. coverImg: row.coverImg,
  64. type: row.materialType,
  65. title: row.materialName,
  66. isCollect: !!row.favoriteFlag,
  67. isSelected: row.source === 'PLATFORM' ? true : false,
  68. content: row.content,
  69. removeFlag: row.removeFlag
  70. });
  71. });
  72. prepareStore.setCoursewareList(temp || []);
  73. const tempCourse: any = [];
  74. temp.forEach((item: any) => {
  75. if (!forms.removeIds.includes(item.id)) {
  76. tempCourse.push(item);
  77. }
  78. });
  79. forms.coursewareList = tempCourse;
  80. } catch {
  81. //
  82. }
  83. forms.loadingStatus = false;
  84. };
  85. // 监听选择的key 左侧选择了其它的课
  86. watch(
  87. () => prepareStore.getSelectKey,
  88. () => {
  89. getList();
  90. }
  91. );
  92. // 声部变化时
  93. watch(
  94. () => prepareStore.getSubjectId,
  95. () => {
  96. getList();
  97. }
  98. );
  99. watch(
  100. () => prepareStore.getIsAddResource,
  101. (val: boolean) => {
  102. if (val) {
  103. getList();
  104. prepareStore.setIsAddResource(false);
  105. }
  106. }
  107. );
  108. // 删除
  109. const onDelete = (item: any) => {
  110. //
  111. forms.removeIds.push(item.id);
  112. const index = forms.coursewareList.findIndex(
  113. (c: any) => c.id === item.id
  114. );
  115. forms.coursewareList.splice(index, 1);
  116. // prepareStore.setCoursewareList(forms.coursewareList);
  117. console.log(prepareStore.getCoursewareList, 'getCourseware');
  118. };
  119. // 完成编辑
  120. const onOverEdit = async () => {
  121. // dialog.warning({
  122. // title: '提示',
  123. // content: `是否完成编辑?`,
  124. // positiveText: '确定',
  125. // negativeText: '取消',
  126. // onPositiveClick: async () => {
  127. try {
  128. const temp: any = [];
  129. forms.coursewareList.forEach((item: any) => {
  130. temp.push({
  131. materialName: item.title,
  132. materialType: item.type,
  133. materialId: item.materialId,
  134. id: item.id
  135. });
  136. });
  137. // 保存课件
  138. await saveCourseware({
  139. coursewareDetailKnowledgeId: prepareStore.getSelectKey,
  140. lessonCoursewareId: prepareStore.getLessonCoursewareId,
  141. lessonCoursewareDetailId: prepareStore.getLessonCoursewareDetailId,
  142. materialList: [...temp]
  143. });
  144. forms.drag = false;
  145. message.success('编辑成功');
  146. forms.removeVisiable = false;
  147. prepareStore.setCoursewareList(deepClone(forms.coursewareList));
  148. // 重置临时删除编号
  149. forms.removeIds = [];
  150. } catch {
  151. //
  152. }
  153. // }
  154. // });
  155. };
  156. // 预览上课
  157. const onPreviewAttend = () => {
  158. // 获取上架的数据
  159. let count = 0;
  160. forms.coursewareList.forEach((item: any) => {
  161. if (!item.removeFlag) {
  162. count++;
  163. }
  164. });
  165. if (count <= 0) {
  166. message.error('课件不能为空');
  167. return;
  168. }
  169. const { href } = router.resolve({
  170. path: '/attend-class',
  171. query: {
  172. type: 'preview',
  173. subjectId: prepareStore.getSubjectId,
  174. detailId: prepareStore.getSelectKey
  175. }
  176. });
  177. window.open(href, +new Date() + '');
  178. };
  179. // 单个删除
  180. const onRemove = async (item: any) => {
  181. try {
  182. dialog.warning({
  183. title: '提示',
  184. content: '该资源已下架,是否删除?',
  185. positiveText: '确定',
  186. negativeText: '取消',
  187. onPositiveClick: async () => {
  188. forms.removeIds.push(item.id);
  189. await teacherKnowledgeMaterialDelete({ ids: item.id });
  190. message.success('删除成功');
  191. getList();
  192. }
  193. });
  194. } catch {
  195. //
  196. }
  197. };
  198. onMounted(async () => {
  199. // 获取教材分类列表
  200. await catchStore.getSubjects();
  201. const subjectList = catchStore.getSubjectList;
  202. // 并且没有声部时才会更新
  203. if (subjectList.length > 0 && !prepareStore.getSubjectId) {
  204. prepareStore.setSubjectId(subjectList[0].id);
  205. }
  206. await getList();
  207. });
  208. return () => (
  209. <div class={styles.coursewareModal}>
  210. <div class={styles.btnGroup}>
  211. {forms.drag ? (
  212. <NSpace>
  213. <NButton
  214. type="default"
  215. onClick={() => {
  216. forms.removeVisiable = true;
  217. }}>
  218. 完成编辑
  219. </NButton>
  220. <NButton
  221. type="error"
  222. onClick={() => {
  223. forms.drag = false;
  224. forms.removeIds = [];
  225. getList();
  226. }}>
  227. 取消编辑
  228. </NButton>
  229. <NButton
  230. type="error"
  231. onClick={() => {
  232. forms.removeVisiable1 = true;
  233. }}>
  234. 清空资源
  235. </NButton>
  236. <span class={styles.tips}>拖动可将资源进行排序</span>
  237. </NSpace>
  238. ) : (
  239. <NSpace>
  240. <NSelect
  241. placeholder="选择声部"
  242. options={catchStore.getSubjectList}
  243. labelField="name"
  244. valueField="id"
  245. value={prepareStore.getSubjectId}
  246. onUpdate:value={(val: any) => {
  247. prepareStore.setSubjectId(val);
  248. getList();
  249. }}
  250. />
  251. <NButton type="default" onClick={() => (forms.drag = true)}>
  252. 编辑
  253. </NButton>
  254. </NSpace>
  255. )}
  256. <NSpace>
  257. <NButton type="default" onClick={onPreviewAttend}>
  258. 预览
  259. </NButton>
  260. <NButton
  261. {...{ id: 'lessons-3' }}
  262. type="primary"
  263. onClick={() => {
  264. let count = 0;
  265. forms.coursewareList.forEach((item: any) => {
  266. if (!item.removeFlag) {
  267. count++;
  268. }
  269. });
  270. if (count <= 0) {
  271. message.error('课件不能为空');
  272. return;
  273. }
  274. forms.showAttendClass = true;
  275. }}>
  276. 开始上课
  277. </NButton>
  278. </NSpace>
  279. </div>
  280. <NScrollbar class={styles.listContainer} {...{ id: 'lessons-2' }}>
  281. <NSpin show={forms.loadingStatus}>
  282. <div
  283. class={[
  284. styles.listSection,
  285. !forms.loadingStatus && forms.coursewareList.length <= 0
  286. ? styles.emptySection
  287. : ''
  288. ]}>
  289. {forms.coursewareList.length > 0 && (
  290. <>
  291. {forms.drag ? (
  292. <Draggable
  293. v-model:modelValue={forms.coursewareList}
  294. itemKey="id"
  295. componentData={{
  296. animation: 200,
  297. group: 'description'
  298. }}
  299. class={styles.list}>
  300. {{
  301. item: (element: any,index:number) => {
  302. const item = element.element;
  303. return (<>
  304. <div
  305. data-id={item.id}
  306. class={[styles.itemBlock, 'row-nav']}>
  307. <CardType
  308. class={[styles.itemContent, 'handle']}
  309. isShowCollect={false}
  310. offShelf={item.removeFlag ? true : false}
  311. onOffShelf={() => onRemove(item)}
  312. item={item}
  313. />
  314. <div class={styles.itemOperation}>
  315. <img
  316. src={iconDelete}
  317. class={styles.iconDelete}
  318. onClick={(e: MouseEvent) => {
  319. e.stopPropagation();
  320. onDelete(item);
  321. }}
  322. />
  323. </div>
  324. </div>
  325. </>
  326. );
  327. }
  328. }}
  329. </Draggable>
  330. ) : (
  331. <div class={styles.list}>
  332. {forms.coursewareList.map((item: any,index:number) => (
  333. <CardType
  334. class={[styles.itemContent, 'handle']}
  335. isShowCollect={false}
  336. item={item}
  337. offShelf={item.removeFlag ? true : false}
  338. onOffShelf={() => onRemove(item)}
  339. />
  340. ))}
  341. </div>
  342. )}
  343. </>
  344. )}
  345. {!forms.loadingStatus && forms.coursewareList.length <= 0 && (
  346. <TheEmpty description="暂无课件" />
  347. )}
  348. </div>
  349. </NSpin>
  350. </NScrollbar>
  351. <NModal
  352. v-model:show={forms.showAttendClass}
  353. preset="card"
  354. showIcon={false}
  355. class={['modalTitle background', styles.attendClassModal]}
  356. title={'选择班级'}
  357. blockScroll={false}>
  358. <AttendClass onClose={() => (forms.showAttendClass = false)} />
  359. </NModal>
  360. <NModal
  361. v-model:show={forms.removeVisiable}
  362. preset="card"
  363. class={['modalTitle', styles.removeVisiable]}
  364. title={'提示'}>
  365. <div class={styles.studentRemove}>
  366. <p>是否完成编辑?</p>
  367. <NSpace class={styles.btnGroupModal} justify="center">
  368. <NButton round type="primary" onClick={onOverEdit}>
  369. 确定
  370. </NButton>
  371. <NButton round onClick={() => (forms.removeVisiable = false)}>
  372. 取消
  373. </NButton>
  374. </NSpace>
  375. </div>
  376. </NModal>
  377. <NModal
  378. v-model:show={forms.removeVisiable1}
  379. preset="card"
  380. class={['modalTitle', styles.removeVisiable1]}
  381. title={'清空资源'}>
  382. <div class={styles.studentRemove}>
  383. <p>
  384. 请确认是否要清空资源?
  385. <span>点击确认后所有的素材内容 将被清空掉。</span>
  386. </p>
  387. <NSpace class={styles.btnGroupModal} justify="center">
  388. <NButton
  389. round
  390. type="primary"
  391. onClick={() => {
  392. forms.coursewareList.forEach((item: any) => {
  393. forms.removeIds.push(item.id);
  394. });
  395. forms.coursewareList = [];
  396. forms.removeVisiable1 = false;
  397. // prepareStore.setCoursewareList([]);
  398. console.log(prepareStore.getCoursewareList, 'getCourseware1');
  399. }}>
  400. 确定
  401. </NButton>
  402. <NButton round onClick={() => (forms.removeVisiable1 = false)}>
  403. 取消
  404. </NButton>
  405. </NSpace>
  406. </div>
  407. </NModal>
  408. </div>
  409. );
  410. }
  411. });