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

91 lines
5.3 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-分仓管理工具完善与优化
## 一、技术选型
| 项 | 选型 | 依据 |
|---|---|---|
| 技术栈 | 沿用迭代 01Node/TS 服务端 + React 客户端) | 技术约束-001/003 |
| 服务端 API | webServer 自开路由 /odl/api/***不 intercept /api** | 技术约束-004 |
| 客户端 bundle | CJS + window.__ModuleLoader__.load 包装 | 技术约束-005 |
| slots.register | component 为第二参数;settings 用 schemastery z.object() | 技术约束-006 |
| 插件安装 | dsh plugin add(自动 reconcile bundles | 技术约束-007 |
| 本地存储 | allocations.json~/.dsh/one-divine-lot/ | 沿用迭代 01 |
## 二、改造点设计
### O2 策略 tab 动态化
**现状**src/client/index.js 写死注册 3 个 tab(全部持仓 + 2 策略)。
**改造**
- 客户端新增「拉取策略配置」逻辑:启动/进入时 fetch /odl/api/strategies,取 visible=true 的策略;
- 按策略列表动态注册 conversation.view tabsid = odl-strategy-<slug>label = 策略名);
- 全部持仓 tab 固定保留(数据源 tab,始终显示);
- 隐藏策略的 tab 不注册/移除;
- 策略变更(设置页保存)→ 顶部轻提示「策略已变更,请手动刷新」+ 提供刷新按钮触发重新拉取注册。
### O3 设置界面完善(策略 CRUD)
**现状**SettingsSection.jsx 只有显示/隐藏开关。
**改造**
- 新增策略:输入名称 → 服务端生成英文 id(slug 化,如「长线持有」→ long-term-hold)→ 追加到列表末尾;
- 重命名:改 name(id 不变,分配数据不受影响);
- 删除:弹窗确认(提示「该策略下 N 股将回到未分配」)→ 删除策略 + 其份额回未分配(服务端原子操作);
- 排序:上移/下移按钮调整 order;
- 预置策略(网格超市/手动做T)与其他策略一视同仁,可删可改;
- 保留显示/隐藏开关。
- 服务端:strategies/update 现有端点承载 CRUD;新增删除时份额回未分配的联动逻辑(删除策略 → storage 中该 strategyId 的分配清除,回到未分配)。
### O5 数据加载失败兜底
**现状**:tab 加载失败仅显示「加载失败」文字。
**改造**
- 统一「加载状态组件」:loading / error(含原因)/ success 三态;
- error 态显示:失败原因(HTTP 错误 / 超时 / 网络异常)+ 「重试」按钮;
- 自动重试 2 次(间隔 2s),仍失败进入 error 态(手动重试);
- 超时:沿用 15s 可配置(qmtTimeoutMs),超时报「数据源超时」;
- **不引入全局数据源状态监控**(O5 本质是页面加载兜底,非状态栏)。
### O6 份额编辑体验
**现状**StrategyTab 添加/移出需逐票输入。
**改造**
- 「全部移入」(单票):策略 tab 表格行内按钮,把该票全部未分配份额移入当前策略(一次 add-shares 调用,shares = 未分配数);
- 「一键清零」(策略级):策略 tab 顶部按钮,弹窗确认后把该策略下所有份额移出(循环 remove 或新增批量端点);
- 保留 step=100 步进 + 手动输入任意值;
- 操作反馈:统一轻提示组件(成功绿/失败红,3s 自动消失)。
## 三、服务端 API 变更
| 端点 | 变更 |
|---|---|
| /odl/api/strategies | 不变(列表) |
| /odl/api/strategies/update | 承载 CRUD;删除时联动清空该策略份额(回未分配) |
| /odl/api/add-shares | 不变(O6 全部移入复用,shares=未分配数) |
| /odl/api/remove-shares | 不变 |
| /odl/api/remove-all-shares(新增) | 一键清零:{ strategyId } → 清空该策略全部份额 |
## 四、客户端组件变更
| 组件 | 变更 |
|---|---|
| src/client/index.js | 动态注册策略 tabs(从 /strategies 拉取) |
| src/client/views/SettingsSection.jsx | 补全 CRUD UI(新增/重命名/删除/排序)+ 删除确认弹窗 |
| src/client/views/StrategyTab.jsx | 全部移入按钮、一键清零按钮(确认)、轻提示反馈 |
| src/client/views/AllPositionsTab.jsx | 加载失败兜底(错误提示 + 重试) |
| src/client/views/connection.jsx | 统一 API 调用错误处理(错误码/原因透出) |
## 五、实现步骤
1. 服务端:strategies/update 删除联动(份额回未分配)+ remove-all-shares 端点;
2. 客户端:加载状态组件 + 轻提示组件;
3. 客户端:SettingsSection CRUD 补全 + 删除确认弹窗;
4. 客户端:tab 动态注册(策略配置驱动 + 变更提示刷新);
5. 客户端:StrategyTab 全部移入 / 一键清零;
6. 构建(tsdown + wrap+ 安装(dsh plugin add);
7. 验收测试。
## 六、涉及设计约束
- 产品约束-004(删除策略份额回未分配 + 弹窗确认,R-003 新增)
- 产品约束-002/003、技术约束-001/003~007
## 七、风险与开放项
1. 动态注册 tabs:重复注册/注销策略 tab 的精确 APIslots.unregister 或重挂载)需在实现时确认;
2. 策略变更提示「手动刷新」的触发范围(当前会话内即时提示?跨会话?)—— 按 O2-3 决策:设置保存后提示手动刷新;
3. 一键清零大批量份额的原子性(删除策略 vs 份额操作并发);
4. 删除策略的份额回未分配是否涉及「未分配」展示(未分配 tab 已有,删除后份额自然出现在未分配)。