Files
kyugao a4902bb730 feat(R-013+重构): 策略自定义字段需求文档 + 结构归类优化
需求与文档:
- R-013 策略自定义字段配置(定义随策略 configSchema 存 settings、值落
  strategy_holdings.values JSON、类型化文本/数字/布尔/枚举)定稿并进入
  PLAN-012 / 迭代 11(含目标数据模型 + 端到端示例 + 技术方案 + 验收标准)
- R-011(Tab设置)/ R-012(UI主题适配)归档至 已完成/,索引标记已归档
- 沉淀约束: 产品约束-010 / 技术约束-015 / 技术约束-016 / UI约束-005

结构重构(技术约束-016):
- src/component/ 平铺还原为语义分域目录: data-source/ storage/ position/
  market/ trades/(git rename 保留历史)
- 清理死代码: 删除 AllocationStorage.js(0 引用)、DataStore
  setDataset/removeDataset(无调用方)
- 同步更新 src/index.js / scripts/*.mjs / tsdown.config.ts 引用
- typecheck + build + test-r009 回归 14/14 通过
2026-09-02 15:38:51 +08:00

80 lines
6.9 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.
# R-011 Tab 设置:统一管理所有 tab(内置 + 策略分组混排,显示/隐藏 + 拖动排序) · 已完成
> 归档日期:2026-09-02 需求状态:**已完成**
> 原索引:docs/05-需求池/需求池索引.md(主索引保留 R-011 条目,指向本归档)
> 实现迭代:09-Tab设置统一管理(验收通过,迭代复盘见 docs/04-迭代记录/09-Tab设置统一管理/迭代复盘.md)
> 讨论记录:2026-09-02 定稿(Q1-Q5 老师确认);实现见迭代 09 技术实现方案/复盘
---
> 状态:**已定稿**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=trueQ3);
- 新增策略**追加到列表末尾**(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/movestrategies/update 仅剩重命名。
3. **src/client/index.js**:合并 registerGeneralTabs + registerStrategyTabs 为统一注册(读 tabs 数组按 order 排序、过滤 visiblebuiltin 走内置 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-Q52026-09-02 老师确认)
- **Q1** 拖动落点确认后**立即持久化**(每次 drop 提交整表)→ 确认。
- **Q2** 新增策略默认**追加到列表末尾** → 确认。
- **Q3** 迁移时旧「隐藏」的策略**变为显示**(visible=true)→ 确认。
- **Q4** 策略改名后 Tab 设置中的名称**自动跟随**join strategies);Tab 设置不支持改名,策略名称在「策略分组」改 → 确认。
- **Q5** Tab 设置中只有**显示/隐藏 + 排序**,**全部 tab 都不支持重命名与删除** → 确认(同时修订 D5:显隐开关保留)。
> 三要素满足(边界清楚 / 核心逻辑明确 / 老师确认 Q1-Q5),**已定稿**,可进入计划范围。