law-case-tree.vue 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. <template>
  2. <div>
  3. <a-spin :spinning="spinningtree" :class="$style.spin" />
  4. <a-empty v-if="empty" />
  5. <a-tree
  6. v-else
  7. :key="key"
  8. ref="caseTree"
  9. v-model="checkedKeys"
  10. :block-node="false"
  11. :show-icon="true"
  12. :show-line="true"
  13. :check-strictly="true"
  14. :checkable="false"
  15. :draggable="false"
  16. :tree-data="treeData"
  17. :replace-fields="replaceFields"
  18. :selected-keys="defaultSelectedKeys"
  19. :expanded-keys="expandedKeys"
  20. :default-expanded-keys="defaultTreeExpandedKeys"
  21. :load-data="onLoadData"
  22. @select="treeSelect"
  23. @check="treeCheck"
  24. @expand="onExpand"
  25. @drop="onDrop"
  26. >
  27. <template v-slot:title="{ text, props }">
  28. <span v-if="text.indexOf(searchValue) > -1">
  29. {{ text.substr(0, text.indexOf(searchValue))
  30. }}<span :class="$style.active">{{ searchValue }}</span
  31. >{{ text.substr(text.indexOf(searchValue) + searchValue.length) }}</span
  32. ><span v-else>{{ text }}</span>
  33. <!-- 后台返回数量,如果有数量的话就显示 -->
  34. <span v-if="props.count > 0">({{ props.count }})</span>
  35. </template>
  36. <!-- 如果已配置负责人,则展示用户图标 -->
  37. <template slot="hasuser" slot-scope="item">
  38. <a-icon type="team" @click="showUser(item)" />
  39. </template>
  40. </a-tree>
  41. <!-- <a-form-model :model="interForm" :label-col="{ span: 7 }" :wrapper-col="{ span: 15 }">
  42. <a-form-model-item label="阶段名称" required>
  43. <a-select v-model="interForm.stageField">
  44. <a-select-option v-for="item in stage" :key="item.code" :value="item.code">
  45. {{ item.name }}
  46. </a-select-option>
  47. </a-select>
  48. </a-form-model-item>
  49. </a-form-model> -->
  50. </div>
  51. </template>
  52. <script>
  53. import { message } from 'ant-design-vue'
  54. import LawService from '../law-service'
  55. import components from './_import-components/law-case-tree-import'
  56. export default {
  57. name: 'LawCaseTree',
  58. metaInfo: {
  59. title: 'LawCaseTree',
  60. },
  61. components,
  62. props: {
  63. // 默认选中节点
  64. caseType: {
  65. type: String,
  66. default: '',
  67. },
  68. caseStage: {
  69. type: String,
  70. default: '',
  71. },
  72. defaultTopNodeText: {
  73. type: String,
  74. default: '案件进展阶段',
  75. },
  76. defaultTopNodeId: {
  77. type: String,
  78. default: '0',
  79. },
  80. },
  81. data() {
  82. return {
  83. empty: false,
  84. spinningtree: true,
  85. treeData: [],
  86. dataList: [], // 数组dataList,搜索要用
  87. defaultTreeExpandedKeys: ['0'],
  88. defaultSelectedKeys: ['0'],
  89. checkedKeys: [], // 选中的节点数据
  90. replaceFields: {
  91. title: 'text',
  92. key: 'ids',
  93. },
  94. expandedKeys: ['0'],
  95. searchValue: '',
  96. searchStr: '',
  97. key: 0,
  98. // 树
  99. }
  100. },
  101. mounted() {
  102. this.initTreeData()
  103. },
  104. methods: {
  105. // 点击地址树展开时调用
  106. onLoadData(treeNode) {
  107. let caseType = ''
  108. let caseStage = ''
  109. if (treeNode.dataRef.props.parentId === 'root') {
  110. caseType = treeNode.dataRef.id
  111. } else {
  112. caseType = treeNode.dataRef.props.parentId
  113. caseStage = treeNode.dataRef.id
  114. }
  115. return LawService.getCaseTree(caseType, caseStage).then((res) => {
  116. if (treeNode.dataRef.id !== '0') {
  117. res.data.forEach((d) => {
  118. d.props.parentName = treeNode.dataRef.text
  119. d.props.caseType = treeNode.dataRef.props.parentId
  120. d.ids = d.id + '_' + treeNode.dataRef.id
  121. })
  122. treeNode.dataRef.children = res.data
  123. this.treeData = this.transformData([...this.treeData])
  124. this.generateList(this.treeData)
  125. }
  126. })
  127. },
  128. // 初始化地址树
  129. initTreeData() {
  130. LawService.getCaseTree(this.caseType, this.caseStage).then((res) => {
  131. this.spinningtree = false
  132. if (res.data.length) {
  133. res.data.forEach((r) => {
  134. r.ids = r.id + '_0'
  135. })
  136. const treeNode = [
  137. {
  138. id: this.caseStage === '' ? this.defaultTopNodeId : this.caseStage,
  139. ids: this.caseStage === '' ? this.defaultTopNodeId : this.caseStage,
  140. text: this.defaultTopNodeText,
  141. leaf: true,
  142. props: {
  143. parentId: this.caseStage === '' ? 'root' : this.caseType,
  144. },
  145. children: res.data,
  146. key: this.defaultTopNodeId,
  147. },
  148. ]
  149. this.treeData = this.transformData(treeNode)
  150. this.expandedKeys = this.defaultTreeExpandedKeys
  151. this.generateList(this.treeData)
  152. this.empty = false
  153. } else {
  154. this.empty = true
  155. }
  156. })
  157. },
  158. transformData(data) {
  159. return data.map((d) => {
  160. const { children, ...rest } = d
  161. return {
  162. ...rest,
  163. children: children && this.transformData(children),
  164. scopedSlots: { title: 'title' },
  165. }
  166. })
  167. },
  168. // 处理搜索用的dataList
  169. generateList(data) {
  170. for (let i = 0; i < data.length; i++) {
  171. const node = data[i]
  172. const key = node.id
  173. const title = node.text
  174. const props = node.props
  175. this.dataList.push({ key, id: key, title: title, props })
  176. if (node.children) {
  177. this.generateList(node.children)
  178. }
  179. }
  180. },
  181. // 点击树
  182. treeSelect(selectedKeys, info) {
  183. this.defaultSelectedKeys = selectedKeys
  184. this.$emit('treeSelect', [...selectedKeys], info)
  185. },
  186. /***
  187. * 选中复选框时的事件
  188. */
  189. treeCheck(allKeys, echecked) {
  190. // echecked.checkedNodes 选中的所有节点信息为数组 .data.props 获取详细信息
  191. // echecked.node.dataRef 当前选中的节点信息
  192. if (this.single) {
  193. this.checkedKeys.checked = []
  194. this.checkedKeys.checked = [echecked.node.dataRef.id]
  195. }
  196. this.$emit('checkedKeys', echecked.node.dataRef, echecked.checkedNodes)
  197. },
  198. onExpand(expandedKeys) {
  199. // 用户点击展开时,取消自动展开效果
  200. this.expandedKeys = expandedKeys
  201. this.autoExpandParent = false
  202. },
  203. // 拖拽节点方法
  204. onDrop(info) {
  205. // 被插入节点信息
  206. const dropKey = info.node.eventKey
  207. const dropNode = info.node.dataRef
  208. // 拖拽节点信息
  209. const dragKey = info.dragNode.eventKey
  210. const dragNode = info.dragNode.dataRef
  211. const dropPos = info.node.pos.split('-')
  212. // -1表示之前 0表示合并 1表示之后
  213. const dropPosition = info.dropPosition - Number(dropPos[dropPos.length - 1])
  214. // 分类合并至事项内
  215. if (dropNode.props.isroot && (dropPosition === 1) | (dropPosition === -1)) {
  216. message.info('不能将分类拖拽至与根节点同层级', 1)
  217. return false
  218. }
  219. // 如果被插入节点是末级节点,并且是合并方式的时候,则不可以执行
  220. if (dropPosition === 0) {
  221. if (dropNode.props.isEnd === '1') {
  222. message.info('被插入节点是末级节点,不可执行', 1)
  223. return false
  224. }
  225. }
  226. const loop = (data, key, callback) => {
  227. data.forEach((item, index, arr) => {
  228. if (item.id === key) {
  229. return callback(item, index, arr)
  230. }
  231. if (item.children) {
  232. return loop(item.children, key, callback)
  233. }
  234. })
  235. }
  236. const data = this.treeData
  237. // Find dragObject
  238. let dragObj
  239. loop(data, dragKey, (item, index, arr) => {
  240. arr.splice(index, 1)
  241. dragObj = item
  242. })
  243. if (!info.dropToGap) {
  244. // Drop on the content
  245. loop(data, dropKey, (item) => {
  246. item.children = item.children || []
  247. // where to insert 示例添加到尾部,可以是随意位置
  248. item.children.push(dragObj)
  249. })
  250. } else if (
  251. (info.node.children || []).length > 0 && // Has children
  252. info.node.expanded && // Is expanded
  253. dropPosition === 1 // On the bottom gap
  254. ) {
  255. loop(data, dropKey, (item) => {
  256. item.children = item.children || []
  257. // where to insert 示例添加到尾部,可以是随意位置
  258. item.children.unshift(dragObj)
  259. })
  260. } else {
  261. let ar
  262. let i
  263. loop(data, dropKey, (item, index, arr) => {
  264. ar = arr
  265. i = index
  266. })
  267. if (dropPosition === -1) {
  268. ar.splice(i, 0, dragObj)
  269. } else {
  270. ar.splice(i + 1, 0, dragObj)
  271. }
  272. }
  273. this.treeData = data
  274. // 拖拽完成,调用接口
  275. const dragParams = {
  276. nodeId: dragNode.id,
  277. targetnodeType: dropNode.props.isroot ? 'root' : 'category', // category/root
  278. targetnodeId: dropNode.id,
  279. position: dropPosition, // -1 0 1 之前 合并 之后
  280. }
  281. LawService.dragNode(dragParams).then((res) => {
  282. if (!res) {
  283. message.info(dropNode.text + '节点下存在相同分类编号,拖拽失败')
  284. }
  285. })
  286. },
  287. },
  288. }
  289. </script>
  290. <style module lang="scss">
  291. @use '@/common/design' as *;
  292. </style>