koko 46e55fa623 Stop tracking generated Python bytecode
Generated __pycache__ files were already ignored in some paths but remained tracked in the repository, which caused merge noise and binary conflicts. This removes the tracked bytecode from the index and adds an explicit recursive ignore rule so future Python runs do not reintroduce them.

Constraint: Existing repository history already tracked pycache files across app, backend, and source_code

Rejected: Delete local pycache directories from disk | only repository tracking needed to be removed

Confidence: high

Scope-risk: narrow

Directive: Do not force-add __pycache__ or *.pyc files unless there is a documented runtime packaging reason

Tested: git ls-files shows no remaining paths containing __pycache__/

Not-tested: Application runtime; change only affects tracked generated artifacts and ignore rules
2026-04-28 20:57:53 +08:00
2026-04-28 15:25:34 +08:00
2026-04-28 15:25:34 +08:00
2026-04-27 09:18:10 +08:00
2026-04-06 22:26:44 +08:00

crawler-plugin

这个仓库是什么

这个仓库不是一个“单体项目”,而是一个混合工作目录。当前更像是以下三层共同组成的一套系统:

  • app/Python 桌面宿主、Flask 页面承载层、pywebview 本地桥接层、自动化任务入口
  • backend-java/Java 业务后端,负责任务模型、文件处理、进度缓存、结果组装、落库、下载
  • frontend-vue/Vue 多页面前端,负责工具页交互和任务发起

如果你是第一次接手这个仓库,不要先把它理解成:

  • 纯 Java 后端项目
  • 纯 Python 自动化项目
  • 纯前后端分离 Web 项目

它当前的真实形态更接近:

Vue 页面 -> Python 桌面桥接/Flask -> Java 任务系统 -> Redis / DB / OSS

同时Python 自动化还会再去驱动本地紫鸟客户端和浏览器。

先看哪里

如果你的目标是理解当前主线,请按这个顺序读:

  1. app/
  2. backend-java/
  3. frontend-vue/

原因很简单:

  • app/ 决定了桌面端怎么承载页面、怎么暴露本地能力、怎么把任务推给 Python 自动化
  • backend-java/ 决定了任务怎么创建、状态怎么缓存、结果怎么回传、文件怎么生成和下载
  • frontend-vue/ 决定了用户是怎么触发这些链路的

以下目录不要默认当成当前主线:

  • source_code/
  • backend/

它们和 app/ 有明显重叠,更像历史版本、迁移残留或中间态副本。阅读时要先带着“可能不是当前生效版本”的假设。

主线架构怎么分工

Python 层:桌面壳 + 本地桥接 + 自动化执行

app/ 不是单纯的业务后端。它更像一个桌面宿主,负责三件事:

  • 承载 Flask 页面和登录态
  • 通过 pywebview 暴露本地文件选择、保存文件、上传文件、任务入队等能力
  • 启动和调度 Python 自动化任务

这一层解决的是“本地能力”和“桌面壳”的问题,不是最终任务结果的权威存储。

Java 层:任务系统 + 结果系统

backend-java/ 是当前业务核心后端,负责:

  • 文件上传与临时文件管理
  • 任务创建、历史查询、批量轮询
  • Redis 进度缓存
  • 分片结果接收与聚合
  • 结果文件生成
  • OSS 上传
  • 下载接口输出

从模块名看Java 端已经承接了大部分工具型任务,例如:

  • brand
  • dedupe
  • split
  • convert
  • deletebrand
  • productrisk
  • shopmatch
  • pricetrack

Vue 层:多页面工具前端

frontend-vue/ 不是单页应用,而是多入口页面工程。它的作用主要是:

  • 让用户选择文件或参数
  • 调用 Java API 创建任务或查询任务
  • 调用 pywebview 桥接拿本地能力
  • 在任务执行过程中轮询状态和下载结果

它构建后的产物输出到 new_web_source/,再由 Python/Flask 暴露出来供桌面端使用。

如何理解目录

当前最值得关注的目录

app/

这是当前阅读优先级最高的 Python 目录,重点看这些角色:

  • main.py:创建 pywebview 窗口,暴露本地桥接 API
  • app.pyFlask 应用入口
  • blueprints/:页面、登录、品牌、通信等 HTTP 层
  • amazon/:删除品牌、商品风险、匹配、跟价等自动化任务实现

backend-java/

这是任务系统核心,重点关注:

  • controller对外 API
  • service任务创建、进度、结果回传、组装
  • model / mapper任务和结果模型
  • application.yml:后端依赖配置

frontend-vue/

这是当前工具页前端源码,重点关注:

  • src/shared/bridges/pywebview.ts:前端如何调 Python 本地桥接
  • src/shared/api/java-modules.ts:前端如何调 Java API
  • src/pages/brand/components/:各个具体工具页

不要误判成源码主线的目录

new_web_source/

更像前端构建产物目录,不是首选手改源码位置。

source_code/

app/ 结构高度相似,但从当前仓库关系看,更像旧线或中间迁移副本。

backend/

另一套 Python 后端实现,和当前主线职责不完全一致,更像旧后台线。

用“patrol-delete”看懂最近新增的自动化链路

从最近的提交看,patrol-delete 是当前最新落地的一条自动化模块。它同样同时经过:

  • 前端
  • Python 桌面桥接
  • Python 自动化执行
  • Java 任务系统

但它和“删除品牌”有一个关键差别:

  • delete-brand 更偏“本地 Excel 文件驱动”
  • patrol-delete 更偏“店铺输入 + 任务模板 + 串行自动化执行”

如果你想快速理解当前新增自动化功能的开发方式,优先看这条线更合适。

下面按职责来拆。

1. 用户先在前端输入店铺,并加入备选区

用户打开 patrol-delete 页面后,不是先选本地文件,而是:

  • 输入店铺名
  • 将店铺加入备选区
  • 勾选要处理的店铺
  • 点击“匹配店铺”

这一阶段前端的核心职责是收集“要处理哪个店铺”。

2. 前端先让 Java 做店铺匹配

前端不会直接把“店铺名”交给 Python 执行,而是先调用 Java 的匹配接口。

Java 在这一阶段负责:

  1. 根据店铺名查索引
  2. 判断是否能命中店铺
  3. 返回 shopId、平台、公司、匹配状态等信息

这里要注意:

  • 这是 frontend -> Java
  • 目的是先把“可执行店铺”筛出来
  • Python 还没有开始实际自动化

3. 前端要求 Java 创建“patrol-delete 任务”

匹配通过后,前端调用 Java 的建任务接口。

Java 在这一阶段做的事情也不是“立刻去删商品”,而是:

  1. 接收店铺与模板结构
  2. 创建 taskId
  3. 创建结果记录
  4. 返回当前任务项的初始数据给前端

这一阶段可以理解成:

  • Java 负责建模和建任务
  • Python 还没有开始自动化执行

4. 前端把“可执行项”推入 Python 本地队列

patrol-delete 不是由 Java 主动调用 Python而是前端把任务 payload 推给 Python。

这一步通过 pywebview 暴露的 enqueue_json() 完成,前端会构造一个类似下面的 payload

  • type: patrol-delete-run
  • taskId
  • user_id
  • items
  • template_rows
  • country_sections
  • cart_ratios

然后交给 Python。

重要区分:

  • 这一步不是 Java 队列
  • 这是 Python 本地进程内队列
  • 当前仓库里对应的是 JSON_TASK_QUEUE

5. Python 的任务监听器开始消费队列

Python 侧有一个任务监听器持续盯着 JSON_TASK_QUEUE

patrol-delete 这条链路的设计Python 拿到任务后会按店铺串行执行,再在店铺内部做页面自动化。

这一层的职责重点是:

  1. 根据 taskId 和店铺信息定位当前任务
  2. 串行执行当前店铺,避免多个店铺同时抢本地浏览器环境
  3. 按模板结构产出各国家的删除结果与购物车比例
  4. 在执行过程中持续回传 Java

同时Python 会在本地维护当前任务状态,例如:

  • 当前店铺
  • 当前步骤
  • 已完成/失败数量
  • 是否需要继续下一个店铺

这些状态主要服务于 Python 本地执行期,不是前端最终查询任务状态的权威来源。

6. Python 自动化驱动紫鸟客户端和浏览器

patrol-delete 的“真正执行动作”也发生在这里。

Python 不会直接操作普通浏览器,而是先和紫鸟客户端通信,再接管浏览器调试口。大致过程是:

  1. 连接或启动本机紫鸟客户端
  2. 打开指定店铺
  3. 进入需要巡店/删除的目标页面
  4. 根据模板中的国家块、状态和数量条件读取页面数据
  5. 找到符合删除条件的商品
  6. 执行删除并整理结果

所以这一段实际上又分两层:

  • Python -> 紫鸟客户端:本地 HTTP IPC
  • Python -> 浏览器:通过调试口/自动化驱动执行页面操作

7. Python 一边执行,一边把结果分片回传给 Java

这条链路的关键点在这里:

  • Python 不是等整个任务做完再一次性提交结果
  • 而是每处理完一部分,就立刻回传给 Java

patrol-delete 这里是按“店铺结果分片”回传,更强调:

  • shopName
  • submissionId
  • chunkIndex
  • chunkTotal
  • shopDone
  • countrySections
  • cartRatios
  • error

回传方式:

  • Python -> Java
  • Content-Type: application/json
  • 接口:/api/patrol-delete/tasks/{taskId}/result

回传的数据里会包含:

  • 当前店铺标识
  • chunkIndex
  • chunkTotal
  • 该店铺当前片段的国家结果
  • 购物车比例
  • 当前片段是否已结束
  • 失败时的错误信息

因此,patrol-delete 这条线里更核心的是一类传输:

  1. 执行结果回传:application/json

它不依赖“先上传本地 Excel 文件”这个前置动作。

8. Java 负责接收分片、缓存进度、判断是否可以完结

Java 收到 Python 的结果分片后,不会简单地“收一条写一条最终结果”,而是会先做任务系统层面的处理:

  1. 校验 taskId
  2. taskId + shopName 聚合店铺结果
  3. 过滤重复分片
  4. 将结果分片缓存起来
  5. 更新实时进度
  6. 判断某个店铺是否已 shopDone
  7. 判断整个任务是否达到 finalize 条件

这一步说明 Java 才是“任务状态和最终结果”的权威系统。

9. Java 在分片收齐后生成最终结果

当 Java 发现所有需要的结果分片都已收齐时,会执行最终组装:

  1. 合并分片
  2. 重建最终结果数据
  3. 生成结果 Excel
  4. 上传 OSS
  5. 更新任务状态
  6. 写入结果记录

如果这一步成功,任务会变成 SUCCESS;否则会进入 FAILED

10. 前端轮询 Java不轮询 Python

前端展示任务状态时,查询对象是 Java而不是 Python 本地队列。

前端主要关心的是:

  • 任务详情
  • 批量进度
  • 下载地址

也就是说:

  • Python 负责执行
  • Java 负责对前端提供任务状态与结果

11. 前端最终通过 Java 下载结果,再交给 Python 保存到本地

任务成功后,前端拿到 Java 下载地址,然后再通过 pywebview 调 Python 的保存能力,把文件落回用户本地磁盘。

所以最后一步仍然是混合协作:

  • 下载来源是 Java
  • 本地保存能力来自 Python 桌面桥接

这条例子可以类比到哪些模块

patrol-delete 不是孤例,它更像当前仓库最近新增自动化模块的代表模式。

同类模式至少还能看到这些任务类型:

  • patrol-delete-run
  • delete-brand-run
  • product-risk-resolve-run
  • shop-match-run
  • price-track

它们的共性通常是:

  1. 前端先建任务
  2. Python 负责本地自动化执行
  3. Java 负责任务状态、结果缓存和最终输出

其中:

  • patrol-delete 更适合理解“店铺驱动 + 模板驱动”的新链路
  • delete-brand 更适合理解“本地文件上传 + 文件解析驱动”的旧链路

理解这两条线之后,再看商品风险、店铺匹配、跟价等模块会容易很多。

接手时最容易踩的坑

不要把 enqueue_json() 当成 Java 队列

它是前端调 Python 的本地桥接,进入的是 Python 进程内队列,不是 Java 消息系统。

不要把 new_web_source/ 当成首选源码目录

它更像构建产物输出,首选还是看 frontend-vue/

不要默认 source_code/backend/ 仍是当前主线

这两个目录有参考价值,但从当前结构看,不应先于 app/backend-java/frontend-vue/ 阅读。

不要把 Python 当成最终任务状态来源

Python 负责执行期状态;前端面向用户看到的任务状态、历史、下载结果,当前主权在 Java。

当前文档的边界

这份 README 基于当前仓库的静态分析整理,有几个边界需要明确:

  • 没有运行仓库程序做启动验证
  • 没有确认最终发布时到底启用哪一个入口
  • source_code/backend/ 的判断是“更像旧线/残留”,不是运行态绝对结论

所以这份文档的目标不是提供启动手册,而是帮助接手开发者先建立正确的系统地图。

一句话结论

理解这个仓库最有效的方式不是按语言分开看,而是按职责看:

  • Python 负责桌面壳、本地桥接、自动化执行
  • Java 负责任务系统、结果系统、下载系统
  • Vue 负责工具页交互和任务发起

其中,“删除品牌自动化”更适合帮助你理解旧的文件驱动链路;当前最新落地的 patrol-delete,则更适合当作你理解新增自动化功能的第一条例子。

Description
No description provided
Readme 259 MiB
Languages
Java 67.4%
Vue 15%
JavaScript 8.6%
Python 4.1%
TypeScript 2.6%
Other 2.2%