Vue2(4)——iHRM组织架构

组织架构-树组件应用

树形组件-用层级结构展示信息,可展开或折叠。

属性设置

  • data(绑定数据)
  • props(设置属性)- children(设置子节点的字段名)/ label(设置显示内容的字段名)
  • default-expand-all(默认展开所有节点)

组织架构-树组件自定义结构

显示右侧结构

节点结构设计

使用elementui的行和列结构

组织架构-节点作用域插槽

 组织架构-递归转化树形结构


/**
 * 列表型数据转化为数组结构
 */
export function transListToTreeData(list,rootValue) {
  const arr = [];
  list.forEach(item=>{
    if (item.pid==rootValue){
      //找到了匹配的节点
      arr.push(item)
      //当前节点的id和当前节点的子节点的pid是相等的
      const children = transListToTreeData(list,item.id)//找到当前节点的子节点
      item.children = children;//将子节点赋值给当前节点
    }
  })

}

组织架构-递归特点

  • 一般来说是用来处理未知层级的数据
  • 递归要有跳出条件
  • 自身调用自身时参数不能重复

组织架构-添加子部门-新建弹层组件

1.注册事件

给每个选项添加command属性,方便我们定位到点击了那个菜单

2.封装组件

 3.控制显示

 组织架构-添加子部门-表单构造

  <el-dialog title="新增部门" :visible="showDialog" @close="close">
    <el-form label-width="120x">
      <el-form-item label="部门名称">
        <el-input placeholder="2-10字符" style="width: 80%" size="mini"/>
      </el-form-item>
      <el-form-item label="部门编码">
        <el-input style="width: 80%" placeholder="2-10字符" size="mini"/>
      </el-form-item>
      <el-form-item label="部门负责人">
        <el-select style="width: 80%" placeholder="2-10字符" size="mini"/>
      </el-form-item>
      <el-form-item label="部门介绍">
        <el-input type="textarea" :row="4" style="width: 80%"  placeholder="1-100字符" size="mini"/>
      </el-form-item>
      <el-form-item>
        <el-row type="flex" justify="center">
          <el-col :span="12" align="center">
            <el-button type="primary" size="mini">确认</el-button>
            <el-button size="mini">取消</el-button>
          </el-col>
        </el-row>
      </el-form-item>
    </el-form>
  </el-dialog>

组织架构-添加子部门-表单校验

  • 定义数据结构
  • 绑定属性
  • 定义规则

<template>
  <el-dialog title="新增部门" :visible="showDialog" @close="close">
    <el-form ref="addDept" :model="formData" :rules="rules" label-width="120x">
      <el-form-item label="部门名称" prop="name">
        <el-input v-model="formData.name" placeholder="2-10字符" style="width: 80%" size="mini"/>
      </el-form-item>
      <el-form-item label="部门编码" prop="code">
        <el-input v-model="formData.code" style="width: 80%" placeholder="2-10字符" size="mini"/>
      </el-form-item>
      <el-form-item label="部门负责人" prop="managerId">
        <el-select v-model="formData.managerId" style="width: 80%" placeholder="2-10字符" size="mini"/>
      </el-form-item>
      <el-form-item label="部门介绍" prop="introduce">
        <el-input v-model="formData.introduce" type="textarea" :row="4" style="width: 80%"  placeholder="1-100字符" size="mini"/>
      </el-form-item>
      <el-form-item>
        <el-row type="flex" justify="center">
          <el-col :span="12" align="center">
            <el-button type="primary" size="mini">确认</el-button>
            <el-button size="mini">取消</el-button>
          </el-col>
        </el-row>
      </el-form-item>
    </el-form>
  </el-dialog>
</template>
<script>
  export default {
    props:{
      showDialog:{
        type: Boolean,
        default: false
      }
    },
    data(){
      return{
        formData: {
          code: '',
          introduce: '',
          managerId: '',
          name: '',
          pid: '',
        },
        rules: {
          code: [
            { required: true, message: '部门编码不能为空', trigger: 'blur' },
            {min: 2, max: 10, message: '部门编码的长度为2-10个字符', trigger: 'blur'}
            ],

          introduce: [
            { required: true, message: '部门介绍不能为空', trigger: 'blur' },
            {min: 1, max: 100, message: '部门介绍的长度为1-100个字符', trigger: 'blur'}
            ],

          managerId: [
            { required: true, message: '部门负责人不能为空', trigger: 'blur' }
            ],

          name: [
            { required: true, message: '部门名称不能为空', trigger: 'blur' },
            {min: 2, max: 10, message: '部门名称的长度为2-10个字符', trigger: 'blur'}
            ],
        }
      }
    },
    methods:{
      close(){
        //修改父组件的值   子传父
        this.$emit('update:showDialog',false)//自定义事件
      }
    }
  }
</script>

 组织架构-添加子部门-业务校验

  • 非空校验
  • 长度校验
  • 业务校验

        自定义校验器:validator(rule, value(输入的值), callback(返回的值))

        数组.some(回调),判断数组是否存在某个值

        rules: {
          code: [
            { required: true, message: '部门编码不能为空', trigger: 'blur' },
            {min: 2, max: 10, message: '部门编码的长度为2-10个字符', trigger: 'blur'},
            {
              trigger: 'blur',
              // 自定义校验模式
              validator: async(rule, value, callback) => {
                // value就是输入的编码
                let result = await getDepartment()
                // 判断是否是编辑模式
                if (this.formData.id) {
                  // 编辑场景
                  result = result.filter(item => item.id !== this.formData.id)
                }
                // result数组中是否存在 value值
                //some判断数组是否存在某个值,里面是回调函数
                if (result.some(item => item.code === value)) {
                  callback(new Error('部门中已经有该编码了'))
                } else {
                  callback()
                }
              }
            }
            ],

          introduce: [
            { required: true, message: '部门介绍不能为空', trigger: 'blur' },
            {min: 1, max: 100, message: '部门介绍的长度为1-100个字符', trigger: 'blur'}
            ],

          managerId: [
            { required: true, message: '部门负责人不能为空', trigger: 'blur' }
            ],

          name: [
            { required: true, message: '部门名称不能为空', trigger: 'blur' },
            {min: 2, max: 10, message: '部门名称的长度为2-10个字符', trigger: 'blur'},
            {
              trigger: 'blur',
              // 自定义校验模式
              validator: async(rule, value, callback) => {
                // value就是输入的编码
                let result = await getDepartment()
                // 判断是否是编辑模式
                if (this.formData.id) {
                  // 编辑场景 排除自身
                  result = result.filter(item => item.id !== this.formData.id)
                }
                // result数组中是否存在 value值
                //some判断数组是否存在某个值,里面是回调函数
                if (result.some(item => item.name === value)) {
                  callback(new Error('部门中已经有该编码了'))
                } else {
                  callback()
                }
              }
            }
            ],
        }
      }
    },

组织架构-添加子部门-负责人数据

1. 初始化调用负责人数据列表

    created() {
      this.getManagerList();
    },
    methods:{
      async getManagerList(){
        const result = await getManagerList();
        this.managerList = result;
      },
      close(){
        //修改父组件的值   子传父
        this.$emit('update:showDialog',false)//自定义事件
      }
    }

2. 表单中循环渲染数据

      <el-form-item label="部门负责人" prop="managerId">
        <el-select v-model="formData.managerId" style="width: 80%" placeholder="2-10字符" size="mini">
<!--          编写下来选项  循环负责人的数据  label表示显示的字段  value为存储字段-->
          <el-option v-for="item in managerList" :key="item.id" :label="item.name" :value="item.id">
          </el-option>
        </el-select>
      </el-form-item>

组织架构-添加子部门-记录部门

 1.点击菜单传输id

2.定义数据记录id

3.组件接受

组织架构-添加子部门-确认取消

 1.封装新增api

/**
 * 新增组织
 * @param data
 * @returns {AxiosPromise}
 */
export function addDepartment(data) {
  return request({
    method:'post',
    url:'/company/department',
    data
  })

2.确实,和通知父组件更新

    btnOK(){
      //表单校验
      //获取表单实例
      this.$refs.addDept.validate(async isOK=>{
        if (isOK){
          await addDepartment({...this.formData,pid : this.currentNodeId})
          //通知父组件去更新
          this.$emit('updateDeptment')
          //提示实现
          this.$message.success('新增部门成功')
          this.close()
        }
      })
    },

3.父组件接收事件调研方法

    <add-dept :current-node-id="currentNodeId" :show-dialog.sync="showDialog" @updateDeptment="getDepartment"/>

4.取消调用close方法

      close(){
        //重置表单
        this.$refs.addDept.resetFields()
        //修改父组件的值   子传父
        this.$emit('update:showDialog',false)//自定义事件
      }

小结代码

1.api/department.js

import request from '@/utils/request'

/**
 * 获取组织架构
 * @param params
 * @returns {AxiosPromise}
 */
export function getDepartment() {
  return request({
    url: '/company/departmant',
  })
}

/**
 * 获取部门负责人数据
 * @param params
 * @returns {AxiosPromise}
 */
export function getManagerList() {
  return request({
    url: '/sys/user/simple',
  })
}

/**
 * 新增组织
 * @param data
 * @returns {AxiosPromise}
 */
export function addDepartment(data) {
  return request({
    method:'post',
    url:'/company/department',
    data
  })

}

 2.add-dept.vue

<template>
  <el-dialog title="新增部门" :visible="showDialog" @close="close">
    <el-form ref="addDept" :model="formData" :rules="rules" label-width="120x">
      <el-form-item label="部门名称" prop="name">
        <el-input v-model="formData.name" placeholder="2-10字符" style="width: 80%" size="mini"/>
      </el-form-item>
      <el-form-item label="部门编码" prop="code">
        <el-input v-model="formData.code" style="width: 80%" placeholder="2-10字符" size="mini"/>
      </el-form-item>
      <el-form-item label="部门负责人" prop="managerId">
        <el-select v-model="formData.managerId" style="width: 80%" placeholder="2-10字符" size="mini">
<!--          编写下来选项  循环负责人的数据  label表示显示的字段  value为存储字段-->
          <el-option v-for="item in managerList" :key="item.id" :label="item.name" :value="item.id">
          </el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="部门介绍" prop="introduce">
        <el-input v-model="formData.introduce" type="textarea" :row="4" style="width: 80%"  placeholder="1-100字符" size="mini"/>
      </el-form-item>
      <el-form-item>
        <el-row type="flex" justify="center">
          <el-col :span="12" align="center">
            <el-button @click="btnOK" type="primary" size="mini">确认</el-button>
            <el-button @click="close" size="mini">取消</el-button>
          </el-col>
        </el-row>
      </el-form-item>
    </el-form>
  </el-dialog>
</template>
<script>
  import {getDepartment,getManagerList,addDepartment} from '@/api/department'
  export default {
    props:{
      showDialog:{
        type: Boolean,
        default: false
      },
      currentNodeId:{
        type: Number,
        default: null
      }
    },
    data(){
      return{
        managerList: [],//存储负责人列表
        formData: {
          code: '',
          introduce: '',
          managerId: '',
          name: '',
          pid: '',
        },
        rules: {
          code: [
            { required: true, message: '部门编码不能为空', trigger: 'blur' },
            {min: 2, max: 10, message: '部门编码的长度为2-10个字符', trigger: 'blur'},
            {
              trigger: 'blur',
              // 自定义校验模式
              validator: async(rule, value, callback) => {
                // value就是输入的编码
                let result = await getDepartment()
                // 判断是否是编辑模式
                if (this.formData.id) {
                  // 编辑场景
                  result = result.filter(item => item.id !== this.formData.id)
                }
                // result数组中是否存在 value值
                //some判断数组是否存在某个值,里面是回调函数
                if (result.some(item => item.code === value)) {
                  callback(new Error('部门中已经有该编码了'))
                } else {
                  callback()
                }
              }
            }
            ],

          introduce: [
            { required: true, message: '部门介绍不能为空', trigger: 'blur' },
            {min: 1, max: 100, message: '部门介绍的长度为1-100个字符', trigger: 'blur'}
            ],

          managerId: [
            { required: true, message: '部门负责人不能为空', trigger: 'blur' }
            ],

          name: [
            { required: true, message: '部门名称不能为空', trigger: 'blur' },
            {min: 2, max: 10, message: '部门名称的长度为2-10个字符', trigger: 'blur'},
            {
              trigger: 'blur',
              // 自定义校验模式
              validator: async(rule, value, callback) => {
                // value就是输入的编码
                let result = await getDepartment()
                // 判断是否是编辑模式
                if (this.formData.id) {
                  // 编辑场景 排除自身
                  result = result.filter(item => item.id !== this.formData.id)
                }
                // result数组中是否存在 value值
                //some判断数组是否存在某个值,里面是回调函数
                if (result.some(item => item.name === value)) {
                  callback(new Error('部门中已经有该编码了'))
                } else {
                  callback()
                }
              }
            }
            ],
        }
      }
    },
    created() {
      this.getManagerList();
    },
    methods:{
      async getManagerList(){
        const result = await getManagerList();
        this.managerList = result;
      },
      close(){
        //重置表单
        this.$refs.addDept.resetFields()
        //修改父组件的值   子传父
        this.$emit('update:showDialog',false)//自定义事件
      }
    },
    btnOK(){
      //表单校验
      //获取表单实例
      this.$refs.addDept.validate(async isOK=>{
        if (isOK){
          await addDepartment({...this.formData,pid : this.currentNodeId})
          //通知父组件去更新
          this.$emit('updateDeptment')
          //提示实现
          this.$message.success('新增部门成功')
          this.close()
        }
      })
    },
  }
</script>

3.index.vue

 

<template>
  <div class="container">
    <div class="app-container">
      <!-- 展示树结构 -->
      <el-tree :expand-on-click-node="false" :data="depts" :props="defaultProps" default-expand-all="true">
<!--        节点结构-->
<!--        v-slot="{node,data}",只能作用在template标签里面-->
        <template v-slot="{data}">
          <el-row style="width:100%;height:40px" type="flex" justify="space-between" align="middle">
            <el-col>{{data.label}}</el-col>
            <el-col :span="4">
              <span class="tree-manager">{{data.managerName}}</span>
<!--              $event 实参 表示类型-->
              <el-dropdown @command="operateDept($event,data.id)">
                <!--              显示区域-->
                <span class="el-dropdown-link">
                下拉菜单<i class="el-icon-arrow-down el-icon--right"></i>
              </span>
                <!--              选项-->
                <el-dropdown-menu slot="dropdown">
                  <el-dropdown-item command="add">添加子部门</el-dropdown-item>
                  <el-dropdown-item command="edit">编辑部门</el-dropdown-item>
                  <el-dropdown-item command="del">删除</el-dropdown-item>
                </el-dropdown-menu>
              </el-dropdown>
            </el-col>
          </el-row>
        </template>
      </el-tree>
    </div>
<!--    3.组件放在最外层的里一层-->
<!--    表示会接受子组件的事件和值 => 属性-->
    <add-dept :current-node-id="currentNodeId" :show-dialog.sync="showDialog" @updateDeptment="getDepartment"/>
  </div>
</template>

<script>
  import {transListToTreeData} from "@/utils"
  //1.导入组件
  import AddDept from "./components/add-dept.vue"
  export default {
    name: 'Department',
    //2.注册局部组件
    components: {AddDept},
    data() {
      return {
        currentNodeId:null,
        showDialog: false,//控制弹层
        depts: [{
          label: '瑞德', managerName:'管理员',id:1,children: [
            {label: '总裁办', managerName:'历史',id:2},{
              label: '行政部', managerName:'五五',id:3
            },
            {
              label: '人事部', managerName:'全球',id:4
            }
          ]
        }],//数据属性
        defaultProps: {
          label: 'label', //要显示字段的名字
          children: 'children' //读取子节点的字段名
        }
      }
    },
    created() {
      this.getDepartment()
    },
    methods:{
      //封装好的方法
      async getDepartment(){
        // const result = await getDepartment()
        // this.depts = transListToTreeData(result,0)
      },
      //操作部门的方法
      operateDept(type,id){
        if (type==="add"){
          this.showDialog=true
          this.currentNodeId=id
        }
      }

    }
  }
</script>

<!--scoped当前组件生效-->
<style scoped>
  .app-container{
    padding: 30px 140px;
    font-size: 14px;
  }
  .tree-manager{
    width: 50px;
    display: inline-block;
    margin: 10px;
  }
</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/462540.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Vue2(三):绑定样式、条件渲染(v-if,v-show)、列表渲染(v-for)、key的原理、列表过滤、列表排序

一、绑定样式 1.绑定class样式 (1)字符串写法 适用于&#xff1a;样式类名不确定&#xff0c;需要动态获取。 <div id"root"><div class"basic" :class"mood" click"changeMood">test</div><!-- class是原本的…

【Python】进阶学习:基于Numpy实现按指定维度拼接两个数组

【Python】进阶学习&#xff1a;基于Numpy实现按指定维度拼接两个数组 &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程&#x1f448; 希…

第十三届蓝桥杯(C/C++ 大学B组)

目录 试题 A: 九进制转十进制 试题 B: 顺子日期 试题 C: 刷题统计 试题 D: 修剪灌木 试题 E: X 进制减法 试题 F: 统计子矩阵 试题 G: 积木画 试题 H: 扫雷 试题 I: 李白打酒加强版 试题 J: 砍竹子 试题 A: 九进制转十进制 九进制正整数 ( 2022 )转换成十进制等于多…

2000-2021年各省外商直接投资水平面板数据(含原始数据+计算结果)(无缺失)

2000-2021年各省外商直接投资水平面板数据&#xff08;含原始数据计算结果&#xff09;&#xff08;无缺失&#xff09; 1、时间&#xff1a;2000-2021年 2、指标&#xff1a;外商直接投资额&#xff08;万美元&#xff09;、外商直接投资额&#xff08;万元&#xff09;、国…

MySQL语法分类 DQL(4)聚合函数

为了更好的学习这里给出基本表数据用于查询操作 create table student (id int, name varchar(20), age int, sex varchar(5),address varchar(100),math int,english int );insert into student (id,name,age,sex,address,math,english) values (1,马云,55,男,杭州,66,78),…

2024年【危险化学品经营单位主要负责人】找解析及危险化学品经营单位主要负责人模拟考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 危险化学品经营单位主要负责人找解析考前必练&#xff01;安全生产模拟考试一点通每个月更新危险化学品经营单位主要负责人模拟考试题目及答案&#xff01;多做几遍&#xff0c;其实通过危险化学品经营单位主要负责人…

移动云行动:5.5G技术引领数字化转型

刚刚结束的全国两会上&#xff0c;有人大代表建议应尽快发挥5G-A&#xff08;5.5G&#xff09;优势&#xff0c;加快试点城市布局。此前&#xff0c;中国移动已宣布将在300多个城市启动5.5G商用部署。在通信技术的历史长河中&#xff0c;4G改变了我们的生活方式&#xff0c;而5…

【Poi-tl Documentation】区块对标签显示隐藏改造

前置说明&#xff1a; <dependency><groupId>com.deepoove</groupId><artifactId>poi-tl</artifactId><version>1.12.1</version> </dependency>模板&#xff1a; 删除行表格测试.docx 改造前测试效果 package run.siyuan…

Iframe 嵌入: 页面嵌入并保持自适应页面的宽高并铺满整个屏幕

文章目录 问题分析1. 嵌入 Iframe2. 样式3. 源码 问题 当我们使用 Iframe 嵌入页面后&#xff0c;会看到它只在小小的一部分进行展示&#xff0c;如何让它铺满整个屏幕 分析 1. 嵌入 Iframe <template><div><iframe :src"embeddedPageUrl" width…

【编程项目开源】微信飞机大战(鸿蒙版)

目标 仿微信飞机大战 效果 开发工具 下载DevEco Studio 工程截图 开源地址 https://gitee.com/lblbc/plane_game/tree/master/PlaneGame_hongmeng_ArkTS 关于 厦门大学计算机专业|华为八年高级工程师 专注《零基础学编程系列》 http://lblbc.cn/blog 包含&#xff1a;Ja…

18.相交链表

给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点&#xff0c;返回 null 。 图示两个链表在节点 c1 开始相交&#xff1a; 题目数据 保证 整个链式结构中不存在环。 注意&#xff0c;函数返回结果后&…

腾讯云2核4g服务器能支持多少人访问?没搞错吧

腾讯云轻量2核4G5M带宽服务器支持多少人在线访问&#xff1f;5M带宽下载速度峰值可达640KB/秒&#xff0c;阿腾云以搭建网站为例&#xff0c;假设优化后平均大小为60KB&#xff0c;则5M带宽可支撑10个用户同时在1秒内打开网站&#xff0c;并发数为10&#xff0c;经阿腾云测试&a…

2024年【P气瓶充装】模拟考试及P气瓶充装证考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 P气瓶充装模拟考试是安全生产模拟考试一点通生成的&#xff0c;P气瓶充装证模拟考试题库是根据P气瓶充装最新版教材汇编出P气瓶充装仿真模拟考试。2024年【P气瓶充装】模拟考试及P气瓶充装证考试 1、【多选题】《中华…

Java中的实用类讲解(上篇)

如果想观看更多Java内容 可上我的个人主页关注我&#xff0c;地址子逸爱编程-CSDN博客https://blog.csdn.net/a15766649633?spm1000.2115.3001.5343 使用工具 IntelliJ IDEA Community Edition 2023.1.4 使用语言 Java8 代码能力快速提升小方法&#xff0c;看完代码自己敲…

python 实现阿里云OSS文件上传

因为我们出口的带宽限制&#xff0c;测试经常找我给他上传个包到阿里云的对象存储&#xff0c;虽然传起来也不是很费事&#xff0c;但是出于运维的职业素养&#xff0c;特意写了一个自动上传的接口&#xff0c;代码如下&#xff1a; # -*- coding: UTF-8 -*- from flask imp…

【保姆及教程】简直不要太爽了!md文件图床工具picgo配合typora和阿里云oss存储,实现文md文件的复制转贴

md文件图床工具picgo的安装和使用、配合阿里云面向对象oss 一、网址 官方网址&#xff1a;https://molunerfinn.com/PicGo/ github地址&#xff1a;https://github.com/Molunerfinn/picgo/releases 选择对应的版本下载即可 但也可以提供我给你的下载的地址&#xff1a; 方…

前端学习之css选择器--基本选择器、关系选择器、属性选择器、复合选择器、伪类选择器

目录 基本选择器 结果 关系选择器 结果 父子关系 祖先后代关系 相邻兄弟关系 兄弟关系 ​编辑 属性选择器 结果 复合选择器 结果 伪类选择器 结果 伪类选择器-操作标签 结果 未访问 访问后 悬停 基本选择器 <!DOCTYPE html> <html lang"en"…

Java-PriorityQueue源码分析

PriorityQueue 源码分析 Java中的PriorityQueue采用的是堆这种数据结构来实现的,而存储堆采用的则是数组。 堆是一个完全二叉树,堆中每一个节点的值都必须大于等于(或小于等于)其子树中每个节点的值,对于每个节点的值都大于等于子树中每个节点值的堆&#xff0c;我们叫做大顶…

数学建模--MATLAB基本使用

1.线性方程组 这个是一个线性方程组&#xff08;属于线性代数的范畴&#xff09;&#xff0c;Axb类型的方程&#xff0c;如果使用MATLAB进行求解&#xff0c;就需要分别表示A矩阵&#xff08;线性方程组未知数前面的系数&#xff09;&#xff0c;b矩阵&#xff08;表示等式右边…

探索Docker:原理、安装与基础应用

进程: 一旦“程序”被执行起来&#xff0c;它就从磁盘上的二进制文件&#xff0c;变成了计算机内存中的数据、寄存器里的值、堆栈中的指令、被打开的文件&#xff0c;以及各种设备的状态信息的一个集合。像这样一个程序运行起来后的计算机执行环境的总和称为进程 静态表现&am…
最新文章