3.1 iHRM人力资源 - 组织架构、树形结构、添加子部门

2024-04-17 02:52

本文主要是介绍3.1 iHRM人力资源 - 组织架构、树形结构、添加子部门,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

iHRM人力资源 - 组织架构

文章目录

  • iHRM人力资源 - 组织架构
  • 一、展示数据-树形组件
    • 1.1 组件说明
    • 1.2 树组件自定义结构获取作用域数据
      • 1.2.1 说明
      • 1.2.2 页面代码
      • 1.2.3 获取组织架构数据-api
    • 1.3 效果图
    • 1.4 修改树形结构bug
  • 二、添加子部门
    • 2.1 表单弹层
      • 2.1.1 下拉菜单点击事件
      • 2.1.2 封装弹层组件
    • 2.2 表单结构及校验
    • 2.3 部门负责人数据
    • 2.4 记录部门
    • 2.5 确认功能
    • 2.6 取消功能

一、展示数据-树形组件

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

image-20240312202534361

使用element-ui组件

https://element.eleme.cn/#/zh-CN/component/tree

1.1 组件说明

image-20240312205537574

<template><!--为什么这里写container和app-container? 因为我们最初的时候导入过样式--><div class="container"><!--在此容器上加了边距(上下30px,左右140px)--><div class="app-container">组织架构<!--展示树形结构--><!--此处正好是标签的属性名叫props,和vue框架中组件传递数据不是一个--><!--default-expand-all属性表示默认将所有的树形结构打开,完整写法是 :default-expand-all=“true” (一定带冒号)--><el-tree :data="depts" :props="defaultProps" default-expand-all></el-tree></div></div>
</template><script>
export default {name: 'Department',data() {return {// 数组属性depts: [{ name: '传智教育', children: [{ name: '总裁办' }, { name: '行政部' }, { name: '人事部' }] }],defaultProps: {// 当前层级数据(在这里找此层级的显示数据)label: 'name',// 子层级(其实就是层级结构,在这里找子节点)children: 'children'}}}
}
</script><style scoped>
.app-container {padding: 30px 140px;
}
</style>

效果图

image-20240312205856054

1.2 树组件自定义结构获取作用域数据

1.2.1 说明

我们其实要实现下面的这种树形结构,在右侧还有操作地方,但是我们在1.1中只展示了名称没有显示右侧

因为element-ui中树形结构默认只显示节点的名称,如果我们想树形结构左边有内容右边也有内容的话,就需要对树形结构进行自定义

我们这个地方需要再使用一个element-ui的行和列组件

image-20240312205942385

如下图所示,我们向实现这种结构

image-20240312212147420

行 el-row

image-20240312212256238

列 el-col

其实span默认是24份,我们分配每列的空间的话,分配span值即可

image-20240312212504452

1.2.2 页面代码

我们代码要实现下面这种形式

image-20240312213737310

<template><!--为什么这里写container和app-container? 因为我们最初的时候导入过样式--><div class="container"><!--在此容器上加了边距(上下30px,左右140px)--><div class="app-container">组织架构<!--展示树形结构--><!--此处正好是标签的属性名叫props,和vue框架中组件传递数据不是一个--><!--default-expand-all属性表示默认将所有的树形结构打开,完整写法是 :default-expand-all=“true” (一定带冒号)--><el-tree :data="depts" :props="defaultProps" default-expand-all><!--v-slot标签只能使用在template标签上--><!--这个data数据其实是el-tree给的,下面的template模板会不断的去循环,有多少个节点就会循环多少次,把每一个数据都塞到了data里面--><template v-slot="{data}"><!--节点结构。使用el-tree组件的插槽--><!--会读取这个节点结构并循环渲染到页面上--><!--我们如果把type布局模式设置为"flex",就可以用厚民安的两个属性,justify="space-between"表示两头对其,align="middle"表示垂直居中--><el-row type="flex" justify="space-between" align="middle" style="width: 100%;height: 40px"><!--一行里面有两列,第一列是组织名称,第二列是管理员和操作(下拉菜单)--><el-col>{{ data.name }}</el-col><!--:span="4"一定带着冒号,因为人家想要一个数字类型--><el-col :span="6"><span class="tree-manager">{{ data.managerName }}</span><!--下拉菜单组件--><el-dropdown><!--显示区域内容--><span class="el-dropdown-link">操作<i class="el-icon-arrow-down el-icon--right"></i></span><!--下拉菜单的选项--><el-dropdown-menu slot="dropdown"><el-dropdown-item>添加子部门</el-dropdown-item><el-dropdown-item>编辑部门</el-dropdown-item><el-dropdown-item>删除</el-dropdown-item></el-dropdown-menu></el-dropdown></el-col></el-row></template></el-tree></div></div>
</template><script>
import { getDepartment } from '@/api/department'
import { transListToTreeData } from '@/utils'export default {name: 'Department',data() {return {// 数组属性depts: [''],defaultProps: {// 当前层级数据(在这里找此层级的显示数据)label: 'name',// 子层级(其实就是层级结构,在这里找子节点)children: 'children'}}},// 页面初始化的时候会调用这个函数created() {// 获取部门数据,这个方法是下面methods里面的,不是api里面的this.getDepartment()},methods: {async getDepartment() {// 下面这个方法是import导入的api请求方法const result = await getDepartment()// 但是我们获取到的数据是列表的形式,没有层级结构,我们要使用递归的方式完成树形结构this.depts = transListToTreeData(result, 0)}}
}
</script><style scoped>
.app-container {padding: 30px 140px;
}.tree-manager {width: 50px;display: inline-block;
//margin: 10px; margin-right: 50px;
}
</style>

1.2.3 获取组织架构数据-api

  1. 封装获取组织架构的API
// 引入封装的axios工具
import request from '@/utils/request'/***  获取组织架构数据*/
export function getDepartment() {// request发送登录请求,会得到一个promise结果并将其返回return request({// 请求地址url: '/company/department',// 请求方式method: 'GET'// 请求参数,但是这里没有请求参数// data: Data// 在ES6中上面data: Data可以简写为 data})
}
  1. 初始化后调用
  // 页面初始化的时候会调用这个函数created() {// 获取部门数据,这个方法是下面methods里面的,不是api里面的this.getDepartment()},methods: {async getDepartment() {// 下面这个方法是import导入的api请求方法const result = await getDepartment()// 但是我们获取到的数据是列表的形式,没有层级结构,我们要使用递归的方式完成树形结构this.depts = transListToTreeData(result, 0)}}
  1. 赋值数据

这里我们要使用递归的方式将后端传输过来的列表数据变成树形结构

下图所示的情况

image-20240312215422002

  • 首先分析数据的关联管理

    层级结构怎么通过数据体现出来的

    如下图所示,其实就是pid与id的关系

    image-20240312220407888

{"success": true,"code": 10000,"data": [{"id": 1,"pid": 0,"name": "传智教育","code": "CZJY","managerId": 1,"managerName": "管理员","introduce": "总部","createTime": "2022-10-26 09:13:37"},{"id": 2,"pid": 1,"name": "总裁办","code": "ZCB","managerId": 1,"managerName": "管理员","introduce": "公司战略部","createTime": "2022-10-26 09:13:37"},{"id": 3,"pid": 1,"name": "行政部","code": "XZB","managerId": 4,"managerName": "黑马文吉星","introduce": "行政部","createTime": "2022-10-26 09:13:39"},......................],"message": "获取组织架构数据成功"
}
  • 封装递归函数根据关系转化层级结构

image-20240312220558856

/*** 列表数据转树形数据* rootValue: 其实就是pid(父id)*/
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 // 将子节点赋值给当前节点// 我们先push再赋值childern也没关系,因为是一个对象,地址是一样的}})return arr
}

1.3 效果图

image-20240312222227585

1.4 修改树形结构bug

当我们点击“操作”的时候,整个树形结构会关闭或者打开,很不方便,然后我们可以将expand-on-click-nod属性设置为false,说明只有点击箭头图标的时候才会展开或者收缩节点

image-20240317231919450

<!--展示树形结构-->
<!--此处正好是标签的属性名叫props,和vue框架中组件传递数据不是一个-->
<!--default-expand-all属性表示默认将所有的树形结构打开,完整写法是 :default-expand-all=“true” (一定带冒号)-->
<el-tree :data="depts" :props="defaultProps" default-expand-all :expand-on-click-node="false">

二、添加子部门

2.1 表单弹层

我们可以将“添加”和“修改”功能公用同一个弹层,也就是“添加”和“修改”的时候公用同一个组件

大体分为两步

  1. 注册添加子部门事件
  2. 封装弹层组件
  3. 控制弹层显示隐藏

image-20240317224454360

在如下位置填写

image-20240317224945483

2.1.1 下拉菜单点击事件

 <!--下拉菜单组件--><!--@command是下拉菜单的执行方法,当点击下拉菜单中的某一项的时候,就会执行operateDept方法--><el-dropdown @command="operateDept"><!--显示区域内容--><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>

当点击某一个下拉框的时候,就会将command的值传输到type

operateDept(type) {alert(type)
}

效果为如下所示,这样我们就能根据不同的按钮做出不同的功能了

image-20240317225504814

2.1.2 封装弹层组件

image-20240317225913751

<template><!--:visible用来控制显示和隐藏,由于我们是一个组件,所以我们需要外部传入一个参数来控制显示还是隐藏--><!--@close用于监视关闭弹层(点击右上角×号的时候,就会执行此函数)--><el-dialog title="新增部门" :visible="showDialog" @close="close"><!--放置弹层内容--></el-dialog>
</template><script>
export default {// 接收外部传输过来的值props: {// 参数showDialog,类型限制为Boolean,默认值为falseshowDialog: { type: Boolean, default: false }},methods: {close() {// 修改父组件的值,子传给父亲// this.$emit可以触发一个自定义事件(父组件需要接收这个时间),然后把false这个值传出去// this.$emit('',false) 但是我们先不用这个方法// 这里我们使用了 sync修饰,表示会接受子组件的事件,也就是update:showDialog这个事件,然后会把值赋值给showDialogthis.$emit('update:showDialog', false)}}
}
</script>

在index.vue组件中进行引用

<template><!--为什么这里写container和app-container? 因为我们最初的时候导入过样式--><div class="container"><!--在此容器上加了边距(上下30px,左右140px)--><div class="app-container">组织架构<!--展示树形结构--><!--此处正好是标签的属性名叫props,和vue框架中组件传递数据不是一个--><!--default-expand-all属性表示默认将所有的树形结构打开,完整写法是 :default-expand-all=“true” (一定带冒号)--><el-tree :data="depts" :props="defaultProps" default-expand-all :expand-on-click-node="false"><!--v-slot标签只能使用在template标签上--><!--这个data数据其实是el-tree给的,下面的template模板会不断的去循环,有多少个节点就会循环多少次,把每一个数据都塞到了data里面--><template v-slot="{data}"><!--节点结构。使用el-tree组件的插槽--><!--会读取这个节点结构并循环渲染到页面上--><!--我们如果把type布局模式设置为"flex",就可以用厚民安的两个属性,justify="space-between"表示两头对其,align="middle"表示垂直居中--><el-row type="flex" justify="space-between" align="middle" style="width: 100%;height: 40px"><!--一行里面有两列,第一列是组织名称,第二列是管理员和操作(下拉菜单)--><el-col>{{ data.name }}</el-col><!--:span="4"一定带着冒号,因为人家想要一个数字类型--><el-col :span="6"><span class="tree-manager">{{ data.managerName }}</span><!--下拉菜单组件--><!--@command是下拉菜单的执行方法,当点击下拉菜单中的某一项的时候,就会执行operateDept方法--><el-dropdown @command="operateDept" ><!--显示区域内容--><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><!--放置弹层--><!--:show-dialog 是我们在add-dept组件中定义的props--><!--sync修饰,表示会接受子组件的事件,也就是update:showDialog这个事件,然后会把值赋值给下面的showDialog--><add-dept :show-dialog.sync="showDialog"></add-dept></div>
</template><script>
import { getDepartment } from '@/api/department'
import { transListToTreeData } from '@/utils'
// 引入封装的弹层组件
import AddDept from './components/add-dept.vue'export default {name: 'Department',components: { AddDept },// 完成AddDept组件局部注册comments: { AddDept },data() {return {// 数组属性depts: [''],defaultProps: {// 当前层级数据(在这里找此层级的显示数据)label: 'name',// 子层级(其实就是层级结构,在这里找子节点)children: 'children'},// 控制弹层的显示和隐藏showDialog: false}},// 页面初始化的时候会调用这个函数created() {// 获取部门数据,这个方法是下面methods里面的,不是api里面的this.getDepartment()},methods: {async getDepartment() {// 下面这个方法是import导入的api请求方法const result = await getDepartment()// 但是我们获取到的数据是列表的形式,没有层级结构,我们要使用递归的方式完成树形结构this.depts = transListToTreeData(result, 0)},operateDept(type) {if (type === 'add') {// 添加子部门// 显示弹层组件this.showDialog = true}}}
}
</script><style scoped>
.app-container {padding: 30px 140px;
}.tree-manager {width: 50px;display: inline-block;
//margin: 10px; margin-right: 50px;
}
</style>

2.2 表单结构及校验

image-20240317232351643

下面是基本校验

image-20240318213926528

也要完成业务校验

如:

  • 部门名称和已有部门不重复
  • 部门编码和已有编码不重复

如果不重复的话,就实行添加功能

<template><!--:visible用来控制显示和隐藏,由于我们是一个组件,所以我们需要外部传入一个参数来控制显示还是隐藏--><!--@close用于监视关闭弹层(点击右上角×号的时候,就会执行此函数)--><el-dialog title="新增部门" :visible="showDialog" @close="close"><!--放置弹层内容--><!--label-width设置文本的宽度,这样文本框左边的字就能对其了--><el-form :model="formDara" :rules="rules" ref="addDept" label-width="120px"><el-form-item prop="name" label="部门名称"><!--place-holder是文本提示信息--><el-input v-model="formDara.name" placeholder="2-10个字符" style="width: 80%" size="mini"></el-input></el-form-item><el-form-item prop="code" label="部门编码"><el-input v-model="formDara.code" placeholder="2-10个字符" style="width: 80%" size="mini"></el-input></el-form-item><el-form-item prop="managerId" label="部门负责人"><!--这个地方是一个下拉菜单--><el-select v-model="formDara.managerId" placeholder="请选择负责人" style="width: 80%" size="mini"><!--下拉选项,循环managerList--><!--label其实是下拉选项中所显示的字段名称;v-model的值为当前被选中的el-option的value属性值--><el-option v-for="item in managerList" :key="item.id" :label="item.username" :value="item.id"></el-option></el-select></el-form-item><el-form-item prop="introduce" label="部门介绍"><!--文本域,4行--><el-input v-model="formDara.introduce" type="textarea" :rows="4" placeholder="1-100个字符" style="width: 80%"size="mini"></el-input></el-form-item><!--按钮部分,并且要实现居中--><el-form-item><!--我们可以使用行和列实现居中布局--><!--justify="center" 水平方式居中--><el-row type="flex" justify="center"><el-col :span="12"><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>
import { getDepartment } from '@/api/department'export default {// 接收外部传输过来的值props: {// 参数showDialog,类型限制为Boolean,默认值为falseshowDialog: { type: Boolean, default: false }},data() {return {formDara: {code: '', // 部门编码introduce: '', // 部门介绍managerId: '', // 部门负责人idname: '', // 部门名称,pid: '' // 父级部门的id},rules: {// 部门编码code: [{ required: true, message: '部门编码不能为空', trigger: 'blur' },{ min: 2, max: 10, message: '部门编码的长度2-10个字符' },// 自定义业务校验,部门编码不能重复{trigger: 'blur', validator: async(rule, value, callback) => {// value值是输入的编码值const result = await getDepartment()// result实际是一个数组,然后查看数组中是否存在用户输入的value值// 我们可以使用some()方法,如果存在就返回true,不存在就返回falseif (result.some(item => item.code === value)) {// 校验失败时的错误对象callback(new Error('部门中已经有该编码'))} else {// 校验成功时的对象callback()}}}],// 部门介绍introduce: [{ required: true, message: '部门介绍不能为空', trigger: 'blur' },{ min: 2, max: 10, message: '部门名称的长度1-100个字符' }],// 部门负责人idmanagerId:[{ required: true, message: '部门负责人id不能为空', trigger: 'blur' }],// 部门名称name:[{ required: true, message: '部门名称不能为空', trigger: 'blur' },{ min: 2, max: 10, message: '部门名称的长度2-10个字符' },{trigger: 'blur', validator: async(rule, value, callback) => {// value值是输入的编码值const result = await getDepartment()// result实际是一个数组,然后查看数组中是否存在用户输入的value值// 我们可以使用some()方法,如果存在就返回true,不存在就返回falseif (result.some(item => item.name === value)) {// 校验失败时的错误对象callback(new Error('部门中已经有该名称'))} else {// 校验成功时的对象callback()}}}]// pid: '' // 父级部门的id}}},methods: {......}
}
</script>

2.3 部门负责人数据

如下图所示

实现步骤:

  • 获取负责人的列表
  • 绑定下拉组件

image-20240318221820293

Api

/*** 获取部门负责人的数据*/
export function getManagerList() {return request({url: '/sys/user/simple',// 请求方式method: 'GET'})
}

组件代码

data() {return {// 存储负责人的列表managerList: [],}
},
methods: {async getManagerList() {this.managerList  = await getManagerList()}
},
created() {this.getManagerList()
},    
      <el-form-item prop="managerId" label="部门负责人"><!--这个地方是一个下拉菜单--><el-select v-model="formDara.managerId" placeholder="请选择负责人" style="width: 80%" size="mini"><!--下拉选项,循环managerList--><!--label其实是下拉选项中所显示的字段名称;v-model的值为当前被选中的el-option的value属性值--><el-option v-for="item in managerList" :key="item.id" :label="item.username" :value="item.id"></el-option></el-select></el-form-item>

2.4 记录部门

我们要在PHP研发部下面添加其子部门,这个时候我们要知道PHP研发部的id才可以

当我们点击PHP研发部的时候,我们需要将其id传输给AddDept组件

image-20240318225101911

我们可以先看一下父组件

image-20240318230018514

<template><!--为什么这里写container和app-container? 因为我们最初的时候导入过样式--><div class="container"><!--在此容器上加了边距(上下30px,左右140px)--><div class="app-container">组织架构<!--展示树形结构--><!--此处正好是标签的属性名叫props,和vue框架中组件传递数据不是一个--><!--default-expand-all属性表示默认将所有的树形结构打开,完整写法是 :default-expand-all=“true” (一定带冒号)--><el-tree :data="depts" :props="defaultProps" default-expand-all :expand-on-click-node="false"><!--v-slot标签只能使用在template标签上--><!--这个data数据其实是el-tree给的,下面的template模板会不断的去循环,有多少个节点就会循环多少次,把每一个数据都塞到了data里面--><template v-slot="{data}"><!--节点结构。使用el-tree组件的插槽--><!--会读取这个节点结构并循环渲染到页面上--><!--我们如果把type布局模式设置为"flex",就可以用厚民安的两个属性,justify="space-between"表示两头对其,align="middle"表示垂直居中--><el-row type="flex" justify="space-between" align="middle" style="width: 100%;height: 40px"><!--一行里面有两列,第一列是组织名称,第二列是管理员和操作(下拉菜单)--><el-col>{{ data.name }}</el-col><!--:span="4"一定带着冒号,因为人家想要一个数字类型--><el-col :span="6"><span class="tree-manager">{{ data.managerName }}</span><!--下拉菜单组件--><!--@command是下拉菜单的执行方法,当点击下拉菜单中的某一项的时候,就会执行operateDept方法--><!--$event实参表示类型,也就是下面command中的值,表示事件所携带的默认参数,如果不传data.id的话,默认传入的就是$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><!--放置弹层--><!--:show-dialog 是我们在add-dept组件中定义的props--><!--sync修饰,表示会接受子组件的事件,也就是update:showDialog这个事件,然后会把值赋值给下面的showDialog--><add-dept :current-node-id="currentNodeId" :show-dialog.sync="showDialog"></add-dept></div>
</template>
methods: {operateDept($event, id) {if ($event === 'add') {// 添加子部门// 显示弹层组件this.showDialog = true// 当前点击节点的idthis.currentNodeId = id}},.................
},data() {return {// 存储当前点击idcurrentNodeId: null,............// 控制弹层的显示和隐藏showDialog: false}}

子组件进行接收

image-20240318230133070

// 接收外部传输过来的值
props: {// 参数showDialog,类型限制为Boolean,默认值为falseshowDialog: { type: Boolean, default: false },currentNodeId: {type: Number,default: null}
}

2.5 确认功能

点击“确认”时,首先进行表单校验,表单校验通过之后,可以将数据提交到后端也就是调用新增接口,如果调用接口成功我们就可以通知父组件更新(组织架构列表要更新),也要重置一下表单数据,再点开后是空白的情况,最后关闭弹层

image-20240318230958537

按钮

<el-button @click="btnOK" type="primary" size="mini">确定</el-button>

api请求

/***  新增组织接口*/
export function addDepartment(data) {return request({url: '/company/department',// 请求方式method: 'POST',data: data})
}

方法

 methods: {close() {// 重置表单this.$refs.addDept.resetFields()// 修改父组件的值,子传给父亲// this.$emit可以触发一个自定义事件(父组件需要接收这个时间),然后把false这个值传出去// this.$emit('',false) 但是我们先不用这个方法// 这里我们使用了 sync修饰,表示会接受子组件的事件,也就是update:showDialog这个事件,然后会把值赋值给showDialogthis.$emit('update:showDialog', false)},async getManagerList() {this.managerList = await getManagerList()},// 点击确定时调用此方法btnOK() {this.$refs.addDept.validate(async isOK => {if (isOK) {// 校验已经通过// ...this.formDara 表示相当于把formDara数据进行了拷贝,考到了一个新对象里面// pid: this.currentNodeId表示将formDara中的pid赋值上currentNodeIdawait addDepartment({ ...this.formDara, pid: this.currentNodeId })// 此时可以通知父组件更新,也就是子传父,可以选择触发一个自定义事件(父组件要监听这个事件)this.$emit('updateDepartment')// 提示消息this.$message.success('新增部门成功')// 关闭this.close()}})}}

父组件index.vue

子组件会触发自定义事件updateDepartment

<!--放置弹层-->
<!--:show-dialog 是我们在add-dept组件中定义的props-->
<!--sync修饰,表示会接受子组件的事件,也就是update:showDialog这个事件,然后会把值赋值给下面的showDialog-->
<!--自定义事件updateDepartment,子组件触发,父组件执行getDepartment方法,刷新组织结构-->
<add-dept @updateDepartment="getDepartment" :current-node-id="currentNodeId" :show-dialog.sync="showDialog"
></add-dept>

2.6 取消功能

点击取消后,重置表单,关闭弹层即可

image-20240318231043397

<el-button @click="close" size="mini">取消</el-button>

这篇关于3.1 iHRM人力资源 - 组织架构、树形结构、添加子部门的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/910609

相关文章

mybatis的整体架构

mybatis的整体架构分为三层: 1.基础支持层 该层包括:数据源模块、事务管理模块、缓存模块、Binding模块、反射模块、类型转换模块、日志模块、资源加载模块、解析器模块 2.核心处理层 该层包括:配置解析、参数映射、SQL解析、SQL执行、结果集映射、插件 3.接口层 该层包括:SqlSession 基础支持层 该层保护mybatis的基础模块,它们为核心处理层提供了良好的支撑。

百度/小米/滴滴/京东,中台架构比较

小米中台建设实践 01 小米的三大中台建设:业务+数据+技术 业务中台--从业务说起 在中台建设中,需要规范化的服务接口、一致整合化的数据、容器化的技术组件以及弹性的基础设施。并结合业务情况,判定是否真的需要中台。 小米参考了业界优秀的案例包括移动中台、数据中台、业务中台、技术中台等,再结合其业务发展历程及业务现状,整理了中台架构的核心方法论,一是企业如何共享服务,二是如何为业务提供便利。

hdu1011(背包树形DP)

没有完全理解这题, m个人,攻打一个map,map的入口是1,在攻打某个结点之前要先攻打其他一个结点 dp[i][j]表示m个人攻打以第i个结点为根节点的子树得到的最优解 状态转移dp[i][ j ] = max(dp[i][j], dp[i][k]+dp[t][j-k]),其中t是i结点的子节点 代码如下: #include<iostream>#include<algorithm

usaco 1.3 Mixing Milk (结构体排序 qsort) and hdu 2020(sort)

到了这题学会了结构体排序 于是回去修改了 1.2 milking cows 的算法~ 结构体排序核心: 1.结构体定义 struct Milk{int price;int milks;}milk[5000]; 2.自定义的比较函数,若返回值为正,qsort 函数判定a>b ;为负,a<b;为0,a==b; int milkcmp(const void *va,c

自定义类型:结构体(续)

目录 一. 结构体的内存对齐 1.1 为什么存在内存对齐? 1.2 修改默认对齐数 二. 结构体传参 三. 结构体实现位段 一. 结构体的内存对齐 在前面的文章里我们已经讲过一部分的内存对齐的知识,并举出了两个例子,我们再举出两个例子继续说明: struct S3{double a;int b;char c;};int mian(){printf("%zd\n",s

系统架构设计师: 信息安全技术

简简单单 Online zuozuo: 简简单单 Online zuozuo 简简单单 Online zuozuo 简简单单 Online zuozuo 简简单单 Online zuozuo :本心、输入输出、结果 简简单单 Online zuozuo : 文章目录 系统架构设计师: 信息安全技术前言信息安全的基本要素:信息安全的范围:安全措施的目标:访问控制技术要素:访问控制包括:等保

利用命令模式构建高效的手游后端架构

在现代手游开发中,后端架构的设计对于支持高并发、快速迭代和复杂游戏逻辑至关重要。命令模式作为一种行为设计模式,可以有效地解耦请求的发起者与接收者,提升系统的可维护性和扩展性。本文将深入探讨如何利用命令模式构建一个强大且灵活的手游后端架构。 1. 命令模式的概念与优势 命令模式通过将请求封装为对象,使得请求的发起者和接收者之间的耦合度降低。这种模式的主要优势包括: 解耦请求发起者与处理者

OpenCV结构分析与形状描述符(11)椭圆拟合函数fitEllipse()的使用

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C++11 算法描述 围绕一组2D点拟合一个椭圆。 该函数计算出一个椭圆,该椭圆在最小二乘意义上最好地拟合一组2D点。它返回一个内切椭圆的旋转矩形。使用了由[90]描述的第一个算法。开发者应该注意,由于数据点靠近包含的 Mat 元素的边界,返回的椭圆/旋转矩形数据

JavaEE7 Servlet 3.1(JSR 340)规范中文版

http://www.iteye.com/news/27727-jinnianshilongnian     Jave EE 7中的部分规范已正式获得批准通过,其中包括JSR340 Java Servlet 3.1规范,去年翻译了该规范,在此分享出来,希望对某些朋友有所帮助,不足之处请指正。   点击直接下载    在线版目录   Servlet3.1规范翻译

创业者该如何设计公司的股权架构

本文来自七八点联合IT橘子和车库咖啡的一系列关于设计公司股权结构的讲座。 主讲人何德文: 在公司发展的不同阶段,创业者都会面临公司股权架构设计问题: 1.合伙人合伙创业第一天,就会面临股权架构设计问题(合伙人股权设计); 2.公司早期要引入天使资金,会面临股权架构设计问题(天使融资); 3.公司有三五十号人,要激励中层管理与重要技术人员和公司长期走下去,会面临股权架构设计问题(员工股权激