index.tsx 11 KB

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