2026-10-17-mp-webview-pl-plan-cert.md 9.5 KB

危化品证上传移动 H5 Implementation Plan

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox syntax for tracking.

Goal: 将 Web 危化品证上传完整迁移为小程序运输管理下的移动 H5,移除导出,保留五个 Tab 与全部其他业务能力。

Architecture: 新增独立 views/m/pl/plan-cert/ 模块,读取既有 API、规则和展示工具,不修改 Web 页面或共享逻辑。页面壳、底部筛选、附件组件复用既有移动模式;独立菜单 SQL 只补入口与祖先角色授权。

Tech Stack: Vue 3、TypeScript、Element Plus、SCSS、uni-app WebView、Node test/tsx、Playwright、MySQL 5.7 菜单 SQL。

Task 0:用户反馈第三次校准(2026-10-17)

Files: openspec/changes/zkxw-engineering-standards/specs/ui-conventions/spec.md, docs/miniprogram-ui-spec-sanqiang.md, bak/mobile-ui/shanxia-mp-crm-pl-cert-style-align-demo.html, web-admin/src/router/routes/staticRoutes.ts, web-admin/scripts/mp-pl-plan-cert-entry.test.mjs, web-admin/scripts/test-mp-pl-plan-cert.mjs, web-admin/src/views/m/pl/plan-cert/index.vue, detail.vue, CertDetail.vue, CertUpload.vue, CertFilters.vue, cert.scss, docs/web-admin-mp-webview-modules.md, delivery/issues docs。

  • Step 1:写失败测试。 入口测试断言 /m/pl/plan-cert/:id 映射 detail.vue;浏览器测试断言列表使用标准 mp-wv-header(17px 标题、单胶囊搜索、无副标题/独立搜索按钮)、列表卡横向 x=0/宽=viewport、查看后 URL 进入独立详情、页面不存在“计划详情”Sheet/ticket-*、三 Tab 存在;筛选/上传 Sheet 底栏两个按钮各约 96px、间距 ≥12px、整体水平居中、字号14px、触达 ≥44px。运行并确认因当前结构失败。
  • Step 2:更新视觉权威。 OpenSpec、UI 规范和 Demo 将详情 SHALL 改为“独立路由 + 普通绿顶栏 + Tab + 信息卡 + 底栏”,删除通用票根要求;为危化品证补“无顶部特殊区、列表全宽、Sheet 按钮居中适宽”场景,Code review 清单同步。
  • Step 3:标准化列表。 index.vue 复用 mp-wv-header 和单个胶囊 search input,移除自定义副标题/搜索按钮;保留搜索→状态Tab→三栏筛选顺序。目标列表区用局部 full-bleed 布局取消双重水平留白,提示文字自行加内边距;不改其他页面。
  • Step 4:创建独立详情。 新增 detail.vue 与动态路由;把现有详情内容从 MpBottomSheet 容器迁入独立 MpWebviewShell 页面,删除票根,保留三 Tab、所有字段、运输复制、合同关联、反馈、证书与附件。详情自行加载权限/ID/数据,并编排上传、齐备、取消齐备和原位刷新;列表与关联计划统一 router.push。
  • Step 5:修正 Sheet 底栏。 只在 plan-cert 的 CertFilters.vue、CertUpload.vue/模块样式中使用居中 action group;按钮 flex:0 0 96px、间距12px、14px字体、44px命中高度,避免共享 MpBottomSheet 全局回归。
  • Step 6:回归功能。 保留五 Tab、查询筛选、分页、批量、上传预览/下载/删除、保存重试、权限、状态限制、合同和复制动作;独立详情新增直达/刷新/路由ID切换测试。运行 E2E 确认由红转绿。
  • Step 7:验证与交付。 执行 model/入口测试、目标 ESLint/Stylelint/Prettier、生产构建、类型基线对比,查看 375/414px 列表/详情/Sheet/附件截图;更新交付与问题文档并更新 frontend/miniprogram/root 图谱。

Task 1:独立移动模块(实现子任务)

Files (new, only): web-admin/src/views/m/pl/plan-cert/model.ts, model.test.ts, index.vue, CertFilters.vue, CertUpload.vue, CertDetail.vue, CertAttachments.vue, PlanCard.vue, cert.scss; 可将详情内运输复制和段次展示拆成同目录单一职责组件。

  • 先写 model 测试并执行 cd web-admin && pnpm exec tsx --test src/views/m/pl/plan-cert/model.test.ts,确认缺失实现导致失败。
  • [x] 建立查询与操作纯函数:

    buildCertQuery(tab, keyword, filters, page, pageSize)
    canUploadCert(plan) // archiveStatus !== archived && followStatus !== cancelled
    eligibleReadyPlans(plans, ready) // 含危化品、可操作且当前状态不同
    certPayload(products) // 仅 id、purchaseCertUrl、transportCertUrl、legalUseCertUrl
    

    测试五 Tab hasHazardProduct=1、未上传 certUploadStatus=incomplete/hazardCertReady=0、默认 followStatus 排除 cancelled、Tab 冲突优先、显式已取消筛选、空/多 URL 保留和去除无关字段、归档/已取消及批量跳过。

    • 实现列表:五个固定顺序文字 Tab,关键词、日期快捷、全部字段筛选、排序、刷新、分页重试、可展开卡片、多选和清除选中。请求版本号拒绝过期响应;只有成功后更新分页;Tab/查询变化清空选中。按 Web 配对行工具过滤卡片段次,保留全部原列信息。
    • 实现筛选面板:直接读 Web columnFilterDefs,enum 静态选项/动态 facet,datetime 范围、number 操作符映射到 queryKeyPrefix,text 映射 queryKey;应用前校验范围。复用 Web 装送客户/合同侧别参数转换,不改原文件。
    • 实现上传面板:每次打开取最新详情并 enrich 危化属性;使用共享 getRequiredCertSlots、AttachmentUploadField;暴露上传中检查,保存前必须检查全部实例;允许空附件,不自动齐备;保存失败保留内容;上传 PATCH 只提交产品证书字段。
    • 实现详情和卡片附件:显示全部段次/产品及数量、基本信息、车辆、运输回传、运费、备注、证书和合同关联;仅保留 Web 本菜单原操作。复制给司机/现场及磅单二维码沿用 usePlPlanArrangeActions,不引入新增计划/作废/安排运输。
    • 权限先获取 fetchGetMenuCodes(),上传/齐备分别判断 Web 按钮权限;失败关闭写入口。提交二次确认,批量逐条处理并汇报成功/失败/跳过,完成后刷新当前详情及列表。
    • module 样式只在本模块 .cert-module / .cert-* 及挂载期间的弹层范围内,三墙绿、44px 触达、375/414px 不横向溢出,附件同列换行。所有新增 Vue API/Element 组件使用已有自动导入。
    • 执行 model 测试、目标 ESLint/Prettier,报告结果及发现但未改的其他模块问题。
    • 独立规格审查通过后进行代码质量审查,修复本次新增问题。

    Task 2:入口和菜单(主任务集成)

    Files: web-admin/src/router/routes/staticRoutes.ts, miniprogram/config/api.js, miniprogram/config/workbench-menus.js, docs/sql/migrations/2026-10-17-mini-pl-plan-cert-webview-menus.sql, docs/miniprogram-ui-spec-sanqiang.md, docs/web-admin-mp-webview-modules.md。

    • 先新增 web-admin/scripts/mp-pl-plan-cert-entry.test.mjs,断言路由、工作台所属组、映射和 SQL 不修改 Web 菜单,运行 node test 验证缺入口失败。
    • 只读确认测试库移动端运输父菜单;绝不打印连接密码,不写数据库。
    • 路由接入: ts { path: '/m/pl/plan-cert', name: 'MpPlPlanCert', component: () => import('@/views/m/pl/plan-cert/index.vue'), meta: { title: '危化品证上传', isHideTab: true, isMpWebview: true } }
  • [x] 工作台加入 {name:'危化品证上传', enabled:true, code:'pl-plan-cert-webview', icon:'📑', perms:'mini:pl:plan-cert:list'};路由映射 PAGE_PATHS.mpWebview + '?path=' + encodeURIComponent('/m/pl/plan-cert')。

  • [x] SQL 使用实际查到的移动根/运输父菜单关系,不新建同名父级;事务中新增移动叶子并对有 Web 列表权限角色补祖先,保持幂等、租户隔离、仅本模块菜单。未授权不执行。

  • [x] 写移动页面结构规范、模块路径/权限/首次发布说明,复跑入口测试与 node --check 两个 mini 配置。

Task 3:集成验证、审查、交付

Files: web-admin/scripts/test-mp-pl-plan-cert.mjs, docs/superpowers/specs/2026-10-17-mp-pl-plan-cert-delivery.md, docs/superpowers/specs/2026-10-17-mp-pl-plan-cert-existing-issues.md。

  • 参考客户测试建立仅在 API 边界模拟的浏览器测试,页面模块使用真实代码;拦截 /api/ 请求,不误拦截 /src/api/,未知业务写请求直接失败。
  • 测试五 Tab 参数、全字段筛选代表路径、关键词日期、分页失败重试、选中重置、单/批齐备和取消、无权限、归档/取消限制、详情关联信息、附件选择/上传等待/删除/保存失败与重试,断言没有导出按钮。
  • 截图375和414宽度的列表/筛选/详情/附件,检查无横向溢出、关键信息可见、附件卡片一致。
  • pnpm build、pnpm exec vue-tsc --noEmit、新增测试与目标 lint;类型检查如失败和前序675错误基线比较,新增错误必须清零,不修其他模块错误。
  • 对实施前保存的 Web/后端/共享组件 SHA256 作逐项比较,证明未改用户禁止范围。
  • 规格审查→代码质量审查→修复→复测,记录真实结果,不以模拟测试代替真机验收。
  • ./scripts/update-graph.sh frontend、graphify update miniprogram、graphify update . 更新对应图谱;图谱体量限制或缺少工具如实记录。
  • 交付文档覆盖完整需求、执行命令结果、待发布/SQL步骤和既有问题。不提交/推送混有用户更改的工作区,不写生产库。