index.tsx 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. import { defineComponent, onMounted, reactive, ref } from 'vue';
  2. import styles from './index.module.less';
  3. import {
  4. NButton,
  5. NCheckbox,
  6. NCheckboxGroup,
  7. // NBreadcrumb,
  8. // NBreadcrumbItem,
  9. // NScrollbar,
  10. NSlider,
  11. NSpace,
  12. NSpin
  13. } from 'naive-ui';
  14. import iconT from '/src/views/content-information/images/icon-t.png';
  15. import iconAddT from '/src/views/content-information/images/icon-add-t.png';
  16. import iconPlusT from '/src/views/content-information/images/icon-plus-t.png';
  17. import {
  18. api_lessonCoursewareDetail_listKnowledge,
  19. api_lessonCoursewareKnowledgeDetail
  20. } from '/src/views/content-information/api';
  21. import TheEmpty from '/src/components/TheEmpty';
  22. import { PageEnum } from '/src/enums/pageEnum';
  23. export default defineComponent({
  24. name: 'cotnent-knowledge',
  25. emits: ['close', 'confirm'],
  26. setup(props, { emit }) {
  27. const show = ref(false);
  28. const content = ref(false);
  29. const musicContentRef = ref();
  30. const state = reactive({
  31. fontSize: 18,
  32. tableList: [] as any,
  33. selectKey: null,
  34. details: {} as any,
  35. selectCheckboxs: [] as any
  36. });
  37. const getDetails = async () => {
  38. show.value = true;
  39. content.value = true;
  40. try {
  41. const { data } = await api_lessonCoursewareDetail_listKnowledge({
  42. type: 'COURSEWARE'
  43. });
  44. state.tableList = data || [];
  45. if (state.tableList.length > 0) {
  46. const item =
  47. state.tableList[0].lessonCoursewareDetailKnowledgeDetailList;
  48. state.tableList[0].selected = true;
  49. if (item && item.length) {
  50. const child = item[0];
  51. state.selectKey = child.id;
  52. await getDetail();
  53. }
  54. state.tableList.forEach((item: any) => {
  55. item.checked = false;
  56. item.indeterminate = false;
  57. });
  58. }
  59. } catch {
  60. //
  61. }
  62. content.value = false;
  63. show.value = false;
  64. };
  65. const getDetail = async () => {
  66. content.value = true;
  67. try {
  68. const { data } = await api_lessonCoursewareKnowledgeDetail({
  69. id: state.selectKey
  70. });
  71. state.details = data;
  72. } catch {
  73. //
  74. }
  75. content.value = false;
  76. };
  77. const onSubmit = () => {
  78. const items: any[] = [];
  79. for (const i in state.selectCheckboxs) {
  80. const ids = state.selectCheckboxs[i];
  81. const item = state.tableList[i];
  82. if (Array.isArray(item.lessonCoursewareDetailKnowledgeDetailList)) {
  83. item.lessonCoursewareDetailKnowledgeDetailList.forEach(
  84. (child: any) => {
  85. if (ids.includes(child.id)) {
  86. items.push(child);
  87. }
  88. }
  89. );
  90. }
  91. }
  92. const result: any[] = [];
  93. items.forEach(item => {
  94. result.push({
  95. coverImg: PageEnum.THEORY_DEFAULT_COVER,
  96. title: item.name,
  97. materialId: item.id,
  98. content: item.id
  99. });
  100. });
  101. emit('confirm', result);
  102. };
  103. onMounted(() => {
  104. getDetails();
  105. });
  106. return () => (
  107. <div class={styles.container}>
  108. <div class={[styles.wrap]}>
  109. <div class={styles.content}>
  110. <div class={styles.contentWrap}>
  111. <div class={styles.directoryList}>
  112. <div
  113. class={[
  114. styles.scrollBar,
  115. !show.value && state.tableList.length <= 0
  116. ? styles.empty
  117. : ''
  118. ]}
  119. style={{ height: '100%' }}>
  120. <NSpin show={show.value} style={{ height: '100%' }}>
  121. <div class={[styles.listSection]}>
  122. {state.tableList.map((item: any, index: number) => (
  123. <div
  124. class={[
  125. styles.treeParent,
  126. item.selected && styles.treeParentSelected
  127. ]}
  128. key={'parent' + index}>
  129. <div
  130. class={[styles.treeItem, styles.parentItem]}
  131. onClick={() => {
  132. state.tableList.forEach((child: any) => {
  133. if (item.id !== child.id) {
  134. child.selected = false;
  135. }
  136. });
  137. item.selected = item.selected ? false : true;
  138. }}>
  139. {item.lessonCoursewareDetailKnowledgeDetailList &&
  140. item.lessonCoursewareDetailKnowledgeDetailList
  141. .length > 0 && (
  142. <span
  143. class={[
  144. styles.arrow,
  145. item.selected ? styles.arrowSelect : ''
  146. ]}></span>
  147. )}
  148. <p
  149. class={[
  150. styles.title,
  151. item.selected ? styles.titleSelect : ''
  152. ]}>
  153. <span
  154. class={[
  155. styles.dir,
  156. item.selected ? styles.dirSelect : ''
  157. ]}></span>
  158. <p>{item.name}</p>
  159. </p>
  160. <div
  161. class={styles.checkbox}
  162. onClick={(e: any) => {
  163. e.stopPropagation();
  164. }}>
  165. <NCheckbox
  166. checked={item.checked}
  167. indeterminate={item.indeterminate}
  168. onUpdate:checked={(val: boolean) => {
  169. item.checked = val;
  170. const child =
  171. item.lessonCoursewareDetailKnowledgeDetailList ||
  172. [];
  173. if (val) {
  174. const ids: any = [];
  175. child.forEach((c: any) => {
  176. ids.push(c.id);
  177. });
  178. state.selectCheckboxs[index] = ids;
  179. } else {
  180. state.selectCheckboxs[index] = [];
  181. }
  182. item.indeterminate = false;
  183. }}></NCheckbox>
  184. </div>
  185. </div>
  186. <NCheckboxGroup
  187. value={state.selectCheckboxs[index]}
  188. onUpdate:value={val => {
  189. state.selectCheckboxs[index] = val;
  190. const child =
  191. item.lessonCoursewareDetailKnowledgeDetailList ||
  192. [];
  193. if (val.length <= 0) {
  194. item.checked = false;
  195. item.indeterminate = false;
  196. } else if (val.length === child.length) {
  197. item.checked = true;
  198. item.indeterminate = false;
  199. } else {
  200. item.checked = false;
  201. item.indeterminate = true;
  202. }
  203. }}>
  204. {item.selected &&
  205. item.lessonCoursewareDetailKnowledgeDetailList &&
  206. item.lessonCoursewareDetailKnowledgeDetailList.map(
  207. (child: any, j: number) => (
  208. <div
  209. key={'child' + j}
  210. class={[
  211. styles.treeItem,
  212. styles.childItem,
  213. styles.animation,
  214. state.selectKey === child.id
  215. ? styles.childSelect
  216. : ''
  217. ]}
  218. onClick={() => {
  219. if (state.selectKey === child.id) return;
  220. state.selectKey = child.id;
  221. getDetail();
  222. musicContentRef.value.$el.scrollTo(0, 0);
  223. }}>
  224. <span class={styles.childArrow}></span>
  225. <p class={styles.title}>{child.name}</p>
  226. <div
  227. class={styles.checkbox}
  228. onClick={(e: any) => e.stopPropagation()}>
  229. <NCheckbox value={child.id}></NCheckbox>
  230. </div>
  231. </div>
  232. )
  233. )}
  234. </NCheckboxGroup>
  235. </div>
  236. ))}
  237. </div>
  238. </NSpin>
  239. {!show.value && state.tableList.length <= 0 && (
  240. <TheEmpty style={{ height: '100%' }} />
  241. )}
  242. </div>
  243. </div>
  244. <div class={styles.musicStaff}>
  245. <NSpin
  246. show={content.value}
  247. ref={musicContentRef}
  248. class={
  249. !content.value && !state.details?.desc ? styles.empty : ''
  250. }>
  251. {state.details?.desc ? (
  252. <div
  253. class={styles.musicContent}
  254. v-html={state.details?.desc}
  255. style={{ fontSize: state.fontSize + 'px' }}></div>
  256. ) : (
  257. ''
  258. )}
  259. {!content.value && !state.details?.desc && <TheEmpty />}
  260. </NSpin>
  261. </div>
  262. <div class={styles.changeSizeSection}>
  263. <img src={iconT} class={styles.iconT} />
  264. <img
  265. src={iconAddT}
  266. class={styles.iconAddT}
  267. onClick={() => {
  268. if (state.fontSize >= 32) return;
  269. state.fontSize += 1;
  270. }}
  271. />
  272. <NSlider
  273. v-model:value={state.fontSize}
  274. vertical
  275. min={12}
  276. max={32}
  277. />
  278. <img
  279. src={iconPlusT}
  280. class={styles.iconPlusT}
  281. onClick={() => {
  282. if (state.fontSize <= 12) return;
  283. state.fontSize -= 1;
  284. }}
  285. />
  286. </div>
  287. </div>
  288. </div>
  289. </div>
  290. <NSpace class={styles.btnGroup} justify="center">
  291. <NButton round onClick={() => emit('close')}>
  292. 取消
  293. </NButton>
  294. <NButton round type="primary" onClick={onSubmit}>
  295. 确认添加
  296. </NButton>
  297. </NSpace>
  298. </div>
  299. );
  300. }
  301. });