docs(plans): 六项前端体验优化实现计划双产物入库并登记索引
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -81,6 +81,7 @@
|
||||
<li><a href="plans/mobile-screens-implementation.html">移动端全屏落地实现计划(m-* 原型 → Flutter,2026-07-04 已执行)</a><span class="tag html">HTML</span> <span class="hint">— 底部 tab + 我的 hub + sheet 交互范式;Stage0 基建 + 4 并行工作包 + 合流验收全记录</span></li>
|
||||
<li><a href="plans/security-hardening.html">安全三件套实现计划(2026-07-05)</a><span class="tag html">HTML</span> <span class="hint">— 限流/登录锁外置 Redis + 公开接口反爬(日配额/UA/防盗链)+ 边缘加固(nginx limit_conn/安全组/DDoS runbook)</span></li>
|
||||
<li><a href="plans/pay-v2-integration.html">授权续费对接 pay v2 改造计划(2026-07-10,已完成)</a><span class="tag html">HTML</span> <span class="hint">— v1→v2 契约升级(金额 int64 分/session 多态/webhook 事件模型)+ 授权管理独立屏三 tab(订单管理);本地提交态,等用户验收部署;执行真相源 plans/2026-07-10-pay-v2-integration.md</span></li>
|
||||
<li><a href="plans/six-frontend-tweaks.html">六项前端体验优化实现计划(2026-07-14,已完成待验收)</a><span class="tag html">HTML</span> <span class="hint">— 库存抽屉供应商/批次·生产日期换位/出入库抽屉双行列/状态多选默认草稿+待审核/默认仓库填充/财务往来筛选+统一时间;后端零改动,design-first;执行真相源 plans/2026-07-14-six-frontend-tweaks.md</span></li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1,162 @@
|
||||
# 六项前端体验优化 实现计划
|
||||
|
||||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||
|
||||
**Goal:** 一次性落地 6 个前端小需求:①库存抽屉加供应商 ②库存桌面列批次号/生产日期换位 ③出入库单详情抽屉加「生产日期+批次号」双行列(两端)④出入库列表状态筛选多选+默认草稿/待审核 ⑤新建单默认填充默认仓库 ⑥财务加往来单位筛选+自定义时间换统一组件。
|
||||
|
||||
**Architecture:** 全部为前端(Flutter client/)+ 设计原型(design/prototype/)改动,**后端零改动**(调研已核实:供应商/批次/生产日期数据链路已通、status 已支持逗号多值、partner_id 过滤已存在、warehouses.is_default 全链路齐备)。按 design-first 铁律:每个任务先改原型、再改真实代码、**原型与代码同一提交**。
|
||||
|
||||
**Tech Stack:** Flutter/Riverpod + 原型 HTML/JS(tokens/atoms 单源);验收闸 check-ds / check_ds_code / check-l1-sync / fidelity / golden。
|
||||
|
||||
## Global Constraints
|
||||
|
||||
- **design-first 铁律(用户 2026-07-14 重申)**:涉及页面的改动必须先改 `design/prototype/` 原型再开发,原型与代码同一提交;改到的屏必须保持 CONTRACT「同步」态。
|
||||
- 颜色/间距一律走 token(`context.tokens`),禁硬编码 hex;新原子先登记原型 `index.html`。
|
||||
- 弹窗/抽屉宽度改动属 L1 层(`atoms.css`),须原型与 Flutter 常量同提交(过 `tools/check-l1-sync.mjs`)。
|
||||
- 多租户/权限口径不变:出库成本/利润仅管理员可见的逻辑不受本次改动影响(新增列均为非成本字段)。
|
||||
- DoD:`flutter analyze --no-fatal-infos --no-fatal-warnings` 零 error、`flutter test` 全绿、`node client/tool/check_ds_code.mjs`、`node tools/check-l1-sync.mjs` 过闸、涉及屏 fidelity ≤ 8%;**不发版、不打 tag、不部署**,完成后停在本地提交态等用户验收。
|
||||
- 提交规范:每个需求一个提交,`feat(client): ...`,原型改动包含在同一提交内。
|
||||
|
||||
## 已定决策(评审时可推翻)
|
||||
|
||||
- **D1 供应商行两端同显**:库存商品抽屉两端共用 `product_editor_drawer.dart` 的 `_infoBody`,加一行两端同时生效、成本为零;桌面端抽屉当前也没有供应商(表格有),一并补齐更一致。行位置:紧跟「生产日期」行之后。
|
||||
- **D2 库存抽屉顺手补「批次号」行(推荐做)**:与需求③口径一致(出入库抽屉都有生产日期+批次号,库存抽屉只有生产日期不对称);`Inventory.batchNo` 数据已有,走与供应商相同的入参传递。若你只要最小改动(仅供应商),评审时说一声即去掉。
|
||||
- **D3 状态筛选「重置」回默认**:重置按钮把状态恢复为默认 `draft,pending`(与进入页面初始态一致),不是回「全部」。
|
||||
- **D4 退单伪状态与多选互斥**:`ret:partial`/`ret:full` 保持与主状态互斥——选退单态清空状态多选,选任一主状态清退单态(沿用现语义,最小改动)。
|
||||
- **D5 移动端 KPI 卡片点击 = 覆盖为单值**:点「待审核」卡即只看待审核(覆盖当前多选集合),保持现有心智。
|
||||
- **D6 移动端财务往来单位筛选形态**:在时间 chips 行尾追加「往来单位」chip,点开 `showMSheet` 底部可搜索单选列表(与桌面 `ComboSearchField` 对应);再点 × 清除。
|
||||
- **D7 出库抽屉加宽 600→660**:出库管理员形态 7→8 列太紧,`atoms.css` `.drawer.wide` 600→660px 与 Flutter `order_detail_drawer.dart:44` 常量同提交;入库 5→6 列余量够,只微调列宽不加宽。
|
||||
|
||||
## 执行分组(多 agent 调度)
|
||||
|
||||
| 波次 | 组 | 任务 | 关键文件域 | 并行性 |
|
||||
|------|----|------|-----------|--------|
|
||||
| 1 | A 库存域 | Task 1 + Task 2 | product_editor_drawer / inventory_list_screen / inventory.html / product-editor.js / m-inventory.html | 与 B、D 并行 |
|
||||
| 1 | B 出入库抽屉 | Task 3 | order_detail_drawer / 两 list_screen(传参处)/ atoms.css / stock-*-list.html ×4 | 与 A、D 并行 |
|
||||
| 1 | D 财务域 | Task 6 | finance_screen / finance_provider / finance.html / m-finance.html | 与 A、B 并行 |
|
||||
| 2 | C 出入库筛选+表单 | Task 4 + Task 5 | 两 provider / 两 list_screen / 两 form_screen / stock-*-list.html ×4 / stock-in.js | **必须等 B 完成**(同文件) |
|
||||
| 3 | 收尾 | Task 7 | CONTRACT.md / fidelity / golden / 手册核查 | 最后 |
|
||||
|
||||
---
|
||||
|
||||
### Task 1: 库存商品抽屉加「供应商」行(+D2 批次号行)【两端】
|
||||
|
||||
**Files:**
|
||||
- Modify: `design/prototype/screens/product-editor.js:60-75`(`infoRows()`)
|
||||
- Modify: `design/prototype/screens/m-inventory.html:98`(详情 sheet 行序)
|
||||
- Modify: `client/lib/widgets/product_editor_drawer.dart`(入参 + `_infoBody` 385-471)
|
||||
- Modify: `client/lib/screens/inventory/inventory_list_screen.dart:123`(`_openEditor` 传参)
|
||||
|
||||
**Interfaces:**
|
||||
- Produces: `showProductEditorDrawer(..., String? supplier, String? batchNo)` 两个新可空入参;不传即不显示(条件行机制),其它调用方(products_screen.dart 等)零改动。
|
||||
|
||||
- [x] **Step 1(原型先行)**: `product-editor.js` `infoRows()` 在「生产日期」行后加「批次号」「供应商」两行(假数据示例 `B20260701` / `XX贸易`);`m-inventory.html` 详情 sheet 同步行序。本地 5180 预览确认。
|
||||
- [x] **Step 2(代码)**: `product_editor_drawer.dart` 的 `showProductEditorDrawer` 加 `String? supplier, String? batchNo` 入参并透传;`_infoBody` 在生产日期行后按非空条件渲染「批次号」「供应商」两行(样式照抄现有 info 行)。
|
||||
- [x] **Step 3(接线)**: `inventory_list_screen.dart` `_openEditor` 传 `supplier: item.supplierName, batchNo: item.batchNo`。
|
||||
- [x] **Step 4(验证)**: `cd client && flutter analyze --no-fatal-infos --no-fatal-warnings && flutter test`;若库存屏 golden 覆盖抽屉则 regen。
|
||||
- [x] **Step 5(提交)**: `feat(client): 库存商品抽屉增加供应商与批次号信息行(两端,原型同步)`
|
||||
|
||||
### Task 2: 库存桌面表格「批次号」「生产日期」列换位【仅桌面】
|
||||
|
||||
**Files:**
|
||||
- Modify: `design/prototype/screens/inventory.html:128`(`COLS` 数组对调)
|
||||
- Modify: `client/lib/screens/inventory/inventory_list_screen.dart:58-73`(`_colDefs` 对调)
|
||||
|
||||
前提核实(调研已确认):移动端卡片无批次号字段,不涉及;列偏好/排序白名单均按 key 存,换位只动数组顺序不动 key,用户已存配置不受影响。
|
||||
|
||||
- [x] **Step 1(原型先行)**: `inventory.html` `COLS` 中 batch 与 prodDate 位置对调,5180 预览确认。
|
||||
- [x] **Step 2(代码)**: `_colDefs` 同步对调两项顺序(连同对应 cell 构建顺序)。
|
||||
- [x] **Step 3(验证)**: `flutter analyze && flutter test`;库存列表 golden 如有列序断言则 regen。
|
||||
- [x] **Step 4(提交)**: `feat(client): 库存列表批次号与生产日期列位对调(原型同步)`
|
||||
|
||||
### Task 3: 出入库单详情抽屉明细加「生产日期+批次号」双行列【两端】
|
||||
|
||||
**Files:**
|
||||
- Modify: `design/prototype/screens/stock-in-list.html:311-312`(明细 grid + 假数据 lines 补 `pdate`/`batch`)
|
||||
- Modify: `design/prototype/screens/stock-out-list.html:306-308`(`GRID` 常量 + 假数据)
|
||||
- Modify: `design/prototype/screens/m-stock-in-list.html:145-149`、`m-stock-out-list.html`(`openOrder` lineRows 插入「生产日期/批次号」双行列)
|
||||
- Modify: `design/prototype/atoms.css:218-220`(`.drawer.wide` 600→660,D7)
|
||||
- Modify: `client/lib/widgets/order_detail_drawer.dart`(`OrderLine`:67-92 加字段;`_LinesTable`:418-618 加列;`_mLineRow`:331-367 插双行列;:44 宽度 660)
|
||||
- Modify: `client/lib/screens/stock_in/stock_in_list_screen.dart:988-999`、`client/lib/screens/stock_out/stock_out_list_screen.dart:1064-1080`(构造 OrderLine 传两字段)
|
||||
- Modify: `client/lib/models/stock_in.dart:63-64`(`StockInItem` 两字段改 `lineOrProduct` 兜底,对齐 stock_out 写法)
|
||||
- Test: `client/test/order_detail_drawer_columns_test.dart`(列结构断言同步更新)
|
||||
|
||||
**Interfaces:**
|
||||
- Produces: `OrderLine(..., String? productionDate, String? batchNo)`;桌面新列单元格样式 = 上行生产日期(fsSm mono)+ 下行批次号(fsXs faint mono),复用「商品·编码」列先例。
|
||||
|
||||
- [x] **Step 1(原型先行)**: 四个原型文件明细区插入「生产日期/批次号」双行列(桌面:入库 grid 插 ~72px 列并把 124→110、88→78;出库 GRID 插列且抽屉用 wide 660)+ 移动 lineRows 在金额左侧同样插入双行列(上=生产日期 fsSm mono,下=批次号 fsXs faint,与桌面同构;用户 2026-07-14 审阅指定);`atoms.css` `.drawer.wide` 600→660。假数据补 pdate/batch。5180 预览两端四屏。
|
||||
- [x] **Step 2(模型兜底)**: `stock_in.dart` `StockInItem.fromJson` 的 production_date/batch_no 改用 `lineOrProduct` 兜底(照 `stock_out.dart:68-69`)。
|
||||
- [x] **Step 3(抽屉代码)**: `OrderLine` 加两字段;`_LinesTable` 入库 5→6 列 / 出库 7→8 列,新列插在「系列·规格」后,列宽按原型定稿值;`_mLineRow` 在金额区左侧插入双行列(上=生产日期 fsSm mono,下=批次号 fsXs faint;两值都空则不渲染该列,避免空占位);:44 桌面宽度 `min(660, 94%)`。
|
||||
- [x] **Step 4(接线)**: 两个 list_screen 构造 OrderLine 时传 `productionDate: it.productionDate, batchNo: it.batchNo`(显示截 `substring(0,10)`)。
|
||||
- [x] **Step 5(测试)**: 更新 `order_detail_drawer_columns_test.dart` 列数/列头断言;`flutter analyze && flutter test`;涉及 golden(stock_{in,out}_list*)若开抽屉则 regen。
|
||||
- [x] **Step 6(L1 闸)**: `node tools/check-l1-sync.mjs` 过闸(atoms.css 与 Flutter 常量同源)。
|
||||
- [x] **Step 7(提交)**: `feat(client): 出入库单详情抽屉明细增加生产日期+批次号列(两端,抽屉加宽 660,原型同步)`
|
||||
|
||||
### Task 4: 出入库列表状态筛选多选 + 默认「草稿+待审核」【两端】
|
||||
|
||||
**Files:**
|
||||
- Modify: `design/prototype/screens/stock-in-list.html:67`、`stock-out-list.html`(chipStatus 单选→多选,默认态 draft+pending,摘要「值/N 项」,参照 inventory.html:69,138-139 既有多选形态)
|
||||
- Modify: `design/prototype/screens/m-stock-in-list.html:101-102`、`m-stock-out-list.html`(状态 sheet 单选→多选勾选)
|
||||
- Modify: `client/lib/providers/stock_in_provider.dart:41`、`stock_out_provider.dart:41`(默认 `_status = 'draft,pending'`)
|
||||
- Modify: `client/lib/screens/stock_in/stock_in_list_screen.dart`(:86-113 归一逻辑重写;:773-790 桌面 chip 改 `showDsMultiMenu`;:678-724 移动 sheet 改多选;:621-630 KPI 点击、`_resetFilters`)
|
||||
- Modify: `client/lib/screens/stock_out/stock_out_list_screen.dart`(:100-128 归一、`_MenuChip` 调用点 ~813、:1973-2020、KPI :548-560/:650-659 同构改法)
|
||||
|
||||
**Interfaces:**
|
||||
- Consumes: 后端 `status IN (逗号分隔)` 已支持(stock_in.go:44-45 / stock_out.go:55-56),零改动。
|
||||
- Produces: 屏内状态 = `Set<String>`,落 provider 时 `join(',')`;空集 = 全部。
|
||||
|
||||
关键陷阱(调研确认):两屏 `initState` 有「归零残留多值」逻辑,会把 `'pending,draft'` 重置为 `''`——必须重写为「按逗号拆分后逐值校验合法性,非法才归默认」,否则默认值刚设就被清掉。
|
||||
|
||||
- [x] **Step 1(原型先行)**: 四个原型文件状态筛选改多选(复用 inventory 屏 chip 摘要形态 / m 端 sheet 勾选形态),默认选中 草稿+待审核。5180 预览。
|
||||
- [x] **Step 2(provider)**: 两个 provider 默认值改 `'draft,pending'`。
|
||||
- [x] **Step 3(归一重写)**: 两屏 initState 残留清洗逻辑改为逐值校验(合法集 = draft/pending/approved/rejected),并兼容退单伪状态互斥(D4)。
|
||||
- [x] **Step 4(桌面 chip)**: 单选 PopupMenu → `_multiChip` + `showDsMultiMenu`(照 `inventory_list_screen.dart:209-246`、`widgets/ds/ds_menu.dart:51`),摘要:1 项显示值 / 多项「N 项」/ × 清为默认(D3)。
|
||||
- [x] **Step 5(移动 sheet + KPI)**: `_openStatusSheet` 改多选勾选(确定时应用);KPI 卡点击 = 覆盖单值(D5);`_resetFilters` 状态回 `draft,pending`(D3)。
|
||||
- [x] **Step 6(验证)**: `flutter analyze && flutter test`;两屏列表 golden regen(默认筛选态变了,golden 基线会变)。
|
||||
- [x] **Step 7(提交)**: `feat(client): 出入库列表状态筛选改多选并默认草稿+待审核(两端,原型同步)`
|
||||
|
||||
### Task 5: 新建入库/出库单默认填充默认仓库【两端,同一代码路径】
|
||||
|
||||
**Files:**
|
||||
- Modify: `design/prototype/screens/stock-in.js`(`state.doc.warehouse` 新建时默认取默认仓,双模式驱动 in/out 两屏)
|
||||
- Modify: `client/lib/screens/stock_in/stock_in_form_screen.dart`(`_warehouseId`:43,加载仓库后填充)
|
||||
- Modify: `client/lib/screens/stock_out/stock_out_form_screen.dart`(:158 同构)
|
||||
|
||||
**Interfaces:**
|
||||
- Consumes: `Warehouse.isDefault`(client/lib/models/warehouse.dart:5,18,已存在);设置页已可指定默认仓。
|
||||
|
||||
- [x] **Step 1(原型先行)**: `stock-in.js` 新建单时仓库字段预填默认仓(假数据标记一个默认仓)。5180 预览 in/out 两屏。
|
||||
- [x] **Step 2(代码)**: 两张表单新建模式(非编辑回填)在仓库列表加载完成后:`_warehouseId ??= 列表中 isDefault 的仓 ?? (列表仅 1 个仓时取它 : 保持 null)`。编辑模式不受影响(仍从单据回填)。
|
||||
- [x] **Step 3(验证)**: `flutter analyze && flutter test`(两表单已有测试如断言初始空值需同步)。
|
||||
- [x] **Step 4(提交)**: `feat(client): 新建出入库单默认填充默认仓库(两端,原型同步)`
|
||||
|
||||
### Task 6: 财务加「往来单位」筛选 + 自定义时间换统一组件【两端】
|
||||
|
||||
**Files:**
|
||||
- Modify: `design/prototype/screens/finance.html`(:82-86 timerow「自定义」接 `datewheel.js openRange`(照 stock-in-list.html:228 写法);流水表 toolbar 加往来单位下拉)
|
||||
- Modify: `design/prototype/screens/m-finance.html`(回填真实端已有的时间 chips 行【存量漂移】+ 时间行尾加「往来单位」chip→sheet,D6)
|
||||
- Modify: `client/lib/providers/finance_provider.dart:18-88`(加 `_partnerId` + `setPartner()`,照 `setType` 写法约 8 行)
|
||||
- Modify: `client/lib/screens/finance/finance_screen.dart`(:89-103 `_applyRange` 自定义分支 `showDateRangePicker` → `showDateRangeDropdown(anchorCtx, initial:)`,anchor 用「自定义」chip 的 Builder context,照 stock_in `_dateMenu`:247-270;:532-557 `_flowTable` toolbar 加 `ComboSearchField` 往来单位(照 stock_out_list_screen.dart:783-797);移动分支时间行尾加往来单位 chip→`showMSheet` 可搜单选)
|
||||
|
||||
**Interfaces:**
|
||||
- Consumes: 后端 `/finance/records?partner_id=` 已支持(finance.go:34,51-52);`finance_repository.listRecords` 已有 `partnerId` 参数(:16,28);数据源 `allPartnersProvider`(partner_provider.dart:31);`showDateRangeDropdown`(widgets/wheel_date_picker.dart,组件内部自适应桌面下拉/窄屏 sheet)。
|
||||
|
||||
- [x] **Step 1(原型先行)**: `finance.html` 自定义时间接 datewheel + toolbar 加往来下拉;`m-finance.html` 回填时间行 + 往来单位 chip/sheet。5180 预览两端。
|
||||
- [x] **Step 2(provider)**: `FinanceListNotifier` 加 `_partnerId`/`setPartner()` 并接入 `listRecords`。
|
||||
- [x] **Step 3(统一时间)**: `_applyRange` 自定义分支换 `showDateRangeDropdown`(一处代码两端生效,删除 `showDateRangePicker` 引用)。
|
||||
- [x] **Step 4(桌面往来筛选)**: `_flowTable` toolbar 类型 chips 旁加 `ComboSearchField`(可搜单选,清除回全部)。
|
||||
- [x] **Step 5(移动往来筛选)**: 时间 chips 行尾加「往来单位」chip → 底部 sheet 可搜单选(D6)。
|
||||
- [x] **Step 6(验证)**: `flutter analyze && flutter test`;财务屏 golden regen(toolbar 变了)。
|
||||
- [x] **Step 7(提交)**: `feat(client): 财务筛选增加往来单位并统一自定义时间组件(两端,原型同步)`
|
||||
|
||||
### Task 7: 收尾——CONTRACT 台账回填 + fidelity 体检 + 手册核查
|
||||
|
||||
**Files:**
|
||||
- Modify: `design/CONTRACT.md`(块 4:库存 :100-101、出入库列表 :106-107、财务 :108 各行备注回填本次改动,保持「同步」态)
|
||||
- Check: `web/content/docs.md` / `docs/manual/user-manual.html`(若有「出入库列表默认显示」「财务筛选」相关描述则同步;无则不动)
|
||||
|
||||
- [x] **Step 1**: 跑受影响屏 fidelity:`node tools/fidelity.mjs`(库存、入库列表、出库列表、财务,桌面+移动),超 8% 回改对齐。
|
||||
- [x] **Step 2**: CONTRACT.md 对应行回填改动说明与 fidelity 结果。
|
||||
- [x] **Step 3**: 手册核查:默认筛选行为变化(草稿+待审核)如手册有描述则两侧同步(web/content/docs.md + user-manual.html)。
|
||||
- [x] **Step 4(全量 DoD)**: `flutter analyze && flutter test`、`node client/tool/check_ds_code.mjs`、`node tools/check-l1-sync.mjs` 全绿。
|
||||
- [x] **Step 5(提交)**: `docs(design): 六项前端优化 CONTRACT 台账回填与手册同步`
|
||||
@@ -0,0 +1,92 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>六项前端体验优化 实现计划 — 酒库管理系统</title><style>
|
||||
:root{
|
||||
--primary:#2563AC; --primary-dark:#154072; --danger:#D14343; --danger-bg:#FDECEC;
|
||||
--success:#2E8B57; --success-bg:#E6F3EC; --warn:#B45309; --warn-bg:#FFF4E5; --accent:#8B2331;
|
||||
--ink:#232934; --muted:#6E7888; --border:#DCE2EB; --paper:#F5F7FA; --head:#F0F4FF;
|
||||
}
|
||||
*{box-sizing:border-box;font-family:-apple-system,"PingFang SC","Microsoft YaHei",sans-serif;}
|
||||
body{margin:0;background:var(--paper);color:var(--ink);padding:28px;line-height:1.7;max-width:1000px;}
|
||||
h1{font-size:22px;margin:0 0 4px;}
|
||||
h2{font-size:17px;margin:30px 0 12px;color:var(--primary-dark);border-bottom:2px solid var(--head);padding-bottom:6px;}
|
||||
h3{font-size:14.5px;margin:18px 0 8px;color:var(--primary-dark);}
|
||||
.sub{color:var(--muted);font-size:13px;margin-bottom:18px;}
|
||||
.card{background:#fff;border:1px solid var(--border);border-radius:10px;padding:16px 20px;margin:14px 0;font-size:13.5px;}
|
||||
code{font-family:ui-monospace,Menlo,monospace;font-size:12px;background:#EEF2F8;padding:1px 5px;border-radius:4px;color:var(--primary-dark);}
|
||||
pre{background:#0F1722;color:#D8E1EC;border-radius:8px;padding:12px 14px;overflow-x:auto;font-size:12px;line-height:1.55;}
|
||||
pre code{background:none;color:inherit;padding:0;}
|
||||
ul,ol{margin:6px 0;padding-left:22px;} li{margin:4px 0;font-size:13px;}
|
||||
table{border-collapse:collapse;width:100%;margin:10px 0;font-size:12.5px;background:#fff;}
|
||||
th,td{border:1px solid var(--border);padding:6px 10px;text-align:left;vertical-align:top;}
|
||||
th{background:var(--head);color:var(--primary-dark);white-space:nowrap;}
|
||||
.tag{display:inline-block;font-size:11px;padding:1px 8px;border-radius:10px;margin-right:6px;font-weight:600;}
|
||||
.tag.keep{background:var(--success-bg);color:var(--success);}
|
||||
.tag.change{background:var(--warn-bg);color:var(--warn);}
|
||||
.tag.risk{background:var(--danger-bg);color:var(--danger);}
|
||||
.chk{color:var(--success);font-weight:700;margin-right:4px;}
|
||||
.hl{background:var(--warn-bg);padding:0 3px;border-radius:3px;}
|
||||
.wrap{overflow-x:auto;}
|
||||
</style></head><body>
|
||||
<h1>六项前端体验优化 实现计划</h1>
|
||||
<div class="sub">2026-07-14 · 状态:<b>7 任务全部完成</b>(本地提交态,DoD 全绿 + fidelity 最差 4.724%≤阈,等用户验收;不发版不部署)· 执行真相源 = <code>docs/plans/2026-07-14-six-frontend-tweaks.md</code>(checkbox),本页为阅读版 · 每任务经独立审查(T3 修掉生产日期空串崩溃 Critical;T4/T5/T6 补 19 个回归用例)</div>
|
||||
|
||||
<h2>结论先行</h2><div class="card">
|
||||
<p style="margin:4px 0"><b>六个需求全部「后端零改动」</b>,均为 Flutter 前端 + 设计原型改动。按 design-first 铁律:每个任务<span class="hl">先改原型 → 再改真实代码 → 同一提交落地</span>,改到的屏保持 CONTRACT「同步」态,完成后跑 fidelity / check-ds / check-l1-sync / golden 全闸。</p>
|
||||
<ul>
|
||||
<li><span class="tag keep">数据已通</span>①供应商:后端库存 List 已返回 <code>supplier_name</code>、前端模型已解析;③生产日期/批次号:出入库明细快照列已有且接口已返回,写入有保障(入库空批次自动生成、出库空值从 product 回填)</li>
|
||||
<li><span class="tag keep">接口已支持</span>④状态多选:List 接口本就 <code>status IN (逗号拆分)</code>;⑥往来单位:<code>/finance/records?partner_id=</code> 过滤已存在,repository 已有参数</li>
|
||||
<li><span class="tag keep">概念已存在</span>⑤默认仓库:<code>warehouses.is_default</code> schema/后端/客户端模型/设置页选择 UI 全链路齐备,只差新建表单一行填充</li>
|
||||
</ul></div>
|
||||
|
||||
<h2>需求 → 改法一览(两端分列)</h2><div class="wrap">
|
||||
<table>
|
||||
<tr><th>#</th><th>需求</th><th>桌面端</th><th>移动端</th><th>后端</th></tr>
|
||||
<tr><td>1</td><td>库存抽屉加供应商</td><td colspan="2"><b>两端共用同一抽屉组件</b>(<code>product_editor_drawer.dart</code> 的 <code>_infoBody</code>,桌面=右滑抽屉 / 移动=底部 sheet),加一行两端同时生效;由库存列表调用点传 <code>item.supplierName</code>,其它调用方不传即不显示</td><td>零</td></tr>
|
||||
<tr><td>2</td><td>批次号↔生产日期换位</td><td><code>inventory.html COLS</code> + <code>_colDefs</code> 对调(批次号第4列 ↔ 生产日期第8列);列偏好按 key 存,用户配置不受影响</td><td>移动端无批次号字段,<b>不涉及</b></td><td>零</td></tr>
|
||||
<tr><td>3</td><td>出入库单抽屉加「生产日期+批次号」</td><td>明细表插双行列(上=生产日期 fsSm mono,下=批次号 fsXs 小字,照抄「商品·编码」列先例):入库 5→6 列微调列宽不加宽;出库管理员 7→8 列太紧,<span class="tag change">抽屉 600→660px</span>(L1 <code>atoms.css .drawer.wide</code> 与 Flutter 常量同提交)</td><td>明细行金额左侧同样插入<b>双行列</b>(上=生产日期,下=批次号小字,与桌面同构;两值皆空不渲染)</td><td>零</td></tr>
|
||||
<tr><td>4</td><td>状态筛选多选 + 默认草稿+待审核</td><td>状态 chip 单选 PopupMenu → 库存屏已有多选先例 <code>showDsMultiMenu</code>(摘要 值/「N 项」/ × 清)</td><td>状态底部 sheet 单选 → 多选勾选;KPI 卡点击=覆盖单值</td><td>零(已支持逗号多值)</td></tr>
|
||||
<tr><td>5</td><td>新建单默认填默认仓库</td><td colspan="2"><b>两表单共用同一代码路径</b>(OrderFormShell docHead),新建模式仓库列表加载后 <code>??=</code> 默认仓(无默认仓且仅一仓则取它),改一处两端生效;编辑模式不受影响</td><td>零</td></tr>
|
||||
<tr><td>6</td><td>财务加往来单位筛选 + 统一时间组件</td><td>流水表 toolbar 加 <code>ComboSearchField</code>(照出库「客户」筛选),数据源 <code>allPartnersProvider</code></td><td>时间 chips 行尾加「往来单位」chip → 底部 sheet 可搜单选(财务移动屏无 toolbar/详搜结构,此为最轻形态)</td><td>零(partner_id 已支持)</td></tr>
|
||||
<tr><td>6b</td><td>自定义时间统一</td><td colspan="2"><code>showDateRangePicker</code>(Material 原生)→ 入库管理用的 <code>showDateRangeDropdown</code>(桌面=chip 下拉双滚轮 / 窄屏=底部 sheet,<b>组件内部自适应,一处改动两端生效</b>)</td><td>零</td></tr>
|
||||
</table></div>
|
||||
|
||||
<h2>已定决策(评审时可推翻)</h2><div class="card"><ul>
|
||||
<li><b>D1 供应商行两端同显</b>:抽屉组件两端共用、成本为零;桌面抽屉当前也没供应商(表格有),一并补齐更一致。行位:生产日期行之后</li>
|
||||
<li><b>D2 库存抽屉顺手补「批次号」行(推荐做)</b>:与需求③口径对称(出入库抽屉都有、库存抽屉只有生产日期),数据已有零成本。<span class="tag risk">待确认</span>只要最小改动就去掉</li>
|
||||
<li><b>D3 状态筛选「重置」回默认</b> <code>draft,pending</code>(与进页初始一致),不是回「全部」</li>
|
||||
<li><b>D4 退单伪状态(ret:*)与主状态多选保持互斥</b>:选退单清多选、选主状态清退单(沿用现语义)</li>
|
||||
<li><b>D5 移动 KPI 卡点击 = 覆盖为单值</b>(点「待审核」即只看待审核,保持现有心智)</li>
|
||||
<li><b>D6 移动财务往来单位形态</b>:时间行尾 chip → 底部可搜索单选 sheet,× 清除</li>
|
||||
<li><b>D7 出库抽屉加宽 600→660px</b>:8 列所需;入库 6 列余量够不加宽</li>
|
||||
</ul></div>
|
||||
|
||||
<h2>任务分解与多 agent 调度(7 任务,每任务原型+代码同提交)</h2>
|
||||
<div class="card"><ul>
|
||||
<li><span class="chk">T1</span><b>库存抽屉供应商(+批次号)行</b> — 原型 product-editor.js / m-inventory.html → 抽屉加入参+条件行 → 列表传参</li>
|
||||
<li><span class="chk">T2</span><b>库存桌面列换位</b> — inventory.html COLS + _colDefs 对调</li>
|
||||
<li><span class="chk">T3</span><b>出入库抽屉双行列</b> — 4 原型 + atoms.css 660 → OrderLine 加字段 + 桌面/移动都插双行列 + 两屏传参 + stock_in 模型 lineOrProduct 兜底 + 列结构专测更新</li>
|
||||
<li><span class="chk">T4</span><b>状态多选+默认值</b> — 4 原型 → provider 默认 <code>draft,pending</code> + <span class="hl">重写 initState「归零残留多值」陷阱逻辑</span> + 桌面 showDsMultiMenu + 移动 sheet 多选 + KPI/重置语义</li>
|
||||
<li><span class="chk">T5</span><b>默认仓库填充</b> — stock-in.js 原型 → 两表单新建时 ??= 默认仓</li>
|
||||
<li><span class="chk">T6</span><b>财务往来筛选+统一时间</b> — finance.html 接 datewheel + m-finance.html 回填时间行(<span class="tag change">顺带修存量漂移</span>:真实端有时间行、移动原型没有)→ provider 加 setPartner → ComboSearchField / chip+sheet / showDateRangeDropdown</li>
|
||||
<li><span class="chk">T7</span><b>收尾</b> — CONTRACT 台账回填 + fidelity 体检(库存/出入库/财务 双端)+ 手册核查(默认筛选行为变化)</li>
|
||||
</ul>
|
||||
<div class="wrap"><table>
|
||||
<tr><th>波次</th><th>并行组</th><th>任务</th><th>说明</th></tr>
|
||||
<tr><td>1</td><td>A 库存域 ∥ B 出入库抽屉 ∥ D 财务域</td><td>T1+T2 ∥ T3 ∥ T6</td><td>三组文件域无交集,并行执行</td></tr>
|
||||
<tr><td>2</td><td>C 出入库筛选+表单</td><td>T4+T5</td><td>与 B 同文件(两 list_screen / 4 原型),<b>必须等 B 完成</b></td></tr>
|
||||
<tr><td>3</td><td>收尾</td><td>T7</td><td>全部完成后统一体检回填</td></tr>
|
||||
</table></div></div>
|
||||
|
||||
<h2>红线与 DoD</h2><div class="card"><ul>
|
||||
<li><b>design-first 铁律</b>:每任务先改原型(5180 可随时预览)再落码,原型与代码同一提交;颜色走 token 禁硬编码</li>
|
||||
<li>后端零改动 · 零写真实库 · <b>不部署不发版不打 tag</b>,完成停在本地提交态等验收</li>
|
||||
<li>DoD:<code>flutter analyze/test</code> 全绿 + <code>check_ds_code.mjs</code> + <code>check-l1-sync.mjs</code> 过闸 + 受影响屏 fidelity ≤8% + golden regen + CONTRACT 保持「同步」态</li>
|
||||
</ul></div>
|
||||
|
||||
<h2>批准后落地流程</h2><div class="card"><ol>
|
||||
<li>todo 登记(全局 todo skill)并标 doing</li>
|
||||
<li>按波次多 agent 派发执行(波1 三组并行 → 波2 → 收尾),每任务一提交</li>
|
||||
<li>完成后本地起服务给你实测验收(5180 原型 + dev.sh run 真实端)</li>
|
||||
</ol></div>
|
||||
</body></html>
|
||||
Reference in New Issue
Block a user