search-group-resources.tsx 14 KB

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