index.tsx 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. import {
  2. defineComponent,
  3. onMounted,
  4. onUnmounted,
  5. reactive,
  6. ref,
  7. watch
  8. } from 'vue';
  9. import styles from './index.module.less';
  10. import { NCascader, NInput, NScrollbar, NSelect, NSpin } from 'naive-ui';
  11. import { useThrottleFn } from '@vueuse/core';
  12. import CoursewareType from '../courseware-type';
  13. import TheEmpty from '/src/components/TheEmpty';
  14. import {
  15. api_chapterLessonCoursewareTag_queryAll,
  16. api_queryOpenCoursewareByPage
  17. } from '../../api';
  18. import { eventGlobal } from '/src/utils';
  19. import dayjs from 'dayjs';
  20. export default defineComponent({
  21. name: 'related-class',
  22. props: {
  23. tableList: {
  24. type: Array,
  25. default: () => []
  26. },
  27. instrumentList: {
  28. type: Array,
  29. default: () => []
  30. },
  31. instrumentId: {
  32. type: [String, Number],
  33. default: ''
  34. },
  35. coursewareDetailKnowledgeId: {
  36. type: [String, Number],
  37. default: ''
  38. }
  39. },
  40. emits: ['close', 'add', 'click'],
  41. setup(props, { emit }) {
  42. const tagList = ref<any[]>([]);
  43. const forms = reactive({
  44. loading: false,
  45. finshed: false, // 是否加载完
  46. pagination: {
  47. page: 1,
  48. rows: 20
  49. },
  50. tableList: [] as any,
  51. searchGroup: {
  52. instrumentId: props.instrumentId ? props.instrumentId : '',
  53. chapterLessonCoursewareTagId: '',
  54. keyword: null
  55. }
  56. });
  57. const getList = async () => {
  58. try {
  59. if (forms.pagination.page === 1) {
  60. forms.loading = true;
  61. }
  62. // 查询公开课件列表
  63. const { data } = await api_queryOpenCoursewareByPage({
  64. coursewareDetailKnowledgeId: props.coursewareDetailKnowledgeId,
  65. ...forms.searchGroup,
  66. ...forms.pagination
  67. });
  68. const result = data.rows || [];
  69. const tempList: any = [];
  70. result.forEach((item: any) => {
  71. // const index = forms.tableList.findIndex(
  72. // (i: any) => i.fromChapterLessonCoursewareId === item.id
  73. // );
  74. const firstItem: any =
  75. item.chapterKnowledgeList[0]?.chapterKnowledgeMaterialList[0];
  76. tempList.push({
  77. id: item.id,
  78. openFlag: item.openFlag,
  79. openFlagEnable: item.openFlagEnable,
  80. instrumentNames: item.instrumentNames,
  81. fromChapterLessonCoursewareId: item.fromChapterLessonCoursewareId,
  82. name: item.name,
  83. coverImg: firstItem?.bizInfo.coverImg,
  84. chapterLessonCoursewareTagName: item.chapterLessonCoursewareTagName,
  85. chapterLessonCoursewareTagColor:
  86. item.chapterLessonCoursewareTagColor,
  87. authorName: item.authorName,
  88. updateTime: item.updateTime
  89. ? dayjs(item.updateTime).format('YYYY-MM-DD')
  90. : '',
  91. type: firstItem?.bizInfo.type,
  92. isAdd: item.addFlag,
  93. isNotWork: item.lessonPreTrainingNum <= 0 ? true : false, // 是否布置作业
  94. coursewareType: item.coursewareType
  95. });
  96. });
  97. forms.loading = false;
  98. forms.tableList.push(...tempList);
  99. forms.finshed = data.pages <= data.current ? true : false;
  100. } catch {
  101. forms.loading = false;
  102. }
  103. };
  104. // 检测数据是否存在
  105. // watch(
  106. // () => props.tableList,
  107. // () => {
  108. // // fromChapterLessonCoursewareId;
  109. // forms.tableList.forEach((item: any) => {
  110. // const index = props.tableList.findIndex(
  111. // (i: any) => i.fromChapterLessonCoursewareId === item.id
  112. // );
  113. // item.isAdd = index !== -1 ? true : false;
  114. // });
  115. // }
  116. // );
  117. const throttleFn = useThrottleFn(() => {
  118. forms.pagination.page = 1;
  119. forms.tableList = [];
  120. getList();
  121. }, 500);
  122. const getTagAll = async () => {
  123. const { data } = await api_chapterLessonCoursewareTag_queryAll();
  124. const result = data || [];
  125. tagList.value = [{ name: '全部', id: '' }, ...result];
  126. };
  127. getTagAll();
  128. onMounted(() => {
  129. getList();
  130. eventGlobal.on('openCoursewareChanged', throttleFn);
  131. });
  132. onUnmounted(() => {
  133. eventGlobal.off('openCoursewareChanged', throttleFn);
  134. });
  135. return () => (
  136. <div class={styles.relatedClass}>
  137. <div class={styles.attendClassSearch}>
  138. <NSelect
  139. placeholder="全部"
  140. class={styles.searchSelect2}
  141. options={tagList.value}
  142. labelField="name"
  143. valueField="id"
  144. clearable
  145. v-model:value={forms.searchGroup.chapterLessonCoursewareTagId}
  146. onUpdate:value={() => {
  147. throttleFn();
  148. }}
  149. />
  150. <NCascader
  151. placeholder="全部乐器"
  152. clearable
  153. options={[
  154. { name: '全部乐器', id: '' },
  155. ...(props.instrumentList as any)
  156. ]}
  157. v-model:value={forms.searchGroup.instrumentId}
  158. onUpdate:value={() => throttleFn()}
  159. checkStrategy="child"
  160. showPath={false}
  161. childrenField="instruments"
  162. expandTrigger="hover"
  163. labelField="name"
  164. valueField="id"
  165. filterable
  166. style={{ width: '200px' }}
  167. />
  168. <NInput
  169. placeholder="请输入课件标题/作者名称"
  170. clearable
  171. v-model:value={forms.searchGroup.keyword}
  172. onKeyup={(e: KeyboardEvent) => {
  173. if (e.code === 'Enter') {
  174. throttleFn();
  175. }
  176. }}
  177. onClear={() => throttleFn()}>
  178. {{
  179. prefix: () => (
  180. <span
  181. class="icon-search-input"
  182. style={{ cursor: 'pointer' }}
  183. onClick={() => throttleFn()}></span>
  184. )
  185. }}
  186. </NInput>
  187. </div>
  188. <NSpin show={forms.loading} size={'small'}>
  189. <NScrollbar
  190. class={styles.classList}
  191. style={{
  192. 'max-height': `60vh`
  193. }}
  194. onScroll={(e: any) => {
  195. const clientHeight = e.target?.clientHeight;
  196. const scrollTop = e.target?.scrollTop;
  197. const scrollHeight = e.target?.scrollHeight;
  198. // 是否到底,是否加载完
  199. if (
  200. clientHeight + scrollTop + 20 >= scrollHeight &&
  201. !forms.finshed &&
  202. !forms.loading
  203. ) {
  204. throttleFn();
  205. }
  206. }}>
  207. <div
  208. style={{
  209. 'min-height': `60vh)`
  210. }}
  211. class={[
  212. styles.listSection,
  213. !forms.loading && forms.tableList.length <= 0
  214. ? styles.emptySection
  215. : ''
  216. ]}>
  217. {forms.tableList.length > 0 && (
  218. <div class={[styles.list]}>
  219. {forms.tableList.map((item: any) => (
  220. <div class={[styles.itemWrap, styles.itemBlock, 'row-nav']}>
  221. <div class={styles.itemWrapBox}>
  222. <CoursewareType
  223. isHoverShowAdd={false}
  224. isShowOpenFlag={false}
  225. isShowAdd
  226. item={item}
  227. background={'#fff'}
  228. onAdd={() => {
  229. emit('add', item);
  230. }}
  231. onLook={() => emit('click', item)}
  232. />
  233. </div>
  234. </div>
  235. ))}
  236. </div>
  237. )}
  238. {!forms.loading && forms.tableList.length <= 0 && <TheEmpty />}
  239. </div>
  240. </NScrollbar>
  241. </NSpin>
  242. </div>
  243. );
  244. }
  245. });