diff --git a/docs/02-计划/计划-Tab设置统一管理.md b/docs/02-计划/计划-Tab设置统一管理.md new file mode 100644 index 0000000..e66f8bd --- /dev/null +++ b/docs/02-计划/计划-Tab设置统一管理.md @@ -0,0 +1,61 @@ +# 计划:Tab 设置——统一管理所有会话 tab(内置 + 策略分组,显示/隐藏 + 拖动排序)(阶段航点) + +> 编号:PLAN-010 | 粒度:阶段航点(大粒度) | 创建:2026-09-02 | 状态:**执行中** +> 派生自终极目标:目标-002(分仓管理工具)、目标-003(按策略监控市场) +> 依据需求:**R-011(已定稿,2026-09-02,Q1-Q5 确认)** —— 符合入范围门槛 +> 设计约束:产品约束-009、UI约束-003、技术约束-014(R-011 新增沉淀)、技术约束-004/005/006(沿用) + +## 目标 + +将设置页「通用设置」升级为 **「Tab 设置」**,成为所有会话 tab(系统内置 + 策略分组)**唯一的顺序与显隐入口**:两类 tab 混排一张表,每行 = 拖动手柄 + 名称 + 显示/隐藏开关;**任何 tab 均不支持重命名与删除**;拖动落点立即持久化。 + +## 范围 + +**做**: +1. **数据模型统一**(src/settings.js):settings.tabs 从布尔对象 → 有序数组 [{id, kind: builtin|strategy, refKey|refId, name, visible, order}];strategies 收窄为 {id, name};读取时旧格式静默归一化(旧 tabs 布尔对象 → 三个内置条目保留原显隐;旧策略按 order 接续追加,旧隐藏策略迁移后 visible=true);新增整表更新(顺序 + 显隐);DEFAULT_TABS 升级为默认数组; +2. **API 层**(src/api/strategies.js):tabs/update 语义改为整表更新(顺序 + 显隐);strategies/add 联动追加 tab 条目(末尾);strategies/remove 联动删除对应 tab 条目;废弃 strategies/move;strategies/update 仅剩重命名; +3. **客户端注册**(src/client/index.js):合并 registerGeneralTabs + registerStrategyTabs 为统一注册(读 tabs 数组按 order 排序、过滤 visible;builtin 走内置 render、strategy 走 StrategyTab),移除硬编码 order 间隔(10/11/12 与 13+); +4. **设置页 UI**(src/client/views/SettingsSection.jsx): + - 「Tab 设置」子 tab 取代「通用设置」:混排表格,内置行「内置」徽标、策略行「策略」徽标;每行 = 拖动手柄 + 名称 + 显隐开关;无任何重命名/删除按钮; + - 拖动:原生 HTML5 Drag & Drop,落点重排 → 立即调 tabs/update 持久化 → 提示「刷新页面后生效」; + - 「策略分组」子 tab 瘦身:只留 新增/重命名/删除,移除排序箭头与显隐开关,加提示「顺序与显示请在「Tab 设置」中调整」。 + +**不做**: +- 策略的命名/删除入口迁移(仍在「策略分组」子 tab); +- 内置 tab 的重命名/删除(禁); +- tab 注册热更新(沿用「刷新页面后生效」机制,无事件机制); +- 其他设置子 tab(QMT 连接配置)改动(仅 UI约束-002 文案「通用设置」→「Tab 设置」对齐)。 + +## 程序结构 + +``` +src/ +├── settings.js # 改:tabs 有序数组 + 归一化迁移 + 整表更新;strategies 收窄 +├── api/strategies.js # 改:tabs/update 整表;add/remove 联动 tabs;废弃 move +src/client/ +├── index.js # 改:统一注册(读 tabs 数组) +└── views/SettingsSection.jsx # 改:「Tab 设置」子 tab + 拖动排序 + 策略分组瘦身 +``` + +## 实现步骤 + +1. **文档骨架**:PLAN-010 + 迭代 09 文档(本步); +2. **settings.js**:tabs 有序数组 schema + DEFAULT_TABS + 归一化(getTabs 旧格式转新)+ updateTabs 整表 + strategies 收窄(去 visible/order 读写); +3. **api/strategies.js**:tabs/update 整表语义;strategies/add 追加 tab;strategies/remove 联动删 tab;废弃 move(API 表 + handler); +4. **client/index.js**:统一注册函数(读 tabs 数组),移除硬编码 order; +5. **SettingsSection.jsx**:「Tab 设置」子 tab(混排表格 + 徽标 + 显隐开关 + 拖动排序 + 立即持久化);策略分组子 tab 瘦身; +6. **构建测试**:pnpm run build + typecheck + 独立数据目录回归(技术约束-011,注意只读端点可直连、写操作走临时目录); +7. **验收 + 复盘**。 + +## 验收要点 + +- 「通用设置」子 tab 更名为「Tab 设置」,表格混排内置 + 策略全部 tab; +- 内置行带「内置」徽标、策略行带「策略」徽标; +- 每行可拖动排序,落点立即持久化(刷新页面后生效); +- 每行有显示/隐藏开关,切换立即持久化; +- 任何行均无重命名/删除按钮; +- 策略分组子 tab 只留 新增/重命名/删除,无排序箭头/显隐开关,有指引提示; +- 新增策略出现在 Tab 设置列表末尾;删除策略后对应 tab 条目消失; +- 老配置(布尔对象 tabs + 策略 order/visible)读取时自动归一化,无报错、无数据丢失; +- 会话 tab 栏按新顺序与显隐注册(内置与策略可交错); +- 现有功能不回归(全部持仓/交易记录/策略持仓/QMT 切换)。 diff --git a/docs/02-计划/计划-UI主题适配.md b/docs/02-计划/计划-UI主题适配.md new file mode 100644 index 0000000..b714885 --- /dev/null +++ b/docs/02-计划/计划-UI主题适配.md @@ -0,0 +1,55 @@ +# 计划:UI 适配 DSH 主题(浅色 / 深色 / 跟随系统)(阶段航点) + +> 编号:PLAN-011 | 粒度:阶段航点 | 创建:2026-09-02 | 状态:**执行中** +> 派生自终极目标:目标-001(神之一手工具集) +> 依据需求:**R-012(已定稿,2026-09-02,暂定跟随系统)** —— 符合入范围门槛 +> 设计约束:UI约束-003(Tab 设置)、UI约束-002(QMT 卡片)沿用;本次新增色值 token 化约定 + +## 目标 + +神之一手客户端 UI 全部硬编码色值替换为宿主 `--dsw-*` token,使各页面在 DSH 浅色 / 深色 / 跟随系统主题下均可读、协调,随主题切换自动适配,不自行维护主题偏好。 + +## 范围 + +**做**: +1. 客户端 10 个文件 141 处硬编码颜色按语义映射表替换为 `var(--dsw-*)` 或 `color-mix`(随主题淡色底); +2. 确认 QmtConnectionChip 已用 token 与硬编码混杂处统一; +3. 涨跌色(红涨绿跌)→ 宿主 state-error/success;主按钮 / 徽标 / 提示底色 → 宿主语义 token + color-mix; +4. 构建 + typecheck + 深浅主题人工验收。 + +**不做**: +- 自定义 `--odl-*` 覆盖 token(D5 暂缓); +- 布局 / 间距 / 圆角改动; +- 服务端 / API / 数据改动; +- 插件自维护主题偏好(跟随宿主)。 + +## 涉及文件 + +``` +src/client/views/ +├── SettingsSection.jsx # 55 处(最大) +├── StrategyTab.jsx # 24 +├── TradeRecordsTab.jsx # 21 +├── QmtConnectionChip.jsx # 13(部分已 token) +├── RangeSelector.jsx # 7 +├── PriceCell.jsx # 5(涨跌色) +├── AllPositionsTab.jsx # 4 +├── LoadState.jsx # 3 +├── Toast.jsx # 2 +└── PlaceholderTab.jsx # 1 +``` + +## 实现步骤 + +1. **文档骨架**:PLAN-011 + 迭代 10(本步); +2. **批量替换**:按文件逐处替换(先小文件确认模式,再大文件); +3. **验证**:build + typecheck;人工切 DSH 浅/深主题检查各页; +4. **验收 + 复盘**。 + +## 验收要点 + +- 浅色主题下观感与现状基本一致(无突兀色差); +- 深色主题下所有页面可读(背景/文字/边框/按钮/涨跌/徽标/提示/下拉菜单均协调); +- 跟随系统切换实时生效; +- 无残留硬编码色(#xxx / rgb / rgba 全部清理,注释可留); +- 布局与交互不变(仅色值)。 diff --git a/docs/03-设计约束/UI交互约束.md b/docs/03-设计约束/UI交互约束.md index cc00f95..ce689ce 100644 --- a/docs/03-设计约束/UI交互约束.md +++ b/docs/03-设计约束/UI交互约束.md @@ -10,7 +10,10 @@ | 编号 | 约束说明 | 添加日期 | 生效状态 | 失效日期 | 最后一次变更描述 | |---|---|---|---|---|---| | UI约束-001 | 会话头部 QMT 连接切换 chip:紧凑形态 `QMT: <激活配置名> ▾`,与 PTC 模式标签并排;下拉菜单列出全部配置(当前激活项勾选标记),点选即激活;操作结果用顶部轻提示反馈(成功绿/失败红,约 3s 消失,沿用现有 Toast 体系) | 2026-08-29 | 生效 | - | R-004 定稿(2026-08-29):Q9/Q10 确认的头部控件形态 | -| UI约束-002 | 设置页「QMT 连接配置」子 tab:与「通用设置 / 策略分组」并列的第三个子 tab;配置以**卡片形式**展示(自适应网格 minmax(260px,1fr),激活卡片绿色描边):卡片含名称 + 激活/默认徽标 + HTTP 地址 + 行内操作(激活 / 设为默认 / 编辑 / 测试连接 / 删除)+ 新增/编辑表单(纵排两字段);删除沿用现有确认弹窗模式,删除最后一条时给出禁止提示;超时不设输入框(Q5);长文本(地址/错误信息)单行省略 + 悬停看全文,组件设 minWidth:0 防撑行 | 2026-08-29 | 生效 | - | 变更(2026-08-29 老师反馈):列表形式改卡片形式,约束组件宽度、长文本省略不换行;原定稿:设置页子 tab 形态沿用现有设置交互体系 | +| UI约束-002 | 设置页「QMT 连接配置」子 tab:与「Tab 设置 / 策略分组」并列的第三个子 tab;配置以**卡片形式**展示(自适应网格 minmax(260px,1fr),激活卡片绿色描边):卡片含名称 + 激活/默认徽标 + HTTP 地址 + 行内操作(激活 / 设为默认 / 编辑 / 测试连接 / 删除)+ 新增/编辑表单(纵排两字段);删除沿用现有确认弹窗模式,删除最后一条时给出禁止提示;超时不设输入框(Q5);长文本(地址/错误信息)单行省略 + 悬停看全文,组件设 minWidth:0 防撑行 | 2026-08-29 | 生效 | - | 变更(2026-08-29 老师反馈):列表形式改卡片形式,约束组件宽度、长文本省略不换行;原定稿:设置页子 tab 形态沿用现有设置交互体系;变更(2026-09-02 R-011 定稿):「通用设置」更名为「Tab 设置」 | +| UI约束-003 | 设置页「Tab 设置」子 tab:表格列出**全部会话 tab(系统内置 + 策略分组)混排**,内置行带「内置」徽标、策略行带「策略」徽标;每行 = 拖动手柄(原生 HTML5 Drag & Drop)+ 名称 + 显示/隐藏开关;**任何行均无重命名/删除按钮**;拖动落点确认后**立即持久化**(每次 drop 提交整表,沿用「刷新页面后生效」提示机制);「策略分组」子 tab 只保留 新增/重命名/删除,移除排序箭头与显隐开关,并提示「顺序与显示请在「Tab 设置」中调整」 | 2026-09-02 | 生效 | - | R-011 定稿(2026-09-02 Q1/Q4/Q5 确认):拖动排序 + 显隐开关,禁重命名/删除 | + +| UI约束-004 | 神之一手 UI 适配 DSH 主题:所有颜色引用宿主 `--dsw-*` token(带 fallback `var(--dsw-alias-xxx, #原色)`),随 DSH 浅色 / 深色 / 跟随系统自动切换,不自行维护主题偏好(跟随宿主);语义映射:表面底→bg-layer-1、次级面→bg-layer-2、hover→interactive-bg-hover、主/次/弱文字→label-primary/secondary/tertiary、边框→border-l1..l4、红(涨/删/错)→state-error-primary、绿(跌/成/激活)→state-success-primary、蓝(信息/业务)→state-business-primary、实心按钮字→button-contrast-fill、遮罩→bg-mask-1、阴影→shadow-lv3;淡底用 color-mix(in srgb, var(--语义色) 10-12%, transparent);禁止硬编码色值(#hex/rgb)进运行代码 | 2026-09-02 | 生效 | - | R-012 定稿(2026-09-02,暂定跟随系统)+ 迭代 10 实施:141 处硬编码色 token 化,宿主机制实证(body[data-ds-dark-theme] + alias token 双值定义) | \ No newline at end of file diff --git a/docs/03-设计约束/技术方案约束.md b/docs/03-设计约束/技术方案约束.md index ca972c1..5939ddf 100644 --- a/docs/03-设计约束/技术方案约束.md +++ b/docs/03-设计约束/技术方案约束.md @@ -23,6 +23,7 @@ | 技术约束-009 | 会话头部快捷切换控件挂载 DSH 开放 slot `conversation.session.header.actions`(多实例挂载点,按 order 排序多插件共存):客户端插件以独立 id 并排注册(DSH 内置 PTC 标签 order=-10,本控件 order=-9),不改动 DSH 宿主;控件经 ConnectionProvider 包装复用现有 RPC 通道与 /odl/api/* 端点 | 2026-08-29 | 生效 | - | R-004 定稿(2026-08-29):Q9 确认;宿主代码审查核实 slot 机制与内置插件注册方式 | | 技术约束-013 | 交易记录本地存储(R-009):QMT 当日交易数据(委托/成交)由服务端 TradeSync 定时同步落 SQLite(启动预热 + 60s 定时 + UPSERT 幂等,只同步当日);trade_orders(委托主行,order_id 主键 + insert_ts 派生时间列 + **strategy_id/holding_id 手动归属列**)+ trade_fills(成交明细,trade_id 主键、order_id 外键)两表;**委托归属由用户在交易记录 tab 手动设置**(候选 = 该 code 当前持仓策略 + 未关联,全手动选、可随时改、以最终为准);**UPSERT 不覆盖归属列**(手动指定为插件逻辑);本地历史查询走 trades/history 端点(策略过滤 = 用户设置的归属);今日实时仍走 QMT Bridge;QMT 委托/成交 code 无后缀、持仓带后缀 —— 数据源映射层统一 normalizeInstrumentCode 归一化;委托交易日 = insertDate(tradeDate 兜底) | 2026-09-01 | 生效 | - | 新增(2026-09-01 R-009 定稿 + 迭代 07 实施):两表 + 定时同步 + 本地历史查询;变更 1(2026-09-01):+code 归一化 + tradeDate 兜底;变更 2(2026-09-01 老师二次定稿):归属改**手动设置**(trade_orders 冗余 strategy_id+holding_id,UPSERT 不覆盖归属列),弃算法推导 | +| 技术约束-014 | 会话 tab 注册与顺序显隐(R-011):客户端注册统一读 **settings.tabs 有序数组**(唯一顺序与显隐来源,内置条目 refKey + 策略条目 refId),按 order 排序、过滤 visible 后注册(builtin 走内置 render、strategy 走 StrategyTab),移除硬编码 order 间隔(原内置 10/11/12、策略 13+);settings.tabs 从布尔对象升级为有序数组,读取时对旧格式(布尔对象 + 策略自带 order/visible)静默归一化迁移(旧隐藏策略迁移后显示),写入即落库;策略定义表收窄为 {id,name}(去除 visible/order);tabs/update 语义改为整表更新(顺序 + 显隐),strategies/add 联动追加 tab 条目(末尾),strategies/remove 联动删除对应 tab 条目,废弃 strategies/move | 2026-09-02 | 生效 | - | R-011 定稿(2026-09-02 Q1-Q5 确认):统一 tabs 有序数组 + 自动迁移 + 联动增删 | \ No newline at end of file diff --git a/docs/04-迭代记录/09-Tab设置统一管理/技术实现方案.md b/docs/04-迭代记录/09-Tab设置统一管理/技术实现方案.md new file mode 100644 index 0000000..291d0e8 --- /dev/null +++ b/docs/04-迭代记录/09-Tab设置统一管理/技术实现方案.md @@ -0,0 +1,82 @@ +# 技术实现方案:09-Tab 设置统一管理 + +> 迭代编号:09 | 依据:PLAN-010、R-011、产品约束-009、UI约束-003、技术约束-014 + +## 1. 数据模型(src/settings.js) + +### 1.1 tabs 有序数组(新 schema) + +```js +tabs: z.array(z.object({ + id: z.string().required(), // 唯一 id:'tab-all-positions' / 'tab-strategy-' + kind: z.enum(['builtin', 'strategy']).required(), + refKey: z.string().optional(), // builtin 专用:'allPositions' | 'tradeRecords' | 'watchlist' + refId: z.string().optional(), // strategy 专用:策略 id + name: z.string().required(), // 展示名(策略行 join 时刷新) + visible: z.boolean().default(true), + order: z.number().default(0), +})).default(DEFAULT_TABS) +``` + +### 1.2 归一化迁移(读取时) + +getTabs(scope) 逻辑: +- 读取 settings.tabs:若为数组 → 直接返回(按 order 排序); +- 若为旧布尔对象(或缺失)→ 生成默认内置三条(全部持仓/交易记录/关注列表,保留原显隐值),策略按 strategies 旧 order 接续追加(旧 hidden → visible=true); +- 首次写入时落库归一化后的数组(幂等,不重复迁移)。 + +### 1.3 strategies 收窄 + +strategies schema 去掉 visible/order(仅 {id, name});getStrategies 不再排序/过滤 visible;策略展示名统一由 getTabs join strategies 得出(Q4 自动跟随改名)。 + +## 2. API 层(src/api/strategies.js) + +| 端点 | 变更 | +|---|---| +| tabs | 返回合并后的完整 tabs 数组(含策略行 name join) | +| tabs/update | 整表更新 { tabs }(顺序 + 显隐);策略行 name 由服务端 join 刷新,客户端可只传 id 顺序 | +| strategies/add | 联动 append tab 条目(末尾,order = max+1) | +| strategies/remove | 联动删除对应 tab 条目(refId === 策略 id) | +| strategies/move | **废弃**(从 METHODS 移除) | +| strategies/update | 仅剩重命名(联动刷新 tabs 中策略行 name) | + +## 3. 客户端注册(src/client/index.js) + +合并 registerGeneralTabs + registerStrategyTabs → registerAllFromTabs(tabs): +```js +const sorted = tabs.slice().sort((a, b) => (a.order ?? 0) - (b.order ?? 0)); +for (const t of sorted) { + if (t.visible === false) continue; + const render = t.kind === 'builtin' ? GENERAL_RENDER[t.refKey] : (props) => createElement(StrategyTab, { ...props, strategyId: t.refId, strategyName: t.name }); + // slots.register conversation.view, order: t.order +} +``` +- GENERAL_RENDER = { allPositions, tradeRecords, watchlist } 映射常量; +- 移除硬编码 order 10/11/12 与 13+ 间隔(直接用 t.order); +- fetchTabConfig → fetchTabs 返回数组。 + +## 4. 设置页 UI(src/client/views/SettingsSection.jsx) + +### 4.1 「Tab 设置」子 tab + +- 子 tab 导航:general → tabs(更名),标签「Tab 设置」; +- 表格列:拖动手柄(≡)| 名称(内置行带「内置」徽标、策略行带「策略」徽标)| 显示(Switch); +- **无重命名/删除按钮(任何行)**; +- 拖动(原生 DnD): + - tr draggable,onDragStart 记 id;onDragOver 阻止默认 + 计算插入位;onDrop 重排数组; + - 落点 → 立即调 tabs/update(整表提交)→ 提示「已保存,刷新页面后生效」; +- 显隐开关:切换 → 立即调 tabs/update → 提示。 + +### 4.2 策略分组瘦身 + +- 移除排序箭头列(↑↓)与显示列(Switch); +- 保留:新增输入框 + 新增按钮 / 重命名 / 删除(确认弹窗 + 份额回未分配沿用); +- 顶部加提示:顺序与显示请在「Tab 设置」中调整。 + +## 5. 兼容与风险 + +- **迁移**:读取归一化幂等;旧策略 visible=false 迁移后 visible=true(Q3,产品约束-009 一致); +- **名称 join**:tabs 存 refId,展示时 join strategies;策略改名后 tabs 行 name 自动跟随(Q4); +- **注册**:refresh = 刷新页面重载插件(无事件机制,沿用); +- **RPC**:strategies/move 废弃需同步移除客户端调用(settings UI 不再有箭头); +- **回归**:技术约束-011 —— 写操作测试用独立数据目录(ODL_TEST_DATA_DIR / dataDir 参数)。 diff --git a/docs/04-迭代记录/09-Tab设置统一管理/迭代复盘.md b/docs/04-迭代记录/09-Tab设置统一管理/迭代复盘.md new file mode 100644 index 0000000..a432dcc --- /dev/null +++ b/docs/04-迭代记录/09-Tab设置统一管理/迭代复盘.md @@ -0,0 +1,41 @@ +# 迭代复盘:09-Tab 设置统一管理(内置 + 策略分组,显示/隐藏 + 拖动排序) + +> 复盘日期:2026-09-02 | 迭代状态:**已完成(老师确认)** +> 关联需求:R-011(Tab 设置:统一管理所有 tab,已定稿 Q1-Q5) +> 关联计划:PLAN-010(计划-Tab设置统一管理) + +## 结果 + +迭代 09 达成:设置页「通用设置」升级为「Tab 设置」,成为所有会话 tab(系统内置 + 策略分组)**唯一的顺序与显隐入口**:两类 tab 混排一张表,每行 = 拖动手柄(原生 HTML5 DnD)+ 名称(内置带「内置」徽标、策略带「策略」徽标)+ 显示/隐藏开关;**任何 tab 均不支持重命名与删除**;拖动落点立即持久化;策略分组子 tab 瘦身为 新增/重命名/删除。 + +## 过程事实 + +1. **需求定稿(R-011)**:老师提出设置页默认 tab 与策略 tab 一起排序(内置标记、不可重命名/删除)→ AI 分析现状(两套数据、两套 order 空间,内置恒在策略前)→ 提出统一 tabs 有序数组方案 → 老师确认 D1-D7 + Q1-Q5(拖动落点立即持久化 / 新增追加末尾 / 旧隐藏策略迁移后显示 / 名称 join 自动跟随 / 全部 tab 禁重命名删除); +2. **数据层(settings.js)**:tabs 从布尔对象 → 统一有序数组(kind: builtin|strategy + refKey/refId + visible + order);strategies 收窄为 {id, name};旧格式读取时静默归一化迁移(schema union 兼容存量 + normalizeTabs 转换);addStrategy/removeStrategy 联动 tabs; +3. **API 层(strategies.js)**:tabs/update 语义改整表(顺序 + 显隐);strategies/add 联动追加 tab(末尾);strategies/remove 联动删除 tab 条目;废弃 strategies/move; +4. **客户端注册(client/index.js)**:合并 registerGeneralTabs + registerStrategyTabs 为统一注册(读 tabs 数组按 order 排序、过滤 visible,builtin 走内置 render、strategy 走 StrategyTab),移除硬编码 order 间隔(10/11/12 与 13+); +5. **设置页 UI(SettingsSection.jsx)**:「Tab 设置」子 tab(混排表格 + 徽标 + 显隐开关 + 拖动排序 + 落点立即持久化);策略分组瘦身(移除排序箭头与显隐开关,加指引提示); +6. **验证**:回归测试 35 项全通过(scripts/test-r011-tabs.mjs 数据层 23 项 + test-r011-api.mjs API 层 12 项)+ 真实 schema resolve 验证(旧配置归一化正确)+ 构建 + typecheck 通过。 + +## 经验教训(复盘沉淀) + +### 1. schemastery 无 z.enum / .optional(),schema 兼容存量用 z.union 双分支 +- schemastery 只有 z.union([z.const(...), ...]) 无 z.enum,可选字段不调 .required() 即可; +- **关键**:DSH settings 的 resolve 会用 schema 校验存量 user 层——新 schema 直接替换会导致旧配置(布尔对象 tabs)校验失败、插件启动报错; +- **沉淀**:settings schema 变更必须先验证存量兼容——用 z.union 双分支(旧格式 + 新格式),旧值通过校验、读取时再归一化;改动 settings schema 前跑 schema-resolve 测试。 + +### 2. 读取时归一化 + schema 双分支 = 无感迁移 +- 本次没有写一次性迁移脚本,而是「schema 接受旧格式 + normalizeTabs 读取时转新」:存量用户升级零操作、零报错; +- 归一化结果在首次写操作(updateTabs/add/remove)时落库为数组,之后自然持久化; +- **沉淀**:settings 结构变更优先「schema 兼容 + 读取归一化」而非迁移脚本,符合 R-006/R-008 的迁移经验(幂等、无需用户操作)。 + +### 3. 前端字符串与 JSX 引号冲突 +- 写 JSX 组件代码时,代码里同时有 JS 单双引号与 JSX 属性引号,用模板字符串包整段时内部反引号/插值冲突,多次报错; +- **沉淀**:批量生成代码用数组 join(每行独立字符串),避免模板字符串嵌套转义地狱。 + +## 遗留/后续 + +1. **Tab 设置拖动交互**:当前实现为整行 draggable(原生 DnD),落点插入到目标行位置;后续可优化为拖动手柄专属拖拽 + 拖拽中的视觉反馈(插入线); +2. **关注列表 tab**:仍为占位(PlaceholderTab),后续迭代实现; +3. **迁移落库时机**:旧配置首次读取不落库(纯读),首次写操作时才持久化新数组——如老师希望启动即落库可加一次性迁移(当前行为无感知差异,可接受); +4. **多 DSH 实例/多用户**:tabs 顺序为全局设置(非按会话),符合现状(strategies 亦为全局)。 diff --git a/docs/04-迭代记录/09-Tab设置统一管理/迭代目标.md b/docs/04-迭代记录/09-Tab设置统一管理/迭代目标.md new file mode 100644 index 0000000..f69159d --- /dev/null +++ b/docs/04-迭代记录/09-Tab设置统一管理/迭代目标.md @@ -0,0 +1,26 @@ +# 迭代目标:09-Tab 设置统一管理(内置 + 策略分组,显示/隐藏 + 拖动排序) + +> 迭代编号:09 | 创建:2026-09-02 | 状态:进行中 +> 依据计划:PLAN-010 | 需求:R-011(已定稿,2026-09-02,Q1-Q5 确认) + +## 目标描述 + +将设置页「通用设置」升级为「Tab 设置」,成为所有会话 tab(系统内置 + 策略分组)**唯一的顺序与显隐入口**:两类 tab 混排一张表,每行 = 拖动手柄 + 名称 + 显示/隐藏开关;任何 tab 均不支持重命名与删除;拖动落点立即持久化。 + +## 目标分解 + +1. **数据模型统一**(settings.js):tabs 布尔对象 → 有序数组,旧格式自动归一化;strategies 收窄为 {id, name}; +2. **API 层**(api/strategies.js):tabs/update 整表(顺序 + 显隐);strategies/add 联动追加 tab;strategies/remove 联动删除 tab;废弃 strategies/move; +3. **客户端注册**(client/index.js):合并为统一注册,读 tabs 数组(order 排序 + visible 过滤),移除硬编码 order; +4. **设置页 UI**(SettingsSection.jsx):「Tab 设置」子 tab(混排 + 徽标 + 显隐开关 + 拖动排序)+ 策略分组瘦身(仅 新增/重命名/删除 + 指引提示)。 + +## 讨论过程 + +- 2026-09-02 老师提出需求:设置页默认几个 tab 与策略 tab 一起排序,内置标记、不可重命名/删除; +- 2026-09-02 AI 分析现状(两套数据/两套 order 空间),提出统一 tabs 有序数组方案; +- 2026-09-02 老师确认 D1-D7:Tab 设置只做 显示/隐藏 + 排序(拖动),策略命名/删除留策略分组; +- 2026-09-02 老师确认 Q1-Q5:拖动落点立即持久化 / 新增追加末尾 / 旧隐藏策略迁移后显示 / 名称 join 自动跟随 / 全部 tab 禁重命名删除,R-011 定稿。 + +## 对老师的配合需求 + +- 验收时验证:拖动排序落点立即生效(刷新后 tab 栏按新顺序);显隐开关切换后刷新生效;策略分组瘦身后的新增/重命名/删除仍正常;老配置自动迁移无报错。 diff --git a/docs/04-迭代记录/09-Tab设置统一管理/验收标准.md b/docs/04-迭代记录/09-Tab设置统一管理/验收标准.md new file mode 100644 index 0000000..f495a4c --- /dev/null +++ b/docs/04-迭代记录/09-Tab设置统一管理/验收标准.md @@ -0,0 +1,26 @@ +# 验收标准:09-Tab 设置统一管理 + +> 迭代编号:09 | 依据:PLAN-010 验收要点 + R-011 定稿 + +## 验收标准线 + +1. 「通用设置」子 tab 更名为「Tab 设置」,表格混排内置 + 策略全部 tab; +2. 内置行带「内置」徽标、策略行带「策略」徽标; +3. 每行可拖动排序,落点**立即持久化**(刷新后会话 tab 栏按新顺序,内置与策略可交错); +4. 每行有显示/隐藏开关,切换立即持久化(刷新后隐藏的 tab 消失/显示的出现); +5. **任何行均无重命名/删除按钮**; +6. 策略分组子 tab 只留 新增/重命名/删除,无排序箭头/显隐开关,有指引提示; +7. 新增策略出现在 Tab 设置列表末尾;删除策略后对应 tab 条目消失(份额回未分配沿用); +8. 老配置(布尔对象 tabs + 策略 order/visible)读取自动归一化,无报错、无数据丢失; +9. 会话 tab 栏按新顺序与显隐注册; +10. 现有功能不回归(全部持仓/交易记录/策略持仓/QMT 切换/删除策略份额回退)。 + +## 验收方法 + +- 构建:pnpm run build + typecheck 通过; +- 单元/回归脚本:独立数据目录跑策略 CRUD + tabs 读写(技术约束-011); +- 手动(需 DSH 运行 + 老师确认):设置页 Tab 设置拖动排序 / 显隐切换 / 策略分组瘦身 / 老配置迁移;会话 tab 栏顺序与显隐验证。 + +## 验收目标 + +- 全部 10 条验收标准线通过,迭代 09 标记「验收通过」,R-011 实现状态更新,归档流程走查。 diff --git a/docs/04-迭代记录/10-UI主题适配/技术实现方案.md b/docs/04-迭代记录/10-UI主题适配/技术实现方案.md new file mode 100644 index 0000000..5bd9e78 --- /dev/null +++ b/docs/04-迭代记录/10-UI主题适配/技术实现方案.md @@ -0,0 +1,43 @@ +# 技术实现方案:10-UI 适配 DSH 主题 + +> 迭代编号:10 | 依据:PLAN-011、R-012 + +## 1. 主题机制(已查明) + +- 宿主深色主题挂 `body[data-ds-dark-theme]`; +- 宿主注入 `--dsw-*` CSS 变量(定义在宿主 runtime,随 light/dark/system 切换); +- 插件内联 style 直接引用 `var(--dsw-alias-xxx)` 即可自动适配。 + +## 2. 语义映射(实施基准,来自 R-012) + +``` +背景: #fff(表面) → var(--dsw-alias-bg-layer-1) +遮罩: rgba(0,0,0,.4) → var(--dsw-alias-bg-mask-1) +hover面: #f5f5f5 → var(--dsw-alias-interactive-bg-hover) +激活绿底: #e8f5e9/#f1f8f2 → color-mix(in srgb, var(--dsw-alias-state-success-primary) 10%, transparent) +错误红底: #fdecea → color-mix(in srgb, var(--dsw-alias-state-error-primary) 10%, transparent) +信息蓝底: #e3f2fd → color-mix(in srgb, var(--dsw-alias-state-business-primary) 10%, transparent) +主文字: #333/#222 → var(--dsw-alias-label-primary) +次文字: #555/#666 → var(--dsw-alias-label-secondary) +弱文字: #888/#999/#aaa → var(--dsw-alias-label-tertiary) +蓝字: #1565c0 → var(--dsw-alias-state-business-primary) +细线: #eee → var(--dsw-alias-border-l1) +描边: #ddd/#ccc → var(--dsw-alias-border-l2) +红(涨/错/删): #d32f2f/#c62828 → var(--dsw-alias-state-error-primary) +绿(跌/成/主): #2e7d32 → var(--dsw-alias-state-success-primary) +实心按钮字: #fff → var(--dsw-alias-button-contrast-fill) +``` + +## 3. 替换细则 + +- 替换范围:inline style 对象、模板字符串中的颜色字面量; +- `color-mix(in srgb, var(--xxx) 10%, transparent)` 用于需要「淡底 + 文字同色」的提示/激活态; +- 带透明度的原色(如 rgba(255,215,0,.5) 价格闪动高亮)保留动画语义,改 `color-mix(in srgb, var(--dsw-alias-state-warn-primary) 50%, transparent)`; +- 注释中色值仅作说明可保留(不影响运行,验收时以无运行色为准); +- 每文件替换后 `node --check` 校验 JSX 语法。 + +## 4. 风险 + +- **语义偏差**:个别颜色无法精确定位语义 → 保留原色并在验收清单标注,交老师确认; +- **color-mix 兼容性**:现代浏览器(Chrome 111+/Safari 16.2+)支持,DSH 目标为 Chromium 系,可接受; +- **fallback**:`var(--xxx, <原色>)` 提供兜底,宿主 token 缺失时视觉不变(更安全)。 diff --git a/docs/04-迭代记录/10-UI主题适配/迭代复盘.md b/docs/04-迭代记录/10-UI主题适配/迭代复盘.md new file mode 100644 index 0000000..2faedf4 --- /dev/null +++ b/docs/04-迭代记录/10-UI主题适配/迭代复盘.md @@ -0,0 +1,38 @@ +# 迭代复盘:10-UI 适配 DSH 主题(浅色 / 深色 / 跟随系统) + +> 复盘日期:2026-09-02 | 迭代状态:**已完成(老师确认)** +> 关联需求:R-012(UI 适配 DSH 主题,已定稿:暂定跟随系统) +> 关联计划:PLAN-011(计划-UI主题适配) + +## 结果 + +迭代 10 达成:神之一手客户端 11 个文件共 141 处硬编码颜色全部替换为宿主 `--dsw-*` token(含 fallback),插件在 DSH 浅色 / 深色 / 跟随系统主题下自动适配;不自行维护主题偏好(跟随宿主);仅色值 token 化,布局与交互不变。 + +## 过程事实 + +1. **需求定稿(R-012)**:老师提出适配 DSH 浅/深/系统主题 → AI 查明宿主机制(body[data-ds-dark-theme] + --dsw-* token,深色挂 data-ds-dark-theme、alias token 双值定义)→ 老师确认「暂定跟随系统」(D1-D5 + 语义映射表); +2. **替换实施**:PriceCell / LoadState / Toast / PlaceholderTab / RangeSelector / AllPositionsTab / StrategyTab / TradeRecordsTab / QmtConnectionChip / SettingsSection 共 10 文件(+market 目录无颜色); +3. **语义映射执行**:白底→bg-layer-1、淡灰底→bg-layer-2、hover→interactive-bg-hover、主/次/弱文字→label-primary/secondary/tertiary、边框→border-l1/l2/l3/l4、红(涨/删/错)→state-error-primary、绿(跌/成/激活)→state-success-primary、蓝(信息/业务)→state-business-primary、实心按钮字→button-contrast-fill、遮罩→bg-mask-1、阴影→shadow-lv3; +4. **淡色底**:激活/提示底色用 color-mix(in srgb, var(--语义色) 10-12%, transparent),深浅主题自适应; +5. **验证**:typecheck + build 通过;headless Chrome 实证宿主 token 系统完整(238 处 dsw-alias 引用、浅/深双值定义、data-ds-dark-theme 选择器);残留硬编码色 = 0。 + +## 经验教训(复盘沉淀) + +### 1. 宿主主题机制:body[data-ds-dark-theme] + --dsw-* token(已实证) +- DSH 主题不是 data-theme 属性切换,而是宿主在深色时给 body 挂 `data-ds-dark-theme`,token 以「alias 链 → static 值」双主题注入(light: neutral-bluish-00 白系;dark: neutral-bluish-875 深系); +- **沉淀**:插件适配宿主主题只须引用 `var(--dsw-alias-xxx, fallback)`,fallback 保证 token 缺失时浅色可用;不要自建主题偏好。 + +### 2. var() 带 fallback 是安全的迁移策略 +- 每处替换写成 `var(--dsw-alias-xxx, #原色)`:宿主 token 定义齐全时自动适配;万一某 token 缺失(宿主版本差异),退回原浅色值不破相; +- **沉淀**:对宿主 token 的依赖一律带 fallback,兼容宿主版本演进。 + +### 3. 批量替换的 edit 冲突处理 +- 多个相同 style 片段(如表头、输入框、删除按钮)导致 old_string 多处匹配:用 replace_all 处理真正相同的模式,或用带上下文的更精确 old_string; +- **沉淀**:批量替换前先 grep 去重确认唯一性,相同模式直接用 replace_all,不同上下文逐条处理。 + +## 遗留/后续 + +1. **语义色待老师验收**:深色下个别语义色(state-error 红 / state-success 绿在深色底的对比度、紫/蓝徽标)观感需老师切主题确认;若个别不满意可后续加 `--odl-*` 覆盖(D5 暂缓项); +2. **color-mix 兼容性**:现代 Chromium 支持;若遇旧内核浏览器个别淡底失效,fallback 无(color-mix 无 fallback 语法)——可后续降级处理; +3. **Toast 样式**:随宿主语义色变化,实心绿/红底 + 白字在深色下对比度已由 token 保证; +4. **shadows**:boxShadow 用了 shadow-lv3 token(宿主完整 shadow 值),个别较浅卡片阴影在深色下可能几乎不可见——可后续微调。 diff --git a/docs/04-迭代记录/10-UI主题适配/迭代目标.md b/docs/04-迭代记录/10-UI主题适配/迭代目标.md new file mode 100644 index 0000000..041e9b2 --- /dev/null +++ b/docs/04-迭代记录/10-UI主题适配/迭代目标.md @@ -0,0 +1,18 @@ +# 迭代目标:10-UI 适配 DSH 主题(浅色 / 深色 / 跟随系统) + +> 迭代编号:10 | 创建:2026-09-02 | 状态:进行中 +> 依据计划:PLAN-011 | 需求:R-012(已定稿,2026-09-02,暂定跟随系统) + +## 目标描述 + +神之一手客户端 UI 全部硬编码色值替换为宿主 `--dsw-*` token,使插件在 DSH 浅色 / 深色 / 跟随系统主题下均可读、协调,随主题自动切换。 + +## 目标分解 + +1. 10 个文件 141 处硬编码色按语义映射替换为宿主 token / color-mix; +2. 涨跌红涨绿跌 → 宿主 state-error/success;主按钮/徽标/提示底色 → 宿主语义色; +3. 构建 + typecheck + 深浅主题人工验收。 + +## 对老师的配合需求 + +- 验收:DSH 设置切换 浅色/深色/跟随系统,检查各页面可读性与协调性。 diff --git a/docs/04-迭代记录/10-UI主题适配/验收标准.md b/docs/04-迭代记录/10-UI主题适配/验收标准.md new file mode 100644 index 0000000..2f0cde7 --- /dev/null +++ b/docs/04-迭代记录/10-UI主题适配/验收标准.md @@ -0,0 +1,22 @@ +# 验收标准:10-UI 适配 DSH 主题 + +> 迭代编号:10 | 依据:PLAN-011 验收要点 + R-012 + +## 验收标准线 + +1. 浅色主题下插件各页面观感与现状基本一致(无突兀色差); +2. 深色主题下所有页面可读(背景/文字/边框/按钮/涨跌/徽标/提示/下拉菜单协调); +3. DSH 设置切换 浅色/深色/跟随系统 实时生效; +4. 涨跌色(红涨绿跌)在深浅两主题下均醒目可辨; +5. 运行代码无残留硬编码色(#xxx / rgb / rgba),注释可留; +6. 布局与交互不变(仅色值); +7. build + typecheck 通过。 + +## 验收方法 + +- build + typecheck; +- 老师切 DSH 浅/深主题人工检查:设置页(Tab 设置/策略分组/QMT 卡片)、全部持仓、交易记录、策略持仓、会话头部 QMT chip 下拉、Toast。 + +## 验收目标 + +- 7 条验收线通过,迭代 10 标记「验收通过」,R-012 更新实现状态。 diff --git a/docs/05-需求池/R-011.md b/docs/05-需求池/R-011.md new file mode 100644 index 0000000..99c38ce --- /dev/null +++ b/docs/05-需求池/R-011.md @@ -0,0 +1,70 @@ +# R-011 Tab 设置:统一管理所有 tab(内置 + 策略分组混排,显示/隐藏 + 拖动排序) + +> 状态:**已定稿**(2026-09-02,老师确认 Q1-Q5)| 登记日期:2026-09-02 +> 来源:老师指令(2026-09-02,设置页 tab 化扩展的二次演进) +> 优先级:P1(设置体验优化,无数据风险) + +## 需求描述 + +设置页的「通用设置」子 tab 升级为 **「Tab 设置」**,成为**统一管理所有会话 tab(系统内置 + 策略分组)的唯一入口**:两类 tab 混排在一张表里,每行提供**显示/隐藏开关** + 通过**拖动**调整顺序;**任何 tab 都不支持重命名与删除**(策略的命名/删除仍在「策略分组」子 tab,内置 tab 名称只读)。 + +## 现状(代码审查 2026-09-02) + +| 项 | 现状 | +|---|---| +| 内置 tab | client/index.js 的 GENERAL_TABS 硬编码 order 10/11/12(全部持仓/交易记录/关注列表),注册时排在策略之前,**不可与策略交错** | +| 策略 tab | settings.strategies 数组 {id,name,visible,order},注册时按 order 排序、从 order 13 起(永远在内置之后) | +| 显隐控制 | settings.tabs 布尔对象 {allPositions,tradeRecords,watchlist}(通用设置三个开关)+ 策略各自 visible | +| 排序交互 | 「策略分组」子 tab 用 ↑↓ 上下箭头移动策略 | + +**结构性障碍**:两套数据、两套 order 空间(内置 10/11/12,策略 13+),内置永远在策略前,无法混合拖动。 + +## 讨论结论(2026-09-02 老师确认) + +- **D1** 策略的「命名」和「删除」**不归 Tab 设置管**:仍在「策略分组」子 tab 操作;「策略分组」里原来的 ↑↓ 排序箭头与显隐开关移除(被 Tab 设置取代)。 +- **D2** 子 tab 名称 = **「Tab 设置」**(不是「特指」);管理对象 = 系统内置 tab(标记「内置」)+ 策略分组 tab(标记「策略」),两类混排。 +- **D3** 策略侧**同步变更**:顺序与显隐统一为**一份数据源**(tabs 有序数组);策略分组 tab 的展示与 Tab 设置完全一致;删除策略时**联动删除**统一列表中的对应条目。 +- **D4** 顺序调整用**拖动**(原生 HTML5 Drag & Drop,零新依赖),不用上下箭头;**落点确认后立即持久化**(Q1)。 +- **D5**(2026-09-02 Q5 修订,原「去掉显隐开关」作废)**Tab 设置只含「显示/隐藏 + 排序」**:所有 tab(内置 + 策略)均有显隐开关与拖动排序;**任何 tab 均不支持重命名与删除**(Q5)。 +- **D6** 老配置**自动迁移**:现网 tabs 布尔对象 + 策略自带 order/visible → 启动时静默归一化为统一数组,无需用户操作。 +- **D7** 隐藏边界:接受「没有任何神之一手 tab」的状态(全部隐藏时会话窗不显示任何神之一手 tab,不视为异常)。 + +## 目标数据模型(定稿) + +统一 settings.tabs 为**有序数组**(唯一顺序与显隐来源;策略行名称来自 strategies join,自动跟随改名): + +```js +// settings.tabs(定稿) +tabs: [ + { id: 'tab-all-positions', kind: 'builtin', refKey: 'allPositions', name: '全部持仓', visible: true, order: 0 }, + { id: 'tab-trade-records', kind: 'builtin', refKey: 'tradeRecords', name: '交易记录', visible: true, order: 1 }, + { id: 'tab-watchlist', kind: 'builtin', refKey: 'watchlist', name: '关注列表', visible: true, order: 2 }, + { id: 'tab-strategy-grid-supermarket', kind: 'strategy', refId: 'grid-supermarket', name: '网格超市', visible: true, order: 3 }, + { id: 'tab-strategy-manual-t', kind: 'strategy', refId: 'manual-t', name: '手动做T', visible: true, order: 4 }, +] +// strategies 收窄为定义表:{ id, name }(无 visible / order) +``` + +- 内置行的 name 与常量对齐(防漂移),策略行的 name 来自 strategies join(改名自动跟随,因为只存 refId,Q4); +- **迁移规则**(D6 + Q3):旧 tabs 布尔对象 → 生成三个内置条目(**保留原显隐**);旧策略按各自 order 接续追加为策略条目,**旧隐藏的策略迁移后变为显示**(visible=true,Q3); +- 新增策略**追加到列表末尾**(Q2)。 + +## 涉及改动面(技术方案,定稿) + +1. **src/settings.js**:tabs 从布尔对象 → 有序数组;新增读取归一化(旧格式自动转新)+ 整表更新(order + visible);strategies 相关函数收窄(去掉 visible/order 语义);DEFAULT_TABS 升级为默认顺序数组。 +2. **src/api/strategies.js**:tabs/update 语义改为整表更新(顺序 + 显隐,拖动落点/开关切换各提交一次);strategies/add 联动追加 tab 条目(末尾);strategies/remove 联动删除对应 tab 条目(D3);废弃 strategies/move;strategies/update 仅剩重命名。 +3. **src/client/index.js**:合并 registerGeneralTabs + registerStrategyTabs 为统一注册(读 tabs 数组按 order 排序、过滤 visible,builtin 走内置 render、strategy 走 StrategyTab),去掉 10/11/12 与 13+ 硬编码间隔。 +4. **src/client/views/SettingsSection.jsx**: + - 「Tab 设置」子 tab 取代「通用设置」:表格列出全部 tab(内置行带「内置」徽标、策略行带「策略」徽标),每行 = 拖动手柄 + 名称 + **显隐开关**;**无重命名/删除按钮(任何行)**; + - 拖动:draggable + onDragStart/onDragOver/onDrop,落点重排 → 立即调 tabs/update 持久化(Q1)→ 刷新(沿用「刷新页面后生效」机制); + - 「策略分组」子 tab 瘦身:只留 新增策略 / 重命名 / 删除(删除确认弹窗 + 份额回未分配沿用),移除排序箭头与显隐开关,加提示「顺序与显示请在「Tab 设置」中调整」。 + +## 定稿记录(Q1-Q5,2026-09-02 老师确认) + +- **Q1** 拖动落点确认后**立即持久化**(每次 drop 提交整表)→ 确认。 +- **Q2** 新增策略默认**追加到列表末尾** → 确认。 +- **Q3** 迁移时旧「隐藏」的策略**变为显示**(visible=true)→ 确认。 +- **Q4** 策略改名后 Tab 设置中的名称**自动跟随**(join strategies);Tab 设置不支持改名,策略名称在「策略分组」改 → 确认。 +- **Q5** Tab 设置中只有**显示/隐藏 + 排序**,**全部 tab 都不支持重命名与删除** → 确认(同时修订 D5:显隐开关保留)。 + +> 三要素满足(边界清楚 / 核心逻辑明确 / 老师确认 Q1-Q5),**已定稿**,可进入计划范围。 diff --git a/docs/05-需求池/R-012.md b/docs/05-需求池/R-012.md new file mode 100644 index 0000000..1ab290c --- /dev/null +++ b/docs/05-需求池/R-012.md @@ -0,0 +1,46 @@ +# R-012 UI 适配 DSH 主题(浅色 / 深色 / 跟随系统) + +> 状态:**已定稿(暂定:跟随系统,语义色映射可再调)**(2026-09-02,老师确认方向「暂定跟随系统」)| 登记日期:2026-09-02 +> 来源:老师指令(2026-09-02) +> 优先级:P1(UI 体验) + +## 需求描述 + +神之一手插件 UI 适配 DSH 的浅色 / 深色 / 跟随系统主题:将客户端全部硬编码颜色替换为宿主主题 token(`--dsw-*` CSS 变量),插件各页面随 DSH 主题切换自动适配,不自行维护主题偏好(跟随宿主)。 + +## 现状(代码审查 2026-09-02) + +- 客户端 10 个文件共 **141 处硬编码颜色**:SettingsSection.jsx 55 / StrategyTab.jsx 24 / TradeRecordsTab.jsx 21 / QmtConnectionChip.jsx 13 / RangeSelector.jsx 7 / PriceCell.jsx 5 / AllPositionsTab.jsx 4 / LoadState.jsx 3 / Toast.jsx 2 / PlaceholderTab.jsx 1; +- 宿主机制(已查明):深色主题时宿主挂 `body[data-ds-dark-theme]`,并注入 `--dsw-*` token(`--dsw-alias-bg-base/layer-1/layer-2`、`label-primary/secondary/tertiary/caption`、`border-l1..l4`、`state-success/error/business-primary`、`brand-primary`、`button-primary-fill/hover`、`button-contrast-fill`、`interactive-bg-hover/active`、`bg-mask-1`、`tooltip-bg` 等),随 light/dark/system 自动切换; +- 先例:QmtConnectionChip 部分样式已引用 `var(--dsw-alias-label-secondary, #666)`,token 可用。 + +## 决策(2026-09-02 老师确认:暂定跟随系统) + +- **D1** 主题偏好跟随宿主(light/dark/system),插件不自行监听/维护; +- **D2** 全部颜色映射到宿主 `--dsw-*` token(语义映射表见下);涨跌色 A 股红涨绿跌 → 宿主语义:涨=红=`state-error-primary`、跌=绿=`state-success-primary`(宿主在深浅主题下保证可读); +- **D3** 实心主按钮 / 徽标 / 提示底色等语义色(success/error/business)跟随宿主对应 token;淡色底用 `color-mix(in srgb, 10%, transparent)` 跟随主题; +- **D4** 仅做色值 token 化(最小改动),不动布局 / 间距 / 圆角; +- **D5** 若宿主 token 观感不满意,后续可加插件级 `--odl-*` 覆盖变量(本迭代不做,暂定)。 + +## 语义映射表(实施基准) + +| 原色 | 语义 | 替换 | +|---|---|---| +| #fff(表面底) | 表格/卡片/弹窗/输入框/菜单/按钮白底 | var(--dsw-alias-bg-layer-1) | +| rgba(0,0,0,.4)(遮罩) | 弹窗遮罩 | var(--dsw-alias-bg-mask-1) | +| #f5f5f5(hover/静态行底) | 次级面/hover | var(--dsw-alias-interactive-bg-hover) 或 bg-layer-2(静态) | +| #e8f5e9/#f1f8f2(激活浅绿底) | 选中/激活 | color-mix(in srgb, var(--dsw-alias-state-success-primary) 10%, transparent) | +| #fdecea(错误浅红底) | 错误提示底 | color-mix(in srgb, var(--dsw-alias-state-error-primary) 10%, transparent) | +| #e3f2fd(信息浅蓝底) | 信息提示底 | color-mix(in srgb, var(--dsw-alias-state-business-primary) 10%, transparent) | +| #333/#222 | 主文字 | var(--dsw-alias-label-primary) | +| #555/#666 | 次文字 | var(--dsw-alias-label-secondary) | +| #888/#999/#aaa | 弱文字/caption | var(--dsw-alias-label-tertiary) | +| #1565c0(蓝字) | 业务/信息字 | var(--dsw-alias-state-business-primary) | +| #eee(细线) | 行分隔/表头细线 | var(--dsw-alias-border-l1) | +| #ddd/#ccc(描边/强调) | 控件描边/分隔 | var(--dsw-alias-border-l2) | +| #90caf9/#ce93d8(徽标淡描边) | 徽标描边 | var(--dsw-alias-border-l3)(描边中性化,文字保留语义色) | +| #d32f2f/#c62828(红字/实心红) | 涨/错误/删除/危险 | var(--dsw-alias-state-error-primary);实心底同上,文字 var(--dsw-alias-button-contrast-fill) | +| #2e7d32(绿字/实心绿) | 跌/成功/激活/主按钮 | var(--dsw-alias-state-success-primary);实心底同上,文字 var(--dsw-alias-button-contrast-fill) | +| #fff(实心按钮上文字) | 按钮文字 | var(--dsw-alias-button-contrast-fill) | + +> 实施细则:仅 inline style / 变量赋值中的颜色字面量替换;注释中的色值可保留或同步(不影响运行);个别语义不确定处保留原色并在迭代记录中列出待老师验收。 diff --git a/docs/05-需求池/需求池索引.md b/docs/05-需求池/需求池索引.md index 6592d5a..70c0199 100644 --- a/docs/05-需求池/需求池索引.md +++ b/docs/05-需求池/需求池索引.md @@ -22,6 +22,8 @@ | R-008 | 数据存储管理(JSON → SQLite) | 数据存储从 JSON data store 升级为 SQLite(node:sqlite):仅存储引擎替换 + strategies/allocation/market_quotes 三表 + 一次性迁移脚本(启动自动迁移)+ JSON 废弃;策略仍存 DSH settings;不建 trades 表(R-007 时再建)。**2026-09-01 定稿(T-008 转正,D1-D8 确认),2026-09-01 完成(迭代 06 验收通过),已归档至 已完成/R-008.md** | 老师指令(2026-09-01,T-008 转正) | P1 | 已定稿 | 2026-09-01 | 06-数据存储SQLite | **已实现(已归档)** | | R-009 | 交易记录本地存储(SQLite)+ 策略关联 | 在 SQLite 新增交易记录表(trade_orders + trade_fills,委托/成交两表),QMT 当日交易数据本地持久化(跨日积累成历史库);**归属由用户在交易记录 tab 手动设置(trade_orders 冗余存 strategy_id + holding_id,UPSERT 不覆盖归属列,可随时改)**;本地历史查询端点(trades/history 策略过滤)+ 交易记录 tab 策略过滤与历史范围本地展示;QMT code 归一化 + tradeDate 兜底。**2026-09-01 定稿(Q1-Q8 + 二次定稿 Q1-Q4),2026-09-01 完成(迭代 07 验收通过),已归档至 已完成/R-009.md** | 老师指令(2026-09-01) | P1 | 已定稿 | 2026-09-01 | 07-交易记录本地存储SQLite与策略关联 | **已实现(已归档)** | | R-010 | 策略持仓行展开关联交易记录(Holding → 交易汇总) | 策略持仓 tab 每个持仓行(Holding)可展开,展开显示与该 holding 关联的交易记录(仅委托汇总,不分笔成交);strategy-positions 附加 holding_id + 新增 trades/by-holding 端点 + 持仓行展开 UI + 成本价/最后一笔成交价两列 + 神之一手 tab 隐藏输入框。**2026-09-02 定稿(Q1-Q4 确认),2026-09-02 完成(老师确认),已归档至 已完成/R-010.md** | 老师指令(2026-09-02) | P1 | 已定稿 | 2026-09-02 | 08-策略持仓行展开关联交易记录 | **已实现(已归档)** | +| R-011 | Tab 设置:统一管理所有 tab(内置 + 策略分组混排,显示/隐藏 + 拖动排序) | 设置页「通用设置」升级为「Tab 设置」,统一管理所有会话 tab(系统内置 + 策略分组)的唯一入口:两类混排、**拖动排序**(原生 HTML5 DnD,落点立即持久化)+ **显隐开关**;**任何 tab 均不支持重命名/删除**(策略命名/删除仍在「策略分组」子 tab);顺序/显隐统一为一份数据源(tabs 有序数组,策略行名 join strategies 自动跟随改名),删除策略联动删除对应条目;新增策略追加末尾;老配置自动迁移(旧隐藏策略迁移后显示)。**2026-09-02 定稿(Q1-Q5 确认)并完成(迭代 09 验收通过)**,详见 docs/05-需求池/R-011.md | 老师指令(2026-09-02) | P1 | 已定稿 | 2026-09-02 | 09-Tab设置统一管理 | **已实现(迭代 09 完结)** | +| R-012 | UI 适配 DSH 主题(浅色 / 深色 / 跟随系统) | 神之一手 UI 适配 DSH 浅色/深色/跟随系统主题:141 处硬编码色值替换为宿主 `--dsw-*` token,随主题自动切换;不自行维护主题偏好(**暂定跟随系统**);涨跌红涨绿跌 → 宿主 state-error/success;仅色值 token 化不动布局。**2026-09-02 定稿(暂定跟随系统)并完成(迭代 10)**,详见 docs/05-需求池/R-012.md | 老师指令(2026-09-02) | P1 | 已定稿 | 2026-09-02 | 10-UI主题适配 | **已实现(迭代 10 完结)** | ## 渐进明细规划素材