平铺数据转树形,以及增加或修改数据时判断数据是否符合要求

125 阅读3分钟

今天做项目后台管理系统,在做组织架构模块的时候涉及到了人员所在部门的增删改查功能,遇到了好多的之前没有总结的或者没有发现的问题。所以在这一次性的总结一下。

问题整合

(1)数据问题,把平铺的数据整合成树形结构
(2)每一个部门增加或者编辑时,需要满足该部门的编码(code)在整个公司是没有的,不可以重复。
(3)每一个部门增加或者编辑时,需要满足该部门的名字与其同级的部门中不可以出现相同的名字 遇到的问题有:当编辑数据时,数据不修改,直接提交校验也会提示出现重复的情况。

1 数据格式转化

把下面这种数据转化成树形数据

[
  { id: '1001', manager: '管理员', name: '行政部', pid: '' },
  { id: '1002', manager: '管理员', name: '财务部', pid: '' },
  { id: '1003', manager: '管理员', name: '人事部', pid: '' },
  { id: '1004', manager: '巴斯慧', name: '上海事业部', pid: '1001' },
  { id: '1005', manager: '孙财', name: '财务核算部', pid: '1002' },
  { id: '1006', manager: '张飞', name: '税务管理部', pid: '1002' }
]

调用下面的函数即可进行转换

function getListTree(list) {
  console.log(list)
  // 1. 定义两个变量,用来接收最终的数据
  const treeList = []
  //这个变量只是用来转换的,只是中间的一个步骤
  const map = {}

  // 2. 建立一个映射关系,并给每个元素补充children属性.
  // 映射关系: 目的是让我们能通过id快速找到对应的元素
  // 补充children:让后边的计算更方便
  list.forEach(item => {
    if (!item.children) {
      item.children = []
    }
    map[item.id] = item
  })

  // 循环
  list.forEach(item => {
    // 对于每一个元素来说,先找它的上级
    //    如果能找到,说明它有上级,则要把它添加到上级的children中去
    //    如果找不到,说明它没有上级,直接添加到 treeList
    const parent = map[item.pid]
    // 如果存在上级则表示item不是最顶层的数据
    if (parent) {
      parent.children.push(item)
    } else {
      // 如果不存在上级 则是顶层数据,直接添加
      treeList.push(item)
    }
  })
  // 返回
  return treeList
}

修改之后数据是如下格式

[
  { id: '1001', manager: '管理员', name: '行政部', pid: '' ,children:
      [{ id: '1004', manager: '巴斯慧', name: '上海事业部', pid: '1001' }]
  },
  { id: '1002', manager: '管理员', name: '财务部', pid: '' ,children:
      [
          { id: '1005', manager: '孙财', name: '财务核算部', pid: '1002' },
          { id: '1006', manager: '张飞', name: '税务管理部', pid: '1002' }
      ]
  },
  { id: '1003', manager: '管理员', name: '人事部', pid: '' },
]

2 表单增加和编辑数据

2.1 父向子传值

首先需要获得所有数据中需要校验的数据,在我做的项目中主要是四个数据是必须的,包括pid可以查看父对象内容,id每一项数据都有一个不同的编号,code是部门编号,name是部门名称。然后使用ES6中的解构语法把获取到的平铺的数据进行整合。

data.map((item) => {
        const { pid, id, code, name } = item
        return { pid, id, code, name }
      })

因为在项目中增加和编辑框是复用的,所以我是重新建立一个.vue页面。所以这就涉及到了父向子传值的内容。先定义一个变量接收上面的返回值。然后传到子组件中,子组件通过prop接收数据名字为originList。

2.2 自定义校验函数【校验code】

通过接受的数据originList,

 const validatecode = (rule, value, callback) => {
      if (value === '') {
        callback(new Error('部门编码不能为空'))
      } else {
        let arr = this.originList.map(item => item.code)
        console.log(arr)
        //使用isEdit区别编辑和增加
        if (this.isEdit) {
          arr = this.originList.filter(item => item.id !== this.id).map(item => item.code)
        }
        arr.includes(value) ? callback(new Error('编码重复!')) : callback()
      }
    }

2.2 自定义校验函数【校验name】

 const validatename = (rule, value, callback) => {
      if (value === '') {
        callback(new Error('部门名称不能为空'))
      } else {
        const arr = this.originList.filter(item => item.pid === this.id).map(item => item.name)
        console.log(arr)
        if (this.isEdit) {
          const pid = this.originList.find(item => item.id === this.pid)
          this.originList.filter(item => item.pid === pid).filter(item => item.id !== this.id).map(item => item.name)
        }
        arr.includes(value) ? callback(new Error('部门名称重复!')) : callback()
      }
    }

这些都是与思维有点关系的,当时做的时候确实卡了很久,然后就记录一下,以防下次还会遇到。