“1028审批权限修改v0.1”

This commit is contained in:
weizhong committed 2025-10-28 14:08:52 +08:00
1 parent 851ebe86e4
commit 76ee97a90c
21 files changed
+2054 -1370

No files matched your search

+157 -7
View File
@@ -24,9 +24,26 @@
**模块名称**:overseas / 出国申请管理
**基础路径**:`/api/rs/overseas`
**版本**:v1.0
**版本**:v1.1
**负责人**:weizzzz
**更新时间**:2025-01-28
**更新时间**:2025-10-28
### 🆕 最近更新
**v1.1 (2025-10-28) - 分级审批权限升级**
- ✅ **审批权限升级为五级审批制度**
- 新增 `rs:overseas:approve1-5` 五个分级审批权限
- 保留 `rs:overseas:approve` 作为通用审批权限
- ✅ **Controller层采用OR模式权限验证**
- 用户拥有任一审批权限即可访问审批接口
- 解决部门负责人403权限错误问题
- ✅ **Service层增加审批级别验证**
- 新增 `validateApproverLevel()` 方法
- 精确验证用户权限是否匹配申请的审批级别
- 防止越级审批
- ✅ **前端按钮权限优化**
- 审批按钮支持多级权限显示
- 改善用户体验,按钮显示逻辑更合理
### 模块功能
@@ -59,12 +76,106 @@
- `rs:overseas:record:create` - 创建记录权限
- `rs:overseas:record:complete` - 完成记录权限
#### 出国审批权限
- **权限前缀**:`rs:overseas:approval:`
- **权限列表**:
#### 出国审批权限(🆕 2025-10-28 更新为五级审批)
- **权限前缀**:`rs:overseas:`
- **审批记录查看权限**:
- `rs:overseas:approval:list` - 查询审批记录列表权限
- `rs:overseas:approval:query` - 查询审批记录详情权限
- `rs:overseas:approval:export` - 导出审批记录权限
- **分级审批权限**(五级审批制度):
- `rs:overseas:approve` - 通用审批权限(超级管理员/高级审批者,可审批任意级别)
- `rs:overseas:approve1` - 第1级:部门负责人审批权限
- `rs:overseas:approve2` - 第2级:人事处审批权限
- `rs:overseas:approve3` - 第3级:纪委审批权限
- `rs:overseas:approve4` - 第4级:学院分管领导审批权限
- `rs:overseas:approve5` - 第5级:学院党委书记审批权限
- **权限使用说明**:
- 审批接口采用 **OR模式**,用户拥有以上任一权限即可调用接口
- 具体审批权限在业务层验证,必须匹配申请的 `approval_level`
- 部门负责人通过 `rs:overseas:approve1` 权限识别,自动应用部门数据过滤
### 🔐 数据权限控制
#### 权限分级说明
出国申请系统采用**基于角色和部门的多级数据权限控制**,确保用户只能访问其权限范围内的数据。
#### 角色权限矩阵
| 角色 | 角色标识 | 数据访问范围 | 可见申请范围 | 备注 |
|------|----------|------------|-------------|------|
| **超级管理员** | `admin` | 全局数据 | 所有申请 | 不受任何限制 |
| **人事管理员** | `rs-admin` | 全局数据 | 所有申请 | 仅当不是部门负责人时 |
| **申请人** | `rs-Applicant` | 个人数据 | 仅自己的申请 | 只能查看和管理自己的申请 |
| **部门负责人** | 具有`rs:overseas:approve1`权限 | 本部门数据 | 本部门所有申请 | **优先级最高** |
| **普通审批人** | 其他审批权限 | 分配数据 | 分配给自己的审批 | 只能看到分配的审批任务 |
#### 部门权限过滤规则(🆕 2025-01-28)
**核心原则**:部门负责人**只能看到本部门成员提交的申请**,不能看到其他部门的申请。
**实现逻辑**:
1. **判断用户是否为部门负责人**(三种方式任选其一):
- 具有 `rs:overseas:approve1` 权限
- 具有 `dept_head_role` 角色
- 具有 `overseas:application:dept_head:approve` 权限(兼容旧版)
2. **应用部门过滤**:
- 查询条件:`申请人的dept_id = 当前用户的dept_id`
- SQL实现:通过 `sys_user` 表关联,筛选申请人所属部门
- **重要**:不限制审批人(approverId),只限制申请人部门(deptId)
3. **权限优先级**(从高到低):
```
超级管理员 > 申请人(自己的数据)> 部门负责人(本部门)> 人事管理员(全局)> 普通审批人(分配数据)
```
**示例场景**:
假设有以下用户和部门:
- **张三**:`dept_id = 001`(测试部门A),角色:申请人
- **李四**:`dept_id = 001`(测试部门A),角色:部门负责人
- **王五**:`dept_id = 002`(测试部门B),角色:部门负责人
- **赵六**:`dept_id = 003`(测试部门C),角色:部门负责人
**张三提交申请后:**
- ✅ **李四**(同部门):可以看到张三的申请
- ❌ **王五**(不同部门):不能看到张三的申请
- ❌ **赵六**(不同部门):不能看到张三的申请
**技术实现**:
```java
// Service层权限过滤逻辑
private void applyDeptPermissionFilter(RsOverseasApprovalQuery query) {
// 1. 判断是否为部门负责人
boolean isDeptApprover = isDeptApprover(currentUserId);
// 2. 如果是部门负责人,只设置部门过滤
if (isDeptApprover) {
query.setDeptId(currentDeptId); // 只应用部门过滤
return; // 不设置approverId,避免过度限制
}
}
```
```xml
<!-- Mapper XML中的部门权限过滤SQL -->
<if test="deptId != null">
AND EXISTS (
SELECT 1 FROM sys_user u
WHERE u.user_id = app.applicant_id
AND u.dept_id = #{deptId}
)
</if>
```
**相关文档**:
- 测试指南:`docs/测试文档/出国申请部门权限过滤测试指南.md`
- 验证脚本:`部门权限过滤验证脚本.sql`
- 代码实现:`RsOverseasApprovalServiceImpl.java`
---
@@ -152,6 +263,7 @@ interface OverseasApplicationVO {
accommodationPlan: string; // 住宿安排
transportationPlan: string; // 交通安排
status: string; // 申请状态编码
approvalStatus: string; // 工作流状态编码
currentApprover: string; // 当前审批人
approvalLevel: string; // 审批级别
applyTime: string; // 申请时间
@@ -162,6 +274,7 @@ interface OverseasApplicationVO {
updateTime: string; // 更新时间
// 显示字段
statusText: string; // 状态文本
approvalStatusText: string; // 工作流状态文本
purposeText: string; // 目的文本
budgetSourceText: string; // 经费来源文本
approvalLevelText: string; // 审批级别文本
@@ -403,7 +516,27 @@ interface OverseasApplicationForm {
### 4. 审批出国申请
**接口地址**:`POST /rs/overseas/application/approve`
**权限要求**:`rs:overseas:application:approve`
**权限要求**:`rs:overseas:approve` (通用) 或 `rs:overseas:approve1-5` (分级) - **支持多级审批权限(2025-10-28更新)**
#### 🔴 权限说明(重要更新)
**分级审批权限体系**(OR模式,满足任一权限即可访问接口):
- `rs:overseas:approve` - 通用审批权限(超级管理员/高级审批者)
- `rs:overseas:approve1` - 第1级:部门负责人审批权限
- `rs:overseas:approve2` - 第2级:人事处审批权限
- `rs:overseas:approve3` - 第3级:纪委审批权限
- `rs:overseas:approve4` - 第4级:学院分管领导审批权限
- `rs:overseas:approve5` - 第5级:学院党委书记审批权限
**权限验证机制**:
1. **接口层验证**:Controller使用 `@SaCheckPermission(value={...}, mode=SaMode.OR)`,满足任一权限即可调用接口
2. **业务层验证**:Service层根据申请的 `approval_level` 字段验证用户是否拥有对应级别的审批权限
3. **权限不匹配处理**:如果用户审批级别与申请要求不符,返回业务异常"您没有第X级审批权限"
**示例场景**:
- 部门负责人(拥有 `approve1`)只能审批 `approval_level=1` 的申请
- 尝试审批 `approval_level=2` 的申请将被拒绝
- 拥有 `rs:overseas:approve` 通用权限的用户可以审批任意级别
#### 请求参数
@@ -412,6 +545,7 @@ interface ApprovalRequest {
applicationId: number | string; // 申请ID(必须)
approvalStatus: string; // 审批状态:1-通过,2-拒绝(必须)
approvalOpinion?: string; // 审批意见
taskId?: string; // 🔴 工作流任务ID(可选,支持标准工作流模式)
}
```
@@ -600,6 +734,20 @@ referer: http://localhost
| 3 | 已取消 | 申请被申请人主动取消 |
| 4 | 已完成 | 出国活动已完成 |
### 工作流状态 (approvalStatus)
| 编码 | 含义 | 描述 |
| ----------- | ------ | ------------------------ |
| cancel | 已撤销 | 申请人主动撤销申请 |
| draft | 草稿 | 申请尚未提交,处于编辑状态 |
| waiting | 待审核 | 申请已提交,正在审批流程中 |
| finish | 已完成 | 所有审批节点都已通过,流程结束 |
| invalid | 已作废 | 申请因某种原因被标记为无效 |
| back | 已退回 | 审批被拒绝,退回给申请人修改 |
| termination | 已终止 | 流程被管理员或系统强制终止 |
> **📝 说明**:工作流状态由 Warm-Flow 工作流引擎自动管理,用于总体流程监听和状态跟踪。
### 出国目的 (purpose)
| 编码 | 含义 | 描述 |
@@ -630,7 +778,7 @@ referer: http://localhost
| 2 | 分管领导 | 第二级审批:分管领导 |
| 3 | 校领导 | 第三级审批:校领导 |
### 审批状态 (approvalStatus)
### 审批记录状态 (审批记录表中的 approvalStatus)
| 编码 | 含义 | 描述 |
| ---- | ------ | ------------------------ |
@@ -638,6 +786,8 @@ referer: http://localhost
| 1 | 通过 | 审批通过 |
| 2 | 拒绝 | 审批拒绝 |
> **⚠️ 注意**:此状态是审批记录表中的状态,与申请表中的工作流状态(approvalStatus)是不同的字段。
### 完成状态 (completionStatus)
> **⚠️ 重要说明**:完成状态(completionStatus)与申请状态(status)是两个不同的概念!