10 KiB
隐患验收页逻辑说明
对应文件:
pages/hiddendanger/acceptance.vue
最后整理:2026-07-15
1. 页面职责
验收页用于对已提交的整改记录进行验收,主要能力:
- 只读展示整改记录(方案、措施、人员、附件等)
- 填写验收表单(结果、备注、验收附件、签名)
- 根据验收选择预览下一步流程
- 选择或通过只读展示下一步处理人
- 提交到
POST /frontend/hazard/verify
2. 页面入参(URL Query)
从首页 / 巡检列表跳转,由 utils/hazardNav.js → buildAcceptanceUrl 构建:
| 参数 | 是否必需 | 说明 |
|---|---|---|
rectifyId |
推荐必带 | 整改记录 ID,有则只调整改详情接口 |
hazardId |
列表通常会带 | 隐患 ID,无 rectifyId 时用于兜底拉取 |
assignId |
可选 | 指派 ID,用于从隐患详情中定位正确 assign |
taskId |
流程预览依赖 | 工作流任务 ID,用于「下一步流程」接口 |
示例:
/pages/hiddendanger/acceptance?hazardId=184&assignId=158&rectifyId=150&taskId=xxx
注意:
rectify/detail响应里通常没有taskId,下一步流程主要依赖 URL 传入的taskId。若列表未带且详情也解析不到,「下一步流程」会显示「暂无下一步流程」。
3. 页面加载流程
onLoad
├─ 解析 URL 参数(rectifyId / hazardId / assignId / taskId)
├─ loadPageData()
│ ├─ 有 rectifyId → fetchRectifyDetail() // 只调一次
│ ├─ 无 rectifyId、有 hazardId → fetchDetail()
│ └─ fetchNextStep()
└─ restoreDraft() // 恢复本地草稿(若有)
3.1 数据接口选择(重要)
不要两个详情接口都调,当前规则:
| 条件 | 调用接口 | 说明 |
|---|---|---|
有 rectifyId |
GET /frontend/hazard/rectify/detail |
唯一数据源 |
无 rectifyId、有 hazardId |
GET /frontend/hazard/detail |
从 assigns[].rectify 取整改记录 |
3.2 两个详情接口的区别
| 对比项 | rectify/detail |
hazard/detail 内嵌 rectify |
|---|---|---|
| 数据范围 | 单条整改记录 | 整条隐患 + 指派 + 整改 |
| 人员结构 | members / managers 对象数组 |
memberNames / managerNames 字符串数组 |
| 整改人 | 有 rectifierName |
有 rectifierName |
| 状态字段 | statusName |
rectifyStatusName |
| 适用场景 | 有 rectifyId 时优先 |
仅无 rectifyId 时兜底 |
4. 整改记录字段映射(applyRectifyData)
接口返回结构不统一,统一在 applyRectifyData 中做映射:
| 页面展示字段 | 映射规则 |
|---|---|
| 整改方案/措施/管控/完成情况/费用 | 同名字段直取 |
| 安全管理人员 | 有 managers[] → 取 nickName 去重;否则用 managerNames |
| 整改责任人 | 有 members[] → 取 nickName 去重;否则用 memberNames |
| 完成情况 | rectifyStatusName 或 statusName |
| 整改附件 | attachments |
| 整改人(不通过时展示) | rectifierName |
人员名显示规则(易踩坑)
rectify/detail 同时可能返回:
memberNames/managerNames(身份名,如:阎勇、user1)members/managers(对象,含nickName,如:xiaomi、duoduo)
当前规则:有 members / managers 数组时,优先用其中的 nickName,不用 memberNames。
5. 验收表单交互
5.1 验收结果 formData.result
| 值 | 含义 |
|---|---|
1 |
通过(默认) |
2 |
不通过 |
切换时触发 onResultChange → 重新请求下一步流程 fetchNextStep()。
- 切到「不通过」:清空已选下一步处理人
- 切到「通过」:若未选快速审批,默认
quickApproveRadio = 'yes'
5.2 是否快速审批 formData.quickApproveRadio
- 仅验收通过时显示,必选
yes= 快速审批;no= 不快速审批- 切换时触发
onQuickApproveChange→fetchNextStep()
5.3 下一步流程(只读预览)
接口:POST /flow/task/next-nodes
三种情况都必须传:
{
"taskId": "当前任务ID",
"includeSubProcess": true,
"previewVariables": { ... }
}
previewVariables 按验收选择变化:
| 场景 | previewVariables |
|---|---|
| 不通过 | { "pass": false } |
| 通过 + 快速审批 | { "pass": true, "quickApprove": true } |
| 通过 + 不快速审批 | { "pass": true, "quickApprove": false } |
展示逻辑:取返回 branches 中 matched === true 的分支(没有则取第一个)的 nextNode.taskName。
5.4 下一步处理人
| 验收结果 | UI | 数据来源 |
|---|---|---|
| 不通过 | 只读文本 | rectify/detail 的 rectifierName(整改人) |
| 通过 | 底部弹窗单选 | GET /admin/user/dept/users/{deptId} |
通过时选人说明:
deptId来自本地userInfo.userIdentity.deptId(无则取userInfo.deptId)- 部门人员接口返回
{ userId, nickName },可能没有identityId - 选人 ID 解析:
identityId→userIdentityId→userId(兜底) - 提交字段名是
assigneeIdentityId,无identityId时实际传的是userId
5.5 电子签名
- 必填,提交前先上传云端得到
signPath - 打开「选择下一步处理人」弹窗时,卸载签名 Canvas(
v-if="showCanvas && !showAssigneePopup"),避免微信小程序原生 canvas 层级穿透盖住弹窗
5.6 验收图片/视频
- 使用
up-upload+ 水印 canvas - 提交时只取
status === 'success'的文件,经buildAttachmentItem转成附件对象
6. 提交验收
接口:POST /frontend/hazard/verify(acceptanceRectification)
6.1 提交前校验
- 必须有
rectifyId - 通过时:必须选「是否快速审批」
- 通过 + 不快速审批:必须选下一步处理人
- 必须有电子签名
6.2 请求体
通用字段(通过/不通过都传):
| 字段 | 类型 | 说明 |
|---|---|---|
rectifyId |
number | 整改记录 ID |
result |
number | 1 通过 / 2 不通过 |
verifyRemark |
string | 验收备注,可为空 |
attachments |
array | 验收附件 [{ fileName, filePath, fileType, fileSize }] |
signPath |
string | 电子签名服务器路径 |
仅通过时额外传:
| 字段 | 条件 | 说明 |
|---|---|---|
quickApprove |
result === 1 |
boolean |
assigneeIdentityId |
quickApprove === false |
下一步处理人 ID |
不提交的内容:
- 整改记录只读区所有字段
- 下一步流程名称(仅预览)
- 不通过时的
rectifierName(仅展示,后端按流程自行处理) - 快速审批为「是」时的下一步处理人
6.3 提交示例
不通过:
{
"rectifyId": 150,
"result": 2,
"verifyRemark": "整改不到位",
"attachments": [],
"signPath": "https://oss.../sign.png"
}
通过 + 快速审批:
{
"rectifyId": 150,
"result": 1,
"verifyRemark": "",
"attachments": [],
"signPath": "https://oss.../sign.png",
"quickApprove": true
}
通过 + 不快速审批:
{
"rectifyId": 150,
"result": 1,
"verifyRemark": "",
"attachments": [],
"signPath": "https://oss.../sign.png",
"quickApprove": false,
"assigneeIdentityId": "44"
}
7. 草稿缓存
使用 useDraftCache,命名空间 DRAFT_NS.ACCEPT,key 基于 rectifyId。
会缓存:
- 验收结果、备注、快速审批选择
- 下一步处理人选择
- 验收上传附件列表
- 签名相关状态
不会缓存:
- 整改记录只读区(每次进页重新拉接口)
恢复草稿后会再次调用 fetchNextStep(),保证下一步流程与当前验收选择一致。
8. 关键函数索引
| 函数 | 作用 |
|---|---|
loadPageData |
页面数据加载入口 |
fetchRectifyDetail |
调整改详情,有 rectifyId 时用 |
fetchDetail |
调隐患详情,无 rectifyId 时兜底 |
applyRectifyData |
统一映射整改记录到页面 |
resolveManagerNames / resolveMemberNames |
人员名映射(优先 members/managers 的 nickName) |
buildPreviewVariables |
构建下一步流程预览变量 |
fetchNextStep |
请求下一步流程名称 |
onResultChange / onQuickApproveChange |
切换验收选项后刷新流程预览 |
openAssigneePopup / fetchAssigneeList |
通过时选择下一步处理人 |
validateFormBeforeSubmit |
提交前表单校验 |
handleSubmit / executeSubmit |
签名处理 + 提交验收 |
9. 关联文件
| 文件 | 关系 |
|---|---|
utils/hazardNav.js |
构建跳转 URL(含 taskId) |
request/api.js |
接口定义 |
utils/upload.js |
附件上传与 buildAttachmentItem |
utils/draftCache.js / utils/useDraftCache.js |
草稿 |
pages/hiddendanger/rectification.vue |
签名 canvas 穿透弹窗的同类处理参考 |
10. 常见问题速查
| 现象 | 可能原因 |
|---|---|
| 下一步流程显示「暂无」 | URL 未带 taskId,且详情接口也解析不到 |
| 人员显示身份名而非 nickName | members 数组为空,走了 memberNames 兜底 |
| 不通过时处理人不对 | 应检查 rectify/detail 的 rectifierName 是否有值 |
| 选人弹窗被白块挡住 | 签名 canvas 未在弹窗打开时卸载 |
| 选人列表为空 | userInfo.userIdentity.deptId 缺失,或部门无人员 |
| 提交了但后端报处理人错误 | assigneeIdentityId 传的是 userId,需确认后端是否接受 |
11. 维护建议
- 有
rectifyId就不要再调hazard/detail做展示,避免重复请求和数据覆盖混乱。 - 改人员展示逻辑时,优先看
resolveManagerNames/resolveMemberNames,不要直接改模板。 - 改流程预览时,确认
taskId、previewVariables、includeSubProcess: true三者始终齐全。 - 新增提交字段时,同步更新本文档第 6 节。