This commit is contained in:
27942
2026-01-14 10:47:59 +08:00
parent 497e25d4f7
commit 38c2e4267d
10 changed files with 0 additions and 2583 deletions

View File

@@ -1,187 +0,0 @@
# 审核逻辑修复完成报告
## 修复时间
2024年
## 修复内容
### ✅ 已修复的4个审核类型
#### 1. "入职财务登记" (第936-975行)
**修复前:** 直接抄送财务,不支持多人团队按顺序流转
**修复后:** 使用统一的`process_approval_flow`函数
```python
# 使用统一的审核流程处理函数
from User.utils import process_approval_flow
current_approver = approval.personincharge
is_completed, error = process_approval_flow(
approval=approval,
business_record=user, # User模型没有approvers_order字段但可以更新state
current_approver=current_approver,
state=state,
approval_type="入职财务登记",
final_state_map={"已通过": "在职", "未通过": "异常"}
)
```
#### 2. "案件管理" (第1184-1223行)
**修复前:** 直接抄送财务,不支持多人团队按顺序流转
**修复后:** 使用统一的`process_approval_flow`函数
```python
# 使用统一的审核流程处理函数
from User.utils import process_approval_flow
current_approver = approval.personincharge
is_completed, error = process_approval_flow(
approval=approval,
business_record=case, # Case模型有approvers_order字段
current_approver=current_approver,
state=state,
approval_type="案件管理",
final_state_map={"已通过": "已通过", "未通过": "未通过"}
)
```
#### 3. "申请用印" (第1225-1259行)
**修复前:** 直接抄送财务,不支持多人团队按顺序流转
**修复后:** 使用统一的`process_approval_flow`函数
```python
# 使用统一的审核流程处理函数
from User.utils import process_approval_flow
current_approver = approval.personincharge
is_completed, error = process_approval_flow(
approval=approval,
business_record=seal_app, # SealApplication模型有approvers_order字段
current_approver=current_approver,
state=state,
approval_type="申请用印",
final_state_map={"已通过": "已通过", "未通过": "未通过"}
)
```
#### 4. "离职财务登记" (第1261-1302行)
**修复前:** 直接抄送财务,不支持多人团队按顺序流转
**修复后:** 使用统一的`process_approval_flow`函数
```python
# 使用统一的审核流程处理函数
from User.utils import process_approval_flow
current_approver = approval.personincharge
is_completed, error = process_approval_flow(
approval=approval,
business_record=user, # User模型没有approvers_order字段但可以更新state
current_approver=current_approver,
state=state,
approval_type="离职财务登记",
final_state_map={"已通过": "已离职", "未通过": "在职"}
)
```
---
## 修复效果
### ✅ 现在所有审核类型都符合统一逻辑
1. **个人团队personal**
- 直接抄送财务(`personincharge="财务"``state="已抄送财务"`
- ✅ 所有审核类型都支持
2. **多人团队team**
- 支持`approvers`参数用户ID列表
- 按顺序流转:第一个审核人 → 第二个审核人 → ... → 最后一个审核人 → 财务
- ✅ 所有审核类型都支持
---
## 已使用统一流程的审核类型共11个
1. ✅ "入职财务登记" - 已修复
2. ✅ "收入确认" - 已正确
3. ✅ "付款申请" - 已正确
4. ✅ "报销申请" - 已正确
5. ✅ "工资/奖金变更" - 已正确
6. ✅ "立项登记" - 已正确
7. ✅ "投标登记" - 已正确
8. ✅ "案件管理" - 已修复
9. ✅ "申请用印" - 已修复
10. ✅ "离职财务登记" - 已修复
11. ✅ "待办" - 已正确
---
## 数据库模型验证
### ✅ 所有业务模型都有`approvers_order`字段
- `ProjectRegistration.approvers_order`
- `Bid.approvers_order`
- `Case.approvers_order`
- `Income.approvers_order`
- `Payment.approvers_order`
- `Reimbursement.approvers_order`
- `BonusChange.approvers_order`
- `Schedule.approvers_order`
- `SealApplication.approvers_order`
**注意:** `User`模型没有`approvers_order`字段,但`process_approval_flow`函数会处理这种情况:
- 如果没有`approvers_order`字段,会直接抄送财务(个人团队逻辑)
- 如果有`approvers_order`字段,会按顺序流转(多人团队逻辑)
---
## 审核逻辑总结
### 创建审核时(`create_approval_with_team_logic`
1. **个人团队personal**
- `personincharge="财务"`
- `state="已抄送财务"`
- 业务记录`state="待财务处理"`
2. **多人团队team**
- 需要`approvers`参数用户ID列表
- 将审核人顺序存储到`approvers_order`字段JSON格式存储用户名列表
- `personincharge=第一个审核人`
- `state="审核中"`
- 业务记录`state="审核中"`
### 审核流转时(`process_approval_flow`
1. **个人团队(无`approvers_order`**
- 直接抄送财务
- `personincharge="财务"`
- `state="已抄送财务"`
2. **多人团队(有`approvers_order`**
-`approvers_order`读取审核人列表
- 找到当前审核人在列表中的位置
- 如果还有下一个审核人:流转到下一个
- 如果是最后一个审核人:抄送财务
---
## 测试建议
1. **个人团队测试**
- 创建审核,验证直接抄送财务
- 财务审核通过,验证状态更新
2. **多人团队测试**
- 创建审核,传入`approvers=[1, 2, 3]`用户ID列表
- 验证第一个审核人收到审核
- 第一个审核人通过,验证流转到第二个审核人
- 第二个审核人通过,验证流转到第三个审核人
- 第三个审核人通过,验证抄送财务
- 财务审核通过,验证完成
3. **边界情况测试**
- 审核不通过的情况
- 审核人不存在的情况
- 没有`approvers_order`字段的旧数据兼容性
---
## 修复完成 ✅
所有审核类型现在都使用统一的审核流程,完全符合用户要求的逻辑:
- ✅ 个人团队:直接抄送财务
- ✅ 多人团队:按顺序流转,最后抄送财务

View File

@@ -1,505 +0,0 @@
# 创建审核接口文档
本文档列出了系统中所有会创建审核记录的接口详情。
## 审核逻辑说明
系统根据团队类型自动判断审核流程:
- **个人团队personal/独立律师)**:不触发审批,直接抄送财务(`state="已抄送财务"``personincharge="财务"`
- **团队team/团队律师)**:需要多级审批,按顺序依次审批,最后抄送财务(`state="审核中"``personincharge`为第一个审核人)
- **无团队**:直接抄送财务
### 审核人参数说明
- `approvers`:审核人列表(可选,多人团队时需要)
- **推荐格式**用户ID数组`[1, 2, 3]``["1", "2", "3"]`(数组顺序即为审核顺序)
- **兼容格式**:用户名数组,如 `["张三", "李四", "王五"]`(数组顺序即为审核顺序)
- **字符串格式**逗号分隔的ID或用户名`"1,2,3"``"张三,李四,王五"`(字符串顺序即为审核顺序)
- 如果不传,则使用团队配置的审核人(按团队审核人顺序)
- `personincharge`:兼容旧接口,单个审核人(已废弃,建议使用`approvers`
---
## 业务模块接口
### 1. 立项登记
**接口路径:** `POST /api2/business/project`
**功能描述:** 创建立项登记并自动创建审核记录
**请求参数:**
```json
{
"user_id": "预立案ID必填",
"type": "项目类型(必填)",
"ContractNo": "合同编号(必填)",
"times": "日期(必填)",
"responsiblefor": "负责人(必填)",
"charge": "收费情况(必填)",
"contract": "合同文件(可选,文件列表)",
"approvers": [1, 2] // 可选团队类型时需要推荐用户ID数组如 [1, 2];兼容:用户名数组,如 ["张三", "李四"]
}
```
**审核逻辑:**
- 根据负责人的团队类型判断是否需要审核
- 个人团队:直接抄送财务
- 团队类型:需要审核人审核(按顺序),最后抄送财务
**审核类型:** `立项登记`
**返回示例:**
```json
{
"message": "登记成功",
"code": 0
}
```
**错误情况:**
- 如果团队类型需要审核但未提供`approvers`参数,返回错误:`团队类型需要指定审核人请提供approvers参数`
---
### 2. 投标登记
**接口路径:** `POST /api2/business/bid`
**功能描述:** 创建投标登记并自动创建审核记录
**请求参数:**
```json
{
"user_id": "预立案ID必填",
"BiddingUnit": "投标单位(必填)",
"ProjectName": "项目名称(必填)",
"times": "日期(必填)",
"BiddingAnnouncement": "招标公告文件(可选,文件列表)",
"approvers": [1, 2] // 可选团队类型时需要推荐用户ID数组如 [1, 2];兼容:用户名数组,如 ["张三", "李四"]
}
```
**审核逻辑:**
- 根据预立案的承办人员团队类型判断是否需要审核
- 个人团队:直接抄送财务
- 团队类型:需要审核人审核(按顺序),最后抄送财务
**审核类型:** `投标登记`
**返回示例:**
```json
{
"message": "登记成功",
"code": 0
}
```
**错误情况:**
- 如果团队类型需要审核但未提供`approvers`参数,返回错误:`团队类型需要指定审核人请提供approvers参数`
---
### 3. 案件管理
**接口路径:** `POST /api2/business/casemanagement`
**功能描述:** 创建或更新案件管理信息,在创建新案件或提交变更申请时创建审核记录
**请求参数:**
```json
{
"user_id": "预立案ID必填",
"times": "日期(可选)",
"AgencyContract": "代理合同文件(可选,文件列表)",
"Contractreturn": "合同回传文件(可选,文件列表)",
"Closingapplication": "结案申请文件(可选,文件列表)",
"ChangeRequest": "变更申请(可选,提交时会创建审核)",
"paymentcollection": "收款情况(可选)",
"personincharge": "审核人(可选,旧接口兼容)"
}
```
**审核逻辑:**
- 创建新案件时:自动创建审核记录,审核人为`personincharge`参数指定的用户
- 提交变更申请时:自动创建审核记录,审核人为`personincharge`参数指定的用户
- 注意:此接口使用旧的审核逻辑,未使用统一的团队审核流程
**审核类型:** `案件管理`
**返回示例:**
```json
{
"message": "创建成功", // 或 "编辑成功"
"code": 0
}
```
---
### 4. 待办创建
**接口路径:** `POST /api2/business/schedule`
**功能描述:** 创建待办事项并自动创建审核记录
**请求参数:**
```json
{
"title": "待办标题(必填)",
"tiems": "开始时间(必填)",
"end_time": "结束时间(必填)",
"remark": "备注(可选)",
"approvers": [1, 2] // 可选团队类型时需要推荐用户ID数组如 [1, 2];兼容:用户名数组,如 ["张三", "李四"]
}
```
**审核逻辑:**
- 根据当前用户的团队类型判断是否需要审核
- 个人团队或无团队:直接抄送财务(`state="待财务处理"`
- 团队类型:创建审批流程,第一个审核人开始审核(`state="审核中"`
- 审核流程:`审核人1 → 审核人2 → ... → 财务`(按顺序审批)
**审核类型:** `待办`
**返回示例:**
```json
{
"message": "添加成功,已直接抄送财务", // 个人团队
// 或
"message": "添加成功,已创建审批流程", // 团队类型
"code": 0
}
```
**错误情况:**
- 如果团队类型需要审核但未提供`approvers`参数且团队未配置审核人,返回错误:`团队类型需要指定审核人请在前端传递approvers参数或配置团队审核人`
- 如果审核人不存在,返回错误:`审核人"xxx"不存在`
---
## 财务模块接口
### 5. 入职财务登记
**接口路径:** `POST /api2/finance/user-register`
**功能描述:** 创建入职财务登记并自动创建审核记录
**请求参数:**
```json
{
"username": "姓名(必填)",
"Dateofjoining": "入职时间必填格式YYYY-MM-DD",
"salary": "工资(必填)",
"card": "身份证(可选,未提供则从人事管理同步)",
"position": "岗位(可选,未提供则从人事管理同步)",
"approvers": [1, 2] // 可选团队类型时需要推荐用户ID数组如 [1, 2];兼容:用户名数组,如 ["张三", "李四"]
}
```
**审核逻辑:**
- 根据用户的团队类型判断是否需要审核
- 个人团队:直接抄送财务
- 团队类型:需要审核人审核(按顺序),最后抄送财务
- 团队信息从人事管理中获取,不在财务登记中修改
**审核类型:** `入职财务登记`
**返回示例:**
```json
{
"message": "登记成功",
"code": 0,
"data": {
"username": "张三",
"Dateofjoining": "2024-01-01",
"salary": "10000",
"card": "身份证号",
"position": "岗位",
"team": "团队名称",
"team_type": "团队类型"
}
}
```
**错误情况:**
- 如果团队类型需要审核但未提供`approvers`参数,返回错误:`团队类型需要指定审核人请提供approvers参数`
- 如果用户不存在,返回错误:`用户不存在,请先在人事管理中创建该用户`
---
### 6. 收入确认
**接口路径:** `POST /api2/finance/confirm`
**功能描述:** 创建收入确认记录并自动创建审核记录
**请求参数:**
```json
{
"times": "收款日期(必填)",
"ContractNo": "合同号(必填)",
"CustomerID": "客户名称(必填)",
"amount": "收款金额(必填)",
"allocate": "收入分配(可选,未提供则设为'待审批人指定'",
"case_id": "案件ID可选用于关联案件",
"approvers": [1, 2] // 可选团队类型时需要推荐用户ID数组如 [1, 2];兼容:用户名数组,如 ["张三", "李四"]
}
```
**审核逻辑:**
- 根据当前用户的团队类型判断是否需要审核
- 个人团队:直接抄送财务
- 团队类型:需要审核人审核(按顺序),最后抄送财务
- 收入分配由审批人指定,提交时可以不填写
**审核类型:** `收入确认`
**返回示例:**
```json
{
"message": "提交成功",
"code": 0,
"data": {
"id": 1,
"ContractNo": "合同号",
"CustomerID": "客户名称",
"amount": "金额",
"allocate": "待审批人指定"
}
}
```
**错误情况:**
- 如果团队类型需要审核但未提供`approvers`参数,返回错误:`团队类型需要指定审核人请提供approvers参数`
---
### 7. 付款申请
**接口路径:** `POST /api2/finance/payment-request`
**功能描述:** 创建付款申请并自动创建审核记录
**请求参数:**
```json
{
"reason": "付款理由(必填)",
"amount": "付款金额(必填)",
"times": "付款日期(必填)",
"payee": "收款人(必填)",
"bankcard": "银行卡号(必填)",
"BankName": "开户行(必填)",
"applicant": "申请人(必填)",
"approvers": [1, 2] // 可选团队类型时需要推荐用户ID数组如 [1, 2];兼容:用户名数组,如 ["张三", "李四"]
}
```
**审核逻辑:**
- 根据申请人的团队类型判断是否需要审核
- 个人团队:直接抄送财务
- 团队类型:需要审核人审核(按顺序),最后抄送财务
**审核类型:** `付款申请`
**返回示例:**
```json
{
"message": "插入成功",
"code": 0
}
```
**错误情况:**
- 如果团队类型需要审核但未提供`approvers`参数,返回错误:`团队类型需要指定审核人请提供approvers参数`
---
### 8. 报销申请
**接口路径:** `POST /api2/finance/reimbursement`
**功能描述:** 创建报销申请并自动创建审核记录
**请求参数:**
```json
{
"person": "报销人(必填)",
"times": "报销日期(必填)",
"reason": "报销理由(必填)",
"amount": "报销金额(必填)",
"FeeDescription": "费用说明(必填)",
"approvers": [1, 2] // 可选团队类型时需要推荐用户ID数组如 [1, 2];兼容:用户名数组,如 ["张三", "李四"]
}
```
**审核逻辑:**
- 根据报销人的团队类型判断是否需要审核
- 个人团队personal/独立律师):不触发审批,直接抄送财务(`state="待财务处理"`
- 团队team/团队律师):需要多级审批,按顺序依次审批,最后抄送财务(`state="审核中"`
**审核类型:** `报销申请`
**返回示例:**
```json
{
"message": "提交成功",
"code": 0,
"data": {
"id": 1,
"state": "审核中", // 或 "待财务处理"
"needs_approval": true // 是否需要审批
}
}
```
**错误情况:**
- 如果团队类型需要审核但未提供`approvers`参数,返回错误:`团队类型需要指定审核人请提供approvers参数`
- 如果报销人不存在,返回错误:`报销人"xxx"不存在或已被删除`
---
### 9. 工资/奖金变更
**接口路径:** `POST /api2/finance/change`
**功能描述:** 创建工资/奖金变更申请并自动创建审核记录
**请求参数:**
```json
{
"username": "用户名(必填)",
"type": "变更类型(必填)",
"Instructions": "调整说明(必填)",
"approvers": [1, 2] // 可选团队类型时需要推荐用户ID数组如 [1, 2];兼容:用户名数组,如 ["张三", "李四"]
}
```
**审核逻辑:**
- 根据用户的团队类型判断是否需要审核
- 个人团队:直接抄送财务
- 团队类型:需要审核人审核(按顺序),最后抄送财务
**审核类型:** `工资/奖金变更`
**返回示例:**
```json
{
"message": "插入成功",
"code": 0,
"data": {
"id": 1,
"submitter": "提交人"
}
}
```
**错误情况:**
- 如果团队类型需要审核但未提供`approvers`参数,返回错误:`团队类型需要指定审核人请提供approvers参数`
---
### 10. 离职财务登记
**接口路径:** `POST /api2/finance/user-departure`
**功能描述:** 创建离职财务登记并自动创建审核记录
**请求参数:**
```json
{
"username": "用户名(必填)",
"Dateofdeparture": "离职时间必填格式YYYY-MM-DD",
"settlement_salary": "结算工资(可选,审批人可以后续填写)",
"approvers": [1, 2] // 可选团队类型时需要推荐用户ID数组如 [1, 2];兼容:用户名数组,如 ["张三", "李四"]
}
```
**审核逻辑:**
- 根据用户的团队类型判断是否需要审核
- 个人团队personal/独立律师):不触发审批,不创建审核记录
- 团队team/团队律师):需要审批,审批人需要指定结算工资
- 如果用户还有未转移的案件,不允许离职登记
**审核类型:** `离职财务登记`
**返回示例:**
```json
{
"message": "登记成功",
"code": 0,
"data": {
"user_id": 1,
"username": "张三",
"Dateofdeparture": "2024-12-31",
"state": "已离职"
}
}
```
**错误情况:**
- 如果团队类型需要审核但未提供`approvers`参数,返回错误:`团队类型需要指定审核人请提供approvers参数`
- 如果用户还有未转移的案件,返回错误:`该用户还有X个案件未转移请先转移案件后再进行离职登记`
- 如果用户不存在,返回错误:`用户不存在或已被删除`
---
## 审核记录字段说明
所有审核记录(`Approval`模型)包含以下字段:
- `title`:审核标题
- `content`:审核内容(详细描述)
- `times`创建时间日期格式YYYY-MM-DD
- `personincharge`:负责人/审核人
- 个人团队:`"财务"`
- 团队类型:第一个审核人的用户名,或`"审核人1 → 审核人2 → ... → 财务"`
- `state`:审核状态
- `"审核中"`:需要审核
- `"已抄送财务"`:已直接抄送财务,无需审核
- `type`:审核类型(见各接口说明)
- `user_id`关联的业务记录ID字符串格式
- `completeTiem`:完成时间(审核通过后填写)
---
## 注意事项
1. **审核人顺序**:如果提供多个审核人,数组顺序即为审核顺序,第一个审核人先审核,通过后自动流转到下一个审核人,最后流转到财务。
2. **团队配置**:如果未提供`approvers`参数,系统会使用团队配置的审核人(按团队审核人顺序)。
3. **兼容性**:接口同时支持`approvers`(推荐)和`personincharge`(旧接口兼容)参数,但建议使用`approvers`
4. **业务记录状态**
- 个人团队:业务记录状态为`"待财务处理"`
- 团队类型:业务记录状态为`"审核中"`
5. **审核人验证**:系统会验证审核人是否存在,如果审核人不存在会返回错误。
---
## 审核流程示例
### 团队类型审核流程
1. 用户提交申请(如立项登记)
2. 系统根据团队类型判断需要审核
3. 创建审核记录,`personincharge`为第一个审核人,`state="审核中"`
4. 第一个审核人审核通过后,系统自动创建新的审核记录给第二个审核人
5. 所有审核人审核通过后,系统创建审核记录给财务
6. 财务处理完成后,业务记录状态更新为`"已完成"`
### 个人团队流程
1. 用户提交申请
2. 系统判断为个人团队,直接创建审核记录,`personincharge="财务"``state="已抄送财务"`
3. 业务记录状态直接为`"待财务处理"`
4. 财务处理完成后,业务记录状态更新为`"已完成"`
---
**文档生成时间:** 2024年
**最后更新:** 2024年

View File

@@ -1,211 +0,0 @@
# 审核参数说明文档
## 一、哪些地方可以不传 `approvers` 参数
### 1. 个人团队personal/独立律师)
**可以不传 `approvers` 的情况:**
-**个人团队personal**:系统会自动判断,直接抄送财务,不需要审核人
-**无团队**:系统会自动判断,直接抄送财务,不需要审核人
**判断逻辑:**
```python
# 在 create_approval_with_team_logic 函数中
if not team_name or not team or (team and team.team_type == 'personal'):
# 个人团队或无团队:直接到财务团队审核
# 不需要 approvers 参数
approval = Approval.objects.create(
personincharge="财务",
state="已抄送财务",
...
)
```
### 2. 团队team/团队律师)
**可以不传 `approvers` 的情况:**
-**团队已配置审核人**:如果不传 `approvers`,系统会自动使用团队配置的审核人
**判断逻辑:**
```python
# 在 create_approval_with_team_logic 函数中
elif team and team.team_type == 'team':
# 团队类型:需要审核人审核(按顺序)
approvers_list = parse_approvers(approvers)
# 如果没有传入审核人,使用团队的审核人
if not approvers_list:
approvers_list = [approver.username for approver in team.approvers.filter(is_deleted=False).order_by('id')]
```
**注意:**
- 如果团队类型是 `team`,且团队没有配置审核人,且前端也没有传 `approvers`,会返回错误:`团队类型需要指定审核人请提供approvers参数`
---
## 二、如何判断是个人律师还是团队
### 1. 判断方式
系统通过 `Team` 模型的 `team_type` 字段判断:
```python
# Team 模型定义
class Team(models.Model):
TEAM_TYPE_CHOICES = [
('personal', '个人团队'), # 个人律师/独立律师
('team', '团队'), # 团队律师
]
team_type = models.CharField(max_length=20, choices=TEAM_TYPE_CHOICES, default='team')
```
### 2. 判断逻辑(在 `create_approval_with_team_logic` 函数中)
```python
# 查找团队
team = None
if team_name:
team = Team.objects.prefetch_related('approvers').filter(name=team_name, is_deleted=False).first()
# 判断团队类型
if not team_name or not team or (team and team.team_type == 'personal'):
# 情况1个人团队personal
# - 直接抄送财务
# - 不需要 approvers 参数
# - personincharge="财务"
# - state="已抄送财务"
elif team and team.team_type == 'team':
# 情况2团队team
# - 需要审核人(可以传 approvers也可以使用团队配置的审核人
# - personincharge=第一个审核人
# - state="审核中"
else:
# 情况3找不到团队或团队类型未知
# - 直接抄送财务
# - 不需要 approvers 参数
```
### 3. 判断结果对应的处理方式
| 团队类型 | team_type | 是否需要 approvers | 处理方式 |
|---------|-----------|-------------------|---------|
| 个人团队 | `personal` | ❌ 不需要 | 直接抄送财务 |
| 团队 | `team` | ✅ 需要(可传可不传) | 按顺序审核,最后抄送财务 |
| 无团队 | `None` | ❌ 不需要 | 直接抄送财务 |
---
## 三、所有创建审核的接口
### 1. 业务模块
#### ① 立项登记 (`POST /api2/business/project`)
- **可以不传 `approvers`**:个人团队时
- **必须传 `approvers`**:团队类型且团队未配置审核人时
#### ② 投标登记 (`POST /api2/business/bid`)
- **可以不传 `approvers`**:个人团队时
- **必须传 `approvers`**:团队类型且团队未配置审核人时
#### ③ 待办创建 (`POST /api2/business/schedule`)
- **可以不传 `approvers`**:个人团队时
- **可以不传 `approvers`**:团队类型且团队已配置审核人时
- **必须传 `approvers`**:团队类型且团队未配置审核人时
### 2. 财务模块
#### ① 入职财务登记 (`POST /api2/finance/user-register`)
- **可以不传 `approvers`**:个人团队时
- **必须传 `approvers`**:团队类型且团队未配置审核人时
#### ② 收入确认 (`POST /api2/finance/confirm`)
- **可以不传 `approvers`**:个人团队时
- **必须传 `approvers`**:团队类型且团队未配置审核人时
#### ③ 付款申请 (`POST /api2/finance/payment-request`)
- **可以不传 `approvers`**:个人团队时
- **必须传 `approvers`**:团队类型且团队未配置审核人时
#### ④ 报销申请 (`POST /api2/finance/reimbursement`)
- **可以不传 `approvers`**:个人团队时
- **必须传 `approvers`**:团队类型且团队未配置审核人时
#### ⑤ 工资/奖金变更 (`POST /api2/finance/change`)
- **可以不传 `approvers`**:个人团队时
- **必须传 `approvers`**:团队类型且团队未配置审核人时
#### ⑥ 离职财务登记 (`POST /api2/finance/user-departure`)
- **可以不传 `approvers`**:个人团队时
- **必须传 `approvers`**:团队类型且团队未配置审核人时
---
## 四、总结
### 可以不传 `approvers` 的情况:
1.**个人团队personal**:系统自动判断,直接抄送财务
2.**无团队**:系统自动判断,直接抄送财务
3.**团队team且团队已配置审核人**:系统自动使用团队配置的审核人
### 必须传 `approvers` 的情况:
1.**团队team且团队未配置审核人**:必须传 `approvers` 参数
### 判断逻辑:
系统会自动通过以下方式判断:
1. 根据用户的 `team` 字段(团队名称)查找 `Team` 模型
2. 检查 `Team.team_type` 字段:
- `'personal'` → 个人团队,不需要审核人
- `'team'` → 团队,需要审核人(可传可不传,取决于团队是否配置了审核人)
---
## 五、代码示例
### 前端调用示例(可以不传 approvers
```javascript
// 个人团队 - 可以不传 approvers
{
"user_id": "123",
"type": "项目类型",
"ContractNo": "合同编号",
"times": "2024-01-01",
"responsiblefor": "负责人",
"charge": "收费情况"
// 不传 approvers系统会自动判断是个人团队直接抄送财务
}
// 团队且团队已配置审核人 - 可以不传 approvers
{
"user_id": "123",
"type": "项目类型",
"ContractNo": "合同编号",
"times": "2024-01-01",
"responsiblefor": "负责人",
"charge": "收费情况"
// 不传 approvers系统会使用团队配置的审核人
}
// 团队且团队未配置审核人 - 必须传 approvers
{
"user_id": "123",
"type": "项目类型",
"ContractNo": "合同编号",
"times": "2024-01-01",
"responsiblefor": "负责人",
"charge": "收费情况",
"approvers": [1, 2, 3] // 必须传,否则会报错
}
```
---
**文档生成时间:** 2024年
**最后更新:** 2024年

View File

@@ -1,238 +0,0 @@
# 审核逻辑分析报告
## 一、用户要求的审核逻辑
### 1. 个人团队personal
- **逻辑**:直接把审核给财务部所有人
- **实现方式**`personincharge="财务"``state="已抄送财务"`
### 2. 多人团队team
- **逻辑**:需要有`approvers`字段是列表数据列表中是用户的id按照顺序一个审核完给第二个最后给财务
- **实现方式**
- `approvers`参数接受用户ID数组`[1, 2, 3]`
- 审核人顺序存储在`approvers_order`字段JSON格式存储用户名列表
- 按顺序流转:第一个审核人 → 第二个审核人 → ... → 最后一个审核人 → 财务
---
## 二、代码逻辑检查
### ✅ 符合要求的逻辑
#### 1. 审核创建逻辑 (`User/utils.py` - `create_approval_with_team_logic`)
**个人团队:**
```python
# 个人团队或无团队:直接到财务团队审核
approval = Approval.objects.create(
personincharge="财务",
state="已抄送财务",
...
)
```
**符合要求**:直接抄送财务
**多人团队:**
```python
# 团队类型:需要审核人审核(按顺序)
approvers_list = parse_approvers(approvers) # 支持ID列表
# 将审核人顺序存储为JSON格式
approvers_order_json = json.dumps(approvers_list, ensure_ascii=False)
# 创建审批记录,第一个审核人
first_approver = approvers_list[0]
approval = Approval.objects.create(
personincharge=first_approver,
state="审核中",
...
)
```
**符合要求**
- 支持用户ID列表
- 按顺序存储审核人
- 第一个审核人开始审核
#### 2. 审核流转逻辑 (`User/utils.py` - `process_approval_flow`)
```python
# 获取审核人列表
approvers_list = get_approvers_from_record(business_record)
# 有审核人列表(多人团队),按顺序流转
current_index = approvers_list.index(current_approver)
# 检查是否还有下一个审核人
if current_index < len(approvers_list) - 1:
# 不是最后一个审核人,流转到下一个
next_approver = approvers_list[current_index + 1]
approval.personincharge = next_approver
approval.state = "审核中"
else:
# 最后一个审核人,抄送财务
approval.personincharge = "财务"
approval.state = "已抄送财务"
```
**符合要求**
-`approvers_order`字段读取审核人列表
- 按顺序流转到下一个审核人
- 最后一个审核人通过后,抄送财务
#### 3. 数据库模型
**Approval模型**
```python
personincharge = models.CharField(max_length=100) # 可以存储"财务"或用户名
state = models.CharField(max_length=100) # 状态:审核中、已抄送财务、已通过等
```
**业务模型ProjectRegistration, Bid, Case, Income, Payment, Reimbursement, BonusChange, Schedule**
```python
approvers_order = models.TextField(null=True, blank=True) # 审核人顺序JSON格式
```
**符合要求**:数据库模型支持存储审核人顺序
---
## 三、发现的冲突和问题
### ❌ 不符合要求的逻辑(存在冲突)
#### 1. `approvalProcessing`接口中的部分审核类型未使用统一流程
**问题位置:** `User/views.py` - `approvalProcessing`
**冲突的审核类型:**
##### ① "入职财务登记" (第936-968行)
```python
if type == "入职财务登记":
# 检查当前是否已经是财务审核
if approval.personincharge == "财务" and approval.state == "已抄送财务":
# 财务审核逻辑
...
# 审批人审核通过后,直接抄送财务(没有按顺序流转)
if state == "已通过":
approval.personincharge = "财务"
approval.state = "已抄送财务"
```
**问题**:没有使用`process_approval_flow`函数,直接抄送财务,不支持多人团队按顺序流转
##### ② "案件管理" (第1176-1214行)
```python
if type == "案件管理":
# 检查当前是否已经是财务审核
if approval.personincharge == "财务" and approval.state == "已抄送财务":
...
# 审批人审核通过后,直接抄送财务(没有按顺序流转)
if state == "已通过":
approval.personincharge = "财务"
approval.state = "已抄送财务"
```
**问题**:没有使用`process_approval_flow`函数,直接抄送财务,不支持多人团队按顺序流转
##### ③ "申请用印" (第1216-1249行)
```python
if type == "申请用印":
# 检查当前是否已经是财务审核
if approval.personincharge == "财务" and approval.state == "已抄送财务":
...
# 审批人审核通过后,直接抄送财务(没有按顺序流转)
if state == "已通过":
approval.personincharge = "财务"
approval.state = "已抄送财务"
```
**问题**:没有使用`process_approval_flow`函数,直接抄送财务,不支持多人团队按顺序流转
##### ④ "离职财务登记" (第1251-1286行)
```python
if type == "离职财务登记":
# 检查当前是否已经是财务审核
if approval.personincharge == "财务" and approval.state == "已抄送财务":
...
# 审批人审核通过后,直接抄送财务(没有按顺序流转)
if state == "已通过":
approval.personincharge = "财务"
approval.state = "已抄送财务"
```
**问题**:没有使用`process_approval_flow`函数,直接抄送财务,不支持多人团队按顺序流转
#### 2. 已正确使用统一流程的审核类型
**以下审核类型已正确使用`process_approval_flow`函数:**
- "收入确认" (第984-1031行)
- "付款申请" (第1061-1082行)
- "报销申请" (第1084-1105行)
- "工资/奖金变更" (第1107-1128行)
- "立项登记" (第1130-1151行)
- "投标登记" (第1153-1174行)
- "待办" (第1288-1310行)
---
## 四、数据库模型检查
### ✅ 符合要求的模型
#### 1. Approval模型
- `personincharge`:可以存储"财务"(个人团队)或用户名(多人团队)
- `state`:可以存储"审核中"、"已抄送财务"、"已通过"、"未通过"等状态
-**符合要求**
#### 2. 业务模型
所有需要审核的业务模型都有`approvers_order`字段:
- `ProjectRegistration.approvers_order`
- `Bid.approvers_order`
- `Case.approvers_order`
- `Income.approvers_order`
- `Payment.approvers_order`
- `Reimbursement.approvers_order`
- `BonusChange.approvers_order`
- `Schedule.approvers_order`
-**符合要求**
#### 3. Team模型
- `team_type`:可以存储'personal'(个人团队)或'team'(多人团队)
- `approvers`:多对多关系,存储团队的审核人
-**符合要求**
---
## 五、总结
### ✅ 符合要求的方面
1. **审核创建逻辑**`create_approval_with_team_logic`函数完全符合要求
- 个人团队:直接抄送财务 ✅
- 多人团队支持用户ID列表按顺序审核 ✅
2. **审核流转逻辑**`process_approval_flow`函数完全符合要求
-`approvers_order`读取审核人列表 ✅
- 按顺序流转 ✅
- 最后一个审核人通过后,抄送财务 ✅
3. **数据库模型**:完全符合要求
- Approval模型支持存储"财务"或用户名 ✅
- 业务模型都有`approvers_order`字段 ✅
### ❌ 需要修复的冲突
**4个审核类型未使用统一流程存在逻辑冲突**
1. **"入职财务登记"** - 需要修复
2. **"案件管理"** - 需要修复
3. **"申请用印"** - 需要修复
4. **"离职财务登记"** - 需要修复
**修复方案:**
将这些审核类型的处理逻辑改为使用统一的`process_approval_flow`函数,确保支持多人团队按顺序流转。
---
## 六、建议
1. **统一审核流程**:将所有审核类型的处理逻辑统一使用`process_approval_flow`函数
2. **保持一致性**:确保所有审核类型都遵循相同的审核逻辑
3. **测试验证**:修复后需要测试多人团队的按顺序流转功能

View File

@@ -1,181 +0,0 @@
# 待办审核流程说明
## 一、待办创建流程
### 1. 创建待办接口
**接口路径:** `POST /api2/business/schedule`
**请求参数:**
```json
{
"title": "待办标题(必填)",
"tiems": "开始时间(必填)",
"end_time": "结束时间(必填)",
"remark": "备注(可选)",
"approvers": [5, 16] // 可选团队类型时需要推荐用户ID数组如 [5, 16]
}
```
### 2. 审核流程判断逻辑
#### 情况1个人团队personal或无团队
- **处理方式**:直接抄送财务部
- **审批记录**
- `personincharge = "财务"`
- `state = "已抄送财务"`
- `type = "待办"`
- **待办状态**`state = "待财务处理"`
- **结果**:财务部的所有人都能看到这个待办
#### 情况2团队类型team
- **处理方式**:创建多级审批流程
- **审核人来源**
- 优先使用前端传入的 `approvers` 参数用户ID数组`[5, 16]`
- 如果没有传入,使用团队配置的审核人(按团队审核人顺序)
- **审批记录**
- `personincharge = 第一个审核人`
- `state = "审核中"`
- `type = "待办"`
- `content = "XXX提交了待办标题审批流程审核人1 → 审核人2 → 财务按顺序审批当前审批人审核人1"`
- **待办状态**`state = "审核中"`
- **审核人顺序存储**:存储在 `Schedule.approvers_order` 字段JSON格式`["张三", "李四"]`
---
## 二、审核流转流程
### 1. 审核处理接口
**接口路径:** `POST /user/approvalProcessing`
**请求参数:**
```json
{
"id": "审批记录ID必填",
"state": "已通过" // 或 "未通过"
}
```
### 2. 流转逻辑(`process_approval_flow` 函数)
#### 步骤1检查审核状态
- 如果 `state = "未通过"`:直接结束,待办状态变为 `"未通过"`
#### 步骤2检查是否已到财务审核
- 如果 `personincharge = "财务"``state = "已抄送财务"`
- 财务部审核通过后,待办状态变为 `"已完成"`
- **注意**:财务部只需要一个人审核完即可完成
#### 步骤3获取审核人列表
-`Schedule.approvers_order` 字段读取审核人列表JSON格式
- 如果没有审核人列表(个人团队),直接抄送财务
#### 步骤4按顺序流转
- **不是最后一个审核人**
- 找到当前审核人在列表中的位置 `current_index`
- 如果 `current_index < len(approvers_list) - 1`
- 流转到下一个审核人:`personincharge = approvers_list[current_index + 1]`
- 更新审批内容:`当前审批人:下一个审核人`
- `state = "审核中"`
- **只有下一个审核人能看到这个待办**
- **是最后一个审核人**
- 如果 `current_index == len(approvers_list) - 1`
- 流转到财务部:`personincharge = "财务"`
- `state = "已抄送财务"`
- 更新审批内容:添加 `,已抄送财务`
- 待办状态:`state = "待财务处理"`
- **财务部的所有人都能看到这个待办**
---
## 三、财务部查看待办
### 1. 代办展示接口
**接口路径:** `POST /user/roxyexhibition`
### 2. 查询逻辑
财务部人员能看到待办的条件:
```python
# 财务匹配条件
finance_query = Q(personincharge="财务", state="已抄送财务")
```
**说明**
- `personincharge = "财务"`:表示已抄送财务部
- `state = "已抄送财务"`:表示处于财务审核状态
- **财务部的所有人都能看到**:只要用户的部门包含"财务部",就能看到所有 `personincharge="财务"` 的待办
### 3. 财务部审核
- **审核逻辑**:财务部只需要一个人审核完即可完成
- **审核通过后**
- 审批记录:`state = "已通过"`
- 待办状态:`state = "已完成"`
---
## 四、完整流程示例
### 示例:团队类型待办,审核人 [5, 16]
#### 1. 创建待办
```
用户提交待办approvers=[5, 16]
→ 创建审批记录personincharge="用户5", state="审核中"
→ 待办状态state="审核中"
→ 只有用户5能看到这个待办
```
#### 2. 用户5审核通过
```
用户5审核通过
→ 流转到下一个审核人personincharge="用户16", state="审核中"
→ 更新审批内容当前审批人用户16
→ 只有用户16能看到这个待办
```
#### 3. 用户16审核通过
```
用户16审核通过
→ 流转到财务部personincharge="财务", state="已抄送财务"
→ 待办状态state="待财务处理"
→ 财务部的所有人都能看到这个待办
```
#### 4. 财务部审核通过
```
财务部任意一人审核通过
→ 审批记录state="已通过"
→ 待办状态state="已完成"
→ 待办完成
```
---
## 五、关键点总结
1. **多人团队审核流程**
- 创建时接受多个审核人(`approvers` 参数)
- 按顺序流转:第一个审核人 → 第二个审核人 → ... → 最后一个审核人 → 财务部
2. **审核人顺序**
- 存储在 `Schedule.approvers_order` 字段JSON格式
- 数组顺序即为审核顺序
3. **财务部审核**
- 最后一个审核人通过后,自动流转到财务部
- 财务部的所有人都能看到(`personincharge="财务"`
- 财务部只需要一个人审核完即可完成
4. **查看权限**
- 审核中:只有当前审核人能看到(`personincharge=当前审核人用户名`
- 已抄送财务:财务部的所有人都能看到(`personincharge="财务"`
---
## 六、代码位置
1. **创建待办**`business/views.py` - `CreateSchedule`第1999-2139行
2. **审核流转**`User/utils.py` - `process_approval_flow` 函数第363-451行
3. **审核处理**`User/views.py` - `approvalProcessing`第1349-1371行
4. **代办展示**`User/views.py` - `roxyExhibition`第727-876行

View File

@@ -1,228 +0,0 @@
# 待办审核问题修复说明
## 一、问题描述
**问题**:入职登记选中了两个人去审核,第一个人审核了,不应该看见这个审核的,但现在还能看见。
**根本原因**
1. `User` 模型没有 `approvers_order` 字段,导致审核人列表无法存储到 `User` 对象中
2. `get_approvers_from_record` 函数无法从 `User` 对象中获取审核人列表
3. `process_approval_flow` 函数认为没有审核人列表,直接抄送财务,导致审核流程不正确
## 二、修复内容
### 1. 修复 `get_approvers_from_record` 函数
**位置**`User/utils.py` - `get_approvers_from_record` 函数
**修复内容**
- 添加了 `approval` 参数,用于从 `Approval.content` 字段解析审核人列表
-`business_record` 没有 `approvers_order` 字段时,从 `Approval.content` 字段解析审核人列表
- 解析格式:`审批流程:张三 → 李四 → 王五 → 财务(按顺序审批),当前审批人:张三`
**代码逻辑**
```python
def get_approvers_from_record(business_record, approval=None):
# 1. 优先从 business_record.approvers_order 字段读取
if hasattr(business_record, 'approvers_order') and business_record.approvers_order:
return json.loads(business_record.approvers_order)
# 2. 如果 business_record 没有 approvers_order 字段,从 Approval.content 字段解析
if approval and approval.content:
if "审批流程:" in approval.content:
# 提取审批流程部分并解析审核人列表
flow_part = approval.content.split("审批流程:")[1].split("(按顺序审批)")[0]
approvers_list = [a.strip() for a in flow_part.split("→") if a.strip()]
# 移除最后的"财务"
if approvers_list and approvers_list[-1].strip() == "财务":
approvers_list = approvers_list[:-1]
return approvers_list
return []
```
### 2. 修复 `process_approval_flow` 函数
**位置**`User/utils.py` - `process_approval_flow` 函数
**修复内容**
- 调用 `get_approvers_from_record` 时传入 `approval` 参数
- 添加详细的调试日志,记录审核流程的每一步
**关键代码**
```python
# 获取审核人列表(传入 approval 参数)
approvers_list = get_approvers_from_record(business_record, approval=approval)
# 按顺序流转
if current_index < len(approvers_list) - 1:
# 流转到下一个审核人
next_approver = approvers_list[current_index + 1]
approval.personincharge = next_approver
approval.state = "审核中"
# ... 更新审批内容
else:
# 最后一个审核人,抄送财务
approval.personincharge = "财务"
approval.state = "已抄送财务"
```
### 3. 添加调试日志
#### 3.1 代办展示接口(`roxyExhibition`
**位置**`User/views.py` - `roxyExhibition`
**日志内容**
- 用户信息用户名、部门IDs
- 查询条件personincharge、state
- 查询结果审批记录数量、前5条记录的详细信息
#### 3.2 审核处理接口(`approvalProcessing`
**位置**`User/views.py` - `approvalProcessing`
**日志内容**
- 审核前审批ID、当前审核人、审核状态、审批内容
- 审核后personincharge、state、业务记录状态
#### 3.3 审核流程函数(`process_approval_flow`
**位置**`User/utils.py` - `process_approval_flow` 函数
**日志内容**
- 审批类型、当前审核人、审核状态、审核人列表
- 当前审核人在列表中的位置
- 流转到下一个审核人的信息
- 抄送财务的信息
#### 3.4 创建审核函数(`create_approval_with_team_logic`
**位置**`User/utils.py` - `create_approval_with_team_logic` 函数
**日志内容**
- 审批类型、审核人列表、第一个审核人
- approvers_order_json 内容
- 创建的审批记录ID、personincharge、state
## 三、修复后的流程
### 1. 创建入职登记审核
```
用户提交入职登记approvers=[5, 16]
→ create_approval_with_team_logic 创建审批记录
→ 审批内容审批流程用户5 → 用户16 → 财务按顺序审批当前审批人用户5
→ personincharge="用户5", state="审核中"
→ 只有用户5能看到这个审核
```
### 2. 第一个审核人审核通过
```
用户5审核通过
→ process_approval_flow 处理审核流程
→ get_approvers_from_record 从 Approval.content 解析审核人列表:["用户5", "用户16"]
→ 当前审核人在列表中的位置0
→ 流转到下一个审核人用户16
→ personincharge="用户16", state="审核中"
→ 只有用户16能看到这个审核用户5不再看到
```
### 3. 第二个审核人审核通过
```
用户16审核通过
→ process_approval_flow 处理审核流程
→ get_approvers_from_record 从 Approval.content 解析审核人列表:["用户5", "用户16"]
→ 当前审核人在列表中的位置1最后一个
→ 流转到财务部
→ personincharge="财务", state="已抄送财务"
→ 财务部的所有人都能看到这个审核
```
### 4. 财务部审核通过
```
财务部任意一人审核通过
→ 审批记录state="已通过"
→ 用户状态state="在职"
→ 审核完成
```
## 四、如何查看日志
### 1. Django 日志配置
确保 `settings.py` 中配置了日志:
```python
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'console': {
'class': 'logging.StreamHandler',
},
},
'loggers': {
'User.utils': {
'handlers': ['console'],
'level': 'INFO',
},
'User.views': {
'handlers': ['console'],
'level': 'INFO',
},
},
}
```
### 2. 查看日志
日志会输出到控制台Django 开发服务器的终端),包含以下信息:
- `get_approvers_from_record`: 从哪个字段获取审核人列表
- `process_approval_flow`: 审核流程的每一步
- `roxyExhibition`: 代办展示的查询逻辑
- `approvalProcessing`: 审核处理的详细信息
- `create_approval_with_team_logic`: 创建审核的详细信息
## 五、测试步骤
1. **创建入职登记**
- 提交入职登记,传入 `approvers=[5, 16]`
- 查看日志,确认审核人列表正确存储
2. **第一个审核人审核**
- 用户5登录查看代办列表
- 应该能看到这个审核
- 用户5审核通过
- 查看日志确认流转到用户16
- 用户5再次查看代办列表
- **应该看不到这个审核了**
3. **第二个审核人审核**
- 用户16登录查看代办列表
- 应该能看到这个审核
- 用户16审核通过
- 查看日志,确认流转到财务部
4. **财务部审核**
- 财务部人员登录,查看代办列表
- 应该能看到这个审核
- 财务部审核通过
- 审核完成
## 六、关键修复点
1.**修复了 `get_approvers_from_record` 函数**:能够从 `Approval.content` 字段解析审核人列表
2.**修复了审核流程**:确保按顺序流转,第一个审核人审核后不再看到审核
3.**添加了详细日志**:方便调试和排查问题
4.**确保最后一个审核人审核完后才流转到财务部**
## 七、注意事项
1. **旧数据兼容**:对于旧的审批记录(没有 `approvers_order` 字段),会从 `Approval.content` 字段解析审核人列表
2. **日志级别**:确保日志级别设置为 `INFO` 或更低,才能看到调试信息
3. **性能考虑**:日志记录可能会影响性能,生产环境建议调整日志级别

View File

@@ -1,160 +0,0 @@
# 接口优化说明:/finance/user-register-detail
## 优化内容
优化了 `/finance/user-register-detail` 接口,将 `team` 字段从简单的字符串(团队名称)改为返回完整的团队信息对象。
## 返回数据结构
### 优化前
```json
{
"code": 0,
"message": "查询成功",
"total": 10,
"data": [
{
"id": 1,
"username": "张三",
"account": "zhangsan",
"team": "团队A", // 只返回团队名称(字符串)
...
}
]
}
```
### 优化后
```json
{
"code": 0,
"message": "查询成功",
"total": 10,
"data": [
{
"id": 1,
"username": "张三",
"account": "zhangsan",
"team": { // 返回完整的团队信息对象
"id": 1,
"name": "团队A",
"team_type": "team", // "personal" 或 "team"
"team_type_display": "团队", // "个人团队" 或 "团队"
"description": "团队描述信息",
"approvers": [ // 审核人列表
{
"id": 2,
"username": "李四"
},
{
"id": 3,
"username": "王五"
}
]
},
...
}
]
}
```
## 团队信息字段说明
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | Integer | 团队ID |
| `name` | String | 团队名称 |
| `team_type` | String | 团队类型:`"personal"`(个人团队)或 `"team"`(团队) |
| `team_type_display` | String | 团队类型显示名称:`"个人团队"``"团队"` |
| `description` | String | 团队描述(可为空) |
| `approvers` | Array | 审核人列表,每个审核人包含 `id``username` |
## 特殊情况处理
### 1. 团队不存在
如果用户的团队名称在数据库中不存在,返回:
```json
{
"team": {
"name": "团队A", // 保留原始团队名称
"team_type": null,
"team_type_display": null,
"description": null,
"approvers": []
}
}
```
### 2. 用户没有团队
如果用户没有分配团队(`user.team` 为空),返回:
```json
{
"team": null
}
```
## 性能优化
为了优化查询性能,使用了批量查询:
1. **批量获取团队信息**:一次性查询所有用户的团队信息,避免 N+1 查询问题
2. **批量获取待审核记录**:一次性查询所有用户的待审核入职登记
## 代码位置
- **文件**`jyls_django/finance/views.py`
- **类**`UnregisteredUserList`
- **方法**`post`
- **行数**391-462
## 使用示例
### 前端调用示例
```javascript
// 调用接口
const response = await fetch('/api2/finance/user-register-detail', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
page: 1,
per_page: 10,
username: '', // 可选
department: '' // 可选
})
});
const data = await response.json();
// 使用团队信息
data.data.forEach(user => {
if (user.team) {
console.log('团队名称:', user.team.name);
console.log('团队类型:', user.team.team_type_display);
console.log('审核人数量:', user.team.approvers.length);
// 判断是否需要审核人
if (user.team.team_type === 'team') {
console.log('需要审核人:', user.team.approvers);
}
}
});
```
## 兼容性说明
-**向后兼容**:如果前端代码期望 `team` 是字符串,可以通过 `user.team.name` 获取团队名称
-**新功能**:前端可以直接使用完整的团队信息,无需额外查询
---
**优化时间**2024年
**最后更新**2024年

View File

@@ -1,356 +0,0 @@
# 数据库模型对比分析
## 一、模型类总结
### User 应用模型
1. **Department** - 部门表
- `username`: 部门名称
- `is_deleted`: 软删除标记
2. **Team** - 团队表(自定义表名:`team`
- `name`: 团队名称
- `team_type`: 团队类型personal/team
- `description`: 团队描述
- `approvers`: 审核人多对多User
- `is_deleted`: 软删除标记
3. **User** - 用户表
- `username`: 姓名
- `account`: 账号
- `password`: 密码
- `ethnicity`: 民族
- `card`: 身份证
- `mobilePhone`: 手机号
- `position`: 岗位
- `team`: 所属团队CharField存储团队名称
- `Dateofjoining`: 入职时间
- `Confirmationtime`: 转正时间
- `Practicingcertificatetime`: 执业证时间
- `Dateofdeparture`: 离职时间
- `AcademicResume`: 学业简历
- `academic`: 学历
- `contract`: 合同
- `ApplicationForm`: 入职申请表
- `salary`: 工资
- `state`: 状态
- `token`: 令牌
- `is_deleted`: 软删除标记
- `department`: 归属部门(多对多)
- `role`: 角色(多对多)
- **注意**:没有 `approvers_order` 字段
4. **Approval** - 审批记录表
- `title`: 标题
- `content`: 内容
- `times`: 提交时间
- `completeTiem`: 完成时间
- `personincharge`: 负责人/审批部门
- `state`: 状态
- `type`: 类别
- `user_id`: 事件IDCharField
- `is_deleted`: 软删除标记
5. **OperationLog** - 操作日志表(自定义表名:`operation_log`
- `operator`: 操作人用户名
- `operator_id`: 操作人ID
- `operation_type`: 操作类型
- `module`: 模块
- `action`: 操作描述
- `target_type`: 目标类型
- `target_id`: 目标ID
- `target_name`: 目标名称
- `old_data`: 操作前的数据JSON
- `new_data`: 操作后的数据JSON
- `ip_address`: IP地址
- `user_agent`: 用户代理
- `request_path`: 请求路径
- `remark`: 备注
- `create_time`: 操作时间
### finance 应用模型
1. **Invoice** - 开票申请表
- `ContractNo`: 合同号
- `personincharge`: 负责人
- `amount`: 开票金额
- `type`: 开票类型
- `unit`: 开票单位全称
- `number`: 纳税人识别号
- `address_telephone`: 地址/电话
- `bank`: 银行卡
- `state`: 状态
- `username`: 谁提交的
- `times`: 提交时间
- `is_deleted`: 软删除标记
- **注意**:没有 `approvers_order` 字段
2. **Income** - 收入确认表
- `times`: 收款日期
- `ContractNo`: 合同号
- `CustomerID`: 客户名称
- `amount`: 收款金额
- `allocate`: 收入分配
- `submit`: 谁提交的
- `submit_tiem`: 提交时间
- `state`: 状态
- `approvers_order`: 审核人顺序JSON格式
- `is_deleted`: 软删除标记
3. **Accounts** - 调账申请表
- `times`: 收款日期
- `ContractNo`: 合同号
- `CustomerID`: 客户名称
- `amount`: 收款金额
- `situation`: 情况说明
- `submit`: 谁提交的
- `submit_tiem`: 提交时间
- `state`: 状态
- `is_deleted`: 软删除标记
- **注意**:没有 `approvers_order` 字段(调账申请直接抄送财务)
4. **Payment** - 付款申请表
- `reason`: 付款理由
- `amount`: 付款金额
- `times`: 付款日期
- `payee`: 收款人
- `bankcard`: 银行卡
- `BankName`: 开户行
- `applicant`: 申请人
- `submit_tiem`: 提交时间
- `state`: 状态
- `approvers_order`: 审核人顺序JSON格式
- `is_deleted`: 软删除标记
5. **Reimbursement** - 报销申请表
- `person`: 报销人
- `times`: 报销日期
- `reason`: 报销理由
- `amount`: 报销金额
- `FeeDescription`: 费用说明
- `submit_tiem`: 提交时间
- `state`: 状态
- `approvers_order`: 审核人顺序JSON格式
- `is_deleted`: 软删除标记
6. **BonusChange** - 工资/奖金变更表
- `username`: 用户名
- `type`: 类型
- `Instructions`: 调整说明
- `times`: 时间
- `state`: 状态
- `submitter`: 提交人
- `approvers_order`: 审核人顺序JSON格式
- `is_deleted`: 软删除标记
### business 应用模型
1. **PreFiling** - 预立案表
- `times`: 预立案时间
- `client_username`: 委托人信息
- `party_username`: 相对方信息
- `description`: 描述
- `Undertaker`: 承办人员
- `submit`: 谁提交的
- `is_deleted`: 软删除标记
2. **ProjectRegistration** - 立项登记表
- `user`: 外键PreFiling
- `type`: 项目类型
- `ContractNo`: 合同编号
- `times`: 立项日期时间
- `responsiblefor`: 负责人
- `charge`: 收费情况
- `contract`: 合同
- `state`: 状态
- `approvers_order`: 审核人顺序JSON格式
- `is_deleted`: 软删除标记
3. **Bid** - 投标登记表
- `user`: 外键PreFiling
- `BiddingUnit`: 招标单位
- `ProjectName`: 项目名称
- `times`: 申请日期
- `BiddingAnnouncement`: 上传招标公告
- `state`: 状态
- `approvers_order`: 审核人顺序JSON格式
- `is_deleted`: 软删除标记
4. **Case** - 案件表
- `user`: 外键PreFiling
- `times`: 立案时间
- `AgencyContract`: 代理合同
- `Contractreturn`: 合同返还
- `Closingapplication`: 结案申请
- `ChangeRequest`: 变更申请
- `paymentcollection`: 已收款
- `state`: 状态
- `approvers_order`: 审核人顺序JSON格式
- `is_deleted`: 软删除标记
5. **Invoice** - 发票表(注意:与 finance.Invoice 不同)
- `user`: 外键PreFiling
- `amount`: 金额
- `file`: 发票图片或PDF
- `is_deleted`: 软删除标记
6. **Caselog** - 案件日志表
- `user`: 外键PreFiling
- `content`: 内容
- `times`: 时间
- `username`: 提交人
- `file`: 文件
- `is_deleted`: 软删除标记
7. **SealApplication** - 申请用印表
- `Printingpurpose`: 用印用途
- `CaseNumber`: 案件编号
- `Reason`: 用印事由
- `seal_number`: 盖章份数
- `seal_type`: 盖章类型
- `file`: 上传用印文件
- `times`: 日期
- `state`: 状态
- `username`: 提交人
- `approvers_order`: 审核人顺序JSON格式
- `is_deleted`: 软删除标记
8. **Schedule** - 待办表
- `title`: 标题
- `tiems`: 开始时间
- `end_time`: 结束时间
- `remark`: 备注
- `state`: 状态
- `submit`: 提交人
- `approvers_order`: 审核人顺序JSON格式
- `is_deleted`: 软删除标记
9. **role** - 角色表
- `RoleName`: 角色名称
- `permissionId`: 权限
- `remark`: 备注
- `is_deleted`: 软删除标记
10. **permission** - 权限表
- `permission_name`: 权限名称
- `permission_logo`: 权限标识
- `parent`: 父级
- `is_deleted`: 软删除标记
11. **Warehousing** - 入库表
- `unit`: 单位
- `mark`: 入库标的
- `lawyer`: 主办律师
- `deadline`: 入库期限
- `contract`: 入库合同
- `times`: 日期
- `is_deleted`: 软删除标记
12. **RegisterPlatform** - 注册平台表
- `platform`: 注册平台
- `number`: 注册号码
- `password`: 密码
- `username`: 注册人员
- `is_deleted`: 软删除标记
13. **Announcement** - 公告表
- `title`: 标题
- `content`: 内容
- `times`: 提交时间
- `file`: 文件
- `username`: 提交人
- `state`: 状态
- `is_deleted`: 软删除标记
14. **LawyerFlie** - 律师文件表
- `title`: 标题
- `remark`: 备注
- `file`: 文件
- `times`: 时间
- `is_deleted`: 软删除标记
## 二、approvers_order 字段分布
### ✅ 有 approvers_order 字段的模型
1. `Income.approvers_order` - 收入确认
2. `Payment.approvers_order` - 付款申请
3. `Reimbursement.approvers_order` - 报销申请
4. `BonusChange.approvers_order` - 工资/奖金变更
5. `ProjectRegistration.approvers_order` - 立项登记
6. `Bid.approvers_order` - 投标登记
7. `Case.approvers_order` - 案件管理
8. `SealApplication.approvers_order` - 申请用印
9. `Schedule.approvers_order` - 待办
### ❌ 没有 approvers_order 字段的模型
1. `User` - 用户表(入职登记和离职登记使用,审核人列表存储在 Approval.content 中)
2. `Invoice` (finance) - 开票申请(已废弃审核流程)
3. `Accounts` - 调账申请(直接抄送财务,不需要审核人)
## 三、潜在冲突点
### 1. Invoice 模型名称冲突
**问题**`finance.Invoice``business.Invoice` 都叫 Invoice
**状态**:✅ 不冲突
- 它们在不同的应用中
- 数据库表名不同:`finance_invoice``business_invoice`
- 代码中通过 `from finance.models import Invoice``from business.models import Invoice` 区分
### 2. User 模型没有 approvers_order 字段
**问题**:入职登记和离职登记使用 User 模型,但没有 approvers_order 字段
**解决方案**
- 审核人列表存储在 `Approval.content` 字段中
- `get_approvers_from_record` 函数会从 `Approval.content` 解析审核人列表
- 这是设计上的考虑,因为 User 不是业务记录
### 3. 外键关系
**需要注意的外键**
- `ProjectRegistration.user``PreFiling.id`
- `Bid.user``PreFiling.id`
- `Case.user``PreFiling.id`
- `business.Invoice.user``PreFiling.id`
- `Caselog.user``PreFiling.id`
**注意**:这些外键在 Django 中定义,但数据库可能没有外键约束(需要检查)
## 四、检查命令使用
### 1. 检查数据库结构
```bash
python manage.py check_database_structure
```
### 2. 检查数据一致性
```bash
python manage.py check_data_consistency
```
### 3. 检查特定应用
```bash
python manage.py check_database_structure --app User
python manage.py check_data_consistency --app finance
```
### 4. 检查并修复
```bash
python manage.py check_database_structure --fix
python manage.py migrate
```
## 五、建议
1. **定期运行检查**:在开发过程中定期运行检查命令,确保数据库和模型一致
2. **迁移前检查**:在应用迁移前运行检查,确保没有冲突
3. **数据导入后检查**:在导入数据后运行一致性检查,确保数据完整
4. **生产环境检查**:在生产环境部署前运行完整检查

View File

@@ -1,316 +0,0 @@
# 数据库结构检查说明
## 一、检查工具
### 1. 数据库结构检查命令
**命令**`python manage.py check_database_structure`
**功能**:检查数据库表结构和模型类是否一致
**参数**
- `--app APP_NAME`: 指定要检查的应用(如 User, finance, business
- `--model MODEL_NAME`: 指定要检查的模型
- `--fix`: 尝试修复不一致的问题(生成迁移文件)
**示例**
```bash
# 检查所有应用
python manage.py check_database_structure
# 只检查 User 应用
python manage.py check_database_structure --app User
# 只检查 User 应用的 User 模型
python manage.py check_database_structure --app User --model User
# 检查并尝试修复
python manage.py check_database_structure --fix
```
### 2. 数据一致性检查命令
**命令**`python manage.py check_data_consistency`
**功能**:检查数据库数据一致性(外键完整性、软删除一致性等)
**参数**
- `--app APP_NAME`: 指定要检查的应用
- `--fix`: 尝试修复发现的问题
**示例**
```bash
# 检查所有数据一致性
python manage.py check_data_consistency
# 只检查 User 应用
python manage.py check_data_consistency --app User
```
## 二、检查内容
### 1. 数据库结构检查
#### 1.1 表存在性检查
- 检查模型对应的数据库表是否存在
- 检查多对多关系表是否存在
#### 1.2 字段检查
- 检查模型字段是否在数据库中存在
- 检查数据库字段是否在模型中存在(可能遗留字段)
- 检查字段类型是否匹配
- 检查字段约束null, default, max_length是否一致
#### 1.3 字段类型映射
| Django 模型字段 | MySQL 数据库类型 |
|----------------|-----------------|
| CharField | VARCHAR |
| TextField | TEXT/LONGTEXT |
| IntegerField | INT |
| BigIntegerField | BIGINT |
| BooleanField | TINYINT(1) |
| DateField | DATE |
| DateTimeField | DATETIME |
| ForeignKey | BIGINT |
### 2. 数据一致性检查
#### 2.1 外键完整性检查
- 检查 `ProjectRegistration.user` 外键是否指向存在的 `PreFiling`
- 检查 `Case.user` 外键是否指向存在的 `PreFiling`
- 检查 `Bid.user` 外键是否指向存在的 `PreFiling`
#### 2.2 软删除一致性检查
- 检查审批记录和业务记录的软删除状态是否一致
- 检查已软删除的业务记录是否还有未删除的审批记录
#### 2.3 审批记录关联检查
- 检查审批记录的 `user_id` 是否指向存在的业务记录
- 检查 `user_id` 是否为有效的整数
#### 2.4 用户团队关系检查
- 检查用户的 `team` 字段是否指向存在的团队
- 检查团队是否存在且未被删除
#### 2.5 部门数据检查
- 检查是否存在"财务部"部门
- 检查是否有用户属于财务部
## 三、常见问题
### 1. 表不存在
**问题**:模型定义了,但数据库中没有对应的表
**原因**
- 迁移文件未执行
- 迁移文件丢失
- 手动删除了表
**解决方法**
```bash
# 生成迁移文件
python manage.py makemigrations
# 应用迁移
python manage.py migrate
```
### 2. 字段不存在
**问题**:模型中有字段,但数据库表中没有
**原因**
- 新增字段后未执行迁移
- 迁移文件未正确生成
**解决方法**
```bash
# 生成迁移文件
python manage.py makemigrations
# 应用迁移
python manage.py migrate
```
### 3. 字段类型不匹配
**问题**:模型字段类型和数据库字段类型不一致
**原因**
- 手动修改了数据库字段类型
- 迁移文件执行错误
**解决方法**
1. 检查模型定义是否正确
2. 生成新的迁移文件
3. 应用迁移(可能需要数据迁移)
### 4. 外键孤立记录
**问题**:外键指向不存在的记录
**原因**
- 手动删除了被引用的记录
- 外键约束未启用
- 数据导入错误
**解决方法**
1. 检查并修复孤立记录
2. 考虑添加数据库外键约束
3. 清理无效数据
### 5. 软删除不一致
**问题**:业务记录已删除,但审批记录未删除
**原因**
- 软删除逻辑不完整
- 手动修改了数据
**解决方法**
1. 检查软删除逻辑
2. 同步软删除状态
3. 添加数据一致性检查
## 四、模型和数据库对应关系
### User 应用
| 模型 | 数据库表名 | 说明 |
|-----|-----------|------|
| User | user_user | 用户表 |
| Department | user_department | 部门表 |
| Team | team | 团队表(自定义表名) |
| Approval | user_approval | 审批记录表 |
| OperationLog | operation_log | 操作日志表(自定义表名) |
**多对多关系表**
- `user_user_department`: User 和 Department 的多对多关系
- `user_user_role`: User 和 role 的多对多关系
- `team_approvers`: Team 和 User 的多对多关系(审核人)
### finance 应用
| 模型 | 数据库表名 | 说明 |
|-----|-----------|------|
| Invoice | finance_invoice | 开票申请表 |
| Income | finance_income | 收入确认表 |
| Accounts | finance_accounts | 调账申请表 |
| Payment | finance_payment | 付款申请表 |
| Reimbursement | finance_reimbursement | 报销申请表 |
| BonusChange | finance_bonuschange | 工资/奖金变更表 |
### business 应用
| 模型 | 数据库表名 | 说明 |
|-----|-----------|------|
| PreFiling | business_prefiling | 预立案表 |
| ProjectRegistration | business_projectregistration | 立项登记表 |
| Bid | business_bid | 投标登记表 |
| Case | business_case | 案件表 |
| Invoice | business_invoice | 发票表(注意:与 finance.Invoice 不同) |
| Caselog | business_caselog | 案件日志表 |
| SealApplication | business_sealapplication | 申请用印表 |
| Schedule | business_schedule | 待办表 |
| role | business_role | 角色表 |
| permission | business_permission | 权限表 |
| Warehousing | business_warehousing | 入库表 |
| RegisterPlatform | business_registerplatform | 注册平台表 |
| Announcement | business_announcement | 公告表 |
| LawyerFlie | business_lawyerflie | 律师文件表 |
## 五、注意事项
### 1. Invoice 模型冲突
**问题**`finance.Invoice``business.Invoice` 是两个不同的模型
**说明**
- `finance.Invoice`: 财务开票申请(表名:`finance_invoice`
- `business.Invoice`: 案件发票(表名:`business_invoice`
**注意**:这两个模型不会冲突,因为它们在不同的应用中。
### 2. User 模型没有 approvers_order 字段
**问题**`User` 模型没有 `approvers_order` 字段,但入职登记和离职登记需要审核人列表
**说明**
- `User` 模型确实没有 `approvers_order` 字段
- 审核人列表存储在 `Approval.content` 字段中(通过解析获取)
- 这是设计上的考虑,因为 `User` 不是业务记录,而是用户信息
### 3. 多对多关系表
**注意**Django 会自动创建多对多关系表,表名格式为:`应用名_模型名_字段名`
例如:
- `user_user_department`: User 和 Department 的多对多
- `user_user_role`: User 和 role 的多对多
- `team_approvers`: Team 和 User 的多对多(因为 Team 定义了 `db_table='team'`
## 六、运行检查
### 1. 完整检查
```bash
# 检查数据库结构
python manage.py check_database_structure
# 检查数据一致性
python manage.py check_data_consistency
```
### 2. 检查特定应用
```bash
# 只检查 User 应用
python manage.py check_database_structure --app User
python manage.py check_data_consistency --app User
```
### 3. 检查并修复
```bash
# 检查并生成迁移文件
python manage.py check_database_structure --fix
# 应用迁移
python manage.py migrate
```
## 七、检查报告示例
```
开始检查数据库结构和模型类...
检查应用: User
================================================================================
检查模型: User
--------------------------------------------------------------------------------
✅ 表 user_user 存在
✅ 字段 username 匹配
✅ 字段 account 匹配
...
⚠️ 数据库中有额外字段: old_field_name
检查模型: Approval
--------------------------------------------------------------------------------
✅ 表 user_approval 存在
✅ 字段 title 匹配
...
检查应用: finance
================================================================================
...
检查完成!
发现 2 个问题:
1. [missing_field] 模型字段 new_field 在数据库表 user_user 中不存在
2. [extra_field] 数据库表 user_user 中有模型中没有的字段: old_field_name
```

View File

@@ -1,201 +0,0 @@
# 财务部判断逻辑说明
## 一、问题发现
**原问题**:代码中 `personincharge="财务"` 的审批记录,所有用户都能看到,并没有判断用户是否是财务部的人。
**原代码逻辑**
```python
# 财务匹配personincharge字段是"财务",且状态为"已抄送财务"
finance_query = Q(personincharge="财务", state="已抄送财务")
# 组合查询:所有用户都能看到财务审核的审批记录
query &= (department_query | person_query | finance_query)
```
**问题**:这意味着**所有用户都能看到 `personincharge="财务"` 的审批记录**,而不仅仅是财务部的人。
## 二、修复方案
### 1. 判断用户是否是财务部人员
**判断方式**:只通过用户的**部门名称**判断
**代码逻辑**
```python
# 获取用户的部门名称列表
user_departments = user.department.values_list('username', flat=True)
user_department_names = list(user_departments)
# 判断用户是否是财务部人员(只通过部门名称判断)
is_finance_user = '财务部' in user_department_names
```
**判断条件**
- 用户的部门名称包含 `"财务部"`
### 2. 修复后的查询逻辑
**修复后的代码**
```python
# 财务匹配:只有财务部人员才能看到
finance_query = Q()
if is_finance_user:
finance_query = Q(personincharge="财务", state="已抄送财务")
# 组合查询:只有财务部人员才能看到财务审核的审批记录
query &= (department_query | person_query | finance_query)
```
**逻辑说明**
- 如果用户是财务部人员(`is_finance_user = True`),则 `finance_query` 包含财务匹配条件
- 如果用户不是财务部人员(`is_finance_user = False`),则 `finance_query` 为空,不会匹配到财务审核的审批记录
## 三、完整的查询逻辑
### 1. 查询条件组合
```python
query = Q(state__in=["审核中", "已抄送财务"])
# 部门匹配personincharge字段是部门ID且匹配用户所属部门
department_query = Q(personincharge__in=user_department_ids_str)
# 审批员匹配personincharge字段是用户名且等于当前用户名
person_query = Q(personincharge=user.username)
# 财务匹配personincharge字段是"财务",且状态为"已抄送财务"(仅财务部人员)
finance_query = Q(personincharge="财务", state="已抄送财务") if is_finance_user else Q()
# 组合查询
query &= (department_query | person_query | finance_query)
```
### 2. 用户能看到审批记录的条件
用户能看到审批记录,需要满足以下**任一条件**
1. **部门匹配**`personincharge` 字段是用户所属部门的ID纯数字字符串
2. **审批员匹配**`personincharge` 字段等于当前用户名(非纯数字字符串)
3. **财务匹配**`personincharge` 字段是 `"财务"`,且用户是财务部人员(角色名称或部门名称包含 `"财务部"`
## 四、数据模型
### 1. User 模型
```python
class User(models.Model):
username = models.CharField(max_length=100) # 姓名
department = models.ManyToManyField(Department) # 归属部门(多对多)
role = models.ManyToManyField(role) # 角色(多对多)
# ... 其他字段
```
### 2. Department 模型
```python
class Department(models.Model):
username = models.CharField(max_length=100) # 部门名称
is_deleted = models.BooleanField(default=False) # 软删除标记
```
### 3. role 模型
```python
class role(models.Model):
RoleName = models.CharField(max_length=100) # 角色名称
# ... 其他字段
```
## 五、判断逻辑示例
### 示例1财务部人员
```
用户:张三
部门:["财务部", "人事部"]
判断结果:
- user_department_names = ["财务部", "人事部"]
- '财务部' in user_department_names = True
- is_finance_user = True
- 可以看到 personincharge="财务" 的审批记录
```
### 示例2非财务部人员
```
用户:王五
部门:["人事部"]
判断结果:
- user_department_names = ["人事部"]
- '财务部' not in user_department_names = True
- is_finance_user = False
- 不能看到 personincharge="财务" 的审批记录
```
## 六、修复后的完整流程
### 1. 创建审核(多人团队)
```
用户提交入职登记approvers=[5, 16]
→ 创建审批记录personincharge="用户5", state="审核中"
→ 只有用户5能看到这个审核
```
### 2. 第一个审核人审核通过
```
用户5审核通过
→ 流转到下一个审核人personincharge="用户16", state="审核中"
→ 只有用户16能看到这个审核用户5不再看到
```
### 3. 第二个审核人审核通过
```
用户16审核通过
→ 流转到财务部personincharge="财务", state="已抄送财务"
→ 只有财务部人员能看到这个审核(通过角色名称或部门名称判断)
```
### 4. 财务部审核通过
```
财务部人员审核通过
→ 审批记录state="已通过"
→ 用户状态state="在职"
→ 审核完成
```
## 七、关键代码位置
1. **代办展示接口**`User/views.py` - `roxyExhibition`第724-966行
2. **财务部判断逻辑**`User/views.py` - `roxyExhibition`第739-780行
3. **参考实现**`finance/views.py` - `confirmdisplay`第1006-1016行
## 八、注意事项
1. **部门名称必须包含"财务部"**:如果部门名称是 `"财务"` 而不是 `"财务部"`,则无法匹配
2. **大小写敏感**:判断是精确匹配,`"财务部"``"财务"` 是不同的
3. **多部门**:只要用户的任一部门名称包含 `"财务部"`,就会被判断为财务部人员
4. **只判断部门**:系统只通过部门名称判断,不通过角色名称判断
## 九、测试建议
1. **测试财务部人员**
- 创建一个部门名称为 `"财务部"` 的用户
- 验证该用户能看到 `personincharge="财务"` 的审批记录
2. **测试非财务部人员**
- 创建一个部门名称不包含 `"财务部"` 的用户
- 验证该用户不能看到 `personincharge="财务"` 的审批记录
3. **测试审核流程**
- 创建多人团队审核,验证最后一个审核人审核后,只有财务部人员能看到
4. **测试多部门用户**
- 创建一个用户,部门包含 `["财务部", "人事部"]`
- 验证该用户能看到 `personincharge="财务"` 的审批记录(因为部门包含"财务部"