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
huangzd1997
95e314cef4
task-37
2026-08-29 22:36:11 +08:00
huangzd1997
93ccb27b40
task-36
2026-08-29 22:05:30 +08:00
huangzd1997
2f89f795f6
task-35
2026-08-29 21:28:28 +08:00
huangzd1997
11e19ef4f1
task-34: 将 ownerInstanceId 从 JSON 查询迁移到显式列并补充索引
2026-08-29 20:44:21 +08:00
huangzd1997
0e4a1c1c35
task-33: 将店铺源文件 key 映射改为确定路径,取消临时目录递归扫描
2026-08-29 20:18:57 +08:00
huangzd1997
2cd5e07248
task-32: 将 task entity 本地缓存替换为有容量和过期回收的实现
2026-08-29 20:11:16 +08:00
huangzd1997
cb4e10c87f
task-31: 将任务快照改为轻量进度字段,避免每次写入完整结果 JSON
2026-08-29 20:04:22 +08:00
huangzd1997
199345fd11
task-30: 为国家结果行建立稳定去重键,替换线性重复扫描
2026-08-29 19:52:08 +08:00
huangzd1997
ec28216984
task-29: 合并 scope 状态查询与更新,减少单 chunk 数据库往返
...
persistResultScope 复用接收前已加载的 scope,不再重复 selectOne ——
每个分片接收的 scope 查询从 2 次降为 1 次;空分片校验前移至任何
scope 查询之前,非法分片零数据库往返。任务级分布式锁保证预读 scope
在锁内不过期。
2026-08-29 19:36:30 +08:00
huangzd1997
f1db31f813
task-28: 以 scope 计数器替代每个 chunk 的 COUNT(*) 完整统计
...
分片接收不再对 chunk 表执行 selectCount 全量统计:新插入分片按 scope 计数器 +1
并钳制到 chunk_total,重复提交(唯一键冲突)保持不变;分片行与 scope 计数器
作为一致性单元,状态写入失败时回滚本次插入的分片行与 payload,重试走全新插入,
避免计数器重复计数或永久欠计。任务级分布式锁串行化同一任务的接收,读改写在锁内完成。
2026-08-29 19:25:59 +08:00
huangzd1997
23eddde770
task-27: chunk 接收改为原子插入/幂等 upsert,去掉先查后插
...
persistResultChunk 去除提交前的 findResultChunk 预查,直接 store payload + insert,
唯一索引 uk_task_scope_chunk 兜底幂等:重复提交命中 DuplicateKeyException 后
重查 winner 校验并清理本次重存 payload;空分片(无可处理数据)在落库前拒绝,
不创建 RustFS payload 与分片行。
2026-08-29 19:11:10 +08:00
huangzd1997
8ea4d2f502
task-26: 模板 workbook 大行数下的样式、图片和工作表兼容测试
...
writeWorkbook(模板路径)改为返回实际写入行数,与 streaming 路径一致;
新增 1000/5000 行规模兼容测试:模板表头样式保留、同 URL 图片按 pictureIndex 去重复用、
5 工作表顺序名称保持模板语义、失败行兜底 URL 文本不中断整表。
全量测试 556 通过。
2026-08-29 18:55:01 +08:00
huangzd1997
4e4af7911a
task-25: 店铺结果 workbook 的 SXSSF 流式写入路径
...
评估结论:SXSSF 无法访问/删除模板行,与现有模板重写流程不兼容,
故模板路径保留 XSSFWorkbook,另提供 writeWorkbookStreaming —— 空构造
SXSSFWorkbook + 自建 5 国工作表与表头,行数据按 rowAccessWindow spill 到磁盘,
写入后 dispose() 释放 spill 文件;图片嵌入复用现有链路,失败行兜底 URL 文本。
全量测试 548 通过。
2026-08-29 18:46:40 +08:00
huangzd1997
7eccbc016a
task-24: 店铺图片预取增加任务级数量、字节和超时上限
...
ShopDataCrawlPrefetchBudget 对预取 URL 施加三重预算:数量截断(去重后按序取前 N)、
字节估算门(urlCount×avgBytes 超预算拒绝)、超时钳制(200ms/URL 估算钳到任务上限);
Excel 组装在 prefetch 前应用预算,未预取 URL 由 embed 兜底直接下载。
全量测试 540 通过。
2026-08-29 18:38:37 +08:00
huangzd1997
70d724382d
task-23: 图片嵌入成功后立即释放外部缩略图字节副本
...
BoundedImageCache.release(url) 移除条目并扣减字节计数,byte[] 可被 GC 回收;
embedImage 在 addPicture 成功后立即释放,同一 URL 后续行复用 pictureIndex 不重复嵌入。
全量测试 532 通过。
2026-08-29 18:34:02 +08:00
huangzd1997
6d488515ca
task-22: 店铺 Excel 图片缓存替换为有界字节缓存
...
BoundedImageCache(字节预算+条目上限,FIFO 淘汰,超预算单图拒绝)替换
ShopDataCrawlExcelAssemblyService 中的无界 ConcurrentHashMap;单图超预算时
embed 走原有直接下载兜底。全量测试 524 通过。
2026-08-29 18:29:25 +08:00
huangzd1997
81da7a182e
task-21: 建立店铺抓取性能基线夹具(1k/5k 行、多国家、图片成功/失败)
...
ShopDataCrawlPerfFixture 提供单店铺多国家抓取结果的确定性生成器:
- generateItems:1k/5k 行、1-5 国家、图片成功/失败(前 N 行无缩略图)场景;
- samplePayload:行数/chunk 数/payload 字节/图片成功与失败行数采样。
全量测试 516 通过。
2026-08-29 18:24:10 +08:00
huangzd1997
29b6353d7e
task-20: Similar ASIN 端到端压测、GC 分析与结果文件兼容回归
...
SimilarAsinPerfFixture 新增三个功能点:
- endToEndBenchmark:生成→分 chunk→序列化,记录行数/chunk 数/payload 字节/耗时/吞吐/峰值堆;
- gcStressAnalysis:多轮生成/序列化/释放循环,采样 GC 计数差与堆峰值;
- compatRoundTrip:payload 序列化往返恢复全量行并校验字段稳定(结果文件兼容回归)。
全量测试 508 通过。
2026-08-29 18:18:24 +08:00
huangzd1997
77ae8b2823
task-19: Coze 请求/响应与 Python 回传日志改采样、截断、DEBUG
...
- 新增 SimilarAsinLogSupport 纯函数:truncate(2000 前缀+长度后缀,代理对安全)
与 shouldLog(每 N 次采样,计数 0 恒采样)
- Coze 请求 body 与 submit 响应正文日志降 DEBUG + 截断;
history 轮询响应降 DEBUG + 每 20 次记一次完整正文,其余只记状态
- Python 回传逐行日志降 DEBUG + 每 20 行采样一行,大任务日志量降到 5%
2026-08-29 18:11:24 +08:00
huangzd1997
92858acb4d
task-18: 统一图片 spool 生命周期,超时/取消/异常路径删除临时文件
...
- ImageSpool 增加 closed 状态:close 幂等、close 后 put 拒绝且消息可识别,
杜绝关闭后再写入导致目录删除失败
- 长预算 prefetchToDisk 任务体补 put 前中断检查:deadline/中断取消后不再
产生新临时文件,close 可完整删除目录(与 best-effort 路径对齐)
- 长预算路径并入测试 hook 探测,与短预算路径行为一致,生命周期可测
2026-08-29 18:02:50 +08:00
huangzd1997
795dd1084c
task-17: 解码采样推广全格式、子采样后像素上限、JPEG 质量估算搜索
...
- sourceSubsampling 通用化:PNG 等非 JPEG 格式也按源长边取 2 的幂子采样,
reader 忽略采样参数时记录日志并按全量解码像素校验
- 新增 MAX_DECODED_PIXELS(2400^2) 子采样后解码像素上限,源像素超限先拒绝,
子采样仍超限再升采样因子,解码像素始终受控,36MP 源不再全量解码
- 质量搜索由固定阶梯 {0.75,0.65,0.55} 改为估算(字节比例钳制 [0.45,0.75]),
最坏编码 9 次降到 6 次,典型 1-2 次即命中,降低 CPU 峰值
2026-08-29 17:55:00 +08:00
huangzd1997
0e3dbe450f
task-16: 图片预取改短预算 best-effort,超时取消在途并回退 URL
...
prefetchToDiskBestEffort 在 budgetSeconds 内尽力预取,预算耗尽即取消
在途任务并返回未预取数量;缺图单元格由既有 fallback 直接写 URL。
put 前检查中断标志,避免取消后写盘与 spool close 竞态产生残留文件。
预算通过 aiimage.similar-asin.image-prefetch-budget-seconds 配置(默认 60s),
长预算后台预热路径 prefetchToDisk 行为不变。
2026-08-29 17:37:11 +08:00
huangzd1997
dc69b002db
task-15: async batched last_used_at touch refresh
2026-08-29 17:24:25 +08:00
huangzd1997
d1ea8feb6f
task-14: batch read image db cache and touch only actual hits
2026-08-29 17:16:40 +08:00
huangzd1997
e201b13301
task-13: cap chunk merge row count and payload bytes with orphan fallback
2026-08-29 17:05:49 +08:00
huangzd1997
4d91146256
task-12: extend coze result buffering beyond poll path
...
- bufferCozeRowsOrMerge: unified DONE result persist entry point; buffers to
transient storage when toggle on, falls back to immediate chunk merge on
failure (result never lost), no-op on empty input
- submit/retry synchronous immediate DONE results now buffer too (previously
always merged immediately); submit path persists a DONE scope state row to
carry the buffer pointer (persistImmediateCozeDoneState)
- poll path drops the batchTotal>1 gate: single-batch tasks also buffer
- CozeCandidate/CozeBatchContext records package-private for test access
2026-08-29 16:46:29 +08:00
huangzd1997
3d085c1605
task-11: Coze 结果合并前按稳定 rowKey HashSet 去重,消除 O(n²) 重复处理
2026-08-29 16:17:12 +08:00
huangzd1997
1ccf4f74ef
task-10: chunk 结果建立 rowKey 批量索引,消除跨 chunk 线性扫描
...
mergeCozeRowsIntoChunk 先 indexRowsByChunkKey 建立 rowKey→chunkKey
索引,assignCozeRowsToChunks 按 O(1) 查找分配行归属,保留原有
命中/fallback/orphan 语义与顺序稳定性,每 chunk 只读一次 payload。
2026-08-29 16:07:45 +08:00
huangzd1997
99c0b7dd75
task-9: chunk 查询改为批量 keyset 分页,保持低内存读取
...
loadChunksKeyset 按 id 递增分批拉取(每批 pageSize),最后按
chunkIndex 升序合并,避免超大任务一次 selectList 全量载入 chunk
元数据。surefire fork 堆显式限制 1536m 防止与主 JVM 叠加挤爆内存。
2026-08-29 15:52:46 +08:00
huangzd1997
3b051bbafe
task-8: WorkbookFactory 输入解析改为受控读取,验证超大 Excel 失败提示
...
解析前用 ZipFile 中央目录探测 xlsx(zip) 条目数与解压总字节(不读压缩
内容),超过 maxWorkbookZipEntries(20000)/maxWorkbookUncompressedBytes
(512MB) 立即拒绝并给出可识别提示;非 zip/损坏文件跳过探测交给
WorkbookFactory 兜底转业务异常。0/负值配置回退默认。新增 8 个测试覆盖
正常路径、多文件、幂等、空输入、单行、解压超限、条目超限、损坏文件、
依赖失败恢复。
2026-08-29 15:11:53 +08:00
huangzd1997
68b7d9a4a4
task-7: 限制单文件大小、最大行数和最大字段长度,防止解析任务无界增长
...
新增 maxSourceFileBytes(50MB)/maxParseRows(50000)/maxFieldLength(2000)
三个配置项:文件超限在解析入口拒绝(异常消息可识别)、行数超限拒绝、
超长单元格字段截断。0/负值配置回退默认。新增 8 个测试覆盖正常路径、
多文件、幂等、空文件、单行、边界(恰好=上限通过、超限拒绝)、
非法输入(文件超限/字段截断)、依赖失败恢复。
2026-08-29 15:08:14 +08:00
huangzd1997
db6e8f0ce8
task-6: 分组数据改为索引/范围引用,避免 groups 嵌套复制完整行对象
...
buildParsedGroups 只写 [startIndex, endIndex) 半开区间引用(同 baseId 行在
items 中天然连续),行对象仅存在于 items 一次;resolveAllRows 优先按引用
展开并安全跳过越界/非法区间;响应组仍内嵌预览行兼容前端。旧 payload 内嵌
items 格式继续可读。新增 8 个测试覆盖引用写入、批量、幂等、空输入、单组、
越界 clamp、非法区间、依赖失败恢复。
2026-08-29 15:02:15 +08:00
huangzd1997
16bec1c0fa
task-5: 预览行数量改为配置驱动并做边界校验
...
解析响应预览上限从硬编码常量改为 SimilarAsinProperties.parseResponsePreviewLimit,
0/负值回退默认 100,超过 1000 clamp 到 1000 防止误配导致响应体无界膨胀。
新增 8 个测试覆盖默认路径、自定义值、幂等、空文件、单行、超限 clamp、非法配置回退、依赖失败恢复。
2026-08-29 14:48:01 +08:00
huangzd1997
026aa4e0c3
task-4: 解析接口只返回固定数量预览行,完整行仅保存在后端任务载荷
...
parseAndCreateTask 响应 items/groups 改为 buildResponsePreviewRows/Groups 裁剪
到 PARSE_RESPONSE_PREVIEW_LIMIT(100) 行:大文件(5000行)响应体不再携带全量行,
前端/队列只依赖统计字段与 taskId,Python 通过 parsed-payload 接口拉全量。
groups 预览副本保留 itemCount 与行级字段,字段完整且顺序稳定。
8 个测试覆盖 150/5000/1/100/101 行、空文件、非法输入、存储失败恢复与临时文件清理。
2026-08-29 14:43:08 +08:00
huangzd1997
9f8bdecc9e
task-3: 统一解析载荷全量行恢复逻辑,新旧结构均可恢复
...
新增 SimilarAsinTaskService.resolveAllRows(payload):优先 items(新规范结构)、
其次 allItems(旧结构)、最后 groups 展开(最旧结构),并收敛 rowCount/
loadAllRowsByBaseId/hydrateParsedPayloadRows/两条 assemble 路径的重复 fallback 链。
旧 payload(含 allItems 或仅 groups)仍可恢复全量行,行数、顺序不丢失。
9 个测试覆盖默认/批量/幂等/空/单行/超限/新旧 JSON 反序列化/组展开顺序。
2026-08-29 14:36:15 +08:00
huangzd1997
8c84ff3394
task-2: 解析载荷改为单一规范行集合,消除 allItems 重复序列化
...
SimilarAsinParsedPayloadDto.allItems 标记 @JsonInclude(NON_EMPTY) 并仅作反序列化
兼容字段(新写入不再输出);buildParsedPayloadJson 只写 items 一份全量行,
消除每任务双倍行序列化的内存与 payload 体积。读取侧 getAllItems() 消费点保留
以兼容旧载荷(task-3 再统一收敛)。9 个测试覆盖默认/批量/幂等/空/单行/超限/
旧格式吸收/依赖失败恢复。
2026-08-29 14:32:11 +08:00
huangzd1997
2039acdfe6
task-1: 建立 Similar ASIN 性能基线夹具 (1000/5000行、图片开关、chunk与payload采样)
...
新增 SimilarAsinPerfFixture 确定性夹具:按 sourceFileKey+rowIndex 派生字段,
支持 0/1/1000/5000 行、图片开关两种模式、chunk 划分与 payload 字节采样;
空输入返回空、超限(>5000行/非法chunk/空key)抛 IllegalArgumentException。
含 10 个测试覆盖默认路径/批量/幂等/边界/非法输入/依赖失败恢复。
2026-08-29 14:22:07 +08:00
huangzd1997
322905607a
修复店铺任务数据覆盖bug
Build Backend JAR / build (push) Has been cancelled
2026-08-29 00:16:47 +08:00
huangzd1997
75f23d4568
统一结果文件下载 URL 生成:历史记录/上传回包等漏网点改用 generateFreshDownloadUrl,result/ 前缀对象走 download 域名
Build Backend JAR / build (push) Has been cancelled
2026-08-26 03:58:29 -04:00
huangzd1997
18db20099a
OSS 结果文件下载分流:新增 aiimage.oss.download-endpoint 配置,result/ 前缀对象生成独立下载域名直链(默认未配置时回退原行为)
Build Backend JAR / build (push) Has been cancelled
2026-08-26 13:37:11 +08:00
huangzd1997
7b238522ed
去重导出列固定顺序为 id/ASIN/国家/价格/品牌;QueryAsin 按店铺加载数据并修正前端回退逻辑
Build Backend JAR / build (push) Has been cancelled
2026-08-25 22:38:38 +08:00
huangzd1997
427a8cb79f
修复:JWT 密钥未配置时使用内置默认密钥,与桌面客户端保持一致
2026-08-25 22:00:30 +08:00
huangzd1997
5f519f9cd5
性能优化:N+1查询改批量、串行远程调用并发化、紫鸟索引巡检批量回写
Build Backend JAR / build (push) Has been cancelled
2026-08-25 19:42:43 +08:00