## Why 现有导出系统(2026-04-30 上线)存在三个影响实际可用性的缺陷:筛选条件被静默丢弃(query_json 存而不用)、finalize 阶段重查全量数据库(shard 产物废弃)、新增场景需要手写 Keyset 游标逻辑(难以支持多表 JOIN)。这三个问题共同导致"想加新导出就得开发介入、开发成本高、加完也无法按条件筛选"的现状。 ## What Changes - **引入 DataSource 接口**:替代 `SceneStrategy` 的 `NextShardBoundary` + `QueryRows` 设计,新接口仅要求实现 `Count / Headers / Fetch`,分片游标逻辑全部由框架接管,开发者只管写业务查询(支持任意 SQL / JOIN) - **支持动态列**:`Headers` 方法接收 `ExportParams`,可在运行时根据数据决定列数,解决"设备绑了几张卡就要几列 ICCID"问题 - **query_json 真正生效**:`ExportParams` 将 `query_json` 解析结果和权限快照一并传入 DataSource,`Fetch` 和 `Count` 均可读取并应用筛选条件 - **修复 finalize 重查问题**:finalize 改为按 shard_no 顺序下载分片 OSS 文件直接拼接,不再重查数据库,shard 产物得到复用 - **迁移现有两个场景**:`device` 和 `iot_card` 迁移到新 DataSource 接口,同时补全 query_json 解析逻辑 - **保留原 SceneStrategy 接口**:作为复杂自定义场景的逃生通道,不强制所有场景使用 DataSource ## Capabilities ### New Capabilities - `export-datasource`:DataSource 接口定义、ExportParams 类型、框架侧 offset/limit 分片驱动逻辑、动态列支持 - `export-query-params`:query_json 的解析规范与 ExportParams 注入机制,让筛选条件从创建任务一路传递到数据查询 ### Modified Capabilities - `unified-export-task-system`:finalize 合并策略从"重查数据库"改为"合并 shard OSS 文件";shard 阶段需保证分片 CSV 可被 finalize 独立拼接(不含表头) ## Impact - **删除**:`internal/exporter/SceneStrategy` 接口中的 `NextShardBoundary` 方法(仅框架调用,外部无直接依赖) - **修改**:`internal/task/export_dispatch.go`(游标分片逻辑改为 offset 驱动)、`internal/task/export_finalize.go`(改为合并分片文件)、`internal/task/export_shard.go`(写分片文件时不含表头) - **新增**:`internal/exporter/datasource.go`(接口 + ExportParams 定义)、`internal/exporter/query_params.go`(query_json 解析) - **迁移**:`device_scene.go` / `iot_card_scene.go` 实现新接口,补 query_json 过滤 - **无 API 变更**:四个对外接口(创建/列表/详情/取消)签名不变,前端无感知 - **无数据库迁移**:不新增表或字段