Commit Graph

132 Commits

Author SHA1 Message Date
huangzd1997 228d481211 perf(全链路): 连接池/事务边界/轮询与 IO 效率收口
Java:
- LLM 180s 读超时不再被全局 call-timeout 静默截断成 90s(长思考请求被掐断→重试→付费网关二次计费)
- 代理 HttpClient 缓存改有界 LRU(jikip 每次提取新 IP,无界缓存持续泄漏 selector 线程与连接池)
- 12 个 service 的 Redis 任务锁移出 @Transactional(自旋最坏 10s 白占 DB 连接,池仅 30),远端对象删/传改 afterCommit
- 结果文件 Job 闸门拒绝时不再回退内联执行(改重新入队,避免把背压转嫁给 MQ 消费线程)
- imagevideo 每秒扫描加列投影、过期清理加 LIMIT;权限页整表查询改列投影(不再拉回密码哈希)
- 哈希改 HexFormat;补 5 处"不能改"的技术依据注释(批量插入会丢回填主键、流式丢模板与图片等)

前端:4 个工具页轮询改轻量端点(带 fallback);PriceTrack 快照节流写盘;候选店铺表分页;页面隐藏时停表

客户端:HTTP 连接池按出口复用(Session 仍每请求新建,保持无跨请求状态);品牌检测 WIPO 逐请求握手;
代理配置按 mtime 缓存;串行任务改专属池;异常降级为标签页重连;紫鸟启动改端口轮询;模板编译缓存;
日志上报连接与落盘收口;Flask 版本 API 改按请求复用连接
2026-09-15 23:01:59 +08:00
huangzd1997 b54f72d3f6 fix(品牌检测): 熔断中止落真实原因+部分结果可下载,熔断加持续时长门槛
- 熔断改为「连续失败持续 6 分钟未恢复」才中止:原 8 次即中止,5 线程一轮
  就能凑满,重跑机制没机会生效导致任务失败率过高(任务 2309 复盘)
- 期间每 30s 冷却重试,重跑轮次 10→30;限流窗口恢复后任务自动跑完
- 失败终态上报内部接口 /api/internal/brand/tasks/{id}/abort:落真实原因 +
  用已收分片部分组装结果(未检测品牌单独成 sheet),不再悬挂到心跳超时被
  判「前端长时间无响应」且已跑数据无法下载
- 组装前从分片重建聚合(缓存快照可能缺后加字段如 keptBrands)
- 前端:失败任务有结果文件即显示「下载结果」
2026-09-14 17:04:19 +08:00
huangzd1997 24c5a09c7f feat(任务派发): 客户端兜底拉取页面未推送成功的任务 + 修店铺匹配定时任务误杀
问题:任务派发链路的"推送"只存在于页面里(Java 解析落库 PENDING → activate →
pywebview 桥 enqueue_json 推本机队列)。只解析没点启动、推送前关页面、在纯浏览器
打开,任务都会停在 PENDING,2 小时后被 StaleTaskRepairService 标失败
(「任务长期未被领取,已自动失败」,09-11 生产清理过 263 条同画像)。

- 服务端新增 GET /api/tasks/pull-pending(TaskClientPullController,身份从 JWT 取,
  不接受 user_id 参数):只挑创建超 5 分钟仍 PENDING 的本用户任务,逐条条件更新认领
  (PENDING→RUNNING + 接管 owner_instance_id)——与页面 activate 同一谓词,天然互斥,
  不会重复执行;认领后组装不出载荷则标 FAILED,不留 RUNNING 孤儿
- payload 由各业务模块实现 ClientTaskPullSpi 组装(task 侧不 import 业务模块,同 G5):
  首批 SIMILAR_ASIN / COLLECT_DATA / APPEARANCE_PATENT——这三个 Python 消费端会自行
  回拉明细,故载荷极简、客户端零模块知识;开关 aiimage.client-task-pull.enabled 默认 false
- 防双执行:三处 activate 由「非终态即可」收紧为只认 PENDING,未命中抛
  「任务已在执行中(可能已由客户端自动接管),无需重复启动」(顺带堵住整行 updateById
  把认领写入的 owner 覆盖回去的竞态);两个前端页 activate 失败即提示并停止入队
- 客户端:amazon/main.py 新增 pending_task_pull_worker,启动点挂在 app_client/main.py
  的 start_task_monitor(独立入口的 worker 线上并不生效);开关 pending_pull_enabled 用
  getattr 读取,避免 test/ 下的旧 config 缺键导致整包导入失败
- 同批修:StaleTaskRepairService 的 SCHEDULED 分支改按 scheduled_at + 120min 判死
  (原按 updated_at 会必杀排期 >2h 的店铺匹配定时任务,而 activate 又被 scheduledAt-90s 挡住)
- 测试:TaskClientPullServiceTest / StaleTaskRepairServiceTest / CollectDataTaskPullSpiImplTest /
  CollectDataActivateGuardTest 共 20 例;客户端 pending_task_pull_worker 7 例并更新启动顺序契约测试
2026-09-14 16:23:34 +08:00
huangzd1997 5ea52e5291 perf(F5+): 行数据按需拉取(结果行版本信号)+ 修复 progress/light 恒判 missing
行数据按需拉取(审查 F5 后续):
- V125 给 biz_file_result 补 updated_at(DEFAULT/ON UPDATE 由数据库维护,
  实体标注 insertStrategy/updateStrategy=NEVER —— 否则 selectById→updateById 的
  写回会把旧值写回去、ON UPDATE 不触发,版本信号静默冻结)
- 装配器回传 rowsVersion=「最后变更时间毫秒#行数」,5 个品牌工具页版本未变即跳过
  带行明细的重型 batch;前端变更信号为 rowsVersion + status/fileStatus/fileReady 复合
  (任务收尾常见「行早写完、之后才置成功」,只看行版本会把界面卡在旧状态)

修复线上缺陷(同一功能验证时暴露):
- TaskProgressLightAssembler 列裁剪漏选 module_type 却用它做模块过滤 →
  getModuleType() 恒为 null → light 恒把任务判成 missing;第七批把 light 接进
  跟价/定时匹配/商品风险的轮询后,消费方会把运行中任务判为 FAILED
- 补选中列 + 守卫用例 taskQueryMustSelectModuleType(已反向验证:去掉修复即红)
- 前端 lightClaimsAllTasksMissing:整体性 missing 结论用重型端点复核后再采信

契约与文档:light 白名单补 rowsVersion(Java 契约测试 / spec 06 §2 / 12 个端点描述)
测试:mvn test 2901 全绿;前端 npm test 765 全绿
2026-09-14 12:08:25 +08:00
huangzd1997 1360a44e01 fix(web): 货源查询/外观专利入队不再把 api_key 当必填
密钥已服务端化,本机无明文属正常状态,Java 侧 readApiKey 会按 uid 从用户密钥表兜底;
列成必填会把未在本机手输密钥的用户全部挡在启动之前。
2026-09-14 11:21:09 +08:00
huangzd1997 c55c4a140b feat(A1/A3+C8): 客户端令牌链路打通(按人鉴权就绪)+ 快照 JSON 写入节流
A1/A3 客户端令牌链路(服务端守卫已能按 JWT 鉴权,缺口在客户端不带身份)
- 前端:新增 user-token-bridge(纯逻辑,值变化才推送)+ user-token-sync(启动安装,
  pywebviewready/storage/60s 轮询补推),main.ts 接入;桥接口补 set_user_token
- 客户端:新增 crawler_core/user_token.py(持有 + 对自家 Java 端点注入
  Authorization: Bearer <jwt>,Session.request 包装,第三方域名不注入、已有头不覆盖、
  登出清空、SHUFUAI_DISABLE_USER_TOKEN_HOOK 可关);main.py 暴露桥方法并在启动安装钩子
- 服务端:守卫契约测试补 5 个用户态前缀用例(开关关闭放行 / 打开后匿名 401 /
  用户令牌通过 / 内部令牌仍放行 / /api/ziniao 第二层)
- 翻开关的前置条件(客户端铺开后置 aiimage.security.user-tool-guard-enabled=true)写入报告

C8 快照 JSON 写入节流
- 读端改以 biz_task_result_item 行为准、JSON 仅兜底(历史任务 JSON 仍是唯一副本时可用)
- 整档 JSON 改 30s 节流写,终态路径 force 立即写;新增 2 个契约测试钉住语义

验证:mvn test 2888 全绿;npm test 741 全绿;user_token 钩子自测(注入/归一/第三方跳过/不覆盖/登出)通过
2026-09-14 10:20:15 +08:00
huangzd1997 67223f8950 perf(frontend): 工具页分页/历史截断/轻量轮询/共享纯逻辑(审查 F5/F6/F9/F12/G3)
- F9 新增 useTablePaging composable 并接入 7 个工具页"匹配结果"表(只切渲染窗口,
  不加选择语义;每页 100 条)+ 深色分页样式
- F6 历史任务抽屉渲染截断(默认 50 条 + "显示全部/收起"),全选口径改为当前可见条目
- F5 新增 task-progress-polling 适配器:等待任务终态的紧循环走 /tasks/progress/light,
  异常或空响应回退重型 batch;已接入跟价/定时匹配的 waitForTaskTerminal
- F12 背景图 bg.jpg 251KB → 166KB(1920 宽 + quality 80,image-set 仍优先 webp)
- G3 抽出共享纯逻辑 task-queue-state(开始时间表序列化校验 + 记录缺失错误判定),
  5 个工具页删除逐字重复实现
- 新增 4 个单测文件(分页切片/历史截断/轻量轮询归一/任务队列纯逻辑)
2026-09-14 06:23:46 +08:00
huangzd1997 6d46506726 fix: 全维度审查修复(安全/正确性/性能/稳定性/客户端/前端)
安全
- /api/ziniao/** 五个匿名接口加管理员鉴权(此前可匿名换取任意员工店铺登录令牌)
- 删除 Flask 遗留后门:默认密码建超管 + 每次启动写生产 users 表(服务端与客户端各一份)
- 进度/详情接口归属过滤:新增 TaskProgressOwnershipSupport,11 模块 progress/light 与
  /tasks/batch 接入,DTO 补 userId,前端 13 个查询封装补传(未传时后端不过滤,兼容旧端)
- 代理提取链接(含账密)不再明文入日志(新增 common/util/SecretMasking)
- 全局异常兜底不再回传原始异常信息;内部令牌比较改常量时间
- 登录加失败计数与锁定(10 次锁 15 分钟);品牌源文件下载加 SSRF 防护
- AdminApiGuardFilter 覆盖前缀从 2 扩到 15(开关默认 false,行为不变,为收紧做准备)
- 生产关闭 springdoc/knife4j(/doc.html 匿名可读全部接口定义)

正确性
- 40901/40902 拆分:锁竞争不再被伪装成 success=true(此前客户端停止重试、分片静默丢失)
- 假成功收敛:集采明细批量写失败改为抛出、去重 worker 异常标失败、4 个 worker 改判
  success 字段、publish 空 ASIN 行参与批次 flush、巡店删除全失败带 error 上报
- 客户端心跳 discard 移入 finally(7 模块,失败路径不再留僵尸 RUNNING 任务)
- 状态机条件更新:跟价停止循环、集采 activate/fail、imagevideo 归档回填、店铺匹配提交

性能
- 前端入口包 JS 1.05MB→204KB、CSS 355KB→10.7KB(Element Plus 改按需 + el-config-provider)
- 载荷引用计数按指针里的 taskId 收敛(原 JSON 列 IN 全表扫且逐行调用)
- 店铺明细多值批量 INSERT;快照 upsert 预载缓存;结果文件列改单条 UPDATE
- 新增迁移 V120(补 3 个缺失索引)/V121(删 4 个被覆盖的冗余索引)/V122(URL 前缀索引)

稳定性
- 新增 common/util/ThreadPools 有界线程池替换 5 处无界队列(防堆积 OOM)
- Redis 锁释放改 Lua 原子校验(原裸 delete 会误删他人已过期的锁)
- imagevideo 加死节点接管;锁续期失败重试;调度池 4→16;openStream 全部加超时
- 事务内远程对象删除移到提交后;启动恢复锁按实例命名

客户端
- 不再 taskkill /f /im chrome.exe(改为按调试端口精准回收,不杀用户自己的浏览器)
- 密码检测不再无条件杀紫鸟进程;品牌检测加全局互斥(代理池不再互相覆盖)
- base_dir 统一到 exe 目录(原被 os.getcwd() 覆盖,日志/缓存会分裂两个目录)
- 缓存加定时清理;图片下载加超时;mkstemp 句柄托管

测试
- 同步更新受影响的契约测试(构造器签名/条件更新/方法改名/新增接口方法等)
- 修复 FaultInjectionTest 等 3 处 mock 未 stub 流式 read 导致的读循环 OOM
- mvn test 2795 个测试全绿
2026-09-14 04:15:36 +08:00
huangzd1997 14a723ab1c refactor(品牌工具页): 历史批量删除抽为 runBatchDelete
16 个品牌页逐字相同的 batchDeleteHistory 循环(逐条删除 + 容忍个别失败计数)
收敛为 shared/utils/batch-delete.ts 的 runBatchDelete;各页仅保留自己的删除调用
与提示文案。补单测 4 例(空列表 / 全成功 / 部分失败继续 / 非 Error 异常)。

净减约 120 行;vue-tsc 构建与 699 个前端单测通过。
2026-09-13 23:32:27 +08:00
huangzd1997 dc6e8924a9 refactor(品牌工具页): 历史轮询抽为 useHistoryPolling
QueryAsin / Withdraw / PatrolDelete 三页逐字相同的 startHistoryPolling /
stopHistoryPolling 收敛为 shared/composables/useHistoryPolling:定时器走各页
categorized-timers(category 固定 history-poll),间隔默认主轮询的 2 倍。
categorized-timers 补 CategorizedTimers 类型导出;补注入式假定时器单测 5 例。

净减约 40 行;vue-tsc 构建与 695 个前端单测通过。
2026-09-13 23:22:49 +08:00
huangzd1997 882ccdac12 refactor(品牌工具页): 抽取 formatDateTime 与 uploadPathsToJava 公共工具
- 新增 shared/utils/datetime.ts:13 个品牌页逐字重复的 formatDateTime 收敛为一处;
  语义不同的 3 个变体(toLocaleString / 字符串切片 / 支持时间戳)保留不动
- 新增 shared/utils/upload-to-java.ts:10 个品牌页的上传循环收敛,api 依赖注入便于单测;
  保留 uploadOss(品牌Tab)与 returnEmptyWhenUnavailable(跟价)两处行为差异
- 补 datetime / upload-to-java 单测 10 例

净减约 327 行;vue-tsc 构建与 690 个前端单测全通过
2026-09-13 23:16:59 +08:00
huangzd1997 82a782550e feat(密钥): 用户 API 密钥服务端化——V115 按账号绑定存储 + 后台密钥管理页 + 桌面端全站拦截与配置引导
- 新增 usersecret 模块:外观专利/货源查询密钥从本地 localStorage 迁移至 biz_user_api_secret(AES 加密、按 uid 绑定)
- 后台「密钥管理」页:脱敏展示、立即检测、清空;每日 04:30 分布式锁定时巡检
- 桌面端:密钥设置面板走服务端、未配齐引导 /setup-secrets、代理余量展示
- 删除专利汇令牌全链路与密钥保留时长选择器
2026-09-13 10:03:59 +08:00
huangzd1997 d1b56918fa fix(跟价): 指定ASIN文件提交改 fileKey + 服务端三形态解析兼容
- 前端 resolveAsinRequestPaths 改发上传返回的 fileKey(与去重/转换/采集一致),
  修复安全加固后服务端按拼接解析绝对路径失败导致"ASIN 文件不存在或不可读"
- Java parseAsinRowsByCountry 三种形态解析:绝对路径直读 → tempRoot 拼接 → fileKey 反查,
  均过 isInsideTempDir 穿越校验,不放开临时目录外读取
2026-09-13 03:01:56 +08:00
huangzd1997 30d31fb318 feat(代理): 代理配置按登录用户隔离——桌面端 current_uid 登录同步 + brand 页 proxy_users[uid] 读写,各用户各自代理池各自计费复用(未登录回退全局 proxy_url 兼容旧配置) 2026-09-11 16:09:56 +08:00
huangzd1997 48ee76d60d fix(patrol-delete): 任务跑完不出现「下载结果」按钮——轮询在任务终态即停,而结果 Excel 由 Java 侧 MQ 异步生成,两者时间窗内前端本地的 fileReady 永远停在 false
现象:任务 27547(用户 996)15:06:31 创建、15:12:20 完成,结果文件 15:12:20 已生成并上传 OSS
(result/patrol_delete/.../巡店删除-27547.xlsx,4033 字节,直链与 /results/{id}/download 均 200),
但页面上始终没有下载入口,用户只能靠刷新页面才刷出来。

排查(生产日志时间线):结果文件任务 15:12:10 入队(MQ)、15:12:20 完成;前端最后一次拉取
history/progress 是 15:12:12,之后客户端再无任何请求——即前端是在 fileReady 尚为 false 时停的轮询。

根因:waitForTaskTerminal 只认 taskStatus(SUCCESS/FAILED)就 return,随后 clearActiveQueueTask()
令 hasQueueWork=false、stopHistoryPolling() 停掉历史轮询,refreshTaskViews() 也只跑这一轮。
taskStatus 是 Python 端回传完毕的信号,而 Excel 是 Java 收尾后(finalizeTaskWorkbook →
enqueueAssembleResult)异步生成的,中间有数秒到数十秒间隔;错过就再也不会刷新,本地 fileReady
永远为 false,canDownload() 恒假 → 历史记录里不渲染「下载结果」按钮。

修复:
① 新增 isResultFilePending():判定「确实有文件任务在生成」(fileJobId 存在或
   fileStatus=PENDING/RUNNING),文件已就绪(fileReady/downloadUrl)或已终态
   (SUCCESS/FAILED)则不再等待;全部店铺失败的任务本就不生成文件(fileStatus 为空),不会被误等。
② waitForTaskTerminal 在任务终态后继续轮询至文件就绪,上限 MAX_FILE_WAIT_ROUNDS=12(≈2 分钟),
   期间 queuePushResult 提示「正在生成结果文件(n/12)」,超时打 warn 后按终态返回,不阻塞队列。
③ 新增 settlePendingResultFiles():页面加载时若历史里存在「任务已完成、文件仍在生成」的记录
   (在生成窗口内刷新页面/重开客户端的场景),继续轮询收敛,避免同一个坑的另一个入口。
   仅在无未完成任务时执行,避免与 processQueue 重复轮询。

与同类页面对齐:BrandAppearancePatentTab 早已用 pendingFileTaskIds 等文件就绪再停轮询,
巡店删除页缺这一环。日志按规范用中文,关键分支(等待/超时/收敛完成)均有输出便于线上排查。
2026-09-10 15:26:59 +08:00
huangzd1997 6fe67b648f feat(patrol-delete): 删除条件改为添加式交互——输入后回车/点添加逐个加入chips列表(可单项移除),去掉原'保存到条件库+勾选'两步式与已知状态下拉,启动时随任务携带条件 2026-09-09 19:06:27 +08:00
huangzd1997 96e93944d9 fix(patrol-delete): 删除条件为空的任务四层拦截——①前端启动前拦截(不再先创建后失败,避免任务残留执行中)并创建时上传delete_conditions ②Java服务端校验删除条件非空(旧版本/直调兜底) ③Python端空条件直接按失败上报,不再逐店空转 2026-09-09 18:59:45 +08:00
huangzd1997 0cf20527a4 fix(frontend): 菜单点击偶发无响应三处根因——①路由懒加载chunk失败被静默吞掉(新增onError自动整页重载+保险丝防循环) ②首页入口被权限接口阻塞(改乐观显示+缓存TTL10分钟+超时30s→8s) ③菜单hover预取目标页chunk(工具卡片/工作流步骤/顶部导航) 2026-09-09 18:53:34 +08:00
huangzd1997 83cb3ff84e style(frontend): 全站背景图 webp 化(bg.jpg 4MB→251KB 压缩 + bg.webp)+品牌工具页默认策略调优(品牌检测默认改精确匹配 Simple、Terms 后置)+任务面板/登录页/亚马逊控制台观感微调 2026-09-09 18:32:56 +08:00
huangzd1997 5fad0ae027 feat(brand): 品牌检测任务统一轮询驱动并展示行级实时进度
任务面板状态改为独立轮询(getTaskPollIntervalMs 节奏),刷新/提交/取消/删除后
按是否有运行中任务自动续轮询或停表;运行中任务通过详情接口拉取 Redis 行级进度,
进度按"已处理品牌行/总行(含查询失败)"推进并展示 crawling/assembling/uploading 阶段文案
2026-09-08 22:52:49 +08:00
huangzd1997 3cc5a64609 fix(brand): 品牌检测提交统一立即执行,去掉无人消费的"添加到队列"模式
queue 模式只建 pending 无后台消费者,任务会永久停在排队中;统一走 /api/brand/run 立即执行(与历史链路一致)
2026-09-08 21:54:02 +08:00
huangzd1997 ba581ed095 fix(brand): 品牌检测源文件改走 OSS URL(服务端化跨节点组装可用)
前端上传桥与降级桥透传 uploadOss;品牌页提交时 fileUrl 优先取上传响应的 OSS url,localPath 仅作旧桌面桥兜底。
2026-09-08 15:19:21 +08:00
huangzd1997 4ac8f8b472 fix(pricetrack): ASIN文件路径防本地路径误提交+fileKey兜底反查 2026-09-08 13:34:08 +08:00
huangzd1997 7b6f62f1bc fix(brand): 品牌检测补上传链+新增 /api/brand/run 端点+文件夹展开桥
- BrandBrandTab 对齐其它工具页:选文件/文件夹后先 upload_file_to_java 再提交(服务器可读路径),修复本地路径直传导致的「请先上传待处理文件/没有有效的xlsx文件路径」
- runBrandNow/createBrandTask 改为 files 契约(fileUrl=临时路径 localPath)+ 传 userId
- Java 新增 POST /api/brand/run(等价 /tasks 并返回待爬取数据),修复前端「立即运行」No static resource
- 选择文件夹改走新版桌面客户端桥 expand_brand_folder(本机展开);旧客户端提示改用文件多选
- 生产 .env 已另配 AIIMAGE_BRAND_CHECK_TOKEN(上游 16890 鉴权),非代码变更
2026-09-08 13:18:58 +08:00
huangzd1997 d9e3f34d37 chore: 移除项目内无用代码(28 文件)
- 清理任务面板/SPA 化改造遗留的未使用变量与函数(模板管理配套 6 函数、
  payloadForDisplay/showTip/hasRunning/schedulePoll/removeMatchedRowLocally 等 30+ 处)
- 清理未使用 import(getBrandTemplateXlsxUrl/uploadTempFileToJava/getProductRiskTasksBatch 等)
- useTaskProgressLoop 改为仅类型导入;progress/task-request 缓存未用参数精简
- DeleteBrandRunService 删除永不执行的 taskItems 死分支
- 全量 vue-tsc(含 --noUnusedLocals/--noUnusedParameters)0 错误;648 测试全过
2026-09-08 10:20:30 +08:00
huangzd1997 e248b6e43a feat(web): 前端 SPA 化 + 工具页任务面板统一与历史批量删除
- SPA 化:22 个 MPA html 入口与 *-main.ts 合并为 index.html + vue-router(URL 无 .html 后缀),
  页面跳转全部 router-link,/new_web_source/xxx.html 旧路径归一为 /xxx
- 任务面板统一:共享 TaskCenterPanel/TaskItemCard/TaskStatCards/HistoryTaskLayer,
  16 个工具页右侧统一为统计卡 + 当前任务 + 历史任务弹层(任务ID/开始/结束/状态必展示)
- 历史记录支持单条删除 + 批量勾选删除(确认框/全选/失败提示)
- Java 7 模块(dedupe/convert/split/productrisk/shopmatch/pricetrack/deletebrand)
  history 接口补齐任务时间字段(VO+Service,复用 biz_file_task 列)
- 图片工作台/API 层(brand/permission/user)既有未提交改动一并提交
2026-09-08 10:02:55 +08:00
huangzd1997 c086d402a7 feat(web): 品牌检测/图片生成服务端化——URL 统一 https+域名,入口文件带 hash 防长缓存失效
- brand/image 本地执行 API 服务端化(主机A shufu-web-api:15126,nginx 转发 /api/brand/* 等)
- 前端撤销本地回连逻辑(local-http 删除,http.ts/brand.ts 还原为域名相对路径)
- 版本更新改桌面桥 do_update_app(原 Flask /api/update/do 桥化,Web 无更新入口)
- 品牌检测页 Web 可用(hasBridge 恢复 blanket 判定:文件选择走浏览器降级、任务/SSE 走域名)
- vite 入口文件带内容 hash(/assets 配了 immutable 长缓存,无 hash 入口导致更新永不生效)
- public/logo.jpg:Web 版 /logo.jpg 素材(原 app_client/logo.jpg 随桌面瘦身移除)
2026-09-07 17:11:33 +08:00
huangzd1997 30b8c910e8 feat(web): 桌面端前端 Web 独立部署适配——浏览器降级桥+登录态引导+页面动态修正
- 新增 web-fallback.ts:无 pywebview 时以浏览器能力降级(文件选择/上传/模板下载/配置),
  其余桌面能力(enqueue_json/vc_*/folder 选择等)保持 undefined 交由页面既有请在本地客户端中打开提示
- 新增 ensure-auth.ts:无 uid 时经 /newApi/check_login 恢复登录态,无 token/失效跳登录页;
  21 个入口 main.ts 挂载前先引导(桌面端已注入 uid 时零开销)
- pywebview.ts:getPywebviewApi() 在纯浏览器环境返回降级桥;新增 isDesktopRuntime 标志
  (首页更新面板/退出链接据此区分桌面与 Web);hasPywebview 语义修正为真实桥判定
- 登录页跳转、首页登出链接、品牌检测页 hasBridge 判定(select_brand_folder 存在性)适配 Web
2026-09-07 16:35:19 +08:00
huangzd1997 d2301db292 feat(frontend-vue): 亚马逊运营工具台与新功能页接入——新版工具台(amazon-console+tool-catalog)、品牌检测/ASIN变体采集/查询ASIN 三个工具页 Vue 化并对接既有后端与桌面桥接;桌面首页/登录页 Vue 化(沿用旧视觉);补充 vc_*/get_device_id/save_file_from_url 桥类型、dev 代理;品牌默认勾选排名+FBM;修正 query-asin 标题
含未提交新版改造累积:Brand*Tab 套入工具台壳(AmazonToolPageShell/AmazonTopBar)与目录/权限联动。
2026-09-07 11:06:05 +08:00
huangzd1997 417a2bf831 后台店铺数据记录页新增 Tab 切换与重复 ASIN 分析;task-169/170 HTTP 客户端配置接入;dedupe/brand 相关改造
Build Backend JAR / build (push) Has been cancelled
- 管理后台:店铺数据记录改为列表分页展示(去任务号/文件列/累计标题,'最新'改'更新时间'),新增'重复 ASIN' Tab 按跨店聚合展示 ASIN/店铺/分组/国家/日期/价格;修复失败/进行中任务被过滤不显示的问题
- task-169: BrandCheckHttpConfigResolver 从 aiimage.http-client.* 读取品牌检查超时/重试(默认同现状、钳制),附 8 条测试
- task-170: surefire 内存调整为 1536m
- dedupe: DedupeRunService 重构(事务边界/进度)、新增 DedupeRunProgressVo、Controller 与结果 VO 调整,PermissionMenuService 相应适配
- brand/dedupe 前端:BrandDedupeTab/BrandPatrolDeleteTab 改造、新增 CountrySelector 组件与 country-options、类型与接口端对齐、测试更新
- 移除无引用文件:backend/static/logo.jpg、prompts/
2026-09-03 01:57:41 +08:00
huangzd1997 759f0b15d8 task-101: 上传/解析/入队三道前端拦截,阻止坏数据卡死 Python 自动化
Build Backend JAR / build (push) Has been cancelled
新增 shared/dispatch-guard.ts(纯 TS 校验,可单测)与 dispatch-guard-ui.ts
(ElMessageBox 弹窗层),在数据流的三个位置设闸:

- 选文件:空选择、非 xlsx/xls/csv、空路径直接拦;重复文件弹确认
- 解析结果:taskId 非法、totalRows 为 0、整批行被丢弃、需要分组却无分组直接拦;
  部分行被丢弃弹确认后才允许推送
- 入队前:结构不符、必填字段缺失、items/groups/country_codes 为空数组、
  行数页数为 0、JSON 不安全值(NaN/Infinity/BigInt/循环引用/数组洞)

覆盖 11 个推 Python 队列的 Tab 与 dedupe/split/convert 三个纯 Java Tab。
闸位按 Tab 挑选以免留下孤儿后端状态:collect-data 校验前置到
activateCollectDataTask 之前(任务保持 PENDING 无需回滚)、product-risk 的国家
检查提到建任务之前;已建任务后才拦下的复用各 Tab 原有失败补偿路径。

两处边界:对象属性 undefined 放行(taskNo 这类可选字段是惯用写法),只拦数组
元素 undefined 与数组洞;price-track 的 asin_rows_by_country 仅在 mode=asin
时要求非空,status 模式下 loadAsinRowsForAppClient 本就返回 {}。

顺带修复 similar-asin / appearance-patent 的 selectFiles 缺少 try/catch,
上传失败会残留上一批文件与解析结果。

测试:tests/dispatch-guard.test.ts 新增 37 个 test_task_101_* 用例。
2026-09-01 12:53:12 +08:00
huangzd1997 e2607ab723 task-98: 移除 similar-asin/appearance-patent 模块 Coze,状态机与共享组件改名 LLM
Build Backend JAR / build (push) Has been cancelled
- similarasin/appearancepatent 模块全部 Coze 工作流调用改走 direct-LLM(已确认唯一运行路径)
- 共享组件改名:CozeTaskQueueGate→TaskQueueGate、CozeGroupResultPropagator→GroupResultPropagator
- 状态机改名:biz_task_scope_state 的 coze_* 列→llm_*、stateJson coze 键→llm(V100 迁移已应用生产)
- 删除 biz_coze_credential 表、CozeCredential* 类、SimilarAsinCozeClient、AppearancePatentCozeClient→LlmClient
- 前端 brand 页 Coze 文案→LLM;Python 后端删除 cozepy 依赖与死配置
- 修复 TaskResultFileJobWorker 启动失败:TaskFileJobConfig 注册 ResultFileJobHandlerRegistry 与 13 个 handler bean(含 validateCoverage 启动校验)
2026-09-01 02:20:50 +08:00
huangzd1997 6600bfaa99 task-88: 解析结果前端只接收预览数据,避免大 payload 进入响应式对象
新增纯 TS 预览裁剪 parse-preview:把解析 Vo 裁剪为摘要字段
(taskId/行数统计/开关/prompt),items/groups 整包剔除,可按
previewRowLimit/previewGroupLimit 有界保留样本行供表格展示。输入
对象永不修改,taskId 非法 fail-fast,属性读取抛错时零部分结果。
BrandSimilarAsinTab 的 parseFiles 改为只接收裁剪后的预览(保留
200 行样本),数千行 items 不再进入 Vue 响应式 ref。8 个测试覆盖
默认、批量、幂等、空、单元素、截断溢出、非法输入与 getter 故障。
2026-08-30 22:55:27 +08:00
huangzd1997 25d5a5a5e3 task-85: 优化 Similar ASIN 轮询与文件生成等待,避免重复 force 请求
新增纯 TS force 节流守卫 asin-force-throttle:为每个 taskId 维护 TTL
冷却窗口,窗口内不重复发 force 请求(避免反复触发后端生成文件),到期
后允许重试,任务终态后 clear 立即释放记录。BrandSimilarAsinTab 的
refreshTaskProgress 改为按 pendingFileTaskIds 逐项查守卫决定本轮是否
带 force,请求成功后整批进入冷却。8 个测试覆盖默认、批量、幂等、空、
单元素、200 任务溢出、非法输入与时钟故障恢复。
2026-08-30 22:49:45 +08:00
huangzd1997 5caca86ad1 task-84: 优化店铺抓取队列状态合并,消除 historyItems 的线性重复查找
新增纯 TS 合并模块 merge-history-items:以 taskId→行列表 二级索引替代
原 mergeProgress 的 [...map.values()].find() 全表扫描(O(n×m)→O(n+m))。
命中语义与原实现一致(taskId 相同且 resultId 相同或 incoming 无
resultId),命中后删除旧 key 写入新 key,shopName 变化不再留下幽灵
重复条目,同批内后到条目可命中先到新增。BrandShopDataCrawlTab 的
mergeProgress 改用该模块。9 个测试覆盖默认、批量、幂等、空、单元素、
maxItems 限流、非法输入、keyOf 故障零变更与幽灵条目场景。
2026-08-30 22:47:41 +08:00
huangzd1997 79596a970c 采集数据进度条改为按关键词计算:processedRows/totalRows,标签改为关键词进度
Build Backend JAR / build (push) Has been cancelled
2026-08-28 11:43:51 +08:00
huangzd1997 ea0a319c27 品牌页前端工具菜单新增「ASIN变体采集」入口
Build Backend JAR / build (push) Has been cancelled
2026-08-27 05:10:51 -04:00
huangzd1997 7b238522ed 去重导出列固定顺序为 id/ASIN/国家/价格/品牌;QueryAsin 按店铺加载数据并修正前端回退逻辑
Build Backend JAR / build (push) Has been cancelled
2026-08-25 22:38:38 +08:00
huangzd1997 c287fe01a8 品牌去重默认勾选列调整为 id/ASIN/国家/价格/品牌
Build Backend JAR / build (push) Has been cancelled
2026-08-25 22:05:35 +08:00
huangzd1997 7b81b7aa01 品牌去重默认勾选列调整为 ASIN/国家/价格/SKU ID/品牌
Build Backend JAR / build (push) Has been cancelled
2026-08-25 22:00:33 +08:00
huangzd1997 a11f44664f 还原ASIN变体采集入口,仅保留变体分析移除
Build Backend JAR / build (push) Has been cancelled
2026-08-24 23:21:53 +08:00
huangzd1997 9ba7181212 导航变体分析改为ASIN变体采集入口,修复AiAssetDropzone类型
Build Backend JAR / build (push) Has been cancelled
2026-08-24 23:20:54 +08:00
huangzd1997 5acf3c79ed 移除品牌页导航栏的变体分析入口
Build Backend JAR / build (push) Has been cancelled
2026-08-24 22:48:03 +08:00
huangzd1997 205b0b71b4 数据去重默认勾选列增加品牌/SKU ID/发货类型
Build Backend JAR / build (push) Has been cancelled
2026-08-24 20:13:14 +08:00
supernijia 159d52194c 更新任务存储、权限与货源查询流程
Build Backend JAR / build (push) Has been cancelled
2026-08-22 21:23:01 +08:00
supernijia 7a7f1dfa21 完善任务存储、权限及货源查询流程
Build Backend JAR / build (push) Has been cancelled
2026-08-14 22:49:15 +08:00
supernijia 38216a1885 处理后台新需求
Build Backend JAR / build (push) Failing after 16m58s
2026-08-09 20:08:39 +08:00
supernijia 28e7fce11c 新需求更新 同步更新 2026-08-06 01:11:54 +08:00
supernijia 7c3c9e53a0 菜单修改优化 2026-07-28 13:40:19 +08:00
supernijia 4ddb8b47b0 完成上架相关优化、oss迁移 2026-07-25 17:57:34 +08:00