# 统一导出任务功能总结 ## 1. 功能概览 本次交付新增统一导出任务系统,提供全局任务入口,支持: - 创建导出任务(`scene=device/iot_card`,`format=xlsx/csv`) - 导出任务列表与详情 - 导出任务取消(待处理/处理中) - 异步三段式执行:`dispatch -> shard -> finalize` - 分片产物与最终产物上传 OSS - 详情接口直出下载链接(固定 24 小时) ## 2. 新增接口 - `POST /api/admin/export-tasks`:创建导出任务 - `GET /api/admin/export-tasks`:导出任务列表(支持 `scene/status/time` 过滤) - `GET /api/admin/export-tasks/:id`:导出任务详情(已完成时返回 `download_url`) - `POST /api/admin/export-tasks/:id/cancel`:取消导出任务 ## 3. 状态机 ### 3.1 主任务状态 - `1` 待处理 - `2` 处理中 - `3` 已完成 - `4` 已失败 - `5` 已取消 ### 3.2 分片状态 - `1` 待处理 - `2` 处理中 - `3` 已成功 - `4` 已失败 - `5` 已取消 ## 4. 核心设计 ### 4.1 模型与迁移 新增两张表: - `tb_export_task`:主任务 - `tb_export_shard_task`:分片任务 关键点: - 无外键,仅使用 `task_id` 做逻辑关联 - 主任务保留进度、分片统计、权限快照、产物信息 - 分片任务保留游标范围、分片产物、执行状态 ### 4.2 场景策略注册中心 新增 `internal/exporter` 场景注册中心与策略接口,首批接入: - `device` 场景策略 - `iot_card` 场景策略 统一定义: - `Headers()`:导出表头 - `NextShardBoundary()`:按 keyset 方式计算分片边界 - `QueryRows()`:按分片边界查询行数据 ### 4.3 执行链路 - `export:dispatch`:构建分片并入队 `export:shard` - `export:shard`:按分片查询数据、写文件、上传 OSS、回写分片结果 - `export:finalize`:汇总分片结果并生成最终文件,更新主任务状态 ### 4.4 幂等与重试安全 - dispatch/shard/finalize 增加 Redis 锁,避免并发重复执行 - 分片状态条件更新,重复消费不会重复计数 - shard/finalize 利用 Asynq 重试上下文,在最终重试失败时才落库失败状态 ### 4.5 取消语义 - 待处理:直接更新为已取消 - 处理中:仅设置 `cancel_requested=true`,由 Worker 检查点协作停止 - dispatch/shard/finalize 均增加取消检查点 ### 4.6 下载链接 - 仅 `status=已完成` 返回 `download_url` - 链接有效期固定 `24h`(常量 `ExportDownloadURLExpire`) - URL 由详情接口实时生成,过期后再次访问可刷新 ## 5. 权限与可见性 - 平台/超管:可见全部导出任务 - 代理:仅可见其店铺范围内创建的导出任务 - 详情越权统一返回:`无权限操作该资源或资源不存在` ## 6. 文档与生成器更新 已同步更新: - 路由文档(新增 `导出任务` Tag 的 4 个接口) - 文档构建 Handler 集合(`pkg/openapi/handlers.go` 新增 `ExportTask`) - OpenAPI 文件重新生成:`docs/admin-openapi.yaml`