Commit Graph

211 Commits

Author SHA1 Message Date
huangzd1997 26f4bb3f25 后台菜单重构:菜单类型分组排序(软件在前/后台在后)、新增同类型末尾排序;任务中心分组移除,视频任务记录归入记录与版本、店铺数据记录归入店铺管理;界面名词优化(菜单权限配置/去重数据汇总/无效ASIN数据/视频任务记录/店铺数据记录/生成记录)
Build Backend JAR / build (push) Has been cancelled
2026-08-31 01:48:05 +08:00
huangzd1997 0408c9752e fix: 菜单排序 app 分组优先于 admin,sort_order 按 menuType 作用域解析
Build Backend JAR / build (push) Has been cancelled
- menuComparator 增加 menuType 排序维度(app → admin → 其他)
- resolveSortOrder 查询限定同 menuType,避免跨类型尾部误判
- 抽出 loadRawMenus 保持原始 SQL 与比较器语义一致
2026-08-31 01:21:45 +08:00
huangzd1997 483374744a fix: Spring 多构造器类显式 @Autowired 标注 + V95 迁移兼容 MySQL 8.4
Build Backend JAR / build (push) Has been cancelled
- CapacityPlanService / ExternalCallMetricsRecorder / ZiniaoClientImpl:
  双构造器(生产 + 测试入口)导致 Spring 6 不自动推断构造器注入,
  启动报 'No default constructor found';生产构造器显式加 @Autowired
- V95:shop_key 列 V85 建表时已有,原 ADD COLUMN shop_key 会报
  duplicate column;MySQL 8.4 不支持 ADD COLUMN IF NOT EXISTS,改
  information_schema 动态 SQL;shop_key 缩到 VARCHAR(255) 以容纳
  (shop_key, business_date) 唯一键(1000 在 utf8mb4 下超 3072 字节
  索引上限);删除多余行改为单表 DELETE
2026-08-31 01:09:19 +08:00
huangzd1997 c517711169 task-80: 补充 JVM 堆、直接内存、临时磁盘和连接池容量配置说明 2026-08-30 22:30:56 +08:00
huangzd1997 ba17e34b84 task-79: 为对象存储、数据库和队列增加故障注入测试 2026-08-30 22:23:33 +08:00
huangzd1997 42bbf4904e feat-admin-ui-interaction
Build Backend JAR / build (push) Has been cancelled
2026-08-30 22:09:22 +08:00
huangzd1997 4c70ca4101 task-78: 为所有外部调用增加耗时、重试、失败率和 payload 字节指标
新增 ExternalCallMetricsRecorder:通过 RestClient 拦截器统一记录
aiimage.external-call.duration(耗时)、aiimage.external-call.total
(失败率)、aiimage.external-call.payload.bytes(请求字节)与
aiimage.external-call.retry.total(重试次数);Coze/品牌检查/紫鸟
三个外部客户端全部接入,指标注册表缺失时静默降级,不改变调用语义。
2026-08-30 22:01:02 +08:00
huangzd1997 39e52858d1 task-77: 统一 Coze、品牌检查和紫鸟 HTTP 客户端的连接复用策略 2026-08-30 21:08:28 +08:00
huangzd1997 04f45bebec task-76: JSON owner 查询迁移到显式列并补充任务/状态复合索引 2026-08-30 20:51:07 +08:00
huangzd1997 6a4a115260 task-75: 虚拟线程任务等待队列上限与拒绝/延迟指标 2026-08-30 20:39:31 +08:00
huangzd1997 5105ca95c5 task-74: 隔离调度线程池、文件作业线程池和外部 Coze/图片执行池 2026-08-30 20:31:39 +08:00
huangzd1997 ec9811c8a5 task-73: 本地文件作业队列 in-flight 去重和队列背压 2026-08-30 20:22:58 +08:00
huangzd1997 baa43d80ba task-72: 文件作业数据库原子 claim,避免重复派发同一 job 2026-08-30 20:01:18 +08:00
huangzd1997 6f32ed86e4 task-71: 清理日志改为数量与 sample ID,禁止输出超长任务 ID 列表 2026-08-30 19:53:49 +08:00
huangzd1997 9de4603484 task-70: 历史清理改为 keyset 分页、小批量和短事务 2026-08-30 19:48:59 +08:00
huangzd1997 5749a421cb task-69: 历史清理任务收集 transient payload 指针并提交删除队列 2026-08-30 19:29:32 +08:00
huangzd1997 2de58b7afc task-68: payload 引用删除改为批量引用检查与异步物理删除
- 新增 TransientPayloadDeleteOrchestrator:提交去重入队(maxPendingDeletes 上限),
  flush 时一次性 IN 批量反查 biz_task_chunk / biz_task_scope_state,
  未引用对象交由后台线程池异步物理删除(剥 rustfs: 前缀)
- 幂等:重复提交只入队一次;保守:查询失败整批保留可重试,不误删
- 空值/非指针忽略,本地/OSS 指针不在批量删除范围(各有归属与清理路径)
2026-08-30 19:13:43 +08:00
huangzd1997 2819fb3c6c task-67: 复用 RustFS/MinIO 客户端与 HTTP 连接池
- buildClient 改为 double-check 懒加载缓存共享 MinioClient(volatile 单例),
  同一实例持有同一 OkHttpClient,连接池随实例共享,不再每次操作新建客户端
- supplier 注入路径优先且不写共享缓存,测试隔离不受污染
- 未配置/空白 endpoint 时不创建实例,拒绝操作并保持缓存为空
2026-08-30 19:04:32 +08:00
huangzd1997 e2d6875ef9 task-66: 限制 RustFS 并发读写与重试的总资源预算
- 新增 aiimage.transient-storage.max-total-concurrent-operations 配置
  (默认 0 不启用):跨 upload/read/delete 的总并发预算
- executeWithRetry 入口获取一个总许可,整次操作(含全部重试)全程占用,
  重试不额外消耗,超预算立即拒绝并计入 operation=total rejected 指标
- 失败/完成后 finally 释放总许可,无残留锁;负值/0 视为未启用保持原行为
2026-08-30 18:57:26 +08:00
huangzd1997 9b1978aec8 task-65: transient payload 读取流式解压 + 解压后字节上限
- 新增 aiimage.transient-storage.max-decompressed-payload-bytes 配置
  (默认 100MB,即 2x 存储上限),覆盖 gzip 二进制与 gzip64 兼容两条路径
- decodeGzipStream 按 8KB 缓冲流式解压,累计输出超过上限立即中止并报错,
  防止压缩炸弹(zip bomb)在读取时无界膨胀内存
- 超限错误保留可识别消息(exceeds configured limit),由 resolvePayload 统一包装
2026-08-30 18:49:55 +08:00
huangzd1997 ca32cde4fe task-64: transient payload 压缩改为直接 gzip 二进制流上传
- RustfsObjectStorageService 新增 uploadBytes/readObjectBytes 二进制流 API
  (application/gzip),uploadText/readObjectAsString 改为其薄包装
- TransientPayloadStorageService 的 encodeStoredPayload 直接输出 gzip 字节,
  不再经过 gzip64 + Base64 文本编码(消除 33% 体积膨胀与中间字符串副本)
- 读取端按 gzip magic 识别二进制流解压;兼容旧 gzip64: 文本与历史裸文本
- 本地回落文件同步改为写二进制(Files.write),超限判定基于 gzip 后字节数
2026-08-30 18:42:19 +08:00
huangzd1997 9c9b8a6078 task-63: 进度快照写入最小更新间隔节流(终态豁免+删除清理跟踪) 2026-08-30 18:28:15 +08:00
huangzd1997 8d91e599ab task-62: 本地任务实体缓存共享组件(容量 LRU/TTL 即时回收/定时清理)接入 8 模块 2026-08-30 18:17:52 +08:00
huangzd1997 8e9c79fc0e task-61: Rustfs 对象存储指标基线验收测试(计数/计时/分布/熔断/拒绝) 2026-08-30 18:00:33 +08:00
huangzd1997 305b897f2a task-60: 采集模块 10k 行压测验收(结果完整性、内存与吞吐)
10k 行批量 upsert 压测验收:100 批 × 100 行恰好写入 10k 行不丢失不重复(引用 JSON 唯一);
10 chunk 分批提交总批量 SQL 调用次数恒定 100;hash 相等重复提交全跳过零写入(幂等);
batchSize=1 时 10k 次调用每批 1 行(内存受 batchSize 约束不无界累积);null/空白 ASIN
行安全跳过;前 50 批失败跳过后重试收敛到真实行数。collectdata 模块完成。
2026-08-30 17:43:13 +08:00
huangzd1997 7147fc464c task-59: 采集模块对象存储与批量 SQL 调用次数验证
deleteHistory 删除历史结果的对象存储调用次数验证:批量 SQL(selectList/delete)调用次数
恒定不随行数增长;RustFS 物理删除按 chunk 引用指针去重后每对象一次(旧格式逐行一次);
空历史零调用、单历史单对象、300 行 100 chunk 恰好 100 次、非法越权拒绝、依赖失败传播后
重试成功无残留。锁定 task-57 引入的去重删除语义在 deleteHistory 路径上的调用次数契约。
2026-08-30 17:38:22 +08:00
huangzd1997 567cb1ab67 task-58: collectdata 结果明细读取失败降级(RustFS 超时跳过该 chunk,不中断其它 chunk)
chunk 级引用读取失败(RustFS 超时/不可用)时降级为跳过该 chunk 的引用行并记录 warn,
结果文件继续生成,缺失行由任务状态可观测;chunk 明细 JSON 损坏仍抛异常(数据问题不降级),
旧格式单行读取失败保持抛异常。失败 chunk 在单次调用内缓存为空哨兵,避免重复 resolve。
task-052 依赖失败测试同步更新为降级语义。
2026-08-30 17:31:21 +08:00
huangzd1997 5bbf601480 task-57: 删除任务/历史时先删 DB 行再物理删对象,引用计数反查基于删除后状态,共享对象跳过删除、独占对象真正释放 2026-08-30 17:20:00 +08:00
huangzd1997 adcfa28af3 task-56: 采集结果 Excel 改为临时文件+原子落位,流式写入或落位失败时清理临时文件,目标路径不残留半成品 2026-08-30 17:05:56 +08:00
huangzd1997 e7828dc926 task-55: 采集进度心跳改为节流/合并写,窗口内心跳只更新内存态不落库,窗口到期或任务结束路径强制持久化,避免高频 task UPDATE 2026-08-30 16:55:37 +08:00
huangzd1997 91f760f789 task-54: finalRowCount 改为任务内增量计数(upsert newlyInserted 累计),移除每 chunk 全表 COUNT(*) 2026-08-30 16:41:02 +08:00
huangzd1997 97ae8a7c51 店铺数据抓取累计文件改为店铺级共享,按国家覆盖更新
同店同日在不同账号下产生多份互不相干的累计文件(唯一键含 user_id),
后台管理页每店只显示最新一份,其他账号抓的国家看起来丢失。

- V95 迁移:加 shop_key/country_codes_json/compensation_done 列,按店铺
  合并存量 daily_file 与成员行,唯一键改为 (shop_key, business_date)
- DailyFileService:findForUpdate/findOlder/acquireLock 去 user 维度,
  店铺级锁跨账号串行
- TaskService:聚合按店铺定位;applyCountryCoverage 按国家覆盖(本次
  回传的国家替换旧行,未更新的国家保留);启动补偿组件按成员快照重建
  合并文件并回填国家列表
- 管理页:country_codes 改从 daily_file.country_codes_json 取,行数用
  累计文件实际值
2026-08-30 16:30:09 +08:00
huangzd1997 ae95b294ec task-53: 采集结果 Excel 生成按 rawRows/finalRows 分段生命周期,rawRows 惰性加载避免同时驻留内存 2026-08-30 16:29:48 +08:00
huangzd1997 48284be214 task-52: 生成结果文件按 chunk 一次读取
CollectDataResultDetailReader 从 biz_task_result_item 解析行:引用格式
按 pointer 缓存整 chunk 明细(同一 chunk 对象只 resolve 一次),再按
offset 取行;旧格式逐行兜底。CollectDataService.loadFinalRows 接入
reader,移除内联逐行读取循环与 detailCache。
2026-08-30 16:00:32 +08:00
huangzd1997 a29d6e6ce4 task-51: accepted 行序列化与 hash 批量生成
CollectDataResultDetailCodec.encodeRefsWithHash 一次迭代为整 chunk 生成
全部行引用 JSON 及其 SHA-256(offset 从 startOffset 递增),带
MAX_REFS_PER_BATCH 上限与参数校验;CollectDataResultItemBatchWriter
接入批量生成,删除逐行 encodeRef+hash 循环,同 chunk 重提结果逐字节一致。
2026-08-30 15:39:38 +08:00
huangzd1997 1127e9c8bb task-50: 结果明细批量 upsert 写入器与唯一键幂等
CollectDataResultItemBatchWriter 按唯一键 uk_task_scope_item 批量 upsert
biz_task_result_item:一次批量查询现有行(payload_hash 相等即跳过),
分批发 INSERT ... ON DUPLICATE KEY UPDATE,替代逐行 select/insert/update;
旧格式逐行 payload 升级为引用时物理删除(引用计数兜底)。CollectDataService
submitResult 接入批量写入,移除逐行 upsertResultItem。
2026-08-30 15:32:55 +08:00
huangzd1997 5919ae12e9 task-49: 结果明细从逐行 RustFS 对象改为 chunk 级 payload 存储,引用 JSON 兼容旧格式 2026-08-30 14:31:04 +08:00
huangzd1997 d4ebe1926d fix: 品牌检查过滤器多构造器显式 @Autowired,供 Spring bean 解析 2026-08-30 14:12:19 +08:00
huangzd1997 98c45486fa task-48: invalid ASIN 记录改为批量 INSERT IGNORE/upsert,唯一键扩为 (data_value, brand) 2026-08-30 14:11:59 +08:00
huangzd1997 b92d3e688d task-47: 品牌检查结果任务内短期缓存,避免同品牌重复远程调用 2026-08-30 13:53:38 +08:00
huangzd1997 0d99baea04 task-46: 跳过空品牌批次的无效远程品牌检查请求
新增 CollectDataBrandBatchFilter 接管品牌检查批次切分与分类:空品牌
批次不发起 checkAll 远程调用(行直接归 rejected),远程抛错整组降级
queryFailed 可恢复。service 委托查询器只做计数与无效 ASIN 落库,语义
与旧 filterByBrandCheck 完全等价。8 个测试覆盖默认/批量/幂等/空输入/
单元素/超限/非法参数/依赖失败,全量回归 720 通过。
2026-08-30 13:40:03 +08:00
huangzd1997 7110d1086b task-45: ASIN 去重与无效品牌查询统一为批量集合查询
新增 CollectDataBatchQuery 把 dedupe 表查询与 invalid_asin 表查询
合并为两次批量集合查询,输出与旧两段式语义等价,并返回两类过滤计数
由 service 维护 stats。8 个测试覆盖默认/批量/幂等/空输入/单元素/
超限/非法参数/依赖失败,全量回归 712 通过。
2026-08-30 13:31:52 +08:00
huangzd1997 639e8b989e task-44: collectdata extra JSON 批量预序列化与内容去重
persistParsedTask 逐行调用 ObjectMapper 序列化 extra 是热点;新增
CollectDataExtraJsonCodec 批量预序列化,相同 extra 只序列化一次,
输出与逐行语义完全一致,失败行降级 {}。8 个测试覆盖去重/幂等/
空输入/单元素/容量淘汰/非法输入/序列化失败,全量回归 704 通过。
2026-08-30 13:19:15 +08:00
huangzd1997 173287e3d6 task-43: 采集源文件查找改为确定路径/索引查询
LocalFileStorageService 新增 fileKey→文件名 有界索引(LinkedHashMap LRU,
上限 1024 淘汰最旧):saveTempFile 登记,findLocalSourceFile 优先按索引
直接构造确定路径,索引过期/进程重启时兜底枚举根层目录,结果与索引一致;
key 与索引名均校验单段字符集,防止路径穿越与索引污染。8 个用例覆盖
正常/批量/幂等/空/单元素/索引容量超限/非法输入/清理与重启降级,
mvn 全量测试通过。
2026-08-30 13:08:13 +08:00
huangzd1997 fec89b6b7b task-42: 限制采集解析的文件大小、最大行数和单 chunk 行数
新增 CollectDataParseLimits 组件并在 CollectDataService 解析/回传路径
接入:源文件大小(默认 50MB)、累计解析行数(默认 50000)、单 chunk
回传行数(默认 5000)超限即拒绝,配置经 aiimage.collect-data.* 环境变量
可调、0/负值回退默认。8 个用例覆盖正常/批量/幂等/空/单元素/边界超限/
非法配置/失败后可恢复路径,mvn 全量测试通过。
2026-08-30 13:04:02 +08:00
huangzd1997 33d0f02c55 task-41: 建立 Collect Data 性能基线夹具(1k/10k 行、多 chunk、品牌检测)
新增 CollectDataPerfFixture:确定性生成 1k/10k 行、多关键词多 chunk 与
品牌检测场景(成功/失败/查询失败/空 ASIN)行集合并采样 payload 字节与
chunk 划分;同一输入重复生成结果一致(幂等),行数/计数/关键词均有上限
校验。8 个用例覆盖正常/批量/幂等/空/单元素/超限/非法输入/序列化失败
降级路径,mvn 全量 681 测试通过。
2026-08-30 12:58:26 +08:00
huangzd1997 7f44ca6383 task-40: 完成店铺抓取压测探针与资源比较
新增 ShopDataCrawlLoadTestProbe:并发多轮执行"生成-采样-回传-上传-锁"
流水线,产出内存峰值、耗时、DB QPS、对象存储流量与锁等待五类可比较
指标;行数/线程/轮数均有上限,注入 OSS 上传与锁获取失败验证依赖降级
可恢复且计数不残留。8 个用例覆盖正常/批量/幂等/空/单元素/超限/非法
输入/依赖失败路径,mvn 全量 672 测试通过。
2026-08-30 12:53:36 +08:00
huangzd1997 b806ab9384 task-39: 补充删除/超时/重复回传/累计文件失败的资源清理测试
新增 ShopDataCrawlCleanupTest 11 个用例覆盖:单条/批量/空输入删除路径的
临时文件与累计对象回收、陈旧 RUNNING 任务超时终态化、分片重复回传的
payload 释放与终态拒绝、累计文件 CAS 冲突重试时上传对象回滚。

同时撤销上一提交误引入的按国家覆盖语义:rowsByCountry 恢复同国累积
(addAll),移除与之矛盾的 writeWorkbookLatestMemberWinsPerCountryOthersPreserved
测试,修复 task-22~26 批量合并回归(行数被覆盖削减)。
2026-08-30 12:16:39 +08:00
huangzd1997 6b76333159 task-39: 店铺 Excel 按国家增量更新,未提交国家保留旧数据
Build Backend JAR / build (push) Has been cancelled
rowsByCountry 由同国行累加改为覆盖语义:按成员顺序累积,
后面的结果覆盖前面同名国家的行(最新任务胜出),本次未提交的
国家从旧累计对象/成员累积中保留,不再被清空。

新增回归测试:两个成员快照(英德法 + 仅德国新行)写入 workbook 后,
英国/法国保留旧行、德国被新任务覆盖、未提交国家保持空表。
2026-08-29 23:46:22 +08:00
huangzd1997 36bed2bdc6 task-38 2026-08-29 23:11:59 +08:00