赞
踩
- <el-tree
- :data="treeData"
- node-key="id"
- default-expand-all
- :expand-on-click-node="false"
- @node-drop="handleDrop"
- @node-drag-enter="nodeDragEnter"
- draggable
- :allow-drop="allowDrop"
- :allow-drag="allowDrag"
- >
- <span class="custom-tree-node" :class="{isDisabled: node.data.enabled === false}" slot-scope="{ node, data }" :key="data.id">
- <template v-if="!node.data.isEdit">
- <el-tooltip class="item" effect="light" :content="node.data.knowledgeName" :open-delay="1000" placement="bottom">
- <span class="label" v-if="node.data.enabled" @dblclick="nodeClick(data,node,true)">{{ node.data.knowledgeName }}</span>
- <span class="label isDisabled" v-else-if="node.data.id && !node.data.enabled" @dblclick="nodeClick(data,node,true)">{{ "(已禁用)" + node.data.knowledgeName }}</span>
- </el-tooltip>
- </template>
- <span class="knowledgeCode" v-else-if="node.data.isEdit && hasAuth('knowledge_points_system_edit')">
- <el-input v-model.trim="knowledgeCode" placeholder="请输入知识点code" v-focus />
- <el-button size="mini" type="primary" :disabled="!knowledgeCode" @click="addKnoeledgeCode(node,data)">确 定</el-button>
- <el-button size="mini" @click="nodeClick(data,node,false)">取 消</el-button>
- </span>
- <span class="operation" v-show="!node.data.isEdit">
- <el-button type="text" class="btn" :disabled="!canStatusChange || !node.data.id" @click="insertAfter(data, node)" style="color: #333">
- 添加同级
- </el-button>
- <span>|</span>
- <el-button type="text" class="btn" :disabled="!canStatusChange || !node.data.id" @click="append(data, node)" style="color: #333">
- 添加下级
- </el-button>
- <span>|</span>
- <el-button type="text" class="btn" :disabled="!node.data.id" @click="toDetail(data)" style="color: #333">
- 查看详情
- </el-button>
- <span>|</span>
- <el-button type="text" class="btn" :disabled="!node.data.id" @click="remove(node, data)" style="color: #333">
- 删除
- </el-button>
- </span>
- </span>
- </el-tree>
-
- <script>
- import { debounce } from '@/utils/comUtil'
- export default {
- name: 'systemTreeItem',
- data() {
- return {
- knowledgeCode: '',
- }
- },
- props: {
- treeData: Array,
- canStatusChange: Boolean
- },
- directives: {
- focus: {
- inserted: function(el) {
- el.querySelector("input").focus();
- }
- }
- },
- methods: {
- addKnoeledgeCode(node,data){
- this.$emit('addKnoeledgeCode',node,data,this.knowledgeCode)
- this.knowledgeCode = ""
- },
- // 拖拽成功完成时触发的事件
- handleDrop(draggingNode, dropNode, dropType, e) {
- this.$emit('handleDrop', draggingNode, dropNode, dropType, e)
- },
- // 获取总层级数
- getTotalLevel(node, arr) {
- if (node.childNodes && node.childNodes.length) {
- node.childNodes.forEach(item => {
- arr.push(item.level)
- if(item.childNodes && node.childNodes.length) {
- this.getTotalLevel(item, arr)
- }
- })
- }else{
- arr.push(node.level)
- }
- },
- // 拖拽进入其他节点时触发的事件
- nodeDragEnter(draggingNode, dropNode){
- // console.log("拖拽进入其他节点时触发的事件",draggingNode, dropNode)
- let arr = []
- this.getTotalLevel(draggingNode, arr)
- const totalLevel = Math.max(...arr) - draggingNode.level + 1 + dropNode.level
- if(totalLevel <= 8) return
- this.banMessag();
- arr = []
- },
- banMessag: debounce(function(){
- this.$message({
- type: 'warning',
- message: '节点层级已达最大值!',
- })
- },500),
- // 拖拽时判定目标节点能否被放置
- allowDrop(draggingNode, dropNode, type) {
- //draggingNode 被拖拽的节点
- //dropNode 目标节点
- //type 参数有三种情况:'prev'、'inner' 和 'next',分别表示放置在目标节点前、插入至目标节点和放置在目标节点后
- // console.log(draggingNode.level, dropNode.level, type)
- // 获取被拖拽的节点层级
- let arr = []
- this.getTotalLevel(draggingNode, arr)
- const totalLevel = Math.max(...arr) - draggingNode.level + 1 + dropNode.level
- // 插入至目标节点内部 节点层级大于8级 不能被放置
- if(totalLevel > 8){
- this.banMessag();
- arr = []
- return false
- }else{
- return true;
- }
- },
- // 判断节点能否被拖拽
- allowDrag(draggingNode) {
- // console.log("allowDrag", draggingNode)
- // 节点处于编辑状态 或者 节点为空节点 不能拖拽
- if(draggingNode.data.isEdit || !draggingNode.data.id){
- return false
- }else{
- return true
- }
- },
- // 节点双击事件 节点变为可编辑状态
- nodeClick(data, node, isEdit) {
- if(isEdit === false){
- this.knowledgeCode = ""
- }
- this.$emit('nodeClick', data, node, isEdit)
- },
- // 添加同级
- insertAfter(data, refNode) {
- this.$emit('insertAfter', data, refNode)
- },
- // 添加下级
- append(data, parentNode) {
- this.$emit('append', data, parentNode)
- },
- toDetail(data) {
- this.$emit('toDetail', data)
- },
- remove(node, data) {
- this.$emit('remove', node, data)
- },
- },
- }
- </script>
拖拽涉及代码是:handleDrop
- <system-tree-item
- :treeData="systemTreeList"
- :canStatusChange="canStatusChange"
- @handleDrop="handleDrop"
- @nodeClick="nodeClick"
- @insertAfter="insertAfter"
- @append="append"
- @toDetail="toDetail"
- @remove="remove"
- @addKnoeledgeCode="addKnoeledgeCode"
- />
- <script>
- import systemTreeService from '@/api/systemTreeService'
- import SystemTreeItem from './components/SystemTreeItem.vue'
- export default {
- name: 'SystemTree',
- components: { SystemTreeItem },
- data() {
- return {
- systemTreeList: [], // 体系树列表
- list: [], // 备份体系树列表数据
- canStatusChange: false //禁用/启用是否可切换 体系树无数据,节点处于编辑状态,节点无id 为false
- }
- },
- created() {
- this.getSystemTreeList()
- },
- methods: {
- // 体系树数据排序
- sortTreeData(arr){
- if(!arr.length) return
- arr.sort((a,b) => a.sort - b.sort)
- arr.forEach(item => {
- if(item.children){
- this.sortTreeData(item.children)
- }
- })
- },
- // 获取体系树列表
- async getSystemTreeList(type) {
- if(!this.systemCode) return
- if (type === 'add') {
- this.systemTreeList = [
- {
- id: '',
- knowledgeCode: '',
- knowledgeName: '',
- parentId: 'ROOT',
- level: 1,
- systemCode: this.systemCode,
- isEdit: true,
- enabled: true,
- children: []
- },
- ]
- } else {
- let res = await systemTreeService.getSystemTreeList({ systemCode: this.systemCode })
- if (res && res.errorCode === 0) {
- this.systemTreeList = res.result // 后端返回的数据为树状结构
- this.sortTreeData(this.systemTreeList)
- // 备份原数据 拖拽失败后还原
- this.list = JSON.parse(JSON.stringify(this.systemTreeList))
- if(this.systemTreeList.length){
- this.canStatusChange = true
- }else{
- this.systemTreeList = [
- {
- id: '',
- knowledgeCode: '',
- knowledgeName: '',
- parentId: 'ROOT',
- level: 1,
- systemCode: this.systemCode,
- isEdit: true,
- enabled: true,
- children: []
- },
- ]
- this.canStatusChange = false
- }
- } else {
- this.systemTreeList = []
- this.canStatusChange = false
- }
- }
- },
- // 添加知识点
- async addKnoeledgeCode(node, data, knowledgeCode) {
- // console.log("添加知识点", node, data)
- node.data.isEdit = false
- data.isEdit = false
- if (knowledgeCode) {
- if(data.id){
- // 替换
- // 如果knowledgeCode等于oldKnowledgeCode
- let oldKnowledgeCode = data.knowledgeCode
- if(knowledgeCode === oldKnowledgeCode){
- this.$message({
- type: 'warning',
- message: '当前knowledgeCode与旧knowledgeCode相同,不能替换!'
- })
- return
- }
- let params = {
- systemCode: this.systemCode,
- nodeId: data.id,
- oldKnowledgeCode,
- newKnowledgeCode: knowledgeCode,
- }
- let res = await systemTreeService.updateKnowledgePoint(params)
- if (res && res.errorCode === 0) {
- this.$message({
- type: 'success',
- message: res.errorInfo,
- })
- }
- }else{
- // 新增 添加同级 添加下级
- // 添加同级 若为一级节点 nodeParentId 为 "", 否则为node.parent.data.id
- let nodeParentId = node.level === 1 ? "" : node.parent.data.id
- let params = {
- systemCode: this.systemCode,
- knowledgeCode,
- nodeParentId,
- }
- let res = await systemTreeService.addKnowledgePoint(params)
- if (res && res.errorCode === 0) {
- this.$message({
- type: 'success',
- message: res.errorInfo,
- })
- }
- }
- this.getSystemTreeList()
- }
- },
- // 拖拽事件
- async handleDrop(draggingNode, dropNode, dropType,e) {
- //draggingNode 被拖拽的节点
- //dropNode 目标节点
- //dropType 类型 被拖拽的节点相对于目标节点的位置 inner before after
- // console.log('tree drop', draggingNode, dropNode, dropType)
- // 难点在于获取受影响的节点,然后遍历,后端根据节点ID修改父节点ID以及sort
- let paramData = [];
- // 当拖拽类型不为inner,同级排序,寻找目标节点的父ID,获取其对象以及所有的子节点
- // 当拖拽类型为inner,说明拖拽节点成为了目标节点的子节点,只需获取目标节点对象
- let data = dropType != "inner" ? dropNode.parent.data : dropNode.data;
- //目标节点为一级节点,并且拖拽类型不为inner即当前节点将成为与目标节点同一级的节点,也是一级节点
- //nodeData=dropNode.parent.data,但是因为目标节点已经是一级节点了,因此nodeData还是目标节点
- //目标节点为一级节点,并且拖拽类型为inner即当前节点将成为目标节点的子节点即二级节点
- //nodeDate=dropNode.parent.data.children,即为目标节点的父节点的子节点,即目标节点同一层级的节点
- //目标节点不是一级节点,并且拖拽类型不为inner即当前节点将成为与目标节点同一层级的节点
- //nodeDate=dropNode.parent.data.children,即为目标节点的父节点的子节点,即目标节点同一层级的节点
- //目标节点不是一级节点,并且拖拽类型为inner即当前节点将成为目标节的子节点
- //nodeDate=dropNode.data.children,即目标节点的子节点
- let nodeData = dropNode.level == 1 && dropType != "inner" ? data : data.children;
- let nodeParentId = ""
- nodeData.forEach((item, i) => {
- if(dropType != "inner"){
- if(draggingNode.data.parentId === dropNode.data.parentId){
- nodeParentId = item.parentId
- }else{
- nodeParentId = dropNode.data.parentId
- }
- }else{
- nodeParentId = data.id
- }
- let collection = {
- nodeId: item.id,
- nodeParentId,
- sort: i + 1
- };
- paramData.push(collection);
- });
- // console.log(paramData)
- let params = {
- systemCode: this.systemCode,
- nodeSortList: paramData
- }
- let res = await systemTreeService.dragTreeNode(params)
- if(res && res.errorCode === 0){
- this.$message({
- type: 'success',
- message: res.errorInfo,
- })
- this.getSystemTreeList()
- }else{
- // 接口报错之后,将数据恢复
- this.systemTreeList = this.list
- }
- },
- // 节点双击事件
- nodeClick(data, node, isEdit) {
- // console.log("nodeClick",data,node,isEdit)
- // 当节点处于编辑状态 或者 节点id不存在
- if(isEdit || !data.id){
- this.canStatusChange = false
- }else{
- this.canStatusChange = true
- }
- this.$set(data,'isEdit',isEdit)
- this.$set(node.data,'isEdit',isEdit)
- },
- // 添加同级
- insertAfter(data, refNode) {
- // console.log("添加同级", data, refNode)
- const newNode = {
- parentId: data.parentId,
- id: '',
- knowledgeCode: '',
- knowledgeName: '',
- level: data.level,
- systemCode: this.systemCode,
- isEdit: true,
- enabled: true,
- children: [],
- }
- this.canStatusChange = false
- if(data.parentId === 'ROOT'){
- refNode.parent.data.push(newNode)
- }else{
- refNode.parent.data.children.push(newNode)
- }
- },
- //添加下级
- append(data, parentNode) {
- // console.log('添加下级', data)
- if (data.level >= 8) {
- this.$message({
- type: 'warning',
- message: '节点层级已达最大值!',
- })
- return
- } else {
- const newChild = {
- parentId: data.id,
- id: '',
- knowledgeCode: '',
- knowledgeName: '',
- level: data.level + 1,
- systemCode: this.systemCode,
- isEdit: true,
- enabled: true,
- children: [],
- }
- this.canStatusChange = false
- if (!data.children) {
- this.$set(data, 'children', [])
- }
- data.children.push(newChild)
- }
- }
- }
- }
- </script>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。