index.tsx 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482
  1. import { computed, defineComponent, onMounted, reactive, ref } from 'vue';
  2. import styles from './index.module.less';
  3. import { NIcon, NSpin, NScrollbar, NModal, NImage, NTooltip } 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. import LessonsGuide from '@/custom-plugins/guide-page/lessons-guide';
  18. import { modalClickMask } from '/src/state';
  19. export default defineComponent({
  20. name: 'directory-main',
  21. props: {
  22. sidebarShow: {
  23. type: Boolean,
  24. default: true
  25. }
  26. },
  27. setup(props) {
  28. const route = useRoute();
  29. const prepareStore = usePrepareStore();
  30. const userStore = useUserStore();
  31. const show = ref(true);
  32. const forms = reactive({
  33. lastUseCoursewareId: route.query.lastUseCoursewareId
  34. ? route.query.lastUseCoursewareId + ''
  35. : null, // 专辑编号
  36. unit: route.query.unit ? route.query.unit + '' : null, // 声部
  37. showSelectBookStatus: false,
  38. coursewareStatus: false
  39. });
  40. const getLessonCourseware = async () => {
  41. try {
  42. const { data } = await lessonCoursewarePage({
  43. page: 1,
  44. rows: 99,
  45. type: 'COURSEWARE',
  46. enableFlag: 1
  47. });
  48. const result = data.rows || [];
  49. if (result.length > 0) {
  50. // 判断是否有默认数据
  51. const selectItem = result.find(
  52. (item: any) =>
  53. item.id ===
  54. (forms.lastUseCoursewareId ||
  55. userStore.getUserInfo?.lastUseCoursewareId)
  56. );
  57. let id: any = null;
  58. let instrumentIds: any = null;
  59. if (selectItem) {
  60. prepareStore.setBaseCourseware(selectItem);
  61. id = selectItem.id;
  62. instrumentIds = selectItem.instrumentIds;
  63. } else {
  64. prepareStore.setBaseCourseware(result[0]);
  65. id = result[0]?.id;
  66. instrumentIds = result[0].instrumentIds;
  67. }
  68. setLastUseCoursewareId(id);
  69. if (instrumentIds) {
  70. const { data } = await getSubjectList2({ instrumentIds });
  71. prepareStore.setInstrumentList(data);
  72. }
  73. }
  74. forms.showSelectBookStatus = true;
  75. } catch {
  76. //
  77. }
  78. };
  79. const getLessonCoursewareDetail = async () => {
  80. try {
  81. const baseCourseware: any = prepareStore.getBaseCourseware;
  82. if (!baseCourseware.id) return;
  83. const { data } = await lessonCoursewareDetail({
  84. id: baseCourseware.id
  85. });
  86. const tempList: any = data.lessonList || [];
  87. const defaultUnitIds = formatParentId(forms.unit, tempList);
  88. tempList.forEach((item: any, index: number) => {
  89. item.selected = false;
  90. // 处理从备课页面带过来的参数
  91. if (defaultUnitIds.length > 1) {
  92. if (item.id === defaultUnitIds[0]) {
  93. item.selected = true;
  94. item.knowledgeList.forEach((know: any) => {
  95. if (know.id === defaultUnitIds[1]) {
  96. prepareStore.setSelectKey(know?.id);
  97. prepareStore.setLessonCoursewareId(know?.lessonCoursewareId);
  98. prepareStore.setLessonCoursewareDetailId(
  99. know?.lessonCoursewareDetailId
  100. );
  101. }
  102. });
  103. }
  104. } else {
  105. if (index === 0) {
  106. item.selected = true;
  107. const temp = item['knowledgeList'][0];
  108. prepareStore.setSelectKey(temp?.id);
  109. prepareStore.setLessonCoursewareId(temp?.lessonCoursewareId);
  110. prepareStore.setLessonCoursewareDetailId(
  111. temp?.lessonCoursewareDetailId
  112. );
  113. }
  114. }
  115. });
  116. prepareStore.setTreeList(tempList);
  117. const tempInstrumentId = prepareStore.getInstrumentId;
  118. if (tempInstrumentId) {
  119. const instrumentList = prepareStore.getFormatInstrumentList;
  120. let status = false;
  121. instrumentList.forEach((item: any) => {
  122. if (item.instruments?.length > 0) {
  123. item.instruments.forEach((child: any) => {
  124. if (child.value == tempInstrumentId) {
  125. status = true;
  126. }
  127. });
  128. }
  129. if (item.value == tempInstrumentId) {
  130. status = true;
  131. }
  132. });
  133. if (!status) {
  134. onShowDefaultInstrument();
  135. }
  136. } else {
  137. onShowDefaultInstrument();
  138. }
  139. } catch {
  140. //
  141. }
  142. };
  143. const onShowDefaultInstrument = () => {
  144. // 默认选中第一个声部
  145. const instrumentList = prepareStore.getFormatInstrumentList;
  146. if (instrumentList.length > 0) {
  147. const tempList = instrumentList[0];
  148. if (tempList.instruments.length > 1) {
  149. const childTempList = tempList.instruments[0];
  150. prepareStore.setInstrumentId(childTempList.value);
  151. } else {
  152. prepareStore.setInstrumentId(tempList.value);
  153. }
  154. }
  155. };
  156. const formatParentId = (id: any, list: any, ids = [] as any) => {
  157. for (const item of list) {
  158. if (item.knowledgeList && item.knowledgeList.length > 0) {
  159. const cIds: any = formatParentId(id, item.knowledgeList, [
  160. ...ids,
  161. item.id
  162. ]);
  163. if (cIds.includes(id)) {
  164. return cIds;
  165. }
  166. }
  167. if (item.id === id) {
  168. return [...ids, id];
  169. }
  170. }
  171. return ids;
  172. };
  173. const setLastUseCoursewareId = async (id: any) => {
  174. try {
  175. await tagUseCourseware({ coursewareId: id });
  176. userStore.getInfo();
  177. } catch {
  178. //
  179. }
  180. };
  181. const clickDetail = (child: any) => {
  182. prepareStore.setSelectKey(child.id);
  183. prepareStore.setLessonCoursewareId(child.lessonCoursewareId);
  184. prepareStore.setLessonCoursewareDetailId(child.lessonCoursewareDetailId);
  185. };
  186. const onChangeClass = async (item: any) => {
  187. show.value = true;
  188. forms.lastUseCoursewareId = item.lastUseCoursewareId;
  189. forms.unit = item.unit;
  190. await getLessonCourseware();
  191. await getLessonCoursewareDetail();
  192. show.value = false;
  193. };
  194. const changeCourseware = async (item: any) => {
  195. prepareStore.setBaseCourseware(item);
  196. // prepareStore.setSubjectList(item.subjectList);
  197. if (item.instrumentIds) {
  198. const { data } = await getSubjectList2({
  199. instrumentIds: item.instrumentIds
  200. });
  201. prepareStore.setInstrumentList(data);
  202. let status = false;
  203. let tempInstrumentId: any = null;
  204. data.forEach((item: any, index: number) => {
  205. if (Array.isArray(item.instruments)) {
  206. item.instruments.forEach((child: any, j: number) => {
  207. if (child.id === prepareStore.getInstrumentId) {
  208. status = true;
  209. }
  210. if (index === 0 && j === 0) {
  211. tempInstrumentId = child.id;
  212. }
  213. });
  214. }
  215. });
  216. await getLessonCoursewareDetail();
  217. // 判断教材里面是否有当前选择的声部,如果没有则默认选择第一个
  218. if (status) {
  219. const instrumentId = tempInstrumentId;
  220. prepareStore.setInstrumentId(instrumentId);
  221. } else {
  222. onShowDefaultInstrument();
  223. }
  224. }
  225. setLastUseCoursewareId(item.id);
  226. };
  227. const formatInstrumentNames = computed(() => {
  228. const names = prepareStore.getBaseCourseware.instrumentNames;
  229. if (!names) {
  230. return '';
  231. }
  232. return names.split(',').join('、');
  233. });
  234. onMounted(async () => {
  235. show.value = true;
  236. await getLessonCourseware();
  237. await getLessonCoursewareDetail();
  238. show.value = false;
  239. // 切换班级时触发
  240. eventGlobal.on('onChangeClass', async (item: any) => {
  241. onChangeClass(item);
  242. });
  243. });
  244. return () => (
  245. <>
  246. <div class={styles.directoryList}>
  247. {forms.showSelectBookStatus &&
  248. (prepareStore.getBaseCourseware.id ? (
  249. <div id="lessons-0" class={styles['select-directory-info']}>
  250. <div
  251. class={styles.itemImg}
  252. onClick={() => (forms.coursewareStatus = true)}>
  253. <NImage
  254. objectFit="cover"
  255. src={prepareStore.getBaseCourseware.coverImg}
  256. lazy
  257. previewDisabled={true}
  258. onLoad={(e: any) => {
  259. (e.target as any).dataset.loaded = 'true';
  260. }}
  261. />
  262. </div>
  263. <div class={styles.itemContent}>
  264. <h2>
  265. {/* <TheNoticeBar text={prepareStore.getBaseCourseware.name} /> */}
  266. <NTooltip showArrow={false} class={styles.theTooltip} placement="top-start">
  267. {{
  268. trigger: () => prepareStore.getBaseCourseware.name,
  269. default: () => prepareStore.getBaseCourseware.name
  270. }}
  271. </NTooltip>
  272. </h2>
  273. <div class={styles.subjects}>
  274. {/* <TheNoticeBar text={formatInstrumentNames.value} /> */}
  275. <NTooltip showArrow={false} class={styles.theTooltip} placement="top-start">
  276. {{
  277. trigger: () => formatInstrumentNames.value,
  278. default: () => formatInstrumentNames.value
  279. }}
  280. </NTooltip>
  281. </div>
  282. <div
  283. class={styles.changeDir}
  284. onClick={() => (forms.coursewareStatus = true)}>
  285. <svg
  286. width="11px"
  287. height="10px"
  288. viewBox="0 0 11 10"
  289. version="1.1"
  290. xmlns="http://www.w3.org/2000/svg">
  291. <title>切片</title>
  292. <g
  293. stroke="none"
  294. stroke-width="1"
  295. fill="none"
  296. fill-rule="evenodd">
  297. <g
  298. transform="translate(-279.000000, -210.000000)"
  299. fill="#0378EC"
  300. fill-rule="nonzero">
  301. <g transform="translate(132.000000, 96.000000)">
  302. <g transform="translate(32.000000, 24.000000)">
  303. <g transform="translate(103.000000, 10.000000)">
  304. <g transform="translate(0.000000, 71.000000)">
  305. <g transform="translate(12.000000, 9.000000)">
  306. <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>
  307. </g>
  308. </g>
  309. </g>
  310. </g>
  311. </g>
  312. </g>
  313. </g>
  314. </svg>
  315. <span>切换教材</span>
  316. </div>
  317. </div>
  318. </div>
  319. ) : (
  320. <div
  321. id="lessons-0"
  322. class={styles['select-directory']}
  323. onClick={() => (forms.coursewareStatus = true)}>
  324. <span
  325. class={['cr-ellipsis']}
  326. title={prepareStore.getBaseCourseware.name}>
  327. {prepareStore.getBaseCourseware.name || '请选择教材'}
  328. </span>
  329. <NIcon class={styles.iconArrow}>
  330. <svg
  331. width="11px"
  332. height="15px"
  333. viewBox="0 0 11 15"
  334. version="1.1"
  335. xmlns="http://www.w3.org/2000/svg">
  336. <g
  337. stroke="none"
  338. stroke-width="1"
  339. fill="none"
  340. fill-rule="evenodd"
  341. opacity="0.699999988">
  342. <g
  343. transform="translate(-445.000000, -137.000000)"
  344. fill="#131415">
  345. <g transform="translate(152.000000, 120.000000)">
  346. <path
  347. 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"
  348. id="三角形"
  349. transform="translate(298.500000, 24.500000) rotate(-270.000000) translate(-298.500000, -24.500000) "></path>
  350. </g>
  351. </g>
  352. </g>
  353. </svg>
  354. </NIcon>
  355. </div>
  356. ))}
  357. <NScrollbar class={styles.scrollBar}>
  358. <NSpin show={show.value}>
  359. <div
  360. class={[
  361. styles.listSection,
  362. !show.value && prepareStore.getTreeList.length <= 0
  363. ? styles.emptySection
  364. : ''
  365. ]}>
  366. {prepareStore.getTreeList.map((item: any, index: number) => (
  367. <div class={styles.treeParent} key={'parent' + index}>
  368. <div
  369. class={[styles.treeItem, styles.parentItem]}
  370. onClick={() => {
  371. prepareStore.getTreeList.forEach((child: any) => {
  372. if (item.id !== child.id) {
  373. child.selected = false;
  374. }
  375. });
  376. item.selected = item.selected ? false : true;
  377. }}>
  378. {item.knowledgeList && item.knowledgeList.length > 0 && (
  379. <span
  380. class={[
  381. styles.arrow,
  382. item.selected ? styles.arrowSelect : ''
  383. ]}></span>
  384. )}
  385. <p
  386. class={[
  387. styles.title,
  388. item.selected ? styles.titleSelect : ''
  389. ]}>
  390. <span
  391. class={[
  392. styles.dir,
  393. item.selected ? styles.dirSelect : ''
  394. ]}></span>
  395. {item.name}
  396. </p>
  397. </div>
  398. {item.selected &&
  399. item.knowledgeList &&
  400. item.knowledgeList.map((child: any, j: number) => (
  401. <div
  402. key={'child' + j}
  403. class={[
  404. styles.treeItem,
  405. styles.childItem,
  406. styles.animation,
  407. prepareStore.getSelectKey === child.id
  408. ? styles.childSelect
  409. : ''
  410. ]}
  411. onClick={() => {
  412. if (prepareStore.getIsEditResource) {
  413. eventGlobal.emit('pageBeforeLeave', () =>
  414. clickDetail(child)
  415. );
  416. } else {
  417. clickDetail(child);
  418. }
  419. }}>
  420. <span class={styles.childArrow}></span>
  421. <p class={styles.title}>{child.name}</p>
  422. </div>
  423. ))}
  424. </div>
  425. ))}
  426. </div>
  427. {!show.value && prepareStore.getTreeList.length <= 0 && (
  428. <TheEmpty />
  429. )}
  430. </NSpin>
  431. </NScrollbar>
  432. {/* 选择教材 */}
  433. <NModal
  434. maskClosable={modalClickMask}
  435. v-model:show={forms.coursewareStatus}
  436. preset="card"
  437. showIcon={false}
  438. class={['modalTitle background', styles.coursewareModal]}
  439. title={'切换教材'}
  440. blockScroll={false}>
  441. <SelectLessonware
  442. onClose={() => (forms.coursewareStatus = false)}
  443. onConfirm={(item: any) => {
  444. if (prepareStore.getIsEditResource) {
  445. eventGlobal.emit('pageBeforeLeave', () =>
  446. changeCourseware(item)
  447. );
  448. } else {
  449. changeCourseware(item);
  450. }
  451. }}
  452. />
  453. </NModal>
  454. </div>
  455. {forms.showSelectBookStatus && !props.sidebarShow && (
  456. <LessonsGuide></LessonsGuide>
  457. )}
  458. </>
  459. );
  460. }
  461. });