left-tree.vue 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. <template>
  2. <div class="jbd-tree">
  3. <ibps-tree
  4. ref="treeIndex"
  5. :title="title"
  6. :width="width"
  7. :height="height"
  8. :data="treeData"
  9. :location="location"
  10. :options="treeOptions"
  11. :contextmenus="hasContextmenu ? treeContextmenus : []"
  12. :position="position"
  13. :has-permission="hasPermission"
  14. :category-key="categoryKey"
  15. @action-event="handleTreeAction"
  16. @node-click="handleNodeClick"
  17. @expand-collapse="handleExpandCollapse"
  18. />
  19. </div>
  20. </template>
  21. <script>
  22. import { findTreeData, remove } from '@/api/platform/cat/type'
  23. import ActionUtils from '@/utils/action'
  24. import TypeEdit from '@/views/platform/cat/type/edit'
  25. import TypeSort from '@/views/platform/cat/type/sort'
  26. import TypeMove from '@/views/platform/cat/type/move'
  27. export default {
  28. components: {
  29. TypeEdit,
  30. TypeSort,
  31. TypeMove
  32. },
  33. props: {
  34. title: {
  35. type: String
  36. },
  37. location: {
  38. type: String,
  39. default: 'initial'
  40. },
  41. categoryKey: {
  42. type: String,
  43. required: true
  44. },
  45. hasContextmenu: {
  46. // 是否有右键菜单
  47. type: Boolean,
  48. default: false
  49. },
  50. width: {
  51. type: [String, Number],
  52. default: 200
  53. },
  54. height: {
  55. type: [String, Number],
  56. default: 500
  57. },
  58. position: {
  59. type: String,
  60. default: 'west'
  61. },
  62. hasPermission: {
  63. // 是否有权限控制
  64. type: Boolean,
  65. default: true
  66. }
  67. },
  68. data() {
  69. return {
  70. typeFormVisible: false,
  71. sortFormVisible: false,
  72. moveFormVisible: false,
  73. editId: '', // 编辑dialog需要使用
  74. editTitle: '编辑分类',
  75. // 树配置
  76. treeOptions: { rootPId: '-1' },
  77. treeContextmenus: [
  78. { icon: 'add', label: '添加分类', value: 'add' },
  79. { icon: 'edit', label: '编辑分类', value: 'edit', rights: ['node'] },
  80. {
  81. icon: 'delete',
  82. label: '删除分类',
  83. value: 'remove',
  84. rights: ['node']
  85. },
  86. { type: 'divided' },
  87. { icon: 'sort', label: '分类排序', value: 'sort' },
  88. {
  89. icon: 'arrows-v',
  90. label: '移动节点',
  91. value: 'moveNode',
  92. rights: ['node']
  93. }
  94. ],
  95. treeData: [],
  96. isPrivate: false,
  97. typeData: {} // 记录分类信息
  98. }
  99. },
  100. created() {
  101. this.loadTreeData()
  102. },
  103. methods: {
  104. loadTreeData() {
  105. const { first = '', second = '' } = this.$store.getters.level || {}
  106. const params = { categoryKey: this.categoryKey }
  107. if (this.categoryKey === 'FILE_TYPE') {
  108. params.diDian = second || first
  109. }
  110. this.$common
  111. .request('query', {
  112. key: 'tkcx',
  113. params: [null]
  114. })
  115. .then((res) => {
  116. const data = res.variables.data || []
  117. data.sort((a, b) => a.tenant_id_ - b.tenant_id_)
  118. const treeData = data.map((t) => ({
  119. name: t.name_ || t.tiao_kuan_hao_ + t.tiao_kuan_jian_ch,
  120. parentId: t.parent_id_,
  121. id: t.id_,
  122. tiaoKuanHao: t.tiao_kuan_hao_,
  123. tiaoKuanJianCheng: t.tiao_kuan_jian_ch,
  124. ...t
  125. }))
  126. const findFaterTree = this.findFaterTree(treeData)
  127. if (!data.some((t) => t.parentId === '-1')) {
  128. treeData.push({
  129. name: '任务分类',
  130. id: findFaterTree[0] ? findFaterTree[0].parentId : '-1',
  131. parentId: '-1'
  132. })
  133. }
  134. console.log('treeData===>', treeData)
  135. this.$emit('treeData', treeData)
  136. this.treeData = treeData
  137. })
  138. // findTreeData(params).then((response) => {
  139. // this.treeData = response.data || []
  140. // if (this.hasPermission) {
  141. // this.treeData = this.treeData.filter((i) => i.isShow !== '1')
  142. // }
  143. // // 按照分类过滤
  144. // const routeName = this.$route.name
  145. // const routeMap = {
  146. // jssllb: '体系分类',
  147. // ywtxyxjl: '模板分类',
  148. // 'wjkzgl-ywyxjlsc': '模板分类'
  149. // }
  150. // this.treeData = this.treeData.filter((i) => {
  151. // const authorityName = JSON.parse(i.authorityName)
  152. // if (authorityName) {
  153. // if (authorityName.fenLei) {
  154. // return (
  155. // authorityName.fenLei === routeMap[routeName] ||
  156. // authorityName.fenLei === '通用'
  157. // )
  158. // } else {
  159. // return true
  160. // }
  161. // }
  162. // return true
  163. // })
  164. // console.log('response.data===>', response.data)
  165. // this.$emit('treeData', response.data)
  166. // })
  167. },
  168. findFaterTree(treeData) {
  169. // 第一步:收集所有节点的id(用于判断父级是否存在)​
  170. const allIds = new Set()
  171. treeData.forEach((item) => {
  172. if (item.id !== null && item.id !== '') {
  173. allIds.add(item.id)
  174. }
  175. })
  176. // 第二步:筛选“parentId不在allIds中”的节点(父级不存在,即最上级)​
  177. const topLevelData = treeData.filter((item) => {
  178. // 若parentId为null/undefined/空字符串,视为无父级(最上级)​
  179. if (!item.parentId) {
  180. return true
  181. }
  182. // 若parentId存在,但不在allIds中(父级不存在,即最上级)​
  183. return !allIds.has(item.parentId)
  184. })
  185. return topLevelData
  186. },
  187. handleTreeAction(command, position, selection, data) {
  188. switch (command) {
  189. case 'refresh': // 查询
  190. this.loadTreeData()
  191. break
  192. case 'add': // 添加
  193. this.typeData = data // { 'name': data.name, 'id': data.id }
  194. this.isPrivate = false
  195. this.editTitle = '添加分类'
  196. this.handTreeEdit()
  197. break
  198. case 'addPrivate': // 添加
  199. this.typeData = data // { 'name': data.name, 'id': data.id }
  200. this.isPrivate = true
  201. this.editTitle = '添加私有分类'
  202. this.handTreeEdit()
  203. break
  204. case 'edit': // 编辑
  205. this.typeData = data
  206. this.isPrivate = true
  207. this.editTitle = '编辑分类'
  208. this.handTreeEdit(data.id)
  209. break
  210. case 'moveNode': // 移动节点
  211. this.typeData = data
  212. this.isPrivate = true
  213. this.editTitle = '移动节点'
  214. this.handTreeMove(data.id)
  215. break
  216. case 'remove': // 删除
  217. this.handleTreeRemove(data.id)
  218. break
  219. case 'export': // 导出
  220. this.handTreeExport(data.id, data.name)
  221. break
  222. case 'sort': // 排序
  223. this.handTreeSort(data)
  224. break
  225. }
  226. },
  227. handleNodeClick(data) {
  228. this.$emit(
  229. 'node-click',
  230. data.parentId === '-1' ? '' : data.id,
  231. data,
  232. this.treeData
  233. )
  234. },
  235. handleExpandCollapse(isExpand) {
  236. this.$emit('expand-collapse', isExpand)
  237. },
  238. handTreeEdit(editId) {
  239. this.editId = editId || ''
  240. this.typeFormVisible = true
  241. },
  242. handTreeMove(editId) {
  243. this.editId = editId || ''
  244. this.moveFormVisible = true
  245. },
  246. handTreeSort(data) {
  247. const children = data.children
  248. if (children && children.length > 0) {
  249. if (children.length === 1) {
  250. ActionUtils.warning('只有一个节点无需排序')
  251. } else {
  252. this.editId = data.id || ''
  253. this.sortFormVisible = true
  254. }
  255. } else {
  256. ActionUtils.warning('无子节点排序')
  257. }
  258. },
  259. handleTreeRemove(ids) {
  260. ActionUtils.removeRecord(ids)
  261. .then((ids) => {
  262. remove({ typeId: ids })
  263. .then((response) => {
  264. ActionUtils.removeSuccessMessage()
  265. this.loadTreeData()
  266. })
  267. .catch((err) => {
  268. console.error(err)
  269. })
  270. })
  271. .catch(() => {})
  272. },
  273. showTree() {
  274. this.$nextTick(() => {
  275. this.$refs.treeIndex.handleExpandCollapse()
  276. })
  277. }
  278. }
  279. }
  280. </script>
  281. <style>
  282. /* .jbd-tree .el-tree > .el-tree-node > .el-tree-node__content {
  283. display: none;
  284. } */
  285. </style>