refactor(selection): replace concept sector filter with sub-industry
- pin the selection sector vocabulary to industry: the /sectors endpoint no longer accepts sector_type, and the port, adapter, and use case all resolve counts and member codes with sector_type="industry" - relabel the results filter to 细分行业 and drop concept-type plumbing from the frontend API, query keys, and types - show only 细分行业 in the signal detail panel; remove the concept-board chips and keep the snapshot-date tooltip on the industry line - update backend and frontend tests to the industry vocabulary and record the revised scope in the task PRD
This commit is contained in:
@@ -1,40 +1,43 @@
|
||||
# 选股页面迭代:布局重构与板块筛选
|
||||
# 选股页面迭代:布局重构与细分行业筛选
|
||||
|
||||
## 需求
|
||||
|
||||
1. 选股页面从左右布局改为「上搜索栏 + 左列表 / 右详情」三段式布局。
|
||||
2. 搜索模块增加板块筛选:下拉选项为当次策略结果的板块聚合,选项旁展示数量,按数量倒序。
|
||||
2. 搜索模块增加细分行业筛选:下拉选项为当次策略结果的细分行业聚合,选项旁展示数量,按数量倒序。
|
||||
3. 选股模块不展示「板块」(概念板块):列表筛选与详情页均去掉;详情页「行业」口径改称「细分行业」。(2026-09-05 修订,原口径为概念板块)
|
||||
|
||||
## 关键决策
|
||||
|
||||
- 板块口径:概念板块(sector_type=concept),与详情面板「板块」标签一致;接口保留 sector_type 参数可扩展行业。
|
||||
- 板块口径:细分行业(sector_type=industry,即东财行业快照),selection 上下文固定为 industry——HTTP `/sectors` 不再接受 sector_type 参数,端口/适配器默认值均为 industry;「细分行业」仍是 sector 词汇的一种,内部参数名保持 `sector` 不变。
|
||||
- 单选下拉;排序按 stock_count 倒序(后端保证),名称升序 tie-break。
|
||||
- 板块数据不在 selection 表中,按 ADR 0001 通过端口委托 sector_radar 读服务(不跨上下文 join SQL)。
|
||||
- 行业数据不在 selection 表中,按 ADR 0001 通过端口委托 sector_radar 读服务(不跨上下文 join SQL)。
|
||||
|
||||
## 实现
|
||||
|
||||
后端(zhixing-server):
|
||||
- sector_radar:`domain/persistence.py` 新增 `SectorCountEntry` + 2 个协议方法;`infrastructure/postgres.py` / `infrastructure/memory.py` 实现 `load_sector_counts` / `load_sector_member_codes`;`application/read.py` 新增 `sector_counts` / `sector_member_codes`(先解析 last-good publication)。
|
||||
- selection:`domain/runs.py` 新增 `SelectionSectorReader` 端口、`SelectionSectorCount` / `SelectionSectorMembership` / `SelectionRunIdentity`,`SelectionResultQuery.sector`;`application/run.py` 新增 `list_sector_counts`,`get_run`/`get_latest` 经 identity → 成员代码 → `sector_stock_codes` 过滤;`infrastructure/postgres_runs.py` `_stock_filter` 支持 `ts_code = ANY(...)` / FALSE;`infrastructure/sector_membership.py` 桥接适配器;`presentation/http.py` 新增 `GET /sectors`,results/runs 增加 `sector` 参数。
|
||||
- selection:`domain/runs.py` 新增 `SelectionSectorReader` 端口、`SelectionSectorCount` / `SelectionSectorMembership` / `SelectionRunIdentity`,`SelectionResultQuery.sector`;`application/run.py` 新增 `list_sector_counts`(固定 industry),`get_run`/`get_latest` 经 identity → 成员代码 → `sector_stock_codes` 过滤;`infrastructure/postgres_runs.py` `_stock_filter` 支持 `ts_code = ANY(...)` / FALSE;`infrastructure/sector_membership.py` 桥接适配器;`presentation/http.py` 新增 `GET /sectors`,results/runs 增加 `sector` 参数。
|
||||
|
||||
前端(zhixing-web):
|
||||
- `selection.types.ts` / `selection.api.ts` / `selection.query.ts`:`SelectionSectors`、`getSelectionResultSectors`、`useSelectionResultSectors`,query key 加 sector,结果失效同时失效 sectors。
|
||||
- `selection.types.ts` / `selection.api.ts` / `selection.query.ts`:`SelectionSectors`(sector_type 收窄为 "industry")、`getSelectionResultSectors`、`useSelectionResultSectors`(不传 sector_type),query key 加 sector,结果失效同时失效 sectors。
|
||||
- `route-tree.tsx`:selection 路由 search 增加 `sector`。
|
||||
- `selection-results-page.tsx`:结果查询带 sector,页面调用 sectors hook 并下传 workbench;切策略重置 sector。
|
||||
- `selection-results-workbench.tsx`:布局重构为上搜索栏 + 下方 320px 列表/详情两栏;板块下拉(全部板块 + 聚合选项带数量徽标);聚合加载后自动清掉失效 sector。
|
||||
- `selection-results-workbench.tsx`:布局重构为上搜索栏 + 下方 320px 列表/详情两栏;细分行业下拉(全部细分行业 + 聚合选项带数量徽标);聚合加载后自动清掉失效 sector。
|
||||
- `signal-detail-panel.tsx`:展示「细分行业:…」(title 提示成分快照日期),不再展示概念板块 chips。
|
||||
|
||||
## 测试
|
||||
|
||||
- 后端:`test_read.py` +8、`test_sector_filter.py` 新建 9 个、`test_selection_http.py` +5。
|
||||
- 前端:页面测试新增「filters by sector and shows per-sector counts」。
|
||||
- 后端:`test_read.py` +8、`test_sector_filter.py` 新建 9 个(口径 industry)、`test_selection_http.py` +3(不再有 sector_type 转发/422 用例)。
|
||||
- 前端:页面测试新增「filters by sub-industry and shows per-industry counts」;详情面板测试改为细分行业断言并删除概念 chips 用例。
|
||||
|
||||
## 验收
|
||||
|
||||
- [x] 页面布局为上搜索栏 + 左列表右详情(移动端纵向堆叠 搜索→列表→详情)
|
||||
- [x] 板块下拉选项为当次策略结果的概念板块聚合,选项旁展示数量,按数量倒序
|
||||
- [x] 选择板块后结果列表服务端过滤,`筛选结果 N 只` 反映叠加计数
|
||||
- [x] 细分行业下拉选项为当次策略结果的细分行业聚合,选项旁展示数量,按数量倒序
|
||||
- [x] 选择细分行业后结果列表服务端过滤,`筛选结果 N 只` 反映叠加计数
|
||||
- [x] 详情面板只展示细分行业,不展示概念板块
|
||||
- [x] 后端 ruff/pyright/pytest 与前端 lint/typecheck/test/build 门禁通过(遗留项均为基线原有)
|
||||
|
||||
## 遗留(均为基线原有,非本次引入)
|
||||
|
||||
- 后端 pyright 16 个错误(chart.py/gold_brick.py pandas 相关、test_run.py 旧 fake 类型);前端 4 个执行状态抽屉测试失败;前端 format:check 有基线未格式化文件(.playwright-cli、sector-radar 部分文件、signal-detail-panel.tsx)。
|
||||
- 后端 pyright 16 个错误(chart.py/gold_brick.py pandas 相关、test_run.py 旧 fake 类型);前端 4 个执行状态抽屉测试失败;前端 format:check 有基线未格式化文件(.playwright-cli、sector-radar 部分文件;signal-detail-panel.tsx 已随本次格式化移除)。
|
||||
|
||||
Reference in New Issue
Block a user