This commit is contained in:
2026-08-29 16:20:33 +08:00
commit cba31428dc
52 changed files with 6553 additions and 0 deletions
@@ -0,0 +1,171 @@
# 迭代 01 实施步骤规划(分步执行)
> 2026-08-27 | 按步骤分批推进,每步有独立产出与验证点
> 关联:技术实现方案.md、程序结构设计.md
## 总览
| 步骤 | 内容 | 产出 | 验证点 | 依赖 |
|---|---|---|---|---|
| S1 | 插件骨架 | package.json + 目录 + 空 apply | 包可被识别 | - |
| S2 | 数据源适配 | qmt-bridge-rest.jsREST 直连) | fetch QMT 返回真实数据 | S1 |
| S3 | 设置管理 | settings.js(策略注册) | 设置中出现策略配置 | S1 |
| S4 | 本地存储 | storage.jsallocations.json | 读写持久化 | S1 |
| S5 | 分仓逻辑 | manager.js(份额分配/聚合) | 单元验证分仓计算 | S2+S4 |
| S6 | 服务端 RPC API | api.jsconnection.rpc | RPC 端点可调用 | S2+S3+S5 |
| S7 | 客户端 tab | client/conversation.view 注册) | tab 出现在对话/轨迹/上下文后 | S3+S6 |
| S8 | 宿主挂载+联调 | cordis.patch.yml + 安装 | 全链路可用 + 验收 | S1-S7 |
## 分步细节
### S1:插件骨架
- package.jsonname/version/main/files + `dsh.client` 声明(web 平台)
- 目录:src/、lib/、src/data-source/、src/position/、src/client/
- src/index.jsapply(ctx) 空实现 + name/inject/apply 导出
- **验证**:node 语法检查 + 包结构完整
### S2:数据源适配(qmt-bridge-rest.js
- src/data-source/types.js:统一数据模型(Position/AssetSummary/DataSource 接口)
- src/data-source/qmt-bridge-rest.js
- baseUrl 配置(默认 http://192.168.3.43:8610
- getPositions() / getAsset() / health()
- 字段映射(语义字段优先,m_ 回退)
- **验证**:独立脚本调用,返回真实持仓/资金数据(对齐快照)
### S3:设置管理(settings.js
- ctx.settings.register('one-divine-lot', schema)
- 策略 schemastrategies: [{id, name, visible, order}]
- 预置:网格超市、手动做T
- **验证**:settings 可读取默认策略;更新后值变化
### S4:本地存储(storage.js
- 路径:~/.dsh/one-divine-lot/allocations.json
- load()/save()/get()/set()
- 原子写(临时文件+rename
- **验证**:写入后文件存在,重启读回一致
### S5:分仓逻辑(position/manager.js
- getAllPositions():全量持仓
- getStrategyPositions(strategyId):按分配份额过滤
- getSummary():各策略份额/市值/盈亏 + 未分配
- allocate():份额分配(校验和 ≤ 总持仓)
- **验证**:单元测试分仓计算(如 1000 股 → 网格 600 + 做T 400
### S6:服务端 RPC APIapi.js
- ctx.connection.rpc.intercept('/api', matcher, handler)
- 端点:strategies/positions/allocations/summary/strategy/:id/positions
- **验证**:通过 DSH RPC 调用端点返回正确数据
### S7:客户端 tabclient/
- client/index.js:读策略设置 → 注册 conversation.view entries
- client/views/StrategyTab.jsx:渲染策略持仓(调 RPC API)
- **验证**:tab 出现在对话/轨迹/上下文后,点击加载数据
### S8:宿主挂载 + 联调验收
- cordis.patch.yml insert 插件行
- 插件安装到 profilepnpm link 等)
- 全链路验收(对照验收标准.md
## 建议执行批次
- **批次 1(S1-S2)**:骨架 + 数据源 —— 打通「插件→QMT REST」数据读取(纯服务端,可独立验证)
- **批次 2S3-S5)**:设置 + 存储 + 分仓逻辑 —— 核心业务逻辑
- **批次 3S6**:RPC API —— 打通「服务端能力 → DSH 通道」
- **批次 4S7-S8**:客户端 tab + 宿主挂载 —— 全链路 UI 呈现
## 前置技术确认(编码前)
1. conversation.view 注册签名(读 dsh-client-ui-conversation slots.d.ts
2. 插件安装到 profile 的方式(pnpm link / 本地路径)
3. settings 注册在 host plane 的注入方式(ctx.settings 是否对插件可用)
## 执行进度(2026-08-27
### ✅ 批次 1-2S1-S4)已完成
| 步骤 | 状态 | 验证结果 |
|---|---|---|
| S1 插件骨架 | ✅ 完成 | package.jsondsh.client 声明)+ src/index.js 空入口,语法通过 |
| S2 数据源适配 | ✅ 完成 | qmt-bridge-rest.js 真实调通 QMT REST:可用性✅、资金✅(总资产129,412.25)、持仓✅(12只,市值85,948 |
| S3 设置管理 | ✅ 完成 | settings.js:默认策略(网格超市/手动做T)、可见过滤、排序,逻辑验证通过 |
| S4 本地存储 | ✅ 完成 | storage.js:读写/持久化/覆盖/删除验证通过(1000股→网格600+做T400 校验通过) |
### 产出文件
- src/index.js(接入 S2-S4
- src/settings.js
- src/storage.js
- src/data-source/types.js
- src/data-source/qmt-bridge-rest.js
### 下一步(批次 2 剩余 / 批次 3)
- S5 分仓逻辑(position/manager.js
- S6 服务端 RPC APIconnection.rpc
- S7-S8 客户端 + 宿主挂载
### ✅ S5 已完成(2026-08-27
| 项 | 结果 |
|---|---|
| S5 分仓逻辑 | ✅ 完成 position/manager.js:全量持仓/策略持仓/未分配/添加/移出/摘要 |
| 验证 | ✅ 真实 QMT 数据:添加(600+400)、超限拦截(>1800拒绝)、移出(400→200)、移出超限拦截、摘要(份额汇总+未分配=1000)全部通过 |
| 设计依据 | S5 讨论定稿(Q1股数/Q2允许未分配/Q3人为分组/Q4无统计/Q5策略tab内编辑) |
### 待办(批次 3-4
- S6 服务端 RPC APIconnection.rpc
- S7 客户端 tab(全部持仓/网格策略持仓/做T持仓)
- S8 宿主挂载 + 联调验收
### ✅ S6 已完成(2026-08-27
| 项 | 结果 |
|---|---|
| S6 服务端 RPC API | ✅ 完成 src/api.jsconnection.rpc.intercept('/api') 暴露 8 个端点 |
| 端点 | positions / strategies / strategy-positions / unallocated / summary / add-shares / remove-shares+ 未知端点错误) |
| 验证 | ✅ 全部端点回归通过;错误码精确(share-limit / share-exceed / unknown-endpoint |
| 模式 | 参照 dsh-api-gatewayintercept('/api', matcher, handler, {authority:'trusted-host'})RpcResult 格式 {ok, value}/{ok:false, error} |
### 待办(批次 4
- S7 客户端 tab(全部持仓/网格策略持仓/做T持仓)
- S8 宿主挂载 + 联调验收
### 🔄 S7 客户端 tab(部分完成,2026-08-27
**已完成**
- src/client/index.js:客户端插件入口(inject slots/connection,注册 3 个 conversation.view tab:全部持仓/网格策略持仓/做T持仓)
- src/client/views/AllPositionsTab.jsx:全部持仓组件(全量+份额标注)
- src/client/views/StrategyTab.jsx:策略持仓组件(添加/移出交互)
- src/client/views/connection.jsRPC 调用 hook
**待完成**
- 构建配置(tsdown/tsconfig + 客户端依赖安装)
- 客户端 bundle 构建 + 语法/类型验证
- 与宿主集成测试(S8 时统一)
**关键约束**S7 现实情况):
- 客户端插件需要 react/slots/runtime 等依赖(peerDependencies),需安装;
- JSX 需要构建工具(tsdown)处理成浏览器 bundle
- 构建环境与宿主挂载(S8)联动,建议 S7+S8 一起验收;
- 客户端代码的完整运行验证依赖 DSH web 宿主重启加载。
### ✅ S7-S8 已完成(2026-08-28
| 项 | 状态 |
|---|---|
| S7 客户端 tab | ✅ 完成:全部持仓/网格策略持仓/做T持仓 三个 conversation.view tab |
| S7 设置菜单 | ✅ 完成:settings.section「神之一手」(策略列表 + 显示开关) |
| S8 宿主挂载 | ✅ 完成:插件 link 到 web profile + bundles 加入 + bundle patch 挂载 |
| 客户端 bundle | ✅ __ModuleLoader__.load 包装(scripts/wrap-client.mjs |
| 服务端 API | ✅ webServer /odl/api/* 路由(8 端点)—— 修正:不用 RPC(与 api-gateway 冲突) |
### 已解决的问题(实现过程中的关键坑)
1. **RPC 冲突**/api 通道只能一个 interceptorapi-gateway 占用)→ 改用 webServer 自开路由
2. **slots.register 签名**:component 必须是第二参数 → React #130 崩溃
3. **客户端 bundle 格式**:必须 __ModuleLoader__.load 包装
4. **settings schema**:必须 schemastery z.object(函数式 schema
5. **endpoint 前缀**:客户端传 one-divine-lot/* 需剥离
### 验证结果(2026-08-28,真实 QMT 数据)
- positions/summary/strategies/add-shares/remove-shares 全部 HTTP 200
- 12 只真实持仓显示正常(老师确认)
- 份额添加/移除/持久化工作正常
- 分仓存储文件 allocations.json 已创建