AutoRpa/rpa_selection
Yuuuu 586db4be90 feat: 班次可重跑,避免对方单据重复
领取 UPDATE 按 500 个 fid 分段,同一事务,任一段失败整单回滚。选品一行一落并续租,系统故障改回待领。页面和商城调用期间归还连接。坏连接丢弃后再借一次,未提交语句只重试一次。

加购登录或查询失败放回待领。传入购物车读数且已够量则不再加车。合同按「我的合同」三态:没有则起草,唯一则复用合同号,多条保持处理中。返利送审前按合同号查已有总单,读到则补写不再新建;读号失败保持处理中。

同一次提交带上本分支尚未入库的 Oracle 连接层(rpa_oracle / rpa_browser)及各班次改接。
2026-10-24 02:41:13 +08:00
..
.vscode chore: 根目录改成 oms + 四个英文作业包 2026-10-02 21:24:46 +08:00
output chore: 根目录改成 oms + 四个英文作业包 2026-10-02 21:24:46 +08:00
tests feat: 班次可重跑,避免对方单据重复 2026-10-24 02:41:13 +08:00
.env.example merge: 合入远程 oms + 四作业包布局 2026-10-03 10:29:44 +08:00
.python-version chore: 根目录改成 oms + 四个英文作业包 2026-10-02 21:24:46 +08:00
README.md feat: 班次可重跑,避免对方单据重复 2026-10-24 02:41:13 +08:00
auth_login.py feat: 班次可重跑,避免对方单据重复 2026-10-24 02:41:13 +08:00
http_util.py feat: 班次可重跑,避免对方单据重复 2026-10-24 02:41:13 +08:00
job.py feat: 班次可重跑,避免对方单据重复 2026-10-24 02:41:13 +08:00
main.py feat: 班次可重跑,避免对方单据重复 2026-10-24 02:41:13 +08:00
mall_config.py feat: 班次可重跑,避免对方单据重复 2026-10-24 02:41:13 +08:00
persist.py feat: 班次可重跑,避免对方单据重复 2026-10-24 02:41:13 +08:00
pipeline.py feat: 班次可重跑,避免对方单据重复 2026-10-24 02:41:13 +08:00
pyproject.toml feat: 班次可重跑,避免对方单据重复 2026-10-24 02:41:13 +08:00
repo.py feat: 班次可重跑,避免对方单据重复 2026-10-24 02:41:13 +08:00
rules.py feat: 班次可重跑,避免对方单据重复 2026-10-24 02:41:13 +08:00
search_yaoex.py feat: 班次可重跑,避免对方单据重复 2026-10-24 02:41:13 +08:00
search_ybm.py feat: 班次可重跑,避免对方单据重复 2026-10-24 02:41:13 +08:00
secrets.example.json chore: 根目录改成 oms + 四个英文作业包 2026-10-02 21:24:46 +08:00
start.ps1 merge: 合入远程 oms + 四作业包布局 2026-10-03 10:29:44 +08:00
util.py feat: 班次可重跑,避免对方单据重复 2026-10-24 02:41:13 +08:00
uv.lock chore: 根目录改成 oms + 四个英文作业包 2026-10-02 21:24:46 +08:00

README.md

洁达商城选品

班次作业:从表 1 捞 deal_flag=0,按条形码搜 1 号药城 / 药帮忙,规则选出仓,结果写入表 2。不加购,不推订单中心。

口径:docs/RPA订单中心接口开发口径_20260930.md 第 3 节。

数据流

rpa_sales_goods_mapping_data (deal_flag=0)
    → 领取并置 3
    → 登录一次 / 平台
    → 按条形码搜索(批准文号只落表,不拿去搜)
    → 选品规则(两平台合并,按仓序拆量)
    → rpa_cart_settlement_goods_data(operate_type=1, push_status=0)
    → 表 1 deal_flag=1 成功 / 2 失败

两平台搜完后合并统一判定。凑齐计划量才落成功行;凑不齐不落部分成功。一边故障、另一边单独能凑齐:按成功落。一边故障且剩下的凑不齐:系统故障(可把 deal_flag 改回 0 重跑)。两边都搜到但合计不够:业务失败「库存不足」,该 omsId 不重跑。

规则

硬过滤三项,再按仓序拆量(同一平台同一仓的多个 sku 都参与,低价先吃):

  1. 自营仓(商家名去 [自营] 后必须等于四级名单全称)
  2. 毛利 (销售价格 - 平台价) / 销售价格 >= 4%
  3. 效期 ≥ 12 个月
  4. 仓序(级内由近到远):药帮忙杭州/长沙/湖北小药药 → 1 药城广东/昆山/湖北亿昊 → 济南小药药、天津壹号、重庆亿昊 → 辽宁亿昊、陕西壹号、河南壹号、重庆壹号、重庆小药药
  5. 按序贪心拆量。凑齐则每条拆量一行,purchase_qty 为该条件数;凑不齐整单失败

multi_platform_flag=1 仅当成功行出现两个 platform_type。湖南壹号、甘肃壹号云不在自营集合。口径见 docs/superpowers/specs/2026-10-02-selection-split-allocation-design.md。

环境

cd rpa_selection
uv sync --python 3.12
uv run playwright install chromium

Oracle 与 rpa_oms 同一套变量:RPA_ORACLE_HOST / PORT / SERVICE / USER / PASSWORD,11.2 用 thick。Windows 还要 RPA_ORACLE_CLIENT_LIB。选品 .env 里 Oracle 密码留空时,会补 rpa_oms/.env 里已有的值。连接从 rpa_oracle 池取,班次默认池大小 1。

商城账号只认环境变量(不要提交真实密码):复制 .env.example 为 .env,填 YAOEX_USERNAME / YAOEX_PASSWORD / YBM_USERNAME / YBM_PASSWORD。

已有登录态可跳过浏览器:--yaoex-auth auth.json、--ybm-cookies cookies.json。

运行

cd rpa_selection
uv run pytest tests/test_pipeline.py::test_split_across_malls_is_success tests/test_job.py::test_job_searches_barcode_not_approval_no -q
uv run python main.py --limit 5
uv run python main.py --platform yaoex

Windows:

cd rpa_selection
uv sync --python 3.12
Copy-Item -LiteralPath .env.example -Destination .env
# 商城账号写本机 .env;Oracle 也可只留在 rpa_oms/.env
.\start.ps1 --limit 5

--limit 只领取本班前 N 条。跑的过程中新进入的留给下一班。

中途崩溃会停在 deal_flag=3。deal_time 超过 30 分钟的 3 下一班会再领;未过期的 3 不领。系统故障不能靠订单中心重推同一 oms_id(接口 1 幂等),把 deal_flag 改回 0 或等租约到期。

模块

文件 职责
main.py 登录编排
job.py 班次:领取 → 按行判定 → 落表
persist.py 判定结果 → 表 2 行 + 表 1 处理标志
repo.py Oracle / 内存仓库
rules.py 选品规则,两平台共用
pipeline.py 单行两平台统一判定
search_yaoex.py / search_ybm.py 搜索接口;查询键是条形码
auth_login.py Playwright 登录

运维

怎么跑

cd rpa_selection
uv sync --python 3.12
uv run python main.py --limit 5

Windows 把商城账号写本机 .env,Oracle 也可只留在 rpa_oms/.env,然后 .\start.ps1 --limit 5。缺 RPA_ORACLE_HOST / 用户 / 密码时入口失败,文案「数据库不可用」。

看哪张表哪几列

  • 表 1 rpa_sales_goods_mapping_data:oms_id、deal_flag(0 待领,3 处理中,1 成功,2 失败)、deal_time、deal_result、bar_code
  • 表 2 rpa_cart_settlement_goods_data:oms_id、status(1 成功,2 失败)、fail_reason、push_status=0、purchase_qty

崩溃改回 SQL

停在 3 且未过 30 分钟租约:

UPDATE rpa_sales_goods_mapping_data
SET deal_flag = 0
WHERE deal_flag = 3 AND oms_id = :oms_id;

过期的 3 下一班会再领,不必改。系统故障也是 deal_flag=2,要重跑同样改回 0。

原因列 vs 日志原文

表 1 deal_result / 表 2 fail_reason 写短码(QUERY_FAILED、LOGIN_FAILED)。查询失败原文写入 rpa_selection_query_audit,不进这两列。

点名命令

cd rpa_selection
uv run pytest tests/test_pipeline.py::test_split_across_malls_is_success -q
uv run pytest tests/test_job.py::test_job_searches_barcode_not_approval_no -q
uv run pytest tests/test_oracle_repo.py::test_from_env_without_user_raises -q
uv run pytest tests/test_job.py::test_claim_reclaims_expired_flag_3 tests/test_job.py::test_claim_skips_fresh_flag_3 -q

本期不做

加购、接口 2 推送、支付回传、批准文号搜索、商家名模糊匹配。