index.tsx 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  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. export default defineComponent({
  27. name: 'courseware-modal',
  28. setup() {
  29. const catchStore = useCatchStore();
  30. const prepareStore = usePrepareStore();
  31. const router = useRouter();
  32. const dialog = useDialog();
  33. const message = useMessage();
  34. const forms = reactive({
  35. coursewareList: [] as any,
  36. loadingStatus: false,
  37. showAttendClass: false,
  38. drag: false
  39. });
  40. // 获取列表
  41. const getList = async () => {
  42. forms.loadingStatus = true;
  43. try {
  44. // 判断是否有选择对应的课件 或声部
  45. if (!prepareStore.getSelectKey || !prepareStore.getSubjectId)
  46. return (forms.loadingStatus = false);
  47. const { data } = await queryCourseware({
  48. coursewareDetailKnowledgeId: prepareStore.getSelectKey,
  49. subjectId: prepareStore.getSubjectId,
  50. page: 1,
  51. rows: 99
  52. });
  53. const tempRows = data.rows || [];
  54. const temp: any = [];
  55. tempRows.forEach((row: any) => {
  56. temp.push({
  57. id: row.id,
  58. materialId: row.materialId,
  59. coverImg: row.coverImg,
  60. type: row.materialType,
  61. title: row.materialName,
  62. isCollect: !!row.favoriteFlag,
  63. isSelected: row.source === 'PLATFORM' ? true : false,
  64. content: row.content,
  65. removeFlag: row.removeFlag
  66. });
  67. });
  68. forms.coursewareList = temp || [];
  69. prepareStore.setCoursewareList(temp || []);
  70. } catch {
  71. //
  72. }
  73. forms.loadingStatus = false;
  74. };
  75. // 监听选择的key 左侧选择了其它的课
  76. watch(
  77. () => prepareStore.getSelectKey,
  78. () => {
  79. getList();
  80. }
  81. );
  82. // 声部变化时
  83. watch(
  84. () => prepareStore.getSubjectId,
  85. () => {
  86. getList();
  87. }
  88. );
  89. watch(
  90. () => prepareStore.getIsAddResource,
  91. (val: boolean) => {
  92. if (val) {
  93. getList();
  94. prepareStore.setIsAddResource(false);
  95. }
  96. }
  97. );
  98. // 删除
  99. const onDelete = (item: any) => {
  100. //
  101. const index = forms.coursewareList.findIndex(
  102. (c: any) => c.id === item.id
  103. );
  104. forms.coursewareList.splice(index, 1);
  105. prepareStore.setCoursewareList(forms.coursewareList);
  106. };
  107. // 完成编辑
  108. const onOverEdit = async () => {
  109. dialog.warning({
  110. title: '提示',
  111. content: `是否完成编辑?`,
  112. positiveText: '确定',
  113. negativeText: '取消',
  114. onPositiveClick: async () => {
  115. try {
  116. const temp: any = [];
  117. forms.coursewareList.forEach((item: any) => {
  118. temp.push({
  119. materialName: item.title,
  120. materialType: item.type,
  121. materialId: item.materialId,
  122. id: item.id
  123. });
  124. });
  125. // 保存课件
  126. await saveCourseware({
  127. coursewareDetailKnowledgeId: prepareStore.getSelectKey,
  128. lessonCoursewareId: prepareStore.getLessonCoursewareId,
  129. lessonCoursewareDetailId:
  130. prepareStore.getLessonCoursewareDetailId,
  131. materialList: [...temp]
  132. });
  133. forms.drag = false;
  134. message.success('编辑成功');
  135. prepareStore.setCoursewareList(forms.coursewareList);
  136. } catch {
  137. //
  138. }
  139. }
  140. });
  141. };
  142. // 预览上课
  143. const onPreviewAttend = () => {
  144. // 获取上架的数据
  145. let count = 0;
  146. forms.coursewareList.forEach((item: any) => {
  147. if (!item.removeFlag) {
  148. count++;
  149. }
  150. });
  151. if (count <= 0) {
  152. message.error('课件不能为空');
  153. return;
  154. }
  155. const { href } = router.resolve({
  156. path: '/attend-class',
  157. query: {
  158. type: 'preview',
  159. subjectId: prepareStore.getSubjectId,
  160. detailId: prepareStore.getSelectKey
  161. }
  162. });
  163. window.open(href, +new Date() + '');
  164. };
  165. // 单个删除
  166. const onRemove = async (item: any) => {
  167. try {
  168. dialog.warning({
  169. title: '提示',
  170. content: '该资源已下架,是否删除?',
  171. positiveText: '确定',
  172. negativeText: '取消',
  173. onPositiveClick: async () => {
  174. await teacherKnowledgeMaterialDelete({ ids: item.id });
  175. message.success('删除成功');
  176. getList();
  177. }
  178. });
  179. } catch {
  180. //
  181. }
  182. };
  183. onMounted(async () => {
  184. // 获取教材分类列表
  185. await catchStore.getSubjects();
  186. const subjectList = catchStore.getSubjectList;
  187. // 并且没有声部时才会更新
  188. if (subjectList.length > 0 && !prepareStore.getSubjectId) {
  189. prepareStore.setSubjectId(subjectList[0].id);
  190. }
  191. await getList();
  192. });
  193. return () => (
  194. <div class={styles.coursewareModal}>
  195. <div class={styles.btnGroup}>
  196. {forms.drag ? (
  197. <NSpace>
  198. <NButton type="default" onClick={onOverEdit}>
  199. 完成编辑
  200. </NButton>
  201. <NButton
  202. type="error"
  203. onClick={() => {
  204. forms.drag = false;
  205. getList();
  206. }}>
  207. 退出编辑
  208. </NButton>
  209. <NButton
  210. type="error"
  211. onClick={() => {
  212. forms.coursewareList = [];
  213. prepareStore.setCoursewareList([]);
  214. }}>
  215. 清空资源
  216. </NButton>
  217. <span class={styles.tips}>拖动可将资源进行排序</span>
  218. </NSpace>
  219. ) : (
  220. <NSpace>
  221. <NSelect
  222. placeholder="选择声部"
  223. options={catchStore.getSubjectList}
  224. labelField="name"
  225. valueField="id"
  226. value={prepareStore.getSubjectId}
  227. onUpdate:value={(val: any) => {
  228. prepareStore.setSubjectId(val);
  229. getList();
  230. }}
  231. />
  232. <NButton type="default" onClick={() => (forms.drag = true)}>
  233. 编辑
  234. </NButton>
  235. </NSpace>
  236. )}
  237. <NSpace>
  238. <NButton type="default" onClick={onPreviewAttend}>
  239. 预览
  240. </NButton>
  241. <NButton
  242. type="primary"
  243. onClick={() => {
  244. let count = 0;
  245. forms.coursewareList.forEach((item: any) => {
  246. if (!item.removeFlag) {
  247. count++;
  248. }
  249. });
  250. if (count <= 0) {
  251. message.error('课件不能为空');
  252. return;
  253. }
  254. forms.showAttendClass = true;
  255. }}>
  256. 开始上课
  257. </NButton>
  258. </NSpace>
  259. </div>
  260. <NScrollbar class={styles.listContainer}>
  261. <NSpin show={forms.loadingStatus}>
  262. <div
  263. class={[
  264. styles.listSection,
  265. !forms.loadingStatus &&
  266. prepareStore.getCoursewareList.length <= 0
  267. ? styles.emptySection
  268. : ''
  269. ]}>
  270. {forms.coursewareList.length > 0 && (
  271. <>
  272. {forms.drag ? (
  273. <Draggable
  274. v-model:modelValue={forms.coursewareList}
  275. itemKey="id"
  276. componentData={{
  277. animation: 200,
  278. group: 'description'
  279. }}
  280. class={styles.list}>
  281. {{
  282. item: (element: any) => {
  283. const item = element.element;
  284. return (
  285. <div
  286. data-id={item.id}
  287. class={[styles.itemBlock, 'row-nav']}>
  288. <CardType
  289. class={[styles.itemContent, 'handle']}
  290. isShowCollect={false}
  291. offShelf={item.removeFlag ? true : false}
  292. onOffShelf={() => onRemove(item)}
  293. item={item}
  294. />
  295. <div class={styles.itemOperation}>
  296. <img
  297. src={iconDelete}
  298. class={styles.iconDelete}
  299. onClick={(e: MouseEvent) => {
  300. e.stopPropagation();
  301. onDelete(item);
  302. }}
  303. />
  304. </div>
  305. </div>
  306. );
  307. }
  308. }}
  309. </Draggable>
  310. ) : (
  311. <div class={styles.list}>
  312. {forms.coursewareList.map((item: any) => (
  313. <CardType
  314. class={[styles.itemContent, 'handle']}
  315. isShowCollect={false}
  316. item={item}
  317. offShelf={item.removeFlag ? true : false}
  318. onOffShelf={() => onRemove(item)}
  319. />
  320. ))}
  321. </div>
  322. )}
  323. </>
  324. )}
  325. {!forms.loadingStatus &&
  326. prepareStore.getCoursewareList.length <= 0 && (
  327. <TheEmpty description="暂无课件" />
  328. )}
  329. </div>
  330. </NSpin>
  331. </NScrollbar>
  332. <NModal
  333. v-model:show={forms.showAttendClass}
  334. preset="card"
  335. showIcon={false}
  336. class={['modalTitle background', styles.attendClassModal]}
  337. title={'选择班级'}
  338. blockScroll={false}>
  339. <AttendClass onClose={() => (forms.showAttendClass = false)} />
  340. </NModal>
  341. </div>
  342. );
  343. }
  344. });