Files
2026-08-29 16:20:33 +08:00

126 lines
7.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 迭代 02 实施步骤规划(分步执行)
> 2026-08-28 | 按步骤分批推进,每步有独立产出与验证点
> 关联:技术实现方案.md、程序结构设计.md(02)、R-003(已定稿)
## 总览
| 步骤 | 内容 | 产出 | 验证点 | 依赖 |
|---|---|---|---|---|
| S1 | 服务端:策略 CRUD 逻辑(settings.js | id 生成/增删改排序 + 删除联动 | 单元验证:slug 生成、CRUD、删除清份额 | - |
| S2 | 服务端:存储清份额(storage.js | removeStrategyShares/clearStrategy | 清空后 allocations.json 正确 | S1 |
| S3 | 服务端:分仓快捷逻辑(manager.js) | 全部移入/清空策略份额 | 单元验证:未分配全部移入、清零 | S2 |
| S4 | 服务端:API 新端点(api.js | strategies/add、remove、move、remove-all-shares | 端点调用正确 + 错误码 | S1-S3 |
| S5 | 客户端:基础组件(LoadState/Toast | 三态加载 + 轻提示 | 组件渲染正确 | - |
| S6 | 客户端:SettingsSection CRUD | 新增/重命名/删除(确认)/排序/显隐 UI | UI 操作正确 + 服务端联动 | S4+S5 |
| S7 | 客户端:tab 动态注册(index.js) | 策略配置驱动 tabs + 手动刷新提示 | tab 随设置变化 + 提示出现 | S4+S5 |
| S8 | 客户端:StrategyTab 快捷操作 | 全部移入/一键清零 | 操作正确 + 确认弹窗 + Toast | S4+S5 |
| S9 | 构建 + 安装 + 联调验收 | 全链路 | 对照验收标准.md | S1-S8 |
## 分步细节
### S1:服务端策略 CRUDsettings.js
- `generateStrategyId(name)`:slug 化(去空格/转小写/非英文转拼音或序号兜底)
- `addStrategy / renameStrategy / removeStrategy / moveStrategy`
- removeStrategy 联动:删除策略 + 调 storage.removeStrategyShares
- **验证**Node 直接调用,验证 slug 生成、CRUD 后 settings 值正确、删除后份额清空
### S2:服务端存储清份额(storage.js)
- `removeStrategyShares(strategyId)`:遍历 allocations,删除该 strategyId,原子保存
- `clearStrategy(strategyId)`:同 removeStrategyShares(供一键清零复用)
- **验证**:构造数据 → 清空 → 文件正确
### S3:服务端分仓快捷逻辑(manager.js)
- `moveAllUnallocatedToStrategy(code, strategyId)`:未分配 = volume - 已分配,全部 add
- `clearStrategyShares(strategyId)`:清空该策略全部份额,返回影响的标的列表
- **验证**:真实/模拟持仓数据,全部移入后未分配归零、清零后份额归零
### S4:服务端 API 新端点(api.js
- `strategies/add`{ name } → 新增策略
- `strategies/remove`{ strategyId } → 删除 + 清份额
- `strategies/move`{ strategyId, dir } → 排序
- `remove-all-shares`{ strategyId } → 一键清零
- 全部移入复用 add-shares(服务端算未分配 or 客户端传)
- **验证**HTTP 调用各端点,200 + 正确返回;错误码(strategy-not-found 等)
### S5:客户端基础组件(LoadState.jsx / Toast.jsx
- LoadStateloading / error(原因+重试) / success 三态;自动重试 2 次(间隔 2s)
- Toastsuccess(绿) / error(红)3s 自动消失
- **验证**:组件在 tab 中渲染正确(可临时构造 error 态验证)
### S6:客户端 SettingsSection CRUDO3
- 新增:名称输入 + 按钮 → strategies/add
- 重命名:行内编辑 → strategies/update
- 删除:确认弹窗(提示份额回未分配)→ strategies/remove
- 排序:上移/下移 → strategies/move
- 显隐开关保留
- 操作后 Toast 反馈 + 触发「策略已变更」事件(供 S7)
- **验证**:完整 CRUD 操作路径
### S7:客户端 tab 动态注册(O2)
- index.jsloadStrategies() → 动态注册策略 tabsvisible=true
- 全部持仓 tab 固定
- 提示「刷新页面后生效」(方案 X);优化项:会话切换自动重拉(方案 Y)
- **验证**:增删/隐藏策略后刷新,tab 栏正确变化
### S8:客户端 StrategyTab 快捷操作(O6
- 行内「全部移入」→ add-sharesshares=未分配)
- 顶部「一键清零」→ 确认弹窗 → remove-all-shares
- Toast 反馈 + reload
- **验证**:操作后份额正确、未分配正确变化
### S9:构建 + 安装 + 联调验收
- pnpm buildtsdown + wrap-client.mjs
- dsh plugin add 更新安装
- 对照验收标准.md 全链路验收(含断 QMT 验证 O5、CRUD 验证 O3、tab 验证 O2、快捷操作验证 O6)
## 建议执行批次
- **批次 1(S1-S3)**:服务端核心逻辑(策略 CRUD + 清份额 + 快捷分仓)—— 纯服务端可独立验证
- **批次 2(S4)**:服务端 API 端点 —— 打通 HTTP 通道
- **批次 3(S5-S6)**:客户端基础组件 + 设置 CRUD UI
- **批次 4S7-S8**:客户端 tab 动态化 + 快捷操作 —— 全链路 UI
- **批次 5(S9)**:构建安装 + 联调验收
## 前置技术确认(编码前)
1. ~~slots.unregister 能力~~**已确认**`ctx.slots.register()` 返回 disposer 函数(SlotCore.register 的 return),可注销 entry;动态 tab 注册/注销可行
2. ~~客户端跨组件事件实现方式~~**已确认**:无事件机制。设置页保存后就地提示「刷新页面后生效」;tab 更新 = 刷新页面 → 插件重载 → 重新注册(方案 X;方案 Y 会话切换自动更新为优化项)
3. settings scope 更新后的 watch 机制(是否需要监听策略变更)
## 执行进度(2026-08-28
### ✅ 批次 1-2(S1-S4)服务端已完成并验证
| 步骤 | 状态 | 验证结果 |
|---|---|---|
| S1 策略 CRUDsettings.js | ✅ 完成 | slug 生成(长线持有→long-term-hold、网格超市→grid-supermarket、去重→-2)、增删改排序单元测试通过 |
| S2 存储清份额(storage.js | ✅ 完成 | removeStrategyShares 清空策略份额正确(受影响标的列表、记录清理) |
| S3 分仓快捷逻辑(manager.js) | ✅ 完成 | 全部移入(未分配 700→1200)、无未分配报错(no-unallocated)、一键清零通过 |
| S4 API 新端点(api.js | ✅ 完成 | strategies/add、remove(联动清份额)、move、move-all-shares、remove-all-shares 全部 HTTP 验证通过 |
### ✅ 批次 3-4(S5-S8)客户端已完成,构建通过
| 步骤 | 状态 | 说明 |
|---|---|---|
| S5 基础组件 | ✅ 完成 | LoadState.jsx(三态+自动重试2次+手动重试)、Toast.jsx(成功绿/失败红,3s |
| S6 SettingsSection CRUD | ✅ 完成 | 新增/重命名/删除(确认弹窗)/排序/显隐 + 就地「刷新后生效」提示 |
| S7 tab 动态注册 | ✅ 完成 | 策略配置驱动注册(slots.register 返回 disposer),全部持仓固定,隐藏策略不注册 |
| S8 StrategyTab 快捷操作 | ✅ 完成 | 全部移入(行内)、一键清零(确认弹窗)、LoadState 兜底 |
### 🔄 S9 构建安装 + 联调验收(进行中)
| 项 | 状态 | 验证结果 |
|---|---|---|
| pnpm build | ✅ 完成 | 客户端 bundle 41KB + 服务端 14 模块,lib 产物集成测试通过 |
| 宿主加载 | ✅ 完成 | 客户端模块清单含 one-divine-lotrev a238b5fa84d1),bundle 为新版本(41KB |
| 服务端 API 真实验证 | ✅ 完成 | 新端点全部可用:add/move/remove(联动清份额)/move-all-shares/remove-all-shares |
| 快捷操作真实验证 | ✅ 完成 | 全部移入(603028.SH 未分配800→manual-t)、一键清零(manual-t 清零)验证通过,数据已恢复 |
| UI 视觉验证 | ⏳ 待老师确认 | 需在浏览器实际查看 tab 动态化、设置 CRUD、快捷操作(当前环境无法自动化浏览器) |
### 待老师确认的 UI 验收项
1. 主窗口 tab 栏:只显示「手动做T」(网格超市 visible=false 不显示)—— O2 动态 tab
2. 设置页「神之一手」:策略 CRUD(新增/重命名/删除弹窗/排序/显隐)+「刷新页面后生效」提示
3. 策略 tab:全部移入(行内)、一键清零(弹窗)、Toast 反馈
4. 加载失败:LoadState 重试(可临时断 QMT 验证)