This commit is contained in:
zlwu committed 2026-07-18 09:14:02 +08:00
1 parent a903fcf6d4
commit 259c55cc23
80 files changed
+6090 -123

No files matched your search

+18 -2
View File
@@ -221,8 +221,22 @@ Tab:首页(占位) | 待办(占位) | 工作台★ | 我的
| S9 | 运输 | 运费结算 + 用户选项 | 列表/选人接口正常 | [x] freight 列表 + users/options ok;无待结算 |
| S10 | 运输 | 运费待审批列表 | 列表正常 | [x] 列表空态 ok |
**接口冒烟结论**:S1–S10 **读路径全部通**(0 FAIL)。写路径有 3 处需跟进:① 线索跟进字段;② 报销创建体应用 `details` 而非 `items`;③ 安排运输依赖证书齐备业务数据。
**前端 UI**:仍由人工在微信开发者工具/真机验收。
**接口冒烟结论**:S1–S10 **读路径全部通**(0 FAIL)。写路径有 3 处需跟进:① 线索跟进字段;② 报销创建体应用 `details` 而非 `items`;③ 安排运输依赖证书齐备业务数据。
### 7.2 H5 UI 冒烟(Playwright,不改 uni-app 工程)
> **执行**:2026-07-17,H5 `http://localhost:5173/`,账号 `admin` / `admin123`,后端 `127.0.0.1:8000`。
> 脚本:独立目录 `miniprogram-e2e/smoke.mjs`(`cd miniprogram-e2e && node smoke.mjs`);截图与 JSON 在 `miniprogram-e2e/artifacts/`。
| # | 路径 | 结果 |
|---|------|------|
| E1 | 登录 → 工作台四模块可见 | [x] PASS |
| E2 | 线索管理 | [x] PASS |
| E3 | 报销申请 | [x] PASS |
| E4 | 地磅仪表盘 | [x] PASS |
| E5 | 运输计划 | [x] PASS |
**UI 冒烟结论**:E1–E5 **全通**(0 FAIL)。微信开发者工具 / 真机验收仍见 §7 未勾项。
---
@@ -248,6 +262,8 @@ Tab:首页(占位) | 待办(占位) | 工作台★ | 我的
| 2026-07-16 | P1–P4 | CRM / 报销 / 地磅 / 运输业务页落地并接线工作台 |
| 2026-07-16 | P4+ | 运费提交审批改为用户选项选人 Sheet;P5 冒烟表写入 §7.1 |
| 2026-07-17 | P5 | 接口冒烟 S1–S10 读路径全通(脚本 `mp_api_smoke.py`);写路径 3 处待对齐见 §7.1 |
| 2026-07-17 | P5 | H5 Playwright E1–E5 冒烟全通(`miniprogram-e2e/smoke.mjs`,见 §7.2) |
| 2026-07-17 | P5 | 按 QA 节奏启动:先全量文字用例(`miniprogram-e2e/cases/`),脚本验证待用例评审后逐步开展 |
<!-- 每完成一批任务追加一行,例如:
| 2026-0x-xx | P0 | TabBar + 工作台落地 |
@@ -0,0 +1,42 @@
# 小程序 CRM 产品分类 Implementation Plan
> **For agentic workers:** Inline execution in this session (user requested 请实现).
**Goal:** 在小程序工作台落地 CRM「产品分类」缩进展开树管理页,功能对齐 Web 核心 CRUD。
**Architecture:** 复用 `/web/crm/product-categories/*`;list 页本地 `expandedIds` 控制可见扁平行;form 页独立路由承载新增/编辑/子分类。
**Tech Stack:** uni-app Vue3、现有 `api/crm.js` + `mp-*` 样式、三墙 Token。
---
### Task 1: API + 路由入口
**Files:**
- Modify: `miniprogram/api/crm.js`
- Modify: `miniprogram/config/api.js`
- Modify: `miniprogram/config/workbench-menus.js`
- Modify: `miniprogram/pages.json`
- [x] 增加 tree/add/update/delete 四个方法
- [x] PAGE_PATHS + WORKBENCH_ROUTE_MAP + 菜单 enabled
- [x] pages.json 注册 list/form
### Task 2: 列表页 list.vue
**Files:**
- Create: `miniprogram/pages/crm/product-category/list.vue`
- [x] 搜索、状态 chips、展开树、行操作、删除确认
### Task 3: 表单页 form.vue
**Files:**
- Create: `miniprogram/pages/crm/product-category/form.vue`
- [x] 上级选择、名称/排序/状态/备注、提交
### Task 4: 收尾
- [x] 更新 design spec 状态
- [x] Demo 标注已采用方案 A
@@ -0,0 +1,87 @@
# 小程序按钮与弹窗用例补全设计
> 日期:2026-07-18
> 状态:已确认(用户选组织方式 C + 源码静态盘点方案 1)
> 范围:`miniprogram` H5/小程序四模块 + 壳层
## 1. 背景与问题
现有 `miniprogram-e2e/cases/00–04` 用例偏重页面与字段,**按钮与弹窗内按钮未做门禁式穷尽覆盖**。
人类测试工程师要求:每个界面可点控件都有用例;点击后若出现弹窗 / ActionSheet / Sheet,则**层内每个按钮**也要有独立用例。
## 2. 目标
1. 建立总清单门禁:`BUTTON-DIALOG-INVENTORY.md`,无 `TODO` 才算「按钮用例写完整」。
2. 详细步骤写在各模块用例文件(`00-shell`…`04-pl`),总清单用用例 ID 回链。
3. 仍遵守「一次只测一个界面」的执行节奏(第二步执行时)。
## 3. 非目标
- 本阶段不执行自动化点测、不改业务代码。
- 不覆盖灰卡背后的未实现业务页内部按钮(灰卡仅测 Toast「本期暂未开放」)。
## 4. 方法(方案 1)
1. 静态扫描 `pages/**/*.vue` + `components/mp-approver-picker`。
2. 识别:页头/底栏/卡片按钮、链接、`uni.showModal`、`uni.showActionSheet`、自定义弹窗、Sheet。
3. 写入总清单;弹层内每个按钮单独成行。
4. 为每行分配/回填用例 ID;缺则 `TODO`。
5. 按界面把 `TODO` 补进模块用例文件后,更新清单状态。
## 5. 总清单字段
| 字段 | 说明 |
|------|------|
| INV-ID | 清单行号,如 `INV-LGN-01` |
| 模块 / 界面 / 路径 | 定位 |
| 触发控件 | 准确文案 |
| 控件类型 | 页头/底栏/卡片/导航/勾选/快捷卡/上传… |
| 弹出层类型 | 无 / showModal / ActionSheet / 自定义弹窗 / Sheet |
| 弹层标题 | 原文 |
| 层内按钮 | 本行关注的那一个按钮文案 |
| 显示条件 | 状态/Tab 等 |
| 用例 ID | 已写则填;否则 `TODO` |
| 最小集 | 见 §6 |
## 6. 有弹层时的最小用例集(门禁)
对每个「触发控件 → 弹层」组合,至少包含:
| # | 用例意图 |
|---|----------|
| 1 | 点击触发 → 弹层出现(标题/关键文案正确) |
| 2 | 点取消/否 → 关闭且业务不变 |
| 3 | 点确认/是/通过等 → 成功路径(或校验失败提示) |
| 4 | 若遮罩可关 → 点遮罩等同取消(一条) |
| 5 | ActionSheet → **每个 item** 至少一条 |
| 6 | Sheet → 取消、确定、未选确定校验 各至少一条 |
无弹层的按钮:至少「点击 → 预期导航/提交/Toast」一条;写操作另补失败/连点等按模块文件既有标准。
## 7. 交付物
| 路径 | 说明 |
|------|------|
| `docs/superpowers/specs/2026-07-18-mp-button-dialog-cases-design.md` | 本文 |
| `miniprogram-e2e/cases/BUTTON-DIALOG-INVENTORY.md` | 总清单门禁 |
| `miniprogram-e2e/cases/00–04*.md` | 补齐详细用例(清单驱动,分批) |
| `miniprogram-e2e/cases/README.md` / `PROGRESS.md` | 索引更新 |
## 8. 完成定义(DoD)
- [ ] 总清单覆盖启用业务页 + 壳层全部可点主操作与全部弹层按钮行
- [ ] 清单中无 `TODO`(均已回链用例 ID)
- [ ] 模块文件中存在对应该 ID 的可执行步骤(预置/步骤/预期)
- [ ] 评审确认后,才进入第二步「按界面执行」
## 9. 风险
- 条件按钮(如仅 draft 显示)需造数才能执行,用例仍须先写全。
- `showModal` 确认键系统默认为「确定」,用例文案以真机/H5 实际为准。
- 费用项目 ActionSheet 的 item 动态来自接口,清单记「动态 item」,用例要求「至少选一项 + 无数据 Toast」。
## 10. 自检
- 无 TBD/占位未解释
- 与用户已选 C + 方案 1 一致
- 不扩大到真机执行本阶段范围
@@ -0,0 +1,124 @@
# 小程序 · CRM 产品分类(缩进展开树)设计
> 日期:2026-07-18
> 状态:已确认并实现
> 视觉 Demo:`mobile-ui/shanxia-mp-crm-product-category-demo.html`(方案 A)
> 功能对照:`web-admin/src/views/crm/product-category/index.vue`
## 1. 背景
- 小程序工作台 CRM 模块中「产品分类」为灰卡(`enabled: false`),页面未实现。
- Web 管理端已具备完整能力:分类树列表、名称/状态筛选、新增/修改/新增子分类/删除、全部展开/折叠。
- 后端接口已存在:`/web/crm/product-categories/{tree,add,update,delete}`,小程序可复用(与其它 CRM 页相同,走 admin JWT)。
## 2. 目标
1. 小程序工作台可进入「产品分类」管理页,功能对齐 Web 端核心 CRUD。
2. 树形数据采用 **方案 A:缩进展开树**(一屏总览 + 行内操作),视觉对齐 Demo 方案 A 与三墙 Token。
3. 复用现有后端,不新增接口;不改表结构。
## 3. 非目标
- 不做 Excel 导入/导出、列显隐、多选批量删除(Web 端工具栏扩展能力本期不做)。
- 不做产品管理页(「产品管理」仍为灰卡)。
- 不改 Web 端产品分类页。
## 4. 信息架构与页面
| 页面 | 路径 | 职责 |
|------|------|------|
| 分类树列表 | `pages/crm/product-category/list` | 搜索、状态筛选、展开树、行操作入口 |
| 新增/编辑表单 | `pages/crm/product-category/form` | 新增顶级 / 新增子分类 / 编辑;选择上级分类 |
入口:工作台 `产品分类` → `enabled: true`,`code: 'crm-product-category'` → 路由到 list。
## 5. UI 设计(方案 A)
### 5.1 列表页骨架
顺序对齐现有 CRM 子页与 Demo:
1. Header:返回工作台 · 标题「产品分类」·「全部展开/折叠」·「+ 新增」
2. 搜索框:分类名称(确认搜索,调用 tree 接口 `categoryName`)
3. 状态 chips:全部 / 正常 / 停用(对应 `status` 空 / `0` / `1`,与 Web 字典 `sys_normal_disable` 一致)
4. 树列表:白底圆角容器内的缩进行
### 5.2 树行
每行展示:
- 左侧展开箭头(无子节点隐藏);缩进按层级(约 18px/级)
- 分类名称(主文案)
- 元信息:状态 Tag(正常=success / 停用=muted)· 排序号 · 子类数量(有子时)
- 右侧:`+`(新增子分类)· `⋯`(打开 ActionSheet:编辑 / 新增子分类 / 删除)
交互:
- 点箭头:仅展开/折叠该节点(本地 `expandedIds`,默认展开一级有子节点)
- 点「全部展开/折叠」:切换整树展开态(对齐 Web)
- 点「+ 新增」:进入 form,上级为空(顶级)
- 点行内 `+` 或 Sheet「新增子分类」:进入 form,预填 `parentId`
- 点 Sheet「编辑」:进入 form,带 `id`
- 点 Sheet「删除」:`uni.showModal` 确认后调 delete,成功刷新树
树为全量接口(不分页),不做触底加载。
### 5.3 表单页字段
对齐 Web 弹窗字段(精简交互适配移动端):
| 字段 | 必填 | 说明 |
|------|------|------|
| 上级分类 | 否 | 选择器:树扁平为带缩进/全路径选项;留空或选「顶级分类」→ `parentId=0`;新增子分类时预填且可改 |
| 分类名称 | 是 | |
| 排序号 | 否 | 数字,默认 0 |
| 状态 | 是 | 正常 `0` / 停用 `1`,默认 `0`(与 Web 表单默认一致) |
| 备注 | 否 | |
编辑时禁止把节点设为自己或自己的子孙为上级(前端用当前树校验;后端若已有校验则透传错误 Toast)。
提交成功后返回列表并刷新。
## 6. 数据与 API
在 `miniprogram/api/crm.js` 增加(与 Web 同路径):
| 方法 | 路径 | 说明 |
|------|------|------|
| `listProductCategoryTree` | `POST /web/crm/product-categories/tree` | body: `{ categoryName?, status? }` → 嵌套 `children` |
| `addProductCategory` | `POST /web/crm/product-categories/add` | |
| `updateProductCategory` | `POST /web/crm/product-categories/update` | |
| `deleteProductCategory` | `POST /web/crm/product-categories/delete` | `{ id }` |
列表页直接消费树结构;表单上级选择器可对同一 tree 做扁平遍历(展示全路径,分隔符 ` / `)。
删除权限:若接口返回创建人限制类错误,Toast 展示后端文案(与 Web `canDeleteByCreator` 语义一致,小程序侧不做复杂权限 UI,依赖接口)。
## 7. 接入改动清单
1. `pages/crm/product-category/list.vue`、`form.vue`(新建)
2. `pages.json` 注册两页
3. `config/api.js`:`PAGE_PATHS` + `WORKBENCH_ROUTE_MAP`
4. `config/workbench-menus.js`:产品分类 `enabled: true`,补 `code`
5. `api/crm.js`:四个分类接口
6. 样式:优先复用 `mp-*` 全局类;树行专用样式可写在 list 页 scoped(Token 用三墙绿,勿用 Web `#10b981`)
7. Demo:保留 `mobile-ui/shanxia-mp-crm-product-category-demo.html` 作为视觉权威;实现后可把方案切换条标注「已采用 A」
## 8. 错误与空态
- 加载失败:Toast + 空列表
- 树为空:空态文案「暂无产品分类」+ 引导新增
- 表单校验失败:字段级 Toast(名称必填)
- 删除确认取消:无副作用
## 9. 验收标准
1. 工作台「产品分类」可点进列表,不再 Toast「本期暂未开放」。
2. 树层级、展开折叠、搜索、状态筛选与 Web 数据一致(同租户同账号)。
3. 可完成:新增顶级 → 新增子分类 → 编辑 → 删除(有子节点时以后端规则为准,失败有提示)。
4. 视觉与 Demo 方案 A 一致:绿渐变头、缩进树、状态 Tag、底部/Sheet 操作。
## 10. 测试建议
- 手工:三级树展开/折叠、搜索命中后祖先仍可见(后端 tree 已带祖先)、停用筛选、表单上级选择、删除确认。
- 若维护 `miniprogram-e2e` 按钮清单:为本页补 INV 行(列表头按钮、行内 +/⋯、Sheet 三项、删除 Modal、表单提交)。