Files
kyugao bb3f8bd28d feat: 迭代03-05 交易记录接入、行情实时、QMT连接配置、data store 标准化
- R-004 QMT连接配置:多配置管理 + 会话头部快捷切换(03-QMT连接配置)
- R-005 WS盘中价格实时更新:服务端中转+缓存+前端轮询(04-WS盘中价格实时更新)
- R-006 策略数据 JSON data store 标准化(store.json/market.json/schema.json)
- R-007 交易记录接入:当日订单+成交单表合并(委托主行+展开成交明细)、时间段查询(今日/本周/本月+手动起止)、费用计算(佣金费率万m_dCommission+最低5元、印花税卖出万5、过户费双向万0.1)
- 架构治理:api 按领域拆分、component 目录、QmtHealthMonitor
2026-09-01 13:21:49 +08:00

56 lines
5.2 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.
# 迭代 03:技术实现方案
> 依据:PLAN-003、技术约束-003/008/009、产品约束-005/006、UI约束-001/002
## 数据模型(settings namespace: one-divine-lot 新增字段 qmtConnections
```
qmtConnections: {
list: [{ id, name, baseUrl, order }], // order 决定列表展示顺序
activeId: string, // 当前激活配置 id'' = 无,展示层回退 defaultId/第一条)
defaultId: string, // 默认配置 id'' = 无;启动时自动激活的目标)
}
```
- id:复用策略 slug 生成逻辑(拼音映射 + 去重),fallback 前缀 qmt-conn
- baseUrl:归一化(trim + 去尾斜杠 + 校验 http(s):// 前缀);
- 生效连接解析顺序(getActiveConnection):activeId → defaultId → order 第一条 → null。
## 关键机制
1. **启动激活(Q1**apply 时 resolveStartupConnection(settings, config)——list 空 → cordis config.qmtBaseUrl 兜底(Q4 不迁移);否则 defaultId → activeId → 第一条;结果直接作为数据源构造参数并打日志。
2. **热切换(Q2**QmtBridgeRestDataSource 增加 setBaseUrl(url)——baseUrl 为按请求读取的实例字段,改字段即对后续请求生效,无需重建实例、无需重启。
3. **删除边界(Q6**removeQmtConnection 内处理——被删为激活 → activeId 指向 defaultId(若有效)否则第一条;被删为默认 → defaultId 转移到第一条;删除后为空 → activeId/defaultId 清空;**列表仅剩一条时拒绝删除**(返回约定错误)。
4. **测试连接(Q3**:服务端代理 GET {baseUrl}/health15s 超时),返回 { ok, latencyMs, status, error };支持传未保存的 baseUrl(表单内先测后存)。
5. **头部挂载(Q9**client 插件向 slot conversation.session.header.actions 注册 id=odl-qmt-switch、order=-9(内置 PTC 标签 order=-10,并排其后);控件用插件自身 connection RPC 读写配置,不依赖 slot 注入。
## 服务端 APIPOST /odl/api/<method>webServer 自开路由 · 技术约束-004)
| 端点 | 入参 | 行为 |
|---|---|---|
| qmt-connections | - | 返回 { list, activeId, defaultId, active }active 为生效连接对象) |
| qmt-connections/add | { name, baseUrl } | 新增;返回新配置 |
| qmt-connections/update | { id, name, baseUrl } | 编辑;若改的是激活配置且 baseUrl 变化 → 编排 setBaseUrl |
| qmt-connections/remove | { id } | 删除(含边界处理);生效连接变化 → 编排 setBaseUrl;仅剩一条时报错 |
| qmt-connections/activate | { id } | 激活(写 activeId+ setBaseUrl |
| qmt-connections/set-default | { id } | 设默认(写 defaultId |
| qmt-connections/test | { baseUrl } 或 { id } | 代理 /health,返回可达性与延迟 |
## 客户端
- **QmtConnectionChip.jsx(新增)**chip `QMT: <激活配置名> ▾` + 自实现下拉菜单(绝对定位 + 外点关闭;激活项勾选);点选 → activate 端点 → toast 反馈 + 本地状态刷新。
- **SettingsSection.jsx(改)**:第三个子 tab「QMT 连接配置」;配置列表(名称/地址/激活与默认徽标)+ 行内操作(激活 / 设为默认 / 编辑 / 测试 / 删除)+ 新增与编辑表单 + 删除确认弹窗(复用 ConfirmDialog+ Toast 反馈。
- **client/index.js(改)**:注册头部 slot;其余 tab 注册不动。
## 安装与构建
服务端直接改 src;客户端 bundle 走既有 tsdown + wrap 构建(技术约束-005/006);安装用 dsh plugin add(技术约束-007)。cordis.patch.yml 不改动(Q4)。
## 实施事实(2026-08-29
- **改动文件**src/settings.jsschema + 9 个 QMT 函数段)、src/data-source/qmt-bridge-rest.jssetBaseUrl)、src/index.js(启动解析 + dataSource 注入 api)、src/api.js7 个 qmt-connections 端点 + testQmtConnection 代理 + activate/update/remove 热切换编排)、src/client/index.js(头部 slot 注册 odl-qmt-switch order=-9)、src/client/views/QmtConnectionChip.jsx(新增)、src/client/views/SettingsSection.jsx(第三个子 tab QmtConnectionsSettings,追加于文件尾)。cordis.patch.yml 未改动。
- **构建**pnpm run build 一次通过(服务端 ESM 14 文件 + 客户端 CJS bundle 69.60kB + wrap 65907 bytes);node --check 服务端全通过;bundle 内已核对 chip 与端点调用代码。
- **安装方式更正**profile~/.dsh/profiles/web)中插件为 link 符号链接指向工作区,工作区 lib/ 即宿主加载产物,构建后无需再执行 dsh plugin add(技术约束-007 补充事实:link 安装形态下构建即生效)。
- **数据层单测**:14 项断言全部通过(mock settings scope):新增归一化去尾斜杠、order 排序、新增不自动激活、空激活态回退第一条、非法地址拒绝、激活/默认写入、生效连接解析、编辑激活配置地址、删除标记返回、删激活/默认→转移第一条并激活、禁删最后一条、空列表回退 cordis、启动激活默认(覆盖上次激活)、启动解析回写 activeId。
- **生效条件**:线上宿主进程(GUI http://127.0.0.1:3080)启动时已加载旧 libqmt-connections 端点 404 证实),需重启 DSH Web 或重载插件后新代码生效。