1. 用户信息管理模块
1.1. 功能设计
(说明:基于概要设计划定的应用功能开展详细设计,包括业务逻辑的抽取及设计、数据访问设计等,粒度需至少达到函数的伪代码实现级别。)
用户信息管理模块的功能主要围绕着用户信息管理进行,包含以下功能
新增用户:
- 新增用户信息: 支持添加新用户信息,添加信息项分为必填项和非必填项;必填项要求在创建新账号时必须明确的内容,如用户名、密码。
- 用户信息导入导出: 支持将选中的用户信息或全量的用户信息导出到 CSV 表格,也可以通过 CSV 表格批量导入创建新用户。
删除用户:
- 删除用户信息: 支持删除已经存在的用户信息。
查询信息:
- 查询用户信息: 支持根据用户 ID 查询该用户信息,查询的用户信息范围根据权限范围返回,admin 管理员可以查询用户所有信息。
- 获取全量用户信息: 支持获取系统中全量的用户信息,在一些集成的场景下需要批量同步用户信息时使用。
修改信息
- 修改用户信息: 支持修改用户信息
- 信息修改审核: 支持修改信息后需要通过审核才能正式生效
- 密码定期修改功能: 密码需要定期修改,如3个月,到期后如果密码没有修改会锁定账号无法登录。
认证信息:
- 用户信息登录认证: 支持根据传递的用户名称、密码等信息,判断账号状态后返回认证结果
- Token 颁发: 通过认证的请求,会颁发一个 Token。认证成功后,需要返回一个 Token 信息。返回信息时,如果用户状态是禁用,或离职时,只返回状态,不返回其他用户信息,用户不能登录系统。
- Token 校验: 认证的 Token 在有效期内都可以登录
信息项读取权限:
- 信息项权限管理: 支持不同的应用或客户端访问用户中心时由于权限不同,返回的内容差异显示。提供 API 获取或同步统一用户中心的信息时,需要进行一定的安全限制,不能默认可以查询用户的所有营私信息。设计一个安全信息管理功能,每个业务系统或调用接口查询的请求,都需要携带一个 appid,给appid定义可查询的字段
- appid为用户 ID时:在登录其他系统的情况下会以用户信息查询统一用户中心中的用户信息,这时返回:用户ID、用户名称、用户邮箱、用户公司、用户组织等基本信息
- appid为 OA 系统时:可以获取所有用户细腻下
- appid为集成的第三方业务系统时:根据系统的能力和场景,适当的配置用户可以获取的用户信息字段
单点登录
提供用户登录能力,支持
- ID 账号密码登录
- 手机验证码登录
- 邮箱验证登录
- 社会化登录(微信、钉钉等)
会话保持
- 支持会话保持:
- 登录记忆。将登录信息缓存在浏览器中,下次登录时自动填充认证信息
支持在同一个浏览器中,多个不同系统使用同一个认证缓存
- 支持多种协议。OAuth2、OIDC、SAML、LDAP 等多种协议。
登出系统:
- 站点没有跳过二步确认:站点侧自行完成会话清理后,可以认为已经完成登出。
- 站点配置了跳过二步确认:站点侧完成会话清理后,需要主动向用户发起一个HTTP 302跳转
1.2. 数据库设计
(说明:遵循和依据公司SG-CIM标准开展物理模型设计,具体设计内容包括:表空间划分、缓冲池定义、序列器定义、数据库配置参数建议、公共编码及数据字典、表设计、视图设计、存储过程设计、函数设计、索引设计等。同时开展物理模型与逻辑模型关系构建,并形成“物理模型遵从逻辑模型映射清单”。)
USER
表
用户基础表,基础相关信息维护,每个字段具有全局唯一性
字段 | 数据类型 | 主键 | 外键 | 必填 | 描述 |
---|---|---|---|---|---|
id | int(8) | TRUE | TRUE | 表的 ID 字段,自增字段 | |
username | varchar(100) | TRUE | TRUE | 用户名称 | |
nickname | varchar(100) | 用户的昵称或花名 | |||
password | varchar(256) | TRUE | 账号登录密码,需要加密 | ||
sex | int(1) | 用户的性别 | |||
nationality | varchar(4) | 国籍:企业成员来自多个不同的国家或地区 | |||
marital_status | varchar(4) | 婚姻状态:结婚状态,如未婚、已婚、离婚 | |||
politics_status | varchar(4) | 政治面貌:群众、团圆、中共党员 | |||
birthday | varchar(11) | 出生年月 | |||
head_picture | blob | 头像 | |||
card_type | varchar(11) | 证件类型:身份证、军官证等 | |||
id_card | varchar(11) | 证件号码:如身份证号码 | |||
native_place | varchar(11) | 籍贯:如北京 | |||
wechart_id | varchar(11) | 个人微信账号 | |||
dingding_id | varchar(11) | 个人钉账号 | |||
phone_number | varchar(11) | 个人手机号码 | |||
personal_email | varchar(30) | 个人邮箱 | |||
status | varchar(30) | 账号状态:正常、异常,异常的账号不能登录系统,异常是指在所有子公司都离职、账号锁定。 | |||
first_working_day | varchar(11) | 参加工作时间:便于企业管理员工的社会工龄和假期 | |||
company_id | varchar(11) | 所属公司,企业可能会有多个子公司,保存公司 ID 列表。假设组织第二级为公司,保存所属第二级组织的 ID | |||
bank_id | varchar(11) | 银行开卡信息,发工资用户的 | |||
relation_id | varchar(11) | 列表类型,与该用户有相关的人员信息 | |||
education_id | varchar(30) | 列表类型,教育经历 | |||
certification_id | varchar(30) | 列表类型,认证职称 | |||
experience_id | varchar(11) | 列表类型,工作经历 | |||
create_datetime | 数据创建时间 | ||||
modify_datetime | 数据修改时间 |
COMPANY_USER
表
用户所属的公司的信息,通过 username 和 company 进行关联
字段 | 数据类型 | 主键 | 外键 | 必填 | 描述 |
---|---|---|---|---|---|
company_id | int(8) | TRUE | TRUE | 表的 ID 字段,自增字段 | |
username | varchar(100) | TRUE | TRUE | 用户名称 | |
company | varchar(30) | TRUE | 所属公司,企业可能会有多个子公司,保存公司 ID 列表。假设组织第二级为公司,保存所属第二级组织的 ID | ||
job_email | varchar(30) | 公司邮箱 | |||
organization | varchar(30) | 所属部门:所属的组织,建议保存组织的 ID。假设为第六级目录,保存目录 ID | |||
address | varchar(30) | 办公地点:如果公司有多个办公地点 | |||
staff_type | varchar(30) | 用户分类:用户可能是内部试用期员工、内部正式员工、外包员工、外部临时员工等 | |||
job_title | varchar(30) | 岗位名称:所属的岗位 ID | |||
professional_level | varchar(30) | 业级别:面向技术人员的级别信息,如 P7 | |||
management_level | varchar(30) | 管理级别:管理人员的级别信息,如 M8 | |||
date_of_entry | varchar(30) | 入职日期 | |||
date_of_conversion | varchar(30) | 转正日期 | |||
date_of_departure | varchar(30) | 离职日期 | |||
leader_name | varchar(30) | 行政汇报人:就是 Leader 是谁 | |||
staff_phone | varchar(30) | 办公室电话:如办公司座机电话 | |||
work_home | varchar(30) | 办公居住地:上班时居住的地方 | |||
status | varchar(30) | 在职状态:如在职、离职、停职 | |||
create_datetime | 数据创建时间 | ||||
modify_datetime | 数据修改时间 |
JOB_TITLE
表
岗位名称:所属的岗位 ID
字段 | 数据类型 | 主键 | 外键 | 必填 | 描述 |
---|---|---|---|---|---|
id | int(8) | TRUE | TRUE | 表的 ID 字段,自增字段 | |
title | varchar(100) | TRUE | TRUE | 用户名称 | |
create_datetime | 数据创建时间 | ||||
modify_datetime | 数据修改时间 |
BANK
表
银行开卡信息,发工资用户的
字段 | 数据类型 | 主键 | 外键 | 必填 | 描述 |
---|---|---|---|---|---|
bank_id | int(8) | TRUE | TRUE | 表的 ID 字段,自增字段 | |
username | varchar(100) | TRUE | TRUE | 用户名称 | |
bank_username | varchar(100) | 开户者 | |||
bank_name | varchar(30) | 开户银行 | |||
branch_bank_name | varchar(30) | 开户支行名称 | |||
bank_account | varchar(30) | 银行账号 | |||
bank_city | varchar(30) | 开户城市 | |||
create_datetime | 数据创建时间 | ||||
modify_datetime | 数据修改时间 |
RELATION_USER
表
与该用户有相关的人员信息
家庭成员信息:便于关怀
紧急联系人:万一有啥事,除了本人要能联系到其他强关系人员
字段 | 数据类型 | 主键 | 外键 | 必填 | 描述 |
---|---|---|---|---|---|
relation_id | int(8) | TRUE | TRUE | 表的 ID 字段,自增字段 | |
emergency_contact | bool | 是否是紧急联系人 | |||
relation_name | 姓名 | ||||
relation_sex | 性别 | ||||
relation_phone | 联系电话 | ||||
relation_type | 与本人关系 | ||||
relation_comapny | 工作单位 | ||||
relation_job | 工作岗位 | ||||
create_datetime | 数据创建时间 | ||||
modify_datetime | 数据修改时间 |
EDUCATION
表:教育信息
大学、研究生等相关教育信息
字段 | 数据类型 | 主键 | 外键 | 必填 | 描述 |
---|---|---|---|---|---|
education_id | int(8) | TRUE | TRUE | 表的 ID 字段,自增字段 | |
education_type | 学历性质:如全日制、在职 | ||||
education_level | 学历:如本科、博士 | ||||
education_school | 学校 | ||||
education_degree | 学位 | ||||
education_major | 专业 | ||||
education_start_data | 开始时间:该条学历入学时间 | ||||
education_end_data | 结束时间 | ||||
education_end_type | 毕业类型:毕业、结业 | ||||
create_datetime | 数据创建时间 | ||||
modify_datetime | 数据修改时间 |
CERTIFICATION
表:职称与证书
便于工作安排和能力评估
- 国家认证的职称:如软考
- 第三方公司的认证:如 CCNA、ACK
- 技能证书:如 CET4
字段 | 数据类型 | 主键 | 外键 | 必填 | 描述 |
---|---|---|---|---|---|
certification_id | int(8) | TRUE | TRUE | 表的 ID 字段,自增字段 | |
certification_name | 职称名称 | ||||
certification_number | 职称证书编号 | ||||
certification_unit | 发证单位 | ||||
certification_date | 发证日期 | ||||
certification_validity_period | 有效期 | ||||
certification_attachment | 证书扫描件 | ||||
create_datetime | 数据创建时间 | ||||
modify_datetime | 数据修改时间 |
JOB_EXPERIENCE
表:工作经历
工作经历:之前参加过哪些工作
字段 | 数据类型 | 主键 | 外键 | 必填 | 描述 |
---|---|---|---|---|---|
experience_id | int(8) | TRUE | TRUE | 表的 ID 字段,自增字段 | |
start_data | 开始时间 | ||||
end_data | 结束时间 | ||||
job_company | 工作单位 | ||||
job_post | 工作岗位 | ||||
job_content | 主要工作内容 | ||||
create_datetime | 数据创建时间 | ||||
modify_datetime | 数据修改时间 |
1.3. 接口设计
(说明:接口从类型上分为前台接口和后台接口,在设计上包括接口实现和接口引用。对于接口引用须要注明其来源。对于接口实现描述其输入、输出、频度、数据量、实现方式、接口承载业务描述等,粒度需至少达到函数的伪代码实现级别。)
URL 接口设计:
/api/v1/user
: [GET] 返回用户ID列表/api/v1/user/XXX
: [GET] 返回 XXX 用户的信息/api/v1/user
: [POST] 新增用户信息/api/v1/user
: [DELETE] 删除用户的信息/api/v1/user
: [PUT] 更新用户的信息
请求头设计:
{
"header": "xxxx"
}
响应设计:
{
"code": 200,
"requestid": "bcdf0f8b-767d-4a9e-b63f-e188ce5af96f",
"data": "xxxxx",
"msg": "fds"
}
响应状态码设计:
状态码 | 状态含义描述 |
---|---|
200~299 | 表示操作成功 |
200 | 操作成功,正常返回 |
201 | 操作成功,已经正在处理该请求 |
300~399 | 表示参数方面的异常 |
300 | 参数类型错误 |
301 | 参数格式错误 |
302 | 参数超出正常取值范围 |
303 | token过期 |
304 | token无效 |
400~499 | 表示请求地址方面的异常: |
400 | 找不到地址 |
500~599 | 表示内部代码异常 |
500 | 服务器代码异常 |
1.4. 类与方法设计
类设计:
- UserController : 用户管理
- UserLoginController:登录管理
- AppAuthorityController:应用集成权限管理
UserController 方法设计:
- addUser:增加用户信息
- delUser:删除用户信息
- updateUser:更新用户信息
- getUser:获取指定用户信息
- getAllUser:获取所有用户信息
- checkUserValidity: 判断用户状态是否正常,离职、锁定为不正常,无法登录系统
LoginController 方法设计
- login:登录
- logout:登出
- createToken: 创建 Token
- checkTokenValidity:判断 Token 有效性
AppAuthorityController 方法设计
- getAppField:获取 app 拥有权限的字段
1.5. 参考实现
UserController.java
@RestController(/v1)
@API(tag=”用户相关接口”)
public class UserController {
@Autowired
private UserJPARepository userJPARepository;
/**
* 查询用户列表
* @return
*/
@GetMapping(value = "/user")
public List<User> findUserList(){
return userJPARepository.findAll();
}
/**
* 根据Id查询一个用户
* @param id
* @return
*/
@GetMapping(value = "/user/query/{id}")
public User findUserOne(@PathVariable("id") Integer id){
return userJPARepository.findOne(id);
}
/**
* 添加用户
* @param name
* @param age
* @param country
* @return
*/
@PostMapping(value = "/user")
public User addUser(@RequestParam("name") String name, @RequestParam("age") int age,
@RequestParam("country") String country){
User user = new User();
user.setName(name);
user.setAge(age);
user.setCountry(country);
return userJPARepository.save(user);
}
/**
* 删除用户
* @param id 用户编号
* @return
*/
@DeleteMapping(value = "/user/{id}")
public List<User> deleteUser(@PathVariable("id") Integer id){
userJPARepository.delete(id);
return userJPARepository.findAll();
}
/**
* 更新用户
* @param id
* @param name
* @param age
* @param country
* @return
*/
@PutMapping(value = "/user/{id}")
public User updateUser(@PathVariable("id") Integer id, @RequestParam("name") String name,
@RequestParam("age") int age, @RequestParam("country") String country){
User user = userJPARepository.findById(id);
user.setName(name);
user.setAge(age);
user.setCountry(country);
return userJPARepository.save(user);
}
/**
* 根据国家查询用户
* @param country
* @return
*/
@GetMapping(value = "/user/{country}")
public List<User> findByCountry(@PathVariable("country") String country){
return userJPARepository.findByCountry(country);
}
}