SaaS-HRM--第3章-SaaS系统用户权限设计

学习目标:

理解RBAC模型的基本概念及设计思路
了解SAAS-HRM中权限控制的需求及表结构分析
完成组织机构的基本CRUD操作
完成用户管理的基本CRUD操作
完成角色管理的基本CRUD操作

1组织机构管理

1.1需求分析

1.1.1需求分析
实现企业组织结构管理,实现部门的基本CRUD操作SaaS-HRM--第3章-SaaS系统用户权限设计_第1张图片
1.1.2数据库表设计


CREATE TABLE `co_department` (
`id` varchar(40) NOT NULL,
`company_id` varchar(255) NOT NULL COMMENT '企业ID',
`parent_id` varchar(255) DEFAULT NULL COMMENT '父级部门ID',
`name` varchar(255) NOT NULL COMMENT '部门名称',
`code` varchar(255) NOT NULL COMMENT '部门编码',
`category` varchar(255) DEFAULT NULL COMMENT '部门类别',
`manager_id` varchar(255) DEFAULT NULL COMMENT '负责人ID',
`city` varchar(255) DEFAULT NULL COMMENT '城市',
`introduce` text COMMENT '介绍',
`create_time` datetime NOT NULL COMMENT '创建时间',
`manager` varchar(40) DEFAULT NULL COMMENT '部门负责人',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4

1.2微服务实现

1.2.1抽取公共代码
(1)在 公 共 controller ihrm_commoncom.模块下的ihrm.common.controller包下添加公共controller

package com.ihrm.common.controller;
import org.springframework.web.bind.annotation.ModelAttribute; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


/**
*公共controller
*获取request,response
*获取企业id,获取企业名称
*/
public class BaseController {


protected HttpServletRequest request; protected HttpServletResponse response;

@ModelAttribute
public void setReqAndResp(HttpServletRequest request, HttpServletResponse response)
{
this.request = request; this.response = response;
}

//企业id,(暂时使用1,以后会动态获取) public String parseCompanyId() {
return "1";
}
public String parseCompanyName() { return "江苏传智播客教育股份有限公司";
}
}

(2)公 共 service ihrm_commoncom.模块下的ihrm.common.service包下添加公共BaseService

public class BaseService {
protected Specification getSpecification(String companyId) { return new Specification() {
@Override
public Predicate toPredicate(Root root, CriteriaQuery criteriaQuery, CriteriaBuilder cb) {
return cb.equal(root.get("companyId").as(String.class),companyId);
}
};
}
}

1.2.2实现基本CRUD操作
(1)实体类
在 包下创建Department实体类


package com.ihrm.domain.company;

import lombok.AllArgsConstructor; import lombok.Data;
import lombok.NoArgsConstructor;

import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; import javax.persistence.Transient; import java.io.Serializable; import java.util.Date;
import java.util.List;

/**
* (Department)实体类
*/ @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;
}

(2)持久化层在

com.ihrm.company.dao包下创建DepartmentDao

package com.ihrm.company.dao;
import com.ihrm.domain.company.Department;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;


/**
* 部门操作持久层
*/
public interface DepartmentDao extends JpaRepository, JpaSpecificationExecutor {
}

(3)业务层在
com.ihrm.company.service包下创建DepartmentService

package com.ihrm.company.service;


import com.ihrm.common.entity.ResultCode;
import com.ihrm.common.exception.CommonException; import com.ihrm.common.service.BaseService; import com.ihrm.common.utils.IdWorker;
import  com.ihrm.company.dao.DepartmentDao;


import  com.ihrm.domain.company.Department;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.jpa.domain.Specification; import org.springframework.stereotype.Service;
import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root;
import java.util.Date; import java.util.List;

/**
* 部门操作业务逻辑层
*/ @Service
public class DepartmentService extends BaseService {


@Autowired
private IdWorker idWorker; @Autowired
private DepartmentDao departmentDao;


/**
* 添加部门
*/
public void save(Department department) {
//填充其他参数department.setId(idWorker.nextId() + ""); department.setCreateTime(new Date()); departmentDao.save(department);
}


/**
* 更新部门信息
*/
public void update(Department department) {
Department sourceDepartment = departmentDao.findById(department.getId()).get(); sourceDepartment.setName(department.getName()); sourceDepartment.setPid(department.getPid()); sourceDepartment.setManagerId(department.getManagerId()); sourceDepartment.setIntroduce(department.getIntroduce()); sourceDepartment.setManager(department.getManager()); departmentDao.save(sourceDepartment);
}
/**
*根据ID获取部门信息
*
*@param id 部门ID
*@return 部门信息
*/
public Department findById(String id) { return departmentDao.findById(id).get();
}


/**
*删除部门
*
*@param id 部门ID
*/
public void delete(String id) { departmentDao.deleteById(id);
}


/**
*获取部门列表
*/
public List findAll(String companyId) {
return departmentDao.findAll(getSpecification(companyId));
}
}

(4)控制层在

ihrm.company.controller创建控制器类DepartmentController

package com.ihrm.company.controller;
import com.ihrm.common.controller.BaseController; import com.ihrm.common.entity.Result;
import com.ihrm.common.entity.ResultCode; import com.ihrm.company.service.CompanyService;
import com.ihrm.company.service.DepartmentService; import com.ihrm.domain.company.Company;
import com.ihrm.domain.company.Department;
import com.ihrm.domain.company.response.DeptListResult; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*; import java.util.*;
import java.util.stream.Collectors;


/**
* 控制器层
*/
@RestController
@RequestMapping("/company")
public class DepartmentController extends BaseController{


@Autowired
private DepartmentService departmentService;


@Autowired
private CompanyService companyService;


/**
* 添加部门
*/
@RequestMapping(value = "/departments", method = RequestMethod.POST) public Result add(@RequestBody Department department) throws Exception {
department.setCompanyId(parseCompanyId()); departmentService.save(department);
return Result.SUCCESS();
}


/**
* 修改部门信息
*/
@RequestMapping(value = "/departments/{id}", method = RequestMethod.PUT)
public Result update(@PathVariable(name = "id") String id, @RequestBody Department department) throws Exception {
department.setCompanyId(parseCompanyId()); department.setId(id); departmentService.update(department); return Result.SUCCESS();
}


/**
* 删除部门
*/
@RequestMapping(value = "/departments/{id}", method = RequestMethod.DELETE) public Result delete(@PathVariable(name = "id") String id) throws Exception {
departmentService.delete(id); return Result.SUCCESS();
}


/**
* 根据id查询
*/
@RequestMapping(value = "/departments/{id}", method = RequestMethod.GET) public Result findById(@PathVariable(name = "id") String id) throws Exception {
Department department = departmentService.findById(id); return new Result(ResultCode.SUCCESS,department);
}


/**
* 组织架构列表
*/
@RequestMapping(value = "/departments", method = RequestMethod.GET) public Result findAll() throws Exception {
Company company = companyService.findById(parseCompanyId()); List list = departmentService.findAll(parseCompanyId()); return	new Result(ResultCode.SUCCESS,new DeptListResult(company,list));
}
}

1.3前端实现

1.3.1创建模块
(1)使用命令行创建module-departments模块并引入到工程中


itheima moduleAdd departments

(2)在src/main.js中注册模块

import departments from '@/module-departments/' // 组织机构管理
Vue.use(departments, store)

(3)配置路由


import Layout from '@/module-dashboard/pages/layout'
const _import = require('@/router/import_' + process.env.NODE_ENV)

export default [
{
root: true,
path: '/departments', component: Layout, redirect: 'noredirect', name: 'departments', meta: {
title: '组织架构管理', icon: 'architecture'
},
children: [
{
path: 'index',
component: _import('departments/pages/index'), name: 'organizations-index',
meta: {title: '组织架构', icon: 'architecture', noCache: true}
}
]
}
]

1.3.2配置请求API
创建departments.js作为组织机构管理的API公共接口方法


import {
createAPI, createFileAPI
} from '@/utils/request'

export const organList = data => createAPI('/company/departments', 'get', data) export const add = data => createAPI('/company/departments', 'post', data)
export const update = data => createAPI(`/company/departments/${data.id}`, 'put', data) export const detail = data => createAPI(`/company/departments/${data.id}`, 'get', data) export const remove = data => createAPI(`/company/departments/${data.id}`, 'delete', data)
export const changeDept = data => createAPI(`/company/departments/changeDept`, 'put', data)
export const saveOrUpdate = data => {return data.id?update(data):add(data)}

1.3.3构造列表
(1)构造基本页面样式找到
,使用element-ui提供的Card组件构造卡片式容器

template>