2. 数据库设计与用户模块:用户表、角色表、权限表
好,咱们进入第二章。这一章很关键,说白了就是给整个OA系统打地基。数据库设计要是歪了,后面盖多少层楼都得塌。我个人习惯,在写一行代码之前,先把表结构理清楚。你想想看,用户、角色、权限这三张表,几乎是所有企业级应用的标配。
2.1 用户表设计:别只存个用户名
用户表是最基础的。但我见过太多新手,上来就只弄个username和password。嗯,这在OA系统里根本不够用。你得考虑:用户叫什么?手机号多少?头像要不要?状态是启用还是禁用?
我在项目中遇到过最坑的事,就是一开始没留deleted字段。后来要搞软删除,不得不改表结构,还影响了线上数据。所以,我建议你从一开始就把这些字段都加上。
| 字段名 | 类型 | 说明 |
|---|---|---|
| id | bigint | 主键,自增 |
| username | varchar(50) | 登录名,唯一 |
| password | varchar(255) | 加密后的密码 |
| real_name | varchar(50) | 真实姓名 |
| phone | varchar(20) | 手机号 |
| varchar(100) | 邮箱 | |
| avatar | varchar(255) | 头像URL |
| status | tinyint | 0禁用 1启用 |
| deleted | tinyint | 0未删 1已删 |
| create_time | datetime | 创建时间 |
| update_time | datetime | 更新时间 |
2.2 角色表设计:权限的集合体
角色是什么?说白了就是一堆权限的打包。比如「管理员」角色,可能包含「创建用户」、「删除用户」、「查看报表」等权限。而「普通员工」角色,就只有「查看自己的信息」、「提交请假」这些。
角色表本身很简单,但要注意一点:角色和用户是多对多的关系。一个用户可以有多个角色,一个角色也可以属于多个用户。所以我们需要一张中间表。
| 字段名 | 类型 | 说明 |
|---|---|---|
| id | bigint | 主键 |
| role_name | varchar(50) | 角色名称,如"管理员" |
| role_code | varchar(50) | 角色编码,如"ADMIN" |
| description | varchar(255) | 角色描述 |
| status | tinyint | 0禁用 1启用 |
2.3 权限表设计:细到按钮级别
权限表,这是整个权限系统的核心。很多小系统只做到「菜单权限」,就是能看到哪些页面。但OA系统往往需要更细的控制——比如「用户管理」页面里的「新增」按钮,能不能点?
我建议把权限设计成树形结构。举个例子:
- 系统管理(菜单权限)
- 用户管理(页面权限)
- 新增用户(按钮权限)
- 编辑用户(按钮权限)
- 删除用户(按钮权限)
- 角色管理(页面权限)
- 分配权限(按钮权限)
- 用户管理(页面权限)
| 字段名 | 类型 | 说明 |
|---|---|---|
| id | bigint | 主键 |
| perm_name | varchar(50) | 权限名称 |
| perm_code | varchar(100) | 权限编码,如"user:add" |
| parent_id | bigint | 父权限ID,0表示顶级 |
| type | tinyint | 1菜单 2页面 3按钮 |
| sort | int | 排序号 |
| status | tinyint | 0禁用 1启用 |
2.4 数据库初始化脚本编写
好了,表结构设计完了,接下来就是写SQL脚本。我习惯把建表语句、初始数据、索引都放在一个文件里,方便部署时一键执行。
-- 用户表
CREATE TABLE `sys_user` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL COMMENT '登录名',
`password` varchar(255) NOT NULL COMMENT '密码',
`real_name` varchar(50) DEFAULT NULL COMMENT '真实姓名',
`phone` varchar(20) DEFAULT NULL COMMENT '手机号',
`email` varchar(100) DEFAULT NULL COMMENT '邮箱',
`avatar` varchar(255) DEFAULT NULL COMMENT '头像',
`status` tinyint(4) DEFAULT '1' COMMENT '0禁用 1启用',
`deleted` tinyint(4) DEFAULT '0' COMMENT '0未删 1已删',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP,
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';
-- 角色表
CREATE TABLE `sys_role` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`role_name` varchar(50) NOT NULL COMMENT '角色名称',
`role_code` varchar(50) NOT NULL COMMENT '角色编码',
`description` varchar(255) DEFAULT NULL COMMENT '描述',
`status` tinyint(4) DEFAULT '1' COMMENT '0禁用 1启用',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_role_code` (`role_code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='角色表';
-- 权限表
CREATE TABLE `sys_permission` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`perm_name` varchar(50) NOT NULL COMMENT '权限名称',
`perm_code` varchar(100) NOT NULL COMMENT '权限编码',
`parent_id` bigint(20) DEFAULT '0' COMMENT '父权限ID',
`type` tinyint(4) DEFAULT '1' COMMENT '1菜单 2页面 3按钮',
`sort` int(11) DEFAULT '0' COMMENT '排序号',
`status` tinyint(4) DEFAULT '1' COMMENT '0禁用 1启用',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_perm_code` (`perm_code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='权限表';
-- 用户角色关联表
CREATE TABLE `sys_user_role` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`user_id` bigint(20) NOT NULL,
`role_id` bigint(20) NOT NULL,
PRIMARY KEY (`id`),
KEY `idx_user_id` (`user_id`),
KEY `idx_role_id` (`role_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户角色关联表';
-- 角色权限关联表
CREATE TABLE `sys_role_permission` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`role_id` bigint(20) NOT NULL,
`perm_id` bigint(20) NOT NULL,
PRIMARY KEY (`id`),
KEY `idx_role_id` (`role_id`),
KEY `idx_perm_id` (`perm_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='角色权限关联表';
-- 插入初始数据
INSERT INTO `sys_role` (`role_name`, `role_code`, `description`) VALUES
('超级管理员', 'SUPER_ADMIN', '拥有所有权限'),
('普通用户', 'USER', '基础用户权限');
INSERT INTO `sys_user` (`username`, `password`, `real_name`, `status`) VALUES
('admin', '$2a$10$...', '系统管理员', 1);
嗯,到这里,数据库设计这块就差不多了。你可能会问:「为什么用户和角色之间要加一张关联表?」其实原因很简单——为了灵活。如果用户只能有一个角色,那直接在用户表加个role_id字段就行了。但现实是,一个人可能既是「部门经理」又是「项目管理员」,多对多的关系必须用中间表。
下一章,咱们开始写代码。我会带着你从零搭建项目骨架,把Spring Boot项目跑起来。到时候这些表就会真正「活」过来。