日期: 2026-07-04
状态: 已实现(2026-07-04)
前置: 现有pl_plan_product.purchase_cert_url/transport_cert_url双证校验逻辑;/#/pl/plan-cert危化品证上传页
界面模式: P06 复杂业务列表 + 弹窗表单(延续危化品证上传页)
| 环节 | 行为 |
|---|---|
| 危化品识别 | 以 CRM 产品主数据 isToxic / isExplosive 为准 |
| 证书存储 | 计划产品行 pl_plan_product.purchase_cert_url(购买证)、transport_cert_url(合法使用证明) |
| 上传页校验 | 上传弹窗保存时 强制 每个危化品产品两个 URL 均非空 |
| 安排运输校验 | 前端 buildMissingHazardCertMessage + 后端 transport.py / _validate_toxic_products 均要求 双证齐全 |
实际业务中,是否需要购买证、合法使用证明,以及是否两个都要,取决于多种现场条件(产品类型、单据类型、客户资质、运输方式等),规则复杂且频繁变化,难以在系统中穷举。
当前「双证强制」导致:
在 pl_plan 增加 hazard_cert_ready(0/1)及可选审计字段(hazard_cert_ready_by、hazard_cert_ready_time)。
| 优点 | 缺点 |
|---|---|
| 与「安排运输按整单校验」一致,改动面小 | 一单多危化品时无法逐行独立确认 |
| 列表可加一列 Tag,一眼可见 | 计划产品变更后需定义是否自动撤销齐备 |
| 后端一处字段即可 gate 安排运输 | 依赖人工责任心,需审计字段 |
在 pl_plan_product 每行增加 cert_ready。
| 优点 | 缺点 |
|---|---|
| 多产品粒度更细 | 安排运输需「所有危化品行齐备」聚合逻辑 |
| 与现有证书 URL 同表,语义近 | UI 更复杂(每行按钮或弹窗内逐行确认) |
| 优点 | 缺点 |
|---|---|
| 理论上可自动化 | 客户已明确规则复杂、难维护,与诉求相反 |
| 开发成本高、持续运维 |
推荐:方案 A(计划级标志),配合审计字段与产品变更自动撤销。若后续确需逐产品确认,可演进为方案 B,API 可预留。
| # | 决策 | 说明 |
|---|---|---|
| D1 | 齐备粒度:计划级 | pl_plan.hazard_cert_ready,仅对「含至少一个危化品产品」的计划有意义 |
| D2 | 无危化品计划免校验 | 计划不含易制毒/易制爆产品时,安排运输不检查齐备标志 |
| D3 | 上传不再强制双证 | 上传弹窗保存时允许购买证/合法使用证明 0~2 个任意组合;至少保留「有危化品产品行」才允许保存附件 |
| D4 | 安排运输只查齐备标志 | 替换现有 purchase_cert_url && transport_cert_url 校验(前后端一致) |
| D5 | 齐备为人工显式操作 | 【危化品证上传】列表工具栏 + 查看弹窗 hero 提供「证书齐备」;需二次确认 |
| D6 | 可撤销齐备 | 提供「取消齐备」;已归档/已作废计划不可操作 |
| D7 | 产品变更自动撤销 | 计划编辑导致危化品产品集合变化(增删改 productId 或危化品行)时,自动 hazard_cert_ready=0 |
| D8 | 上传证书不自动齐备 | 保存附件 ≠ 证书齐备;须单独点击「证书齐备」 |
| D9 | 运输计划页无上传入口 | 维持已移除「上传证书」;仅提示「请至危化品证上传页确认证书齐备」 |
| D10 | 零附件可确认齐备 ✅ 2026-07-04 | 不要求任何附件即可点击「证书齐备」;人工确认即视为通过(证在客户处、纯备案等场景) |
| D11 | 齐备后可继续补传附件 ✅ 2026-07-04 | hazard_cert_ready=1 不阻断 后续在危化品证上传页打开上传弹窗、补充/更新购买证或合法使用证明;齐备状态保持,除非 D7 触发撤销 |
pl_plan 新增字段| 字段 | 类型 | 说明 |
|---|---|---|
hazard_cert_ready |
tinyint, default 0 | 危化品证书是否已人工确认齐备:0-否 1-是 |
hazard_cert_ready_by |
varchar(64), nullable | 确认人 user id |
hazard_cert_ready_time |
datetime, nullable | 确认时间 |
DDL 写入 docs/sql/shanxia2.0.sql(及迁移片段如项目惯例)。
pl_plan_product.purchase_cert_url / transport_cert_url 保留,继续用于存档与列表「有/无」展示;PATCH /api/transport/plan/{id}/hazard-cert-ready
Body: { "ready": true | false }
规则:
ready=true:计划须含至少一个危化品产品(CRM 标识),否则 400;不校验 是否已上传任何附件(D10);ready=false:清空 hazard_cert_ready_by/time;update_by;可选写操作日志。权限:pl:plan-cert:edit 或与上传证书同权限 pl:plan-cert:list + 编辑(与菜单权限对齐,实现时查现有 plan-cert 权限码)。
_validate_toxic_products 与 transport.py 内联校验改为:
# 伪代码
if plan_has_hazard_products(plan):
if not plan.hazard_cert_ready:
raise HTTPException(400, "该计划危化品证书尚未确认齐备,请至危化品证上传页操作")
删除对 purchase_cert_url / transport_cert_url 的非空检查。
在 update_plan(或产品明细 diff 逻辑)中:若危化品产品集合或危化品行 id 集合变化 → hazard_cert_ready=0,清空 by/time。
_row_to_dict / Plan schema 增加:
hazardCertReady (bool/int)hazardCertReadyBy / hazardCertReadyTime(详情与危化品证上传列表展示)plan-cert/index.vue列表
el-tag,success=已齐备 / warning=待确认 / info=无需(无危化品);CircleCheck 图标),确认框后调 API;CircleClose),确认框后调 API。上传弹窗 PlPlanCertUploadDialog
ElMessage.warning 拦截;hazardCertReady=1 禁用「上传证书」;查看弹窗 hero-actions
plan/index.vue + PlPlanArrangeDialog!hazardCertReady,ElMessageBox.alert:buildMissingHazardCertMessage 对 URL 的检查(可保留 composable 供列表展示「有/无」,或重命名用途)。PlPlanListCertCell / PlPlanListProductCell 继续展示各证「有/无」,不作为运输门槛;[计划含危化品]
│
├──(可选) 零附件──► 点击「证书齐备」+ 确认 ──► hazard_cert_ready=1 ──► 可安排运输
│
└──(可选) 先传部分附件 ──► 同上
│
└── 已齐备后仍可「上传证书」补传/更新附件(齐备状态不变,D11)
│
编辑计划(危化品行变化) ──► 自动撤销齐备 (hazard_cert_ready=0)
点击「取消齐备」 ──► hazard_cert_ready=0
无危化品计划:hazard_cert_ready 保持 0,安排运输跳过校验。
| 层 | 文件/模块 |
|---|---|
| SQL | docs/sql/shanxia2.0.sql |
| Model | backend/app/models/pl_models.py |
| Schema | backend/app/schemas/pl/plan.py |
| Service | pl_plan_service.py:_validate_toxic_products、update_plan 撤销逻辑、新增 set_hazard_cert_ready |
| API | plan.py:PATCH hazard-cert-ready;transport.py:校验替换 |
| FE API | web-admin/src/api/pl/index.ts |
| FE 页 | plan-cert/index.vue |
| FE 组件 | pl-plan-cert-upload-dialog、pl-plan-arrange-dialog |
| FE 类型 | Plan interface、usePlToxicProductCertCheck.ts(调整或拆分) |
非目标:不改 CRM 产品危化品标识;不改司机/车辆危化品证(hazmat_cert_no)逻辑。
| 风险 | 缓解 |
|---|---|
| 人工误点齐备导致无证运输 | 二次确认文案强调合规责任;记录确认人/时间;列表保留附件有/无 |
| 计划变更后仍显示已齐备 | D7 自动撤销 |
| 历史已双证齐全的计划 | 迁移:含危化品且双证 historically 齐全 可批量 hazard_cert_ready=1(可选脚本,非必须) |
| 后端被绕过 | 安排运输 API 服务端强制校验齐备标志 |
| # | 问题 | 状态 |
|---|---|---|
| 1 | 齐备粒度:计划级还是产品级? | 默认 计划级(D1),若无异议按此实现 |
| 2 | 零附件是否允许齐备 | ✅ 已确认:允许(D10);人工点确认即通过 |
| 3 | 齐备后是否可补传附件 | ✅ 已确认:可以(D11);齐备不锁死上传入口 |
| 4 | 权限:「证书齐备」是否与「上传证书」同一角色即可? | 待确认(默认:是,沿用 pl:plan-cert:list 菜单权限) |
| 5 | 历史数据:是否对已有双证齐全的计划批量标记已齐备? | 待确认(默认:否,由操作员按需点确认) |