2026-10-17-mp-pl-plan-cert-existing-issues.md 7.2 KB

危化品证上传迁移期间的既有问题记录

原迁移范围:只记录迁移范围外的问题,不修改 Web 或其他既有页面。2026-10-17 用户追加授权修复问题 1、4,问题 2、3 按要求忽略,保留记录但不修改对应功能。

1. Web 上传证书时,保存未等待附件上传结束(已修复)

  • 位置:web-admin/src/components/business/pl-plan-cert-upload-dialog/index.vue 的 handleSubmit 和保存按钮。
  • 原因:原保存按钮仅按 hazardProducts.length 禁用;提交函数直接读取三个证书 URL。AttachmentUploadField 在上传完成后才同步 URL,虽暴露 hasUploading(),但原弹窗没有引用或检查它。
  • 可能影响:慢网下选中文件后立即保存,可能提交旧 URL 并关闭弹窗,刚选文件未绑定到计划。
  • 建议复现:浏览器网络限速,选择一个证书文件,在上传返回前点击保存,对比 PATCH 请求载荷与上传返回后的 URL。
  • 修复:收集所有证书附件组件引用,提交前检查 hasUploading();上传中提示“附件正在上传,请稍候再保存”且不提交、不关闭。保存请求期间禁用附件编辑,加载中及重复提交也被拦截。
  • 验证:真实 Web 弹窗和附件组件的 Playwright 测试(API 边界替身)先复现旧代码上传中仍发送 1 次 PATCH,再确认修复后发送 0 次;上传完成后保存包含新 URL,关闭销毁后重开也能正常保存。未写入真实业务数据。
  • 状态:已按追加授权修复。测试脚本:web-admin/scripts/test-pl-plan-cert-upload-dialog.mjs。

2. H5 模块接入文档引用的运输计划菜单 SQL 不存在

  • 位置:docs/web-admin-mp-webview-modules.md 的双权限说明引用 docs/sql/migrations/2026-09-14-mini-pl-plan-webview-menus.sql。
  • 依据:当前工作区读取该路径返回不存在,docs/sql/ 文件检索也未找到同名脚本。
  • 影响:按旧文档发布运输计划时无法直接定位该菜单初始化脚本;不代表数据库现有菜单缺失。
  • 状态:按用户要求忽略,本次未修改旧文档该引用。本模块已有独立菜单脚本,不代表旧运输计划文档问题已修复。

3. 证书写接口未接入对应按钮权限校验(代码审查发现,未越权实测)

  • 位置:backend/app/api/pl/plan.py 的 patch_plan_product_certs、patch_plan_hazard_cert_ready;权限工具在 backend/app/services/pl_plan_cert_perm.py。
  • 依据:两个接口检查登录、租户、计划数据范围后调用业务服务,路由聚合未配置相应菜单权限依赖;user_can_upload_plan_cert、user_can_manage_plan_cert_ready 在当前后端仅有定义、没有调用。Web 页显示按钮的检查不能代替服务端权限检查。
  • 可能影响:有计划数据访问范围但没有对应按钮权限的登录用户,可能仍可直接调用证书写接口。
  • 状态:按用户要求忽略,本次未修改权限校验;未使用真实账号实施越权请求。新移动页保留独立的按钮及提交前权限检查,但不能声称已修复服务端权限问题。

4. 证书附件保存服务未拒绝已取消计划(已修复)

  • 位置:backend/app/services/pl_plan_service.py 的 update_plan_product_certs。
  • 原因:原函数拒绝已归档计划,但没有与 set_hazard_cert_ready 一样检查 follow_status == 'cancelled';前端 Web 的 canUploadCert 则禁止已取消计划操作。
  • 可能影响:页面打开后计划被另一用户取消,仍可能保存证书附件,前后端状态限制不一致。
  • 修复:读取计划后、查询及修改产品证书前,检查已作废状态并返回 HTTP 400:“已作废的计划不能修改危化品证书”。保留原租户、软删除和归档检查;不改变按钮权限。
  • 验证:服务回归测试先确认旧代码对已作废计划不抛错,修复后确认拒绝且不修改 URL、修改人、齐备状态,不提交事务;另覆盖已归档、不存在及正常计划保存。测试使用数据库边界替身,不写入真实业务库;不声明已解决数据库事务之间的并发锁定问题。
  • 状态:已按追加授权修复。测试文件:backend/tests/test_pl_plan_product_certs.py。

5. CRM 六个移动菜单未回灌全量 SQL 基线(仅记录)

  • 位置:docs/sql/shanxia2.0.sql 与 docs/sql/migrations/2026-10-15-mini-crm-*-webview-menus.sql、2026-10-17-mini-crm-customer-webview-menus.sql。
  • 依据:当前全量基线未包含 MINI_CRM_* 菜单;客户、产品、报价、报价审批、合同、合同审批只存在于增量迁移。
  • 可能影响:仅使用全量基线初始化的新环境不会出现六个工作台入口,必须额外执行对应迁移。
  • 状态:本轮先记录。用户当前授权是界面标准化,不据此写数据库;在 CRM 六页收尾时再评估是否同步基线 SQL。

6. 旧 CRM 菜单迁移对软删除记录的幂等性不足(仅记录)

  • 位置:2026-10-15 的产品、报价和合同工作台菜单迁移。
  • 依据:脚本的 NOT EXISTS 仅检查 del_flag=0,但插入使用固定主键;若同主键记录已软删除,重新执行会触发主键冲突。客户迁移已使用 ON DUPLICATE KEY UPDATE del_flag=0,行为更稳健。
  • 可能影响:环境曾软删除菜单后重跑迁移可能失败,祖先角色绑定也可能无法恢复。
  • 状态:本轮先记录,不修改数据库迁移或真实数据。

7. 旧小程序 CRM 回归说明仍标记已启用入口为“未开放”(仅记录)

  • 位置:bak/miniprogram-e2e/cases/01-crm.md。
  • 依据:文档仍把产品管理、合同审批描述为灰卡/未开放;当前 workbench-menus.js 中六个 CRM WebView 入口均已启用并受权限过滤。
  • 可能影响:人工验收人员可能按过期说明跳过页面或误报入口状态。
  • 状态:本轮只记录;CRM 六页交付时统一修订回归说明。

8. Demo 原“证书上传时间”没有可对应的 Web/API 筛选字段(已校准文档)

  • 位置:bak/mobile-ui/shanxia-mp-crm-pl-cert-style-align-demo.html 的危化品证「更多」示意字段。
  • 依据:Web 端 columnFilterDefs.ts 与计划列表 API 只有计划日期、送货时间、证书齐备状态等已生效条件,没有独立的证书上传时刻字段。
  • 处理:按用户“功能完全参考 Web 端”的要求,删除 Demo 中无法生效的示意字段,并在 OpenSpec/UI 规范中明确单页不得为凑控件类型伪造查询条件;未改动后端或其他页面功能。

本次验证

  • 后端:venv/bin/python -m pytest tests/test_pl_plan_product_certs.py tests/test_pl_plan_cert_list_filters.py tests/test_pl_menu_badge_plan_cert.py tests/test_pl_plan_product_upsert.py tests/test_pl_plan_draft_save.py -q(在 backend/):17 项通过。
  • Web:node scripts/test-pl-plan-cert-upload-dialog.mjs(在 web-admin/,本地 Vite 默认端口 3006):通过。
  • 构建:pnpm build 通过;保留原有组件重名和包体积警告。pnpm exec vue-tsc --noEmit 仍未通过,其输出与修复前基线完全一致,无本次新增类型错误。
  • 本次没有新增字段、数据库结构或菜单权限变更,无需执行 SQL。