部门实体类
@Entity
@Table(name = "co_department")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Department implements Serializable {
private static final long serialVersionUID = -9084332495284489553L;
//ID
@Id
private String id;
/**
* 父级ID
*/
private String pid;
/**
* 企业ID
*/
private String companyId;
/**
* 部门名称
*/
private String name;
/**
* 部门编码,同级部门不可重复
*/
private String code;
/**
* 负责人ID
*/
private String managerId;
/**
* 负责人名称
*/
private String manager;
/**
* 介绍
*/
private String introduce;
/**
* 创建时间
*/
private Date createTime;
}
返回结果实体类
@Getter
@Setter
@NoArgsConstructor
public class DeptListResult {
private String companyId;
private String companyName;
private String companyManage;
private List<Department> depts;
public DeptListResult(Company company,List depts){
this.companyId = company.getId();
this.companyName = company.getName();
this.companyManage = company.getLegalRepresentative();
this.depts = depts;
}
}
部门service
@Service
public class DepartmentService {
@Autowired
private DepartmentDao departmentDao;
@Autowired
private IdWorker idWorker;
/**
* 1.保存部门
*/
public void save(Department department){
//设置主键的值
String id = idWorker.nextId()+"";
department.setId(id);
//调用dao保存部门
departmentDao.save(department);
}
/**
* 2.更新部门
*/
public void update(Department department){
//1.根据id查询部门
Department dept = departmentDao.findById(department.getId()).get();
//2. 设置部门属性
dept.setCode(department.getCode());
dept.setIntroduce(department.getIntroduce());
dept.setName(department.getName());
//3.更新部门
departmentDao.save(dept);
}
/**
* 3.根据id查询部门
*/
public Department findById(String id){
return departmentDao.findById(id).get();
}
/**
* 4.查询全部部门列表
*/
public List<Department> findAll(String companyId){
/**
* 用户构造查询条件
* root : 包含了所有的对象数据
* cq: 一般不用
* cb: 构造查询条件
*/
Specification<Department> spec = new Specification<Department>() {
@Override
public Predicate toPredicate(Root<Department> root, CriteriaQuery<?> cq, CriteriaBuilder cb) {
//根据企业id查询
return cb.equal(root.get("companyId").as(String.class),companyId);
}
};
return departmentDao.findAll(spec);
}
/**
* 5.根据id删除部门
*/
public void deleteById(String id){
departmentDao.deleteById(id);
}
}
经常会出现依据companyId查询数据,抽取成baseService
public class BaseService<T> {
/**
* 用户构造查询条件
* 1.只查询companyId
* 2.很多的地方都需要根据companyId查询
* 3.很多的对象中都具有companyId
*/
protected Specification<T> getSpec(String companyId){
Specification<T> spect = new Specification<T>() {
@Override
public Predicate toPredicate(Root<T> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) {
//根据企业id查询
return cb.equal(root.get("companyId").as(String.class),companyId);
}
};
return spect;
}
}
部门controller
@CrossOrigin
@RestController
@RequestMapping(value = "/company")
public class DepartmentController extends BaseController {
@Autowired
private DepartmentService departmentService;
@Autowired
private CompanyService companyService;
/**
* 保存
*/
@RequestMapping(value="/department",method = RequestMethod.POST)
public Result save(@RequestBody Department department){
//1.设置保存的企业id
/**
* 企业id:目前使用固定值1,以后会解决
*/
department.setCompanyId(companyId);
//2.调用service完成保存企业
departmentService.save(department);
//3.构造返回结果
return new Result(ResultCode.SUCCESS);
}
/**
* 查询企业的部门列表
* 指定企业id
*/
@RequestMapping(value="/department",method = RequestMethod.GET)
public Result findAll(){
//1.指定企业id
Company company = companyService.findById(companyId);
//2.完成查询
List<Department> list = departmentService.findAll(companyId);
//3.构造返回结果
DeptListResult deptListResult = new DeptListResult(company,list);
return new Result(ResultCode.SUCCESS,deptListResult);
}
/**
* 根据ID查询department
*
*/
@RequestMapping(value = "/department/{id}",method = RequestMethod.GET)
public Result findById(@PathVariable(value = "id") String id){
Department department = departmentService.findById(id);
return new Result(ResultCode.SUCCESS,department);
}
/**
* 修改Department
*/
@RequestMapping(value = "/department/{id}",method = RequestMethod.PUT)
public Result update(@PathVariable(value = "id") String id,@RequestBody Department department){
department.setCompanyId(id);
departmentService.update(department);
return new Result(ResultCode.SUCCESS);
}
/**
* 根据Id删除
*/
@RequestMapping(value = "/department/{id}",method = RequestMethod.DELETE)
public Result delete(@PathVariable(value = "id") String id,@RequestBody Department department){
departmentService.deleteById(id);
return new Result(ResultCode.SUCCESS);
}
}
BaseController
被@ModelAttribute注释的方法会在此controller每个方法执行前被执行
package com.ihrm.common.controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class BaseController {
protected HttpServletRequest request;
protected HttpServletResponse response;
protected String companyId;
protected String companyName;
@ModelAttribute
public void setResAndReq(HttpServletRequest request,HttpServletResponse response){
this.request = request;
this.response = response;
this.companyId = "1";
this.companyName = "钟佳宏";
}
}
前端
在属性面前加冒号
加冒号的,说明后面的是一个变量或者表达式,没加冒号的后面就是对应的字符串字面量
:class="node.expanded?'fa fa-minus-square-o':'fa fa-plus-square-o'"

部门管理.png
点击添加子部门,点击查看部门,查看和更新

添加和更新部门页面.png
<template>
<div class="dashboard-container">
<div class="app-container">
<el-card shadow="never">
<div class='organization-index'>
<div class='organization-index-top'>
<div class='main-top-title'>
<el-tabs v-model="activeName">
<el-tab-pane label="组织结构" name="first"></el-tab-pane>
<div class="el-tabs-report">
<a class="el-button el-button--primary el-button--mini" title="导出" >导入</a>
<a class="el-button el-button--primary el-button--mini" title="导出" >导出</a>
</div>
</el-tabs>
</div>
</div>
<div style="overflow: scroll;white-space:nowrap" class="treBox">
<div class="treeCon clearfix">
<span>
<i class="fa fa-university" aria-hidden="true"></i>
<span ><strong>{{departData.companyName}}</strong></span>
</span>
<div class="fr">
<span class="treeRinfo">
<div class="treeRinfo">
<span>{{departData.companyManage}}</span>
<span>在职 <em class="colGreen" title="在职人数">---</em> (<em class="colGreen" title="正式员工">---</em> / <em class="colRed" title="非正式员工">---</em>)</span>
</div>
<div class="treeRinfo">
<el-dropdown class="item">
<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-button type="text" @click="handlAdd('')">添加子部门</el-button>
</el-dropdown-item>
<el-dropdown-item>
<el-button type="text" @click="handleList()">查看待分配员工</el-button>
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</span>
</div>
</div>
<!--
构造树形列表
叶子 <i class="fa fa-male"></i>
非叶子
展开 <i class="fa fa-minus-square-o">
闭合 <i class="fa fa-plus-square-o">
<div class="generalClass" slot-scope="{node,data}" style="width:99%">
-->
<el-tree :props="{label:'name'}" :data="depts" node-key="id" default-expand-all>
<div class="generalClass" slot-scope="{node,data}" style="width:99%">
<span>
<i v-if="node.isLeaf" class="fa fa-male"></i>
<i v-else :class="node.expanded?'fa fa-minus-square-o':'fa fa-plus-square-o'"></i>
<span>{{ node.label }}</span>
</span>
<div class="fr">
<span class="treeRinfo">
<div class="treeRinfo">
<span>{{departData.companyManage}}</span>
<span>在职 <em class="colGreen" title="在职人数">---</em> (<em class="colGreen" title="正式员工">---</em> / <em class="colRed" title="非正式员工">---</em>)</span>
</div>
<div class="treeRinfo">
<el-dropdown class="item">
<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-button type="text" @click="handlAdd(data.id)">添加子部门</el-button>
</el-dropdown-item>
<el-dropdown-item>
<el-button type="text" @click="handlUpdate(data.id)">查看部门</el-button>
</el-dropdown-item>
<el-dropdown-item>
<el-button type="text" @click="handleList()">查看待分配员工</el-button>
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</span>
</div>
<span>
</div>
</el-tree>
</div>
</div>
</el-card>
</div>
<!-- 弹出框 -->
<el-dialog title="编辑部门" :visible.sync="dialogFormVisible">
<el-form :model="dept">
<el-form-item label="部门名称">
<el-input v-model="dept.name" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="部门编码">
<el-input v-model="dept.code" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="部门负责人">
<el-input v-model="dept.manager" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="部门介绍">
<el-input v-model="dept.introduce" autocomplete="off"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible = false">取 消</el-button>
<el-button type="primary" @click="saveDept">确 定</el-button>
</div>
</el-dialog>
</div>
</template>
location.reload();重新加载
<!-- 引入组件 -->
<script>
import {list,saveOrUpdate,find} from "@/api/base/dept"
import commonApi from '@/utils/common'
export default {
data() {
return {
activeName: 'first',
departData:{},
depts:[],
//添加部门的模型
parentId:'',
dialogFormVisible:false,
dept:{}
}
},
methods: {
//添加部门
handlAdd(parentId){
this.parentId = parentId;
this.dialogFormVisible = true
},
handUpdate(id){
//根据Id查询部门
find({id:id}).then(res=>{
//数据绑定到dept对象中
this.dept = res.data.data;
this.dialogFormVisible = true;
})
//显示弹出层
},
saveDept(){
this.dept.pid = this.parentId
saveOrUpdate(this.dept).then(res => {
alert(res.data.message)
//保存成功
if(res.data.success){
//如果成功
location.reload();
}
})
},
//构造查询方法
getList(){
list().then(res =>{
this.departData = res.data.data
//将普通的数据转化为父子结构
this.depts = commonApi.transformToTreeFormat(res.data.data.depts);
})
}
},
created: function() {
this.getList();
},
}
</script>
将弹出层独立成一个模块,放在component
1.在div中引用组件
<component v-bind:is="deptAdd" ref="addDept"></component>
- 在<component>里面使用 v-bind: is,可以实现动态组件的效果。
- ref 有三种用法:
- ref 加在普通的元素上,用this.ref.name 获取到的是dom元素
- ref 加在子组件上,用this.ref.name 获取到的是组件实例,可以使用组件的所有方法。
- 利用 v-for 和 ref 获取一组数组或者dom 节点
2.js方法中
-
ref被用来给元素或子组件注册引用信息。引用信息将会注册在父组件的refs对象上。refs持有已注册过ref的所有子组件
js.png
3.组件

组件.png
RBAC模型
(全称:Role-Based Access Control)基于角色的权限访问控制。,用户通过成为适当角色的成员而得到这些角色的权限。

1564372730(1).png
- 前端
前端菜单:根据是否有请求菜单权限进行动态加载
按钮:根据是否具有此权限点进行显示/隐藏的控制 -
后端
前端发送请求到后端接口,有必要对接口的访问进行权限的验证
1564372888(1).png

