position-select.js 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. import { ref, computed, getCurrentInstance } from 'vue';
  2. import { onLoad, onReady } from '@dcloudio/uni-app';
  3. import { listIndustry, listIndustrySkill } from '../../api/systemIndustry';
  4. export default {
  5. setup() {
  6. const searchQuery = ref('');
  7. const activeIndex = ref(0);
  8. const scrollIntoId = ref('category-0');
  9. const currentSelected = ref('');
  10. let sectionHeights = [];
  11. let isClickScrolling = false;
  12. let clickTimer = null;
  13. const instance = getCurrentInstance();
  14. const positionData = ref([]);
  15. const loadData = async (selectedVal) => {
  16. try {
  17. uni.showLoading({ title: '加载中...' });
  18. const [indRes, skillRes] = await Promise.all([
  19. listIndustry(),
  20. listIndustrySkill()
  21. ]);
  22. if (indRes.code === 200 && skillRes.code === 200) {
  23. const industries = indRes.rows || indRes.data || [];
  24. const skills = skillRes.rows || skillRes.data || [];
  25. // Level 1: parentId = 0
  26. const level1 = industries.filter(i => i.parentId == 0 || !i.parentId);
  27. const result = level1.map(l1 => {
  28. // Level 2: parentId = l1.industryId
  29. const level2 = industries.filter(i => i.parentId == l1.industryId);
  30. const sections = level2.map(l2 => {
  31. // Level 3: skill.industryId = l2.industryId
  32. const level3 = skills
  33. .filter(s => s.industryId == l2.industryId)
  34. .map(s => s.skillName);
  35. return {
  36. name: l2.industryName,
  37. id: l2.industryId,
  38. children: level3
  39. };
  40. });
  41. // 过滤掉没下级节点的(可选)
  42. return {
  43. name: l1.industryName,
  44. id: l1.industryId,
  45. sections: sections
  46. };
  47. });
  48. positionData.value = result;
  49. // 计算回显
  50. if (selectedVal) {
  51. for (let i = 0; i < result.length; i++) {
  52. let found = false;
  53. for (let j = 0; j < result[i].sections.length; j++) {
  54. if (result[i].sections[j].children.includes(selectedVal)) {
  55. activeIndex.value = i;
  56. scrollIntoId.value = 'category-' + i;
  57. found = true;
  58. break;
  59. }
  60. }
  61. if (found) break;
  62. }
  63. }
  64. setTimeout(() => {
  65. calculateSectionHeights();
  66. }, 500);
  67. }
  68. } catch (e) {
  69. console.error('加载职位结构失败', e);
  70. uni.showToast({ title: '加载职位失败', icon: 'none' });
  71. } finally {
  72. uni.hideLoading();
  73. }
  74. };
  75. const searchResults = computed(() => {
  76. if (!searchQuery.value) return [];
  77. const q = searchQuery.value.toLowerCase();
  78. const results = [];
  79. positionData.value.forEach(l1 => {
  80. l1.sections.forEach(l2 => {
  81. l2.children.forEach(pos => {
  82. if (pos.toLowerCase().includes(q)) {
  83. results.push(pos);
  84. }
  85. });
  86. });
  87. });
  88. return results;
  89. });
  90. onLoad((options) => {
  91. let selectedParam = '';
  92. if (options && options.selected) {
  93. currentSelected.value = decodeURIComponent(options.selected);
  94. selectedParam = currentSelected.value;
  95. }
  96. uni.setNavigationBarTitle({ title: '选择职位名称' });
  97. loadData(selectedParam);
  98. });
  99. const calculateSectionHeights = () => {
  100. const query = uni.createSelectorQuery().in(instance.proxy);
  101. query.selectAll('.category-wrapper').boundingClientRect(rects => {
  102. if (rects && rects.length > 0) {
  103. let currentTop = 0;
  104. sectionHeights = rects.map(r => {
  105. let top = currentTop;
  106. currentTop += r.height;
  107. return top;
  108. });
  109. }
  110. }).exec();
  111. };
  112. const onRightScroll = (e) => {
  113. if (isClickScrolling || sectionHeights.length === 0) return;
  114. const scrollTop = e.detail.scrollTop;
  115. let currentIndex = 0;
  116. for (let i = 0; i < sectionHeights.length; i++) {
  117. if (scrollTop >= sectionHeights[i] - 15) {
  118. currentIndex = i;
  119. } else {
  120. break;
  121. }
  122. }
  123. if (activeIndex.value !== currentIndex) {
  124. activeIndex.value = currentIndex;
  125. }
  126. };
  127. const selectMenu = (index) => {
  128. activeIndex.value = index;
  129. scrollIntoId.value = 'category-' + index;
  130. isClickScrolling = true;
  131. clearTimeout(clickTimer);
  132. clickTimer = setTimeout(() => {
  133. isClickScrolling = false;
  134. }, 600);
  135. };
  136. const selectPosition = (posName) => {
  137. uni.$emit('select_position', posName);
  138. uni.navigateBack();
  139. };
  140. return {
  141. searchQuery,
  142. activeIndex,
  143. scrollIntoId,
  144. currentSelected,
  145. positionData,
  146. searchResults,
  147. selectMenu,
  148. selectPosition,
  149. onRightScroll
  150. };
  151. }
  152. }