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。
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。
/m/pl/plan-cert/:id 映射 detail.vue;浏览器测试断言列表使用标准 mp-wv-header(17px 标题、单胶囊搜索、无副标题/独立搜索按钮)、列表卡横向 x=0/宽=viewport、查看后 URL 进入独立详情、页面不存在“计划详情”Sheet/ticket-*、三 Tab 存在;筛选/上传 Sheet 底栏两个按钮各约 96px、间距 ≥12px、整体水平居中、字号14px、触达 ≥44px。运行并确认因当前结构失败。index.vue 复用 mp-wv-header 和单个胶囊 search input,移除自定义副标题/搜索按钮;保留搜索→状态Tab→三栏筛选顺序。目标列表区用局部 full-bleed 布局取消双重水平留白,提示文字自行加内边距;不改其他页面。detail.vue 与动态路由;把现有详情内容从 MpBottomSheet 容器迁入独立 MpWebviewShell 页面,删除票根,保留三 Tab、所有字段、运输复制、合同关联、反馈、证书与附件。详情自行加载权限/ID/数据,并编排上传、齐备、取消齐备和原位刷新;列表与关联计划统一 router.push。CertFilters.vue、CertUpload.vue/模块样式中使用居中 action group;按钮 flex:0 0 96px、间距12px、14px字体、44px命中高度,避免共享 MpBottomSheet 全局回归。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; 可将详情内运输复制和段次展示拆成同目录单一职责组件。
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 保留和去除无关字段、归档/已取消及批量跳过。
columnFilterDefs,enum 静态选项/动态 facet,datetime 范围、number 操作符映射到 queryKeyPrefix,text 映射 queryKey;应用前校验范围。复用 Web 装送客户/合同侧别参数转换,不改原文件。fetchGetMenuCodes(),上传/齐备分别判断 Web 按钮权限;失败关闭写入口。提交二次确认,批量逐条处理并汇报成功/失败/跳过,完成后刷新当前详情及列表。.cert-module / .cert-* 及挂载期间的弹层范围内,三墙绿、44px 触达、375/414px 不横向溢出,附件同列换行。所有新增 Vue API/Element 组件使用已有自动导入。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 配置。
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/ 请求,不误拦截 /src/api/,未知业务写请求直接失败。pnpm build、pnpm exec vue-tsc --noEmit、新增测试与目标 lint;类型检查如失败和前序675错误基线比较,新增错误必须清零,不修其他模块错误。./scripts/update-graph.sh frontend、graphify update miniprogram、graphify update . 更新对应图谱;图谱体量限制或缺少工具如实记录。