index.tsx 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432
  1. import {
  2. PropType,
  3. defineComponent,
  4. nextTick,
  5. onMounted,
  6. reactive,
  7. ref,
  8. toRef,
  9. toRefs,
  10. watch
  11. } from 'vue';
  12. import styles from './index.module.less';
  13. import {
  14. NButton,
  15. NForm,
  16. NFormItem,
  17. NImage,
  18. NPopselect,
  19. NSpace
  20. } from 'naive-ui';
  21. import { resourceTypeArray } from '/src/utils/searchArray';
  22. import { useCatchStore } from '/src/store/modules/catchData';
  23. import { useThrottleFn } from '@vueuse/core';
  24. import TheSearch from '/src/components/TheSearch';
  25. import isCollaose from '/src/views/natural-resources/images/isCollaose.png';
  26. const ChildNodeSearch = defineComponent({
  27. name: 'ChildNodeSearch',
  28. props: {
  29. activeRow: {
  30. type: Object,
  31. default: () => ({})
  32. },
  33. list: {
  34. type: Array,
  35. default: () => []
  36. }
  37. },
  38. emits: ['selectChildTag'],
  39. setup(props, { emit }) {
  40. const { activeRow } = toRefs(props);
  41. const selectItem = ref({});
  42. watch(
  43. () => props.activeRow,
  44. () => {
  45. activeRow.value = props.activeRow;
  46. selectItem.value = {};
  47. }
  48. );
  49. return () => (
  50. <>
  51. {activeRow.value?.id && (
  52. <>
  53. <NFormItem label={activeRow.value.columnName + ':'}>
  54. <NSpace class={styles.spaceSection}>
  55. {activeRow.value?.children.map((subject: any) => (
  56. <span
  57. class={[
  58. styles.textBtn,
  59. (activeRow.value.activeIndex || '') == subject.id &&
  60. styles.textBtnActive
  61. ]}
  62. onClick={() => {
  63. activeRow.value.activeIndex = subject.id;
  64. let children: any;
  65. let columnName = '';
  66. if (subject.children) {
  67. children = [
  68. {
  69. columnName: subject.children[0].columnName,
  70. name: '全部',
  71. id: ''
  72. },
  73. ...subject.children
  74. ];
  75. columnName = subject.children[0].columnName;
  76. selectItem.value = {
  77. ...subject,
  78. columnName,
  79. activeIndex: '',
  80. children
  81. };
  82. } else {
  83. selectItem.value = {};
  84. }
  85. emit('selectChildTag', activeRow.value.activeIndex);
  86. }}>
  87. {subject.name}
  88. </span>
  89. ))}
  90. </NSpace>
  91. </NFormItem>
  92. <ChildNodeSearch
  93. activeRow={selectItem.value}
  94. onSelectChildTag={(item: any) => {
  95. emit('selectChildTag', item || activeRow.value.activeIndex);
  96. }}
  97. />
  98. </>
  99. )}
  100. </>
  101. );
  102. }
  103. });
  104. export default defineComponent({
  105. name: 'resource-search-group',
  106. props: {
  107. type: {
  108. type: String as PropType<
  109. 'relateResources' | 'shareResources' | 'myResources' | 'myCollect'
  110. >,
  111. default: 'shareResources'
  112. },
  113. subjectId: {
  114. type: String,
  115. default: null
  116. }
  117. },
  118. emits: ['search'],
  119. setup(props, { emit }) {
  120. const subjectId = toRef(props.subjectId);
  121. const catchStore = useCatchStore();
  122. const forms = reactive({
  123. type: 'MUSIC', //
  124. name: '',
  125. subjectId: subjectId.value as any,
  126. // grade: null as any,
  127. bookVersionId: null as any
  128. // musicSheetCategoriesId: null as any
  129. });
  130. const state = reactive({
  131. tempSubjectId: null,
  132. gradeList: [] as any[],
  133. musicCategory: [] as any
  134. });
  135. const data = reactive({
  136. selectParents: {}, // 选中的数据
  137. tags: [] as any[],
  138. tagActiveId: '' as any,
  139. tagActive: {} as any,
  140. childSelectId: null as any
  141. });
  142. const resourceType = ref([] as any);
  143. const onSearch = (type?: string) => {
  144. emit(
  145. 'search',
  146. {
  147. ...forms,
  148. bookVersionId: data.childSelectId || data.tagActiveId
  149. },
  150. type
  151. );
  152. };
  153. const throttleFn = useThrottleFn(() => onSearch(), 500);
  154. const collapseWrapRef = ref();
  155. const divDomList = ref([] as any);
  156. const orginHeight = ref(0);
  157. const hiddenHeight = ref(0);
  158. const line = ref(0);
  159. const isCollapse = ref(false);
  160. const loadingCollapse = ref(false); // 是否加载完成
  161. const musicCateRef = (el: any) => {
  162. if (el?.selfElRef) {
  163. divDomList.value.push(el.selfElRef.parentNode);
  164. }
  165. };
  166. const setCollapse = (flag: boolean) => {
  167. isCollapse.value = flag;
  168. getLive();
  169. };
  170. const getLive = () => {
  171. try {
  172. divDomList.value = [...new Set(divDomList.value)];
  173. let offsetLeft = -1;
  174. divDomList.value.forEach((item: any, index: number) => {
  175. if (index === 0) {
  176. line.value = 1;
  177. offsetLeft = item.offsetLeft;
  178. } else if (item.offsetLeft === offsetLeft && index != 0) {
  179. // 如果某个标签的offsetLeft和第一个标签的offsetLeft相等 说明增加了一行
  180. line.value++;
  181. }
  182. if (!isCollapse.value) {
  183. if (line.value > 1) {
  184. //从第3行开始 隐藏标签
  185. item.style.display = 'none';
  186. // 显示展开按钮 class名chu是在前面动态添加的
  187. } else {
  188. item.style.display = 'block';
  189. }
  190. } else {
  191. item.style.display = 'block';
  192. }
  193. });
  194. loadingCollapse.value = true;
  195. } catch {
  196. //
  197. }
  198. };
  199. const selectChildObj = (item: any) => {
  200. const obj: any = {};
  201. item?.forEach((child: any) => {
  202. if (child.id === forms.subjectId) {
  203. obj.selected = true;
  204. obj.name = child.name;
  205. }
  206. });
  207. return obj;
  208. };
  209. const _initTags = () => {
  210. const tags = catchStore.getMusicTagTree;
  211. data.tags = [
  212. {
  213. columnName: tags[0].columnName,
  214. name: '全部',
  215. id: ''
  216. },
  217. ...tags
  218. ];
  219. data.tagActiveId = data.tags[0].id;
  220. };
  221. const changeTag = (item: any) => {
  222. data.tagActiveId = item.id;
  223. data.childSelectId = null;
  224. let children: any;
  225. let columnName = '';
  226. if (item.children) {
  227. children = [
  228. {
  229. columnName: item.children[0].columnName,
  230. name: '全部',
  231. id: ''
  232. },
  233. ...item.children
  234. ];
  235. columnName = item.children[0].columnName;
  236. data.selectParents = {
  237. ...item,
  238. columnName,
  239. activeIndex: '',
  240. children
  241. };
  242. } else {
  243. data.selectParents = {};
  244. }
  245. onSearch();
  246. };
  247. onMounted(async () => {
  248. resourceTypeArray.forEach((item: any) => {
  249. resourceType.value.push(item);
  250. });
  251. // // 获取教材分类列表
  252. // await catchStore.getMusicSheetCategory();
  253. await catchStore.getMusicTagTreeApi();
  254. _initTags();
  255. // 获取声部
  256. await catchStore.getSubjects();
  257. forms.subjectId = null;
  258. // 这里开始
  259. // musicCateRef
  260. if (forms.type === 'MUSIC') {
  261. orginHeight.value = collapseWrapRef.value?.offsetHeight;
  262. hiddenHeight.value = collapseWrapRef.value?.offsetHeight / line.value;
  263. // 默认隐藏
  264. getLive();
  265. }
  266. if (props.type === 'shareResources') {
  267. onSearch('timer');
  268. }
  269. });
  270. return () => (
  271. <div class={styles.searchGroup}>
  272. <div class={styles.searchCatatory}>
  273. <NSpace size="small" class={styles.btnType}>
  274. {resourceType.value.map((item: any) => (
  275. <NButton
  276. type={forms.type === item.value ? 'primary' : 'default'}
  277. secondary={forms.type === item.value ? false : true}
  278. round
  279. size="small"
  280. focusable={false}
  281. onClick={() => {
  282. forms.type = item.value;
  283. forms.subjectId = null;
  284. data.tagActiveId = '';
  285. data.childSelectId = null;
  286. data.selectParents = {};
  287. onSearch();
  288. try {
  289. nextTick(() => {
  290. if (forms.type === 'MUSIC') {
  291. orginHeight.value = collapseWrapRef.value?.offsetHeight;
  292. hiddenHeight.value =
  293. collapseWrapRef.value?.offsetHeight / line.value;
  294. // 默认隐藏
  295. getLive();
  296. } else {
  297. divDomList.value = [];
  298. }
  299. });
  300. } catch {
  301. //
  302. }
  303. }}>
  304. {item.label}
  305. </NButton>
  306. ))}
  307. </NSpace>
  308. <TheSearch
  309. class={styles.inputSearch}
  310. round
  311. onSearch={(val: string) => {
  312. forms.name = val;
  313. throttleFn();
  314. }}
  315. />
  316. </div>
  317. <NForm
  318. labelAlign="left"
  319. labelPlacement="left"
  320. class={styles.searchForm}>
  321. {forms.type === 'MUSIC' && props.type === 'shareResources' && (
  322. <>
  323. <NFormItem label={data.tags[0]?.columnName + ':'}>
  324. <NSpace class={styles.spaceSection}>
  325. {data.tags.map((subject: any) => (
  326. <span
  327. class={[
  328. styles.textBtn,
  329. data.tagActiveId === subject.id && styles.textBtnActive
  330. ]}
  331. onClick={() => {
  332. changeTag(subject);
  333. }}>
  334. {subject.name}
  335. </span>
  336. ))}
  337. </NSpace>
  338. </NFormItem>
  339. <ChildNodeSearch
  340. activeRow={data.selectParents}
  341. onSelectChildTag={(val: any) => {
  342. data.childSelectId = val;
  343. onSearch();
  344. }}
  345. />
  346. </>
  347. )}
  348. <NFormItem label="乐器:">
  349. <NSpace class={styles.spaceSection2}>
  350. {/* {catchStore.getSubjectAllList.map((music: any) => (
  351. <NButton
  352. secondary={forms.subjectId === music.id}
  353. quaternary={forms.subjectId !== music.id}
  354. strong
  355. focusable={false}
  356. type={forms.subjectId === music.id ? 'primary' : 'default'}
  357. onClick={() => {
  358. forms.subjectId = music.id;
  359. onSearch();
  360. }}>
  361. {music.name}
  362. </NButton>
  363. ))} */}
  364. {catchStore.getSubjectInstruments.map((subject: any) =>
  365. subject.instruments && subject.instruments.length > 1 ? (
  366. <NPopselect
  367. options={subject.instruments}
  368. trigger="hover"
  369. scrollable
  370. v-model:value={state.tempSubjectId}
  371. onUpdate:value={() => {
  372. forms.subjectId = state.tempSubjectId;
  373. onSearch();
  374. }}
  375. key={subject.value}
  376. class={[styles.popSelect]}>
  377. <span
  378. class={[
  379. styles.textBtn,
  380. selectChildObj(subject.instruments).selected &&
  381. styles.textBtnActive
  382. ]}>
  383. {selectChildObj(subject.instruments).name || subject.name}
  384. <i class={styles.iconArrow}></i>
  385. </span>
  386. </NPopselect>
  387. ) : (
  388. <span
  389. class={[
  390. styles.textBtn,
  391. forms.subjectId === subject.value && styles.textBtnActive
  392. ]}
  393. onClick={() => {
  394. forms.subjectId = subject.value;
  395. state.tempSubjectId = null;
  396. onSearch();
  397. }}>
  398. {subject.name}
  399. </span>
  400. )
  401. )}
  402. </NSpace>
  403. </NFormItem>
  404. </NForm>
  405. </div>
  406. );
  407. }
  408. });