OA系统项目总结
GitHub: https://github.com/csushl/imooc-oa
涉及技术
MySQL、MyBatis、Alibaba Druid、Servlet、Vue、Element Plus.
项目亮点
项目基于MVC模式进行开发,通过MVC的设计使得各层之间有效解藕。
使用了Vue3、Element Plus前端技术。
本项目主要是请假流程的模块,针对于请假流程,设计了process flow任务流进行处理,这是底层设计的亮点.
对于MVC的理解

基于MVC的软件分层设计

每一层各司其职,从后往前依次推进(不允许出现夸层调用):
- 最底层是数据持久层,使用MyBatis的mapper完成数据库的增删改查。
- 业务逻辑层是负责处理响应业务逻辑的地方,并且是完成业务的主体方法。
- 控制层:接收前端传来的数据、根据前端传来的数据调用相应的业务逻辑、最后将业务逻辑返回的数据进行包装,返回给前端。
- 视图层指责为:向Servlet提交数据、从Servlet接收相应数据显示出来,前端进行渲染。
RBAC的实现原理
基于角色进行权限控制

RBAC的核心是角色,角色是进行数据绑定核心。
工作流程设计
请假流程
- 部门经理只允许批准本部门员工申请
- 部门经理请假需直接由总经理审批
- 总经理提起请假申请,系统自动批准通过

设计约束
- 每个请假单位对应一个审批流程
- 请假单创建后,按业务规则生成部门经理、总经理审批任务
- 审批任务的经办人只能审批自己辖区内的请假申请
- 所有审批任务“通过”,代表请假已经批准
- 任意审批任务“驳回”操作,其余审批任务取消,请假申请被驳回
- 请假流程中任意节点产生的操作都要生成对应的系统通知
数据库设计
RBAC表设计
/* Navicat Premium Data Transfer Source Server : localhost Source Server Type : MySQL Source Server Version : 80016 Source Host : localhost:3306 Source Schema : imooc_oa Target Server Type : MySQL Target Server Version : 80016 File Encoding : 65001 Date: 12/06/2021 18:14:52 */ SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0;
sys_node 系统功能定义表
DROP TABLE IF EXISTS `sys_node`;
CREATE TABLE `sys_node` (
`node_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '节点编号',
`node_type` int(255) NOT NULL COMMENT '节点类型 1-模块 2-功能',
`node_name` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '节点名称',
`url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '功能地址',
`node_code` int(255) NOT NULL COMMENT '节点编码,用于排序',
`parent_id` bigint(20) NULL DEFAULT NULL COMMENT '上级节点编号',
PRIMARY KEY (`node_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of sys_node
-- ----------------------------
INSERT INTO `sys_node` VALUES (1, 1, '行政审批', NULL, 1000000, NULL);
INSERT INTO `sys_node` VALUES (2, 2, '通知公告', '/notice.html', 1000001, 1);
INSERT INTO `sys_node` VALUES (3, 2, '请假申请', '/leave_form.html', 1000002, 1);
INSERT INTO `sys_node` VALUES (4, 2, '请假审批', '/audit.html', 1000003, 1);
sys_role 系统角色表
DROP TABLE IF EXISTS `sys_role`;
CREATE TABLE `sys_role` (
`role_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '角色编号',
`role_description` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '角色描述',
PRIMARY KEY (`role_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of sys_role
-- ----------------------------
INSERT INTO `sys_role` VALUES (1, '业务岗角色');
INSERT INTO `sys_role` VALUES (2, '管理岗角色');
sys_role_node 系统角色功能表
DROP TABLE IF EXISTS `sys_role_node`;
CREATE TABLE `sys_role_node` (
`rn_id` bigint(20) NOT NULL AUTO_INCREMENT,
`role_id` bigint(20) NOT NULL,
`node_id` bigint(20) NOT NULL,
PRIMARY KEY (`rn_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 8 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of sys_role_node
-- ----------------------------
INSERT INTO `sys_role_node` VALUES (1, 1, 1);
INSERT INTO `sys_role_node` VALUES (2, 1, 2);
INSERT INTO `sys_role_node` VALUES (3, 1, 3);
INSERT INTO `sys_role_node` VALUES (4, 2, 1);
INSERT INTO `sys_role_node` VALUES (5, 2, 2);
INSERT INTO `sys_role_node` VALUES (6, 2, 3);
INSERT INTO `sys_role_node` VALUES (7, 2, 4);
sys_role_user 系统角色用户表
DROP TABLE IF EXISTS `sys_role_user`;
CREATE TABLE `sys_role_user` (
`ru_id` bigint(20) NOT NULL AUTO_INCREMENT,
`role_id` bigint(20) NOT NULL,
`user_id` int(11) NOT NULL,
PRIMARY KEY (`ru_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 12 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of sys_role_user
-- ----------------------------
INSERT INTO `sys_role_user` VALUES (1, 2, 1);
INSERT INTO `sys_role_user` VALUES (2, 2, 2);
INSERT INTO `sys_role_user` VALUES (3, 1, 3);
INSERT INTO `sys_role_user` VALUES (4, 1, 4);
INSERT INTO `sys_role_user` VALUES (5, 1, 5);
INSERT INTO `sys_role_user` VALUES (6, 2, 6);
INSERT INTO `sys_role_user` VALUES (7, 1, 7);
INSERT INTO `sys_role_user` VALUES (8, 1, 8);
INSERT INTO `sys_role_user` VALUES (9, 1, 9);
INSERT INTO `sys_role_user` VALUES (10, 1, 10);
sys_user 系统用户表
DROP TABLE IF EXISTS `sys_user`;
CREATE TABLE `sys_user` (
`user_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '用户编号',
`username` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '用户名',
`password` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '密码',
`employee_id` bigint(20) NOT NULL COMMENT '员工编号',
`salt` int(255) NOT NULL COMMENT '盐值',
PRIMARY KEY (`user_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 11 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of sys_user
-- ----------------------------
INSERT INTO `sys_user` VALUES (1, 'm8', 'f57e762e3fb7e1e3ec8ec4db6a1248e1', 1, 188);
INSERT INTO `sys_user` VALUES (2, 't7', 'dcfa022748271dccf5532c834e98ad08', 2, 189);
INSERT INTO `sys_user` VALUES (3, 't6', '76ce11f8b004e8bdc8b0976b177c620d', 3, 190);
INSERT INTO `sys_user` VALUES (4, 't5', '11f04f04054772bc1a8fdc41e70c7977', 4, 191);
INSERT INTO `sys_user` VALUES (5, 't4', '8d7713848189a8d5c224f94f65d18b06', 5, 192);
INSERT INTO `sys_user` VALUES (6, 's7', '044214e86e07d96c97de79a2222188cd', 6, 193);
INSERT INTO `sys_user` VALUES (7, 's6', 'ecbd2f592ee65838328236d06ce35252', 7, 194);
INSERT INTO `sys_user` VALUES (8, 's5', '846ecc83bba8fe420adc38b39f897201', 8, 195);
INSERT INTO `sys_user` VALUES (9, 's4', 'c1e523cd2daa02f6cf4b98b2f26585fd', 9, 196);
INSERT INTO `sys_user` VALUES (10, 's3', '89e89f369e07634fbb2286efffb9492b', 10, 197);
SET FOREIGN_KEY_CHECKS = 1;
adm_department 部门表
DROP TABLE IF EXISTS `adm_department`;
CREATE TABLE `adm_department` (
`department_id` bigint(20) NOT NULL AUTO_INCREMENT,
`department_name` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
PRIMARY KEY (`department_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of adm_department
-- ----------------------------
INSERT INTO `adm_department` VALUES (1, '总裁办');
INSERT INTO `adm_department` VALUES (2, '研发部');
INSERT INTO `adm_department` VALUES (3, '市场部');
adm_employee 员工表
DROP TABLE IF EXISTS `adm_employee`;
CREATE TABLE `adm_employee` (
`employee_id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`department_id` bigint(20) NOT NULL,
`title` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`level` int(255) NOT NULL,
PRIMARY KEY (`employee_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 11 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of adm_employee
-- ----------------------------
INSERT INTO `adm_employee` VALUES (1, '张晓涛', 1, '总经理', 8);
INSERT INTO `adm_employee` VALUES (2, '齐紫陌', 2, '部门经理', 7);
INSERT INTO `adm_employee` VALUES (3, '王美美', 2, '高级研发工程师', 6);
INSERT INTO `adm_employee` VALUES (4, '宋彩妮', 2, '研发工程师', 5);
INSERT INTO `adm_employee` VALUES (5, '欧阳峰', 2, '初级研发工程师', 4);
INSERT INTO `adm_employee` VALUES (6, '张世豪', 3, '部门经理', 7);
INSERT INTO `adm_employee` VALUES (7, '王子豪', 3, '大客户经理', 6);
INSERT INTO `adm_employee` VALUES (8, '段峰', 3, '客户经理', 5);
INSERT INTO `adm_employee` VALUES (9, '章雪峰', 3, '客户经理', 4);
INSERT INTO `adm_employee` VALUES (10, '李莉', 3, '见习客户经理', 3);
请假流程中的表设计
adm_leave_form 请假申请表
DROP TABLE IF EXISTS `adm_leave_form`;
CREATE TABLE `adm_leave_form` (
`form_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '请假单编号',
`employee_id` bigint(20) NOT NULL COMMENT '员工编号',
`form_type` int(255) NOT NULL COMMENT '请假类型 1-事假 2-病假 3-工伤假 4-婚假 5-产假 6-丧假',
`start_time` datetime(0) NOT NULL COMMENT '请假起始时间',
`end_time` datetime(0) NOT NULL COMMENT '请假结束时间',
`reason` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '请假事由',
`create_time` datetime(0) NOT NULL COMMENT '创建时间',
`state` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'processing-正在审批 approved-审批已通过 refused-审批被驳回',
PRIMARY KEY (`form_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 40 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
adm_process_flow 执行流程表
DROP TABLE IF EXISTS `adm_process_flow`;
CREATE TABLE `adm_process_flow` (
`process_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '处理任务编号',
`form_id` bigint(20) NOT NULL COMMENT '表单编号',
`operator_id` bigint(20) NOT NULL COMMENT '经办人编号',
`action` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'apply-申请 audit-审批',
`result` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT 'approved-同意 refused-驳回',
`reason` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '审批意见',
`create_time` datetime(0) NOT NULL COMMENT '创建时间',
`audit_time` datetime(0) NULL DEFAULT NULL COMMENT '审批时间',
`order_no` int(11) NOT NULL COMMENT '任务序号',
`state` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'ready-准备 process-正在处理 complete-处理完成 cancel-取消',
`is_last` int(255) NOT NULL COMMENT '是否最后节点,0-否 1-是',
PRIMARY KEY (`process_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 96 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
sys_notice 消息通知表
DROP TABLE IF EXISTS `sys_notice`;
CREATE TABLE `sys_notice` (
`notice_id` bigint(20) NOT NULL AUTO_INCREMENT,
`receiver_id` bigint(20) NOT NULL,
`content` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`create_time` datetime(0) NOT NULL,
PRIMARY KEY (`notice_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 29 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
敏感数据加密
使用MD5加盐设计。MD5可以产生出128的散列值,可以唯一标识原数据。
MD5特点:
- 压缩性,MD5生成的摘要长度固定
- 抗修改,源数据哪怕有一个字节变化,MD5也会有巨大差异
- 不可逆,无法通过MD5反向推算源数据
项目中应用:
/**
* 对源数据加盐混淆后生成MD5摘要
* @param source 源数据
* @param salt 盐值
* @return MD5摘要
*/
public static String md5Digest(String source,Integer salt){
char[] chars = source.toCharArray();
for (int i= 0 ; i< chars.length ; i++){
chars[i] = (char) (chars[i] + salt);
}
String target = new String(chars);
//System.out.println(target);
String md5 = DigestUtils.md5Hex(target);
return md5;
}

浙公网安备 33010602011771号