# 凭证管理审核功能增强说明 ## 功能概述 本次更新对凭证管理模块进行了审核流程增强,主要包括: 1. **承运商信息自动记录**:上传时自动识别并记录承运商信息 2. **权限控制**:外部组织用户只能查看自己上传的凭证数据 3. **审核流程**:处理完成后自动进入待审核状态,支持审核通过和审核驳回 4. **界面优化**:承运商用户隐藏不相关的字段和操作 ## 一、数据库变更 ### 1.1 新增字段 文件:`/doc/sql/transport/blade_voucher_manage_audit_20260908.sql` ```sql -- 添加承运商ID字段 ALTER TABLE `blade_voucher_manage` ADD COLUMN `carrier_id` bigint DEFAULT NULL COMMENT '承运商ID(组织ID)' AFTER `carrier_name`; -- 添加索引 ALTER TABLE `blade_voucher_manage` ADD KEY `idx_voucher_manage_carrier_id` (`carrier_id`), ADD KEY `idx_voucher_manage_audit_status` (`audit_status`); ``` ### 1.2 新增菜单权限 ```sql INSERT INTO `blade_menu` (2090000000000000905, 2090000000000000900, 'voucher_manage_audit_pass', '审核通过', ...), (2090000000000000906, 2090000000000000900, 'voucher_manage_audit_reject', '审核驳回', ...); ``` ## 二、后端变更 ### 2.1 实体类 (VoucherManage.java) 新增字段: - `Long carrierId` - 承运商ID(组织ID) ### 2.2 Controller (VoucherManageController.java) 新增接口: - `POST /audit-pass` - 审核通过 - `POST /audit-reject` - 审核驳回(支持驳回原因) ### 2.3 Service接口 (IVoucherManageService.java) 新增方法: ```java void auditPass(Long id); void auditReject(Long id, String rejectReason); ``` ### 2.4 Service实现 (VoucherManageServiceImpl.java) #### 2.4.1 submit方法增强 - 自动判断用户组织类型 - 如果顶级组织是"外部组织",自动设置: - `uploadSource = "承运商"` - `carrierId = 当前用户组织ID` - `carrierName = 当前用户组织名称` - 否则设置为"内部"上传 #### 2.4.2 buildQuery方法增强 - 添加权限控制逻辑 - 外部组织用户只能查询自己上传的凭证(`createUser = 当前用户ID`) #### 2.4.3 processUploadedVoucher方法增强 - 处理完成后自动设置 `auditStatus = "待审核"` #### 2.4.4 新增审核方法 ```java // 审核通过 public void auditPass(Long id) { // 验证状态:必须是"处理完成"且"待审核" // 设置 auditStatus = "审核通过" } // 审核驳回 public void auditReject(Long id, String rejectReason) { // 验证状态:必须是"处理完成"且"待审核" // 设置 auditStatus = "审核驳回" } ``` #### 2.4.5 新增辅助方法 ```java // 判断是否为外部组织(递归查询顶级组织) private boolean isExternalOrganization(Long deptId); // 获取组织名称 private String getOrganizationName(Long deptId); ``` ### 2.5 Mapper (VoucherManageMapper.java) 新增查询方法: ```java // 查询组织的顶级父组织ID(使用递归CTE) Long selectTopDeptId(@Param("deptId") Long deptId); // 查询组织名称 String selectDeptName(@Param("deptId") Long deptId); ``` ## 三、前端变更 ### 3.1 API接口 (voucher-manage.js) 新增方法: ```javascript export const auditPass = id => request({ url: `${baseUrl}/audit-pass`, method: 'post', params: { id } }); export const auditReject = (id, rejectReason) => request({ url: `${baseUrl}/audit-reject`, method: 'post', params: { id, rejectReason } }); ``` ### 3.2 页面组件 (voucher-manage.vue) #### 3.2.1 用户类型判断 ```javascript // 判断当前用户是否为承运商 const isCarrier = ref(false); const checkIfCarrier = () => { const userInfo = store.getters.userInfo || {}; const topDeptName = userInfo.top_dept_name || userInfo.topDeptName || ''; isCarrier.value = topDeptName === '外部组织'; }; ``` #### 3.2.2 搜索表单优化 - 承运商用户隐藏"上传来源"和"承运商"搜索条件(`v-if="!isCarrier"`) #### 3.2.3 表格列优化 - 承运商用户隐藏以下列: - 上传来源 - 承运商名称 #### 3.2.4 操作按钮优化 表格操作列宽度调整为 `200px`,新增审核按钮: | 按钮 | 显示条件 | 用户限制 | |------|---------|---------| | 审核通过 | 处理完成 + 待审核 | 仅内部用户 | | 审核驳回 | 处理完成 + 待审核 | 仅内部用户 | | 查看 | 处理完成 | 全部用户 | | 下载 | 处理完成 | 全部用户 | | 更换运单批次 | 未完成或待审核 | 全部用户 | | 删除 | 上传中或审核驳回 | 全部用户 | #### 3.2.5 新增审核方法 ```javascript // 审核通过 const handleAuditPass = row => { ElMessageBox.confirm(`确认审核通过凭证批次"${row.voucherBatchNo}"吗?`, '提示', { type: 'warning', }).then(async () => { await api.auditPass(row.id); ElMessage.success('审核通过'); load(); }); }; // 审核驳回(支持输入驳回原因) const handleAuditReject = row => { ElMessageBox.prompt('请输入驳回原因(可选)', '审核驳回', { confirmButtonText: '确认', cancelButtonText: '取消', inputPattern: /.*/, }).then(async ({ value }) => { await api.auditReject(row.id, value || ''); ElMessage.success('审核驳回'); load(); }); }; ``` ## 四、业务流程 ### 4.1 承运商上传流程 1. 承运商用户登录(顶级组织为"外部组织") 2. 上传凭证时,系统自动记录: - 上传来源:承运商 - 承运商ID:用户组织ID - 承运商名称:用户组织名称 3. 上传完成后,凭证进入"处理中"状态 4. 处理完成后,自动变为"待审核"状态 5. 承运商用户只能看到自己上传的凭证 ### 4.2 内部用户审核流程 1. 内部用户可以看到所有凭证(包括内部和承运商上传的) 2. 处理完成且待审核的凭证,显示"审核通过"和"审核驳回"按钮 3. 点击"审核通过":凭证状态变为"审核通过" 4. 点击"审核驳回":可输入驳回原因,凭证状态变为"审核驳回" 5. 审核驳回的凭证可以被删除 ### 4.3 状态流转 ``` 上传中 → 处理中 → 处理完成(自动变为"待审核") ↓ 待审核 → 审核通过 ↘ 审核驳回 → 可删除 ``` ## 五、权限控制说明 ### 5.1 数据权限 | 用户类型 | 可见范围 | |---------|---------| | 内部用户 | 全部凭证 | | 承运商用户 | 仅自己上传的凭证 | ### 5.2 功能权限 | 功能 | 内部用户 | 承运商用户 | |-----|---------|-----------| | 批量导入凭证 | ✓ | ✓ | | 查看凭证 | ✓ | ✓(仅自己的) | | 下载凭证 | ✓ | ✓(仅自己的) | | 更换运单批次 | ✓ | ✓(仅自己的) | | 删除凭证 | ✓ | ✓(仅自己的) | | 审核通过 | ✓ | ✗ | | 审核驳回 | ✓ | ✗ | | 查看上传来源字段 | ✓ | ✗ | | 查看承运商字段 | ✓ | ✗ | ## 六、部署步骤 ### 6.1 数据库部署 执行SQL脚本: ```bash mysql -u用户名 -p数据库名 < blade_voucher_manage_audit_20260908.sql ``` ### 6.2 后端部署 1. 编译后端代码 2. 重启 `blade-transport` 服务 ### 6.3 前端部署 1. 构建前端代码:`pnpm run build:prod` 2. 部署到Web服务器 ## 七、注意事项 1. **数据兼容性**:现有凭证的 `carrier_id` 字段为 `NULL`,不影响现有功能 2. **权限配置**:需要为相关角色分配"审核通过"和"审核驳回"权限 3. **组织判断**:依赖 `blade_dept` 表的 `dept_name` 字段,顶级组织必须命名为"外部组织" 4. **审核状态**:只有"处理完成"且"待审核"的凭证才能审核 5. **用户信息**:前端需要确保 `store.getters.userInfo` 中包含 `top_dept_name` 或 `topDeptName` 字段 ## 八、测试建议 ### 8.1 功能测试 - [ ] 内部用户上传凭证,验证上传来源为"内部" - [ ] 承运商用户上传凭证,验证上传来源为"承运商",承运商信息自动记录 - [ ] 承运商用户只能看到自己上传的凭证 - [ ] 内部用户可以看到所有凭证 - [ ] 凭证处理完成后自动变为"待审核"状态 - [ ] 内部用户可以审核通过凭证 - [ ] 内部用户可以审核驳回凭证 - [ ] 承运商用户看不到审核按钮 - [ ] 承运商用户看不到"上传来源"和"承运商名称"列 ### 8.2 权限测试 - [ ] 承运商用户无法访问 `/audit-pass` 接口 - [ ] 承运商用户无法访问 `/audit-reject` 接口 - [ ] 承运商用户无法看到其他承运商的凭证 ### 8.3 异常测试 - [ ] 审核非"待审核"状态的凭证,验证错误提示 - [ ] 审核非"处理完成"状态的凭证,验证错误提示 - [ ] 组织信息缺失时,系统正常运行 --- **修改日期**:2026-09-08 **修改人**:Claude **版本**:v1.0