• 文件型黑灰名单前后端明确方案

      1. 页面目标

      • 黑名单页增加 动态黑名单 tab
      • 灰名单页增加 动态灰名单 tab
      • 现有长期黑名单、长期灰名单逻辑不改
      • 动态页面使用新的文件型接口

      2. 后端方案

      2.1 接口

      黑名单:

      • GET /api/file-blacklist/options/brokers
      • GET /api/file-blacklist/options/products?broker_name=...
      • GET /api/file-blacklist/options/dates?broker_name=...&product_name=...
      • POST /api/file-blacklist/query

      灰名单:

      • GET /api/file-graylist/options/brokers
      • GET /api/file-graylist/options/products?broker_name=...
      • GET /api/file-graylist/options/dates?broker_name=...&product_name=...
      • POST /api/file-graylist/query

      2.2 数据来源

      信息总览:

      • backend/data/mail_state/processed.json

      主体表格:

      • backend/data/mail_export_json/{broker}/{product}/{date}.json

      黑名单主体:

      • blacklist.signal

      灰名单主体:

      • graylist.signal

      2.3 options 实现

      brokers
      • 扫描 backend/data/mail_export_json 一级目录
      products
      • 扫描 backend/data/mail_export_json/{broker} 二级目录
      dates
      • 扫描 backend/data/mail_export_json/{broker}/{product} 下的 *.json
      • 去掉扩展名后返回日期

      2.4 query 实现

      请求参数:

      • broker_name 必填
      • product_name 必填
      • date 必填
      • stock_code 可选

      处理流程:

      1. 读取 processed.json
      2. 遍历其中所有记录
      3. 只保留成功记录
      4. 分别匹配:
        • broker_name
        • product_name
        • processed_at[:10]
      5. 如果命中多条,取 processed_at 最新的一条
      6. 从该记录中取 json_path
      7. 读取 json_path 对应的产品日期 JSON
      8. 用该记录组装 overview
      9. 用该 JSON 组装 table_rows
      10. 如果传了 stock_code,只过滤 table_rows

      规则:

      • stock_code 不参与总览记录匹配
      • json_path 只用于读取主体文件,不作为主匹配键

      2.5 黑名单返回内容

      overview 包含:

      • broker_name
      • product_name
      • processed_at
      • attachment_name
      • source_email
      • stock_count
      • excel_blacklist_unique_count
      • excel_blacklist_excluded_unique_count
      • dynamic_blacklist_unique_count
      • excel_dynamic_overlap_unique_count
      • dynamic_blacklist_only_unique_count
      • final_blacklist_unique_count

      table_rows

      • 只返回 stock_code

      2.6 灰名单返回内容

      overview 包含:

      • broker_name
      • product_name
      • processed_at
      • attachment_name
      • source_email
      • stock_count
      • excel_whitelist_unique_count
      • excel_whitelist_excluded_unique_count
      • daily_quote_stock_unique_count
      • all_stock_excel_whitelist_overlap_unique_count
      • all_stock_final_blacklist_overlap_unique_count
      • all_stock_excel_whitelist_final_blacklist_overlap_unique_count
      • excluded_from_all_stock_unique_count
      • base_graylist_unique_count
      • allowed_buy_quantity_signal_unique_count
      • base_graylist_allowed_buy_overlap_unique_count
      • allowed_buy_qty_low_non_base_unique_count
      • invalid_allowed_buy_qty_unique_count
      • final_graylist_unique_count

      table_rows

      • stock_code
      • available_buy_qty
      • avg_volume_base
      • max_allowed_position
      • today_filled_qty
      • today_pending_qty
      • total_used_capacity
      • yesterday_position

      2.7 后端组织方式

      • 公共文件搜索、路径处理、processed.json 读取放公共层
      • 黑名单单独处理自己的 overviewtable_rows
      • 灰名单单独处理自己的 overviewtable_rows

      3. 前端方案

      3.1 路由

      • 不新增主路由
      • 继续使用 /blacklist
      • 继续使用 /graylist

      3.2 页面结构

      黑名单页内部 tab:

      • 长期黑名单
      • 动态黑名单

      灰名单页内部 tab:

      • 长期灰名单
      • 动态灰名单

      动态页面统一拆成三段组件:

      • QueryForm
      • Overview
      • Table

      3.3 QueryForm

      固定只放:

      • 券商
      • 产品
      • 日期
      • 查询按钮

      3.4 Overview

      负责展示上半部分信息总览

      3.5 Table

      负责展示下半部分主体表格,并包含:

      • 股票编号搜索框
      • 搜索按钮
      • 重置按钮
      • 表格内容

      规则:

      • 股票编号搜索放在 Table 模块
      • 不放在 QueryForm

      4. 前端 API

      新增两个 API 文件:

      • fileBlacklist.js
      • fileGraylist.js

      黑名单 API:

      • brokers
      • products
      • dates
      • query

      灰名单 API:

      • brokers
      • products
      • dates
      • query

      旧 API 保持原用途,不混用。

      5. 前端 models

      5.1 上半部分配置

      每个产品单独维护一份总览字段数组,例如:

      • dynamicBlackListHuaxinMOM33 = []
      • dynamicGrayListHuaxinMOM33 = []

      这些数组里只放上半部分需要展示的字段定义。

      5.2 映射关系

      通过 mapping 做产品映射,例如:

      • dynamicBlackListMapping = [{ broker, product, List }]
      • dynamicGrayListMapping = [{ broker, product, List }]

      作用:

      • 根据 broker + product 找到当前要使用的总览字段配置

      5.3 下半部分固定列

      主体表格列不跟产品走,直接固定:

      • dynamicBlackListTableColumns
      • dynamicGrayListTableColumns

      含义:

      • 黑名单下半部分固定只展示 stock_code
      • 灰名单下半部分固定展示全部指标列

      6. 前端数据流

      1. 进入动态页
      2. 先拉取 broker options
      3. 选择 broker 后拉取 product options
      4. 选择 product 后拉取 date options
      5. 点击查询后请求 query 接口
      6. 根据 broker + product 找到上半部分配置
      7. 渲染 Overview
      8. 用固定列配置渲染 Table
      9. 输入 stock_code 时重新请求 query 接口

      7. 状态管理

      • 不新增 Pinia store
      • 查询条件放组件内部
      • options 放组件内部
      • query 结果放组件内部

      8. 最终方案总结

      • 后端接口黑灰名单拆开
      • options 通过扫描文件目录生成
      • query 通过 processed.json 分别匹配 broker_nameproduct_nameprocessed_at[:10]
      • 命中记录后再用 json_path 读取主体文件
      • 前端在现有黑名单、灰名单页面内部增加动态 tab
      • 动态页面拆成 QueryForm / Overview / Table 三段
      • 上半部分按产品配置渲染
      • 下半部分黑灰名单分别使用固定列配置