init
This commit is contained in:
@@ -0,0 +1,181 @@
|
||||
# 程序结构设计:02-分仓管理工具完善与优化
|
||||
|
||||
> 迭代设计 v2 的程序结构细化 | 2026-08-28
|
||||
> 关联:技术实现方案.md(02)、R-003(已定稿)
|
||||
|
||||
## 一、整体目录结构(基于迭代 01 演进)
|
||||
|
||||
```
|
||||
one_divine_lot/
|
||||
├── package.json # 不变(已有 dsh.client 声明)
|
||||
├── src/ # 源码(服务端 + 客户端)
|
||||
│ ├── index.js # 插件入口:apply(ctx),组装各模块(少量调整)
|
||||
│ ├── settings.js # 设置管理:策略 CRUD 逻辑扩展(新增 id 生成、删除联动)
|
||||
│ ├── storage.js # 本地存储:allocations.json(新增:清空策略份额)
|
||||
│ ├── api.js # 服务端 HTTP API(webServer /odl/api/*):新增端点
|
||||
│ ├── data-source/
|
||||
│ │ ├── types.js # 不变
|
||||
│ │ └── qmt-bridge-rest.js # 不变
|
||||
│ ├── position/
|
||||
│ │ └── manager.js # 分仓逻辑:新增全部移入/清空策略份额
|
||||
│ └── client/
|
||||
│ ├── index.js # 客户端入口:tab 动态注册(O2 核心改造)
|
||||
│ └── views/
|
||||
│ ├── AllPositionsTab.jsx # 加载失败兜底(O5)
|
||||
│ ├── StrategyTab.jsx # 全部移入/一键清零(O6)
|
||||
│ ├── SettingsSection.jsx # 策略 CRUD 补全(O3)
|
||||
│ ├── connection.jsx # API 调用错误透出增强(O5)
|
||||
│ ├── LoadState.jsx # 【新增】三态加载组件(O5)
|
||||
│ └── Toast.jsx # 【新增】轻提示组件(O6/O3)
|
||||
└── docs/ # 神之一手框架文档(既有)
|
||||
```
|
||||
|
||||
## 二、模块职责与变更点
|
||||
|
||||
### 1. index.js(插件入口)
|
||||
- 基本不变;新增:把「策略配置读取」能力暴露给 api(已由 settings 提供)
|
||||
- 组装链保持:dataSource → settings → storage → manager → api
|
||||
|
||||
### 2. settings.js(设置管理)—— O3 核心
|
||||
- **现有**:registerSettings / getStrategies / getVisibleStrategies / updateStrategies
|
||||
- **新增**:
|
||||
- `generateStrategyId(name)`:中文/任意名 → 英文 slug(如「长线持有」→ long-term-hold;去空格、转小写、连字符)
|
||||
- `addStrategy(scope, name)`:生成 id + 追加到列表末尾(order = max+1)
|
||||
- `renameStrategy(scope, id, name)`:只改 name(id 不变,分配数据不受影响)
|
||||
- `removeStrategy(scope, id)`:删除策略(**联动清空该策略份额** —— 调用 storage 清理 + 更新策略列表)
|
||||
- `moveStrategy(scope, id, dir)`:上移/下移(调整 order)
|
||||
- 策略 schema 不变(id/name/visible/order)
|
||||
|
||||
### 3. storage.js(本地存储)—— 配合 O3/O6
|
||||
- **现有**:load/save/get/getAll/set/remove(按 code)
|
||||
- **新增**:
|
||||
- `removeStrategyShares(strategyId)`:遍历所有 code,删除该 strategyId 的份额(删除策略联动)
|
||||
- `clearStrategy(strategyId)`:同 removeStrategyShares(O6 一键清零可复用)
|
||||
|
||||
### 4. position/manager.js(分仓逻辑)—— O6
|
||||
- **现有**:getAllPositions/getStrategyPositions/getUnallocated/addToStrategy/removeFromStrategy/getSummary
|
||||
- **新增**:
|
||||
- `moveAllUnallocatedToStrategy(code, strategyId)`:把某票**全部未分配份额**移入指定策略(O6 全部移入)—— 未分配 = volume - 已分配,一次 add
|
||||
- `clearStrategyShares(strategyId)`:清空某策略全部份额(O6 一键清零)—— 调 storage.clearStrategy + 返回影响标的列表
|
||||
- 校验保持:各策略份额之和 ≤ 总持仓
|
||||
|
||||
### 5. api.js(服务端 API)—— 承载新端点
|
||||
- **现有**:/odl/api/* 8 端点(webServer 自开路由,技术约束-004)
|
||||
- **新增端点**:
|
||||
- `POST /odl/api/strategies/remove`:{ strategyId } → 删除策略 + 联动清份额(O3)
|
||||
- `POST /odl/api/strategies/move`:{ strategyId, dir } → 排序(O3)
|
||||
- `POST /odl/api/strategies/add`:{ name } → 新增(O3,也可并入 update,分开更清晰)
|
||||
- `POST /odl/api/remove-all-shares`:{ strategyId } → 一键清零(O6)
|
||||
- 全部移入复用现有 `add-shares`(shares = 未分配数,由客户端先算好或服务端算)
|
||||
- `strategies/update` 保留(重命名/显隐仍走整表更新)
|
||||
- 错误透出:统一错误码(not-found / strategy-not-found / share-limit 等)
|
||||
|
||||
### 6. client/index.js(客户端入口)—— O2 核心改造
|
||||
- **现有**:写死注册 3 个 tab
|
||||
- **改造**:
|
||||
- 新增 `loadStrategies()`:fetch /odl/api/strategies,取 visible=true 列表
|
||||
- **动态注册**:遍历策略列表,逐个 `slots.register('conversation.view', { id: 'odl-strategy-<slug>', label: 策略名 }, StrategyTab)`
|
||||
- 全部持仓 tab 固定保留(order 10,数据源 tab)
|
||||
- **刷新机制**:暴露「刷新 tab 栏」函数 —— 重新拉策略配置 → 注销旧策略 tabs → 注册新 tabs
|
||||
- **变更提示(无事件机制,老师确认)**:设置页保存成功后**就地提示**「策略已变更,刷新页面后生效」(Toast);
|
||||
- **tab 更新时机**:插件启动时按策略配置注册 tabs → 刷新页面 = 插件重载 = 按最新策略重新注册(基线方案 X);
|
||||
- **可选优化(方案 Y)**:tab 栏利用「会话切换/重新挂载」时机重新拉策略配置自动更新(无需自定义事件,实现时验证框架挂载钩子,失败则保持方案 X)
|
||||
- **技术确认(已核实)**:`ctx.slots.register(...)` 返回 **disposer 函数**(注销该 entry)——动态注销旧 tabs 可行:注册时保存 disposer 列表,刷新时逐一调用 disposer 移除,再注册新 tabs
|
||||
|
||||
### 7. client/views/SettingsSection.jsx —— O3 UI
|
||||
- **现有**:策略列表 + 显示开关
|
||||
- **改造**:
|
||||
- 新增策略:输入框 + 按钮 → call strategies/add { name }
|
||||
- 重命名:行内编辑(改 name → strategies/update)
|
||||
- 删除:删除按钮 → **确认弹窗**(提示「该策略下 N 股将回到未分配」)→ call strategies/remove
|
||||
- 排序:上移/下移按钮 → call strategies/move
|
||||
- 保留显示开关
|
||||
- 操作反馈:Toast(成功/失败)
|
||||
|
||||
### 8. client/views/StrategyTab.jsx —— O6 UI
|
||||
- **现有**:添加(选标的+份额)/ 移出(指定数量)
|
||||
- **改造**:
|
||||
- 「全部移入」按钮(行内):该票未分配全部移入当前策略(call add-shares,shares=未分配)
|
||||
- 「一键清零」按钮(顶部):弹窗确认 → call remove-all-shares
|
||||
- 操作反馈:Toast
|
||||
- 加载失败:LoadState 兜底(O5)
|
||||
|
||||
### 9. client/views/AllPositionsTab.jsx —— O5
|
||||
- **现有**:直接显示/加载失败文字
|
||||
- **改造**:套 LoadState 三态组件(loading/error+重试/success)
|
||||
|
||||
### 10. 【新增】client/views/LoadState.jsx —— O5
|
||||
- 三态组件:loading(加载中)/ error(失败原因 + 重试按钮)/ success(children)
|
||||
- 自动重试 2 次(间隔 2s)逻辑内置(或由父组件控制)
|
||||
|
||||
### 11. 【新增】client/views/Toast.jsx —— O6/O3
|
||||
- 轻提示:success(绿)/ error(红),3s 自动消失
|
||||
- 简单实现:全局 state + 定时器,或 React portal
|
||||
|
||||
## 三、职责边界(延续迭代 01)
|
||||
|
||||
| 层 | 文件 | 职责 |
|
||||
|---|---|---|
|
||||
| API 封装层 | api.js | 接收 HTTP 请求 → 调业务层 |
|
||||
| 业务逻辑层 | position/manager.js + settings.js | 分仓逻辑 + 策略管理 |
|
||||
| 数据源适配层 | data-source/qmt-bridge-rest.js | 真正发 HTTP 到 QMT |
|
||||
| 存储层 | storage.js | allocations.json 本地持久化 |
|
||||
|
||||
**调用链**:client → HTTP /odl/api/* → api.js → manager/settings → storage / qmt-bridge-rest → QMT
|
||||
|
||||
## 四、数据流(关键路径)
|
||||
|
||||
```
|
||||
【O2 动态 tab】
|
||||
设置页保存策略变更
|
||||
→ SettingsSection 调 strategies/update(或 add/remove/move)
|
||||
→ 服务端更新 settings + 联动 storage
|
||||
→ 客户端 Toast「策略已变更,请手动刷新」+ 刷新按钮
|
||||
→ 用户点刷新 → 重新 loadStrategies() → 注销旧 tabs → 注册新 tabs
|
||||
|
||||
【O3 删除策略】
|
||||
设置页点删除 → 确认弹窗
|
||||
→ call strategies/remove { strategyId }
|
||||
→ settings.removeStrategy + storage.removeStrategyShares(strategyId)
|
||||
→ 份额回未分配(全部持仓 tab 未分配数增加)
|
||||
|
||||
【O6 全部移入】
|
||||
策略 tab 行内「全部移入」
|
||||
→ 客户端已知该票未分配数 → call add-shares { code, strategyId, shares: 未分配数 }
|
||||
→ manager.addToStrategy(校验 ≤ 总持仓)
|
||||
→ Toast 成功 → reload
|
||||
|
||||
【O6 一键清零】
|
||||
策略 tab 顶部「一键清零」→ 确认弹窗
|
||||
→ call remove-all-shares { strategyId }
|
||||
→ manager.clearStrategyShares → storage.clearStrategy
|
||||
→ Toast 成功 → reload
|
||||
```
|
||||
|
||||
## 五、关键接口签名(待实现时对照类型确认)
|
||||
|
||||
- slots.register('conversation.view', {id, label}, Component) —— 动态注册/注销(读 slots.d.ts 确认 unregister)
|
||||
- webServer.register({kind:'prefix', path:'/odl/api', handler}) —— 已有
|
||||
- settings scope.get()/update() —— 已有
|
||||
- **事件机制:不需要(老师确认,2026-08-28)**——策略变更的提示在设置页内就地显示,tab 更新靠「刷新页面 → 插件重载 → 重新注册」,全程无跨组件事件;
|
||||
- 优化(方案 Y):若框架支持会话切换挂载钩子,tab 栏自动重新拉策略配置(仍无事件)
|
||||
|
||||
## 六、开发顺序(编码)
|
||||
|
||||
1. 服务端:settings.js(add/rename/remove/move + id 生成)
|
||||
2. 服务端:storage.js(removeStrategyShares/clearStrategy)
|
||||
3. 服务端:manager.js(moveAllUnallocated/clearStrategyShares)
|
||||
4. 服务端:api.js(新端点 + 错误透出)
|
||||
5. 客户端:LoadState.jsx + Toast.jsx(基础组件)
|
||||
6. 客户端:SettingsSection CRUD + 确认弹窗
|
||||
7. 客户端:index.js 动态 tab 注册 + 刷新机制
|
||||
8. 客户端:StrategyTab 全部移入/一键清零
|
||||
9. 构建 + 安装 + 联调验收
|
||||
|
||||
## 七、非目标(本期不做)
|
||||
|
||||
- 表格列可配置(T-006 数据池)
|
||||
- 数据源状态全局监控(O5 澄清为加载兜底)
|
||||
- 数据实时刷新/WebSocket(T-005)
|
||||
- 持仓信息补全列(O1)
|
||||
- 网格参数管理、做T 记录、风控
|
||||
Reference in New Issue
Block a user