index.tsx 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484
  1. import { defineComponent, onMounted, reactive } from 'vue';
  2. import styles from './index.module.less';
  3. import {
  4. NButton,
  5. NCascader,
  6. NForm,
  7. NFormItem,
  8. NImage,
  9. NInput,
  10. NModal,
  11. NPopselect,
  12. NScrollbar,
  13. NSelect,
  14. NSpace,
  15. NSpin,
  16. useDialog,
  17. useMessage
  18. } from 'naive-ui';
  19. import AddTeaching, {
  20. BOOK_DATA
  21. } from '/src/views/natural-resources/model/add-teaching';
  22. import {
  23. lessonCoursewarePage,
  24. lessonCoursewareRemove,
  25. api_lessonCoursewareTeacherCategory
  26. } from '../../../api';
  27. import iconUploadBg from '../images/icon-upload-bg.png';
  28. import { useCatchStore } from '/src/store/modules/catchData';
  29. import { useThrottleFn } from '@vueuse/core';
  30. import iconEdit from '../images/icon-edit.png';
  31. import iconDelete from '../images/icon-delete.png';
  32. import { modalClickMask } from '/src/state';
  33. export default defineComponent({
  34. name: 'select-lessonware',
  35. emits: ['close', 'confirm'],
  36. setup(props, { emit }) {
  37. const catchStore = useCatchStore();
  38. const dialog = useDialog();
  39. const message = useMessage();
  40. const forms = reactive({
  41. loading: false,
  42. list: [] as any[],
  43. teachingStatus: false,
  44. musicTagList: [] as any[],
  45. selectItem: {} as any,
  46. bookVersionId: null,
  47. keyword: null,
  48. currentGradeNum: '' as any,
  49. instrumentId: '' as any,
  50. removeVisiable: false,
  51. removeRow: {} as any,
  52. bookType: '' as any
  53. });
  54. const treeList = reactive({
  55. tempSubjectId: null,
  56. versionList: [] as any, // 教材
  57. gradeList: [] as any, // 年级
  58. bookTypeList: [] as any // 册别
  59. });
  60. const getLessonCourseware = async () => {
  61. forms.loading = true;
  62. try {
  63. console.log(forms.bookVersionId, 'bookVersionId')
  64. const { data } = await lessonCoursewarePage({
  65. page: 1,
  66. rows: 99,
  67. type: 'COURSEWARE',
  68. enableFlag: 1,
  69. bookVersionId: forms.bookVersionId === '0' ? null : forms.bookVersionId,
  70. customFlag: forms.bookVersionId === '0' ? true : null,
  71. keyword: forms.keyword,
  72. currentGradeNum: forms.currentGradeNum,
  73. instrumentId: forms.instrumentId,
  74. bookType: forms.bookType
  75. });
  76. forms.list = data.rows;
  77. } catch {
  78. //
  79. }
  80. forms.loading = false;
  81. };
  82. // 删除教材
  83. const onDelete = async (item: any) => {
  84. try {
  85. await lessonCoursewareRemove({ id: forms.removeRow.id });
  86. message.success('删除成功');
  87. getLessonCourseware();
  88. forms.removeVisiable = false;
  89. } catch (e) {
  90. console.log(e);
  91. }
  92. };
  93. const throttledFn = useThrottleFn(() => getLessonCourseware(), 500);
  94. const onDetail = (item: any) => {
  95. emit('confirm', item);
  96. emit('close');
  97. };
  98. const getSearchDetail = async () => {
  99. try {
  100. const { data } = await api_lessonCoursewareTeacherCategory();
  101. const result = data || []
  102. treeList.versionList = [{
  103. name: '全部',
  104. id: ''
  105. }, ...result]
  106. } catch {
  107. //
  108. }
  109. };
  110. const selectChildObj = (item: any) => {
  111. const obj: any = {};
  112. item?.forEach((child: any) => {
  113. if (child.id === forms.instrumentId) {
  114. obj.selected = true;
  115. obj.name = child.name;
  116. }
  117. });
  118. return obj;
  119. };
  120. onMounted(async () => {
  121. // 获取教材分类列表
  122. try {
  123. await catchStore.getSubjects();
  124. // const { data } = await bookVersionPage({
  125. // page: 1,
  126. // rows: 99,
  127. // type: 'COURSEWARE'
  128. // });
  129. // const temp = data.rows || [];
  130. // temp.forEach((item: any) => {
  131. // forms.musicTagList.push({
  132. // id: item.id,
  133. // name: item.name
  134. // });
  135. // });
  136. await getSearchDetail();
  137. } catch {
  138. //
  139. }
  140. getLessonCourseware();
  141. });
  142. return () => (
  143. <div class={styles.selectLessonware}>
  144. <NScrollbar class={styles.classList}>
  145. <div class={styles.attendClassSearch}>
  146. <NForm labelAlign="left" labelPlacement="left">
  147. {treeList.versionList.length > 0 && <NFormItem label="教程:">
  148. <NSpace class={styles.spaceSection}>
  149. {treeList.versionList?.map((subject: any) => (
  150. <span
  151. class={[
  152. styles.textBtn,
  153. (forms.bookVersionId || '') ==
  154. subject.id && styles.textBtnActive
  155. ]}
  156. onClick={() => {
  157. treeList.bookTypeList = []
  158. forms.currentGradeNum = ''
  159. forms.bookType = ''
  160. if(subject.children && subject.children.length > 0) {
  161. const result = subject.children || []
  162. treeList.gradeList = [{
  163. name: '全部',
  164. id: ''
  165. }, ...result]
  166. } else {
  167. treeList.gradeList = []
  168. }
  169. forms.bookVersionId = subject.id
  170. throttledFn()
  171. }}>
  172. {subject.name}
  173. </span>
  174. ))}
  175. </NSpace>
  176. </NFormItem>}
  177. {treeList.gradeList.length > 0 && <NFormItem label="年级:">
  178. <NSpace class={styles.spaceSection}>
  179. {treeList.gradeList?.map((subject: any) => (
  180. <span
  181. class={[
  182. styles.textBtn,
  183. (forms.currentGradeNum || '') == subject.id &&
  184. styles.textBtnActive
  185. ]}
  186. onClick={() => {
  187. forms.bookType = ''
  188. if(subject.children && subject.children.length > 0) {
  189. treeList.bookTypeList = subject.children || []
  190. const result = subject.children || []
  191. treeList.bookTypeList = [{
  192. name: '全部',
  193. id: ''
  194. }, ...result]
  195. } else {
  196. treeList.bookTypeList = []
  197. }
  198. forms.currentGradeNum = subject.id
  199. throttledFn()
  200. }}>
  201. {subject.name}
  202. </span>
  203. ))}
  204. </NSpace>
  205. </NFormItem>}
  206. {treeList.bookTypeList.length > 0 && <NFormItem label="册别:">
  207. <NSpace class={styles.spaceSection}>
  208. {treeList.bookTypeList?.map((subject: any) => (
  209. <span
  210. class={[
  211. styles.textBtn,
  212. (forms.bookType || '') ==
  213. subject.id && styles.textBtnActive
  214. ]}
  215. onClick={() => {
  216. forms.bookType = subject.id
  217. throttledFn()
  218. }}>
  219. {subject.name}
  220. </span>
  221. ))}
  222. </NSpace>
  223. </NFormItem>}
  224. <NFormItem label="乐器:">
  225. <NSpace class={styles.spaceSection}>
  226. {[
  227. { name: '全部乐器', value: '' },
  228. ...catchStore.getSubjectInstrumentOnly
  229. ].map((subject: any) =>
  230. subject.instruments && subject.instruments.length > 1 ? (
  231. <NPopselect
  232. options={subject.instruments}
  233. trigger="hover"
  234. scrollable
  235. v-model:value={treeList.tempSubjectId}
  236. onUpdate:value={() => {
  237. forms.instrumentId = treeList.tempSubjectId;
  238. throttledFn()
  239. }}
  240. key={subject.value}
  241. class={[styles.popSelect]}>
  242. <span
  243. class={[
  244. styles.textBtn,
  245. selectChildObj(subject.instruments).selected &&
  246. styles.textBtnActive
  247. ]}>
  248. {selectChildObj(subject.instruments).name ||
  249. subject.name}
  250. <i class={styles.iconArrow}></i>
  251. </span>
  252. </NPopselect>
  253. ) : (
  254. <span
  255. class={[
  256. styles.textBtn,
  257. forms.instrumentId === subject.value &&
  258. styles.textBtnActive
  259. ]}
  260. onClick={() => {
  261. forms.instrumentId = subject.value;
  262. treeList.tempSubjectId = null;
  263. throttledFn()
  264. }}>
  265. {subject.name}
  266. </span>
  267. )
  268. )}
  269. </NSpace>
  270. </NFormItem>
  271. </NForm>
  272. {/* <NInput
  273. placeholder="请输入教材名称"
  274. clearable
  275. v-model:value={forms.keyword}
  276. onKeyup={(e: KeyboardEvent) => {
  277. if (e.code === 'Enter') {
  278. throttledFn();
  279. }
  280. }}
  281. onClear={() => {
  282. forms.keyword = null;
  283. throttledFn();
  284. }}>
  285. {{
  286. prefix: () => (
  287. <span
  288. class="icon-search-input"
  289. onClick={() => throttledFn()}></span>
  290. )
  291. }}
  292. </NInput>
  293. <NCascader
  294. placeholder="请选择乐器"
  295. v-model:value={forms.instrumentId}
  296. onUpdate:value={() => throttledFn()}
  297. options={
  298. [
  299. { name: '全部乐器', id: null },
  300. ...catchStore.getSubjectList
  301. ] as any
  302. }
  303. checkStrategy="child"
  304. showPath={false}
  305. childrenField="instruments"
  306. expandTrigger="hover"
  307. labelField="name"
  308. valueField="id"
  309. clearable
  310. filterable
  311. style={{ width: '400px' }}
  312. />
  313. <NSelect
  314. placeholder="全部版本"
  315. clearable
  316. options={[{ id: null, name: '全部版本' }, ...forms.musicTagList]}
  317. labelField="name"
  318. valueField="id"
  319. v-model:value={forms.bookVersionId}
  320. onUpdate:value={() => throttledFn()}
  321. />
  322. <NSelect
  323. placeholder="全部年级"
  324. options={
  325. [{ label: '全部年级', value: null }, ...BOOK_DATA.grades] as any
  326. }
  327. v-model:value={forms.currentGradeNum}
  328. clearable
  329. filterable
  330. onUpdate:value={() => throttledFn()}
  331. /> */}
  332. {/* <NSelect
  333. placeholder="全部册别"
  334. options={
  335. [
  336. { label: '全部册别', value: null },
  337. ...BOOK_DATA.bookTypes
  338. ] as any
  339. }
  340. v-model:value={forms.bookType}
  341. clearable
  342. onUpdate:value={() => throttledFn()}
  343. /> */}
  344. </div>
  345. <NSpin show={forms.loading} class={styles.content}>
  346. <NSpace class={styles.teachingSpace}>
  347. <div
  348. class={styles.item}
  349. key={`item--1`}
  350. onClick={() => {
  351. forms.selectItem = {};
  352. forms.teachingStatus = true;
  353. }}>
  354. <div class={styles.cover}>
  355. <div class={styles.itemImg}>
  356. <div class={styles.itemBg}></div>
  357. <NImage
  358. objectFit="cover"
  359. src={iconUploadBg}
  360. lazy
  361. previewDisabled={true}
  362. onLoad={(e: any) => {
  363. (e.target as any).dataset.loaded = 'true';
  364. }}
  365. />
  366. </div>
  367. </div>
  368. </div>
  369. {forms.list.map((item: any, index: number) => {
  370. return (
  371. <div
  372. class={styles.item}
  373. key={`item-${index}`}
  374. onClick={() => onDetail(item)}>
  375. <div class={styles.cover}>
  376. <div class={styles.itemImg}>
  377. <div class={styles.itemBg}></div>
  378. <NImage
  379. objectFit="cover"
  380. src={item.coverImg}
  381. lazy
  382. previewDisabled={true}
  383. onLoad={(e: any) => {
  384. (e.target as any).dataset.loaded = 'true';
  385. }}
  386. />
  387. {item.customFlag && (
  388. <>
  389. <div class={styles.iconCustom}></div>
  390. <div class={styles.editContainer}>
  391. <div class={styles.editBtnGroup}>
  392. <img
  393. src={iconEdit}
  394. class={styles.imgBtn}
  395. onClick={(e: MouseEvent) => {
  396. e.stopPropagation();
  397. forms.selectItem = item;
  398. forms.teachingStatus = true;
  399. }}
  400. />
  401. <img
  402. src={iconDelete}
  403. class={styles.imgBtn}
  404. onClick={(e: MouseEvent) => {
  405. e.stopPropagation();
  406. forms.removeVisiable = true;
  407. forms.removeRow = item;
  408. }}
  409. />
  410. </div>
  411. </div>
  412. </>
  413. )}
  414. </div>
  415. </div>
  416. <div class={styles.itemName}>{item.name}</div>
  417. </div>
  418. );
  419. })}
  420. </NSpace>
  421. </NSpin>
  422. </NScrollbar>
  423. {/* 添加自定义教材 */}
  424. <NModal
  425. maskClosable={modalClickMask}
  426. v-model:show={forms.teachingStatus}
  427. preset="card"
  428. showIcon={false}
  429. class={['modalTitle background', styles.teachingModal]}
  430. title={'自定义教材'}
  431. blockScroll={false}>
  432. <AddTeaching
  433. item={forms.selectItem}
  434. onClose={() => (forms.teachingStatus = false)}
  435. onConfirm={() => {
  436. getLessonCourseware();
  437. forms.selectItem = {};
  438. }}
  439. />
  440. </NModal>
  441. <NModal
  442. maskClosable={modalClickMask}
  443. v-model:show={forms.removeVisiable}
  444. preset="card"
  445. class={['modalTitle', styles.removeVisiable]}
  446. title={'删除教材'}>
  447. <div class={styles.studentRemove}>
  448. <p>是否删除该教材</p>
  449. <NSpace class={styles.btnGroup} justify="center">
  450. <NButton round type="primary" onClick={onDelete}>
  451. 确定
  452. </NButton>
  453. <NButton round onClick={() => (forms.removeVisiable = false)}>
  454. 取消
  455. </NButton>
  456. </NSpace>
  457. </div>
  458. </NModal>
  459. </div>
  460. );
  461. }
  462. });