ClassifyWrap.vue 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. <script setup>
  2. import { reactive, ref, watch } from 'vue'
  3. import { SearchIcon, Icon } from 'tdesign-icons-vue-next';
  4. import { apiETAChart } from '@/api/etaChart'
  5. import { apiSystemCommon } from '@/api/system'
  6. import { useClassify } from '../hooks/useClassify'
  7. const emits = defineEmits(['change', 'filter'])
  8. const userProps = {
  9. label: 'RealName',
  10. value: 'AdminId',
  11. children: 'ChildrenList'
  12. }
  13. const userOpts = ref([])
  14. const { userVal } = useClassify()
  15. async function getCompanyUserData() {
  16. const res = await apiSystemCommon.companyUserList()
  17. if (res.Ret === 200) {
  18. userOpts.value = res.Data.List || []
  19. }
  20. }
  21. getCompanyUserData()
  22. watch(
  23. ()=>userVal.value,
  24. (n)=>{
  25. emits('filter')
  26. getClassify()
  27. }
  28. )
  29. // 2024-4-26 目前组件库change事件有bug会触发多次
  30. // function handleUserChange(value,context) {
  31. // emits('filter')
  32. // getClassify()
  33. // }
  34. const searchSelectKeys = {
  35. value: 'ChartInfoId',
  36. label: 'ChartName'
  37. }
  38. const searchVal = ref('')
  39. const searchOpts = ref([])
  40. const searchLoading = ref(false)
  41. let searchPage = 1
  42. const searchPageSize = 20
  43. let finished = false
  44. function handleSearchChart(keyword) {
  45. finished = false
  46. searchPage = 1
  47. searchOpts.value = []
  48. handleGetSearchChartList(keyword)
  49. }
  50. async function handleGetSearchChartList(keyword) {
  51. searchLoading.value = true
  52. const res = await apiETAChart.chartSearch({
  53. PageSize: searchPageSize,
  54. CurrentIndex: searchPage,
  55. SysUserIds: userVal.value?.join(','),
  56. Keyword: keyword
  57. })
  58. searchLoading.value = false
  59. if (res.Ret === 200) {
  60. const arr = res.Data.List || []
  61. searchOpts.value = [...searchOpts.value, ...arr]
  62. finished = res.Data.Paging.IsEnd
  63. }
  64. }
  65. async function handleLoadMoreChart() {
  66. if (finished || searchLoading.value) return
  67. handleGetSearchChartList()
  68. }
  69. function handleSelectChart(value, context) {
  70. if (value) {
  71. emits('change', context.option)
  72. }
  73. }
  74. //分类列表
  75. const classifyTreeKeys = {
  76. label: 'ChartClassifyName',
  77. children: 'Children',
  78. value: 'ChartClassifyId'
  79. }
  80. const classifyList = ref([])
  81. const { classifyActived } = useClassify()
  82. async function getClassify() {
  83. const res = await apiETAChart.classifyList({
  84. ParentId: -1,
  85. SysUserIds: userVal.value?.join(',')
  86. })
  87. if (res.Ret === 200) {
  88. const arr = res.Data.AllNodes || []
  89. classifyList.value = arr.map(item => {
  90. return {
  91. ...item,
  92. Children: true
  93. }
  94. })
  95. }
  96. }
  97. getClassify()
  98. // 懒加载分类
  99. async function classifyLoad(node) {
  100. return new Promise(async (resolve) => {
  101. let nodes = []
  102. const res = await apiETAChart.classifyList({
  103. ParentId: node.data.ChartClassifyId,
  104. SysUserIds: userVal.value?.join(',')
  105. })
  106. if (res.Ret === 200) {
  107. const arr = res.Data.AllNodes || []
  108. nodes = arr.map(item => {
  109. return {
  110. ...item,
  111. Children: item.ChartInfoId ? [] : true,
  112. ChartClassifyId: item.ChartInfoId ? item.UniqueCode : item.ChartClassifyId,//如果是指标则将分类id设置为图表UniqueCode
  113. }
  114. })
  115. }
  116. resolve(nodes);
  117. });
  118. }
  119. //点击目录树
  120. function handleClassifyActiveChange({ node }) {
  121. classifyActived.value = [node.data.ChartClassifyId]
  122. if (node.data.ChartInfoId) {//选择的是图表
  123. emits('change', node.data)
  124. } else {
  125. emits('filter')
  126. }
  127. }
  128. </script>
  129. <template>
  130. <div class="bg-white classify-wrap">
  131. <div class="select-wrap">
  132. <t-cascader
  133. v-model="userVal"
  134. :options="userOpts"
  135. :keys="userProps"
  136. multiple
  137. :minCollapsedNum="1"
  138. clearable
  139. filterable
  140. :showAllLevels="false"
  141. placeholder="创建人"
  142. />
  143. </div>
  144. <t-select
  145. v-model="searchVal"
  146. placeholder="请输入图表名称"
  147. clearable
  148. filterable
  149. :keys="searchSelectKeys"
  150. :options="searchOpts"
  151. :loading="searchLoading"
  152. @search="handleSearchChart"
  153. @change="handleSelectChart"
  154. :popup-props="{ 'on-scroll-to-bottom': handleLoadMoreChart }"
  155. >
  156. <template #prefixIcon>
  157. <search-icon />
  158. </template>
  159. </t-select>
  160. <div class="classify-list-box">
  161. <t-tree
  162. :actived="classifyActived"
  163. :data="classifyList"
  164. activable
  165. transition
  166. lazy
  167. :load="classifyLoad"
  168. value-mode="all"
  169. :keys="classifyTreeKeys"
  170. check-strictly
  171. :onClick="handleClassifyActiveChange"
  172. >
  173. <template #icon="{ node }">
  174. <t-icon
  175. name="add-rectangle"
  176. v-if="node.getChildren() && !node.expanded"
  177. />
  178. <t-icon
  179. name="minus-rectangle"
  180. v-if="node.getChildren() && node.expanded"
  181. />
  182. </template>
  183. </t-tree>
  184. </div>
  185. </div>
  186. </template>
  187. <style lang="scss" scoped>
  188. .classify-wrap {
  189. width: 300px;
  190. flex-shrink: 0;
  191. padding: 20px;
  192. .select-wrap {
  193. display: flex;
  194. gap: 0 10px;
  195. margin-bottom: 10px;
  196. }
  197. .classify-list-box {
  198. padding-top: 10px;
  199. height: calc(100vh - 260px);
  200. overflow-y: auto;
  201. }
  202. }
  203. </style>