index.tsx 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421
  1. import { computed, defineComponent, onMounted, reactive, ref } from 'vue';
  2. import styles from './index.module.less';
  3. import { NIcon, NSpin, NScrollbar, NModal, NImage } from 'naive-ui';
  4. import {
  5. lessonCoursewareDetail,
  6. lessonCoursewarePage,
  7. tagUseCourseware
  8. } from '../../api';
  9. import SelectLessonware from './select-lessonware';
  10. import TheEmpty from '/src/components/TheEmpty';
  11. import { usePrepareStore } from '/src/store/modules/prepareLessons';
  12. import { useUserStore } from '/src/store/modules/users';
  13. import { useRoute } from 'vue-router';
  14. import { eventGlobal } from '/src/utils';
  15. import TheNoticeBar from '/src/components/TheNoticeBar';
  16. import { getSubjectList2 } from '/src/api/user';
  17. export default defineComponent({
  18. name: 'directory-main',
  19. setup() {
  20. const route = useRoute();
  21. const prepareStore = usePrepareStore();
  22. const userStore = useUserStore();
  23. const show = ref(true);
  24. const forms = reactive({
  25. lastUseCoursewareId: route.query.lastUseCoursewareId
  26. ? route.query.lastUseCoursewareId + ''
  27. : null, // 专辑编号
  28. unit: route.query.unit ? route.query.unit + '' : null, // 声部
  29. showSelectBookStatus: false,
  30. coursewareStatus: false
  31. });
  32. const getLessonCourseware = async () => {
  33. try {
  34. const { data } = await lessonCoursewarePage({
  35. page: 1,
  36. rows: 99,
  37. type: 'COURSEWARE',
  38. enableFlag: 1
  39. });
  40. const result = data.rows || [];
  41. if (result.length > 0) {
  42. // 判断是否有默认数据
  43. const selectItem = result.find(
  44. (item: any) =>
  45. item.id ===
  46. (forms.lastUseCoursewareId ||
  47. userStore.getUserInfo?.lastUseCoursewareId)
  48. );
  49. let id: any = null;
  50. let instrumentIds: any = null;
  51. if (selectItem) {
  52. prepareStore.setBaseCourseware(selectItem);
  53. id = selectItem.id;
  54. instrumentIds = selectItem.instrumentIds;
  55. } else {
  56. prepareStore.setBaseCourseware(result[0]);
  57. id = result[0]?.id;
  58. instrumentIds = result[0].instrumentIds;
  59. }
  60. setLastUseCoursewareId(id);
  61. if (instrumentIds) {
  62. const { data } = await getSubjectList2({ instrumentIds });
  63. prepareStore.setInstrumentList(data);
  64. }
  65. }
  66. forms.showSelectBookStatus = true;
  67. } catch {
  68. //
  69. }
  70. };
  71. const getLessonCoursewareDetail = async () => {
  72. try {
  73. const baseCourseware: any = prepareStore.getBaseCourseware;
  74. if (!baseCourseware.id) return;
  75. const { data } = await lessonCoursewareDetail({
  76. id: baseCourseware.id
  77. });
  78. const tempList: any = data.lessonList || [];
  79. const defaultUnitIds = formatParentId(forms.unit, tempList);
  80. tempList.forEach((item: any, index: number) => {
  81. item.selected = false;
  82. // 处理从备课页面带过来的参数
  83. if (defaultUnitIds.length > 1) {
  84. if (item.id === defaultUnitIds[0]) {
  85. item.selected = true;
  86. item.knowledgeList.forEach((know: any) => {
  87. if (know.id === defaultUnitIds[1]) {
  88. prepareStore.setSelectKey(know?.id);
  89. prepareStore.setLessonCoursewareId(know?.lessonCoursewareId);
  90. prepareStore.setLessonCoursewareDetailId(
  91. know?.lessonCoursewareDetailId
  92. );
  93. }
  94. });
  95. }
  96. } else {
  97. if (index === 0) {
  98. item.selected = true;
  99. const temp = item['knowledgeList'][0];
  100. prepareStore.setSelectKey(temp?.id);
  101. prepareStore.setLessonCoursewareId(temp?.lessonCoursewareId);
  102. prepareStore.setLessonCoursewareDetailId(
  103. temp?.lessonCoursewareDetailId
  104. );
  105. }
  106. }
  107. });
  108. prepareStore.setTreeList(tempList);
  109. } catch {
  110. //
  111. }
  112. };
  113. const formatParentId = (id: any, list: any, ids = [] as any) => {
  114. for (const item of list) {
  115. if (item.knowledgeList && item.knowledgeList.length > 0) {
  116. const cIds: any = formatParentId(id, item.knowledgeList, [
  117. ...ids,
  118. item.id
  119. ]);
  120. if (cIds.includes(id)) {
  121. return cIds;
  122. }
  123. }
  124. if (item.id === id) {
  125. return [...ids, id];
  126. }
  127. }
  128. return ids;
  129. };
  130. const setLastUseCoursewareId = async (id: any) => {
  131. try {
  132. await tagUseCourseware({ coursewareId: id });
  133. userStore.getInfo();
  134. } catch {
  135. //
  136. }
  137. };
  138. const clickDetail = (child: any) => {
  139. prepareStore.setSelectKey(child.id);
  140. prepareStore.setLessonCoursewareId(child.lessonCoursewareId);
  141. prepareStore.setLessonCoursewareDetailId(child.lessonCoursewareDetailId);
  142. };
  143. const onChangeClass = async (item: any) => {
  144. show.value = true;
  145. forms.lastUseCoursewareId = item.lastUseCoursewareId;
  146. forms.unit = item.unit;
  147. await getLessonCourseware();
  148. await getLessonCoursewareDetail();
  149. show.value = false;
  150. };
  151. const changeCourseware = async (item: any) => {
  152. prepareStore.setBaseCourseware(item);
  153. // prepareStore.setSubjectList(item.subjectList);
  154. if (item.instrumentIds) {
  155. const { data } = await getSubjectList2({
  156. instrumentIds: item.instrumentIds
  157. });
  158. prepareStore.setInstrumentList(data);
  159. let status = false;
  160. let tempInstrumentId: any = null;
  161. data.forEach((item: any, index: number) => {
  162. if (Array.isArray(item.instruments)) {
  163. item.instruments.forEach((child: any, j: number) => {
  164. if (child.id === prepareStore.getInstrumentId) {
  165. status = true;
  166. }
  167. if (index === 0 && j === 0) {
  168. tempInstrumentId = child.id;
  169. }
  170. });
  171. }
  172. });
  173. // 判断教材里面是否有当前选择的声部,如果没有则默认选择第一个
  174. if (status) {
  175. const instrumentId = tempInstrumentId;
  176. sessionStorage.removeItem('prepareLessonCourseWareSubjectIsNull');
  177. prepareStore.setInstrumentId(instrumentId);
  178. }
  179. }
  180. getLessonCoursewareDetail();
  181. setLastUseCoursewareId(item.id);
  182. };
  183. const formatInstrumentNames = computed(() => {
  184. const names = prepareStore.getBaseCourseware.instrumentNames;
  185. if (!names) {
  186. return '';
  187. }
  188. return names.split(',').join('、');
  189. });
  190. onMounted(async () => {
  191. show.value = true;
  192. await getLessonCourseware();
  193. await getLessonCoursewareDetail();
  194. show.value = false;
  195. // 切换班级时触发
  196. eventGlobal.on('onChangeClass', async (item: any) => {
  197. onChangeClass(item);
  198. });
  199. });
  200. return () => (
  201. <div class={styles.directoryList}>
  202. {forms.showSelectBookStatus &&
  203. (prepareStore.getBaseCourseware.id ? (
  204. <div id="lessons-0" class={styles['select-directory-info']}>
  205. <div
  206. class={styles.itemImg}
  207. onClick={() => (forms.coursewareStatus = true)}>
  208. <NImage
  209. objectFit="cover"
  210. src={prepareStore.getBaseCourseware.coverImg}
  211. lazy
  212. previewDisabled={true}
  213. onLoad={e => {
  214. (e.target as any).dataset.loaded = 'true';
  215. }}
  216. />
  217. </div>
  218. <div class={styles.itemContent}>
  219. <h2>
  220. <TheNoticeBar text={prepareStore.getBaseCourseware.name} />
  221. </h2>
  222. <div class={styles.subjects}>
  223. <TheNoticeBar
  224. text={formatInstrumentNames.value}
  225. time={formatInstrumentNames.value.length > 15 ? 10 : 5}
  226. />
  227. </div>
  228. <div
  229. class={styles.changeDir}
  230. onClick={() => (forms.coursewareStatus = true)}>
  231. <svg
  232. width="11px"
  233. height="10px"
  234. viewBox="0 0 11 10"
  235. version="1.1"
  236. xmlns="http://www.w3.org/2000/svg">
  237. <title>切片</title>
  238. <g
  239. stroke="none"
  240. stroke-width="1"
  241. fill="none"
  242. fill-rule="evenodd">
  243. <g
  244. transform="translate(-279.000000, -210.000000)"
  245. fill="#0378EC"
  246. fill-rule="nonzero">
  247. <g transform="translate(132.000000, 96.000000)">
  248. <g transform="translate(32.000000, 24.000000)">
  249. <g transform="translate(103.000000, 10.000000)">
  250. <g transform="translate(0.000000, 71.000000)">
  251. <g transform="translate(12.000000, 9.000000)">
  252. <path d="M10.4116565,3.89985699 C10.6551462,3.89985699 10.8747497,3.75140792 10.9680437,3.52360884 C11.0613377,3.29606287 11.0096883,3.03384082 10.8376072,2.85944797 L8.08018279,0.0692888872 C7.98888976,-0.0230962957 7.8410701,-0.0230962957 7.74977708,0.0692888872 L7.22840639,0.59689687 C7.13711336,0.689282053 7.13711336,0.838996672 7.22840639,0.931255299 L8.95772133,2.68113191 L0.230858792,2.68113191 C0.103423738,2.68113191 0,2.78566638 0,2.91475252 L0,3.66636293 C0,3.79532253 0.10329868,3.89998355 0.230858792,3.89998355 L10.4116565,3.89998355 L10.4116565,3.89985699 Z M10.877501,6.10001645 L0.699579677,6.10001645 C0.456089932,6.10001645 0.236486444,6.24846552 0.143192479,6.4762646 C0.0498985147,6.70381057 0.101547854,6.96603263 0.273628948,7.14042548 L3.03105338,9.93071111 C3.12234641,10.0230963 3.27016607,10.0230963 3.36145909,9.93071111 L3.88282978,9.40310313 C3.97412281,9.31071795 3.97412281,9.16100333 3.88282978,9.0687447 L2.15351484,7.31874154 L10.877501,7.31874154 C11.0065618,7.31874154 11.1111111,7.21281496 11.1111111,7.08233671 L11.1111111,6.33654783 C11.1111111,6.20594302 11.0065618,6.10001645 10.877501,6.10001645 Z"></path>
  253. </g>
  254. </g>
  255. </g>
  256. </g>
  257. </g>
  258. </g>
  259. </g>
  260. </svg>
  261. <span>切换教材</span>
  262. </div>
  263. </div>
  264. </div>
  265. ) : (
  266. <div
  267. id="lessons-0"
  268. class={styles['select-directory']}
  269. onClick={() => (forms.coursewareStatus = true)}>
  270. <span
  271. class={['cr-ellipsis']}
  272. title={prepareStore.getBaseCourseware.name}>
  273. {prepareStore.getBaseCourseware.name || '请选择教材'}
  274. </span>
  275. <NIcon class={styles.iconArrow}>
  276. <svg
  277. width="11px"
  278. height="15px"
  279. viewBox="0 0 11 15"
  280. version="1.1"
  281. xmlns="http://www.w3.org/2000/svg">
  282. <g
  283. stroke="none"
  284. stroke-width="1"
  285. fill="none"
  286. fill-rule="evenodd"
  287. opacity="0.699999988">
  288. <g
  289. transform="translate(-445.000000, -137.000000)"
  290. fill="#131415">
  291. <g transform="translate(152.000000, 120.000000)">
  292. <path
  293. d="M299.326227,20.2118001 L304.934089,28.4366632 C305.245211,28.8929759 305.127511,29.515105 304.671198,29.8262273 C304.505147,29.9394437 304.308836,30 304.107861,30 L292.892139,30 C292.339854,30 291.892139,29.5522847 291.892139,29 C291.892139,28.7990254 291.952695,28.6027139 292.065911,28.4366632 L297.673773,20.2118001 C297.984895,19.7554873 298.607024,19.6377872 299.063337,19.9489096 C299.16663,20.0193364 299.255801,20.1085074 299.326227,20.2118001 Z"
  294. id="三角形"
  295. transform="translate(298.500000, 24.500000) rotate(-270.000000) translate(-298.500000, -24.500000) "></path>
  296. </g>
  297. </g>
  298. </g>
  299. </svg>
  300. </NIcon>
  301. </div>
  302. ))}
  303. <NScrollbar class={styles.scrollBar}>
  304. <NSpin show={show.value}>
  305. <div
  306. class={[
  307. styles.listSection,
  308. !show.value && prepareStore.getTreeList.length <= 0
  309. ? styles.emptySection
  310. : ''
  311. ]}>
  312. {prepareStore.getTreeList.map((item: any, index: number) => (
  313. <div class={styles.treeParent} key={'parent' + index}>
  314. <div
  315. class={[styles.treeItem, styles.parentItem]}
  316. onClick={() => {
  317. prepareStore.getTreeList.forEach((child: any) => {
  318. if (item.id !== child.id) {
  319. child.selected = false;
  320. }
  321. });
  322. item.selected = item.selected ? false : true;
  323. }}>
  324. {item.knowledgeList && item.knowledgeList.length > 0 && (
  325. <span
  326. class={[
  327. styles.arrow,
  328. item.selected ? styles.arrowSelect : ''
  329. ]}></span>
  330. )}
  331. <p
  332. class={[
  333. styles.title,
  334. item.selected ? styles.titleSelect : ''
  335. ]}>
  336. <span
  337. class={[
  338. styles.dir,
  339. item.selected ? styles.dirSelect : ''
  340. ]}></span>
  341. {item.name}
  342. </p>
  343. </div>
  344. {item.selected &&
  345. item.knowledgeList &&
  346. item.knowledgeList.map((child: any, j: number) => (
  347. <div
  348. key={'child' + j}
  349. class={[
  350. styles.treeItem,
  351. styles.childItem,
  352. styles.animation,
  353. prepareStore.getSelectKey === child.id
  354. ? styles.childSelect
  355. : ''
  356. ]}
  357. onClick={() => {
  358. if (prepareStore.getIsEditResource) {
  359. eventGlobal.emit('pageBeforeLeave', () =>
  360. clickDetail(child)
  361. );
  362. } else {
  363. clickDetail(child);
  364. }
  365. }}>
  366. <span class={styles.childArrow}></span>
  367. <p class={styles.title}>{child.name}</p>
  368. </div>
  369. ))}
  370. </div>
  371. ))}
  372. </div>
  373. {!show.value && prepareStore.getTreeList.length <= 0 && (
  374. <TheEmpty />
  375. )}
  376. </NSpin>
  377. </NScrollbar>
  378. {/* 选择教材 */}
  379. <NModal
  380. v-model:show={forms.coursewareStatus}
  381. preset="card"
  382. showIcon={false}
  383. class={['modalTitle background', styles.coursewareModal]}
  384. title={'切换教材'}
  385. blockScroll={false}>
  386. <SelectLessonware
  387. onClose={() => (forms.coursewareStatus = false)}
  388. onConfirm={(item: any) => {
  389. if (prepareStore.getIsEditResource) {
  390. eventGlobal.emit('pageBeforeLeave', () =>
  391. changeCourseware(item)
  392. );
  393. } else {
  394. changeCourseware(item);
  395. }
  396. }}
  397. />
  398. </NModal>
  399. </div>
  400. );
  401. }
  402. });