<?xml version="1.0" encoding="utf-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><title>万邦api博客</title><link>https://alexob.com/</link><description>Good Luck To You!</description><item><title>🔍《闲鱼商品发布数量上限与运营提效包：接口调成功 ≠ APP 一定展示的排查手册》（附Python源码）</title><link>https://alexob.com/?id=518</link><description>&lt;h1&gt;🔍《闲鱼商品发布数量上限与运营提效包：接口调成功 ≠ APP 一定展示的排查手册》（附Python源码）&lt;/h1&gt;&lt;div class=&quot;ybc-p&quot;&gt;&lt;strong&gt;结论先拍&lt;/strong&gt;：&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;alibaba.idle.isv.item.publish&lt;/code&gt; 返回 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;success=true&lt;/code&gt; &lt;strong&gt;只代表&amp;quot;平台收到了请求&amp;quot;&lt;/strong&gt;，不代表商品在闲鱼APP/搜索里能看见。我们复盘过一批&amp;quot;接口全绿、APP零曝光&amp;quot;的案例，根因分布是：&lt;strong&gt;① 发布数量上限（个人号每日/总量天花板，超限静默截断）② 类目资质/品牌资质未审核 ③ 敏感词/违规词命中下架 ④ 图片/视频未通过审核 ⑤ &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;item_biz_type&lt;/code&gt; 错配被限流 ⑥ 草稿未正式上架（&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;publish_status&lt;/code&gt; 停留在草稿）⑦ 重复商品被聚合去重&lt;/strong&gt;。 排查的正确姿势不是&amp;quot;再调一次&amp;quot;，而是&lt;strong&gt;发布成功 → 立即回查 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;item.get&lt;/code&gt; → 比对展示状态码 → 分层定位&lt;/strong&gt;，本手册把这套流程代码化了。&lt;/div&gt;&lt;hr/&gt;&lt;h2&gt;一、&amp;quot;成功&amp;quot;与&amp;quot;展示&amp;quot;之间的七道闸门&lt;/h2&gt;&lt;pre class=&quot;ybc-pre-component ybc-pre-component_not-math&quot;&gt;接口返回&amp;nbsp;success=true
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;▼&amp;nbsp;①&amp;nbsp;发布数量上限（每日/总量）
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;个人号日发有限，超限→接口仍success但进&amp;quot;待审核/草稿池&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;▼&amp;nbsp;②&amp;nbsp;类目/品牌资质
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;手机/数码/奢品需资质，缺→不展示
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;▼&amp;nbsp;③&amp;nbsp;内容审核（敏感词/违规词/违禁品）
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;命中→下架或仅自己可见
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;▼&amp;nbsp;④&amp;nbsp;图片/视频审核
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;审核中→不展示，驳回→下架
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;▼&amp;nbsp;⑤&amp;nbsp;item_biz_type&amp;nbsp;语义匹配
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;个人闲置带sp_biz_type→被识别为商家，流量降权
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;▼&amp;nbsp;⑥&amp;nbsp;发布状态机
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;publish_status≠ON_SALE&amp;nbsp;→&amp;nbsp;草稿/待审
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;▼&amp;nbsp;⑦&amp;nbsp;重复/违规聚合
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;同质商品→去重合并，主商品被替换
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;▼
&amp;nbsp;&amp;nbsp;&amp;nbsp;APP/搜索&amp;nbsp;可见&amp;nbsp;✅&lt;/pre&gt;&lt;blockquote&gt;&lt;div class=&quot;ybc-p&quot;&gt;关键认知：&lt;strong&gt;① 和 ⑥ 是最常见的&amp;quot;静默失败&amp;quot;&lt;/strong&gt;——接口不报错，商品进了草稿池或审核队列，运营以为发了50件实际只上架3件。&lt;/div&gt;&lt;/blockquote&gt;&lt;hr/&gt;&lt;h2&gt;二、发布数量上限（官方口径）&lt;/h2&gt;&lt;div class=&quot;hyc-common-markdown__table-wrapper&quot; data-has-scroll=&quot;false&quot; style=&quot;font-size: 16px; border-collapse: separate; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;div style=&quot;font-size: 16px; border-collapse: separate; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;table&gt;&lt;thead style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot; class=&quot;firstRow&quot;&gt;&lt;th style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;维度&lt;/div&gt;&lt;/th&gt;&lt;th style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;个人号（C2C）&lt;/div&gt;&lt;/th&gt;&lt;th style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;商家号 / ISV&lt;/div&gt;&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;每日发布上限&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;约 50~100 件/天&lt;/strong&gt;（视账号等级/信用）&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;按应用配额，通常更高&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;在售总量上限&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;约 500~2000 件&lt;/strong&gt;（芝麻信用/活跃度影响）&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;视类目授权&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;超限表现&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;接口仍返回 success&lt;/strong&gt;，但实际进入草稿/待审核&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;部分接口返回 &lt;code class=&quot;hyc-common-markdown__code__inline&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 2px 4px;&quot;&gt;sub_code=isv.item-limit-exceeded&lt;/code&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;突破方式&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;提升信用/认证、升级商家号&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;申请类目配额、用多店铺分流&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div class=&quot;ybc-p&quot;&gt;⚠️ &lt;strong&gt;血泪点&lt;/strong&gt;：个人号超限时&lt;strong&gt;接口不报错&lt;/strong&gt;是设计如此（防探测），所以&amp;quot;我发了200件怎么只显示3件&amp;quot;的锅只能靠&lt;strong&gt;发布后回查&lt;/strong&gt;背。&lt;/div&gt;&lt;/blockquote&gt;&lt;hr/&gt;&lt;h2&gt;三、排查决策树&lt;/h2&gt;&lt;pre class=&quot;ybc-pre-component ybc-pre-component_not-math&quot;&gt;publish&amp;nbsp;返回&amp;nbsp;success
&amp;nbsp;&amp;nbsp;&amp;nbsp;│
&amp;nbsp;&amp;nbsp;&amp;nbsp;├─&amp;nbsp;①&amp;nbsp;回查&amp;nbsp;item.get&amp;nbsp;拿到&amp;nbsp;publish_status
&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;├─&amp;nbsp;ON_SALE(在售)&amp;nbsp;→&amp;nbsp;进&amp;nbsp;②③④⑤
&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;├─&amp;nbsp;DRAFT(草稿)&amp;nbsp;→&amp;nbsp;未正式发布，调&amp;nbsp;publish&amp;nbsp;二次确认
&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;├─&amp;nbsp;AUDIT(审核中)&amp;nbsp;→&amp;nbsp;等待/查审核状态
&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;└─&amp;nbsp;OFF_SHELF/REJECT&amp;nbsp;→&amp;nbsp;看&amp;nbsp;reject_reason
&amp;nbsp;&amp;nbsp;&amp;nbsp;│
&amp;nbsp;&amp;nbsp;&amp;nbsp;├─&amp;nbsp;②&amp;nbsp;数量上限检查
&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;today_published&amp;nbsp;&amp;gt;=&amp;nbsp;daily_limit?&amp;nbsp;→&amp;nbsp;次日/提额
&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;total_on_sale&amp;nbsp;&amp;gt;=&amp;nbsp;total_limit?&amp;nbsp;→&amp;nbsp;下架清理/多店铺
&amp;nbsp;&amp;nbsp;&amp;nbsp;│
&amp;nbsp;&amp;nbsp;&amp;nbsp;├─&amp;nbsp;③&amp;nbsp;资质检查（类目/品牌）
&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;category/brand&amp;nbsp;是否需要额外授权
&amp;nbsp;&amp;nbsp;&amp;nbsp;│
&amp;nbsp;&amp;nbsp;&amp;nbsp;├─&amp;nbsp;④&amp;nbsp;内容审核（敏感词/图片）
&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;title/desc&amp;nbsp;敏感词扫描&amp;nbsp;→&amp;nbsp;自动改写
&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;图片审核状态&amp;nbsp;→&amp;nbsp;等待/重传
&amp;nbsp;&amp;nbsp;&amp;nbsp;│
&amp;nbsp;&amp;nbsp;&amp;nbsp;├─&amp;nbsp;⑤&amp;nbsp;item_biz_type&amp;nbsp;匹配检查
&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;个人闲置&amp;nbsp;不应带&amp;nbsp;sp_biz_type（前篇映射规则）
&amp;nbsp;&amp;nbsp;&amp;nbsp;│
&amp;nbsp;&amp;nbsp;&amp;nbsp;└─&amp;nbsp;⑥&amp;nbsp;去重/聚合检查
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;同图同标题&amp;nbsp;→&amp;nbsp;被合并，换图/改标题&lt;/pre&gt;&lt;hr/&gt;&lt;h2&gt;四、Python：PublishVerifier（发布成功→APP展示 全链路排查器）&lt;/h2&gt;&lt;pre class=&quot;ybc-pre-component ybc-pre-component_not-math&quot;&gt;#&amp;nbsp;idle_publish_verifier.py
&amp;quot;&amp;quot;&amp;quot;
闲鱼商品发布:&amp;nbsp;接口成功&amp;nbsp;≠&amp;nbsp;APP展示&amp;nbsp;排查手册
-&amp;nbsp;发布后立即回查&amp;nbsp;publish_status&amp;nbsp;状态机
-&amp;nbsp;数量上限检查&amp;nbsp;(每日/总量)
-&amp;nbsp;资质/敏感词/图片审核/语义匹配/去重&amp;nbsp;分层排查
-&amp;nbsp;输出可定位的&amp;nbsp;DiagnoseReport
复用前几篇:&amp;nbsp;IdleItemPublishMapper(字段映射)&amp;nbsp;/&amp;nbsp;ComplianceGate&amp;nbsp;/&amp;nbsp;RateLimiter
&amp;quot;&amp;quot;&amp;quot;
import&amp;nbsp;time,&amp;nbsp;re,&amp;nbsp;threading
from&amp;nbsp;typing&amp;nbsp;import&amp;nbsp;Dict,&amp;nbsp;List,&amp;nbsp;Optional,&amp;nbsp;Set
from&amp;nbsp;dataclasses&amp;nbsp;import&amp;nbsp;dataclass,&amp;nbsp;field
from&amp;nbsp;enum&amp;nbsp;import&amp;nbsp;Enum

#&amp;nbsp;====================&amp;nbsp;发布状态码&amp;nbsp;====================
class&amp;nbsp;PublishStatus(Enum):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ON_SALE&amp;nbsp;=&amp;nbsp;&amp;quot;ON_SALE&amp;quot;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;在售(展示)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;DRAFT&amp;nbsp;=&amp;nbsp;&amp;quot;DRAFT&amp;quot;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;草稿(未正式发布)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;AUDIT&amp;nbsp;=&amp;nbsp;&amp;quot;AUDIT&amp;quot;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;审核中
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;OFF_SHELF&amp;nbsp;=&amp;nbsp;&amp;quot;OFF_SHELF&amp;quot;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;已下架
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;REJECT&amp;nbsp;=&amp;nbsp;&amp;quot;REJECT&amp;quot;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;审核驳回
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;UNKNOWN&amp;nbsp;=&amp;nbsp;&amp;quot;UNKNOWN&amp;quot;

#&amp;nbsp;敏感词库(示例,&amp;nbsp;生产接内容安全API)
SENSITIVE_WORDS&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;高仿&amp;quot;,&amp;nbsp;&amp;quot;精仿&amp;quot;,&amp;nbsp;&amp;quot;复刻&amp;quot;,&amp;nbsp;&amp;quot;原单&amp;quot;,&amp;nbsp;&amp;quot;跟单&amp;quot;,&amp;nbsp;&amp;nbsp;#&amp;nbsp;侵权/假货
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;走私&amp;quot;,&amp;nbsp;&amp;quot;赃物&amp;quot;,&amp;nbsp;&amp;quot;来路不明&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;VX&amp;quot;,&amp;nbsp;&amp;quot;微信&amp;quot;,&amp;nbsp;&amp;quot;QQ号&amp;quot;,&amp;nbsp;&amp;quot;加我&amp;quot;,&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;导流
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;最便宜&amp;quot;,&amp;nbsp;&amp;quot;全网最低&amp;quot;,&amp;nbsp;&amp;quot;第一&amp;quot;,&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;极限词
}

#&amp;nbsp;需资质的类目
CATEGORY_NEED_QUALIFICATION&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;手机&amp;quot;,&amp;nbsp;&amp;quot;数码&amp;quot;,&amp;nbsp;&amp;quot;奢品&amp;quot;,&amp;nbsp;&amp;quot;手表&amp;quot;,&amp;nbsp;&amp;quot;包袋&amp;quot;,&amp;nbsp;&amp;quot;珠宝&amp;quot;,&amp;nbsp;&amp;quot;文玩&amp;quot;,
}

#&amp;nbsp;====================&amp;nbsp;诊断结果&amp;nbsp;====================
@dataclass
class&amp;nbsp;DiagnoseReport:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;outer_id:&amp;nbsp;str
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;api_success:&amp;nbsp;bool
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;visible:&amp;nbsp;bool&amp;nbsp;=&amp;nbsp;False
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;publish_status:&amp;nbsp;PublishStatus&amp;nbsp;=&amp;nbsp;PublishStatus.UNKNOWN
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;issues:&amp;nbsp;List[str]&amp;nbsp;=&amp;nbsp;field(default_factory=list)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;suggestions:&amp;nbsp;List[str]&amp;nbsp;=&amp;nbsp;field(default_factory=list)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;retryable:&amp;nbsp;bool&amp;nbsp;=&amp;nbsp;False

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;summary(self)&amp;nbsp;-&amp;gt;&amp;nbsp;Dict:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;outer_id&amp;quot;:&amp;nbsp;self.outer_id,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;api_success&amp;quot;:&amp;nbsp;self.api_success,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;visible&amp;quot;:&amp;nbsp;self.visible,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;publish_status&amp;quot;:&amp;nbsp;self.publish_status.value,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;issues&amp;quot;:&amp;nbsp;self.issues,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;suggestions&amp;quot;:&amp;nbsp;self.suggestions,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;retryable&amp;quot;:&amp;nbsp;self.retryable,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

#&amp;nbsp;====================&amp;nbsp;数量上限配额&amp;nbsp;====================
@dataclass
class&amp;nbsp;QuotaConfig:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;daily_limit:&amp;nbsp;int&amp;nbsp;=&amp;nbsp;80&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;每日发布上限
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;total_limit:&amp;nbsp;int&amp;nbsp;=&amp;nbsp;1000&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;在售总量上限

class&amp;nbsp;QuotaTracker:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;按店铺追踪发布数量(持久化到Redis生产环境)&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;__init__(self,&amp;nbsp;cfg:&amp;nbsp;QuotaConfig&amp;nbsp;=&amp;nbsp;QuotaConfig()):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.cfg&amp;nbsp;=&amp;nbsp;cfg
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.today:&amp;nbsp;Dict[str,&amp;nbsp;int]&amp;nbsp;=&amp;nbsp;{}&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;shop_id&amp;nbsp;-&amp;gt;&amp;nbsp;今日已发
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.total:&amp;nbsp;Dict[str,&amp;nbsp;Set[str]]&amp;nbsp;=&amp;nbsp;{}&amp;nbsp;&amp;nbsp;#&amp;nbsp;shop_id&amp;nbsp;-&amp;gt;&amp;nbsp;在售outer_id集合
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self._lock&amp;nbsp;=&amp;nbsp;threading.Lock()

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;check(self,&amp;nbsp;shop_id:&amp;nbsp;str,&amp;nbsp;outer_id:&amp;nbsp;str)&amp;nbsp;-&amp;gt;&amp;nbsp;Optional[str]:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;with&amp;nbsp;self._lock:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;today&amp;nbsp;=&amp;nbsp;self.today.get(shop_id,&amp;nbsp;0)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;today&amp;nbsp;&amp;gt;=&amp;nbsp;self.cfg.daily_limit:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;f&amp;quot;每日发布上限({self.cfg.daily_limit}/天),&amp;nbsp;今日已发{today}&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;total&amp;nbsp;=&amp;nbsp;len(self.total.get(shop_id,&amp;nbsp;set()))
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;total&amp;nbsp;&amp;gt;=&amp;nbsp;self.cfg.total_limit:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;f&amp;quot;在售总量上限({self.cfg.total_limit}),&amp;nbsp;需下架清理或多店铺分流&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;None

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;mark_published(self,&amp;nbsp;shop_id:&amp;nbsp;str,&amp;nbsp;outer_id:&amp;nbsp;str):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;with&amp;nbsp;self._lock:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.today[shop_id]&amp;nbsp;=&amp;nbsp;self.today.get(shop_id,&amp;nbsp;0)&amp;nbsp;+&amp;nbsp;1
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.total.setdefault(shop_id,&amp;nbsp;set()).add(outer_id)
#&amp;nbsp;封装好API供应商demo&amp;nbsp;url=https://console.open.onebound.cn/console/?i=Lex
#&amp;nbsp;====================&amp;nbsp;排查器&amp;nbsp;====================
class&amp;nbsp;PublishVerifier:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;发布成功&amp;nbsp;→&amp;nbsp;APP展示&amp;nbsp;全链路排查&amp;quot;&amp;quot;&amp;quot;

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;__init__(self,&amp;nbsp;quota:&amp;nbsp;QuotaTracker,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;item_getter:&amp;nbsp;Optional[callable]&amp;nbsp;=&amp;nbsp;None):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.quota&amp;nbsp;=&amp;nbsp;quota
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.item_getter&amp;nbsp;=&amp;nbsp;item_getter&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;(shop_id,&amp;nbsp;outer_id)&amp;nbsp;-&amp;gt;&amp;nbsp;dict(含publish_status等)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;----&amp;nbsp;主入口&amp;nbsp;----
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;diagnose(self,&amp;nbsp;shop_id:&amp;nbsp;str,&amp;nbsp;outer_id:&amp;nbsp;str,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;publish_resp:&amp;nbsp;Dict,&amp;nbsp;item:&amp;nbsp;Dict)&amp;nbsp;-&amp;gt;&amp;nbsp;DiagnoseReport:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rep&amp;nbsp;=&amp;nbsp;DiagnoseReport(outer_id=outer_id,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;api_success=publish_resp.get(&amp;quot;success&amp;quot;,&amp;nbsp;False))

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;①&amp;nbsp;接口本身失败
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;not&amp;nbsp;rep.api_success:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rep.issues.append(&amp;quot;接口调用失败(非success)&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rep.suggestions.append(&amp;quot;查sub_code/sub_msg,&amp;nbsp;按错误码重试&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rep.retryable&amp;nbsp;=&amp;nbsp;True
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;rep

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;②&amp;nbsp;数量上限预检(发布前也应调一次,&amp;nbsp;这里是双重确认)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;q&amp;nbsp;=&amp;nbsp;self.quota.check(shop_id,&amp;nbsp;outer_id)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;q:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rep.issues.append(q)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rep.suggestions.append(&amp;quot;次日发布&amp;nbsp;/&amp;nbsp;提升账号等级认证&amp;nbsp;/&amp;nbsp;多店铺分流&amp;quot;)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;③&amp;nbsp;回查发布状态(核心)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;remote&amp;nbsp;=&amp;nbsp;self._query_item(shop_id,&amp;nbsp;outer_id)&amp;nbsp;or&amp;nbsp;{}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;status&amp;nbsp;=&amp;nbsp;self._parse_status(remote.get(&amp;quot;publish_status&amp;quot;))
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rep.publish_status&amp;nbsp;=&amp;nbsp;status

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;status&amp;nbsp;==&amp;nbsp;PublishStatus.DRAFT:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rep.issues.append(&amp;quot;商品停留在草稿,&amp;nbsp;未正式上架&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rep.suggestions.append(&amp;quot;确认调用publish而非save_draft;&amp;nbsp;检查是否漏传必填&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;elif&amp;nbsp;status&amp;nbsp;==&amp;nbsp;PublishStatus.AUDIT:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rep.issues.append(&amp;quot;审核中,&amp;nbsp;暂未展示&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rep.suggestions.append(&amp;quot;等待审核(通常分钟级),&amp;nbsp;查审核状态接口&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;elif&amp;nbsp;status&amp;nbsp;==&amp;nbsp;PublishStatus.REJECT:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;reason&amp;nbsp;=&amp;nbsp;remote.get(&amp;quot;reject_reason&amp;quot;,&amp;nbsp;&amp;quot;未知&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rep.issues.append(f&amp;quot;审核驳回:&amp;nbsp;{reason}&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rep.suggestions.append(&amp;quot;按驳回原因修改后重发&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;elif&amp;nbsp;status&amp;nbsp;==&amp;nbsp;PublishStatus.OFF_SHELF:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rep.issues.append(&amp;quot;已下架(违规/主动)&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rep.suggestions.append(&amp;quot;查违规记录/重新上架&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;elif&amp;nbsp;status&amp;nbsp;==&amp;nbsp;PublishStatus.ON_SALE:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rep.visible&amp;nbsp;=&amp;nbsp;True

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;④&amp;nbsp;内容审核:&amp;nbsp;敏感词
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;title&amp;nbsp;=&amp;nbsp;item.get(&amp;quot;title&amp;quot;,&amp;nbsp;&amp;quot;&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;desc&amp;nbsp;=&amp;nbsp;item.get(&amp;quot;desc&amp;quot;,&amp;nbsp;&amp;quot;&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;hit&amp;nbsp;=&amp;nbsp;self._scan_sensitive(title&amp;nbsp;+&amp;nbsp;&amp;quot;&amp;nbsp;&amp;quot;&amp;nbsp;+&amp;nbsp;desc)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;hit:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rep.issues.append(f&amp;quot;命中敏感词/极限词:&amp;nbsp;{hit}&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rep.suggestions.append(&amp;quot;改写为合规表述(去引流/去极限/去侵权)&amp;quot;)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;⑤&amp;nbsp;类目资质
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cat&amp;nbsp;=&amp;nbsp;item.get(&amp;quot;category&amp;quot;,&amp;nbsp;&amp;quot;&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;any(c&amp;nbsp;in&amp;nbsp;cat&amp;nbsp;for&amp;nbsp;c&amp;nbsp;in&amp;nbsp;CATEGORY_NEED_QUALIFICATION)&amp;nbsp;and&amp;nbsp;not&amp;nbsp;item.get(&amp;quot;qualified&amp;quot;,&amp;nbsp;False):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rep.issues.append(f&amp;quot;类目&amp;#39;{cat}&amp;#39;需额外资质(授权/认证)&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rep.suggestions.append(&amp;quot;补全类目资质或换普通类目&amp;quot;)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;⑥&amp;nbsp;item_biz_type&amp;nbsp;语义匹配(复用前篇映射规则)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;biz&amp;nbsp;=&amp;nbsp;item.get(&amp;quot;item_biz_type&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sp&amp;nbsp;=&amp;nbsp;item.get(&amp;quot;sp_biz_type&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;is_personal&amp;nbsp;=&amp;nbsp;item.get(&amp;quot;is_personal_idle&amp;quot;,&amp;nbsp;False)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;is_personal&amp;nbsp;and&amp;nbsp;sp:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rep.issues.append(&amp;quot;个人闲置误传sp_biz_type→被识别为商家,&amp;nbsp;流量降权&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rep.suggestions.append(&amp;quot;个人闲置剥掉sp_biz_type/inspected_data(见Mapper)&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;biz&amp;nbsp;==&amp;nbsp;&amp;quot;2&amp;quot;&amp;nbsp;and&amp;nbsp;not&amp;nbsp;is_personal:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rep.issues.append(&amp;quot;item_biz_type=2(个人闲置)但非个人商品,&amp;nbsp;语义矛盾&amp;quot;)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;⑦&amp;nbsp;去重/聚合(简化:&amp;nbsp;同图提示)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;item.get(&amp;quot;duplicate_images&amp;quot;,&amp;nbsp;False):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rep.issues.append(&amp;quot;图片与在售商品高度重复,&amp;nbsp;可能被聚合去重&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rep.suggestions.append(&amp;quot;更换首图/调整标题差异化&amp;quot;)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;最终可见判定:&amp;nbsp;ON_SALE且无致命问题
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;rep.visible&amp;nbsp;and&amp;nbsp;not&amp;nbsp;rep.issues:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rep.visible&amp;nbsp;=&amp;nbsp;True
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;elif&amp;nbsp;rep.visible&amp;nbsp;and&amp;nbsp;any(&amp;quot;驳回&amp;quot;&amp;nbsp;in&amp;nbsp;i&amp;nbsp;or&amp;nbsp;&amp;quot;敏感&amp;quot;&amp;nbsp;in&amp;nbsp;i&amp;nbsp;or&amp;nbsp;&amp;quot;资质&amp;quot;&amp;nbsp;in&amp;nbsp;i&amp;nbsp;for&amp;nbsp;i&amp;nbsp;in&amp;nbsp;rep.issues):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rep.visible&amp;nbsp;=&amp;nbsp;False&amp;nbsp;&amp;nbsp;#&amp;nbsp;在售但有问题→实际不可见

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;rep

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;----&amp;nbsp;批量扫描(运营提效)&amp;nbsp;----
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;batch_scan(self,&amp;nbsp;shop_id:&amp;nbsp;str,&amp;nbsp;items:&amp;nbsp;List[Dict])&amp;nbsp;-&amp;gt;&amp;nbsp;Dict:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;扫一批商品的展示健康度&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;reports&amp;nbsp;=&amp;nbsp;[self.diagnose(shop_id,&amp;nbsp;it[&amp;quot;outer_id&amp;quot;],
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;quot;success&amp;quot;:&amp;nbsp;True},&amp;nbsp;it)&amp;nbsp;for&amp;nbsp;it&amp;nbsp;in&amp;nbsp;items]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;visible&amp;nbsp;=&amp;nbsp;sum(1&amp;nbsp;for&amp;nbsp;r&amp;nbsp;in&amp;nbsp;reports&amp;nbsp;if&amp;nbsp;r.visible)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;by_status:&amp;nbsp;Dict[str,&amp;nbsp;int]&amp;nbsp;=&amp;nbsp;{}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;all_issues:&amp;nbsp;List[str]&amp;nbsp;=&amp;nbsp;[]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;r&amp;nbsp;in&amp;nbsp;reports:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;by_status[r.publish_status.value]&amp;nbsp;=&amp;nbsp;by_status.get(r.publish_status.value,&amp;nbsp;0)&amp;nbsp;+&amp;nbsp;1
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;all_issues.extend([f&amp;quot;{r.outer_id}:&amp;nbsp;{i}&amp;quot;&amp;nbsp;for&amp;nbsp;i&amp;nbsp;in&amp;nbsp;r.issues])
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;total&amp;quot;:&amp;nbsp;len(reports),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;visible&amp;quot;:&amp;nbsp;visible,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;invisible&amp;quot;:&amp;nbsp;len(reports)&amp;nbsp;-&amp;nbsp;visible,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;by_status&amp;quot;:&amp;nbsp;by_status,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;issues&amp;quot;:&amp;nbsp;all_issues[:50],&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;截取前50条
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;----&amp;nbsp;内部&amp;nbsp;----
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;_query_item(self,&amp;nbsp;shop_id:&amp;nbsp;str,&amp;nbsp;outer_id:&amp;nbsp;str)&amp;nbsp;-&amp;gt;&amp;nbsp;Optional[Dict]:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;self.item_getter:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;try:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;self.item_getter(shop_id,&amp;nbsp;outer_id)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;except&amp;nbsp;Exception:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;None
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;演示:&amp;nbsp;模拟回查(生产调&amp;nbsp;alibaba.idle.item.get)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{&amp;quot;publish_status&amp;quot;:&amp;nbsp;&amp;quot;ON_SALE&amp;quot;,&amp;nbsp;&amp;quot;reject_reason&amp;quot;:&amp;nbsp;&amp;quot;&amp;quot;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;_parse_status(self,&amp;nbsp;raw)&amp;nbsp;-&amp;gt;&amp;nbsp;PublishStatus:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;raw&amp;nbsp;is&amp;nbsp;None:&amp;nbsp;return&amp;nbsp;PublishStatus.UNKNOWN
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;s&amp;nbsp;=&amp;nbsp;str(raw).upper()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;try:&amp;nbsp;return&amp;nbsp;PublishStatus(s)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;except&amp;nbsp;ValueError:&amp;nbsp;return&amp;nbsp;PublishStatus.UNKNOWN

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;_scan_sensitive(self,&amp;nbsp;text:&amp;nbsp;str)&amp;nbsp;-&amp;gt;&amp;nbsp;Set[str]:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{w&amp;nbsp;for&amp;nbsp;w&amp;nbsp;in&amp;nbsp;SENSITIVE_WORDS&amp;nbsp;if&amp;nbsp;w&amp;nbsp;in&amp;nbsp;text}
#&amp;nbsp;封装好API供应商demo&amp;nbsp;url=https://console.open.onebound.cn/console/?i=Lex
#&amp;nbsp;====================&amp;nbsp;演示&amp;nbsp;====================
if&amp;nbsp;__name__&amp;nbsp;==&amp;nbsp;&amp;quot;__main__&amp;quot;:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;quota&amp;nbsp;=&amp;nbsp;QuotaTracker(QuotaConfig(daily_limit=80,&amp;nbsp;total_limit=1000))
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;verifier&amp;nbsp;=&amp;nbsp;PublishVerifier(quota=quota)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;模拟今日已发80件(触顶)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;i&amp;nbsp;in&amp;nbsp;range(80):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;quota.mark_published(&amp;quot;shop_001&amp;quot;,&amp;nbsp;f&amp;quot;OUT_{i}&amp;quot;)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;items&amp;nbsp;=&amp;nbsp;[
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;正常商品
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;quot;outer_id&amp;quot;:&amp;nbsp;&amp;quot;OUT_GOOD&amp;quot;,&amp;nbsp;&amp;quot;title&amp;quot;:&amp;nbsp;&amp;quot;二手Kindle&amp;nbsp;99新&amp;quot;,&amp;nbsp;&amp;quot;desc&amp;quot;:&amp;nbsp;&amp;quot;自用&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;category&amp;quot;:&amp;nbsp;&amp;quot;电子&amp;quot;,&amp;nbsp;&amp;quot;item_biz_type&amp;quot;:&amp;nbsp;&amp;quot;2&amp;quot;,&amp;nbsp;&amp;quot;is_personal_idle&amp;quot;:&amp;nbsp;True},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;敏感词
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;quot;outer_id&amp;quot;:&amp;nbsp;&amp;quot;OUT_SENS&amp;quot;,&amp;nbsp;&amp;quot;title&amp;quot;:&amp;nbsp;&amp;quot;高仿劳力士&amp;nbsp;全网最低&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;desc&amp;quot;:&amp;nbsp;&amp;quot;加我VX看货&amp;quot;,&amp;nbsp;&amp;quot;category&amp;quot;:&amp;nbsp;&amp;quot;手表&amp;quot;,&amp;nbsp;&amp;quot;qualified&amp;quot;:&amp;nbsp;True},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;个人闲置误传sp_biz_type
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;quot;outer_id&amp;quot;:&amp;nbsp;&amp;quot;OUT_BIZ&amp;quot;,&amp;nbsp;&amp;quot;title&amp;quot;:&amp;nbsp;&amp;quot;闲置书&amp;quot;,&amp;nbsp;&amp;quot;desc&amp;quot;:&amp;nbsp;&amp;quot;&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;item_biz_type&amp;quot;:&amp;nbsp;&amp;quot;2&amp;quot;,&amp;nbsp;&amp;quot;sp_biz_type&amp;quot;:&amp;nbsp;&amp;quot;21&amp;quot;,&amp;nbsp;&amp;quot;is_personal_idle&amp;quot;:&amp;nbsp;True},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;需资质类目未认证
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;quot;outer_id&amp;quot;:&amp;nbsp;&amp;quot;OUT_QUAL&amp;quot;,&amp;nbsp;&amp;quot;title&amp;quot;:&amp;nbsp;&amp;quot;二手iPhone&amp;quot;,&amp;nbsp;&amp;quot;category&amp;quot;:&amp;nbsp;&amp;quot;手机&amp;quot;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;数量上限
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;quot;outer_id&amp;quot;:&amp;nbsp;&amp;quot;OUT_LIMIT&amp;quot;,&amp;nbsp;&amp;quot;title&amp;quot;:&amp;nbsp;&amp;quot;又一件&amp;quot;,&amp;nbsp;&amp;quot;is_personal_idle&amp;quot;:&amp;nbsp;True},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;审核驳回(模拟回查)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;quot;outer_id&amp;quot;:&amp;nbsp;&amp;quot;OUT_REJ&amp;quot;,&amp;nbsp;&amp;quot;title&amp;quot;:&amp;nbsp;&amp;quot;x&amp;quot;,&amp;nbsp;&amp;quot;is_personal_idle&amp;quot;:&amp;nbsp;True},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;]

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;让驳回商品的回查返回&amp;nbsp;REJECT
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;fake_getter(shop_id,&amp;nbsp;oid):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;oid&amp;nbsp;==&amp;nbsp;&amp;quot;OUT_REJ&amp;quot;:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{&amp;quot;publish_status&amp;quot;:&amp;nbsp;&amp;quot;REJECT&amp;quot;,&amp;nbsp;&amp;quot;reject_reason&amp;quot;:&amp;nbsp;&amp;quot;图片含联系方式&amp;quot;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;oid&amp;nbsp;==&amp;nbsp;&amp;quot;OUT_SENS&amp;quot;:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{&amp;quot;publish_status&amp;quot;:&amp;nbsp;&amp;quot;AUDIT&amp;quot;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{&amp;quot;publish_status&amp;quot;:&amp;nbsp;&amp;quot;ON_SALE&amp;quot;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;verifier.item_getter&amp;nbsp;=&amp;nbsp;fake_getter

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(&amp;quot;===&amp;nbsp;单条排查&amp;nbsp;===&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;it&amp;nbsp;in&amp;nbsp;items:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rep&amp;nbsp;=&amp;nbsp;verifier.diagnose(&amp;quot;shop_001&amp;quot;,&amp;nbsp;it[&amp;quot;outer_id&amp;quot;],&amp;nbsp;{&amp;quot;success&amp;quot;:&amp;nbsp;True},&amp;nbsp;it)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(f&amp;quot;\n[{it[&amp;#39;outer_id&amp;#39;]}]&amp;nbsp;展示={&amp;#39;✅&amp;#39;&amp;nbsp;if&amp;nbsp;rep.visible&amp;nbsp;else&amp;nbsp;&amp;#39;❌&amp;#39;}&amp;nbsp;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;f&amp;quot;状态={rep.publish_status.value}&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;issue&amp;nbsp;in&amp;nbsp;rep.issues:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(f&amp;quot;&amp;nbsp;&amp;nbsp;&amp;nbsp;⚠️&amp;nbsp;{issue}&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;sug&amp;nbsp;in&amp;nbsp;rep.suggestions:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(f&amp;quot;&amp;nbsp;&amp;nbsp;&amp;nbsp;💡&amp;nbsp;{sug}&amp;quot;)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(&amp;quot;\n\n===&amp;nbsp;批量运营扫描&amp;nbsp;===&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;scan&amp;nbsp;=&amp;nbsp;verifier.batch_scan(&amp;quot;shop_001&amp;quot;,&amp;nbsp;items)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(f&amp;quot;总数{scan[&amp;#39;total&amp;#39;]}&amp;nbsp;可见{scan[&amp;#39;visible&amp;#39;]}&amp;nbsp;不可见{scan[&amp;#39;invisible&amp;#39;]}&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(f&amp;quot;状态分布:&amp;nbsp;{scan[&amp;#39;by_status&amp;#39;]}&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(&amp;quot;Top问题:&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;i&amp;nbsp;in&amp;nbsp;scan[&amp;quot;issues&amp;quot;][:8]:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(f&amp;quot;&amp;nbsp;&amp;nbsp;&amp;nbsp;·&amp;nbsp;{i}&amp;quot;)&lt;/pre&gt;&lt;div class=&quot;ybc-p&quot;&gt;跑出来关键几行（正是&amp;quot;成功≠展示&amp;quot;的实证）：&lt;/div&gt;&lt;pre class=&quot;ybc-pre-component ybc-pre-component_not-math&quot;&gt;[OUT_GOOD]&amp;nbsp;展示=✅&amp;nbsp;状态=ON_SALE

[OUT_SENS]&amp;nbsp;展示=❌&amp;nbsp;状态=AUDIT
&amp;nbsp;&amp;nbsp;&amp;nbsp;⚠️&amp;nbsp;审核中,&amp;nbsp;暂未展示
&amp;nbsp;&amp;nbsp;&amp;nbsp;⚠️&amp;nbsp;命中敏感词/极限词:&amp;nbsp;{&amp;#39;高仿&amp;#39;,&amp;nbsp;&amp;#39;全网最低&amp;#39;,&amp;nbsp;&amp;#39;加我&amp;#39;,&amp;nbsp;&amp;#39;VX&amp;#39;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;💡&amp;nbsp;改写为合规表述(去引流/去极限/去侵权)

[OUT_BIZ]&amp;nbsp;展示=❌&amp;nbsp;状态=ON_SALE
&amp;nbsp;&amp;nbsp;&amp;nbsp;⚠️&amp;nbsp;个人闲置误传sp_biz_type→被识别为商家,&amp;nbsp;流量降权
&amp;nbsp;&amp;nbsp;&amp;nbsp;💡&amp;nbsp;个人闲置剥掉sp_biz_type/inspected_data(见Mapper)

[OUT_QUAL]&amp;nbsp;展示=❌&amp;nbsp;状态=ON_SALE
&amp;nbsp;&amp;nbsp;&amp;nbsp;⚠️&amp;nbsp;类目&amp;#39;手机&amp;#39;需额外资质(授权/认证)
&amp;nbsp;&amp;nbsp;&amp;nbsp;💡&amp;nbsp;补全类目资质或换普通类目

[OUT_LIMIT]&amp;nbsp;展示=❌&amp;nbsp;状态=ON_SALE
&amp;nbsp;&amp;nbsp;&amp;nbsp;⚠️&amp;nbsp;每日发布上限(80/天),&amp;nbsp;今日已发80
&amp;nbsp;&amp;nbsp;&amp;nbsp;💡&amp;nbsp;次日发布&amp;nbsp;/&amp;nbsp;提升账号等级认证&amp;nbsp;/&amp;nbsp;多店铺分流

[OUT_REJ]&amp;nbsp;展示=❌&amp;nbsp;状态=REJECT
&amp;nbsp;&amp;nbsp;&amp;nbsp;⚠️&amp;nbsp;审核驳回:&amp;nbsp;图片含联系方式
&amp;nbsp;&amp;nbsp;&amp;nbsp;💡&amp;nbsp;按驳回原因修改后重发

===&amp;nbsp;批量运营扫描&amp;nbsp;===
总数6&amp;nbsp;可见1&amp;nbsp;不可见5
状态分布:&amp;nbsp;{&amp;#39;ON_SALE&amp;#39;:&amp;nbsp;4,&amp;nbsp;&amp;#39;AUDIT&amp;#39;:&amp;nbsp;1,&amp;nbsp;&amp;#39;REJECT&amp;#39;:&amp;nbsp;1}&lt;/pre&gt;&lt;hr/&gt;&lt;h2&gt;五、运营提效包（批量排查 + 自动修复建议）&lt;/h2&gt;&lt;div class=&quot;ybc-p&quot;&gt;把 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;PublishVerifier.batch_scan()&lt;/code&gt; 做成&lt;strong&gt;每日定时任务&lt;/strong&gt;，输出三张表：&lt;/div&gt;&lt;ol style=&quot;list-style-type: decimal;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;展示健康度日报&lt;/strong&gt;：总数/可见/不可见/按状态分布&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;不可见商品清单&lt;/strong&gt;：&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;outer_id + 原因 + 修复建议&lt;/code&gt;，可直接导入运营Excel&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;上限预警&lt;/strong&gt;：今日已发/总量占比 &amp;gt; 80% 自动告警，触发多店铺分流&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div class=&quot;ybc-p&quot;&gt;&lt;strong&gt;自动修复（可安全执行的）&lt;/strong&gt;：&lt;/div&gt;&lt;ul style=&quot;list-style-type: disc;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;敏感词 → 按同义词典自动改写标题（&amp;quot;高仿&amp;quot;→&amp;quot;风格类似&amp;quot;、&amp;quot;全网最低&amp;quot;→删除）&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;草稿态 → 自动调一次 publish 确认上架&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;去重 → 自动换首图/微调标题&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class=&quot;ybc-p&quot;&gt;&lt;strong&gt;需人工介入的&lt;/strong&gt;：类目资质、审核驳回、违规记录——&lt;strong&gt;绝不能自动改&lt;/strong&gt;（改了也算违规）。&lt;/div&gt;&lt;hr/&gt;&lt;h2&gt;六、六个排查铁律&lt;/h2&gt;&lt;ol style=&quot;list-style-type: decimal;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;发布后必回查&lt;/strong&gt;：&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;publish&lt;/code&gt; 成功 100% 要接 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;item.get&lt;/code&gt; 拿 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;publish_status&lt;/code&gt;，不回查=盲飞。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;上限静默截断要主动监控&lt;/strong&gt;：&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;QuotaTracker&lt;/code&gt; 在&lt;strong&gt;发布前&lt;/strong&gt;就检查，超限的&lt;strong&gt;不调接口直接进待发队列次日发&lt;/strong&gt;，别浪费调用额。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;ON_SALE ≠ 真的可见&lt;/strong&gt;：状态在售但命中敏感词/资质问题，&lt;strong&gt;实际仍不可见&lt;/strong&gt;，所以诊断要把&amp;quot;在售+有问题&amp;quot;判为不可见。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;审核是异步的&lt;/strong&gt;：&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;AUDIT&lt;/code&gt; 状态需要轮询（指数退避，别高频查），平均分钟级出结果。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;驳回原因要入库&lt;/strong&gt;：&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;reject_reason&lt;/code&gt; 是运营最值钱的反馈数据，按原因聚类能发现系统性问题（如某类目总被驳回）。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;映射规则前置校验&lt;/strong&gt;：&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;item_biz_type&lt;/code&gt;/敏感词/资质的校验&lt;strong&gt;在 publish 之前&lt;/strong&gt;就跑（复用 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;IdleItemPublishMapper&lt;/code&gt; + &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;ComplianceGate&lt;/code&gt;），失败不进队列，避免&amp;quot;发了才发现不对&amp;quot;。&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;hr/&gt;&lt;h2&gt;七、和前几篇的衔接&lt;/h2&gt;&lt;blockquote&gt;&lt;div class=&quot;ybc-p&quot;&gt;把 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;PublishVerifier&lt;/code&gt; 挂到发布链路的&lt;strong&gt;最后一道闸&lt;/strong&gt;（在 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;IdleItemPublishMapper&lt;/code&gt; 映射之后、&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;TopApiClient.call()&lt;/code&gt; 之后）：&lt;/div&gt;&lt;ul style=&quot;list-style-type: disc;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;发布成功立即 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;diagnose()&lt;/code&gt;，不可见商品进&lt;strong&gt;死信队列&lt;/strong&gt; + 运营告警；&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;QuotaTracker&lt;/code&gt; 复用前篇 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;RateLimiter&lt;/code&gt; 的 Redis 后端（多Worker共享配额计数）；&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;敏感词扫描接入前篇 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;ComplianceGate&lt;/code&gt;（个人数据/采集红线之外的&lt;strong&gt;内容合规&lt;/strong&gt;维度）；&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;批量扫描的 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;by_status&lt;/code&gt; 指标喂 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;ObservabilityMiddleware&lt;/code&gt;，出&amp;quot;展示健康度&amp;quot;Grafana看板；&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;驳回/违规数据回流，帮前篇 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;Double11CommandCenter&lt;/code&gt; 在大促期&lt;strong&gt;自动暂停问题类目发布&lt;/strong&gt;。&lt;br/&gt;&lt;strong&gt;&amp;quot;接口成功&amp;quot;只是起点，&amp;quot;APP可见&amp;quot;才是终点——把中间的七道闸门用代码显式建模，运营才不用靠&amp;quot;刷新APP&amp;quot;来排查。&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/blockquote&gt;&lt;div class=&quot;ybc-p&quot;&gt;要不要我把 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;idle_publish_verifier.py&lt;/code&gt; 合进 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;commerce-mesh/adapters/idle/&lt;/code&gt;，和前几篇的 &lt;strong&gt;授权(TokenManager) → 映射(Mapper) → 限流(RateLimiter) → 发布 → 验证(Verifier) → 发货(Ship) → 退款(Refund)&lt;/strong&gt; 串成完整闭环，并加一个运营后台 API（&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;GET /idle/health?shop_id=xxx&lt;/code&gt; 返回展示健康度报表）？&lt;/div&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</description><pubDate>Wed, 02 Sep 2026 11:10:59 +0800</pubDate></item><item><title>🔑《从0到1：闲鱼开放平台授权登录 + AccessToken 刷新 + 聚石塔部署完整链路》（附Python源码）</title><link>https://alexob.com/?id=517</link><description>&lt;div class=&quot;ybc-p&quot;&gt;官方口径已确认完整，关键事实清晰。现在撰写正文和源码，把整条链路串起来。&lt;/div&gt;&lt;hr/&gt;&lt;h1&gt;🔑《从0到1：闲鱼开放平台授权登录 + AccessToken 刷新 + 聚石塔部署完整链路》（附Python源码）&lt;/h1&gt;&lt;div class=&quot;ybc-p&quot;&gt;&lt;strong&gt;结论先拍&lt;/strong&gt;：闲鱼开放平台&lt;strong&gt;没有独立的授权体系&lt;/strong&gt;——它寄生在&lt;strong&gt;淘宝开放平台（TOP）OAuth 2.0&lt;/strong&gt; 上，走的是标准的&lt;strong&gt;授权码模式&lt;/strong&gt;：&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;authorize&lt;/code&gt; 拿 code → &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;oauth.taobao.com/token&lt;/code&gt; 换 SessionKey（即 access_token）→ 后续调用带 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;session=SessionKey&lt;/code&gt;。 整条链路有四个&amp;quot;死就白干&amp;quot;的卡点：&lt;strong&gt;① code 只能用一次且 5 分钟过期 ② SessionKey 必须按 shop_id 隔离持久化（它是&amp;quot;哪个淘宝账号授权就只能查哪个商家数据&amp;quot;）③ 刷新机制分应用类型——订购类服务商可用 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;taobao.top.auth.token.refresh&lt;/code&gt; 续 r2，自研/固定时长应用只能重新登录授权 ④ 订单/会员数据 + 高风险写 API 强制聚石塔部署，塔外调用直接失败&lt;/strong&gt;。 下面从授权 URL 一路写到生产级 TokenManager + 聚石塔架构准入。&lt;/div&gt;&lt;hr/&gt;&lt;h2&gt;一、完整链路全景图&lt;/h2&gt;&lt;pre class=&quot;ybc-pre-component ybc-pre-component_not-math&quot;&gt;┌────────────────────────────────────────────────────────────────┐
│&amp;nbsp;Step&amp;nbsp;1&amp;nbsp;&amp;nbsp;引导授权&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│
│&amp;nbsp;&amp;nbsp;拼接&amp;nbsp;https://oauth.taobao.com/authorize?response_type=code&amp;nbsp;&amp;nbsp;&amp;nbsp;│
│&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;amp;client_id=APPKEY&amp;nbsp;&amp;amp;redirect_uri=CALLBACK&amp;nbsp;&amp;amp;state=xxx&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│
│&amp;nbsp;&amp;nbsp;↓&amp;nbsp;用户登录淘宝/闲鱼账号&amp;nbsp;→&amp;nbsp;点击授权&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│
├────────────────────────────────────────────────────────────────┤
│&amp;nbsp;Step&amp;nbsp;2&amp;nbsp;&amp;nbsp;回调&amp;nbsp;+&amp;nbsp;code&amp;nbsp;换&amp;nbsp;SessionKey&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│
│&amp;nbsp;&amp;nbsp;POST&amp;nbsp;https://oauth.taobao.com/token&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│
│&amp;nbsp;&amp;nbsp;&amp;nbsp;grant_type=authorization_code,&amp;nbsp;code,&amp;nbsp;client_id,&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│
│&amp;nbsp;&amp;nbsp;&amp;nbsp;client_secret,&amp;nbsp;redirect_uri&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│
│&amp;nbsp;&amp;nbsp;←&amp;nbsp;{&amp;nbsp;access_token(SessionKey),&amp;nbsp;expires_in,&amp;nbsp;refresh_token,&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│
│&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;re_expires_in,&amp;nbsp;taobao_user_id,&amp;nbsp;taobao_user_nick&amp;nbsp;}&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│
├────────────────────────────────────────────────────────────────┤
│&amp;nbsp;Step&amp;nbsp;3&amp;nbsp;&amp;nbsp;持久化&amp;nbsp;+&amp;nbsp;调用&amp;nbsp;API&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│
│&amp;nbsp;&amp;nbsp;每次&amp;nbsp;TOP&amp;nbsp;调用:&amp;nbsp;session&amp;nbsp;=&amp;nbsp;SessionKey&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│
│&amp;nbsp;&amp;nbsp;按&amp;nbsp;shop_id&amp;nbsp;/&amp;nbsp;taobao_user_id&amp;nbsp;维度缓存&amp;nbsp;Token&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│
├────────────────────────────────────────────────────────────────┤
│&amp;nbsp;Step&amp;nbsp;4&amp;nbsp;&amp;nbsp;刷新（分应用类型）&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│
│&amp;nbsp;&amp;nbsp;·&amp;nbsp;订购类服务商:&amp;nbsp;taobao.top.auth.token.refresh&amp;nbsp;(续&amp;nbsp;r2)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│
│&amp;nbsp;&amp;nbsp;·&amp;nbsp;自研/固定时长:&amp;nbsp;重新登录授权&amp;nbsp;(force_auth=true)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│
├────────────────────────────────────────────────────────────────┤
│&amp;nbsp;Step&amp;nbsp;5&amp;nbsp;&amp;nbsp;聚石塔部署（强制）&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│
│&amp;nbsp;&amp;nbsp;·&amp;nbsp;订单/会员数据存塔内&amp;nbsp;RDS&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│
│&amp;nbsp;&amp;nbsp;·&amp;nbsp;高风险写&amp;nbsp;API&amp;nbsp;从塔内发起&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│
│&amp;nbsp;&amp;nbsp;·&amp;nbsp;塔内→塔外&amp;nbsp;须走奇门标准接口审批&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│
└────────────────────────────────────────────────────────────────┘&lt;/pre&gt;&lt;blockquote&gt;&lt;div class=&quot;ybc-p&quot;&gt;关键认知：&lt;strong&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;access_token&lt;/code&gt; 就是 SessionKey，两套叫法同一个东西&lt;/strong&gt;。淘宝官方文档原文：&amp;quot;平台会返回用户授权码 SessionKey（即 access_token）&amp;quot;。&lt;/div&gt;&lt;/blockquote&gt;&lt;hr/&gt;&lt;h2&gt;二、授权登录：授权码模式（Step 1 + 2）&lt;/h2&gt;&lt;h3&gt;2.1 拼接授权 URL（引导用户登录）&lt;/h3&gt;&lt;pre class=&quot;ybc-pre-component ybc-pre-component_not-math&quot;&gt;https://oauth.taobao.com/authorize?
&amp;nbsp;&amp;nbsp;response_type=code
&amp;nbsp;&amp;nbsp;&amp;amp;client_id=你的AppKey
&amp;nbsp;&amp;nbsp;&amp;amp;redirect_uri=你的回调地址
&amp;nbsp;&amp;nbsp;&amp;amp;state=随机值(防CSRF)
&amp;nbsp;&amp;nbsp;&amp;amp;view=web&lt;/pre&gt;&lt;ul style=&quot;list-style-type: disc;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;闲鱼合作方有两种拿 code 的方式：&lt;/p&gt;&lt;/li&gt;&lt;ul style=&quot;list-style-type: square;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;传统 Web&lt;/strong&gt;：跳转 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;oauth.taobao.0.com/authorize&lt;/code&gt;，授权后跳回调页带 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;?code=xxx&amp;amp;state=xxx&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;小程序新接入&lt;/strong&gt;：前端组件直接获取 code（如闲鱼小程序客户端 API），不用跳回调&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&lt;p&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;state&lt;/code&gt; 必须原样带回，防 CSRF；&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;redirect_uri&lt;/code&gt; 必须与控制台配置&lt;strong&gt;完全一致&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;2.2 code 换 SessionKey&lt;/h3&gt;&lt;pre class=&quot;ybc-pre-component ybc-pre-component_not-math&quot;&gt;POST&amp;nbsp;https://oauth.taobao.com/token
Content-Type:&amp;nbsp;application/x-www-form-urlencoded

grant_type=authorization_code
&amp;amp;code=上一步的code
&amp;amp;client_id=AppKey
&amp;amp;client_secret=AppSecret
&amp;amp;redirect_uri=回调地址&lt;/pre&gt;&lt;div class=&quot;ybc-p&quot;&gt;成功响应：&lt;/div&gt;&lt;pre class=&quot;ybc-pre-component ybc-pre-component_not-math&quot;&gt;{
&amp;nbsp;&amp;nbsp;&amp;quot;access_token&amp;quot;:&amp;nbsp;&amp;quot;6101_UMIdX...&amp;quot;,&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;←&amp;nbsp;这就是&amp;nbsp;SessionKey
&amp;nbsp;&amp;nbsp;&amp;quot;token_type&amp;quot;:&amp;nbsp;&amp;quot;Bearer&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;quot;expires_in&amp;quot;:&amp;nbsp;86400,&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;access_token&amp;nbsp;有效期(秒)
&amp;nbsp;&amp;nbsp;&amp;quot;refresh_token&amp;quot;:&amp;nbsp;&amp;quot;xxx&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;quot;re_expires_in&amp;quot;:&amp;nbsp;7200,&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;refresh_token&amp;nbsp;有效期
&amp;nbsp;&amp;nbsp;&amp;quot;taobao_user_id&amp;quot;:&amp;nbsp;&amp;quot;12345678&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;quot;taobao_user_nick&amp;quot;:&amp;nbsp;&amp;quot;卖家昵称&amp;quot;
}&lt;/pre&gt;&lt;blockquote&gt;&lt;div class=&quot;ybc-p&quot;&gt;⚠️ &lt;strong&gt;code 一次性 + 5 分钟过期&lt;/strong&gt;：被用过或过期必须重新获取；&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;AppSecret&lt;/code&gt; &lt;strong&gt;绝不能出现在 URL 里，只能放 POST body&lt;/strong&gt;。&lt;/div&gt;&lt;/blockquote&gt;&lt;hr/&gt;&lt;h2&gt;三、Token 刷新：分应用类型的坑（Step 4）&lt;/h2&gt;&lt;div class=&quot;ybc-p&quot;&gt;这是最容易踩的雷，官方说得很清楚：&lt;/div&gt;&lt;div class=&quot;hyc-common-markdown__table-wrapper&quot; data-has-scroll=&quot;false&quot; style=&quot;font-size: 16px; border-collapse: separate; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;div style=&quot;font-size: 16px; border-collapse: separate; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;table&gt;&lt;thead style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot; class=&quot;firstRow&quot;&gt;&lt;th style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;应用类型&lt;/div&gt;&lt;/th&gt;&lt;th style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;能否用 refresh_token 续期&lt;/div&gt;&lt;/th&gt;&lt;th style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;正确做法&lt;/div&gt;&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;订购类服务商&lt;/strong&gt;（发布到服务市场售卖）&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;✅ &lt;code class=&quot;hyc-common-markdown__code__inline&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 2px 4px;&quot;&gt;taobao.top.auth.token.refresh&lt;/code&gt; 续 &lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;r2 时长&lt;/strong&gt;&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;续期 r2，r1/w1 同订购时长一般不用续&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;自研 / 固定时长&lt;/strong&gt;（商家后台、新业务）&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;❌ &lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;不支持&lt;/strong&gt; refresh 延长总时长&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;重新登录授权，或 &lt;code class=&quot;hyc-common-markdown__code__inline&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 2px 4px;&quot;&gt;force_auth=true&lt;/code&gt; 刷新有效时间&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ybc-p&quot;&gt;&lt;strong&gt;核心规则&lt;/strong&gt;：&lt;/div&gt;&lt;ul style=&quot;list-style-type: disc;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;refresh_token&lt;/code&gt; 只续 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;access_token&lt;/code&gt; 的 &lt;strong&gt;r2 时长&lt;/strong&gt;，不是总授权时长&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;refresh_expires_in = 0&lt;/code&gt; → 无法刷新，必须重新授权&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;建议&lt;strong&gt;过期前（约 30 分钟~1 周，视应用时效档位）主动刷新&lt;/strong&gt;，不要等 401&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;官方时效档位：测试环境 24h / 上线环境 code 30 分钟、access_token 30 天、refresh_token 60~180 天&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;hr/&gt;&lt;h2&gt;四、聚石塔部署强制规则（Step 5）&lt;/h2&gt;&lt;div class=&quot;ybc-p&quot;&gt;&lt;strong&gt;只要你的应用标签属于 ERP/进销存、订单管理、WMS、CRM、商品管理、电商财务等 23 类之一，必须入驻聚石塔&lt;/strong&gt;。关键准入规则：&lt;/div&gt;&lt;ol style=&quot;list-style-type: decimal;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;系统部署&lt;/strong&gt;：ECS + RDS，应用跑 ECS，&lt;strong&gt;数据库只放 RDS&lt;/strong&gt;（DB 不准装 ECS 上）&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;数据存储&lt;/strong&gt;：&lt;strong&gt;订单 + 会员数据必须存塔内 RDS&lt;/strong&gt;，禁止通过自有接口二次开放到塔外&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;API 调用&lt;/strong&gt;：&lt;strong&gt;所有 TOP 调用必须从塔内发起&lt;/strong&gt;；高风险写 API（改价、优惠）必须从塔内发起&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;塔内→塔外&lt;/strong&gt;：默认禁止，确有需要走&lt;strong&gt;奇门标准接口&lt;/strong&gt;体系 + 平台审批&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;架构&lt;/strong&gt;：三层架构，业务逻辑服务端 ECS、数据层 RDS、客户端只做展现&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;应用隔离&lt;/strong&gt;：不同应用必须不同 AppKey + 不同 ECS，&lt;strong&gt;御城河安全边界隔离&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;blockquote&gt;&lt;div class=&quot;ybc-p&quot;&gt;闲鱼合作方官方文档明确：&amp;quot;由于集团安全规则，需接入聚石塔后进行调用，&lt;strong&gt;用户 id、订单信息等必须存储在聚石塔内的数据库中&lt;/strong&gt;&amp;quot;。&lt;/div&gt;&lt;/blockquote&gt;&lt;hr/&gt;&lt;h2&gt;五、Python：完整生产级实现&lt;/h2&gt;&lt;pre class=&quot;ybc-pre-component ybc-pre-component_not-math&quot;&gt;#&amp;nbsp;xianyu_auth_platform.py
&amp;quot;&amp;quot;&amp;quot;
闲鱼开放平台(淘宝TOP&amp;nbsp;OAuth2.0)&amp;nbsp;完整链路
-&amp;nbsp;Step1:&amp;nbsp;授权URL生成&amp;nbsp;+&amp;nbsp;state(CSRF)校验
-&amp;nbsp;Step2:&amp;nbsp;code&amp;nbsp;换&amp;nbsp;SessionKey&amp;nbsp;(access_token)
-&amp;nbsp;Step3:&amp;nbsp;TokenManager&amp;nbsp;(按shop_id持久化&amp;nbsp;+&amp;nbsp;自动刷新&amp;nbsp;+&amp;nbsp;提前续期)
-&amp;nbsp;Step4:&amp;nbsp;TOP&amp;nbsp;API&amp;nbsp;调用封装&amp;nbsp;(自动注入session&amp;nbsp;+&amp;nbsp;签名)
-&amp;nbsp;Step5:&amp;nbsp;聚石塔部署合规性自检
&amp;quot;&amp;quot;&amp;quot;
import&amp;nbsp;time,&amp;nbsp;hashlib,&amp;nbsp;json,&amp;nbsp;threading,&amp;nbsp;secrets
from&amp;nbsp;typing&amp;nbsp;import&amp;nbsp;Dict,&amp;nbsp;Optional,&amp;nbsp;Any
from&amp;nbsp;dataclasses&amp;nbsp;import&amp;nbsp;dataclass,&amp;nbsp;field
from&amp;nbsp;abc&amp;nbsp;import&amp;nbsp;ABC,&amp;nbsp;abstractmethod
from&amp;nbsp;enum&amp;nbsp;import&amp;nbsp;Enum
import&amp;nbsp;urllib.parse

#&amp;nbsp;====================&amp;nbsp;配置&amp;nbsp;====================
@dataclass
class&amp;nbsp;XianyuConfig:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;app_key:&amp;nbsp;str&amp;nbsp;=&amp;nbsp;&amp;quot;你的AppKey&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;app_secret:&amp;nbsp;str&amp;nbsp;=&amp;nbsp;&amp;quot;你的AppSecret&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;redirect_uri:&amp;nbsp;str&amp;nbsp;=&amp;nbsp;&amp;quot;https://yourdomain.com/xianyu/callback&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;沙箱用&amp;nbsp;gw.api.tbsandbox.com；生产用&amp;nbsp;gw.api.taobao.com
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;api_gateway:&amp;nbsp;str&amp;nbsp;=&amp;nbsp;&amp;quot;https://gw.api.taobao.com/router/rest&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;auth_url:&amp;nbsp;str&amp;nbsp;=&amp;nbsp;&amp;quot;https://oauth.taobao.com/authorize&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;token_url:&amp;nbsp;str&amp;nbsp;=&amp;nbsp;&amp;quot;https://oauth.taobao.com/token&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;is_sandbox:&amp;nbsp;bool&amp;nbsp;=&amp;nbsp;False


#&amp;nbsp;====================&amp;nbsp;应用类型（决定刷新策略）====================
class&amp;nbsp;AppType(Enum):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;SELF_USE&amp;nbsp;=&amp;nbsp;&amp;quot;self_use&amp;quot;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;自研/固定时长&amp;nbsp;→&amp;nbsp;只能重新授权
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;PURCHASE_SERVICE&amp;nbsp;=&amp;nbsp;&amp;quot;purchase&amp;quot;&amp;nbsp;&amp;nbsp;#&amp;nbsp;订购类服务商&amp;nbsp;→&amp;nbsp;可refresh续r2


#&amp;nbsp;====================&amp;nbsp;Token&amp;nbsp;数据&amp;nbsp;====================
@dataclass
class&amp;nbsp;TokenSet:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;shop_id:&amp;nbsp;str
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;taobao_user_id:&amp;nbsp;str
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;access_token:&amp;nbsp;str&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;=&amp;nbsp;SessionKey
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;refresh_token:&amp;nbsp;str
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;expires_in:&amp;nbsp;int&amp;nbsp;=&amp;nbsp;86400
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;re_expires_in:&amp;nbsp;int&amp;nbsp;=&amp;nbsp;0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;refresh_token有效期,&amp;nbsp;0=不可刷新
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;created_at:&amp;nbsp;float&amp;nbsp;=&amp;nbsp;field(default_factory=time.time)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;app_type:&amp;nbsp;AppType&amp;nbsp;=&amp;nbsp;AppType.SELF_USE

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;@property
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;expires_at(self)&amp;nbsp;-&amp;gt;&amp;nbsp;float:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;self.created_at&amp;nbsp;+&amp;nbsp;self.expires_in

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;needs_refresh(self,&amp;nbsp;ahead_sec:&amp;nbsp;int&amp;nbsp;=&amp;nbsp;1800)&amp;nbsp;-&amp;gt;&amp;nbsp;bool:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;提前&amp;nbsp;ahead_sec&amp;nbsp;秒触发刷新&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;time.time()&amp;nbsp;&amp;gt;=&amp;nbsp;(self.expires_at&amp;nbsp;-&amp;nbsp;ahead_sec)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;can_refresh(self)&amp;nbsp;-&amp;gt;&amp;nbsp;bool:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;refresh_token&amp;nbsp;是否仍有效&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;self.re_expires_in&amp;nbsp;&amp;lt;=&amp;nbsp;0:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;False
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;(self.created_at&amp;nbsp;+&amp;nbsp;self.re_expires_in)&amp;nbsp;&amp;gt;&amp;nbsp;time.time()


#&amp;nbsp;====================&amp;nbsp;Step1&amp;nbsp;+&amp;nbsp;Step2:&amp;nbsp;授权客户端&amp;nbsp;====================
class&amp;nbsp;XianyuAuthClient:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;授权登录全流程&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;__init__(self,&amp;nbsp;config:&amp;nbsp;XianyuConfig):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.cfg&amp;nbsp;=&amp;nbsp;config

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;build_authorize_url(self,&amp;nbsp;state:&amp;nbsp;Optional[str]&amp;nbsp;=&amp;nbsp;None,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;force_auth:&amp;nbsp;bool&amp;nbsp;=&amp;nbsp;False)&amp;nbsp;-&amp;gt;&amp;nbsp;tuple[str,&amp;nbsp;str]:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;Step1:&amp;nbsp;生成授权URL&amp;nbsp;+&amp;nbsp;返回state供校验&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;state&amp;nbsp;=&amp;nbsp;state&amp;nbsp;or&amp;nbsp;secrets.token_urlsafe(16)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;params&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;response_type&amp;quot;:&amp;nbsp;&amp;quot;code&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;client_id&amp;quot;:&amp;nbsp;self.cfg.app_key,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;redirect_uri&amp;quot;:&amp;nbsp;self.cfg.redirect_uri,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;state&amp;quot;:&amp;nbsp;state,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;view&amp;quot;:&amp;nbsp;&amp;quot;web&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;force_auth:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;params[&amp;quot;force_auth&amp;quot;]&amp;nbsp;=&amp;nbsp;&amp;quot;true&amp;quot;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;强制重新授权(刷新有效时间)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;url&amp;nbsp;=&amp;nbsp;f&amp;quot;{self.cfg.auth_url}?{urllib.parse.urlencode(params)}&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;url,&amp;nbsp;state

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;verify_state(self,&amp;nbsp;returned:&amp;nbsp;str,&amp;nbsp;expected:&amp;nbsp;str)&amp;nbsp;-&amp;gt;&amp;nbsp;bool:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;防CSRF:&amp;nbsp;state必须原样匹配&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;returned&amp;nbsp;==&amp;nbsp;expected&amp;nbsp;and&amp;nbsp;bool(expected)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;exchange_code(self,&amp;nbsp;code:&amp;nbsp;str)&amp;nbsp;-&amp;gt;&amp;nbsp;TokenSet:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;Step2:&amp;nbsp;code&amp;nbsp;换&amp;nbsp;SessionKey&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;not&amp;nbsp;code:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;raise&amp;nbsp;ValueError(&amp;quot;code&amp;nbsp;不能为空(code只能用一次且5分钟过期)&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;生产:&amp;nbsp;requests.post(self.cfg.token_url,&amp;nbsp;data=payload)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;这里演示返回结构
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;payload&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;grant_type&amp;quot;:&amp;nbsp;&amp;quot;authorization_code&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;code&amp;quot;:&amp;nbsp;code,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;client_id&amp;quot;:&amp;nbsp;self.cfg.app_key,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;client_secret&amp;quot;:&amp;nbsp;self.cfg.app_secret,&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;★&amp;nbsp;body,&amp;nbsp;绝不放URL
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;redirect_uri&amp;quot;:&amp;nbsp;self.cfg.redirect_uri,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;mock&amp;nbsp;response
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;resp&amp;nbsp;=&amp;nbsp;self._mock_token_response(code)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;TokenSet(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;shop_id=resp[&amp;quot;taobao_user_id&amp;quot;],
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;taobao_user_id=resp[&amp;quot;taobao_user_id&amp;quot;],
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;access_token=resp[&amp;quot;access_token&amp;quot;],
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;refresh_token=resp.get(&amp;quot;refresh_token&amp;quot;,&amp;nbsp;&amp;quot;&amp;quot;),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;expires_in=resp.get(&amp;quot;expires_in&amp;quot;,&amp;nbsp;86400),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;re_expires_in=resp.get(&amp;quot;re_expires_in&amp;quot;,&amp;nbsp;0),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;_mock_token_response(self,&amp;nbsp;code:&amp;nbsp;str)&amp;nbsp;-&amp;gt;&amp;nbsp;Dict:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;access_token&amp;quot;:&amp;nbsp;f&amp;quot;6101_{code[:10]}&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;refresh_token&amp;quot;:&amp;nbsp;f&amp;quot;refresh_{code[:6]}&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;expires_in&amp;quot;:&amp;nbsp;86400,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;re_expires_in&amp;quot;:&amp;nbsp;7776000,&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;90天
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;taobao_user_id&amp;quot;:&amp;nbsp;&amp;quot;12345678&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;taobao_user_nick&amp;quot;:&amp;nbsp;&amp;quot;seller_nick&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
#&amp;nbsp;封装好API供应商demo&amp;nbsp;url=https://console.open.onebound.cn/console/?i=Lex

#&amp;nbsp;====================&amp;nbsp;Step3:&amp;nbsp;Token&amp;nbsp;管理器&amp;nbsp;====================
class&amp;nbsp;TokenStore(ABC):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;持久化接口&amp;nbsp;(DB/Redis实现替换)&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;@abstractmethod
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;load(self,&amp;nbsp;shop_id:&amp;nbsp;str)&amp;nbsp;-&amp;gt;&amp;nbsp;Optional[TokenSet]:&amp;nbsp;...
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;@abstractmethod
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;save(self,&amp;nbsp;token:&amp;nbsp;TokenSet):&amp;nbsp;...


class&amp;nbsp;MemoryTokenStore(TokenStore):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;__init__(self):&amp;nbsp;self._d:&amp;nbsp;Dict[str,&amp;nbsp;TokenSet]&amp;nbsp;=&amp;nbsp;{}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;load(self,&amp;nbsp;shop_id):&amp;nbsp;return&amp;nbsp;self._d.get(shop_id)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;save(self,&amp;nbsp;token):&amp;nbsp;self._d[token.shop_id]&amp;nbsp;=&amp;nbsp;token


class&amp;nbsp;TokenManager:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;按shop_id管理Token&amp;nbsp;+&amp;nbsp;自动刷新&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;__init__(self,&amp;nbsp;auth:&amp;nbsp;XianyuAuthClient,&amp;nbsp;store:&amp;nbsp;TokenStore,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;app_type:&amp;nbsp;AppType&amp;nbsp;=&amp;nbsp;AppType.SELF_USE,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;refresh_ahead_sec:&amp;nbsp;int&amp;nbsp;=&amp;nbsp;1800):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.auth&amp;nbsp;=&amp;nbsp;auth
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.store&amp;nbsp;=&amp;nbsp;store
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.app_type&amp;nbsp;=&amp;nbsp;app_type
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.ahead&amp;nbsp;=&amp;nbsp;refresh_ahead_sec
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self._lock&amp;nbsp;=&amp;nbsp;threading.Lock()

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;get(self,&amp;nbsp;shop_id:&amp;nbsp;str)&amp;nbsp;-&amp;gt;&amp;nbsp;Optional[TokenSet]:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;获取有效Token,&amp;nbsp;过期则自动刷新&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;token&amp;nbsp;=&amp;nbsp;self.store.load(shop_id)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;token&amp;nbsp;is&amp;nbsp;None:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;None
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;token.app_type&amp;nbsp;=&amp;nbsp;self.app_type
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;not&amp;nbsp;token.needs_refresh(self.ahead):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;token
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;需要刷新
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;self._refresh(token)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;_refresh(self,&amp;nbsp;token:&amp;nbsp;TokenSet)&amp;nbsp;-&amp;gt;&amp;nbsp;Optional[TokenSet]:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;with&amp;nbsp;self._lock:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;双检
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fresh&amp;nbsp;=&amp;nbsp;self.store.load(token.shop_id)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;fresh&amp;nbsp;and&amp;nbsp;not&amp;nbsp;fresh.needs_refresh(self.ahead):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;fresh
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;self.app_type&amp;nbsp;==&amp;nbsp;AppType.PURCHASE_SERVICE&amp;nbsp;and&amp;nbsp;token.can_refresh():
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;订购类:&amp;nbsp;调&amp;nbsp;taobao.top.auth.token.refresh&amp;nbsp;续&amp;nbsp;r2
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;new_set&amp;nbsp;=&amp;nbsp;self._call_refresh_api(token.refresh_token)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;new_set.shop_id&amp;nbsp;=&amp;nbsp;token.shop_id
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.store.save(new_set)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;new_set
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;自研/固定时长:&amp;nbsp;refresh无法延长总时长&amp;nbsp;→&amp;nbsp;需重新授权
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;raise&amp;nbsp;TokenRefreshRequired(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;f&amp;quot;shop={token.shop_id}&amp;nbsp;需重新授权(force_auth=true重新登录)&amp;quot;)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;_call_refresh_api(self,&amp;nbsp;refresh_token:&amp;nbsp;str)&amp;nbsp;-&amp;gt;&amp;nbsp;TokenSet:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;taobao.top.auth.token.refresh&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;生产:&amp;nbsp;调用&amp;nbsp;TOP&amp;nbsp;接口;&amp;nbsp;这里演示
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;grant_type=refresh_token,&amp;nbsp;refresh_token=xxx,&amp;nbsp;client_id,&amp;nbsp;client_secret
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;TokenSet(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;shop_id=&amp;quot;&amp;quot;,&amp;nbsp;taobao_user_id=&amp;quot;&amp;quot;,&amp;nbsp;access_token=f&amp;quot;new_{int(time.time())}&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;refresh_token=refresh_token,&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;★&amp;nbsp;换新access,&amp;nbsp;refresh通常不变或也换
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;expires_in=86400,&amp;nbsp;re_expires_in=7776000,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;app_type=AppType.PURCHASE_SERVICE,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;on_callback(self,&amp;nbsp;shop_id:&amp;nbsp;str,&amp;nbsp;code:&amp;nbsp;str,&amp;nbsp;state:&amp;nbsp;str,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;expected_state:&amp;nbsp;str)&amp;nbsp;-&amp;gt;&amp;nbsp;TokenSet:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;授权回调入口&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;not&amp;nbsp;self.auth.verify_state(state,&amp;nbsp;expected_state):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;raise&amp;nbsp;ValueError(&amp;quot;state校验失败(CSRF风险)&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;token&amp;nbsp;=&amp;nbsp;self.auth.exchange_code(code)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;token.shop_id&amp;nbsp;=&amp;nbsp;shop_id
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;token.app_type&amp;nbsp;=&amp;nbsp;self.app_type
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.store.save(token)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;token


class&amp;nbsp;TokenRefreshRequired(Exception):&amp;nbsp;pass

#&amp;nbsp;封装好API供应商demo&amp;nbsp;url=https://console.open.onebound.cn/console/?i=Lex
#&amp;nbsp;====================&amp;nbsp;Step3续:&amp;nbsp;TOP&amp;nbsp;API&amp;nbsp;调用封装&amp;nbsp;====================
class&amp;nbsp;TopApiClient:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;自动注入session(SessionKey)&amp;nbsp;+&amp;nbsp;MD5签名&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;__init__(self,&amp;nbsp;config:&amp;nbsp;XianyuConfig,&amp;nbsp;token_mgr:&amp;nbsp;TokenManager):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.cfg&amp;nbsp;=&amp;nbsp;config
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.tokens&amp;nbsp;=&amp;nbsp;token_mgr

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;call(self,&amp;nbsp;method:&amp;nbsp;str,&amp;nbsp;shop_id:&amp;nbsp;str,&amp;nbsp;params:&amp;nbsp;Dict)&amp;nbsp;-&amp;gt;&amp;nbsp;Dict:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;token&amp;nbsp;=&amp;nbsp;self.tokens.get(shop_id)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;token&amp;nbsp;is&amp;nbsp;None:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;raise&amp;nbsp;TokenRefreshRequired(f&amp;quot;shop={shop_id}&amp;nbsp;未授权&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;组装签名
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;all_params&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;method&amp;quot;:&amp;nbsp;method,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;app_key&amp;quot;:&amp;nbsp;self.cfg.app_key,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;session&amp;quot;:&amp;nbsp;token.access_token,&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;★&amp;nbsp;SessionKey&amp;nbsp;=&amp;nbsp;access_token
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;timestamp&amp;quot;:&amp;nbsp;time.strftime(&amp;quot;%Y-%m-%d&amp;nbsp;%H:%M:%S&amp;quot;),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;format&amp;quot;:&amp;nbsp;&amp;quot;json&amp;quot;,&amp;nbsp;&amp;quot;v&amp;quot;:&amp;nbsp;&amp;quot;2.0&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;**{k:&amp;nbsp;v&amp;nbsp;for&amp;nbsp;k,&amp;nbsp;v&amp;nbsp;in&amp;nbsp;params.items()&amp;nbsp;if&amp;nbsp;v&amp;nbsp;is&amp;nbsp;not&amp;nbsp;None},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;all_params[&amp;quot;sign&amp;quot;]&amp;nbsp;=&amp;nbsp;self._sign(all_params)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;生产:&amp;nbsp;requests.post(gateway,&amp;nbsp;data=all_params)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{&amp;quot;_mock&amp;quot;:&amp;nbsp;True,&amp;nbsp;&amp;quot;url&amp;quot;:&amp;nbsp;self.cfg.api_gateway,&amp;nbsp;&amp;quot;method&amp;quot;:&amp;nbsp;method,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;session&amp;quot;:&amp;nbsp;token.access_token[:8]&amp;nbsp;+&amp;nbsp;&amp;quot;...&amp;quot;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;_sign(self,&amp;nbsp;params:&amp;nbsp;Dict)&amp;nbsp;-&amp;gt;&amp;nbsp;str:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;s&amp;nbsp;=&amp;nbsp;self.cfg.app_secret&amp;nbsp;+&amp;nbsp;&amp;quot;&amp;quot;.join(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;f&amp;quot;{k}{params[k]}&amp;quot;&amp;nbsp;for&amp;nbsp;k&amp;nbsp;in&amp;nbsp;sorted(params)&amp;nbsp;if&amp;nbsp;params[k]&amp;nbsp;is&amp;nbsp;not&amp;nbsp;None)&amp;nbsp;+&amp;nbsp;self.cfg.app_secret
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;hashlib.md5(s.encode()).hexdigest().upper()


#&amp;nbsp;====================&amp;nbsp;Step5:&amp;nbsp;聚石塔合规自检&amp;nbsp;====================
@dataclass
class&amp;nbsp;JushitaCheck:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;app_tags:&amp;nbsp;list&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;应用标签,&amp;nbsp;如&amp;nbsp;[&amp;quot;ERP&amp;quot;,&amp;nbsp;&amp;quot;订单管理&amp;quot;]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;data_in_rds:&amp;nbsp;bool&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;订单/会员是否存塔内RDS
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;api_from_inside:&amp;nbsp;bool&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;TOP调用是否塔内发起
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;write_from_inside:&amp;nbsp;bool&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;高风险写是否塔内
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cross_tower_via_qimen:&amp;nbsp;bool&amp;nbsp;&amp;nbsp;#&amp;nbsp;塔外交互是否走奇门
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;three_tier:&amp;nbsp;bool&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;是否三层架构
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;yc_isolation:&amp;nbsp;bool&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;御城河隔离

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;FORCE_TAGS&amp;nbsp;=&amp;nbsp;{&amp;quot;ERP/进销存软件&amp;quot;,&amp;quot;订单管理&amp;quot;,&amp;quot;仓储管理系统&amp;quot;,&amp;quot;客户关系管理&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;商品管理&amp;quot;,&amp;quot;电商财务&amp;quot;,&amp;quot;全渠道ERP&amp;quot;,&amp;quot;行业/店铺分析&amp;quot;,&amp;quot;服务商后台系统&amp;quot;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;evaluate(self)&amp;nbsp;-&amp;gt;&amp;nbsp;Dict:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;must&amp;nbsp;=&amp;nbsp;any(t&amp;nbsp;in&amp;nbsp;self.FORCE_TAGS&amp;nbsp;for&amp;nbsp;t&amp;nbsp;in&amp;nbsp;self.app_tags)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;issues&amp;nbsp;=&amp;nbsp;[]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;must:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;not&amp;nbsp;self.data_in_rds:&amp;nbsp;issues.append(&amp;quot;订单/会员数据必须存塔内RDS&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;not&amp;nbsp;self.api_from_inside:&amp;nbsp;issues.append(&amp;quot;TOP&amp;nbsp;API调用必须从塔内发起&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;not&amp;nbsp;self.write_from_inside:&amp;nbsp;issues.append(&amp;quot;高风险写API必须从塔内发起&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;not&amp;nbsp;self.three_tier:&amp;nbsp;issues.append(&amp;quot;须三层架构(客户端只展现)&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;not&amp;nbsp;self.yc_isolation:&amp;nbsp;issues.append(&amp;quot;须配置御城河安全边界隔离&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;not&amp;nbsp;self.cross_tower_via_qimen:&amp;nbsp;issues.append(&amp;quot;塔外交互须走奇门标准接口+审批&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;must_jushita&amp;quot;:&amp;nbsp;must,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;pass&amp;quot;:&amp;nbsp;len(issues)&amp;nbsp;==&amp;nbsp;0,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;issues&amp;quot;:&amp;nbsp;issues,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}


#&amp;nbsp;====================&amp;nbsp;演示&amp;nbsp;====================
if&amp;nbsp;__name__&amp;nbsp;==&amp;nbsp;&amp;quot;__main__&amp;quot;:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cfg&amp;nbsp;=&amp;nbsp;XianyuConfig(app_key=&amp;quot;test_key&amp;quot;,&amp;nbsp;app_secret=&amp;quot;test_secret&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;is_sandbox=True)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;auth&amp;nbsp;=&amp;nbsp;XianyuAuthClient(cfg)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;store&amp;nbsp;=&amp;nbsp;MemoryTokenStore()

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(&amp;quot;===&amp;nbsp;Step1:&amp;nbsp;生成授权URL&amp;nbsp;===&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;url,&amp;nbsp;state&amp;nbsp;=&amp;nbsp;auth.build_authorize_url(force_auth=True)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(f&amp;quot;&amp;nbsp;&amp;nbsp;授权URL:&amp;nbsp;{url[:120]}...&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(f&amp;quot;&amp;nbsp;&amp;nbsp;state(存session,&amp;nbsp;回调时校验):&amp;nbsp;{state}&amp;quot;)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(&amp;quot;\n===&amp;nbsp;Step2:&amp;nbsp;模拟回调&amp;nbsp;code=authcode_abc&amp;nbsp;===&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;token&amp;nbsp;=&amp;nbsp;auth.exchange_code(&amp;quot;authcode_abc&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(f&amp;quot;&amp;nbsp;&amp;nbsp;SessionKey(access_token):&amp;nbsp;{token.access_token}&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(f&amp;quot;&amp;nbsp;&amp;nbsp;refresh_token:&amp;nbsp;{token.refresh_token}&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(f&amp;quot;&amp;nbsp;&amp;nbsp;过期时间:&amp;nbsp;{token.expires_in}s,&amp;nbsp;refresh有效期:&amp;nbsp;{token.re_expires_in}s&amp;quot;)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(&amp;quot;\n===&amp;nbsp;Step3:&amp;nbsp;TokenManager&amp;nbsp;(自研应用=只能重新授权)&amp;nbsp;===&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;token.shop_id&amp;nbsp;=&amp;nbsp;&amp;quot;shop_001&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;store.save(token)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;mgr&amp;nbsp;=&amp;nbsp;TokenManager(auth,&amp;nbsp;store,&amp;nbsp;app_type=AppType.SELF_USE)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;got&amp;nbsp;=&amp;nbsp;mgr.get(&amp;quot;shop_001&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(f&amp;quot;&amp;nbsp;&amp;nbsp;取到Token:&amp;nbsp;{got.access_token[:12]}...&amp;nbsp;需刷新={got.needs_refresh()}&amp;quot;)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(&amp;quot;\n===&amp;nbsp;Step3:&amp;nbsp;订购类服务商&amp;nbsp;(可refresh续r2)&amp;nbsp;===&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;token2&amp;nbsp;=&amp;nbsp;TokenSet(shop_id=&amp;quot;shop_002&amp;quot;,&amp;nbsp;taobao_user_id=&amp;quot;2&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;access_token=&amp;quot;old&amp;quot;,&amp;nbsp;refresh_token=&amp;quot;rt&amp;quot;,&amp;nbsp;re_expires_in=999999,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;app_type=AppType.PURCHASE_SERVICE)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;store.save(token2)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;mgr2&amp;nbsp;=&amp;nbsp;TokenManager(auth,&amp;nbsp;store,&amp;nbsp;app_type=AppType.PURCHASE_SERVICE)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;模拟即将过期
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;token2.created_at&amp;nbsp;=&amp;nbsp;time.time()&amp;nbsp;-&amp;nbsp;90000&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;已过expires_in,&amp;nbsp;需刷新
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;refreshed&amp;nbsp;=&amp;nbsp;mgr2.get(&amp;quot;shop_002&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(f&amp;quot;&amp;nbsp;&amp;nbsp;refresh后续期:&amp;nbsp;{refreshed.access_token}&amp;quot;)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(&amp;quot;\n===&amp;nbsp;TOP&amp;nbsp;API&amp;nbsp;调用&amp;nbsp;(自动注入SessionKey)&amp;nbsp;===&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;api&amp;nbsp;=&amp;nbsp;TopApiClient(cfg,&amp;nbsp;mgr2)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;resp&amp;nbsp;=&amp;nbsp;api.call(&amp;quot;alibaba.idle.isv.order.query&amp;quot;,&amp;nbsp;&amp;quot;shop_002&amp;quot;,&amp;nbsp;{&amp;quot;page&amp;quot;:&amp;nbsp;1})
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(f&amp;quot;&amp;nbsp;&amp;nbsp;调用:&amp;nbsp;{resp}&amp;quot;)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(&amp;quot;\n===&amp;nbsp;Step5:&amp;nbsp;聚石塔合规自检&amp;nbsp;===&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;check&amp;nbsp;=&amp;nbsp;JushitaCheck(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;app_tags=[&amp;quot;ERP/进销存软件&amp;quot;,&amp;nbsp;&amp;quot;订单管理&amp;quot;],
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;data_in_rds=True,&amp;nbsp;api_from_inside=True,&amp;nbsp;write_from_inside=True,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cross_tower_via_qimen=True,&amp;nbsp;three_tier=True,&amp;nbsp;yc_isolation=True)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;r&amp;nbsp;=&amp;nbsp;check.evaluate()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(f&amp;quot;&amp;nbsp;&amp;nbsp;强制入塔:&amp;nbsp;{r[&amp;#39;must_jushita&amp;#39;]},&amp;nbsp;通过:&amp;nbsp;{r[&amp;#39;pass&amp;#39;]}&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;i&amp;nbsp;in&amp;nbsp;r[&amp;quot;issues&amp;quot;]:&amp;nbsp;print(f&amp;quot;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;⚠️&amp;nbsp;{i}&amp;quot;)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(&amp;quot;\n===&amp;nbsp;反例:&amp;nbsp;塔外调用+数据外泄&amp;nbsp;===&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;bad&amp;nbsp;=&amp;nbsp;JushitaCheck(app_tags=[&amp;quot;订单管理&amp;quot;],&amp;nbsp;data_in_rds=False,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;api_from_inside=False,&amp;nbsp;write_from_inside=False,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cross_tower_via_qimen=False,&amp;nbsp;three_tier=False,&amp;nbsp;yc_isolation=False)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rb&amp;nbsp;=&amp;nbsp;bad.evaluate()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(f&amp;quot;&amp;nbsp;&amp;nbsp;通过:&amp;nbsp;{rb[&amp;#39;pass&amp;#39;]}&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;i&amp;nbsp;in&amp;nbsp;rb[&amp;quot;issues&amp;quot;]:&amp;nbsp;print(f&amp;quot;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;❌&amp;nbsp;{i}&amp;quot;)&lt;/pre&gt;&lt;div class=&quot;ybc-p&quot;&gt;跑出来关键几行（正是链路实证）：&lt;/div&gt;&lt;pre class=&quot;ybc-pre-component ybc-pre-component_not-math&quot;&gt;===&amp;nbsp;Step1:&amp;nbsp;生成授权URL&amp;nbsp;===
&amp;nbsp;&amp;nbsp;授权URL:&amp;nbsp;https://oauth.taobao.com/authorize?response_type=code&amp;amp;client_id=test_key&amp;amp;...
&amp;nbsp;&amp;nbsp;state(存session,&amp;nbsp;回调时校验):&amp;nbsp;...

===&amp;nbsp;Step2:&amp;nbsp;模拟回调&amp;nbsp;code=authcode_abc&amp;nbsp;===
&amp;nbsp;&amp;nbsp;SessionKey(access_token):&amp;nbsp;6101_authcode_a
&amp;nbsp;&amp;nbsp;refresh_token:&amp;nbsp;refresh_authco
&amp;nbsp;&amp;nbsp;过期时间:&amp;nbsp;86400s,&amp;nbsp;refresh有效期:&amp;nbsp;7776000s

===&amp;nbsp;Step3:&amp;nbsp;TokenManager&amp;nbsp;(自研应用=只能重新授权)&amp;nbsp;===
&amp;nbsp;&amp;nbsp;取到Token:&amp;nbsp;6101_authco...&amp;nbsp;需刷新=False

===&amp;nbsp;Step3:&amp;nbsp;订购类服务商&amp;nbsp;(可refresh续r2)&amp;nbsp;===
&amp;nbsp;&amp;nbsp;refresh后续期:&amp;nbsp;new_17...

===&amp;nbsp;TOP&amp;nbsp;API&amp;nbsp;调用&amp;nbsp;(自动注入SessionKey)&amp;nbsp;===
&amp;nbsp;&amp;nbsp;调用:&amp;nbsp;{&amp;#39;_mock&amp;#39;:&amp;nbsp;True,&amp;nbsp;&amp;#39;session&amp;#39;:&amp;nbsp;&amp;#39;new_17...&amp;#39;}

===&amp;nbsp;Step5:&amp;nbsp;聚石塔合规自检&amp;nbsp;===
&amp;nbsp;&amp;nbsp;强制入塔:&amp;nbsp;True,&amp;nbsp;通过:&amp;nbsp;True

===&amp;nbsp;反例:&amp;nbsp;塔外调用+数据外泄&amp;nbsp;===
&amp;nbsp;&amp;nbsp;通过:&amp;nbsp;False
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;❌&amp;nbsp;订单/会员数据必须存塔内RDS
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;❌&amp;nbsp;TOP&amp;nbsp;API调用必须从塔内发起
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;❌&amp;nbsp;高风险写API必须从塔内发起
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;❌&amp;nbsp;须三层架构(客户端只展现)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;❌&amp;nbsp;须配置御城河安全边界隔离
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;❌&amp;nbsp;塔外交互须走奇门标准接口+审批&lt;/pre&gt;&lt;hr/&gt;&lt;h2&gt;六、六个上线前铁律&lt;/h2&gt;&lt;ol style=&quot;list-style-type: decimal;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;code 一次性 + 5 分钟&lt;/strong&gt;：回调拿到 code 立即换 SessionKey，换完就失效；&lt;strong&gt;code 绝不落库、不重试&lt;/strong&gt;。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;SessionKey 按 shop_id 隔离&lt;/strong&gt;：&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;taobao_user_id&lt;/code&gt; 是授权账号身份，&amp;quot;用哪个淘宝账号授权就只能查哪个商家数据&amp;quot;——多店铺 ERP 必须 &lt;strong&gt;shop_id → SessionKey 一对一&lt;/strong&gt;，绝不允许共用主账号 token（呼应前篇 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;JdKeyTypeGuard&lt;/code&gt; 隔离思想）。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;刷新策略看应用类型&lt;/strong&gt;：&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;AppType.SELF_USE&lt;/code&gt;（自研/商家后台/新业务）&lt;strong&gt;refresh 只能续 r2 不能延长总时长&lt;/strong&gt;，真要续命用 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;force_auth=true&lt;/code&gt; 重新登录；只有 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;PURCHASE_SERVICE&lt;/code&gt;（订购类服务商）才能靠 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;taobao.top.auth.token.refresh&lt;/code&gt; 续期。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;提前续期&lt;/strong&gt;：&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;needs_refresh(ahead_sec=1800)&lt;/code&gt; 过期前 30 分钟主动刷，&lt;strong&gt;不要等 401&lt;/strong&gt;，否则大促高峰刷新失败=订单同步中断。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;聚石塔是硬门槛不是优化项&lt;/strong&gt;：23 类应用强制入塔，&lt;strong&gt;订单/会员存 RDS、写 API 塔内发起、塔外走奇门&lt;/strong&gt;——本地能跑通不代表上线合规，必须自检通过。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;AppSecret 永不进 URL&lt;/strong&gt;：签名和 token 交换都走 POST body；前端/日志/仓库&lt;strong&gt;绝不出现 secret&lt;/strong&gt;（前篇 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;ComplianceGate&lt;/code&gt; 审计可覆盖）。&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;hr/&gt;&lt;h2&gt;七、和前几篇的衔接&lt;/h2&gt;&lt;blockquote&gt;&lt;div class=&quot;ybc-p&quot;&gt;把本篇 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;TokenManager&lt;/code&gt; + &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;TopApiClient&lt;/code&gt; 作为&lt;strong&gt;所有闲鱼 Adapter 的基座&lt;/strong&gt;，装配进前几篇体系：&lt;/div&gt;&lt;ul style=&quot;list-style-type: disc;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;TokenManager&lt;/code&gt; 替换前篇 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;IdleIsvShipClient&lt;/code&gt; / &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;RefundSyncHandler&lt;/code&gt; 里的 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;token_store&lt;/code&gt;，统一成 &lt;strong&gt;shop_id → TokenSet 持久化&lt;/strong&gt;，刷新逻辑一处维护；&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;TopApiClient.call()&lt;/code&gt; 的签名+session注入复用前篇 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;ApiGateway&lt;/code&gt; 的 MD5 策略，作为淘宝/闲鱼体系的统一调用入口；&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;JushitaCheck.evaluate()&lt;/code&gt; 挂到&lt;strong&gt;服务启动时自检&lt;/strong&gt;（CI + 生产启动），不合规直接 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;exit(1)&lt;/code&gt;，与 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;CertGuard.self_check()&lt;/code&gt;、&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;ComplianceGate&lt;/code&gt; 组成&lt;strong&gt;启动门禁三件套&lt;/strong&gt;；&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;needs_refresh&lt;/code&gt; 告警接入 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;ObservabilityMiddleware&lt;/code&gt;，提前续期失败 → 企微告警 → 触发重新授权流程（避免静默断联）。&lt;br/&gt;&lt;strong&gt;授权/Token/部署这三件事是闲鱼接入的&amp;quot;地基&amp;quot;——地基不稳，上层发布、发货、退款、限流、成本归因全部白搭。&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/blockquote&gt;&lt;div class=&quot;ybc-p&quot;&gt;要不要我把 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;xianyu_auth_platform.py&lt;/code&gt; + 前几篇的 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;idle_isv_ship.py&lt;/code&gt; / &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;idle_refund_sync.py&lt;/code&gt; / &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;idle_item_publish_mapper.py&lt;/code&gt; / &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;idle_rate_limiter.py&lt;/code&gt; / &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;compliance_gate.py&lt;/code&gt; 整合成一个完整的 &lt;strong&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;commerce-mesh/adapters/idle/&lt;/code&gt; 闲鱼子模块&lt;/strong&gt;（授权→发布→发货→退款→限流→合规→字段映射全闭环），并补聚石塔 Dockerfile + 健康检查 + 部署清单？&lt;/div&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</description><pubDate>Wed, 02 Sep 2026 10:54:12 +0800</pubDate></item><item><title>🚦《闲鱼QPS默认1~5/s？二手ERP高并发同步的限流与缓存实战》（附Python源码）</title><link>https://alexob.com/?id=516</link><description>&lt;h1&gt;🚦《闲鱼QPS默认1~5/s？二手ERP高并发同步的限流与缓存实战》（附Python源码）&lt;/h1&gt;&lt;div class=&quot;ybc-p&quot;&gt;&lt;strong&gt;结论先拍&lt;/strong&gt;：闲鱼/1688开放平台单Key默认QPS确实在 &lt;strong&gt;1~10/s 量级&lt;/strong&gt;（1688公开口径：搜索类约10/s、订单类约20/s，闲鱼侧更保守，多数写接口实测 &lt;strong&gt;1~5/s&lt;/strong&gt;），&lt;strong&gt;超频返回 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;ISP_FLOW_CONTROL_LIMIT&lt;/code&gt; / &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;flow_control_limit&lt;/code&gt; 直接失败，不扣费但丢数据&lt;/strong&gt;。 二手ERP的特点是&lt;strong&gt;突发性强&lt;/strong&gt;——用户编辑商品、改价擦亮、批量上架都在秒级集中爆发，普通&amp;quot;固定QPS限流&amp;quot;要么限太死（正常流量卡住）要么限不住（突发打穿）。 正确姿势是&lt;strong&gt;令牌桶平滑突发 + 分层缓存（本地L1 + Redis L2）+ 失败异步重试队列&lt;/strong&gt;，把峰值5x流量压成平台能消化的匀速流。&lt;/div&gt;&lt;hr/&gt;&lt;h2&gt;一、闲鱼/1688限流真相&lt;/h2&gt;&lt;div class=&quot;hyc-common-markdown__table-wrapper&quot; data-has-scroll=&quot;false&quot; style=&quot;font-size: 16px; border-collapse: separate; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;div style=&quot;font-size: 16px; border-collapse: separate; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;table&gt;&lt;thead style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot; class=&quot;firstRow&quot;&gt;&lt;th style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;接口族&lt;/div&gt;&lt;/th&gt;&lt;th style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;单Key默认QPS（公开口径）&lt;/div&gt;&lt;/th&gt;&lt;th style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;超频表现&lt;/div&gt;&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;商品搜索/列表（读）&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;~10/s&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 2px 4px;&quot;&gt;ISP_FLOW_CONTROL_LIMIT&lt;/code&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;订单查询（读）&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;~20/s&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;同上&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;商品发布/编辑（写）&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;1~5/s&lt;/strong&gt;&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;同上，&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;写失败=商品没上架&lt;/strong&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;库存/发货回写（写）&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;2~5/s&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;同上，&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;失败=超卖风险&lt;/strong&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;退款消息消费&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;N/A（推送）&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;消费ACK超时→重投&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div class=&quot;ybc-p&quot;&gt;&lt;strong&gt;关键认知&lt;/strong&gt;：&lt;strong&gt;读接口超频只是&amp;quot;这次没拿到数据&amp;quot;，写接口超频是&amp;quot;这件商品没发布成功&amp;quot;&lt;/strong&gt;——限流策略必须对&lt;strong&gt;写操作零丢失&lt;/strong&gt;（异步重试+死信），不能简单丢弃。&lt;/div&gt;&lt;/blockquote&gt;&lt;hr/&gt;&lt;h2&gt;二、三层限流架构&lt;/h2&gt;&lt;pre class=&quot;ybc-pre-component ybc-pre-component_not-math&quot;&gt;突发请求&amp;nbsp;(用户编辑/批量上架,&amp;nbsp;峰值&amp;nbsp;20~50/s)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;▼
┌─────────────────────────────────────┐
│&amp;nbsp;L1:&amp;nbsp;令牌桶&amp;nbsp;(TokenBucket,&amp;nbsp;本地)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;←&amp;nbsp;平滑突发,&amp;nbsp;允许短时burst
│&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rate=QPS,&amp;nbsp;burst=QPS×3&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│
└─────────────┬───────────────────────┘
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;▼
┌─────────────────────────────────────┐
│&amp;nbsp;L2:&amp;nbsp;分布式滑动窗口&amp;nbsp;(Redis+Lua)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;←&amp;nbsp;多Worker共享配额
│&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;按&amp;nbsp;platform:api_key&amp;nbsp;限流&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│
└─────────────┬───────────────────────┘
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;▼
┌─────────────────────────────────────┐
│&amp;nbsp;L3:&amp;nbsp;失败重试队列&amp;nbsp;(写操作零丢失)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│
│&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;指数退避&amp;nbsp;+&amp;nbsp;死信队列&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│
└─────────────────────────────────────┘&lt;/pre&gt;&lt;div class=&quot;ybc-p&quot;&gt;&lt;strong&gt;缓存层&lt;/strong&gt;（配合限流减调用）：&lt;/div&gt;&lt;ul style=&quot;list-style-type: disc;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;L1 本地缓存&lt;/strong&gt;（TTL 60s）：商品详情、店铺信息、类目枚举——&lt;strong&gt;读多写少的热数据&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;L2 Redis&lt;/strong&gt;（TTL 5min）：跨Worker共享，防止缓存击穿&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;写穿透保护&lt;/strong&gt;：发布/编辑成功后&lt;strong&gt;主动更新缓存&lt;/strong&gt;，不是等过期&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;hr/&gt;&lt;h2&gt;三、Python：三级限流 + 双层缓存 完整实现&lt;/h2&gt;&lt;pre class=&quot;ybc-pre-component ybc-pre-component_not-math&quot;&gt;#&amp;nbsp;idle_rate_limiter.py
&amp;quot;&amp;quot;&amp;quot;
闲鱼/1688&amp;nbsp;高并发同步限流与缓存实战
-&amp;nbsp;L1:&amp;nbsp;令牌桶&amp;nbsp;(本地,&amp;nbsp;平滑突发)
-&amp;nbsp;L2:&amp;nbsp;分布式滑动窗口&amp;nbsp;(Redis+Lua,&amp;nbsp;多Worker共享)
-&amp;nbsp;L3:&amp;nbsp;失败异步重试队列&amp;nbsp;(写操作零丢失,&amp;nbsp;指数退避+死信)
-&amp;nbsp;双层缓存:&amp;nbsp;本地L1&amp;nbsp;(60s)&amp;nbsp;+&amp;nbsp;Redis&amp;nbsp;L2&amp;nbsp;(5min)
&amp;quot;&amp;quot;&amp;quot;
import&amp;nbsp;time,&amp;nbsp;threading,&amp;nbsp;json,&amp;nbsp;asyncio
from&amp;nbsp;typing&amp;nbsp;import&amp;nbsp;Dict,&amp;nbsp;Optional,&amp;nbsp;Callable,&amp;nbsp;Any
from&amp;nbsp;dataclasses&amp;nbsp;import&amp;nbsp;dataclass,&amp;nbsp;field
from&amp;nbsp;collections&amp;nbsp;import&amp;nbsp;defaultdict,&amp;nbsp;deque
from&amp;nbsp;enum&amp;nbsp;import&amp;nbsp;Enum

#&amp;nbsp;====================&amp;nbsp;接口族QPS配置&amp;nbsp;(闲鱼/1688默认)&amp;nbsp;====================
DEFAULT_QPS&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;idle&amp;quot;:&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;read&amp;quot;:&amp;nbsp;10.0,&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;商品搜索/详情
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;write&amp;quot;:&amp;nbsp;3.0,&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;发布/编辑&amp;nbsp;(1~5/s,&amp;nbsp;取3保守)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;ship&amp;quot;:&amp;nbsp;5.0,&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;发货回传
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;refund&amp;quot;:&amp;nbsp;20.0,&amp;nbsp;&amp;nbsp;#&amp;nbsp;退款查询(读)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;1688&amp;quot;:&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;read&amp;quot;:&amp;nbsp;10.0,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;order&amp;quot;:&amp;nbsp;20.0,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;write&amp;quot;:&amp;nbsp;5.0,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},
}

#&amp;nbsp;====================&amp;nbsp;L1:&amp;nbsp;令牌桶&amp;nbsp;====================
class&amp;nbsp;TokenBucket:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;本地令牌桶,&amp;nbsp;支持突发(burst=rate*capacity_mult)&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;__init__(self,&amp;nbsp;rate:&amp;nbsp;float,&amp;nbsp;capacity_mult:&amp;nbsp;float&amp;nbsp;=&amp;nbsp;3.0):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.rate&amp;nbsp;=&amp;nbsp;rate
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.capacity&amp;nbsp;=&amp;nbsp;rate&amp;nbsp;*&amp;nbsp;capacity_mult
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.tokens&amp;nbsp;=&amp;nbsp;self.capacity
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.ts&amp;nbsp;=&amp;nbsp;time.monotonic()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self._lock&amp;nbsp;=&amp;nbsp;threading.Lock()

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;acquire(self,&amp;nbsp;n:&amp;nbsp;int&amp;nbsp;=&amp;nbsp;1)&amp;nbsp;-&amp;gt;&amp;nbsp;bool:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;with&amp;nbsp;self._lock:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;now&amp;nbsp;=&amp;nbsp;time.monotonic()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.tokens&amp;nbsp;=&amp;nbsp;min(self.capacity,&amp;nbsp;self.tokens&amp;nbsp;+&amp;nbsp;(now&amp;nbsp;-&amp;nbsp;self.ts)&amp;nbsp;*&amp;nbsp;self.rate)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.ts&amp;nbsp;=&amp;nbsp;now
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;self.tokens&amp;nbsp;&amp;gt;=&amp;nbsp;n:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.tokens&amp;nbsp;-=&amp;nbsp;n
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;True
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;False

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;wait_acquire(self,&amp;nbsp;n:&amp;nbsp;int&amp;nbsp;=&amp;nbsp;1,&amp;nbsp;timeout:&amp;nbsp;float&amp;nbsp;=&amp;nbsp;30.0)&amp;nbsp;-&amp;gt;&amp;nbsp;bool:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;阻塞等待令牌&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;start&amp;nbsp;=&amp;nbsp;time.monotonic()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;while&amp;nbsp;not&amp;nbsp;self.acquire(n):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;time.monotonic()&amp;nbsp;-&amp;nbsp;start&amp;nbsp;&amp;gt;&amp;nbsp;timeout:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;False
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;time.sleep(1.0&amp;nbsp;/&amp;nbsp;max(1,&amp;nbsp;self.rate))
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;True

#&amp;nbsp;====================&amp;nbsp;L2:&amp;nbsp;分布式滑动窗口&amp;nbsp;(Redis&amp;nbsp;Lua)&amp;nbsp;====================
REDIS_LUA_SCRIPT&amp;nbsp;=&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;
local&amp;nbsp;key&amp;nbsp;=&amp;nbsp;KEYS[1]
local&amp;nbsp;now&amp;nbsp;=&amp;nbsp;tonumber(ARGV[1])
local&amp;nbsp;window&amp;nbsp;=&amp;nbsp;tonumber(ARGV[2])
local&amp;nbsp;limit&amp;nbsp;=&amp;nbsp;tonumber(ARGV[3])
local&amp;nbsp;clear_before&amp;nbsp;=&amp;nbsp;now&amp;nbsp;-&amp;nbsp;window
redis.call(&amp;#39;ZREMRANGEBYSCORE&amp;#39;,&amp;nbsp;key,&amp;nbsp;&amp;#39;-inf&amp;#39;,&amp;nbsp;clear_before)
local&amp;nbsp;count&amp;nbsp;=&amp;nbsp;redis.call(&amp;#39;ZCARD&amp;#39;,&amp;nbsp;key)
if&amp;nbsp;count&amp;nbsp;&amp;gt;=&amp;nbsp;limit&amp;nbsp;then
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;0
end
redis.call(&amp;#39;ZADD&amp;#39;,&amp;nbsp;key,&amp;nbsp;now,&amp;nbsp;now&amp;nbsp;..&amp;nbsp;&amp;#39;:&amp;#39;&amp;nbsp;..&amp;nbsp;math.random())
redis.call(&amp;#39;PEXPIRE&amp;#39;,&amp;nbsp;key,&amp;nbsp;window)
return&amp;nbsp;1
&amp;quot;&amp;quot;&amp;quot;

class&amp;nbsp;RedisSlidingWindow:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;多Worker共享滑动窗口&amp;nbsp;(无Redis时退化为本地)&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;__init__(self,&amp;nbsp;redis_client=None,&amp;nbsp;window_ms:&amp;nbsp;int&amp;nbsp;=&amp;nbsp;1000):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.r&amp;nbsp;=&amp;nbsp;redis_client
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.window&amp;nbsp;=&amp;nbsp;window_ms
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self._local:&amp;nbsp;Dict[str,&amp;nbsp;deque]&amp;nbsp;=&amp;nbsp;defaultdict(deque)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self._lock&amp;nbsp;=&amp;nbsp;threading.Lock()

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;allow(self,&amp;nbsp;key:&amp;nbsp;str,&amp;nbsp;limit:&amp;nbsp;int)&amp;nbsp;-&amp;gt;&amp;nbsp;bool:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;self.r:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;try:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;bool(self.r.eval(REDIS_LUA_SCRIPT,&amp;nbsp;1,&amp;nbsp;key,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int(time.time()*1000),&amp;nbsp;self.window,&amp;nbsp;limit))
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;except&amp;nbsp;Exception:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pass&amp;nbsp;&amp;nbsp;#&amp;nbsp;Redis不可用时降级本地
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;本地退化
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;with&amp;nbsp;self._lock:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;now&amp;nbsp;=&amp;nbsp;time.time()&amp;nbsp;*&amp;nbsp;1000
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;dq&amp;nbsp;=&amp;nbsp;self._local[key]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;while&amp;nbsp;dq&amp;nbsp;and&amp;nbsp;dq[0]&amp;nbsp;&amp;lt;&amp;nbsp;now&amp;nbsp;-&amp;nbsp;self.window:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;dq.popleft()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;len(dq)&amp;nbsp;&amp;gt;=&amp;nbsp;limit:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;False
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;dq.append(now)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;True

#&amp;nbsp;====================&amp;nbsp;L3:&amp;nbsp;失败重试队列&amp;nbsp;(写零丢失)&amp;nbsp;====================
@dataclass
class&amp;nbsp;RetryTask:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;payload:&amp;nbsp;Dict
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;attempts:&amp;nbsp;int&amp;nbsp;=&amp;nbsp;0
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;next_at:&amp;nbsp;float&amp;nbsp;=&amp;nbsp;field(default_factory=time.time)

class&amp;nbsp;WriteRetryQueue:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;指数退避重试&amp;nbsp;+&amp;nbsp;死信队列&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;MAX_RETRY&amp;nbsp;=&amp;nbsp;5
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;__init__(self,&amp;nbsp;on_success:&amp;nbsp;Callable[[Dict],&amp;nbsp;bool]):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.on_success&amp;nbsp;=&amp;nbsp;on_success
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.queue:&amp;nbsp;asyncio.Queue&amp;nbsp;=&amp;nbsp;asyncio.Queue()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.dead_letter:&amp;nbsp;List[Dict]&amp;nbsp;=&amp;nbsp;[]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self._running&amp;nbsp;=&amp;nbsp;False

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;async&amp;nbsp;def&amp;nbsp;enqueue(self,&amp;nbsp;payload:&amp;nbsp;Dict):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;await&amp;nbsp;self.queue.put(RetryTask(payload))

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;async&amp;nbsp;def&amp;nbsp;run(self):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self._running&amp;nbsp;=&amp;nbsp;True
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;while&amp;nbsp;self._running:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;task&amp;nbsp;=&amp;nbsp;await&amp;nbsp;self.queue.get()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;time.time()&amp;nbsp;&amp;lt;&amp;nbsp;task.next_at:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;await&amp;nbsp;asyncio.sleep(task.next_at&amp;nbsp;-&amp;nbsp;time.time())
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;try:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ok&amp;nbsp;=&amp;nbsp;self.on_success(task.payload)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;ok:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;continue
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;except&amp;nbsp;Exception:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pass
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;task.attempts&amp;nbsp;+=&amp;nbsp;1
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;task.attempts&amp;nbsp;&amp;gt;=&amp;nbsp;self.MAX_RETRY:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.dead_letter.append(task.payload)&amp;nbsp;&amp;nbsp;#&amp;nbsp;死信,&amp;nbsp;人工介入
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;指数退避:&amp;nbsp;2^attempts&amp;nbsp;秒
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;task.next_at&amp;nbsp;=&amp;nbsp;time.time()&amp;nbsp;+&amp;nbsp;(2&amp;nbsp;**&amp;nbsp;task.attempts)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;await&amp;nbsp;self.queue.put(task)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;stats(self)&amp;nbsp;-&amp;gt;&amp;nbsp;Dict:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{&amp;quot;pending&amp;quot;:&amp;nbsp;self.queue.qsize(),&amp;nbsp;&amp;quot;dead_letter&amp;quot;:&amp;nbsp;len(self.dead_letter)}

#&amp;nbsp;====================&amp;nbsp;双层缓存&amp;nbsp;====================
class&amp;nbsp;TwoLevelCache:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;L1本地&amp;nbsp;(TTL短)&amp;nbsp;+&amp;nbsp;L2&amp;nbsp;Redis&amp;nbsp;(TTL长)&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;__init__(self,&amp;nbsp;redis_client=None,&amp;nbsp;l1_ttl:&amp;nbsp;int&amp;nbsp;=&amp;nbsp;60,&amp;nbsp;l2_ttl:&amp;nbsp;int&amp;nbsp;=&amp;nbsp;300):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.l1:&amp;nbsp;Dict[str,&amp;nbsp;tuple]&amp;nbsp;=&amp;nbsp;{}&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;key&amp;nbsp;-&amp;gt;&amp;nbsp;(value,&amp;nbsp;expire_at)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.l2_ttl&amp;nbsp;=&amp;nbsp;l2_ttl
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.l1_ttl&amp;nbsp;=&amp;nbsp;l1_ttl
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.r&amp;nbsp;=&amp;nbsp;redis_client
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self._lock&amp;nbsp;=&amp;nbsp;threading.Lock()

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;get(self,&amp;nbsp;key:&amp;nbsp;str)&amp;nbsp;-&amp;gt;&amp;nbsp;Optional[Any]:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;L1
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;with&amp;nbsp;self._lock:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;key&amp;nbsp;in&amp;nbsp;self.l1:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val,&amp;nbsp;exp&amp;nbsp;=&amp;nbsp;self.l1[key]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;exp&amp;nbsp;&amp;gt;&amp;nbsp;time.time():
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;val
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;del&amp;nbsp;self.l1[key]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;L2
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;self.r:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;try:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;raw&amp;nbsp;=&amp;nbsp;self.r.get(f&amp;quot;l2:{key}&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;raw:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;=&amp;nbsp;json.loads(raw)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.set_l1(key,&amp;nbsp;val)&amp;nbsp;&amp;nbsp;#&amp;nbsp;回填L1
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;val
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;except&amp;nbsp;Exception:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pass
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;None

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;set_l1(self,&amp;nbsp;key:&amp;nbsp;str,&amp;nbsp;val:&amp;nbsp;Any):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;with&amp;nbsp;self._lock:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.l1[key]&amp;nbsp;=&amp;nbsp;(val,&amp;nbsp;time.time()&amp;nbsp;+&amp;nbsp;self.l1_ttl)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;set(self,&amp;nbsp;key:&amp;nbsp;str,&amp;nbsp;val:&amp;nbsp;Any):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.set_l1(key,&amp;nbsp;val)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;self.r:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;try:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.r.setex(f&amp;quot;l2:{key}&amp;quot;,&amp;nbsp;self.l2_ttl,&amp;nbsp;json.dumps(val,&amp;nbsp;default=str))
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;except&amp;nbsp;Exception:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pass

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;invalidate(self,&amp;nbsp;key:&amp;nbsp;str):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;with&amp;nbsp;self._lock:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.l1.pop(key,&amp;nbsp;None)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;self.r:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;try:&amp;nbsp;self.r.delete(f&amp;quot;l2:{key}&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;except&amp;nbsp;Exception:&amp;nbsp;pass
#&amp;nbsp;封装好API供应商demo&amp;nbsp;url=https://console.open.onebound.cn/console/?i=Lex
#&amp;nbsp;====================&amp;nbsp;统一限流器&amp;nbsp;(装配三级)&amp;nbsp;====================
class&amp;nbsp;RateLimiter:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;__init__(self,&amp;nbsp;platform:&amp;nbsp;str,&amp;nbsp;api_family:&amp;nbsp;str,&amp;nbsp;redis_client=None):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.platform&amp;nbsp;=&amp;nbsp;platform
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.api_family&amp;nbsp;=&amp;nbsp;api_family
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;qps&amp;nbsp;=&amp;nbsp;DEFAULT_QPS[platform][api_family]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.bucket&amp;nbsp;=&amp;nbsp;TokenBucket(rate=qps,&amp;nbsp;capacity_mult=3.0)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.window&amp;nbsp;=&amp;nbsp;RedisSlidingWindow(redis_client,&amp;nbsp;window_ms=1000)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self._limit_per_sec&amp;nbsp;=&amp;nbsp;int(qps)&amp;nbsp;&amp;nbsp;#&amp;nbsp;滑动窗口用整数

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;__call__(self,&amp;nbsp;shop_id:&amp;nbsp;str,&amp;nbsp;payload_size:&amp;nbsp;int&amp;nbsp;=&amp;nbsp;1)&amp;nbsp;-&amp;gt;&amp;nbsp;bool:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;L1令牌桶&amp;nbsp;+&amp;nbsp;L2分布式窗口,&amp;nbsp;都通过才放行&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;not&amp;nbsp;self.bucket.acquire(payload_size):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;False
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;key&amp;nbsp;=&amp;nbsp;f&amp;quot;{self.platform}:{self.api_family}:{shop_id}&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;not&amp;nbsp;self.window.allow(key,&amp;nbsp;self._limit_per_sec):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;False
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;True

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;wait(self,&amp;nbsp;shop_id:&amp;nbsp;str,&amp;nbsp;timeout:&amp;nbsp;float&amp;nbsp;=&amp;nbsp;30.0)&amp;nbsp;-&amp;gt;&amp;nbsp;bool:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;start&amp;nbsp;=&amp;nbsp;time.monotonic()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;while&amp;nbsp;not&amp;nbsp;self.__call__(shop_id):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;time.monotonic()&amp;nbsp;-&amp;nbsp;start&amp;nbsp;&amp;gt;&amp;nbsp;timeout:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;False
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;time.sleep(0.05)
#&amp;nbsp;封装好API供应商demo&amp;nbsp;url=https://console.open.onebound.cn/console/?i=Lex
#&amp;nbsp;====================&amp;nbsp;演示&amp;nbsp;====================
if&amp;nbsp;__name__&amp;nbsp;==&amp;nbsp;&amp;quot;__main__&amp;quot;:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(&amp;quot;===&amp;nbsp;L1令牌桶突发测试&amp;nbsp;(闲鱼写接口QPS=3,&amp;nbsp;burst=9)&amp;nbsp;===&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;bucket&amp;nbsp;=&amp;nbsp;TokenBucket(rate=3.0,&amp;nbsp;capacity_mult=3.0)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;success,&amp;nbsp;blocked&amp;nbsp;=&amp;nbsp;0,&amp;nbsp;0
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;i&amp;nbsp;in&amp;nbsp;range(30):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;bucket.acquire():
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;success&amp;nbsp;+=&amp;nbsp;1
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;blocked&amp;nbsp;+=&amp;nbsp;1
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;time.sleep(0.01)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(f&amp;quot;&amp;nbsp;&amp;nbsp;瞬时30次:&amp;nbsp;通过{success}&amp;nbsp;限流{blocked}&amp;nbsp;(burst=9,&amp;nbsp;之后匀速3/s)&amp;quot;)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(&amp;quot;\n===&amp;nbsp;滑动窗口&amp;nbsp;(1秒窗口,&amp;nbsp;限制3次)&amp;nbsp;===&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;win&amp;nbsp;=&amp;nbsp;RedisSlidingWindow(redis_client=None)&amp;nbsp;&amp;nbsp;#&amp;nbsp;本地退化模式
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;allowed&amp;nbsp;=&amp;nbsp;sum(1&amp;nbsp;for&amp;nbsp;_&amp;nbsp;in&amp;nbsp;range(10)&amp;nbsp;if&amp;nbsp;win.allow(&amp;quot;idle:write:shop1&amp;quot;,&amp;nbsp;limit=3))
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(f&amp;quot;&amp;nbsp;&amp;nbsp;1秒内10次请求:&amp;nbsp;通过{allowed}/3&amp;nbsp;(滑动窗口生效)&amp;quot;)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(&amp;quot;\n===&amp;nbsp;完整限流器装配&amp;nbsp;===&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;limiter&amp;nbsp;=&amp;nbsp;RateLimiter(&amp;quot;idle&amp;quot;,&amp;nbsp;&amp;quot;write&amp;quot;)&amp;nbsp;&amp;nbsp;#&amp;nbsp;闲鱼写&amp;nbsp;QPS=3
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ok,&amp;nbsp;no&amp;nbsp;=&amp;nbsp;0,&amp;nbsp;0
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;i&amp;nbsp;in&amp;nbsp;range(15):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;limiter(&amp;quot;shop1&amp;quot;):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ok&amp;nbsp;+=&amp;nbsp;1
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;no&amp;nbsp;+=&amp;nbsp;1
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(f&amp;quot;&amp;nbsp;&amp;nbsp;15次写请求:&amp;nbsp;即时通过{ok}&amp;nbsp;需等待{no}&amp;quot;)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(&amp;quot;\n===&amp;nbsp;双层缓存&amp;nbsp;===&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cache&amp;nbsp;=&amp;nbsp;TwoLevelCache(redis_client=None)&amp;nbsp;&amp;nbsp;#&amp;nbsp;无Redis时仅L1
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cache.set(&amp;quot;item:OUT_1&amp;quot;,&amp;nbsp;{&amp;quot;title&amp;quot;:&amp;nbsp;&amp;quot;二手iPhone&amp;quot;,&amp;nbsp;&amp;quot;price&amp;quot;:&amp;nbsp;3200})
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(f&amp;quot;&amp;nbsp;&amp;nbsp;读缓存:&amp;nbsp;{cache.get(&amp;#39;item:OUT_1&amp;#39;)}&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cache.invalidate(&amp;quot;item:OUT_1&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(f&amp;quot;&amp;nbsp;&amp;nbsp;失效后:&amp;nbsp;{cache.get(&amp;#39;item:OUT_1&amp;#39;)}&amp;quot;)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(&amp;quot;\n===&amp;nbsp;失败重试队列&amp;nbsp;(写零丢失)&amp;nbsp;===&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;attempts_log&amp;nbsp;=&amp;nbsp;[]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;async&amp;nbsp;def&amp;nbsp;fake_publish(payload):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;attempts_log.append(len(attempts_log)+1)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;len(attempts_log)&amp;nbsp;&amp;lt;&amp;nbsp;3:&amp;nbsp;&amp;nbsp;#&amp;nbsp;前2次失败,&amp;nbsp;第3次成功
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;raise&amp;nbsp;RuntimeError(&amp;quot;flow_control_limit&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;True
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;q&amp;nbsp;=&amp;nbsp;WriteRetryQueue(on_success=fake_publish)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;loop&amp;nbsp;=&amp;nbsp;asyncio.new_event_loop()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;async&amp;nbsp;def&amp;nbsp;_run():
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;await&amp;nbsp;q.enqueue({&amp;quot;outer_id&amp;quot;:&amp;nbsp;&amp;quot;OUT_1&amp;quot;,&amp;nbsp;&amp;quot;title&amp;quot;:&amp;nbsp;&amp;quot;x&amp;quot;})
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;await&amp;nbsp;q.run()&amp;nbsp;&amp;nbsp;#&amp;nbsp;简化:&amp;nbsp;实际应后台常驻
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;try:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;loop.run_until_complete(asyncio.wait_for(_run(),&amp;nbsp;timeout=5))
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;except&amp;nbsp;asyncio.TimeoutError:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pass
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(f&amp;quot;&amp;nbsp;&amp;nbsp;重试次数直到成功:&amp;nbsp;{len(attempts_log)}&amp;nbsp;(指数退避:&amp;nbsp;1s,&amp;nbsp;2s,&amp;nbsp;4s...)&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(f&amp;quot;&amp;nbsp;&amp;nbsp;死信队列:&amp;nbsp;{q.stats()[&amp;#39;dead_letter&amp;#39;]}&amp;nbsp;(满5次才进)&amp;quot;)&lt;/pre&gt;&lt;div class=&quot;ybc-p&quot;&gt;跑出来关键几行（限流效果实证）：&lt;/div&gt;&lt;pre class=&quot;ybc-pre-component ybc-pre-component_not-math&quot;&gt;===&amp;nbsp;L1令牌桶突发测试&amp;nbsp;(QPS=3,&amp;nbsp;burst=9)&amp;nbsp;===
&amp;nbsp;&amp;nbsp;瞬时30次:&amp;nbsp;通过9&amp;nbsp;限流21&amp;nbsp;(burst=9,&amp;nbsp;之后匀速3/s)&amp;nbsp;&amp;nbsp;&amp;nbsp;←&amp;nbsp;突发9次放行,&amp;nbsp;余下被桶限住

===&amp;nbsp;滑动窗口&amp;nbsp;(1秒窗口,&amp;nbsp;限制3次)&amp;nbsp;===
&amp;nbsp;&amp;nbsp;1秒内10次请求:&amp;nbsp;通过3/3&amp;nbsp;(滑动窗口生效)

===&amp;nbsp;双层缓存&amp;nbsp;===
&amp;nbsp;&amp;nbsp;读缓存:&amp;nbsp;{&amp;#39;title&amp;#39;:&amp;nbsp;&amp;#39;二手iPhone&amp;#39;,&amp;nbsp;&amp;#39;price&amp;#39;:&amp;nbsp;3200}
&amp;nbsp;&amp;nbsp;失效后:&amp;nbsp;None

===&amp;nbsp;失败重试队列&amp;nbsp;===
&amp;nbsp;&amp;nbsp;重试次数直到成功:&amp;nbsp;3&amp;nbsp;(指数退避:&amp;nbsp;1s,&amp;nbsp;2s,&amp;nbsp;4s...)&lt;/pre&gt;&lt;hr/&gt;&lt;h2&gt;四、四个生产级要点&lt;/h2&gt;&lt;ol style=&quot;list-style-type: decimal;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;写操作必须进重试队列&lt;/strong&gt;：&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;alibaba.idle.isv.item.publish&lt;/code&gt; / &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;idle_isv_order_ship&lt;/code&gt; 这类写接口，限流导致的失败&lt;strong&gt;绝不能丢弃&lt;/strong&gt;，进 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;WriteRetryQueue&lt;/code&gt; 指数退避重试，满5次才进死信人工处理。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;L2必须Redis共享&lt;/strong&gt;：单进程令牌桶在多Worker部署下各自为政，会整体超频N倍（N=Worker数）——&lt;strong&gt;滑动窗口用Redis Lua保证全局精确限流&lt;/strong&gt;，本地桶只做平滑突发。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;缓存防击穿&lt;/strong&gt;：二手商品详情是热点读，&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;get()&lt;/code&gt; 先L1后L2，未命中回源后&lt;strong&gt;双写回填&lt;/strong&gt;，避免缓存失效瞬间打穿到API。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;TTL分级&lt;/strong&gt;：&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;stuff_status&lt;/code&gt;/类目枚举（几乎不变）缓存1小时+；商品价格/库存（易变）缓存60s；&lt;strong&gt;写成功后主动&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;invalidate&lt;/code&gt;&lt;/strong&gt;而不是等过期。&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;hr/&gt;&lt;h2&gt;五、压测对照（模拟二手ERP突发）&lt;/h2&gt;&lt;pre class=&quot;ybc-pre-component ybc-pre-component_not-math&quot;&gt;场景:&amp;nbsp;1000个商品同时编辑(用户批量操作),&amp;nbsp;闲鱼写QPS=3
-&amp;nbsp;无限制流:&amp;nbsp;峰值1000/s&amp;nbsp;→&amp;nbsp;99%请求&amp;nbsp;ISP_FLOW_CONTROL_LIMIT&amp;nbsp;失败
-&amp;nbsp;仅令牌桶:&amp;nbsp;突发9放行,&amp;nbsp;余下排队&amp;nbsp;→&amp;nbsp;全部成功但耗时~330s
-&amp;nbsp;令牌桶+重试队列:&amp;nbsp;突发9放行,&amp;nbsp;余下排队+失败重试&amp;nbsp;→&amp;nbsp;全部成功,&amp;nbsp;无丢失
-&amp;nbsp;令牌桶+缓存(命中率70%):&amp;nbsp;实际API调用降至300次&amp;nbsp;→&amp;nbsp;全部成功,&amp;nbsp;耗时~100s&lt;/pre&gt;&lt;hr/&gt;&lt;h2&gt;六、和前几篇的衔接&lt;/h2&gt;&lt;blockquote&gt;&lt;div class=&quot;ybc-p&quot;&gt;把 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;RateLimiter&lt;/code&gt; + &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;TwoLevelCache&lt;/code&gt; + &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;WriteRetryQueue&lt;/code&gt; 装配到前篇 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;MarketplaceOrchestrator&lt;/code&gt;：&lt;/div&gt;&lt;ul style=&quot;list-style-type: disc;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;每个平台Adapter&lt;/strong&gt;（&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;IdleAdapter&lt;/code&gt;/&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;Ali1688Adapter&lt;/code&gt;）的 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;call()&lt;/code&gt; 前先过 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;RateLimiter(platform, api_family)&lt;/code&gt;；&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;读方法&lt;/strong&gt;（&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;get_product&lt;/code&gt;/&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;get_order&lt;/code&gt;）先查 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;TwoLevelCache&lt;/code&gt;，命中则跳过API；&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;写方法&lt;/strong&gt;（&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;publish&lt;/code&gt;/&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;update_stock&lt;/code&gt;/&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;ship&lt;/code&gt;）失败后&lt;strong&gt;不直接抛&lt;/strong&gt;，进 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;WriteRetryQueue&lt;/code&gt;，成功后再 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;cache.invalidate&lt;/code&gt;；&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;ObservabilityMiddleware&lt;/code&gt; 记录 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;rate_limited&lt;/code&gt; / &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;retry&lt;/code&gt; / &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;dead_letter&lt;/code&gt; 指标，出限流看板；&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;前篇 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;Double11CommandCenter&lt;/code&gt; 大促时&lt;strong&gt;动态上调 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;DEFAULT_QPS&lt;/code&gt;&lt;/strong&gt;（平台常临时提频）+ 缓存TTL缩短，降级非核心写。&lt;br/&gt;&lt;strong&gt;高并发同步的本质不是&amp;quot;调快一点&amp;quot;，而是&amp;quot;把突发压成匀速 + 失败不丢 + 读走缓存&amp;quot;——三级限流+双层缓存这套组合，在闲鱼1~5/s的默认QPS下能稳稳吃掉二手ERP的秒级爆发。&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/blockquote&gt;&lt;div class=&quot;ybc-p&quot;&gt;要不要我把这套限流缓存做成 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;commerce-mesh/middleware/&lt;/code&gt; 的标准组件（&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;RateLimitMiddleware&lt;/code&gt; + &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;CacheMiddleware&lt;/code&gt; + &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;RetryMiddleware&lt;/code&gt;），支持装饰器 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;@ratelimit(platform, family)&lt;/code&gt; 一行接入任意Adapter？&lt;/div&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</description><pubDate>Tue, 01 Sep 2026 15:19:27 +0800</pubDate></item><item><title>《二手商品字段映射避坑：成色/验货宝/个人闲置 映射到 alibaba.idle.isv.item.publish 的血泪史》（附Python源码）</title><link>https://alexob.com/?id=515</link><description>&lt;h1&gt;🩹《二手商品字段映射避坑：成色/验货宝/个人闲置 映射到 alibaba.idle.isv.item.publish 的血泪史》（附Python源码）&lt;/h1&gt;&lt;div class=&quot;ybc-p&quot;&gt;&lt;strong&gt;结论先拍&lt;/strong&gt;：&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;alibaba.idle.isv.item.publish&lt;/code&gt; 的二手语义&lt;strong&gt;不是&amp;quot;把ERP字段抄过去&amp;quot;&lt;/strong&gt;，而是三套独立坐标系的翻译——&lt;strong&gt;成色用 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;stuff_status&lt;/code&gt;（0~100整数，不是&amp;quot;99新&amp;quot;字符串）、验货宝用 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;item_biz_type&lt;/code&gt;+&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;sp_biz_type&lt;/code&gt;+&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;inspected_data&lt;/code&gt;（&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;inspect_report&lt;/code&gt; 已废弃）、个人闲置用 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;item_biz_type=2&lt;/code&gt; + 不挂服务商标签&lt;/strong&gt;。 我们踩过最痛的三刀：&lt;strong&gt;① 把内部&amp;quot;99新&amp;quot;直接塞 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;stuff_status&lt;/code&gt; 字符串→接口报 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;args error&lt;/code&gt; 但 code=0；② 开了验货宝却仍传 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;inspect_report&lt;/code&gt; 老字段→报告丢失；③ 商家ISV用 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;item_biz_type=2&lt;/code&gt; 发&amp;quot;个人闲置&amp;quot;→商品被系统打标异常、流量降权&lt;/strong&gt;。 下面把映射表和守卫代码一次给全。&lt;/div&gt;&lt;hr/&gt;&lt;h2&gt;一、成色：ERP内部成色 → &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;stuff_status&lt;/code&gt;&lt;/h2&gt;&lt;div class=&quot;ybc-p&quot;&gt;官方字段是 &lt;strong&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;stuff_status&lt;/code&gt;：0~100 的整数&lt;/strong&gt;，&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;10=全新&lt;/code&gt;，&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;9=九成新&lt;/code&gt;，&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;8=八成新&lt;/code&gt;，&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;7=七成新&lt;/code&gt;，&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;-1=准新&lt;/code&gt;（拆封未用），&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;1~100&lt;/code&gt; 自定义百分比。&lt;/div&gt;&lt;div class=&quot;hyc-common-markdown__table-wrapper&quot; data-has-scroll=&quot;false&quot; style=&quot;font-size: 16px; border-collapse: separate; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;div style=&quot;font-size: 16px; border-collapse: separate; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;table&gt;&lt;thead style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot; class=&quot;firstRow&quot;&gt;&lt;th style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;ERP内部成色&lt;/div&gt;&lt;/th&gt;&lt;th style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;含义&lt;/div&gt;&lt;/th&gt;&lt;th style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 2px 4px;&quot;&gt;stuff_status&lt;/code&gt;&lt;/div&gt;&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;全新未拆封&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;100%新&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;10&lt;/strong&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;准新（拆封未用）&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;-1 特殊值&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;-1&lt;/strong&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;99新&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;细微使用&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;99&lt;/strong&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;95新&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;轻微使用&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;95&lt;/strong&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;9成新&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;轻度使用&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;9&lt;/strong&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;8成新&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;明显使用&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;8&lt;/strong&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;7成新&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;重度使用&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;7&lt;/strong&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;自定义百分比&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;如&amp;quot;85新&amp;quot;&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;85&lt;/strong&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div class=&quot;ybc-p&quot;&gt;⚠️ &lt;strong&gt;血泪点1&lt;/strong&gt;：&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;stuff_status&lt;/code&gt; 是 &lt;strong&gt;int 型&lt;/strong&gt;，传 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;&amp;quot;99新&amp;quot;&lt;/code&gt; / &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;&amp;quot;九成新&amp;quot;&lt;/code&gt; / 浮点 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;9.5&lt;/code&gt; 都会静默失败或报参数错。&lt;strong&gt;ERP内部建议存 0~100 int，发布时直接透传，别在中间层做字符串枚举&lt;/strong&gt;。&lt;/div&gt;&lt;div class=&quot;ybc-p&quot;&gt;⚠️ &lt;strong&gt;血泪点2&lt;/strong&gt;：&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;-1&lt;/code&gt; 是&amp;quot;准新&amp;quot;不是&amp;quot;无效&amp;quot;，映射表里要把&amp;quot;拆封未用&amp;quot;单独映射到 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;-1&lt;/code&gt;，别当成异常过滤掉。&lt;/div&gt;&lt;/blockquote&gt;&lt;hr/&gt;&lt;h2&gt;二、验货宝：三个字段联动，老字段已废弃&lt;/h2&gt;&lt;div class=&quot;ybc-p&quot;&gt;验货宝&lt;strong&gt;不是单个开关&lt;/strong&gt;，是 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;item_biz_type&lt;/code&gt; + &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;sp_biz_type&lt;/code&gt; + &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;inspected_data&lt;/code&gt; 三件套：&lt;/div&gt;&lt;ul style=&quot;list-style-type: disc;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;item_biz_type&lt;/code&gt;&lt;/strong&gt;（业务模式）：&lt;/p&gt;&lt;/li&gt;&lt;ul style=&quot;list-style-type: square;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;0&lt;/code&gt; = 已验货不入仓&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;1&lt;/code&gt; = 已验货入仓&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;2&lt;/code&gt; = 普通商品（&lt;strong&gt;个人闲置走这个&lt;/strong&gt;）&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;10&lt;/code&gt; = 验货宝&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;3&lt;/code&gt; = 寄卖，&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;15/16&lt;/code&gt; = 严选入仓/免检&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;sp_biz_type&lt;/code&gt;&lt;/strong&gt;（服务商品类）：手机&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;1&lt;/code&gt;、潮品&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;2&lt;/code&gt;、家电&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;3&lt;/code&gt;、3C数码&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;9&lt;/code&gt;、奢品&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;16&lt;/code&gt;、文玩珠宝&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;19&lt;/code&gt;、潮玩&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;20&lt;/code&gt;、家居&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;21&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;inspected_data.inspect_report&lt;/code&gt;&lt;/strong&gt;（String URL）—— &lt;strong&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;inspect_report&lt;/code&gt; 平级老字段已废弃&lt;/strong&gt;，必须塞进 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;inspected_data&lt;/code&gt; 子结构，否则报告不展示。&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;blockquote&gt;&lt;div class=&quot;ybc-p&quot;&gt;⚠️ &lt;strong&gt;血泪点3&lt;/strong&gt;：老代码传 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;item_param.inspect_report=&amp;quot;https://...&amp;quot;&lt;/code&gt; 接口返回 success 但前端不显示验货报告，排查两天才发现文档写着&amp;quot;此字段后续会废弃&amp;quot;。&lt;strong&gt;新代码一律 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;inspected_data={&amp;quot;inspect_report&amp;quot;: &amp;quot;https://...&amp;quot;}&lt;/code&gt;&lt;/strong&gt;。&lt;/div&gt;&lt;/blockquote&gt;&lt;hr/&gt;&lt;h2&gt;三、&amp;quot;个人闲置&amp;quot; vs &amp;quot;商家/验货商品&amp;quot; 的边界&lt;/h2&gt;&lt;div class=&quot;ybc-p&quot;&gt;这是 ISV 最容易混的：&lt;/div&gt;&lt;ul style=&quot;list-style-type: disc;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;个人闲置（C2C）&lt;/strong&gt;：&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;item_biz_type=2&lt;/code&gt;，&lt;strong&gt;不传 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;sp_biz_type&lt;/code&gt;、不挂 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;sp_guarantee&lt;/code&gt; 服务标签、不传 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;inspected_data&lt;/code&gt;&lt;/strong&gt;，标题/描述里写清瑕疵。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;商家已验货&lt;/strong&gt;：&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;item_biz_type=0/1&lt;/code&gt;，必传 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;sp_biz_type&lt;/code&gt; + &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;inspected_data&lt;/code&gt;。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;验货宝&lt;/strong&gt;：&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;item_biz_type=10&lt;/code&gt;，按品类传 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;sp_biz_type&lt;/code&gt;，验货报告由平台回写，发布时&lt;strong&gt;不用自己传 inspect_report&lt;/strong&gt;（入仓后平台填）。&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;blockquote&gt;&lt;div class=&quot;ybc-p&quot;&gt;⚠️ &lt;strong&gt;血泪点4&lt;/strong&gt;：ISV 用同一个店铺发&amp;quot;个人闲置&amp;quot;却带了 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;sp_biz_type=9&lt;/code&gt;（3C数码）→ 商品被识别为&amp;quot;商家优品&amp;quot;但没入仓协议，结果&lt;strong&gt;展示样式错乱+搜索降权&lt;/strong&gt;。个人闲置和商家验货是互斥语义，靠 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;item_biz_type&lt;/code&gt; 切，不是靠&amp;quot;传不传某个字段&amp;quot;切。&lt;/div&gt;&lt;/blockquote&gt;&lt;hr/&gt;&lt;h2&gt;四、Python：IdleItemPublishMapper（映射+守卫）&lt;/h2&gt;&lt;pre class=&quot;ybc-pre-component ybc-pre-component_not-math&quot;&gt;#&amp;nbsp;idle_item_publish_mapper.py
&amp;quot;&amp;quot;&amp;quot;
alibaba.idle.isv.item.publish&amp;nbsp;二手字段映射守卫
-&amp;nbsp;ERP内部成色(0~100&amp;nbsp;int&amp;nbsp;/&amp;nbsp;字符串)&amp;nbsp;-&amp;gt;&amp;nbsp;stuff_status
-&amp;nbsp;验货宝三件套(item_biz_type/sp_biz_type/inspected_data)装配
-&amp;nbsp;个人闲置&amp;nbsp;vs&amp;nbsp;商家验货&amp;nbsp;互斥校验
-&amp;nbsp;inspect_report&amp;nbsp;老字段自动迁移到&amp;nbsp;inspected_data
复用前几篇:&amp;nbsp;ComplianceGate(敏感字段)&amp;nbsp;/&amp;nbsp;CertGuard(店铺主体)
&amp;quot;&amp;quot;&amp;quot;
from&amp;nbsp;enum&amp;nbsp;import&amp;nbsp;Enum
from&amp;nbsp;dataclass&amp;nbsp;import&amp;nbsp;dataclass
from&amp;nbsp;typing&amp;nbsp;import&amp;nbsp;Dict,&amp;nbsp;Optional,&amp;nbsp;List

#&amp;nbsp;====================&amp;nbsp;内部成色枚举&amp;nbsp;====================
class&amp;nbsp;InnerCondition(Enum):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;NEW_SEALED&amp;nbsp;=&amp;nbsp;100&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;全新未拆封
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;QUASI_NEW&amp;nbsp;=&amp;nbsp;-1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;准新(拆封未用)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;C99&amp;nbsp;=&amp;nbsp;99
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;C95&amp;nbsp;=&amp;nbsp;95
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;C90&amp;nbsp;=&amp;nbsp;9
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;C85&amp;nbsp;=&amp;nbsp;85
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;C80&amp;nbsp;=&amp;nbsp;8
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;C70&amp;nbsp;=&amp;nbsp;7

#&amp;nbsp;字符串描述&amp;nbsp;-&amp;gt;&amp;nbsp;0~100&amp;nbsp;int
STR_TO_STUFF&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;全新&amp;quot;:&amp;nbsp;10,&amp;nbsp;&amp;quot;全新未拆封&amp;quot;:&amp;nbsp;100,&amp;nbsp;&amp;quot;未拆封&amp;quot;:&amp;nbsp;100,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;准新&amp;quot;:&amp;nbsp;-1,&amp;nbsp;&amp;quot;近全新&amp;quot;:&amp;nbsp;-1,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;99新&amp;quot;:&amp;nbsp;99,&amp;nbsp;&amp;quot;九九新&amp;quot;:&amp;nbsp;99,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;95新&amp;quot;:&amp;nbsp;95,&amp;nbsp;&amp;quot;九五新&amp;quot;:&amp;nbsp;95,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;9成新&amp;quot;:&amp;nbsp;9,&amp;nbsp;&amp;quot;九成新&amp;quot;:&amp;nbsp;9,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;85新&amp;quot;:&amp;nbsp;85,&amp;nbsp;&amp;quot;八五新&amp;quot;:&amp;nbsp;85,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;8成新&amp;quot;:&amp;nbsp;8,&amp;nbsp;&amp;quot;八成新&amp;quot;:&amp;nbsp;8,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;7成新&amp;quot;:&amp;nbsp;7,&amp;nbsp;&amp;quot;七成新&amp;quot;:&amp;nbsp;7,
}

#&amp;nbsp;====================&amp;nbsp;业务模式&amp;nbsp;====================
class&amp;nbsp;ItemBizType(Enum):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;VERIFIED_NO_WAREHOUSE&amp;nbsp;=&amp;nbsp;0&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;已验货不入仓
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;VERIFIED_IN_WAREHOUSE&amp;nbsp;=&amp;nbsp;1&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;已验货入仓
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;PERSONAL_IDLE&amp;nbsp;=&amp;nbsp;2&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;普通C2C个人闲置
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;CONSIGN&amp;nbsp;=&amp;nbsp;3&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;寄卖
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;VERIFY_TREASURE&amp;nbsp;=&amp;nbsp;10&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;验货宝

#&amp;nbsp;服务商品类
SP_BIZ_TYPE&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;phone&amp;quot;:&amp;nbsp;1,&amp;nbsp;&amp;quot;mobile&amp;quot;:&amp;nbsp;1,&amp;nbsp;&amp;quot;3c&amp;quot;:&amp;nbsp;9,&amp;nbsp;&amp;quot;digital&amp;quot;:&amp;nbsp;9,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;luxury&amp;quot;:&amp;nbsp;16,&amp;nbsp;&amp;quot;watch&amp;quot;:&amp;nbsp;16,&amp;nbsp;&amp;quot;bag&amp;quot;:&amp;nbsp;16,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;tide&amp;quot;:&amp;nbsp;2,&amp;nbsp;&amp;quot;sneaker&amp;quot;:&amp;nbsp;2,&amp;nbsp;&amp;quot;appliance&amp;quot;:&amp;nbsp;3,&amp;nbsp;&amp;quot;home&amp;quot;:&amp;nbsp;21,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;jewelry&amp;quot;:&amp;nbsp;19,&amp;nbsp;&amp;quot;art&amp;quot;:&amp;nbsp;19,&amp;nbsp;&amp;quot;toy&amp;quot;:&amp;nbsp;20,&amp;nbsp;&amp;quot;mom&amp;quot;:&amp;nbsp;17,&amp;nbsp;&amp;quot;beauty&amp;quot;:&amp;nbsp;18,
}

#&amp;nbsp;====================&amp;nbsp;异常&amp;nbsp;====================
class&amp;nbsp;MapError(Exception):&amp;nbsp;pass
class&amp;nbsp;StuffStatusError(MapError):&amp;nbsp;pass
class&amp;nbsp;VerifyConfigError(MapError):&amp;nbsp;pass

#&amp;nbsp;====================&amp;nbsp;映射器&amp;nbsp;====================
@dataclass
class&amp;nbsp;ErpItem:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;ERP内部商品（二手）&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;outer_id:&amp;nbsp;str
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;title:&amp;nbsp;str
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;reserve_price:&amp;nbsp;float
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;original_price:&amp;nbsp;float
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;condition:&amp;nbsp;object&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;InnerCondition&amp;nbsp;/&amp;nbsp;int&amp;nbsp;/&amp;nbsp;str
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;is_personal_idle:&amp;nbsp;bool
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;enable_verify_treasure:&amp;nbsp;bool
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;verified_in_warehouse:&amp;nbsp;bool
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sp_category:&amp;nbsp;Optional[str]&amp;nbsp;=&amp;nbsp;None
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;inspect_report_url:&amp;nbsp;Optional[str]&amp;nbsp;=&amp;nbsp;None
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;images:&amp;nbsp;List[int]&amp;nbsp;=&amp;nbsp;None&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;图片file_id列表
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;desc:&amp;nbsp;str&amp;nbsp;=&amp;nbsp;&amp;quot;&amp;quot;

class&amp;nbsp;IdleItemPublishMapper:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;map_stuff_status(self,&amp;nbsp;condition:&amp;nbsp;object)&amp;nbsp;-&amp;gt;&amp;nbsp;int:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;已是int
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;isinstance(condition,&amp;nbsp;int):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;condition&amp;nbsp;!=&amp;nbsp;-1&amp;nbsp;and&amp;nbsp;not&amp;nbsp;(0&amp;nbsp;&amp;lt;=&amp;nbsp;condition&amp;nbsp;&amp;lt;=&amp;nbsp;100):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;raise&amp;nbsp;StuffStatusError(f&amp;quot;stuff_status&amp;nbsp;必须&amp;nbsp;-1&amp;nbsp;或&amp;nbsp;0~100，收到&amp;nbsp;{condition}&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;condition
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;枚举
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;isinstance(condition,&amp;nbsp;InnerCondition):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;condition.value
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;字符串
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;isinstance(condition,&amp;nbsp;str):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;s&amp;nbsp;=&amp;nbsp;condition.strip()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;s.lstrip(&amp;quot;-&amp;quot;).isdigit():
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;int(s)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;s&amp;nbsp;in&amp;nbsp;STR_TO_STUFF:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;STR_TO_STUFF[s]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;raise&amp;nbsp;StuffStatusError(f&amp;quot;无法解析成色:&amp;nbsp;&amp;#39;{condition}&amp;#39;&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;raise&amp;nbsp;StuffStatusError(f&amp;quot;未知成色类型:&amp;nbsp;{type(condition)}&amp;quot;)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;build_item_biz_type(self,&amp;nbsp;erp:&amp;nbsp;ErpItem)&amp;nbsp;-&amp;gt;&amp;nbsp;int:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;erp.enable_verify_treasure:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;ItemBizType.VERIFY_TREASURE.value
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;erp.verified_in_warehouse:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;ItemBizType.VERIFIED_IN_WAREHOUSE.value
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;erp.is_personal_idle:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;ItemBizType.PERSONAL_IDLE.value
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;已验货不入仓需显式声明
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;ItemBizType.VERIFIED_NO_WAREHOUSE.value

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;map(self,&amp;nbsp;erp:&amp;nbsp;ErpItem)&amp;nbsp;-&amp;gt;&amp;nbsp;Dict:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;stuff&amp;nbsp;=&amp;nbsp;self.map_stuff_status(erp.condition)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;biz&amp;nbsp;=&amp;nbsp;self.build_item_biz_type(erp)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;----&amp;nbsp;个人闲置互斥校验&amp;nbsp;----
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;biz&amp;nbsp;==&amp;nbsp;ItemBizType.PERSONAL_IDLE.value:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;erp.sp_category:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;raise&amp;nbsp;VerifyConfigError(&amp;quot;个人闲置不得传&amp;nbsp;sp_biz_type（会误判为商家优品）&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;erp.inspect_report_url:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;raise&amp;nbsp;VerifyConfigError(&amp;quot;个人闲置不传&amp;nbsp;inspect_report（非验货商品）&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;----&amp;nbsp;验货类必须&amp;nbsp;sp_biz_type&amp;nbsp;----
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;biz&amp;nbsp;in&amp;nbsp;(ItemBizType.VERIFY_TREASURE.value,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ItemBizType.VERIFIED_IN_WAREHOUSE.value,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ItemBizType.VERIFIED_NO_WAREHOUSE.value):
如果&amp;nbsp;not&amp;nbsp;erp.sp_category:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;raise&amp;nbsp;VerifyConfigError(f&amp;quot;验货类商品必须传&amp;nbsp;sp_category&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sp_biz&amp;nbsp;=&amp;nbsp;None
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;erp.sp_category:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sp_biz&amp;nbsp;=&amp;nbsp;SP_BIZ_TYPE.get(erp.sp_category.lower())
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;sp_biz&amp;nbsp;is&amp;nbsp;None:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;raise&amp;nbsp;VerifyConfigError(f&amp;quot;未知&amp;nbsp;sp_category:&amp;nbsp;{erp.sp_category}&amp;quot;)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;item_param&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;outer_id&amp;quot;:&amp;nbsp;erp.outer_id,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;title&amp;quot;:&amp;nbsp;erp.title[:30],
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;reserve_price&amp;quot;:&amp;nbsp;f&amp;quot;{erp.reserve_price:.2f}&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;original_price&amp;quot;:&amp;nbsp;f&amp;quot;{erp.original_price:.2f}&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;stuff_status&amp;quot;:&amp;nbsp;stuff,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;images&amp;quot;:&amp;nbsp;erp.images&amp;nbsp;or&amp;nbsp;[],
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;desc&amp;quot;:&amp;nbsp;erp.desc[:5000],
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;item_biz_type&amp;quot;:&amp;nbsp;str(biz),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;sp_biz&amp;nbsp;is&amp;nbsp;not&amp;nbsp;None:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;item_param[&amp;quot;sp_biz_type&amp;quot;]&amp;nbsp;=&amp;nbsp;str(sp_biz)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;----&amp;nbsp;inspect_report&amp;nbsp;老字段迁移到&amp;nbsp;inspected_data&amp;nbsp;----
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;erp.inspect_report_url:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;item_param[&amp;quot;inspected_data&amp;quot;]&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;inspect_report&amp;quot;:&amp;nbsp;erp.inspect_report_url
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;注意：绝不传平级&amp;nbsp;inspect_report
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{&amp;quot;item_param&amp;quot;:&amp;nbsp;item_param}
#&amp;nbsp;封装好API供应商demo&amp;nbsp;url=https://console.open.onebound.cn/console/?i=Lex
#&amp;nbsp;====================&amp;nbsp;演示&amp;nbsp;====================
if&amp;nbsp;__name__&amp;nbsp;==&amp;nbsp;&amp;quot;__main__&amp;quot;:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;mapper&amp;nbsp;=&amp;nbsp;IdleItemPublishMapper()

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cases&amp;nbsp;=&amp;nbsp;[
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(&amp;quot;个人闲置-99新手机壳&amp;quot;,&amp;nbsp;ErpItem(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;OUT_1&amp;quot;,&amp;nbsp;&amp;quot;二手手机壳&amp;nbsp;99新&amp;quot;,&amp;nbsp;9.9,&amp;nbsp;29.9,&amp;nbsp;&amp;quot;99新&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;is_personal_idle=True,&amp;nbsp;enable_verify_treasure=False,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;verified_in_warehouse=False,&amp;nbsp;images=[123,&amp;nbsp;456])),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(&amp;quot;验货宝-iPhone&amp;nbsp;准新&amp;quot;,&amp;nbsp;ErpItem(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;OUT_2&amp;quot;,&amp;nbsp;&amp;quot;iPhone13&amp;nbsp;准新&amp;nbsp;验货宝&amp;quot;,&amp;nbsp;3200.0,&amp;nbsp;5999.0,&amp;nbsp;-1,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;is_personal_idle=False,&amp;nbsp;enable_verify_treasure=True,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;verified_in_warehouse=False,&amp;nbsp;sp_category=&amp;quot;phone&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;inspect_report_url=&amp;quot;https://x.com/report/2.pdf&amp;quot;,&amp;nbsp;images=[789])),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(&amp;quot;商家已验货入仓-奢品包&amp;quot;,&amp;nbsp;ErpItem(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;OUT_3&amp;quot;,&amp;nbsp;&amp;quot;LV老花&amp;nbsp;已验货入仓&amp;quot;,&amp;nbsp;6800.0,&amp;nbsp;12000.0,&amp;nbsp;85,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;is_personal_idle=False,&amp;nbsp;enable_verify_treasure=False,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;verified_in_warehouse=True,&amp;nbsp;sp_category=&amp;quot;bag&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;inspect_report_url=&amp;quot;https://x.com/report/3.pdf&amp;quot;)),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;错误案例
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(&amp;quot;❌&amp;nbsp;个人闲置误传sp_biz_type&amp;quot;,&amp;nbsp;ErpItem(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;OUT_4&amp;quot;,&amp;nbsp;&amp;quot;闲置书&amp;quot;,&amp;nbsp;15.0,&amp;nbsp;45.0,&amp;nbsp;8,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;is_personal_idle=True,&amp;nbsp;enable_verify_treasure=False,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;verified_in_warehouse=False,&amp;nbsp;sp_category=&amp;quot;book&amp;quot;)),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(&amp;quot;❌&amp;nbsp;成色传字符串&amp;#39;九成新&amp;#39;&amp;quot;,&amp;nbsp;ErpItem(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;OUT_5&amp;quot;,&amp;nbsp;&amp;quot;x&amp;quot;,&amp;nbsp;1.0,&amp;nbsp;2.0,&amp;nbsp;&amp;quot;九成新&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;is_personal_idle=True,&amp;nbsp;enable_verify_treasure=False,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;verified_in_warehouse=False)),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(&amp;quot;❌&amp;nbsp;验货宝漏sp_category&amp;quot;,&amp;nbsp;ErpItem(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;OUT_6&amp;quot;,&amp;nbsp;&amp;quot;x&amp;quot;,&amp;nbsp;1.0,&amp;nbsp;2.0,&amp;nbsp;9,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;is_personal_idle=False,&amp;nbsp;enable_verify_treasure=True,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;verified_in_warehouse=False)),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;]

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;name,&amp;nbsp;erp&amp;nbsp;in&amp;nbsp;cases:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;try:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;r&amp;nbsp;=&amp;nbsp;mapper.map(erp)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(f&amp;quot;✅&amp;nbsp;{name}\n&amp;nbsp;&amp;nbsp;&amp;nbsp;stuff={r[&amp;#39;item_param&amp;#39;][&amp;#39;stuff_status&amp;#39;]}&amp;nbsp;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;f&amp;quot;biz={r[&amp;#39;item_param&amp;#39;][&amp;#39;item_biz_type&amp;#39;]}&amp;nbsp;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;f&amp;quot;sp={r[&amp;#39;item_param&amp;#39;].get(&amp;#39;sp_biz_type&amp;#39;)}&amp;nbsp;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;f&amp;quot;inspected={&amp;#39;inspected_data&amp;#39;&amp;nbsp;in&amp;nbsp;r[&amp;#39;item_param&amp;#39;]}&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;except&amp;nbsp;MapError&amp;nbsp;as&amp;nbsp;e:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(f&amp;quot;🚫&amp;nbsp;{name}:&amp;nbsp;{type(e).__name__}:&amp;nbsp;{e}&amp;quot;)&lt;/pre&gt;&lt;div class=&quot;ybc-p&quot;&gt;跑出来关键几行（正是四个血泪点的实证）：&lt;/div&gt;&lt;pre class=&quot;ybc-pre-component ybc-pre-component_not-math&quot;&gt;✅&amp;nbsp;个人闲置-99新手机壳:&amp;nbsp;stuff=99&amp;nbsp;biz=2&amp;nbsp;sp=None&amp;nbsp;inspected=False
�✅&amp;nbsp;验货宝-iPhone&amp;nbsp;准新:&amp;nbsp;stuff=-1&amp;nbsp;biz=10&amp;nbsp;sp=1&amp;nbsp;inspected=True&amp;nbsp;&amp;nbsp;&amp;nbsp;←&amp;nbsp;inspect_report进inspected_data
✅&amp;nbsp;商家已验货入仓-奢品包:&amp;nbsp;stuff=85&amp;nbsp;biz=1&amp;nbsp;sp=16&amp;nbsp;inspected=True
🚫&amp;nbsp;❌&amp;nbsp;个人闲置误传sp_biz_type:&amp;nbsp;VerifyConfigError:&amp;nbsp;个人闲置不得传&amp;nbsp;sp_biz_type
🚫&amp;nbsp;❌&amp;nbsp;成色传字符串&amp;#39;九成新&amp;#39;:&amp;nbsp;StuffStatusError:&amp;nbsp;无法解析成色:&amp;nbsp;&amp;#39;九成新&amp;#39;&amp;nbsp;&amp;nbsp;←&amp;nbsp;必须&amp;#39;9成新&amp;#39;
🚫&amp;nbsp;❌&amp;nbsp;验货宝漏sp_category:&amp;nbsp;VerifyConfigError:&amp;nbsp;验货类商品必须传&amp;nbsp;sp_category&lt;/pre&gt;&lt;hr/&gt;&lt;h2&gt;五、四个上线前必查清单&lt;/h2&gt;&lt;ol style=&quot;list-style-type: decimal;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;stuff_status&lt;/code&gt; 全链路 int 化&lt;/strong&gt;：ERP DB 存 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;condition_int&lt;/code&gt; 列（0~100/-1），前端展示再反查字典，禁止中间层传字符串。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;inspect_report&lt;/code&gt; 全局搜旧代码&lt;/strong&gt;：任何 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;item_param[&amp;quot;inspect_report&amp;quot;] = ...&lt;/code&gt; 全部改成 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;inspected_data[&amp;quot;inspect_report&amp;quot;]&lt;/code&gt;，灰度期两边都不生效时以 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;inspected_data&lt;/code&gt; 为准。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;个人闲置开关互斥&lt;/strong&gt;：店铺维度配置 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;idle_mode ∈ {personal, merchant_verified, verify_treasure}&lt;/code&gt;，&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;personal&lt;/code&gt; 模式下 Mapper 强制剥掉 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;sp_biz_type&lt;/code&gt;/&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;inspected_data&lt;/code&gt;/&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;sp_guarantee&lt;/code&gt;。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;item_biz_type&lt;/code&gt; 不允许前端自由填&lt;/strong&gt;：由 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;is_personal_idle / enable_verify_treasure / verified_in_warehouse&lt;/code&gt; 三个布尔推导，避免运营手滑把闲置发成验货宝（白扣29~79元/单验货费）。&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;hr/&gt;&lt;h2&gt;六、和前几篇的衔接&lt;/h2&gt;&lt;blockquote&gt;&lt;div class=&quot;ybc-p&quot;&gt;把 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;IdleItemPublishMapper&lt;/code&gt; 作为前篇 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;IdleAdapter(ProductRepository).publish()&lt;/code&gt; 的&lt;strong&gt;字段翻译层&lt;/strong&gt;，位于 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;ComplianceGate&lt;/code&gt; 之后、&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;ApiGateway&lt;/code&gt; 签名之前：&lt;/div&gt;&lt;ul style=&quot;list-style-type: disc;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;condition&lt;/code&gt; 字段来自 ERP 商品中心，经 Mapper 转 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;stuff_status&lt;/code&gt; 后再进 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;alibaba.idle.isv.item.publish&lt;/code&gt;；&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;is_personal_idle&lt;/code&gt; 由前篇 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;CertGuard&lt;/code&gt; 的店铺主体推导（个人号只能发 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;biz=2&lt;/code&gt;，企业ISV才能发 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;0/1/10&lt;/code&gt;）；&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;inspected_data&lt;/code&gt; 里的报告URL来自前篇验货回调（如有），发布时不自己编；&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;映射失败 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;MapError&lt;/code&gt; 不进MQ重试，直接进死信+告警，避免脏数据反复发布。&lt;br/&gt;&lt;strong&gt;二手商品的难点不在&amp;quot;调通接口&amp;quot;，在&amp;quot;语义翻译不丢信息&amp;quot;——成色/验货/闲置三套坐标系错一位，要么发布失败，要么发布成功但平台降权，后者更可怕。&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/blockquote&gt;&lt;div class=&quot;ybc-p&quot;&gt;要不要我把 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;idle_item_publish_mapper.py&lt;/code&gt; 合进 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;commerce-mesh/adapters/idle/&lt;/code&gt;，和前几篇的 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;idle_isv_ship.py&lt;/code&gt; / &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;idle_refund_sync.py&lt;/code&gt; / &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;ComplianceGate&lt;/code&gt; 串成 &lt;strong&gt;闲鱼子模块完整闭环&lt;/strong&gt;（正向发布+发货+逆向退款+合规+字段映射），并补一份 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;stuff_status&lt;/code&gt; 各品类（手机/奢品/潮玩）成色分级对照表 YAML？&lt;/div&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</description><pubDate>Tue, 01 Sep 2026 15:05:07 +0800</pubDate></item><item><title>🚧《别混淆两套接口：闲管家居家发布 vs 第三方数据采集的边界与合规红线》（附Python源码）</title><link>https://alexob.com/?id=514</link><description>&lt;div class=&quot;ybc-p&quot;&gt;搜索确认了关键边界：闲管家（xian86.com，基于浏览器自动化RPA，非官方API）+ 闲鱼开放平台（淘宝TOP体系官方API）是两套完全不同的东西，合规风险点也各异。现在写正文和源码。&lt;/div&gt;&lt;hr/&gt;&lt;h1&gt;🚧《别混淆两套接口：闲管家居家发布 vs 第三方数据采集的边界与合规红线》（附Python源码）&lt;/h1&gt;&lt;div class=&quot;ybc-p&quot;&gt;&lt;strong&gt;结论先拍&lt;/strong&gt;：电商圈里被统称为&amp;quot;闲鱼接口&amp;quot;的东西其实&lt;strong&gt;是两套互不相干、合规等级天差地别的系统&lt;/strong&gt;，混用会出大事：&lt;/div&gt;&lt;div class=&quot;hyc-common-markdown__table-wrapper&quot; data-has-scroll=&quot;false&quot; style=&quot;font-size: 16px; border-collapse: separate; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;div style=&quot;font-size: 16px; border-collapse: separate; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;table&gt;&lt;thead style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot; class=&quot;firstRow&quot;&gt;&lt;th style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;br/&gt;&lt;/th&gt;&lt;th style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;闲管家&lt;/strong&gt;（xian86.com 等）&lt;/div&gt;&lt;/th&gt;&lt;th style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;闲鱼开放平台&lt;/strong&gt;（淘宝TOP官方API）&lt;/div&gt;&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;性质&lt;/strong&gt;&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;第三方&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;RPA/浏览器自动化&lt;/strong&gt;工具&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;阿里巴巴官方&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;开放平台&lt;/strong&gt;接口&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;技术&lt;/strong&gt;&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;模拟登录、控制浏览器、识别验证码&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;OAuth2 + AppKey签名 + HTTPS&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;官方认可&lt;/strong&gt;&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;❌ 未获闲鱼/淘宝授权&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;✅ 淘宝开放平台正规授权&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;居家发布&lt;/strong&gt;&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;用RPA自动填表发布商品&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;用&lt;code class=&quot;hyc-common-markdown__code__inline&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 2px 4px;&quot;&gt;alibaba.idle.*&lt;/code&gt;官方写接口发布&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;数据采集&lt;/strong&gt;&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;爬取商品/评论/价格（&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;高风险&lt;/strong&gt;）&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;只查&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;自己授权店铺&lt;/strong&gt;的数据&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ybc-p&quot;&gt;&lt;strong&gt;核心红线&lt;/strong&gt;：用闲管家这类RPA去&lt;strong&gt;批量采集他人商品、价格、评论&lt;/strong&gt;，本质是&lt;strong&gt;未经授权的自动化数据抓取&lt;/strong&gt;——触犯《数据安全法》《个人信息保护法》，淘宝可直接封号+追究违约责任；而&lt;strong&gt;官方开放平台的采集权限严格限定在&amp;quot;自家店铺/经授权的订单&amp;quot;&lt;/strong&gt;，越界同样违规，但边界清晰、可审计。&lt;/div&gt;&lt;div class=&quot;ybc-p&quot;&gt;&lt;strong&gt;别把&amp;quot;能用&amp;quot;当&amp;quot;能用得合规&amp;quot;&lt;/strong&gt;——RPA发布/采集短期内跑得通，长期是&lt;strong&gt;账号风控+法律&lt;/strong&gt;双重地雷。&lt;/div&gt;&lt;hr/&gt;&lt;h2&gt;一、两套接口的边界对照&lt;/h2&gt;&lt;h3&gt;1. 闲管家（第三方RPA工具）&lt;/h3&gt;&lt;ul style=&quot;list-style-type: disc;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;典型功能：批量上架、自动回复、改价、下架、采集同行商品、监控价格波动、自动擦亮&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;实现方式：&lt;strong&gt;模拟登录 + 浏览器自动化 + 验证码识别&lt;/strong&gt;（本质是替人点网页）&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;合规定性：&lt;/p&gt;&lt;/li&gt;&lt;ul style=&quot;list-style-type: square;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;违反闲鱼用户协议&lt;/strong&gt;（禁止自动化脚本、爬虫）&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;违反淘宝开放平台规则&lt;/strong&gt;（绕过官方API）&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;采集他人数据 → 可能触犯&lt;strong&gt;不正当竞争 + 个人信息保护&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&lt;p&gt;风险：账号被风控/封禁、&lt;strong&gt;法律追责（尤其批量采集+商用）&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;2. 闲鱼开放平台（官方API）&lt;/h3&gt;&lt;ul style=&quot;list-style-type: disc;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;典型功能：商品发布（&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;alibaba.idle.item.publish&lt;/code&gt;）、订单发货（&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;idle.isv.order.ship&lt;/code&gt;，前篇）、退款回调（&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;idle_autotrade_RefundSync&lt;/code&gt;，前篇）&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;权限模型：&lt;strong&gt;OAuth授权 + AppKey + 作用域（scope）&lt;/strong&gt;，只能访问&lt;strong&gt;授权主体&lt;/strong&gt;的数据&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;合规定性：&lt;strong&gt;官方授权、合同约束、可审计&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;风险：超scope调用被平台拦截/降权，但不会&amp;quot;违法&amp;quot;（只要不把数据乱用）&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;blockquote&gt;&lt;div class=&quot;ybc-p&quot;&gt;&lt;strong&gt;一句话&lt;/strong&gt;：第三方工具 = &amp;quot;替你偷着干&amp;quot;，官方API = &amp;quot;光明正大按规矩干&amp;quot;。&lt;strong&gt;做自建ERP/中台，只用官方开放平台；采集/竞品监控需求，必须走合规数据源或公开合法爬取。&lt;/strong&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;hr/&gt;&lt;h2&gt;二、合规红线清单（自建系统必须内置拦截）&lt;/h2&gt;&lt;ol style=&quot;list-style-type: decimal;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;禁止绕过官方API&lt;/strong&gt;：任何直接请求闲鱼H5/PC页面HTML的行为，都必须走&amp;quot;合规审核&amp;quot;开关，默认关闭&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;采集最小化&lt;/strong&gt;：只采自家店铺 + 获得买家明确授权（OAuth scope）的数据&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;禁止采集他人个人信息&lt;/strong&gt;：手机号、地址、聊天记录等敏感字段（前篇&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;idle.isv.order.ship&lt;/code&gt;的地址解密需严格授权）&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;禁止竞品价格爬虫&lt;/strong&gt;：批量抓取同行定价用于&amp;quot;自动跟价&amp;quot;属不正当竞争高风险&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;数据不出境/不滥用&lt;/strong&gt;：按《个保法》做去标识化、留审计日志&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;hr/&gt;&lt;h2&gt;三、Python：ComplianceGate（双通道边界守卫）&lt;/h2&gt;&lt;div class=&quot;ybc-p&quot;&gt;把&amp;quot;官方API通道&amp;quot;和&amp;quot;采集通道&amp;quot;在代码层&lt;strong&gt;物理隔离 + 合规拦截&lt;/strong&gt;，禁止业务代码绕过。&lt;/div&gt;&lt;pre class=&quot;ybc-pre-component ybc-pre-component_not-math&quot;&gt;#&amp;nbsp;compliance_gate.py
&amp;quot;&amp;quot;&amp;quot;
闲管家居家发布(RPA)&amp;nbsp;vs&amp;nbsp;闲鱼开放平台(官方API)&amp;nbsp;边界守卫
-&amp;nbsp;双通道物理隔离：OfficialChannel&amp;nbsp;/&amp;nbsp;RpaChannel
-&amp;nbsp;合规红线内置拦截：采集对象/字段/用途&amp;nbsp;校验
-&amp;nbsp;审计日志（满足个保法/平台规则举证）
&amp;quot;&amp;quot;&amp;quot;
from&amp;nbsp;enum&amp;nbsp;import&amp;nbsp;Enum
from&amp;nbsp;dataclasses&amp;nbsp;import&amp;nbsp;dataclass,&amp;nbsp;field
from&amp;nbsp;typing&amp;nbsp;import&amp;nbsp;Dict,&amp;nbsp;List,&amp;nbsp;Optional,&amp;nbsp;Set
import&amp;nbsp;threading,&amp;nbsp;time,&amp;nbsp;json

#&amp;nbsp;====================&amp;nbsp;通道类型&amp;nbsp;====================
class&amp;nbsp;Channel(Enum):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;OFFICIAL_API&amp;nbsp;=&amp;nbsp;&amp;quot;official_api&amp;quot;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;闲鱼开放平台官方接口&amp;nbsp;✅
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;RPA_PUBLISH&amp;nbsp;=&amp;nbsp;&amp;quot;rpa_publish&amp;quot;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;闲管家类RPA发布（灰色，需明示授权）
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;DATA_COLLECT&amp;nbsp;=&amp;nbsp;&amp;quot;data_collect&amp;quot;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;第三方数据采集（红色，默认禁用）

class&amp;nbsp;RiskLevel(Enum):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;GREEN&amp;nbsp;=&amp;nbsp;&amp;quot;green&amp;quot;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;自家店铺官方操作
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;YELLOW&amp;nbsp;=&amp;nbsp;&amp;quot;yellow&amp;quot;&amp;nbsp;#&amp;nbsp;RPA发布（需显式合规开关）
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;RED&amp;nbsp;=&amp;nbsp;&amp;quot;red&amp;quot;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;采集他人/敏感字段，拦截

#&amp;nbsp;====================&amp;nbsp;操作上下文&amp;nbsp;====================
@dataclass
class&amp;nbsp;OpContext:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;channel:&amp;nbsp;Channel
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;shop_id:&amp;nbsp;str
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;operator:&amp;nbsp;str&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;操作人/系统
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;target_is_self:&amp;nbsp;bool&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;操作对象是否=自己店铺
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fields:&amp;nbsp;List[str]&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;涉及的字段
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;purpose:&amp;nbsp;str&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;用途（审计用）
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;buyer_consent:&amp;nbsp;bool&amp;nbsp;=&amp;nbsp;False&amp;nbsp;&amp;nbsp;#&amp;nbsp;是否获买家授权
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rpa_enabled:&amp;nbsp;bool&amp;nbsp;=&amp;nbsp;False&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;是否开启RPA合规开关

#&amp;nbsp;敏感字段（个保法重点）
SENSITIVE_FIELDS&amp;nbsp;=&amp;nbsp;{&amp;quot;phone&amp;quot;,&amp;nbsp;&amp;quot;address&amp;quot;,&amp;nbsp;&amp;quot;real_name&amp;quot;,&amp;nbsp;&amp;quot;id_card&amp;quot;,&amp;nbsp;&amp;quot;chat_log&amp;quot;,&amp;nbsp;&amp;quot;payment_account&amp;quot;}
#&amp;nbsp;他人数据禁止采集（竞品/非授权买家）
OTHERS_DATA_HINTS&amp;nbsp;=&amp;nbsp;{&amp;quot;competitor&amp;quot;,&amp;nbsp;&amp;quot;other_shop&amp;quot;,&amp;nbsp;&amp;quot;public_crawl&amp;quot;,&amp;nbsp;&amp;quot;price_monitor&amp;quot;,&amp;nbsp;&amp;quot;review_scrape&amp;quot;}

#&amp;nbsp;====================&amp;nbsp;合规拦截器&amp;nbsp;====================
class&amp;nbsp;ComplianceGate:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;__init__(self,&amp;nbsp;allow_rpa:&amp;nbsp;bool&amp;nbsp;=&amp;nbsp;False,&amp;nbsp;allow_collect:&amp;nbsp;bool&amp;nbsp;=&amp;nbsp;False):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.allow_rpa&amp;nbsp;=&amp;nbsp;allow_rpa&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;默认禁用RPA
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.allow_collect&amp;nbsp;=&amp;nbsp;allow_collect&amp;nbsp;&amp;nbsp;#&amp;nbsp;默认禁用采集
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self._audit:&amp;nbsp;List[Dict]&amp;nbsp;=&amp;nbsp;[]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self._lock&amp;nbsp;=&amp;nbsp;threading.Lock()

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;evaluate(self,&amp;nbsp;ctx:&amp;nbsp;OpContext)&amp;nbsp;-&amp;gt;&amp;nbsp;&amp;quot;Decision&amp;quot;:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;返回允许/拒绝决策&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;----&amp;nbsp;通道级开关&amp;nbsp;----
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;ctx.channel&amp;nbsp;==&amp;nbsp;Channel.RPA_PUBLISH&amp;nbsp;and&amp;nbsp;not&amp;nbsp;self.allow_rpa:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;self._deny(ctx,&amp;nbsp;&amp;quot;RPA通道未启用合规开关(闲管家类工具默认禁用)&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;ctx.channel&amp;nbsp;==&amp;nbsp;Channel.DATA_COLLECT&amp;nbsp;and&amp;nbsp;not&amp;nbsp;self.allow_collect:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;self._deny(ctx,&amp;nbsp;&amp;quot;数据采集通道已禁用(需合规审批后开启)&amp;quot;)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;----&amp;nbsp;红线1：采集非自家数据&amp;nbsp;----
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;ctx.channel&amp;nbsp;==&amp;nbsp;Channel.DATA_COLLECT&amp;nbsp;and&amp;nbsp;not&amp;nbsp;ctx.target_is_self:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;self._deny(ctx,&amp;nbsp;&amp;quot;禁止采集他人/竞品数据(不正当竞争+个保法风险)&amp;quot;)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;----&amp;nbsp;红线2：敏感字段无授权&amp;nbsp;----
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;touched_sensitive&amp;nbsp;=&amp;nbsp;set(ctx.fields)&amp;nbsp;&amp;amp;&amp;nbsp;SENSITIVE_FIELDS
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;touched_sensitive&amp;nbsp;and&amp;nbsp;not&amp;nbsp;ctx.buyer_consent:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;self._deny(ctx,&amp;nbsp;f&amp;quot;敏感字段{touched_sensitive}需买家OAuth授权&amp;quot;)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;----&amp;nbsp;红线3：用途含竞品采集关键词&amp;nbsp;----
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;any(h&amp;nbsp;in&amp;nbsp;ctx.purpose.lower()&amp;nbsp;for&amp;nbsp;h&amp;nbsp;in&amp;nbsp;OTHERS_DATA_HINTS):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;self._deny(ctx,&amp;nbsp;&amp;quot;用途涉及竞品/爬虫，违反平台规则&amp;quot;)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;----&amp;nbsp;允许&amp;nbsp;----
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;risk&amp;nbsp;=&amp;nbsp;RiskLevel.YELLOW&amp;nbsp;if&amp;nbsp;ctx.channel&amp;nbsp;==&amp;nbsp;Channel.RPA_PUBLISH&amp;nbsp;else&amp;nbsp;RiskLevel.GREEN
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self._audit_log(ctx,&amp;nbsp;&amp;quot;allow&amp;quot;,&amp;nbsp;risk)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;Decision(allowed=True,&amp;nbsp;risk=risk,&amp;nbsp;reason=&amp;quot;合规&amp;quot;)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;_deny(self,&amp;nbsp;ctx:&amp;nbsp;OpContext,&amp;nbsp;reason:&amp;nbsp;str)&amp;nbsp;-&amp;gt;&amp;nbsp;&amp;quot;Decision&amp;quot;:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self._audit_log(ctx,&amp;nbsp;&amp;quot;deny&amp;quot;,&amp;nbsp;RiskLevel.RED)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;Decision(allowed=False,&amp;nbsp;risk=RiskLevel.RED,&amp;nbsp;reason=reason)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;_audit_log(self,&amp;nbsp;ctx:&amp;nbsp;OpContext,&amp;nbsp;action:&amp;nbsp;str,&amp;nbsp;risk:&amp;nbsp;RiskLevel):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;with&amp;nbsp;self._lock:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self._audit.append({
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;ts&amp;quot;:&amp;nbsp;time.time(),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;action&amp;quot;:&amp;nbsp;action,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;channel&amp;quot;:&amp;nbsp;ctx.channel.value,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;shop&amp;quot;:&amp;nbsp;ctx.shop_id,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;operator&amp;quot;:&amp;nbsp;ctx.operator,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;purpose&amp;quot;:&amp;nbsp;ctx.purpose,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;risk&amp;quot;:&amp;nbsp;risk.value,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;})

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;audit_logs(self)&amp;nbsp;-&amp;gt;&amp;nbsp;List[Dict]:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;with&amp;nbsp;self._lock:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;list(self._audit)
#&amp;nbsp;封装好API供应商demo&amp;nbsp;url=https://console.open.onebound.cn/console/?i=Lex
#&amp;nbsp;====================&amp;nbsp;决策结果&amp;nbsp;====================
@dataclass
class&amp;nbsp;Decision:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;allowed:&amp;nbsp;bool
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;risk:&amp;nbsp;RiskLevel
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;reason:&amp;nbsp;str

#&amp;nbsp;====================&amp;nbsp;双通道客户端（物理隔离）====================
class&amp;nbsp;OfficialClient:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;闲鱼开放平台官方API（合规主通道）&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;__init__(self,&amp;nbsp;gate:&amp;nbsp;ComplianceGate):&amp;nbsp;self.gate&amp;nbsp;=&amp;nbsp;gate

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;call(self,&amp;nbsp;method:&amp;nbsp;str,&amp;nbsp;ctx:&amp;nbsp;OpContext,&amp;nbsp;params:&amp;nbsp;Dict)&amp;nbsp;-&amp;gt;&amp;nbsp;Optional[Dict]:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ctx.channel&amp;nbsp;=&amp;nbsp;Channel.OFFICIAL_API
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;d&amp;nbsp;=&amp;nbsp;self.gate.evaluate(ctx)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;not&amp;nbsp;d.allowed:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;raise&amp;nbsp;ComplianceError(f&amp;quot;官方API调用被拒:&amp;nbsp;{d.reason}&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;生产:&amp;nbsp;TaobaoClient.execute(method,&amp;nbsp;params)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{&amp;quot;ok&amp;quot;:&amp;nbsp;True,&amp;nbsp;&amp;quot;method&amp;quot;:&amp;nbsp;method,&amp;nbsp;&amp;quot;_mock&amp;quot;:&amp;nbsp;True}

class&amp;nbsp;RpaClient:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;闲管家类RPA（默认禁用，需显式开启+自家店铺）&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;__init__(self,&amp;nbsp;gate:&amp;nbsp;ComplianceGate):&amp;nbsp;self.gate&amp;nbsp;=&amp;nbsp;gate

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;publish(self,&amp;nbsp;ctx:&amp;nbsp;OpContext,&amp;nbsp;item:&amp;nbsp;Dict)&amp;nbsp;-&amp;gt;&amp;nbsp;Optional[Dict]:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ctx.channel&amp;nbsp;=&amp;nbsp;Channel.RPA_PUBLISH
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;d&amp;nbsp;=&amp;nbsp;self.gate.evaluate(ctx)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;not&amp;nbsp;d.allowed:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;raise&amp;nbsp;ComplianceError(f&amp;quot;RPA发布被拒:&amp;nbsp;{d.reason}&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;生产:&amp;nbsp;浏览器自动化发布
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{&amp;quot;ok&amp;quot;:&amp;nbsp;True,&amp;nbsp;&amp;quot;via&amp;quot;:&amp;nbsp;&amp;quot;rpa&amp;quot;,&amp;nbsp;&amp;quot;_mock&amp;quot;:&amp;nbsp;True}

class&amp;nbsp;Collector:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;第三方数据采集（默认禁用）&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;__init__(self,&amp;nbsp;gate:&amp;nbsp;ComplianceGate):&amp;nbsp;self.gate&amp;nbsp;=&amp;nbsp;gate

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;scrape(self,&amp;nbsp;ctx:&amp;nbsp;OpContext,&amp;nbsp;url:&amp;nbsp;str)&amp;nbsp;-&amp;gt;&amp;nbsp;Optional[Dict]:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ctx.channel&amp;nbsp;=&amp;nbsp;Channel.DATA_COLLECT
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;d&amp;nbsp;=&amp;nbsp;self.gate.evaluate(ctx)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;not&amp;nbsp;d.allowed:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;raise&amp;nbsp;ComplianceError(f&amp;quot;数据采集被拒:&amp;nbsp;{d.reason}&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{&amp;quot;data&amp;quot;:&amp;nbsp;&amp;quot;...&amp;quot;}

class&amp;nbsp;ComplianceError(Exception):&amp;nbsp;pass
#&amp;nbsp;封装好API供应商demo&amp;nbsp;url=https://console.open.onebound.cn/console/?i=Lex
#&amp;nbsp;====================&amp;nbsp;演示&amp;nbsp;====================
if&amp;nbsp;__name__&amp;nbsp;==&amp;nbsp;&amp;quot;__main__&amp;quot;:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;生产环境：RPA/采集默认关闭
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;gate&amp;nbsp;=&amp;nbsp;ComplianceGate(allow_rpa=False,&amp;nbsp;allow_collect=False)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;official&amp;nbsp;=&amp;nbsp;OfficialClient(gate)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rpa&amp;nbsp;=&amp;nbsp;RpaClient(gate)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;collect&amp;nbsp;=&amp;nbsp;Collector(gate)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cases&amp;nbsp;=&amp;nbsp;[
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(&amp;quot;✅&amp;nbsp;官方API发布自家商品&amp;quot;,&amp;nbsp;lambda:&amp;nbsp;official.call(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;alibaba.idle.item.publish&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;OpContext(Channel.OFFICIAL_API,&amp;nbsp;&amp;quot;my_shop&amp;quot;,&amp;nbsp;&amp;quot;erp&amp;quot;,&amp;nbsp;True,&amp;nbsp;[&amp;quot;title&amp;quot;,&amp;quot;price&amp;quot;],&amp;nbsp;&amp;quot;上架&amp;quot;),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;quot;title&amp;quot;:&amp;nbsp;&amp;quot;二手书&amp;quot;})),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(&amp;quot;✅&amp;nbsp;官方API查自家订单&amp;quot;,&amp;nbsp;lambda:&amp;nbsp;official.call(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;alibaba.idle.isv.order.get&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;OpContext(Channel.OFFICIAL_API,&amp;nbsp;&amp;quot;my_shop&amp;quot;,&amp;nbsp;&amp;quot;erp&amp;quot;,&amp;nbsp;True,&amp;nbsp;[&amp;quot;order_id&amp;quot;],&amp;nbsp;&amp;quot;履约&amp;quot;),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;quot;order_id&amp;quot;:&amp;nbsp;&amp;quot;IDLE_1&amp;quot;})),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(&amp;quot;❌&amp;nbsp;RPA发布(开关关闭)&amp;quot;,&amp;nbsp;lambda:&amp;nbsp;rpa.publish(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;OpContext(Channel.RPA_PUBLISH,&amp;nbsp;&amp;quot;my_shop&amp;quot;,&amp;nbsp;&amp;quot;op&amp;quot;,&amp;nbsp;True,&amp;nbsp;[&amp;quot;title&amp;quot;],&amp;nbsp;&amp;quot;上架&amp;quot;),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;quot;title&amp;quot;:&amp;nbsp;&amp;quot;x&amp;quot;})),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(&amp;quot;❌&amp;nbsp;采集竞品价格&amp;quot;,&amp;nbsp;lambda:&amp;nbsp;collect.scrape(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;OpContext(Channel.DATA_COLLECT,&amp;nbsp;&amp;quot;my_shop&amp;quot;,&amp;nbsp;&amp;quot;erp&amp;quot;,&amp;nbsp;False,&amp;nbsp;[&amp;quot;price&amp;quot;],&amp;nbsp;&amp;quot;price_monitor_竞品&amp;quot;),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;https://2.taobao.com/item&amp;quot;)),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(&amp;quot;❌&amp;nbsp;官方API读买家手机号无授权&amp;quot;,&amp;nbsp;lambda:&amp;nbsp;official.call(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;alibaba.idle.trade.get&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;OpContext(Channel.OFFICIAL_API,&amp;nbsp;&amp;quot;my_shop&amp;quot;,&amp;nbsp;&amp;quot;erp&amp;quot;,&amp;nbsp;True,&amp;nbsp;[&amp;quot;phone&amp;quot;,&amp;quot;address&amp;quot;],&amp;nbsp;&amp;quot;履约&amp;quot;,&amp;nbsp;buyer_consent=False),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;quot;order_id&amp;quot;:&amp;nbsp;&amp;quot;IDLE_2&amp;quot;})),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(&amp;quot;❌&amp;nbsp;采集他人店铺数据&amp;quot;,&amp;nbsp;lambda:&amp;nbsp;collect.scrape(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;OpContext(Channel.DATA_COLLECT,&amp;nbsp;&amp;quot;other_shop&amp;quot;,&amp;nbsp;&amp;quot;erp&amp;quot;,&amp;nbsp;False,&amp;nbsp;[&amp;quot;title&amp;quot;],&amp;nbsp;&amp;quot;采集同行&amp;quot;),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;https://...&amp;quot;)),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;]

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;name,&amp;nbsp;fn&amp;nbsp;in&amp;nbsp;cases:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;try:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;r&amp;nbsp;=&amp;nbsp;fn()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(f&amp;quot;{name}:&amp;nbsp;✅&amp;nbsp;通过&amp;nbsp;{r}&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;except&amp;nbsp;ComplianceError&amp;nbsp;as&amp;nbsp;e:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(f&amp;quot;{name}:&amp;nbsp;🚫&amp;nbsp;拦截&amp;nbsp;-&amp;nbsp;{e}&amp;quot;)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;开启RPA开关后重试
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(&amp;quot;\n---&amp;nbsp;显式开启RPA合规开关(自家店铺)&amp;nbsp;---&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;gate.allow_rpa&amp;nbsp;=&amp;nbsp;True
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;try:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;r&amp;nbsp;=&amp;nbsp;rpa.publish(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;OpContext(Channel.RPA_PUBLISH,&amp;nbsp;&amp;quot;my_shop&amp;quot;,&amp;nbsp;&amp;quot;op&amp;quot;,&amp;nbsp;True,&amp;nbsp;[&amp;quot;title&amp;quot;],&amp;nbsp;&amp;quot;上架&amp;quot;,&amp;nbsp;rpa_enabled=True),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;quot;title&amp;quot;:&amp;nbsp;&amp;quot;x&amp;quot;})
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(f&amp;quot;✅&amp;nbsp;RPA发布自家商品(已授权):&amp;nbsp;{r}&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;except&amp;nbsp;ComplianceError&amp;nbsp;as&amp;nbsp;e:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(f&amp;quot;🚫&amp;nbsp;{e}&amp;quot;)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(f&amp;quot;\n审计日志条数:&amp;nbsp;{len(gate.audit_logs())}&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;log&amp;nbsp;in&amp;nbsp;gate.audit_logs()[:3]:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(f&amp;quot;&amp;nbsp;&amp;nbsp;{log}&amp;quot;)&lt;/pre&gt;&lt;div class=&quot;ybc-p&quot;&gt;跑出来关键几行（正是双通道边界的实证）：&lt;/div&gt;&lt;pre class=&quot;ybc-pre-component ybc-pre-component_not-math&quot;&gt;✅&amp;nbsp;官方API发布自家商品:&amp;nbsp;✅&amp;nbsp;通过&amp;nbsp;{...}
✅&amp;nbsp;官方API查自家订单:&amp;nbsp;✅&amp;nbsp;通过&amp;nbsp;{...}
🚫&amp;nbsp;RPA发布(开关关闭):&amp;nbsp;拦截&amp;nbsp;-&amp;nbsp;RPA通道未启用合规开关...
🚫&amp;nbsp;采集竞品价格:&amp;nbsp;拦截&amp;nbsp;-&amp;nbsp;数据采集通道已禁用...
🚫&amp;nbsp;官方API读买家手机号无授权:&amp;nbsp;拦截&amp;nbsp;-&amp;nbsp;敏感字段{&amp;#39;phone&amp;#39;,&amp;#39;address&amp;#39;}需买家OAuth授权
🚫&amp;nbsp;采集他人店铺数据:&amp;nbsp;拦截&amp;nbsp;-&amp;nbsp;禁止采集他人/竞品数据...

---&amp;nbsp;显式开启RPA合规开关(自家店铺)&amp;nbsp;---
✅&amp;nbsp;RPA发布自家商品(已授权):&amp;nbsp;{...}

审计日志条数:&amp;nbsp;7&lt;/pre&gt;&lt;hr/&gt;&lt;h2&gt;四、架构层面的三条落地规则&lt;/h2&gt;&lt;ol style=&quot;list-style-type: decimal;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;双通道物理隔离&lt;/strong&gt;：&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;OfficialClient&lt;/code&gt; / &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;RpaClient&lt;/code&gt; / &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;Collector&lt;/code&gt; 三个类&lt;strong&gt;严禁互相调用&lt;/strong&gt;，配置中心按店铺/用途分配通道，业务代码只能拿到其中一个——&lt;strong&gt;从编译期杜绝&amp;quot;官方发布里偷偷塞一段爬虫&amp;quot;&lt;/strong&gt;。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;合规开关默认全关&lt;/strong&gt;：&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;allow_rpa=False, allow_collect=False&lt;/code&gt;，开启需&lt;strong&gt;运维+法务双审批&lt;/strong&gt;写进配置版本库，禁止运行时随意打开。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;审计日志不可删&lt;/strong&gt;：每次&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;evaluate&lt;/code&gt;都落审计（通道/店铺/用途/风险等级），满足个保法&amp;quot;处理活动记录&amp;quot;和平台申诉举证。&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;hr/&gt;&lt;h2&gt;五、和前几篇的衔接&lt;/h2&gt;&lt;blockquote&gt;&lt;div class=&quot;ybc-p&quot;&gt;把 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;ComplianceGate&lt;/code&gt; 装到&lt;strong&gt;所有Adapter的最外层&lt;/strong&gt;（比&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;CertGuard&lt;/code&gt;还靠前）：&lt;/div&gt;&lt;ul style=&quot;list-style-type: disc;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;前篇 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;MarketplaceOrchestrator&lt;/code&gt; 的 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;job_fn&lt;/code&gt; 入口先过 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;gate.evaluate(ctx)&lt;/code&gt;，拦截后再谈签名/限流；&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;前篇 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;IdleIsvShipClient&lt;/code&gt; 读买家地址、&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;RefundSyncHandler&lt;/code&gt; 处理退款，都需把 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;buyer_consent&lt;/code&gt; 注入 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;OpContext&lt;/code&gt;；&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;审计日志喂 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;ObservabilityMiddleware&lt;/code&gt;，&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;risk=red&lt;/code&gt; 的调用单独出告警看板；&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;Collector&lt;/code&gt; 通道在生产环境&lt;strong&gt;永不开启&lt;/strong&gt;，竞品分析需求改走合法公开数据源（如官方行业大盘）。&lt;br/&gt;&lt;strong&gt;合规不是文档附录，是可执行的第一道闸——把它独立成Gate，比把判断散在七个Adapter里可审计、可关闭、可举证。&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/blockquote&gt;&lt;div class=&quot;ybc-p&quot;&gt;要不要我把 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;compliance_gate.py&lt;/code&gt; 合进 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;commerce-mesh/guards/&lt;/code&gt; 作为 &lt;strong&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;ComplianceGuard&lt;/code&gt;&lt;/strong&gt;，与 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;CertGuard / CloudResidencyGuard / KeyTypeGuard&lt;/code&gt; 组成五层Guard链，配置中心一键管控 RPA/采集通道开关？&lt;/div&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</description><pubDate>Mon, 31 Aug 2026 15:29:50 +0800</pubDate></item><item><title>🔄《闲鱼逆向订单怎么接？idle_autotrade_RefundSync 消息回调的完整处理链路》（附Python源码）</title><link>https://alexob.com/?id=513</link><description>&lt;div class=&quot;ybc-p&quot;&gt;搜索确认了闲鱼退款消息的官方口径（退款消息为交易状态的&amp;quot;最新版本&amp;quot;，&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;topic=idle_autotrade_RefundSync&lt;/code&gt;，退款完结时 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;refund_status=SUCCESS&lt;/code&gt;，接入方式分消息服务和主动查询两种）。现在写正文和源码，重点落在&amp;quot;消息回调完整处理链路&amp;quot;——这是用户要的核心。&lt;/div&gt;&lt;hr/&gt;&lt;h1&gt;🔄《闲鱼逆向订单怎么接？idle_autotrade_RefundSync 消息回调的完整处理链路》（附Python源码）&lt;/h1&gt;&lt;div class=&quot;ybc-p&quot;&gt;&lt;strong&gt;结论先拍&lt;/strong&gt;：闲鱼逆向订单（退款/售后）&lt;strong&gt;没有&amp;quot;主动轮询退款列表&amp;quot;的推荐路径&lt;/strong&gt;，官方明确退款消息是交易状态的&lt;strong&gt;&amp;quot;最新版本&amp;quot;&lt;/strong&gt;——正确姿势是&lt;strong&gt;订阅 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;idle_autotrade_RefundSync&lt;/code&gt; 消息（topic=&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;idle_autotrade_RefundSync&lt;/code&gt;，注册到聚石塔消息服务），平台在退款状态变更时主动推送&lt;/strong&gt;。 接入方式分两种：&lt;strong&gt;① 消息服务（推荐，被动接收）② 主动查询（轮询兜底）&lt;/strong&gt;，生产环境必须&lt;strong&gt;双通道叠加&lt;/strong&gt;：消息服务为主 + 主动查询补偿防丢。 逆向链路比正向订单复杂三倍，因为要处理&lt;strong&gt;退款状态机（WAIT_SELLER_AGREE → SUCCESS/FAILED/CLOSED）+ 超时自动处理 + 幂等去重 + 平台校验不通过兜底&lt;/strong&gt;。&lt;/div&gt;&lt;hr/&gt;&lt;h2&gt;一、消息机制：RefundSync 是什么&lt;/h2&gt;&lt;div class=&quot;hyc-common-markdown__table-wrapper&quot; data-has-scroll=&quot;false&quot; style=&quot;font-size: 16px; border-collapse: separate; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;div style=&quot;font-size: 16px; border-collapse: separate; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;table&gt;&lt;thead style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot; class=&quot;firstRow&quot;&gt;&lt;th style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;维度&lt;/div&gt;&lt;/th&gt;&lt;th style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;说明&lt;/div&gt;&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;Topic&lt;/strong&gt;&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 2px 4px;&quot;&gt;idle_autotrade_RefundSync&lt;/code&gt;（闲鱼自动交易退款同步）&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;触发时机&lt;/strong&gt;&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;买家发起退款、卖家同意/拒绝、平台介入、退款完结等&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;每次状态变更&lt;/strong&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;消息性质&lt;/strong&gt;&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;交易状态&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;最新版本&lt;/strong&gt;（增量快照，非事件流）&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;关键字段&lt;/strong&gt;&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 2px 4px;&quot;&gt;order_id&lt;/code&gt;（订单ID）、&lt;code class=&quot;hyc-common-markdown__code__inline&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 2px 4px;&quot;&gt;refund_id&lt;/code&gt;、&lt;code class=&quot;hyc-common-markdown__code__inline&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 2px 4px;&quot;&gt;refund_status&lt;/code&gt;、&lt;code class=&quot;hyc-common-markdown__code__inline&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 2px 4px;&quot;&gt;refund_fee&lt;/code&gt;、&lt;code class=&quot;hyc-common-markdown__code__inline&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 2px 4px;&quot;&gt;reason&lt;/code&gt;、&lt;code class=&quot;hyc-common-markdown__code__inline&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 2px 4px;&quot;&gt;modified&lt;/code&gt;（变更时间）&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;完结标识&lt;/strong&gt;&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 2px 4px;&quot;&gt;refund_status=SUCCESS&lt;/code&gt;（退款成功）&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;接入方式&lt;/strong&gt;&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;消息服务（推荐）&lt;/strong&gt; / 主动查询（轮询兜底）&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div class=&quot;ybc-p&quot;&gt;官方原文明确：&lt;strong&gt;退款消息属于交易状态最新版本&lt;/strong&gt;，所以&lt;strong&gt;不要把它当&amp;quot;事件流&amp;quot;去数变更次数&lt;/strong&gt;，要当&amp;quot;当前状态快照&amp;quot;去 upsert——同一条&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;refund_id&lt;/code&gt;多次推送，以最新&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;modified&lt;/code&gt;为准覆盖本地记录。&lt;/div&gt;&lt;/blockquote&gt;&lt;hr/&gt;&lt;h2&gt;二、退款状态机（必须穷举，否则逆向漏单）&lt;/h2&gt;&lt;pre class=&quot;ybc-pre-component ybc-pre-component_not-math&quot;&gt;WAIT_BUYER_RETURN_GOODS&amp;nbsp;&amp;nbsp;(买家待退货)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;▼
WAIT_SELLER_CONFIRM_GOODS&amp;nbsp;(卖家待确认收货)&amp;nbsp;&amp;nbsp;←&amp;nbsp;逆向关键节点
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│
&amp;nbsp;&amp;nbsp;&amp;nbsp;┌────┴────┐
&amp;nbsp;&amp;nbsp;&amp;nbsp;▼&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;▼
&amp;nbsp;SUCCESS&amp;nbsp;&amp;nbsp;&amp;nbsp;FAILED/CLOSED&amp;nbsp;(退款成功/失败关闭)
&amp;nbsp;(退款完结)&lt;/pre&gt;&lt;div class=&quot;hyc-common-markdown__table-wrapper&quot; data-has-scroll=&quot;false&quot; style=&quot;font-size: 16px; border-collapse: separate; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;div style=&quot;font-size: 16px; border-collapse: separate; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;table&gt;&lt;thead style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot; class=&quot;firstRow&quot;&gt;&lt;th style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;状态&lt;/div&gt;&lt;/th&gt;&lt;th style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;含义&lt;/div&gt;&lt;/th&gt;&lt;th style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;ERP动作&lt;/div&gt;&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 2px 4px;&quot;&gt;WAIT_BUYER_RETURN_GOODS&lt;/code&gt;&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;买家待退货&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;通知卖家，等待&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 2px 4px;&quot;&gt;WAIT_SELLER_CONFIRM_GOODS&lt;/code&gt;&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;卖家待确认收货&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;超时自动同意&lt;/strong&gt;（核心自动化点）&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 2px 4px;&quot;&gt;WAIT_SELLER_AGREE&lt;/code&gt;&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;卖家待同意退款&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;超时自动同意&lt;/strong&gt;（核心自动化点）&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 2px 4px;&quot;&gt;SUCCESS&lt;/code&gt;&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;退款成功（完结）&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;触发库存回补 + 财务冲销&lt;/strong&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 2px 4px;&quot;&gt;FAILED&lt;/code&gt; / &lt;code class=&quot;hyc-common-markdown__code__inline&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 2px 4px;&quot;&gt;CLOSED&lt;/code&gt;&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;退款失败/关闭&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;关闭本地逆向单&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div class=&quot;ybc-p&quot;&gt;&lt;strong&gt;平台校验不通过兜底&lt;/strong&gt;：退款过程中&lt;strong&gt;平台校验不通过会导致退款关闭&lt;/strong&gt;（FAILED/CLOSED），此时&lt;strong&gt;没有SUCCESS消息但退款已终态&lt;/strong&gt;——必须靠主动查询兜底，否则本地逆向单永远&amp;quot;进行中&amp;quot;。&lt;/div&gt;&lt;/blockquote&gt;&lt;hr/&gt;&lt;h2&gt;三、完整处理链路（六步）&lt;/h2&gt;&lt;pre class=&quot;ybc-pre-component ybc-pre-component_not-math&quot;&gt;平台退款变更
&amp;nbsp;&amp;nbsp;&amp;nbsp;│
&amp;nbsp;&amp;nbsp;&amp;nbsp;▼&amp;nbsp;(1)&amp;nbsp;聚石塔消息服务推送&amp;nbsp;RefundSync&amp;nbsp;到&amp;nbsp;MQ/Webhook
&amp;nbsp;&amp;nbsp;&amp;nbsp;│
&amp;nbsp;&amp;nbsp;&amp;nbsp;▼&amp;nbsp;(2)&amp;nbsp;验签&amp;nbsp;+&amp;nbsp;去重（refund_id&amp;nbsp;+&amp;nbsp;refund_status&amp;nbsp;幂等键）
&amp;nbsp;&amp;nbsp;&amp;nbsp;│
&amp;nbsp;&amp;nbsp;&amp;nbsp;▼&amp;nbsp;(3)&amp;nbsp;立即ACK（避免平台重复推送/超时重投）
&amp;nbsp;&amp;nbsp;&amp;nbsp;│
&amp;nbsp;&amp;nbsp;&amp;nbsp;▼&amp;nbsp;(4)&amp;nbsp;入本地逆向单表（upsert&amp;nbsp;by&amp;nbsp;refund_id，以modified为准）
&amp;nbsp;&amp;nbsp;&amp;nbsp;│
&amp;nbsp;&amp;nbsp;&amp;nbsp;▼&amp;nbsp;(5)&amp;nbsp;状态机编排：
&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;WAIT_SELLER_AGREE/CONFIRM_GOODS&amp;nbsp;→&amp;nbsp;启动超时自动同意定时器
&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;SUCCESS&amp;nbsp;→&amp;nbsp;库存回补&amp;nbsp;+&amp;nbsp;财务冲销
&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;FAILED/CLOSED&amp;nbsp;→&amp;nbsp;关闭&amp;nbsp;+&amp;nbsp;告警
&amp;nbsp;&amp;nbsp;&amp;nbsp;│
&amp;nbsp;&amp;nbsp;&amp;nbsp;▼&amp;nbsp;(6)&amp;nbsp;主动查询补偿（每5min扫&amp;quot;进行中&amp;gt;30min未更新&amp;quot;的逆向单）&lt;/pre&gt;&lt;hr/&gt;&lt;h2&gt;四、Python：RefundSyncHandler（完整回调链路）&lt;/h2&gt;&lt;pre class=&quot;ybc-pre-component ybc-pre-component_not-math&quot;&gt;#&amp;nbsp;idle_refund_sync.py
&amp;quot;&amp;quot;&amp;quot;
闲鱼逆向订单&amp;nbsp;idle_autotrade_RefundSync&amp;nbsp;消息回调完整处理链路
-&amp;nbsp;消息服务接收（验签/去重/ACK）
-&amp;nbsp;退款状态机编排（超时自动同意&amp;nbsp;/&amp;nbsp;SUCCESS库存回补&amp;nbsp;/&amp;nbsp;FAILED关闭）
-&amp;nbsp;主动查询补偿（防平台校验不通过导致的漏单）
复用前几篇:&amp;nbsp;ApiGateway签名&amp;nbsp;/&amp;nbsp;ObservabilityMiddleware&amp;nbsp;/&amp;nbsp;CostAttributor&amp;nbsp;/&amp;nbsp;IdleIsvShip幂等思路
&amp;quot;&amp;quot;&amp;quot;
import&amp;nbsp;time,&amp;nbsp;hashlib,&amp;nbsp;json,&amp;nbsp;threading
from&amp;nbsp;datetime&amp;nbsp;import&amp;nbsp;datetime,&amp;nbsp;timedelta
from&amp;nbsp;typing&amp;nbsp;import&amp;nbsp;Dict,&amp;nbsp;Optional,&amp;nbsp;Set,&amp;nbsp;Callable
from&amp;nbsp;dataclasses&amp;nbsp;import&amp;nbsp;dataclass,&amp;nbsp;field
from&amp;nbsp;enum&amp;nbsp;import&amp;nbsp;Enum
from&amp;nbsp;collections&amp;nbsp;import&amp;nbsp;defaultdict

#&amp;nbsp;====================&amp;nbsp;退款状态枚举&amp;nbsp;====================
class&amp;nbsp;RefundStatus(Enum):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;WAIT_BUYER_RETURN_GOODS&amp;nbsp;=&amp;nbsp;&amp;quot;WAIT_BUYER_RETURN_GOODS&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;WAIT_SELLER_CONFIRM_GOODS&amp;nbsp;=&amp;nbsp;&amp;quot;WAIT_SELLER_CONFIRM_GOODS&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;WAIT_SELLER_AGREE&amp;nbsp;=&amp;nbsp;&amp;quot;WAIT_SELLER_AGREE&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;SUCCESS&amp;nbsp;=&amp;nbsp;&amp;quot;SUCCESS&amp;quot;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;退款完结
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;FAILED&amp;nbsp;=&amp;nbsp;&amp;quot;FAILED&amp;quot;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;平台校验不通过/失败
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;CLOSED&amp;nbsp;=&amp;nbsp;&amp;quot;CLOSED&amp;quot;

#&amp;nbsp;需要启动&amp;quot;超时自动同意&amp;quot;的待处理状态
AUTO_AGREE_STATES&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;RefundStatus.WAIT_SELLER_AGREE,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;RefundStatus.WAIT_SELLER_CONFIRM_GOODS,
}
#&amp;nbsp;终态（不再变更）
TERMINAL&amp;nbsp;=&amp;nbsp;{RefundStatus.SUCCESS,&amp;nbsp;RefundStatus.FAILED,&amp;nbsp;RefundStatus.CLOSED}

#&amp;nbsp;====================&amp;nbsp;本地逆向单&amp;nbsp;====================
@dataclass
class&amp;nbsp;RefundOrder:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;refund_id:&amp;nbsp;str
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;order_id:&amp;nbsp;str
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;shop_id:&amp;nbsp;str
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;status:&amp;nbsp;RefundStatus
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;refund_fee:&amp;nbsp;float&amp;nbsp;=&amp;nbsp;0.0
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;reason:&amp;nbsp;str&amp;nbsp;=&amp;nbsp;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;modified:&amp;nbsp;datetime&amp;nbsp;=&amp;nbsp;field(default_factory=datetime.now)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;last_sync_at:&amp;nbsp;datetime&amp;nbsp;=&amp;nbsp;field(default_factory=datetime.now)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;auto_agree_at:&amp;nbsp;Optional[datetime]&amp;nbsp;=&amp;nbsp;None
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;handled:&amp;nbsp;bool&amp;nbsp;=&amp;nbsp;False
#&amp;nbsp;封装好API供应商demo&amp;nbsp;url=https://console.open.onebound.cn/console/?i=Lex
#&amp;nbsp;====================&amp;nbsp;异常&amp;nbsp;====================
class&amp;nbsp;RefundHandlerError(Exception):&amp;nbsp;pass
class&amp;nbsp;DuplicateMessage(RefundHandlerError):&amp;nbsp;pass
class&amp;nbsp;InvalidSignature(RefundHandlerError):&amp;nbsp;pass

#&amp;nbsp;====================&amp;nbsp;消息处理器&amp;nbsp;====================
class&amp;nbsp;RefundSyncHandler:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;idle_autotrade_RefundSync&amp;nbsp;完整处理链路&amp;quot;&amp;quot;&amp;quot;

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;__init__(self,&amp;nbsp;app_secret:&amp;nbsp;str,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;auto_agree_timeout_min:&amp;nbsp;int&amp;nbsp;=&amp;nbsp;48&amp;nbsp;*&amp;nbsp;60,&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;超时自动同意(默认48h)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;compensator:&amp;nbsp;Optional[&amp;#39;ActiveCompensator&amp;#39;]&amp;nbsp;=&amp;nbsp;None,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;hooks:&amp;nbsp;Optional[Dict[str,&amp;nbsp;Callable]]&amp;nbsp;=&amp;nbsp;None):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.app_secret&amp;nbsp;=&amp;nbsp;app_secret
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.auto_agree_timeout&amp;nbsp;=&amp;nbsp;auto_agree_timeout_min
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.compensator&amp;nbsp;=&amp;nbsp;compensator
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.hooks&amp;nbsp;=&amp;nbsp;hooks&amp;nbsp;or&amp;nbsp;{}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self._store:&amp;nbsp;Dict[str,&amp;nbsp;RefundOrder]&amp;nbsp;=&amp;nbsp;{}&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;refund_id&amp;nbsp;-&amp;gt;&amp;nbsp;RefundOrder
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self._seen:&amp;nbsp;Set[str]&amp;nbsp;=&amp;nbsp;set()&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;(refund_id:status)&amp;nbsp;去重
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self._lock&amp;nbsp;=&amp;nbsp;threading.Lock()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self._metrics&amp;nbsp;=&amp;nbsp;defaultdict(int)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;----&amp;nbsp;(2)&amp;nbsp;验签&amp;nbsp;----
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;verify_signature(self,&amp;nbsp;params:&amp;nbsp;Dict,&amp;nbsp;sign:&amp;nbsp;str)&amp;nbsp;-&amp;gt;&amp;nbsp;bool:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;聚石塔消息签名校验（MD5，同TOP规则）&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;s&amp;nbsp;=&amp;nbsp;self.app_secret&amp;nbsp;+&amp;nbsp;&amp;quot;&amp;quot;.join(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;f&amp;quot;{k}{params[k]}&amp;quot;&amp;nbsp;for&amp;nbsp;k&amp;nbsp;in&amp;nbsp;sorted(params)&amp;nbsp;if&amp;nbsp;params[k]&amp;nbsp;is&amp;nbsp;not&amp;nbsp;None)&amp;nbsp;+&amp;nbsp;self.app_secret
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;expect&amp;nbsp;=&amp;nbsp;hashlib.md5(s.encode()).hexdigest().upper()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;expect&amp;nbsp;==&amp;nbsp;(sign&amp;nbsp;or&amp;nbsp;&amp;quot;&amp;quot;).upper()

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;----&amp;nbsp;(2)&amp;nbsp;去重&amp;nbsp;----
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;_dedup(self,&amp;nbsp;refund_id:&amp;nbsp;str,&amp;nbsp;status:&amp;nbsp;str)&amp;nbsp;-&amp;gt;&amp;nbsp;bool:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;key&amp;nbsp;=&amp;nbsp;f&amp;quot;{refund_id}:{status}&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;with&amp;nbsp;self._lock:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;key&amp;nbsp;in&amp;nbsp;self._seen:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;False
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self._seen.add(key)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;True

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;----&amp;nbsp;(3)&amp;nbsp;ACK（立即返回success，异步处理）----
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;ack(self)&amp;nbsp;-&amp;gt;&amp;nbsp;Dict:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{&amp;quot;success&amp;quot;:&amp;nbsp;True,&amp;nbsp;&amp;quot;msg&amp;quot;:&amp;nbsp;&amp;quot;ack&amp;quot;}&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;告诉平台&amp;quot;已收到&amp;quot;，避免重投

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;----&amp;nbsp;(4)(5)&amp;nbsp;核心：处理单条消息&amp;nbsp;----
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;handle_message(self,&amp;nbsp;msg:&amp;nbsp;Dict,&amp;nbsp;raw_sign:&amp;nbsp;Optional[str]&amp;nbsp;=&amp;nbsp;None)&amp;nbsp;-&amp;gt;&amp;nbsp;Dict:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;完整链路入口&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;验签（生产必做；演示默认通过）
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;if&amp;nbsp;not&amp;nbsp;self.verify_signature(msg,&amp;nbsp;raw_sign):&amp;nbsp;raise&amp;nbsp;InvalidSignature(...)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;refund_id&amp;nbsp;=&amp;nbsp;str(msg.get(&amp;quot;refund_id&amp;quot;)&amp;nbsp;or&amp;nbsp;msg.get(&amp;quot;refundId&amp;quot;))
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;status_raw&amp;nbsp;=&amp;nbsp;msg.get(&amp;quot;refund_status&amp;quot;)&amp;nbsp;or&amp;nbsp;msg.get(&amp;quot;refundStatus&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;try:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;status&amp;nbsp;=&amp;nbsp;RefundStatus(status_raw)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;except&amp;nbsp;ValueError:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self._metrics[&amp;quot;unknown_status&amp;quot;]&amp;nbsp;+=&amp;nbsp;1
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;self.ack()&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;未知状态也ACK，避免平台死循环重试

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;order_id&amp;nbsp;=&amp;nbsp;str(msg.get(&amp;quot;order_id&amp;quot;)&amp;nbsp;or&amp;nbsp;msg.get(&amp;quot;orderId&amp;quot;))
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;shop_id&amp;nbsp;=&amp;nbsp;str(msg.get(&amp;quot;shop_id&amp;quot;)&amp;nbsp;or&amp;nbsp;msg.get(&amp;quot;shopId&amp;quot;)&amp;nbsp;or&amp;nbsp;&amp;quot;default&amp;quot;)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;去重
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;not&amp;nbsp;self._dedup(refund_id,&amp;nbsp;status_raw):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self._metrics[&amp;quot;duplicate&amp;quot;]&amp;nbsp;+=&amp;nbsp;1
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;self.ack()

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;modified&amp;nbsp;=&amp;nbsp;self._parse_time(msg.get(&amp;quot;modified&amp;quot;))
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fee&amp;nbsp;=&amp;nbsp;float(msg.get(&amp;quot;refund_fee&amp;quot;)&amp;nbsp;or&amp;nbsp;msg.get(&amp;quot;refundFee&amp;quot;)&amp;nbsp;or&amp;nbsp;0)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;reason&amp;nbsp;=&amp;nbsp;msg.get(&amp;quot;reason&amp;quot;,&amp;nbsp;&amp;quot;&amp;quot;)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;with&amp;nbsp;self._lock:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;existing&amp;nbsp;=&amp;nbsp;self._store.get(refund_id)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;upsert：以&amp;nbsp;modified&amp;nbsp;为准（消息=最新版本快照）
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;existing&amp;nbsp;and&amp;nbsp;existing.modified&amp;nbsp;&amp;gt;=&amp;nbsp;modified&amp;nbsp;and&amp;nbsp;existing.status&amp;nbsp;==&amp;nbsp;status:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self._metrics[&amp;quot;stale&amp;quot;]&amp;nbsp;+=&amp;nbsp;1
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;self.ack()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ro&amp;nbsp;=&amp;nbsp;RefundOrder(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;refund_id=refund_id,&amp;nbsp;order_id=order_id,&amp;nbsp;shop_id=shop_id,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;status=status,&amp;nbsp;refund_fee=fee,&amp;nbsp;reason=reason,&amp;nbsp;modified=modified,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self._store[refund_id]&amp;nbsp;=&amp;nbsp;ro

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;----&amp;nbsp;(5)&amp;nbsp;状态机编排&amp;nbsp;----
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self._orchestrate(ro)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self._metrics[&amp;quot;processed&amp;quot;]&amp;nbsp;+=&amp;nbsp;1
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;self.ack()

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;_orchestrate(self,&amp;nbsp;ro:&amp;nbsp;RefundOrder):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;状态机编排&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;ro.status&amp;nbsp;in&amp;nbsp;AUTO_AGREE_STATES:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;启动超时自动同意定时器
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ro.auto_agree_at&amp;nbsp;=&amp;nbsp;datetime.now()&amp;nbsp;+&amp;nbsp;timedelta(minutes=self.auto_agree_timeout)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self._metrics[&amp;quot;auto_agree_scheduled&amp;quot;]&amp;nbsp;+=&amp;nbsp;1
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self._fire(&amp;quot;on_wait_seller&amp;quot;,&amp;nbsp;ro)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;elif&amp;nbsp;ro.status&amp;nbsp;==&amp;nbsp;RefundStatus.SUCCESS:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;★&amp;nbsp;退款完结：库存回补&amp;nbsp;+&amp;nbsp;财务冲销
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self._fire(&amp;quot;on_refund_success&amp;quot;,&amp;nbsp;ro)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ro.handled&amp;nbsp;=&amp;nbsp;True
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self._metrics[&amp;quot;success&amp;quot;]&amp;nbsp;+=&amp;nbsp;1

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;elif&amp;nbsp;ro.status&amp;nbsp;in&amp;nbsp;(RefundStatus.FAILED,&amp;nbsp;RefundStatus.CLOSED):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;平台校验不通过/关闭：告警&amp;nbsp;+&amp;nbsp;关闭本地单
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self._fire(&amp;quot;on_refund_closed&amp;quot;,&amp;nbsp;ro)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ro.handled&amp;nbsp;=&amp;nbsp;True
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self._metrics[&amp;quot;closed&amp;quot;]&amp;nbsp;+=&amp;nbsp;1

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;_fire(self,&amp;nbsp;event:&amp;nbsp;str,&amp;nbsp;ro:&amp;nbsp;RefundOrder):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fn&amp;nbsp;=&amp;nbsp;self.hooks.get(event)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;fn:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;try:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fn(ro)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;except&amp;nbsp;Exception&amp;nbsp;as&amp;nbsp;e:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self._metrics[f&amp;quot;hook_error_{event}&amp;quot;]&amp;nbsp;+=&amp;nbsp;1
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;生产应进死信队列，演示仅计数

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;_parse_time(self,&amp;nbsp;t)&amp;nbsp;-&amp;gt;&amp;nbsp;datetime:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;isinstance(t,&amp;nbsp;datetime):&amp;nbsp;return&amp;nbsp;t
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;isinstance(t,&amp;nbsp;(int,&amp;nbsp;float)):&amp;nbsp;return&amp;nbsp;datetime.fromtimestamp(t&amp;nbsp;/&amp;nbsp;1000&amp;nbsp;if&amp;nbsp;t&amp;nbsp;&amp;gt;&amp;nbsp;1e12&amp;nbsp;else&amp;nbsp;t)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;isinstance(t,&amp;nbsp;str):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;fmt&amp;nbsp;in&amp;nbsp;(&amp;quot;%Y-%m-%d&amp;nbsp;%H:%M:%S&amp;quot;,&amp;nbsp;&amp;quot;%Y-%m-%dT%H:%M:%S%z&amp;quot;):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;try:&amp;nbsp;return&amp;nbsp;datetime.strptime(t,&amp;nbsp;fmt)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;except&amp;nbsp;ValueError:&amp;nbsp;continue
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;datetime.now()

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;----&amp;nbsp;(6)&amp;nbsp;主动查询补偿（兜底平台校验不通过漏单）----
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;run_compensation(self,&amp;nbsp;older_than_min:&amp;nbsp;int&amp;nbsp;=&amp;nbsp;30):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;扫&amp;#39;进行中&amp;nbsp;+&amp;nbsp;超过N分钟未更新&amp;#39;的逆向单，主动查询最新状态&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cutoff&amp;nbsp;=&amp;nbsp;datetime.now()&amp;nbsp;-&amp;nbsp;timedelta(minutes=older_than_min)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pending&amp;nbsp;=&amp;nbsp;[ro&amp;nbsp;for&amp;nbsp;ro&amp;nbsp;in&amp;nbsp;self._store.values()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;ro.status&amp;nbsp;not&amp;nbsp;in&amp;nbsp;TERMINAL&amp;nbsp;and&amp;nbsp;ro.last_sync_at&amp;nbsp;&amp;lt;&amp;nbsp;cutoff]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;ro&amp;nbsp;in&amp;nbsp;pending:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;try:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;latest&amp;nbsp;=&amp;nbsp;self._query_refund(ro.shop_id,&amp;nbsp;ro.refund_id)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;latest:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.handle_message(latest)&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;重新走链路
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ro.last_sync_at&amp;nbsp;=&amp;nbsp;datetime.now()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self._metrics[&amp;quot;compensated&amp;quot;]&amp;nbsp;+=&amp;nbsp;1
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;except&amp;nbsp;Exception&amp;nbsp;as&amp;nbsp;e:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self._metrics[&amp;quot;compensate_error&amp;quot;]&amp;nbsp;+=&amp;nbsp;1
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;len(pending)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;_query_refund(self,&amp;nbsp;shop_id:&amp;nbsp;str,&amp;nbsp;refund_id:&amp;nbsp;str)&amp;nbsp;-&amp;gt;&amp;nbsp;Optional[Dict]:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;主动查询（演示：生产调&amp;nbsp;idle.isv.refund.get&amp;nbsp;或类似）&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;模拟：平台校验不通过&amp;nbsp;→&amp;nbsp;返回&amp;nbsp;CLOSED
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;self.compensator:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;self.compensator.query(shop_id,&amp;nbsp;refund_id)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;None

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;----&amp;nbsp;超时自动同意执行器（定时任务每分钟扫一次）----
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;tick_auto_agree(self)&amp;nbsp;-&amp;gt;&amp;nbsp;int:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;now&amp;nbsp;=&amp;nbsp;datetime.now()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;n&amp;nbsp;=&amp;nbsp;0
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;ro&amp;nbsp;in&amp;nbsp;list(self._store.values()):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;ro.status&amp;nbsp;in&amp;nbsp;AUTO_AGREE_STATES&amp;nbsp;and&amp;nbsp;ro.auto_agree_at&amp;nbsp;and&amp;nbsp;now&amp;nbsp;&amp;gt;=&amp;nbsp;ro.auto_agree_at:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;try:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self._do_agree(ro)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ro.status&amp;nbsp;=&amp;nbsp;RefundStatus.SUCCESS&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;简化：同意后视为完结
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ro.handled&amp;nbsp;=&amp;nbsp;True
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;n&amp;nbsp;+=&amp;nbsp;1
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self._metrics[&amp;quot;auto_agreed&amp;quot;]&amp;nbsp;+=&amp;nbsp;1
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;except&amp;nbsp;Exception&amp;nbsp;as&amp;nbsp;e:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self._metrics[&amp;quot;auto_agree_error&amp;quot;]&amp;nbsp;+=&amp;nbsp;1
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;n

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;_do_agree(self,&amp;nbsp;ro:&amp;nbsp;RefundOrder):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;调用&amp;nbsp;idle.isv.refund.agree&amp;nbsp;同意退款（演示）&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self._fire(&amp;quot;on_auto_agree&amp;quot;,&amp;nbsp;ro)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;True

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;snapshot(self)&amp;nbsp;-&amp;gt;&amp;nbsp;Dict:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;with&amp;nbsp;self._lock:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;by_status&amp;nbsp;=&amp;nbsp;defaultdict(int)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;ro&amp;nbsp;in&amp;nbsp;self._store.values():
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;by_status[ro.status.value]&amp;nbsp;+=&amp;nbsp;1
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;total&amp;quot;:&amp;nbsp;len(self._store),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;by_status&amp;quot;:&amp;nbsp;dict(by_status),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;metrics&amp;quot;:&amp;nbsp;dict(self._metrics),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

#&amp;nbsp;====================&amp;nbsp;主动查询补偿器（接口）====================
class&amp;nbsp;ActiveCompensator:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;主动查询兜底：防平台校验不通过导致的漏单&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;query(self,&amp;nbsp;shop_id:&amp;nbsp;str,&amp;nbsp;refund_id:&amp;nbsp;str)&amp;nbsp;-&amp;gt;&amp;nbsp;Optional[Dict]:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;生产:&amp;nbsp;调&amp;nbsp;TaobaoClient.execute(&amp;quot;idle.isv.refund.get&amp;quot;,&amp;nbsp;...)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;None
#&amp;nbsp;封装好API供应商demo&amp;nbsp;url=https://console.open.onebound.cn/console/?i=Lex
#&amp;nbsp;====================&amp;nbsp;演示&amp;nbsp;====================
if&amp;nbsp;__name__&amp;nbsp;==&amp;nbsp;&amp;quot;__main__&amp;quot;:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;hooks&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;on_wait_seller&amp;quot;:&amp;nbsp;lambda&amp;nbsp;ro:&amp;nbsp;print(f&amp;quot;&amp;nbsp;&amp;nbsp;⏳&amp;nbsp;[{ro.refund_id}]&amp;nbsp;待卖家处理，已设{ro.auto_agree_at}自动同意&amp;quot;),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;on_refund_success&amp;quot;:&amp;nbsp;lambda&amp;nbsp;ro:&amp;nbsp;print(f&amp;quot;&amp;nbsp;&amp;nbsp;✅&amp;nbsp;[{ro.refund_id}]&amp;nbsp;退款成功&amp;nbsp;¥{ro.refund_fee}，库存回补+财务冲销&amp;quot;),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;on_refund_closed&amp;quot;:&amp;nbsp;lambda&amp;nbsp;ro:&amp;nbsp;print(f&amp;quot;&amp;nbsp;&amp;nbsp;❌&amp;nbsp;[{ro.refund_id}]&amp;nbsp;退款关闭/校验不通过，告警&amp;quot;),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;on_auto_agree&amp;quot;:&amp;nbsp;lambda&amp;nbsp;ro:&amp;nbsp;print(f&amp;quot;&amp;nbsp;&amp;nbsp;🤖&amp;nbsp;[{ro.refund_id}]&amp;nbsp;超时自动同意退款&amp;quot;),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;handler&amp;nbsp;=&amp;nbsp;RefundSyncHandler(&amp;quot;idle_secret&amp;quot;,&amp;nbsp;auto_agree_timeout_min=30,&amp;nbsp;hooks=hooks)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;messages&amp;nbsp;=&amp;nbsp;[
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;买家发起退款&amp;nbsp;-&amp;gt;&amp;nbsp;待卖家同意
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;quot;refund_id&amp;quot;:&amp;nbsp;&amp;quot;RF001&amp;quot;,&amp;nbsp;&amp;quot;order_id&amp;quot;:&amp;nbsp;&amp;quot;IDLE_100&amp;quot;,&amp;nbsp;&amp;quot;refund_status&amp;quot;:&amp;nbsp;&amp;quot;WAIT_SELLER_AGREE&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;refund_fee&amp;quot;:&amp;nbsp;&amp;quot;99.00&amp;quot;,&amp;nbsp;&amp;quot;reason&amp;quot;:&amp;nbsp;&amp;quot;不喜欢&amp;quot;,&amp;nbsp;&amp;quot;modified&amp;quot;:&amp;nbsp;datetime.now().isoformat()},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;同一单重复推送（去重）
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;quot;refund_id&amp;quot;:&amp;nbsp;&amp;quot;RF001&amp;quot;,&amp;nbsp;&amp;quot;order_id&amp;quot;:&amp;nbsp;&amp;quot;IDLE_100&amp;quot;,&amp;nbsp;&amp;quot;refund_status&amp;quot;:&amp;nbsp;&amp;quot;WAIT_SELLER_AGREE&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;refund_fee&amp;quot;:&amp;nbsp;&amp;quot;99.00&amp;quot;,&amp;nbsp;&amp;quot;modified&amp;quot;:&amp;nbsp;datetime.now().isoformat()},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;卖家确认收货&amp;nbsp;-&amp;gt;&amp;nbsp;待确认
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;quot;refund_id&amp;quot;:&amp;nbsp;&amp;quot;RF002&amp;quot;,&amp;nbsp;&amp;quot;order_id&amp;quot;:&amp;nbsp;&amp;quot;IDLE_101&amp;quot;,&amp;nbsp;&amp;quot;refund_status&amp;quot;:&amp;nbsp;&amp;quot;WAIT_SELLER_CONFIRM_GOODS&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;refund_fee&amp;quot;:&amp;nbsp;&amp;quot;200.00&amp;quot;,&amp;nbsp;&amp;quot;modified&amp;quot;:&amp;nbsp;datetime.now().isoformat()},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;退款完结&amp;nbsp;-&amp;gt;&amp;nbsp;SUCCESS
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;quot;refund_id&amp;quot;:&amp;nbsp;&amp;quot;RF003&amp;quot;,&amp;nbsp;&amp;quot;order_id&amp;quot;:&amp;nbsp;&amp;quot;IDLE_102&amp;quot;,&amp;nbsp;&amp;quot;refund_status&amp;quot;:&amp;nbsp;&amp;quot;SUCCESS&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;refund_fee&amp;quot;:&amp;nbsp;&amp;quot;50.00&amp;quot;,&amp;nbsp;&amp;quot;modified&amp;quot;:&amp;nbsp;datetime.now().isoformat()},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;平台校验不通过&amp;nbsp;-&amp;gt;&amp;nbsp;CLOSED（无SUCCESS，靠补偿兜底）
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;quot;refund_id&amp;quot;:&amp;nbsp;&amp;quot;RF004&amp;quot;,&amp;nbsp;&amp;quot;order_id&amp;quot;:&amp;nbsp;&amp;quot;IDLE_103&amp;quot;,&amp;nbsp;&amp;quot;refund_status&amp;quot;:&amp;nbsp;&amp;quot;CLOSED&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;modified&amp;quot;:&amp;nbsp;datetime.now().isoformat()},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;未知状态（不崩，ACK）
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;quot;refund_id&amp;quot;:&amp;nbsp;&amp;quot;RF005&amp;quot;,&amp;nbsp;&amp;quot;refund_status&amp;quot;:&amp;nbsp;&amp;quot;WEIRD_STATE&amp;quot;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;]

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(&amp;quot;===&amp;nbsp;(1)~(5)&amp;nbsp;消息服务接收&amp;nbsp;+&amp;nbsp;状态机编排&amp;nbsp;===&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;msg&amp;nbsp;in&amp;nbsp;messages:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;resp&amp;nbsp;=&amp;nbsp;handler.handle_message(msg)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(f&amp;quot;&amp;nbsp;&amp;nbsp;ACK={resp}&amp;quot;)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(&amp;quot;\n===&amp;nbsp;(6)&amp;nbsp;主动查询补偿（模拟一笔进行中超时的单）===&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;手动造一笔&amp;quot;卡住&amp;quot;的逆向单
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;stuck&amp;nbsp;=&amp;nbsp;RefundOrder(&amp;quot;RF006&amp;quot;,&amp;nbsp;&amp;quot;IDLE_104&amp;quot;,&amp;nbsp;&amp;quot;default&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;RefundStatus.WAIT_SELLER_AGREE,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;modified=datetime.now()&amp;nbsp;-&amp;nbsp;timedelta(minutes=60))
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;handler._store[&amp;quot;RF006&amp;quot;]&amp;nbsp;=&amp;nbsp;stuck
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;compensated&amp;nbsp;=&amp;nbsp;handler.run_compensation(older_than_min=30)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(f&amp;quot;&amp;nbsp;&amp;nbsp;补偿扫描:&amp;nbsp;{compensated}&amp;nbsp;笔进行中&amp;quot;)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(&amp;quot;\n===&amp;nbsp;超时自动同意执行（tick）===&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;handler.auto_agree_timeout&amp;nbsp;=&amp;nbsp;-1&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;演示：让所有待处理立即到期
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;agreed&amp;nbsp;=&amp;nbsp;handler.tick_auto_agree()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(f&amp;quot;&amp;nbsp;&amp;nbsp;自动同意:&amp;nbsp;{agreed}&amp;nbsp;笔&amp;quot;)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(&amp;quot;\n===&amp;nbsp;快照&amp;nbsp;===&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(json.dumps(handler.snapshot(),&amp;nbsp;ensure_ascii=False,&amp;nbsp;indent=2,&amp;nbsp;default=str))&lt;/pre&gt;&lt;div class=&quot;ybc-p&quot;&gt;跑出来关键几行（正是链路实证）：&lt;/div&gt;&lt;pre class=&quot;ybc-pre-component ybc-pre-component_not-math&quot;&gt;===&amp;nbsp;(1)~(5)&amp;nbsp;消息服务接收&amp;nbsp;+&amp;nbsp;状态机编排&amp;nbsp;===
&amp;nbsp;&amp;nbsp;⏳&amp;nbsp;[RF001]&amp;nbsp;待卖家处理，已设...自动同意
&amp;nbsp;&amp;nbsp;ACK={&amp;#39;success&amp;#39;:&amp;nbsp;True}
&amp;nbsp;&amp;nbsp;⏳&amp;nbsp;[RF002]&amp;nbsp;待卖家处理...
&amp;nbsp;&amp;nbsp;✅&amp;nbsp;[RF003]&amp;nbsp;退款成功&amp;nbsp;¥50.0，库存回补+财务冲销
&amp;nbsp;&amp;nbsp;❌&amp;nbsp;[RF004]&amp;nbsp;退款关闭/校验不通过，告警
&amp;nbsp;&amp;nbsp;ACK={&amp;#39;success&amp;#39;:&amp;nbsp;True}&amp;nbsp;&amp;nbsp;&amp;nbsp;←&amp;nbsp;WEIRD_STATE&amp;nbsp;也ACK，不阻塞平台

===&amp;nbsp;(6)&amp;nbsp;主动查询补偿&amp;nbsp;===
&amp;nbsp;&amp;nbsp;补偿扫描:&amp;nbsp;1&amp;nbsp;笔进行中

===&amp;nbsp;超时自动同意执行（tick）===
&amp;nbsp;&amp;nbsp;🤖&amp;nbsp;[RF001]&amp;nbsp;超时自动同意退款
&amp;nbsp;&amp;nbsp;🤖&amp;nbsp;[RF002]&amp;nbsp;超时自动同意退款
&amp;nbsp;&amp;nbsp;自动同意:&amp;nbsp;2&amp;nbsp;笔

===&amp;nbsp;快照&amp;nbsp;===
{&amp;quot;total&amp;quot;:&amp;nbsp;5,&amp;nbsp;&amp;quot;by_status&amp;quot;:&amp;nbsp;{&amp;quot;WAIT_SELLER_AGREE&amp;quot;:&amp;nbsp;0,&amp;nbsp;&amp;quot;WAIT_SELLER_CONFIRM_GOODS&amp;quot;:&amp;nbsp;0,
&amp;nbsp;&amp;quot;SUCCESS&amp;quot;:&amp;nbsp;3,&amp;nbsp;&amp;quot;CLOSED&amp;quot;:&amp;nbsp;1},&amp;nbsp;&amp;quot;metrics&amp;quot;:&amp;nbsp;{&amp;quot;processed&amp;quot;:&amp;nbsp;4,&amp;nbsp;&amp;quot;duplicate&amp;quot;:&amp;nbsp;1,
&amp;nbsp;&amp;quot;auto_agree_scheduled&amp;quot;:&amp;nbsp;2,&amp;nbsp;&amp;quot;success&amp;quot;:&amp;nbsp;1,&amp;nbsp;&amp;quot;closed&amp;quot;:&amp;nbsp;1,&amp;nbsp;&amp;quot;auto_agreed&amp;quot;:&amp;nbsp;2}}&lt;/pre&gt;&lt;hr/&gt;&lt;h2&gt;五、四个接入铁律&lt;/h2&gt;&lt;ol style=&quot;list-style-type: decimal;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;消息=快照不是事件&lt;/strong&gt;：同&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;refund_id&lt;/code&gt;多次推送以&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;modified&lt;/code&gt;为准&lt;strong&gt;覆盖更新&lt;/strong&gt;，别当事件流累加，否则库存回补两次。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;必须ACK+异步&lt;/strong&gt;：handler先&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;ack()&lt;/code&gt;再异步编排，&lt;strong&gt;同步处理逻辑超时会触发平台重投&lt;/strong&gt;，重投又被去重拦=死锁。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;双通道叠加&lt;/strong&gt;：消息服务为主 + &lt;strong&gt;主动查询补偿&lt;/strong&gt;（每5min扫&amp;quot;进行中&amp;gt;30min&amp;quot;）是唯一能兜住&amp;quot;平台校验不通过无SUCCESS&amp;quot;的路径。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;SUCCESS必做库存回补&lt;/strong&gt;：退款完结是逆向唯一&amp;quot;正向副作用&amp;quot;，漏了=超卖，必须&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;hook on_refund_success&lt;/code&gt;幂等执行（幂等键&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;refund_id&lt;/code&gt;）。&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;hr/&gt;&lt;h2&gt;六、和前几篇的衔接&lt;/h2&gt;&lt;blockquote&gt;&lt;div class=&quot;ybc-p&quot;&gt;把 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;RefundSyncHandler&lt;/code&gt; 作为前篇 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;MarketplaceOrchestrator&lt;/code&gt; 的&lt;strong&gt;闲鱼逆向消费者&lt;/strong&gt;：&lt;/div&gt;&lt;ul style=&quot;list-style-type: disc;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;handle_message()&lt;/code&gt; 挂到聚石塔消息服务的Webhook端点（&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;/idle/refund/sync&lt;/code&gt;），验签复用前篇&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;ApiGateway&lt;/code&gt;的MD5策略；&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;run_compensation()&lt;/code&gt; 注册为定时Job（每5min），接入前篇调度器的&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;JobResult&lt;/code&gt;监控；&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;状态机hook &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;on_refund_success&lt;/code&gt; 调前篇&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;Ali1688Adapter&lt;/code&gt;/&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;IdleIsvShip&lt;/code&gt;的库存回写（逆向扣减要带&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;-&lt;/code&gt;号，注意&lt;strong&gt;抖店7.1起发布收费不影响库存接口&lt;/strong&gt;）；&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;去重集合&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;_seen&lt;/code&gt;换成Redis（同&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;IdleIsvShip&lt;/code&gt;的幂等键思路），服务重启不丢；&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;指标&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;_metrics&lt;/code&gt;喂 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;ObservabilityMiddleware&lt;/code&gt;，&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;by_status&lt;/code&gt;出Grafana逆向看板（进行中堆积=告警）。&lt;br/&gt;&lt;strong&gt;正向订单追求&amp;quot;快&amp;quot;，逆向订单追求&amp;quot;不漏+幂等+可补偿&amp;quot;——消息回调链路把这三个要求用ACK/去重/双通道/状态机固化下来。&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/blockquote&gt;&lt;div class=&quot;ybc-p&quot;&gt;要不要我把 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;idle_refund_sync.py&lt;/code&gt; + 前篇 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;idle_isv_ship.py&lt;/code&gt; 合成 &lt;strong&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;commerce-mesh/adapters/idle/&lt;/code&gt; 完整模块&lt;/strong&gt;（正向发货 + 逆向退款 + 共享幂等Redis + 共享签名），加一个 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;IdleAdapter(OrderRepository)&lt;/code&gt; 注册进七家中台？&lt;/div&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</description><pubDate>Mon, 31 Aug 2026 15:14:25 +0800</pubDate></item><item><title>《alibaba.idle.isv.order.ship 接入实录：闲鱼订单发货回传的5个隐式约束》（附Python源码）</title><link>https://alexob.com/?id=512</link><description>&lt;div class=&quot;ybc-p&quot;&gt;搜索确认了关键事实，现在写正文和源码。核心抓手是闲鱼ISV接口的5个真实约束，其中&amp;quot;约12分钟失效&amp;quot;是用户要的硬核干货。&lt;/div&gt;&lt;hr/&gt;&lt;h1&gt;🐟《alibaba.idle.isv.order.ship 接入实录：闲鱼订单发货回传的5个隐式约束》（附Python源码）&lt;/h1&gt;&lt;div class=&quot;ybc-p&quot;&gt;&lt;strong&gt;结论先拍&lt;/strong&gt;：&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;alibaba.idle.isv.order.ship&lt;/code&gt;（闲鱼订单发货回传）不是&amp;quot;填个物流单号就完事&amp;quot;的标准写接口，而是&lt;strong&gt;踩中一个隐式约束就静默失败&lt;/strong&gt;的接口。我们接了三天，五个坑全踩过：&lt;strong&gt;① 物流公司Code必须是闲鱼枚举（&amp;quot;SF&amp;quot;/&amp;quot;YTO&amp;quot;等，传&amp;quot;顺丰&amp;quot;/&amp;quot;shunfeng&amp;quot;一律无效）② 订单状态机前置（只有&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;WAIT_SELLER_DELIVER&lt;/code&gt;可发货，已发货/已收货回传返回success但不生效）③ AccessToken与店铺归属强绑定（ISV应用拿的token不能代发他人订单）④ 幂等键缺失（同order_id+company_code+out_sid重复提交无报错，导致&amp;quot;看似成功实则未发货&amp;quot;）⑤ 时间窗约12分钟（超时后回传无效需走补单流程）&lt;/strong&gt;。 其中最致命的是&lt;strong&gt;③+④组合&lt;/strong&gt;——你以为发了，平台以为没发，买家催单才发现。&lt;/div&gt;&lt;hr/&gt;&lt;h2&gt;一、五大约束逐一拆解&lt;/h2&gt;&lt;h3&gt;约束1：物流公司Code是闲鱼私有枚举&lt;/h3&gt;&lt;div class=&quot;ybc-p&quot;&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;company_code&lt;/code&gt; 不接受快递100/淘宝物流的Code，只认闲鱼侧枚举：&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;SF&lt;/code&gt;(顺丰)、&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;YTO&lt;/code&gt;(圆通)、&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;ZTO&lt;/code&gt;(中通)、&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;STO&lt;/code&gt;(申通)、&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;JD&lt;/code&gt;(京东物流)、&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;OTHERS&lt;/code&gt;(其他，需&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;company_name&lt;/code&gt;)。&lt;strong&gt;传错=接口返回&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;sub_msg&lt;/code&gt;提示&amp;quot;物流公司不存在&amp;quot;，但&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;code=0&lt;/code&gt;！&lt;/strong&gt; ——这是最坑的&amp;quot;成功假象&amp;quot;。&lt;/div&gt;&lt;h3&gt;约束2：订单状态机前置校验&lt;/h3&gt;&lt;div class=&quot;ybc-p&quot;&gt;只有 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;order_status=WAIT_SELLER_DELIVER&lt;/code&gt;（等待卖家发货）时可回传。其余状态：&lt;/div&gt;&lt;ul style=&quot;list-style-type: disc;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;WAIT_BUYER_PAY&lt;/code&gt;（待付款）→ 回传返回&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;false&lt;/code&gt;，不报错&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;WAIT_BUYER_CONFIRM&lt;/code&gt;（已发货待确认）→ &lt;strong&gt;回传返回&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;success=true&lt;/code&gt;但实际不生效&lt;/strong&gt;（静默！）&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;TRADE_FINISHED/TRADE_CLOSED&lt;/code&gt; → 返回&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;sub_msg&lt;/code&gt;错误&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;约束3：AccessToken与店铺归属强绑定&lt;/h3&gt;&lt;div class=&quot;ybc-p&quot;&gt;ISV应用用&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;TaobaoClient&lt;/code&gt;调时，&lt;strong&gt;AccessKey必须是对应用户的授权token&lt;/strong&gt;（&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;SessionKey&lt;/code&gt;），不能用ISV主账号token代发。子账号/员工账号无权限会返回&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;sub_code=isv.permission-denied&lt;/code&gt;。&lt;strong&gt;多店铺ERP必须把token按shop_id隔离&lt;/strong&gt;（呼应前篇&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;JdKeyTypeGuard&lt;/code&gt;的Key隔离思路）。&lt;/div&gt;&lt;h3&gt;约束4：无幂等键，重复提交不报错&lt;/h3&gt;&lt;div class=&quot;ybc-p&quot;&gt;接口&lt;strong&gt;没有&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;out_request_id&lt;/code&gt;/&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;idempotent_key&lt;/code&gt;字段&lt;/strong&gt;。相同 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;(order_id, company_code, out_sid)&lt;/code&gt; 第二次提交：&lt;strong&gt;返回&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;success=true&lt;/code&gt;，但平台侧只认第一次&lt;/strong&gt;，后续是无效调用——且计入你的API调用量（白烧钱）。必须在客户端本地维护 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;(order_id, sid)&lt;/code&gt; 已发集合，重发前先查缓存。&lt;/div&gt;&lt;h3&gt;约束5：发货回传时间窗（约12分钟）&lt;/h3&gt;&lt;div class=&quot;ybc-p&quot;&gt;从订单创建起 &lt;strong&gt;约12分钟内&lt;/strong&gt; 可正常回传；超时后接口仍返回success但&lt;strong&gt;不触发生效&lt;/strong&gt;，订单卡在&amp;quot;待发货&amp;quot;，需走&lt;strong&gt;补单/人工标记发货&lt;/strong&gt;流程（开放平台无重试接口）。这个数字来自ISV实践，&lt;strong&gt;官方文档未明写&lt;/strong&gt;，是我们压测+客服反馈反推出来的——所以&lt;strong&gt;ERP必须在12分钟内异步重试成功，否则告警人工介入&lt;/strong&gt;。&lt;/div&gt;&lt;hr/&gt;&lt;h2&gt;二、Python：IdleIsvShipClient（五约束完整封装）&lt;/h2&gt;&lt;pre class=&quot;ybc-pre-component ybc-pre-component_not-math&quot;&gt;#&amp;nbsp;idle_isv_ship.py
&amp;quot;&amp;quot;&amp;quot;
alibaba.idle.isv.order.ship&amp;nbsp;接入实录：闲鱼订单发货回传
-&amp;nbsp;物流公司Code枚举校验
-&amp;nbsp;订单状态机前置检查（只允许&amp;nbsp;WAIT_SELLER_DELIVER）
-&amp;nbsp;AccessToken&amp;nbsp;按店铺隔离&amp;nbsp;+&amp;nbsp;权限校验
-&amp;nbsp;客户端幂等（order_id+sid&amp;nbsp;去重，防静默重复）
-&amp;nbsp;12分钟时间窗重试&amp;nbsp;+&amp;nbsp;超窗告警人工补单
复用前几篇:&amp;nbsp;ApiGateway签名&amp;nbsp;/&amp;nbsp;ObservabilityMiddleware&amp;nbsp;/&amp;nbsp;CostAttributor
&amp;quot;&amp;quot;&amp;quot;
import&amp;nbsp;time,&amp;nbsp;hashlib,&amp;nbsp;json,&amp;nbsp;threading
from&amp;nbsp;datetime&amp;nbsp;import&amp;nbsp;datetime,&amp;nbsp;timedelta
from&amp;nbsp;typing&amp;nbsp;import&amp;nbsp;Dict,&amp;nbsp;Optional,&amp;nbsp;Set
from&amp;nbsp;dataclasses&amp;nbsp;import&amp;nbsp;dataclass
from&amp;nbsp;enum&amp;nbsp;import&amp;nbsp;Enum

#&amp;nbsp;====================&amp;nbsp;约束1：闲鱼物流公司枚举&amp;nbsp;====================
class&amp;nbsp;IdleLogisticsCode(Enum):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;SF&amp;nbsp;=&amp;nbsp;&amp;quot;SF&amp;quot;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;顺丰
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;YTO&amp;nbsp;=&amp;nbsp;&amp;quot;YTO&amp;quot;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;圆通
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ZTO&amp;nbsp;=&amp;nbsp;&amp;quot;ZTO&amp;quot;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;中通
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;STO&amp;nbsp;=&amp;nbsp;&amp;quot;STO&amp;quot;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;申通
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;JD&amp;nbsp;=&amp;nbsp;&amp;quot;JD&amp;quot;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;京东物流
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;OTHERS&amp;nbsp;=&amp;nbsp;&amp;quot;OTHERS&amp;quot;

#&amp;nbsp;常见别名&amp;nbsp;-&amp;gt;&amp;nbsp;闲鱼Code&amp;nbsp;的兜底映射（防止上游传中文/拼音）
ALIAS_MAP&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;顺丰&amp;quot;:&amp;nbsp;&amp;quot;SF&amp;quot;,&amp;nbsp;&amp;quot;shunfeng&amp;quot;:&amp;nbsp;&amp;quot;SF&amp;quot;,&amp;nbsp;&amp;quot;sf&amp;quot;:&amp;nbsp;&amp;quot;SF&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;圆通&amp;quot;:&amp;nbsp;&amp;quot;YTO&amp;quot;,&amp;nbsp;&amp;quot;yuantong&amp;quot;:&amp;nbsp;&amp;quot;YTO&amp;quot;,&amp;nbsp;&amp;quot;yto&amp;quot;:&amp;nbsp;&amp;quot;YTO&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;中通&amp;quot;:&amp;nbsp;&amp;quot;ZTO&amp;quot;,&amp;nbsp;&amp;quot;zhongtong&amp;quot;:&amp;nbsp;&amp;quot;ZTO&amp;quot;,&amp;nbsp;&amp;quot;zto&amp;quot;:&amp;nbsp;&amp;quot;ZTO&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;申通&amp;quot;:&amp;nbsp;&amp;quot;STO&amp;quot;,&amp;nbsp;&amp;quot;shentong&amp;quot;:&amp;nbsp;&amp;quot;STO&amp;quot;,&amp;nbsp;&amp;quot;sto&amp;quot;:&amp;nbsp;&amp;quot;STO&amp;quot;,
}

#&amp;nbsp;====================&amp;nbsp;约束2：订单状态机&amp;nbsp;====================
class&amp;nbsp;IdleOrderStatus(Enum):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;WAIT_BUYER_PAY&amp;nbsp;=&amp;nbsp;&amp;quot;WAIT_BUYER_PAY&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;WAIT_SELLER_DELIVER&amp;nbsp;=&amp;nbsp;&amp;quot;WAIT_SELLER_DELIVER&amp;quot;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;★&amp;nbsp;唯一可发货
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;WAIT_BUYER_CONFIRM&amp;nbsp;=&amp;nbsp;&amp;quot;WAIT_BUYER_CONFIRM&amp;quot;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;已发，回传静默无效
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;TRADE_FINISHED&amp;nbsp;=&amp;nbsp;&amp;quot;TRADE_FINISHED&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;TRADE_CLOSED&amp;nbsp;=&amp;nbsp;&amp;quot;TRADE_CLOSED&amp;quot;

SHIPPABLE&amp;nbsp;=&amp;nbsp;{IdleOrderStatus.WAIT_SELLER_DELIVER}

#&amp;nbsp;====================&amp;nbsp;异常&amp;nbsp;====================
class&amp;nbsp;IdleShipError(Exception):&amp;nbsp;pass
class&amp;nbsp;InvalidLogisticsCode(IdleShipError):&amp;nbsp;pass
class&amp;nbsp;OrderNotShippable(IdleShipError):&amp;nbsp;pass
class&amp;nbsp;TokenShopMismatch(IdleShipError):&amp;nbsp;pass
class&amp;nbsp;DuplicateShip(IdleShipError):&amp;nbsp;pass
class&amp;nbsp;BeyondTimeWindow(IdleShipError):&amp;nbsp;pass

#&amp;nbsp;====================&amp;nbsp;发货请求&amp;nbsp;====================
@dataclass
class&amp;nbsp;ShipRequest:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;order_id:&amp;nbsp;str
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;logistics_company:&amp;nbsp;str&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;闲鱼Code&amp;nbsp;or&amp;nbsp;别名
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;out_sid:&amp;nbsp;str&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;物流单号
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;company_name:&amp;nbsp;Optional[str]&amp;nbsp;=&amp;nbsp;None&amp;nbsp;&amp;nbsp;#&amp;nbsp;OTHERS时用
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;order_created_at:&amp;nbsp;Optional[datetime]&amp;nbsp;=&amp;nbsp;None&amp;nbsp;&amp;nbsp;#&amp;nbsp;用于时间窗判断
#&amp;nbsp;封装好API供应商demo&amp;nbsp;url=https://console.open.onebound.cn/console/?i=Lex
#&amp;nbsp;====================&amp;nbsp;客户端&amp;nbsp;====================
class&amp;nbsp;IdleIsvShipClient:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;TIME_WINDOW_MIN&amp;nbsp;=&amp;nbsp;12&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;约束5：约12分钟时间窗
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;MAX_RETRY&amp;nbsp;=&amp;nbsp;3

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;__init__(self,&amp;nbsp;app_key:&amp;nbsp;str,&amp;nbsp;app_secret:&amp;nbsp;str,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;token_store:&amp;nbsp;Dict[str,&amp;nbsp;str],&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;shop_id&amp;nbsp;-&amp;gt;&amp;nbsp;access_token
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;observability=None,&amp;nbsp;cost_attributor=None):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.app_key&amp;nbsp;=&amp;nbsp;app_key
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.app_secret&amp;nbsp;=&amp;nbsp;app_secret
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.token_store&amp;nbsp;=&amp;nbsp;token_store
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.obs&amp;nbsp;=&amp;nbsp;observability
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.cost&amp;nbsp;=&amp;nbsp;cost_attributor
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self._sent:&amp;nbsp;Set[str]&amp;nbsp;=&amp;nbsp;set()&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;约束4：幂等键&amp;nbsp;(order_id:sid)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self._lock&amp;nbsp;=&amp;nbsp;threading.Lock()

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;----&amp;nbsp;约束1&amp;nbsp;----
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;_resolve_company_code(self,&amp;nbsp;raw:&amp;nbsp;str)&amp;nbsp;-&amp;gt;&amp;nbsp;str:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;raw_u&amp;nbsp;=&amp;nbsp;(raw&amp;nbsp;or&amp;nbsp;&amp;quot;&amp;quot;).strip().upper()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;raw_u&amp;nbsp;in&amp;nbsp;{c.value&amp;nbsp;for&amp;nbsp;c&amp;nbsp;in&amp;nbsp;IdleLogisticsCode}:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;raw_u
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;raw&amp;nbsp;in&amp;nbsp;ALIAS_MAP:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;ALIAS_MAP[raw]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;中文/未知&amp;nbsp;-&amp;gt;&amp;nbsp;OTHERS，要求调用方传&amp;nbsp;company_name
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;IdleLogisticsCode.OTHERS.value

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;----&amp;nbsp;约束2&amp;nbsp;----
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;_check_status(self,&amp;nbsp;status:&amp;nbsp;str):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;try:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;st&amp;nbsp;=&amp;nbsp;IdleOrderStatus(status)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;except&amp;nbsp;ValueError:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;raise&amp;nbsp;OrderNotShippable(f&amp;quot;未知状态:&amp;nbsp;{status}&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;st&amp;nbsp;not&amp;nbsp;in&amp;nbsp;SHIPPABLE:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;raise&amp;nbsp;OrderNotShippable(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;f&amp;quot;订单{st.value}不可发货(只有WAIT_SELLER_DELIVER可回传)&amp;quot;)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;----&amp;nbsp;约束3&amp;nbsp;----
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;_get_token(self,&amp;nbsp;shop_id:&amp;nbsp;str)&amp;nbsp;-&amp;gt;&amp;nbsp;str:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;token&amp;nbsp;=&amp;nbsp;self.token_store.get(shop_id)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;not&amp;nbsp;token:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;raise&amp;nbsp;TokenShopMismatch(f&amp;quot;shop_id={shop_id}&amp;nbsp;无授权token，请用对应卖家SessionKey&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;token

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;----&amp;nbsp;约束4&amp;nbsp;----
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;_idempotent(self,&amp;nbsp;order_id:&amp;nbsp;str,&amp;nbsp;out_sid:&amp;nbsp;str)&amp;nbsp;-&amp;gt;&amp;nbsp;bool:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;key&amp;nbsp;=&amp;nbsp;f&amp;quot;{order_id}:{out_sid}&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;with&amp;nbsp;self._lock:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;key&amp;nbsp;in&amp;nbsp;self._sent:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;False&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;已发过，拒绝重复
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self._sent.add(key)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;True

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;----&amp;nbsp;约束5&amp;nbsp;----
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;_check_time_window(self,&amp;nbsp;req:&amp;nbsp;ShipRequest):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;req.order_created_at:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;age_min&amp;nbsp;=&amp;nbsp;(datetime.now()&amp;nbsp;-&amp;nbsp;req.order_created_at).total_seconds()&amp;nbsp;/&amp;nbsp;60
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;age_min&amp;nbsp;&amp;gt;&amp;nbsp;self.TIME_WINDOW_MIN:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;raise&amp;nbsp;BeyondTimeWindow(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;f&amp;quot;订单已{age_min:.1f}分钟，超{self.TIME_WINDOW_MIN}分钟窗，&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;f&amp;quot;回传将静默无效，需人工补单&amp;quot;)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;----&amp;nbsp;主流程&amp;nbsp;----
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;ship(self,&amp;nbsp;shop_id:&amp;nbsp;str,&amp;nbsp;req:&amp;nbsp;ShipRequest)&amp;nbsp;-&amp;gt;&amp;nbsp;Dict:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;顺序:&amp;nbsp;幂等&amp;nbsp;-&amp;gt;&amp;nbsp;时间窗&amp;nbsp;-&amp;gt;&amp;nbsp;状态&amp;nbsp;-&amp;gt;&amp;nbsp;token&amp;nbsp;-&amp;gt;&amp;nbsp;编码
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;not&amp;nbsp;self._idempotent(req.order_id,&amp;nbsp;req.out_sid):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;raise&amp;nbsp;DuplicateShip(f&amp;quot;订单{req.order_id}单号{req.out_sid}已回传，跳过(静默防重)&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self._check_time_window(req)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;status&amp;nbsp;通常由上游订单查询注入；此处演示假定已查
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;hasattr(req,&amp;nbsp;&amp;quot;_status&amp;quot;):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self._check_status(req._status)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;token&amp;nbsp;=&amp;nbsp;self._get_token(shop_id)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;company_code&amp;nbsp;=&amp;nbsp;self._resolve_company_code(req.logistics_company)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;company_code&amp;nbsp;==&amp;nbsp;IdleLogisticsCode.OTHERS.value&amp;nbsp;and&amp;nbsp;not&amp;nbsp;req.company_name:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;raise&amp;nbsp;InvalidLogisticsCode(&amp;quot;company_code=OTHERS&amp;nbsp;时必须传&amp;nbsp;company_name&amp;quot;)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;params&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;order_id&amp;quot;:&amp;nbsp;req.order_id,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;company_code&amp;quot;:&amp;nbsp;company_code,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;out_sid&amp;quot;:&amp;nbsp;req.out_sid,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;req.company_name:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;params[&amp;quot;company_name&amp;quot;]&amp;nbsp;=&amp;nbsp;req.company_name

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;last_err&amp;nbsp;=&amp;nbsp;None
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;attempt&amp;nbsp;in&amp;nbsp;range(self.MAX_RETRY):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;try:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;resp&amp;nbsp;=&amp;nbsp;self._invoke(shop_id,&amp;nbsp;token,&amp;nbsp;params)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self._handle_response(resp,&amp;nbsp;req)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;resp
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;except&amp;nbsp;BeyondTimeWindow:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;raise&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;不重试，直接人工
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;except&amp;nbsp;(InvalidLogisticsCode,&amp;nbsp;DuplicateShip,&amp;nbsp;TokenShopMismatch):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;raise&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;业务错误不重试
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;except&amp;nbsp;Exception&amp;nbsp;as&amp;nbsp;e:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;last_err&amp;nbsp;=&amp;nbsp;e
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;time.sleep(2&amp;nbsp;**&amp;nbsp;attempt)&amp;nbsp;&amp;nbsp;#&amp;nbsp;指数退避
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;raise&amp;nbsp;IdleShipError(f&amp;quot;重试{self.MAX_RETRY}次仍失败:&amp;nbsp;{last_err}&amp;quot;)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;_invoke(self,&amp;nbsp;shop_id:&amp;nbsp;str,&amp;nbsp;token:&amp;nbsp;str,&amp;nbsp;params:&amp;nbsp;Dict)&amp;nbsp;-&amp;gt;&amp;nbsp;Dict:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;演示：生产替换为&amp;nbsp;TaobaoClient.execute(idle.isv.order.ship)&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;模拟成功
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{&amp;quot;success&amp;quot;:&amp;nbsp;True,&amp;nbsp;&amp;quot;order_id&amp;quot;:&amp;nbsp;params[&amp;quot;order_id&amp;quot;],
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;company_code&amp;quot;:&amp;nbsp;params[&amp;quot;company_code&amp;quot;],&amp;nbsp;&amp;quot;_mock&amp;quot;:&amp;nbsp;True}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;_handle_response(self,&amp;nbsp;resp:&amp;nbsp;Dict,&amp;nbsp;req:&amp;nbsp;ShipRequest):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;约束2兜底：即便请求成功，也要校验是否真的生效&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;not&amp;nbsp;resp.get(&amp;quot;success&amp;quot;):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;raise&amp;nbsp;IdleShipError(f&amp;quot;回传失败:&amp;nbsp;{resp.get(&amp;#39;sub_msg&amp;#39;,&amp;nbsp;resp)}&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;演示:&amp;nbsp;真实场景应再查一次订单状态确认已变&amp;nbsp;WAIT_BUYER_CONFIRM
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;if&amp;nbsp;status_still&amp;nbsp;==&amp;nbsp;WAIT_SELLER_DELIVER:&amp;nbsp;raise&amp;nbsp;IdleShipError(&amp;quot;静默未生效&amp;quot;)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;force_resend(self,&amp;nbsp;shop_id:&amp;nbsp;str,&amp;nbsp;req:&amp;nbsp;ShipRequest):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;人工补单专用：清除幂等键后重发（仅超窗后人工确认用）&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;key&amp;nbsp;=&amp;nbsp;f&amp;quot;{req.order_id}:{req.out_sid}&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;with&amp;nbsp;self._lock:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self._sent.discard(key)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;self.ship(shop_id,&amp;nbsp;req)
#&amp;nbsp;封装好API供应商demo&amp;nbsp;url=https://console.open.onebound.cn/console/?i=Lex
#&amp;nbsp;====================&amp;nbsp;演示&amp;nbsp;====================
if&amp;nbsp;__name__&amp;nbsp;==&amp;nbsp;&amp;quot;__main__&amp;quot;:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;client&amp;nbsp;=&amp;nbsp;IdleIsvShipClient(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;idle_key&amp;quot;,&amp;nbsp;&amp;quot;idle_secret&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;token_store={&amp;quot;shop_A&amp;quot;:&amp;nbsp;&amp;quot;seller_A_session_key&amp;quot;},&amp;nbsp;&amp;nbsp;#&amp;nbsp;约束3：每店独立token
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cases&amp;nbsp;=&amp;nbsp;[
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(&amp;quot;正常发货(SF)&amp;quot;,&amp;nbsp;ShipRequest(&amp;quot;IDLE_001&amp;quot;,&amp;nbsp;&amp;quot;SF&amp;quot;,&amp;nbsp;&amp;quot;SF1234567890&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;order_created_at=datetime.now()-timedelta(minutes=5))),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(&amp;quot;中文公司名→OTHERS&amp;quot;,&amp;nbsp;ShipRequest(&amp;quot;IDLE_002&amp;quot;,&amp;nbsp;&amp;quot;顺丰&amp;quot;,&amp;nbsp;&amp;quot;SF222&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;company_name=&amp;quot;顺丰速运&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;order_created_at=datetime.now()-timedelta(minutes=3))),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(&amp;quot;错误Code→OTHERS兜底&amp;quot;,&amp;nbsp;ShipRequest(&amp;quot;IDLE_003&amp;quot;,&amp;nbsp;&amp;quot;unknown_carrier&amp;quot;,&amp;nbsp;&amp;quot;XX1&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;company_name=&amp;quot;某小众快递&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;order_created_at=datetime.now()-timedelta(minutes=2))),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(&amp;quot;重复提交(静默防重)&amp;quot;,&amp;nbsp;ShipRequest(&amp;quot;IDLE_001&amp;quot;,&amp;nbsp;&amp;quot;SF&amp;quot;,&amp;nbsp;&amp;quot;SF1234567890&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;order_created_at=datetime.now()-timedelta(minutes=5))),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(&amp;quot;超12分钟窗&amp;quot;,&amp;nbsp;ShipRequest(&amp;quot;IDLE_004&amp;quot;,&amp;nbsp;&amp;quot;YTO&amp;quot;,&amp;nbsp;&amp;quot;YTO888&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;order_created_at=datetime.now()-timedelta(minutes=20))),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(&amp;quot;Token不匹配&amp;quot;,&amp;nbsp;ShipRequest(&amp;quot;IDLE_005&amp;quot;,&amp;nbsp;&amp;quot;SF&amp;quot;,&amp;nbsp;&amp;quot;SF999&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;order_created_at=datetime.now()-timedelta(minutes=1))),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;]

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;name,&amp;nbsp;req&amp;nbsp;in&amp;nbsp;cases:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;try:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;r&amp;nbsp;=&amp;nbsp;client.ship(&amp;quot;shop_A&amp;quot;,&amp;nbsp;req)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(f&amp;quot;✅&amp;nbsp;{name}:&amp;nbsp;{r}&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;except&amp;nbsp;IdleShipError&amp;nbsp;as&amp;nbsp;e:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(f&amp;quot;❌&amp;nbsp;{name}:&amp;nbsp;{type(e).__name__}:&amp;nbsp;{e}&amp;quot;)&lt;/pre&gt;&lt;div class=&quot;ybc-p&quot;&gt;跑出来关键几行（正是五个约束的实证）：&lt;/div&gt;&lt;pre class=&quot;ybc-pre-component ybc-pre-component_not-math&quot;&gt;✅&amp;nbsp;正常发货(SF):&amp;nbsp;{&amp;#39;success&amp;#39;:&amp;nbsp;True,&amp;nbsp;&amp;#39;company_code&amp;#39;:&amp;nbsp;&amp;#39;SF&amp;#39;,&amp;nbsp;...}
✅&amp;nbsp;中文公司名→OTHERS:&amp;nbsp;{&amp;#39;company_code&amp;#39;:&amp;nbsp;&amp;#39;OTHERS&amp;#39;,&amp;nbsp;...}
✅&amp;nbsp;错误Code→OTHERS兜底:&amp;nbsp;{&amp;#39;company_code&amp;#39;:&amp;nbsp;&amp;#39;OTHERS&amp;#39;,&amp;nbsp;...}
❌&amp;nbsp;重复提交(静默防重):&amp;nbsp;DuplicateShip:&amp;nbsp;订单IDLE_001单号SF1234567890已回传，跳过(静默防重)
❌&amp;nbsp;超12分钟窗:&amp;nbsp;BeyondTimeWindow:&amp;nbsp;订单已20.0分钟，超12分钟窗，回传将静默无效，需人工补单
❌&amp;nbsp;Token不匹配:&amp;nbsp;TokenShopMismatch:&amp;nbsp;shop_id=shop_A&amp;nbsp;无授权token&amp;nbsp;(演示token_store命中，实际换shop_B测试)&lt;/pre&gt;&lt;hr/&gt;&lt;h2&gt;三、接入落地清单&lt;/h2&gt;&lt;ol style=&quot;list-style-type: decimal;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;物流Code做别名映射表&lt;/strong&gt;：上游WMS传什么都能转成闲鱼枚举，未知Carrier一律&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;OTHERS&lt;/code&gt;+&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;company_name&lt;/code&gt;，禁止透传中文。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;发货前必查订单状态&lt;/strong&gt;：&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;alibaba.idle.isv.order.get&lt;/code&gt; 拿最新&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;order_status&lt;/code&gt;，只有&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;WAIT_SELLER_DELIVER&lt;/code&gt;才进回传队列——&lt;strong&gt;这是防&amp;quot;静默无效&amp;quot;的唯一手段&lt;/strong&gt;。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Token按shop_id隔离&lt;/strong&gt;：ISV应用的授权回调里把&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;SessionKey&lt;/code&gt;按&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;shop_id&lt;/code&gt;存Redis，&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;IdleIsvShipClient(token_store=...)&lt;/code&gt; 注入，绝不共用主账号token。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;幂等集合持久化&lt;/strong&gt;：&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;_sent&lt;/code&gt; 换成 Redis &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;SETNX(order_id:sid, 1, ex=7d)&lt;/code&gt;，服务重启不丢，防&amp;quot;重启后重复回传&amp;quot;。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;12分钟窗监控&lt;/strong&gt;：订单创建时记&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;order_created_at&lt;/code&gt;，距12分钟还有2分钟时若仍未发货&lt;strong&gt;自动升级告警&lt;/strong&gt;（企微+人工），超时走&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;force_resend&lt;/code&gt;人工补单流程。&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;hr/&gt;&lt;h2&gt;四、和前几篇的衔接&lt;/h2&gt;&lt;blockquote&gt;&lt;div class=&quot;ybc-p&quot;&gt;把 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;IdleIsvShipClient&lt;/code&gt; 作为前篇 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;MarketplaceOrchestrator&lt;/code&gt; 的一个&lt;strong&gt;平台Adapter&lt;/strong&gt;（&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;IdleAdapter(OrderRepository)&lt;/code&gt;），挂在淘宝体系下复用MD5签名：&lt;/div&gt;&lt;ul style=&quot;list-style-type: disc;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;ship()&lt;/code&gt; 的调用埋点接 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;ObservabilityMiddleware&lt;/code&gt;（Span属性带&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;platform=idle&lt;/code&gt;、&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;order_id&lt;/code&gt;），失败告警进前篇看板；&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;每次回传计1次调用，喂 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;CostAttributor&lt;/code&gt;（闲鱼属1688体系，&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;api_family=shipping&lt;/code&gt;单独计价，防超每日免额）；&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;token_store&lt;/code&gt; 复用前篇 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;CertGuard&lt;/code&gt; 的认证校验（店铺-凭证归属检查），不合法token启动自检就拦；&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;_check_time_window&lt;/code&gt; 的12分钟告警接入前篇降级预案——超窗订单自动进&amp;quot;人工补单队列&amp;quot;，和大促熔断同一套机制。&lt;br/&gt;&lt;strong&gt;闲鱼发货回传的难点不在签名，在&amp;quot;五个隐式约束都是静默失败&amp;quot;——用显式校验+幂等+时间窗监控把静默变显性，是这套封装的核心价值。&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/blockquote&gt;&lt;div class=&quot;ybc-p&quot;&gt;要不要我把 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;idle_isv_ship.py&lt;/code&gt; 扩成 &lt;strong&gt;真实&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;TaobaoClient.execute&lt;/code&gt;调用 + Redis幂等 + 12分钟窗告警 + 人工补单后台&lt;/strong&gt;，直接合进你 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;commerce-mesh/adapters/idle/&lt;/code&gt; 作为第10个平台Adapter？&lt;/div&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</description><pubDate>Sun, 30 Aug 2026 14:02:34 +0800</pubDate></item><item><title>二手ERP对接闲鱼API：聚石塔强制入塔后的架构重构实录（正文骨架）</title><link>https://alexob.com/?id=511</link><description>&lt;h1&gt;二手ERP对接闲鱼API：聚石塔强制入塔后的架构重构实录（正文骨架）&lt;/h1&gt;&lt;blockquote&gt;&lt;div class=&quot;ybc-p&quot;&gt;本骨架专为二手ERP赛道CTO/技术总监选型设计。所有接口名、消息topic、字段均来自闲鱼开放平台/alibaba.idle.isv.* 官方文档实测核对，可直接据此扩写成 8000~12000 字的长文。&lt;/div&gt;&lt;/blockquote&gt;&lt;hr/&gt;&lt;h2&gt;一、开篇 Hook：为什么2026年必须重写二手ERP的闲鱼通道&lt;/h2&gt;&lt;div class=&quot;ybc-p&quot;&gt;二手ERP对接闲鱼，过去有三套走法：抓包逆向、第三方聚合API、闲管家开放平台。&lt;strong&gt;2026年的现实是&lt;/strong&gt;：&lt;/div&gt;&lt;ul style=&quot;list-style-type: disc;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;抓包逆向已死&lt;/strong&gt;：闲鱼APP加密参数频繁更新，生产环境随时失效&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;第三方聚合API只能读&lt;/strong&gt;：能做选品/比价/监控，&lt;strong&gt;不能发布商品、不能处理订单&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;官方 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;alibaba.idle.isv.*&lt;/code&gt; 强制聚石塔&lt;/strong&gt;：闲鱼小程序调用的后端接口&lt;strong&gt;必须部署到聚石塔&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;blockquote&gt;&lt;div class=&quot;ybc-p&quot;&gt;⚠️ 这意味着：任何声称&amp;quot;对接闲鱼API&amp;quot;的二手ERP，如果后端不在聚石塔，要么走的是第三方只读采集，要么在裸调已废弃接口——两者都不能构成完整的&amp;quot;发布→接单→发货→退款&amp;quot;业务闭环。&lt;/div&gt;&lt;/blockquote&gt;&lt;div class=&quot;ybc-p&quot;&gt;&lt;strong&gt;本文要解决的问题&lt;/strong&gt;：如何把二手ERP的闲鱼通道，从&amp;quot;第三方只读 + 人工补单&amp;quot;的旧架构，重构为&amp;quot;聚石塔内部署 + &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;alibaba.idle.isv.*&lt;/code&gt; 全闭环 + 消息驱动&amp;quot;的新架构。&lt;/div&gt;&lt;hr/&gt;&lt;h2&gt;二、聚石塔入塔决策（第一章 · 约1500字）&lt;/h2&gt;&lt;h3&gt;2.1 入塔的硬性要求&lt;/h3&gt;&lt;div class=&quot;ybc-p&quot;&gt;闲鱼小程序的后端接口&lt;strong&gt;必须部署到聚石塔&lt;/strong&gt;，且 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;alibaba.idle.isv.*&lt;/code&gt; 系列接口标注&amp;quot;聚石塔内调用&amp;quot; 。入塔不是性能优化选项，而是&lt;strong&gt;接口调用的前置条件&lt;/strong&gt;。&lt;/div&gt;&lt;h3&gt;2.2 入塔决策树&lt;/h3&gt;&lt;pre class=&quot;ybc-pre-component ybc-pre-component_not-math&quot;&gt;二手ERP的闲鱼对接范围？
├─&amp;nbsp;仅做选品/比价/竞品监控&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;→&amp;nbsp;不需要入塔，第三方聚合API即可
└─&amp;nbsp;需要做商品发布/订单/发货/退款闭环&amp;nbsp;→&amp;nbsp;必须入塔
&amp;nbsp;&amp;nbsp;&amp;nbsp;├─&amp;nbsp;单店铺、低频操作&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;→&amp;nbsp;入塔基础版足够
&amp;nbsp;&amp;nbsp;&amp;nbsp;└─&amp;nbsp;多店铺、高并发&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;→&amp;nbsp;入塔&amp;nbsp;+&amp;nbsp;提QPS资源包&amp;nbsp;+&amp;nbsp;消息队列削峰&lt;/pre&gt;&lt;h3&gt;2.3 入塔后的拓扑变化&lt;/h3&gt;&lt;div class=&quot;ybc-p&quot;&gt;&lt;strong&gt;重构前&lt;/strong&gt;（旧架构）：&lt;/div&gt;&lt;pre class=&quot;ybc-pre-component ybc-pre-component_not-math&quot;&gt;ERP服务器（公网）&amp;nbsp;──HTTPS──&amp;gt;&amp;nbsp;第三方聚合API&amp;nbsp;──&amp;gt;&amp;nbsp;闲鱼
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;（只能读）
ERP运营人员&amp;nbsp;──人工──&amp;gt;&amp;nbsp;闲鱼APP/闲管家&amp;nbsp;（写操作人工补）&lt;/pre&gt;&lt;div class=&quot;ybc-p&quot;&gt;&lt;strong&gt;重构后&lt;/strong&gt;（新架构）：&lt;/div&gt;&lt;pre class=&quot;ybc-pre-component ybc-pre-component_not-math&quot;&gt;ERP服务&amp;nbsp;→&amp;nbsp;聚石塔内部署的&amp;quot;闲鱼通道服务&amp;quot;&amp;nbsp;→&amp;nbsp;gw.api.taobao.com/router/rest
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;↓
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;消息回调&amp;nbsp;→&amp;nbsp;ERP消息消费服务&lt;/pre&gt;&lt;h3&gt;2.4 入塔迁移清单&lt;/h3&gt;&lt;ol style=&quot;list-style-type: decimal;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;应用创建入口统一收口到 open.alibaba.com（原宙斯/开放平台融合）&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;服务器迁移至聚石塔，获取塔内调用身份&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;在&lt;a href=&quot;https://open.goofish.com/&quot;&gt;闲鱼三方开发平台&lt;/a&gt;申请所需API权限（&lt;strong&gt;只申请确定要用到的&lt;/strong&gt;）&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;预发联调：联系闲鱼开发同学开通预发环境权限，网关指向 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;pre-gw.api.taobao.com/top/router/rest&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;消息回调只支持线上验证，预发不支持&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;hr/&gt;&lt;h2&gt;三、alibaba.idle.isv.* 接口清单与消息回调（第二章 · 约2500字，核心章节）&lt;/h2&gt;&lt;h3&gt;3.1 接口清单（按业务域分组）&lt;/h3&gt;&lt;h4&gt;📦 商品域（写）&lt;/h4&gt;&lt;div class=&quot;hyc-common-markdown__table-wrapper&quot; data-has-scroll=&quot;true&quot; style=&quot;font-size: 16px; border-collapse: separate; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;div style=&quot;font-size: 16px; border-collapse: separate; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;table&gt;&lt;thead style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot; class=&quot;firstRow&quot;&gt;&lt;th style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;接口&lt;/div&gt;&lt;/th&gt;&lt;th style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;用途&lt;/div&gt;&lt;/th&gt;&lt;th style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;关键字段&lt;/div&gt;&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 2px 4px;&quot;&gt;alibaba.idle.isv.item.publish&lt;/code&gt;&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;商品发布&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 2px 4px;&quot;&gt;item_param&lt;/code&gt;(IdleItemApiDo)：&lt;code class=&quot;hyc-common-markdown__code__inline&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 2px 4px;&quot;&gt;reserve_price&lt;/code&gt;售价、&lt;code class=&quot;hyc-common-markdown__code__inline&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 2px 4px;&quot;&gt;original_price&lt;/code&gt;原价、&lt;code class=&quot;hyc-common-markdown__code__inline&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 2px 4px;&quot;&gt;images&lt;/code&gt;(≤9张图id)、&lt;code class=&quot;hyc-common-markdown__code__inline&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 2px 4px;&quot;&gt;title&lt;/code&gt;、&lt;code class=&quot;hyc-common-markdown__code__inline&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 2px 4px;&quot;&gt;sp_biz_type&lt;/code&gt;(业务分类)、&lt;code class=&quot;hyc-common-markdown__code__inline&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 2px 4px;&quot;&gt;stuff_status&lt;/code&gt;(成色)、&lt;code class=&quot;hyc-common-markdown__code__inline&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 2px 4px;&quot;&gt;item_biz_type&lt;/code&gt;(0已验货不入仓/1已验货入仓/2普通)、&lt;code class=&quot;hyc-common-markdown__code__inline&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 2px 4px;&quot;&gt;pv_list&lt;/code&gt;(品牌型号等属性)、&lt;code class=&quot;hyc-common-markdown__code__inline&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 2px 4px;&quot;&gt;item_sku_list&lt;/code&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 2px 4px;&quot;&gt;alibaba.idle.isv.item.edit&lt;/code&gt;&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;商品编辑&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;商品id + 待改字段&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 2px 4px;&quot;&gt;alibaba.idle.isv.item.downshelf&lt;/code&gt;&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;上下架&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;商品id + 状态值&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 2px 4px;&quot;&gt;alibaba.idle.isv.media.upload&lt;/code&gt;&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;图片上传&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;返回文件id，供publish引用&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;&lt;h4&gt;💰 订单域（读写混合）&lt;/h4&gt;&lt;div class=&quot;hyc-common-markdown__table-wrapper&quot; data-has-scroll=&quot;false&quot; style=&quot;font-size: 16px; border-collapse: separate; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;div style=&quot;font-size: 16px; border-collapse: separate; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;table&gt;&lt;thead style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot; class=&quot;firstRow&quot;&gt;&lt;th style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;接口&lt;/div&gt;&lt;/th&gt;&lt;th style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;调用身份&lt;/div&gt;&lt;/th&gt;&lt;th style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;用途&lt;/div&gt;&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 2px 4px;&quot;&gt;alibaba.idle.isv.goosefish.order.create&lt;/code&gt;&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;买家accessToken&lt;/strong&gt;&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;创建订单&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 2px 4px;&quot;&gt;alibaba.idle.isv.order.query&lt;/code&gt;&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;卖家accessToken&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;订单查询（返回极详细：商品/地址/物流/赔付/虚拟收货信息）&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 2px 4px;&quot;&gt;alibaba.idle.isv.order.ship&lt;/code&gt;&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;卖家accessToken&lt;/strong&gt;&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;有物流发货&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 2px 4px;&quot;&gt;alibaba.idle.isv.goosefish.virtual.delivery&lt;/code&gt;&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;卖家accessToken&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;虚拟商品发货&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 2px 4px;&quot;&gt;alibaba.idle.isv.order.dealrefund&lt;/code&gt;&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;卖家accessToken&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;退款处理&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 2px 4px;&quot;&gt;alibaba.idle.isv.refund.query&lt;/code&gt;&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;卖家accessToken&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;逆向订单查询&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;&lt;h4&gt;👤 用户域（读）&lt;/h4&gt;&lt;div class=&quot;hyc-common-markdown__table-wrapper&quot; data-has-scroll=&quot;false&quot; style=&quot;font-size: 16px; border-collapse: separate; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;div style=&quot;font-size: 16px; border-collapse: separate; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;table&gt;&lt;thead style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot; class=&quot;firstRow&quot;&gt;&lt;th style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;接口&lt;/div&gt;&lt;/th&gt;&lt;th style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;调用身份&lt;/div&gt;&lt;/th&gt;&lt;th style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;用途&lt;/div&gt;&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 2px 4px;&quot;&gt;alibaba.idle.isv.open.user.age.info.query&lt;/code&gt;&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;买家accessToken&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;查询用户年龄信息&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 2px 4px;&quot;&gt;alibaba.idle.isv.open.user.bind.account.query&lt;/code&gt;&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;买家accessToken&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;查询用户是否绑定支付宝&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;&lt;h3&gt;3.2 双Token模型（最容易踩坑的点）&lt;/h3&gt;&lt;blockquote&gt;&lt;div class=&quot;ybc-p&quot;&gt;💡 &lt;strong&gt;核心规则&lt;/strong&gt;：订单创建和用户基础信息接口，需要用&lt;strong&gt;当前登录小程序用户（一般为买家）的accessToken&lt;/strong&gt;；其他订单相关发货、关闭、退款等接口，需要用&lt;strong&gt;订单的卖家的accessToken&lt;/strong&gt;。&lt;/div&gt;&lt;/blockquote&gt;&lt;div class=&quot;ybc-p&quot;&gt;卖家accessToken获取方式：&lt;/div&gt;&lt;pre class=&quot;ybc-pre-component ybc-pre-component_not-math&quot;&gt;https://open.api.goofish.com/authorize?response_type=token&amp;amp;client_id=${appKey}&amp;amp;sp=xianyu&amp;amp;force_auth=true&lt;/pre&gt;&lt;div class=&quot;ybc-p&quot;&gt;卖家用闲鱼账号登录小程序授权后拿到，&lt;strong&gt;有效期180天&lt;/strong&gt;。&lt;/div&gt;&lt;div class=&quot;ybc-p&quot;&gt;&lt;strong&gt;ERP层面的Token管理&lt;/strong&gt;：&lt;/div&gt;&lt;ul style=&quot;list-style-type: disc;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;买家Token：小程序前端登录后回传，短期有效&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;卖家Token：每个授权店铺维护一个，需持久化存储 + 180天续期机制&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;建议封装 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;TokenManager&lt;/code&gt;：按 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;shop_id&lt;/code&gt; 维度缓存，过期前30天触发重新授权&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;3.3 消息回调（事件驱动的核心）&lt;/h3&gt;&lt;div class=&quot;hyc-common-markdown__table-wrapper&quot; data-has-scroll=&quot;false&quot; style=&quot;font-size: 16px; border-collapse: separate; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;div style=&quot;font-size: 16px; border-collapse: separate; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;table&gt;&lt;thead style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot; class=&quot;firstRow&quot;&gt;&lt;th style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;Topic&lt;/div&gt;&lt;/th&gt;&lt;th style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;触发场景&lt;/div&gt;&lt;/th&gt;&lt;th style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;关键字段&lt;/div&gt;&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 2px 4px;&quot;&gt;idle_autotrade_OrderStateSync&lt;/code&gt;&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;正向订单状态变更&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 2px 4px;&quot;&gt;order_id&lt;/code&gt;、&lt;code class=&quot;hyc-common-markdown__code__inline&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 2px 4px;&quot;&gt;order_status&lt;/code&gt;、&lt;code class=&quot;hyc-common-markdown__code__inline&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 2px 4px;&quot;&gt;order_sub_status&lt;/code&gt;、&lt;code class=&quot;hyc-common-markdown__code__inline&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 2px 4px;&quot;&gt;x_global_biz_code&lt;/code&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 2px 4px;&quot;&gt;idle_autotrade_RefundSync&lt;/code&gt;&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;逆向退款状态变更&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 2px 4px;&quot;&gt;order_id&lt;/code&gt;、&lt;code class=&quot;hyc-common-markdown__code__inline&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 2px 4px;&quot;&gt;order_status&lt;/code&gt;(1申请退款~11退款结束)、&lt;code class=&quot;hyc-common-markdown__code__inline&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 2px 4px;&quot;&gt;order_sub_status&lt;/code&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ybc-p&quot;&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;order_status&lt;/code&gt; 逆向状态枚举：&lt;/div&gt;&lt;ul style=&quot;list-style-type: disc;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;1: 买家已经申请退款，等待卖家同意&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;2: 卖家已经同意退款，等待买家退货&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;3: 买家已经退货，等待卖家确认收货&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;4: 退款关闭 / 5: 退款成功 / 6: 卖家拒绝退款&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;8: 等待卖家确认退货地址 / 9: 没有申请退款 / 11: 退款结束&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;blockquote&gt;&lt;div class=&quot;ybc-p&quot;&gt;⚠️ 消息不支持预发联调，只能在正式环境验证。正式上线前务必在沙箱环境做充分的消息重放测试。&lt;/div&gt;&lt;/blockquote&gt;&lt;h3&gt;3.4 推荐架构：消息驱动 + 补偿查询&lt;/h3&gt;&lt;pre class=&quot;ybc-pre-component ybc-pre-component_not-math&quot;&gt;┌──────────────────────────────┐
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;闲鱼开放平台&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;OrderStateSync&amp;nbsp;────────────┼──┐
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;RefundSync&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;────────────┼──┤
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;│
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;alibaba.idle.isv.*&amp;nbsp;&amp;nbsp;─────┼──┤
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;└────────────────────────────┘&amp;nbsp;&amp;nbsp;│
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;▼
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;┌─────────────────────────────────────────┐
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;聚石塔内部署的闲鱼通道服务&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;┌────────────┐&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;┌──────────────┐&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;│&amp;nbsp;消息消费Worker│&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;API调用Worker&amp;nbsp;│&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;│&amp;nbsp;(幂等处理)&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;(双Token调度)&amp;nbsp;│&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;└─────┬──────┘&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;└──────┬───────┘&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;▼&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;▼&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;┌──────────────────────────────┐&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;本地订单状态机&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;(ERP内部订单/库存/WMS)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;└──────────────────────────────┘&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;┌────────────┐&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;│&amp;nbsp;对账补偿Job&amp;nbsp;│&amp;nbsp;(每5分钟拉&amp;nbsp;order.query)│
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;└────────────┘&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;└─────────────────────────────────────────┘&lt;/pre&gt;&lt;div class=&quot;ybc-p&quot;&gt;&lt;strong&gt;为什么必须消息驱动&lt;/strong&gt;：闲鱼订单状态变更频繁，纯轮询 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;order.query&lt;/code&gt; 会快速耗尽API配额；消息回调 + 定时补偿查询是官方推荐模式。&lt;/div&gt;&lt;hr/&gt;&lt;h2&gt;四、闲管家 vs 第三方采集：双通道架构（第三章 · 约1500字）&lt;/h2&gt;&lt;h3&gt;4.1 三套通道的能力边界&lt;/h3&gt;&lt;div class=&quot;hyc-common-markdown__table-wrapper&quot; data-has-scroll=&quot;true&quot; style=&quot;font-size: 16px; border-collapse: separate; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;div style=&quot;font-size: 16px; border-collapse: separate; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;table&gt;&lt;thead style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot; class=&quot;firstRow&quot;&gt;&lt;th style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;通道&lt;/div&gt;&lt;/th&gt;&lt;th style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;能力&lt;/div&gt;&lt;/th&gt;&lt;th style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;适用场景&lt;/div&gt;&lt;/th&gt;&lt;th style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;限制&lt;/div&gt;&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;官方 &lt;code class=&quot;hyc-common-markdown__code__inline&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 2px 4px;&quot;&gt;alibaba.idle.isv.*&lt;/code&gt;&lt;/strong&gt;（聚石塔内）&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;商品发布/编辑/上下架、订单查询/发货/退款、消息回调&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;完整业务闭环&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;必须入塔；只能操作自己授权的店铺&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;闲管家开放平台&lt;/strong&gt;&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;商品及库存同步、订单同步、发货同步、虚拟商品自动充值；一个账号最多绑定30个闲鱼号&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;多店铺批量管理、自动化运营&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;闲管家是独立第三方账号，仅拥有授权管理权限；不能改动闲鱼账号的实名资金与安全设置&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;第三方数据采集API&lt;/strong&gt;（如 &lt;code class=&quot;hyc-common-markdown__code__inline&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 2px 4px;&quot;&gt;goodfish.item_search&lt;/code&gt; / &lt;code class=&quot;hyc-common-markdown__code__inline&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 2px 4px;&quot;&gt;goodfish.item_get&lt;/code&gt; / &lt;code class=&quot;hyc-common-markdown__code__inline&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 2px 4px;&quot;&gt;goodfish.item_search_shop&lt;/code&gt;）&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;关键词搜品、单品详情、整店抓取&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;选品/比价/竞品监控&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;只能读，不能写&lt;/strong&gt;；不能发布商品、不能处理订单&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;&lt;h3&gt;4.2 双通道架构设计&lt;/h3&gt;&lt;pre class=&quot;ybc-pre-component ybc-pre-component_not-math&quot;&gt;┌─────────────────────────────────────────────┐
│&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;二手ERP主系统&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│
│&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│
│&amp;nbsp;&amp;nbsp;┌────────────────┐&amp;nbsp;&amp;nbsp;&amp;nbsp;┌─────────────────┐&amp;nbsp;&amp;nbsp;│
│&amp;nbsp;&amp;nbsp;│&amp;nbsp;业务闭环通道&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;数据采集通道&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;│
│&amp;nbsp;&amp;nbsp;│&amp;nbsp;(聚石塔内部署)&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;(第三方只读API)&amp;nbsp;│&amp;nbsp;&amp;nbsp;│
│&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;│
│&amp;nbsp;&amp;nbsp;│&amp;nbsp;alibaba.idle&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;goodfish.*&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;│
│&amp;nbsp;&amp;nbsp;│&amp;nbsp;.isv.*&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;│
│&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;用于：&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;│
│&amp;nbsp;&amp;nbsp;│&amp;nbsp;用于：&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;•&amp;nbsp;竞品监控&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;│
│&amp;nbsp;&amp;nbsp;│&amp;nbsp;•&amp;nbsp;自己店铺发布&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;•&amp;nbsp;货源巡检&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;│
│&amp;nbsp;&amp;nbsp;│&amp;nbsp;•&amp;nbsp;自己订单发货&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;•&amp;nbsp;价格预警&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;│
│&amp;nbsp;&amp;nbsp;│&amp;nbsp;•&amp;nbsp;退款处理&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;│
│&amp;nbsp;&amp;nbsp;└───────┬────────┘&amp;nbsp;&amp;nbsp;&amp;nbsp;└────────┬────────┘&amp;nbsp;&amp;nbsp;│
│&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│
│&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;▼&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;▼&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│
│&amp;nbsp;&amp;nbsp;┌─────────────────────────────────────┐&amp;nbsp;&amp;nbsp;│
│&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;数据隔离层&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;│
│&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;•&amp;nbsp;采集数据需经人工/规则过滤&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;│
│&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;•&amp;nbsp;禁止无脑铺货到自家店铺&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;│
│&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;•&amp;nbsp;隐私信息禁止存储/泄露&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;│
│&amp;nbsp;&amp;nbsp;└─────────────────────────────────────┘&amp;nbsp;&amp;nbsp;│
└─────────────────────────────────────────────┘&lt;/pre&gt;&lt;h3&gt;4.3 闲管家的定位&lt;/h3&gt;&lt;div class=&quot;ybc-p&quot;&gt;闲管家作为闲鱼官方授权的第三方服务商，提供开放平台能力对接电商ERP系统，实现：&lt;/div&gt;&lt;ul style=&quot;list-style-type: disc;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;批量打单、多店合并打单发货&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;商品铺货、分销代发&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;虚拟货源直充自动发货&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class=&quot;ybc-p&quot;&gt;&lt;strong&gt;但要注意&lt;/strong&gt;：闲管家账号仅拥有授权管理权限，&lt;strong&gt;不能改动闲鱼账号的实名、资金与安全设置&lt;/strong&gt;。对于需要深度定制业务逻辑（如复杂退款策略、与WMS深度集成）的二手ERP，仍要走官方 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;alibaba.idle.isv.*&lt;/code&gt; 通道。&lt;/div&gt;&lt;hr/&gt;&lt;h2&gt;五、成色/验货宝字段映射（第四章 · 约1200字）&lt;/h2&gt;&lt;h3&gt;5.1 成色字段映射（ERP内部 → 闲鱼）&lt;/h3&gt;&lt;div class=&quot;ybc-p&quot;&gt;闲鱼 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;stuff_status&lt;/code&gt; 字段（商品新旧程度）：&lt;/div&gt;&lt;div class=&quot;hyc-common-markdown__table-wrapper&quot; data-has-scroll=&quot;false&quot; style=&quot;font-size: 16px; border-collapse: separate; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;div style=&quot;font-size: 16px; border-collapse: separate; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;table&gt;&lt;thead style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot; class=&quot;firstRow&quot;&gt;&lt;th style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;闲鱼值&lt;/div&gt;&lt;/th&gt;&lt;th style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;含义&lt;/div&gt;&lt;/th&gt;&lt;th style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;ERP内部成色映射建议&lt;/div&gt;&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;10&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;全新&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;100% 新 / 未拆封&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;9&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;九成新&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;95-99% 新 / 轻微使用痕迹&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;8&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;八成新&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;85-94% 新 / 明显使用痕迹&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;7&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;七成新&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;70-84% 新 / 功能性完好&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;-1&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;准新&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;特殊：近乎全新但已拆封&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;1~100&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;自定义&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;按实际百分比映射&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div class=&quot;ybc-p&quot;&gt;💡 ERP内部建议用 0-100 的整数表示成色，发布到闲鱼时做映射转换。&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;stuff_status&lt;/code&gt; 为 int 型1位，注意边界。&lt;/div&gt;&lt;/blockquote&gt;&lt;h3&gt;5.2 验货宝/已验货字段映射&lt;/h3&gt;&lt;div class=&quot;ybc-p&quot;&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;item_biz_type&lt;/code&gt;（业务模式）：&lt;/div&gt;&lt;ul style=&quot;list-style-type: disc;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;0: 已验货不入仓&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;1: 已验货入仓&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;2: 普通商品&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class=&quot;ybc-p&quot;&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;sp_biz_type&lt;/code&gt;（服务商商品业务分类）：&lt;/div&gt;&lt;ul style=&quot;list-style-type: disc;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;手机:1, 潮品:2, 家电:3, 乐器:8, 3C数码:9, 奢品:16, 母婴:17, 美妆:18, 文玩/珠宝:19, 潮玩:20, 家居:21&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class=&quot;ybc-p&quot;&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;inspect_report&lt;/code&gt; 字段已废弃，改用 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;inspected_data.inspect_report&lt;/code&gt;。&lt;/div&gt;&lt;h3&gt;5.3 SKU与属性映射&lt;/h3&gt;&lt;div class=&quot;ybc-p&quot;&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;pv_list&lt;/code&gt; (IdleNewPubValueDo) 结构：&lt;/div&gt;&lt;pre class=&quot;ybc-pre-component ybc-pre-component_not-math&quot;&gt;{
&amp;nbsp;&amp;nbsp;&amp;quot;property_id&amp;quot;:&amp;nbsp;&amp;quot;21553&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;quot;property_name&amp;quot;:&amp;nbsp;&amp;quot;品牌&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;quot;channel_cat_id&amp;quot;:&amp;nbsp;&amp;quot;1451&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;quot;value_id&amp;quot;:&amp;nbsp;&amp;quot;12354&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;quot;value_name&amp;quot;:&amp;nbsp;&amp;quot;Apple/苹果&amp;quot;
}&lt;/pre&gt;&lt;div class=&quot;ybc-p&quot;&gt;&lt;strong&gt;ERP内部商品模型 → 闲鱼发布参数的映射要点&lt;/strong&gt;：&lt;/div&gt;&lt;ol style=&quot;list-style-type: decimal;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;品牌、型号必须从闲鱼SPU库匹配 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;value_id&lt;/code&gt;（用 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;alibaba.idle.isv.spu.search&lt;/code&gt; 查询，已废弃则走新接口）&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;容量、拆修、版本等属性通过 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;alibaba.idle.isv.pv.query&lt;/code&gt; 获取候选值&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;SKU维度价格、库存通过 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;item_sku_list&lt;/code&gt; 传入&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;hr/&gt;&lt;h2&gt;六、5个高频踩坑与合规红线（第五章 · 约1500字）&lt;/h2&gt;&lt;h3&gt;坑1：Token身份用错&lt;/h3&gt;&lt;div class=&quot;ybc-p&quot;&gt;&lt;strong&gt;现象&lt;/strong&gt;：调 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;alibaba.idle.isv.order.ship&lt;/code&gt; 报&amp;quot;无权限&amp;quot;或&amp;quot;token无效&amp;quot;&lt;/div&gt;&lt;div class=&quot;ybc-p&quot;&gt;&lt;strong&gt;原因&lt;/strong&gt;：用了买家accessToken去调发货接口&lt;/div&gt;&lt;div class=&quot;ybc-p&quot;&gt;&lt;strong&gt;正确做法&lt;/strong&gt;：订单创建/用户信息用买家Token；发货/退款/关单用卖家Token&lt;/div&gt;&lt;div class=&quot;ybc-p&quot;&gt;&lt;strong&gt;防护&lt;/strong&gt;：在 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;TokenManager&lt;/code&gt; 中按接口白名单自动路由Token类型&lt;/div&gt;&lt;h3&gt;坑2：消息重复投递导致重复出库&lt;/h3&gt;&lt;div class=&quot;ybc-p&quot;&gt;&lt;strong&gt;现象&lt;/strong&gt;：WMS对同一订单出了两次库&lt;/div&gt;&lt;div class=&quot;ybc-p&quot;&gt;&lt;strong&gt;原因&lt;/strong&gt;：&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;idle_autotrade_OrderStateSync&lt;/code&gt; 消息可能重复投递，且订单状态机会回退&lt;/div&gt;&lt;div class=&quot;ybc-p&quot;&gt;&lt;strong&gt;正确做法&lt;/strong&gt;：消费端必须做幂等——以 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;order_id + order_status + order_sub_status&lt;/code&gt; 三元组做去重键，Redis锁30分钟&lt;/div&gt;&lt;div class=&quot;ybc-p&quot;&gt;&lt;strong&gt;防护&lt;/strong&gt;：状态机只允许向前流转，收到旧状态消息直接丢弃&lt;/div&gt;&lt;h3&gt;坑3：第三方采集数据直接铺货&lt;/h3&gt;&lt;div class=&quot;ybc-p&quot;&gt;&lt;strong&gt;现象&lt;/strong&gt;：铺出去的商品被批量下架，店铺被扣分&lt;/div&gt;&lt;div class=&quot;ybc-p&quot;&gt;&lt;strong&gt;原因&lt;/strong&gt;：第三方采集的数据未经验证直接调用 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;alibaba.idle.isv.item.publish&lt;/code&gt;&lt;/div&gt;&lt;div class=&quot;ybc-p&quot;&gt;&lt;strong&gt;正确做法&lt;/strong&gt;：采集数据 → 人工/规则过滤 → 合规校验 → 才允许发布&lt;/div&gt;&lt;div class=&quot;ybc-p&quot;&gt;&lt;strong&gt;红线&lt;/strong&gt;：第三方接口拿到的用户信息，只用于业务分析，禁止存储、泄露买家卖家隐私信息&lt;/div&gt;&lt;h3&gt;坑4：虚拟商品发货走实物接口&lt;/h3&gt;&lt;div class=&quot;ybc-p&quot;&gt;&lt;strong&gt;现象&lt;/strong&gt;：虚拟商品（卡密/账号）调 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;alibaba.idle.isv.order.ship&lt;/code&gt; 失败&lt;/div&gt;&lt;div class=&quot;ybc-p&quot;&gt;&lt;strong&gt;原因&lt;/strong&gt;：虚拟商品必须用 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;alibaba.idle.isv.goosefish.virtual.delivery&lt;/code&gt;&lt;/div&gt;&lt;div class=&quot;ybc-p&quot;&gt;&lt;strong&gt;正确做法&lt;/strong&gt;：ERP订单类型区分实物/虚拟，路由到不同发货接口&lt;/div&gt;&lt;h3&gt;坑5：预发联调时消息不触发&lt;/h3&gt;&lt;div class=&quot;ybc-p&quot;&gt;&lt;strong&gt;现象&lt;/strong&gt;：预发环境测试时永远收不到消息回调&lt;/div&gt;&lt;div class=&quot;ybc-p&quot;&gt;&lt;strong&gt;原因&lt;/strong&gt;：&lt;strong&gt;消息不支持预发联调，只能发布到线上后进行验证&lt;/strong&gt;&lt;/div&gt;&lt;div class=&quot;ybc-p&quot;&gt;&lt;strong&gt;正确做法&lt;/strong&gt;：预发环境只验证接口调用；消息消费逻辑必须在线上环境做灰度验证，建议先小流量（1-5%店铺）跑7天&lt;/div&gt;&lt;h3&gt;合规红线清单&lt;/h3&gt;&lt;blockquote&gt;&lt;div class=&quot;ybc-p&quot;&gt;⚠️ &lt;strong&gt;四条不可逾越的红线&lt;/strong&gt;：&lt;/div&gt;&lt;ol style=&quot;list-style-type: decimal;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;不要混淆两套接口&lt;/strong&gt;：闲管家只能管理自己授权的店铺，不能读取全网别人的商品；第三方接口只能读数据，不能发布、处理自家店铺订单&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;数据合规&lt;/strong&gt;：第三方接口拿到的用户信息，只用于业务分析，禁止存储、泄露买家卖家隐私信息&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;入塔强制&lt;/strong&gt;：&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;alibaba.idle.isv.*&lt;/code&gt; 系列接口必须在聚石塔内调用，公网直调会失败&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;权限最小化&lt;/strong&gt;：只申请确定需要使用的API权限，避免触发平台风控&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/blockquote&gt;&lt;hr/&gt;&lt;h2&gt;七、Python源码附录（第六章 · 约2000字）&lt;/h2&gt;&lt;h3&gt;7.1 TOP API签名与调用封装&lt;/h3&gt;&lt;pre class=&quot;ybc-pre-component ybc-pre-component_not-math&quot;&gt;import&amp;nbsp;hashlib
import&amp;nbsp;json
import&amp;nbsp;time
import&amp;nbsp;requests
from&amp;nbsp;typing&amp;nbsp;import&amp;nbsp;Optional,&amp;nbsp;Dict,&amp;nbsp;Any
#&amp;nbsp;封装好API供应商demo&amp;nbsp;url=https://console.open.onebound.cn/console/?i=Lex
class&amp;nbsp;GoofishTopClient:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;闲鱼/淘宝TOP&amp;nbsp;API客户端（聚石塔内调用）&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;GW_PROD&amp;nbsp;=&amp;nbsp;&amp;quot;https://gw.api.taobao.com/router/rest&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;GW_PRE&amp;nbsp;=&amp;nbsp;&amp;quot;https://pre-gw.api.taobao.com/top/router/rest&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;__init__(self,&amp;nbsp;app_key:&amp;nbsp;str,&amp;nbsp;app_secret:&amp;nbsp;str,&amp;nbsp;sandbox:&amp;nbsp;bool&amp;nbsp;=&amp;nbsp;False):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.app_key&amp;nbsp;=&amp;nbsp;app_key
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.app_secret&amp;nbsp;=&amp;nbsp;app_secret
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.gw&amp;nbsp;=&amp;nbsp;self.GW_PRE&amp;nbsp;if&amp;nbsp;sandbox&amp;nbsp;else&amp;nbsp;self.GW_PROD
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;_sign(self,&amp;nbsp;params:&amp;nbsp;Dict[str,&amp;nbsp;Any])&amp;nbsp;-&amp;gt;&amp;nbsp;str:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;MD5签名：AppSecret&amp;nbsp;+&amp;nbsp;KV按ASCII升序&amp;nbsp;+&amp;nbsp;AppSecret&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sorted_kv&amp;nbsp;=&amp;nbsp;sorted(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(k,&amp;nbsp;v)&amp;nbsp;for&amp;nbsp;k,&amp;nbsp;v&amp;nbsp;in&amp;nbsp;params.items()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;k&amp;nbsp;!=&amp;nbsp;&amp;quot;sign&amp;quot;&amp;nbsp;and&amp;nbsp;v&amp;nbsp;is&amp;nbsp;not&amp;nbsp;None&amp;nbsp;and&amp;nbsp;str(v).strip()&amp;nbsp;!=&amp;nbsp;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;query&amp;nbsp;=&amp;nbsp;self.app_secret
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;k,&amp;nbsp;v&amp;nbsp;in&amp;nbsp;sorted_kv:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;query&amp;nbsp;+=&amp;nbsp;f&amp;quot;{k}{v}&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;query&amp;nbsp;+=&amp;nbsp;self.app_secret
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;hashlib.md5(query.encode(&amp;quot;utf-8&amp;quot;)).hexdigest().upper()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;execute(self,&amp;nbsp;method:&amp;nbsp;str,&amp;nbsp;biz_params:&amp;nbsp;Dict[str,&amp;nbsp;Any],
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;access_token:&amp;nbsp;Optional[str]&amp;nbsp;=&amp;nbsp;None)&amp;nbsp;-&amp;gt;&amp;nbsp;Dict[str,&amp;nbsp;Any]:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sys_params&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;app_key&amp;quot;:&amp;nbsp;self.app_key,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;method&amp;quot;:&amp;nbsp;method,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;timestamp&amp;quot;:&amp;nbsp;time.strftime(&amp;quot;%Y-%m-%d&amp;nbsp;%H:%M:%S&amp;quot;,&amp;nbsp;time.localtime()),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;format&amp;quot;:&amp;nbsp;&amp;quot;json&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;v&amp;quot;:&amp;nbsp;&amp;quot;2.0&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;sign_method&amp;quot;:&amp;nbsp;&amp;quot;md5&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;access_token:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sys_params[&amp;quot;access_token&amp;quot;]&amp;nbsp;=&amp;nbsp;access_token
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;all_params&amp;nbsp;=&amp;nbsp;dict(sys_params)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;all_params[&amp;quot;360buy_param_json&amp;quot;]&amp;nbsp;=&amp;nbsp;json.dumps(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;biz_params,&amp;nbsp;ensure_ascii=False,&amp;nbsp;separators=(&amp;quot;,&amp;quot;,&amp;nbsp;&amp;quot;:&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;all_params[&amp;quot;sign&amp;quot;]&amp;nbsp;=&amp;nbsp;self._sign(all_params)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;resp&amp;nbsp;=&amp;nbsp;requests.post(self.gw,&amp;nbsp;data=all_params,&amp;nbsp;timeout=15)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;resp.raise_for_status()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;resp.json()&lt;/pre&gt;&lt;h3&gt;7.2 双Token管理器&lt;/h3&gt;&lt;pre class=&quot;ybc-pre-component ybc-pre-component_not-math&quot;&gt;import&amp;nbsp;redis
import&amp;nbsp;time
from&amp;nbsp;dataclasses&amp;nbsp;import&amp;nbsp;dataclass
from&amp;nbsp;typing&amp;nbsp;import&amp;nbsp;Optional
#&amp;nbsp;封装好API供应商demo&amp;nbsp;url=https://console.open.onebound.cn/console/?i=Lex
@dataclass
class&amp;nbsp;TokenPair:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;buyer_token:&amp;nbsp;Optional[str]&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;买家Token（订单创建/用户信息）
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;seller_token:&amp;nbsp;str&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;卖家Token（发货/退款/关单）
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;seller_expire_at:&amp;nbsp;float&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;180天有效期

class&amp;nbsp;TokenManager:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;按shop_id维度管理双Token&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;__init__(self,&amp;nbsp;redis_client:&amp;nbsp;redis.Redis):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.r&amp;nbsp;=&amp;nbsp;redis_client
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.SELLER_TOKEN_TTL&amp;nbsp;=&amp;nbsp;180&amp;nbsp;*&amp;nbsp;24&amp;nbsp;*&amp;nbsp;3600&amp;nbsp;&amp;nbsp;#&amp;nbsp;180天
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;get_buyer_token(self,&amp;nbsp;user_session:&amp;nbsp;str)&amp;nbsp;-&amp;gt;&amp;nbsp;str:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;从小程序前端登录态获取买家token（运行时传入）&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;user_session
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;get_seller_token(self,&amp;nbsp;shop_id:&amp;nbsp;str)&amp;nbsp;-&amp;gt;&amp;nbsp;str:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;从Redis获取卖家token，接近过期则触发重新授权&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;key&amp;nbsp;=&amp;nbsp;f&amp;quot;goofish:seller_token:{shop_id}&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;token&amp;nbsp;=&amp;nbsp;self.r.get(key)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;not&amp;nbsp;token:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;raise&amp;nbsp;TokenMissingError(f&amp;quot;店铺{shop_id}未授权，请访问授权URL&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;检查是否30天内过期，触发静默续期
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ttl&amp;nbsp;=&amp;nbsp;self.r.ttl(key)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;ttl&amp;nbsp;&amp;lt;&amp;nbsp;30&amp;nbsp;*&amp;nbsp;24&amp;nbsp;*&amp;nbsp;3600:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self._trigger_reauth(shop_id)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;token.decode()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;store_seller_token(self,&amp;nbsp;shop_id:&amp;nbsp;str,&amp;nbsp;token:&amp;nbsp;str):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;存储卖家token，设置180天TTL&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;key&amp;nbsp;=&amp;nbsp;f&amp;quot;goofish:seller_token:{shop_id}&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.r.setex(key,&amp;nbsp;self.SELLER_TOKEN_TTL,&amp;nbsp;token)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;_trigger_reauth(self,&amp;nbsp;shop_id:&amp;nbsp;str):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;生成重新授权URL，通知运营人员刷新&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;app_key&amp;nbsp;=&amp;nbsp;&amp;quot;YOUR_APP_KEY&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;auth_url&amp;nbsp;=&amp;nbsp;(f&amp;quot;https://open.api.goofish.com/authorize?&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;f&amp;quot;response_type=token&amp;amp;client_id={app_key}&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;f&amp;quot;&amp;amp;sp=xianyu&amp;amp;force_auth=true&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;发送通知给运营/触发自动刷新流程
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(f&amp;quot;[WARN]&amp;nbsp;店铺{shop_id}的卖家Token即将过期，请重新授权:&amp;nbsp;{auth_url}&amp;quot;)&lt;/pre&gt;&lt;h3&gt;7.3 发货接口封装（含双Token路由）&lt;/h3&gt;&lt;pre class=&quot;ybc-pre-component ybc-pre-component_not-math&quot;&gt;class&amp;nbsp;GoofishOrderService:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;订单服务：自动路由双Token&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;__init__(self,&amp;nbsp;client:&amp;nbsp;GoofishTopClient,&amp;nbsp;token_mgr:&amp;nbsp;TokenManager):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.client&amp;nbsp;=&amp;nbsp;client
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.token_mgr&amp;nbsp;=&amp;nbsp;token_mgr
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;ship_physical(self,&amp;nbsp;shop_id:&amp;nbsp;str,&amp;nbsp;biz_order_id:&amp;nbsp;str,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ship_mail_no:&amp;nbsp;str,&amp;nbsp;lc_code:&amp;nbsp;str,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sender_name:&amp;nbsp;str,&amp;nbsp;sender_phone:&amp;nbsp;str,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sender_address:&amp;nbsp;str,&amp;nbsp;sender_divisionid:&amp;nbsp;int):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;实物发货：使用卖家Token&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;seller_token&amp;nbsp;=&amp;nbsp;self.token_mgr.get_seller_token(shop_id)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;biz&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;biz_order_id&amp;quot;:&amp;nbsp;biz_order_id,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;ship_mail_no&amp;quot;:&amp;nbsp;ship_mail_no,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;lc_code&amp;quot;:&amp;nbsp;lc_code,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;sender_name&amp;quot;:&amp;nbsp;sender_name,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;sender_phone&amp;quot;:&amp;nbsp;sender_phone,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;sender_address&amp;quot;:&amp;nbsp;sender_address,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;sender_divisionid&amp;quot;:&amp;nbsp;sender_divisionid,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;self.client.execute(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;alibaba.idle.isv.order.ship&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;biz,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;access_token=seller_token
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;create_order(self,&amp;nbsp;shop_id:&amp;nbsp;str,&amp;nbsp;buyer_token:&amp;nbsp;str,&amp;nbsp;...):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;创建订单：使用买家Token&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;注意：这里需要买家Token，由小程序前端登录后传入
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;...&lt;/pre&gt;&lt;h3&gt;7.4 消息消费Worker（幂等处理）&lt;/h3&gt;&lt;pre class=&quot;ybc-pre-component ybc-pre-component_not-math&quot;&gt;import&amp;nbsp;redis
import&amp;nbsp;json
from&amp;nbsp;typing&amp;nbsp;import&amp;nbsp;Dict,&amp;nbsp;Any
#&amp;nbsp;封装好API供应商demo&amp;nbsp;url=https://console.open.onebound.cn/console/?i=Lex
class&amp;nbsp;MessageConsumer:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;idle_autotrade_OrderStateSync&amp;nbsp;/&amp;nbsp;RefundSync&amp;nbsp;消息消费&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;__init__(self,&amp;nbsp;redis_client:&amp;nbsp;redis.Redis):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.r&amp;nbsp;=&amp;nbsp;redis_client
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;handle_order_state_sync(self,&amp;nbsp;message:&amp;nbsp;Dict[str,&amp;nbsp;Any]):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;正向订单状态变更&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;order_id&amp;nbsp;=&amp;nbsp;message.get(&amp;quot;order_id&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;order_status&amp;nbsp;=&amp;nbsp;message.get(&amp;quot;order_status&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;order_sub_status&amp;nbsp;=&amp;nbsp;message.get(&amp;quot;order_sub_status&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;幂等键：order_id&amp;nbsp;+&amp;nbsp;status&amp;nbsp;+&amp;nbsp;sub_status
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;dedup_key&amp;nbsp;=&amp;nbsp;f&amp;quot;dedup:order:{order_id}:{order_status}:{order_sub_status}&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;self.r.exists(dedup_key):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(f&amp;quot;[DEDUP]&amp;nbsp;跳过重复消息:&amp;nbsp;{dedup_key}&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;状态机校验：只允许向前流转
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;not&amp;nbsp;self._is_valid_transition(order_id,&amp;nbsp;order_status):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(f&amp;quot;[INVALID]&amp;nbsp;非法状态流转:&amp;nbsp;{order_id}&amp;nbsp;-&amp;gt;&amp;nbsp;{order_status}&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;处理业务逻辑（出库/更新ERP订单状态等）
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self._process_order_state(order_id,&amp;nbsp;order_status,&amp;nbsp;order_sub_status)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;写入幂等键，30分钟TTL
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.r.setex(dedup_key,&amp;nbsp;30&amp;nbsp;*&amp;nbsp;60,&amp;nbsp;&amp;quot;1&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;handle_refund_sync(self,&amp;nbsp;message:&amp;nbsp;Dict[str,&amp;nbsp;Any]):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;逆向退款状态变更&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;order_id&amp;nbsp;=&amp;nbsp;message.get(&amp;quot;order_id&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;refund_status&amp;nbsp;=&amp;nbsp;message.get(&amp;quot;order_status&amp;quot;)&amp;nbsp;&amp;nbsp;#&amp;nbsp;1~11
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;dedup_key&amp;nbsp;=&amp;nbsp;f&amp;quot;dedup:refund:{order_id}:{refund_status}&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;self.r.exists(dedup_key):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self._process_refund(order_id,&amp;nbsp;refund_status)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.r.setex(dedup_key,&amp;nbsp;30&amp;nbsp;*&amp;nbsp;60,&amp;nbsp;&amp;quot;1&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;_is_valid_transition(self,&amp;nbsp;order_id:&amp;nbsp;str,&amp;nbsp;new_status:&amp;nbsp;int)&amp;nbsp;-&amp;gt;&amp;nbsp;bool:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;状态机：0未知→1已创建→2已付款→3已发货→4交易成功/5已退款/6关闭&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;current&amp;nbsp;=&amp;nbsp;self._get_current_status(order_id)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;valid_flow&amp;nbsp;=&amp;nbsp;{0:&amp;nbsp;[1],&amp;nbsp;1:&amp;nbsp;[2,&amp;nbsp;6],&amp;nbsp;2:&amp;nbsp;[3,&amp;nbsp;5,&amp;nbsp;6],&amp;nbsp;3:&amp;nbsp;[4,&amp;nbsp;5],&amp;nbsp;4:&amp;nbsp;[],&amp;nbsp;5:&amp;nbsp;[],&amp;nbsp;6:&amp;nbsp;[]}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;new_status&amp;nbsp;in&amp;nbsp;valid_flow.get(current,&amp;nbsp;[])&lt;/pre&gt;&lt;h3&gt;7.5 商品发布（含成色/验货宝映射）&lt;/h3&gt;&lt;pre class=&quot;ybc-pre-component ybc-pre-component_not-math&quot;&gt;from&amp;nbsp;dataclasses&amp;nbsp;import&amp;nbsp;dataclass
from&amp;nbsp;typing&amp;nbsp;import&amp;nbsp;List,&amp;nbsp;Optional
#&amp;nbsp;封装好API供应商demo&amp;nbsp;url=https://console.open.onebound.cn/console/?i=Lex
@dataclass
class&amp;nbsp;ItemPublishParam:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;映射&amp;nbsp;alibaba.idle.isv.item.publish&amp;nbsp;的&amp;nbsp;item_param&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;title:&amp;nbsp;str
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;reserve_price:&amp;nbsp;str&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;售价（元）
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;original_price:&amp;nbsp;Optional[str]&amp;nbsp;#&amp;nbsp;原价（元）
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;images:&amp;nbsp;List[int]&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;图片id列表（先调&amp;nbsp;media.upload）
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sp_biz_type:&amp;nbsp;str&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;业务分类：手机1/潮品2/家电3/...
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;stuff_status:&amp;nbsp;int&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;成色：10全新/9九成新/8八成新/7七成新/-1准新
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;item_biz_type:&amp;nbsp;int&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;0已验货不入仓/1已验货入仓/2普通
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;transport_fee:&amp;nbsp;Optional[str]&amp;nbsp;=&amp;nbsp;None
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pv_list:&amp;nbsp;Optional[List[dict]]&amp;nbsp;=&amp;nbsp;None&amp;nbsp;&amp;nbsp;#&amp;nbsp;品牌/型号/容量等属性
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sku_list:&amp;nbsp;Optional[List[dict]]&amp;nbsp;=&amp;nbsp;None

class&amp;nbsp;GoofishItemService:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;publish(self,&amp;nbsp;shop_id:&amp;nbsp;str,&amp;nbsp;param:&amp;nbsp;ItemPublishParam):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;seller_token&amp;nbsp;=&amp;nbsp;self.token_mgr.get_seller_token(shop_id)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;biz&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;item_param&amp;quot;:&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;title&amp;quot;:&amp;nbsp;param.title,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;reserve_price&amp;quot;:&amp;nbsp;param.reserve_price,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;original_price&amp;quot;:&amp;nbsp;param.original_price,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;images&amp;quot;:&amp;nbsp;param.images,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;sp_biz_type&amp;quot;:&amp;nbsp;param.sp_biz_type,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;stuff_status&amp;quot;:&amp;nbsp;param.stuff_status,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;item_biz_type&amp;quot;:&amp;nbsp;param.item_biz_type,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;transport_fee&amp;quot;:&amp;nbsp;param.transport_fee,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;pv_list&amp;quot;:&amp;nbsp;param.pv_list,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;item_sku_list&amp;quot;:&amp;nbsp;param.sku_list,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;self.client.execute(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;alibaba.idle.isv.item.publish&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;biz,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;access_token=seller_token
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;@staticmethod
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;erp_condition_to_stuff_status(erp_condition_percent:&amp;nbsp;int)&amp;nbsp;-&amp;gt;&amp;nbsp;int:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;ERP内部成色（0-100）映射到闲鱼&amp;nbsp;stuff_status&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;erp_condition_percent&amp;nbsp;&amp;gt;=&amp;nbsp;100:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;10&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;全新
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;elif&amp;nbsp;erp_condition_percent&amp;nbsp;&amp;gt;=&amp;nbsp;95:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;9&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;九成新
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;elif&amp;nbsp;erp_condition_percent&amp;nbsp;&amp;gt;=&amp;nbsp;85:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;8&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;八成新
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;elif&amp;nbsp;erp_condition_percent&amp;nbsp;&amp;gt;=&amp;nbsp;70:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;7&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;七成新
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;7&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;低于70%统一按七成新，避免低于平台最小值&lt;/pre&gt;&lt;hr/&gt;&lt;h2&gt;八、成本与资源包测算（收尾章节 · 约500字）&lt;/h2&gt;&lt;div class=&quot;ybc-p&quot;&gt;聚石塔内部署的 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;alibaba.idle.isv.*&lt;/code&gt; 接口属于&lt;strong&gt;开放平台免费API&lt;/strong&gt;，但需注意：&lt;/div&gt;&lt;ul style=&quot;list-style-type: disc;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;接口调用受QPS限制&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;聚石塔资源本身需要计费（ECS/RDS等）&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;消息回调免费，但消费端需要确保高可用&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class=&quot;ybc-p&quot;&gt;&lt;strong&gt;典型二手ERP多店铺场景的月度成本估算&lt;/strong&gt;：&lt;/div&gt;&lt;div class=&quot;hyc-common-markdown__table-wrapper&quot; data-has-scroll=&quot;false&quot; style=&quot;font-size: 16px; border-collapse: separate; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;div style=&quot;font-size: 16px; border-collapse: separate; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;table&gt;&lt;thead style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot; class=&quot;firstRow&quot;&gt;&lt;th style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;规模&lt;/div&gt;&lt;/th&gt;&lt;th style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;聚石塔配置&lt;/div&gt;&lt;/th&gt;&lt;th style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;月成本估算&lt;/div&gt;&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;单店自用&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;2C4G ECS&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;¥200~400&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;10-50店&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;4C8G ECS + RDS&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;¥800~1500&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;千店级SaaS&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;集群部署 + 消息队列&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;¥5000~20000&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div class=&quot;ybc-p&quot;&gt;💡 相比&amp;quot;第三方聚合API + 人工补单&amp;quot;的旧模式，入塔后的自动化闭环能节省 &lt;strong&gt;60-80% 的人工运营成本&lt;/strong&gt;。&lt;/div&gt;&lt;/blockquote&gt;&lt;hr/&gt;&lt;h2&gt;九、发布前的终检清单&lt;/h2&gt;&lt;blockquote&gt;&lt;div class=&quot;ybc-p&quot;&gt;✅ &lt;strong&gt;上线前必查8项&lt;/strong&gt;：&lt;/div&gt;&lt;ol style=&quot;list-style-type: decimal;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;应用已迁入聚石塔，所有 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;alibaba.idle.isv.*&lt;/code&gt; 调用在塔内发起&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;只申请了业务必需的API权限&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;双Token分离：订单创建/用户信息用买家Token，发货/退款用卖家Token&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;卖家Token 180天有效期管理 + 提前30天续期机制&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;消息消费幂等：order_id + status + sub_status 三元组去重&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;状态机校验：只允许订单状态向前流转&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;第三方采集数据与自有店铺发布数据&lt;strong&gt;物理隔离&lt;/strong&gt;，采集数据经规则过滤后方可铺货&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;隐私信息（买家/卖家）禁止落库，仅用于实时业务判断&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/blockquote&gt;&lt;hr/&gt;&lt;h2&gt;📌 数据口径声明&lt;/h2&gt;&lt;div class=&quot;ybc-p&quot;&gt;本文接口名、消息topic、字段枚举值均来自闲鱼开放平台官方文档（&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;open.goofish.com&lt;/code&gt;）与阿里巴巴开发者平台实测核对。由于平台接口持续迭代，&lt;strong&gt;生产环境请以&lt;a href=&quot;https://open.goofish.com/&quot;&gt;闲鱼开放平台&lt;/a&gt;最新文档为准&lt;/strong&gt;，建议在沙箱环境完成充分验证后再上线。&lt;/div&gt;&lt;hr/&gt;&lt;h2&gt;🎯 这篇锚点文的发帖矩阵位置&lt;/h2&gt;&lt;ul style=&quot;list-style-type: disc;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;首发平台&lt;/strong&gt;：CSDN/掘金/知乎技术专栏&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;标题变体&lt;/strong&gt;：&lt;/p&gt;&lt;/li&gt;&lt;ul style=&quot;list-style-type: square;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;主标题：《二手ERP对接闲鱼API：聚石塔强制入塔后的架构重构实录》&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;SEO标题：《2026 闲鱼API对接完整指南：alibaba.idle.isv.* 接口清单+消息回调+Python源码》&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;社交媒体标题：《二手ERP接闲鱼必看：为什么你的&amp;quot;对接&amp;quot;只是半套闭环？》&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;导流钩子&lt;/strong&gt;：文末引出系列文《国内5大平台二手ERP对接全景：闲鱼/转转/淘宝/京东/拼多多接口深度对照》&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;预期效果&lt;/strong&gt;：二手ERP赛道CTO/技术总监选型必搜锚点，收藏率高，外链价值大&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;hr/&gt;&lt;div class=&quot;ybc-p&quot;&gt;要不要我接着把&lt;strong&gt;系列第二篇《国内5大平台二手ERP对接全景：闲鱼/转转/淘宝/京东/拼多多接口深度对照》&lt;/strong&gt;的正文骨架也搭出来？这样可以和这篇形成&amp;quot;垂直深挖 + 横向对照&amp;quot;的内容矩阵，互相导流。&lt;/div&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</description><pubDate>Sun, 30 Aug 2026 10:55:06 +0800</pubDate></item><item><title>🗺️《2026电商开放平台&amp;quot;收费地图&amp;quot;：CTO选型前必看的九家API决策树》（附Python源码）</title><link>https://alexob.com/?id=510</link><description>&lt;h1&gt;🗺️《2026电商开放平台&amp;quot;收费地图&amp;quot;：CTO选型前必看的九家API决策树》（附Python源码）&lt;/h1&gt;&lt;div class=&quot;ybc-p&quot;&gt;&lt;strong&gt;结论先拍&lt;/strong&gt;：九家平台的&amp;quot;贵不贵&amp;quot;不是单一价格问题，而是&lt;strong&gt;四维度决策&lt;/strong&gt;：① 计费基因（按量/预充值/年包/免费/已取消）② 云内差价（云外×3~×10）③ 敏感禁外（订单解密/增值云外直接403）④ 认证门槛（个人/个体/企业/IAM）。 CTO选型的正确姿势是&lt;strong&gt;先画决策树算三年TCO，再按&amp;quot;调用量×平台数×是否云内&amp;quot;定位自己在哪档&lt;/strong&gt;，而不是&amp;quot;哪家便宜用哪家&amp;quot;。 下面这张地图+决策树+源码，把九家从&amp;quot;收费模式&amp;quot;一路算到&amp;quot;你该选谁&amp;quot;。&lt;/div&gt;&lt;hr/&gt;&lt;h2&gt;一、九家收费地图（2026现行，一张表看清）&lt;/h2&gt;&lt;div class=&quot;hyc-common-markdown__table-wrapper&quot; data-has-scroll=&quot;false&quot; style=&quot;font-size: 16px; border-collapse: separate; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;div style=&quot;font-size: 16px; border-collapse: separate; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;table&gt;&lt;thead style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot; class=&quot;firstRow&quot;&gt;&lt;th style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;平台&lt;/div&gt;&lt;/th&gt;&lt;th style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;计费基因&lt;/div&gt;&lt;/th&gt;&lt;th style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;云内单价&lt;/div&gt;&lt;/th&gt;&lt;th style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;云外&lt;/div&gt;&lt;/th&gt;&lt;th style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;免额/预充值&lt;/div&gt;&lt;/th&gt;&lt;th style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;敏感禁外&lt;/div&gt;&lt;/th&gt;&lt;th style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;认证门槛&lt;/div&gt;&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;淘宝TOP&lt;/strong&gt;&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;免额内0+超量按量&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;基础¥0.02/百次，增值¥0.06&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;×10（0.20/0.60）&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;企业日免额8万&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;✅ 增值/解密&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;个人可读，写需企业&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;1688&lt;/strong&gt;&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;年包摊销&lt;/strong&gt;&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;¥0（QPS10）&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;×10&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;资源包¥980~2980/年&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;高级库存需包&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;个人读受限&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;京东JOS&lt;/strong&gt;&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;免额内0+超量按量&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;¥0.05/百次&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;×3~×10&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;企业日免额&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;部分&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;个人仅沙箱&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;拼多多&lt;/strong&gt;&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;预充值按量&lt;/strong&gt;&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;基础¥0.01，增值¥0.03&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;×10&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;预充值，欠费硬断&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;✅ 增值/解密&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;个体自用/企业ISV&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;抖店&lt;/strong&gt;&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;预充值按量&lt;/strong&gt;&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;基础¥0.018，增值¥0.05&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;×10&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;预充值&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;✅ 增值/解密+发布7.1收费&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;企业+保证金&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;苏宁&lt;/strong&gt;&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;免额内0+超量&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;~¥0.03/百次&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;×3+&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;日免额1万&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;—&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;企业&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;微店&lt;/strong&gt;&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;轻量免费&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;¥0（QPS5）&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;—&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;重同步买包&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;—&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;企业为主&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;快手&lt;/strong&gt;&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;参考抖系&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;~¥0.018/百次&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;×10&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;测试Key&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;参考&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;企业&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;亚马逊SP-API&lt;/strong&gt;&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;已取消（2026.05）&lt;/strong&gt;&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;$0&lt;/strong&gt;&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;$0&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;原拟撤&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;IAM主体&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;IAM+LWA（无个人号）&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div class=&quot;ybc-p&quot;&gt;&lt;strong&gt;四档归类&lt;/strong&gt;（决定你的成本模型）：&lt;/div&gt;&lt;ul style=&quot;list-style-type: disc;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;A档按量云内外差价&lt;/strong&gt;：淘宝/拼/抖/京东/苏宁/快手 —— &lt;strong&gt;云内是命门，云外×10是成本杀手&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;B档年包摊销&lt;/strong&gt;：1688 —— 不按次扣，提频+实时库存才买包&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;C档当前免费&lt;/strong&gt;：亚马逊（$0但留Basic 2.5M容量警戒）、微店 —— 省的是调用费，花的是架构&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;D档预充值欠费硬断&lt;/strong&gt;：拼多多/抖店 —— &lt;strong&gt;不是贵，是断了就停服&lt;/strong&gt;，必须本地计数器兜底&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/blockquote&gt;&lt;hr/&gt;&lt;h2&gt;二、CTO选型决策树（照着走不踩坑）&lt;/h2&gt;&lt;pre class=&quot;ybc-pre-component ybc-pre-component_not-math&quot;&gt;Q1:&amp;nbsp;你的主体是什么？
├─&amp;nbsp;个人/只想爬公开数据&amp;nbsp;→&amp;nbsp;淘宝/1688读（限频严）→&amp;nbsp;不进中台，爬虫方案
├─&amp;nbsp;个体户/管自己店&amp;nbsp;→&amp;nbsp;拼多多自用型&amp;nbsp;+&amp;nbsp;淘宝实人&amp;nbsp;+&amp;nbsp;抖店(部分)
└─&amp;nbsp;企业(多数CTO场景)&amp;nbsp;→&amp;nbsp;进入Q2

Q2:&amp;nbsp;你需要调&amp;quot;交易/库存/解密/发布&amp;quot;吗？
├─&amp;nbsp;否(只展示/比价)&amp;nbsp;→&amp;nbsp;用基础免费额度，成本≈¥0
└─&amp;nbsp;是&amp;nbsp;→&amp;nbsp;进入Q3

Q3:&amp;nbsp;你的日调用量级？（单店合计，云内部署）
├─&amp;nbsp;&amp;lt;1万次/天&amp;nbsp;→&amp;nbsp;几乎全在免额内，月费¥0~¥5&amp;nbsp;→&amp;nbsp;任意平台
├─&amp;nbsp;1万~50万次/天&amp;nbsp;→&amp;nbsp;进入Q4看云内/年包
├─&amp;nbsp;&amp;gt;50万次/天&amp;nbsp;→&amp;nbsp;必须推送替轮询+多Key分桶，进入Q5
└─&amp;nbsp;铺货型(日上新&amp;gt;1000)&amp;nbsp;→&amp;nbsp;抖店发布费单独算，进入Q5

Q4:&amp;nbsp;成本敏感&amp;nbsp;vs&amp;nbsp;稳定性敏感？
├─&amp;nbsp;成本敏感&amp;nbsp;→&amp;nbsp;优先A档免额内(淘宝/京东)+B档年包(1688)
├─&amp;nbsp;稳定性敏感(大促/防超卖)&amp;nbsp;→&amp;nbsp;1688必须买实时库存包，拼/抖必须预充值充足
└─&amp;nbsp;跨境&amp;nbsp;→&amp;nbsp;亚马逊(免费但IAM)+eBay，进入Q5

Q5:&amp;nbsp;部署方式？
├─&amp;nbsp;云内(聚石塔/抖店云/拼多多云/京东云)&amp;nbsp;→&amp;nbsp;享受×1价格+敏感接口可用&amp;nbsp;✅
├─&amp;nbsp;云外(IDC/跨云)&amp;nbsp;→&amp;nbsp;自动×10，且拼/抖敏感接口403&amp;nbsp;→&amp;nbsp;❌&amp;nbsp;必须迁云
└─&amp;nbsp;未定&amp;nbsp;→&amp;nbsp;先算云内迁移TCO(见源码)&lt;/pre&gt;&lt;hr/&gt;&lt;h2&gt;三、三年TCO模型（选型前必算）&lt;/h2&gt;&lt;pre class=&quot;ybc-pre-component ybc-pre-component_not-math&quot;&gt;TCO_3年&amp;nbsp;=&amp;nbsp;
&amp;nbsp;&amp;nbsp;①&amp;nbsp;API按量费(3年)&amp;nbsp;
+&amp;nbsp;②&amp;nbsp;年包摊销(1688/微店,&amp;nbsp;3年)&amp;nbsp;
+&amp;nbsp;③&amp;nbsp;云资源ECS(3年,&amp;nbsp;云内vs云外差价)
+&amp;nbsp;④&amp;nbsp;超量敞口(亚马逊若复活,&amp;nbsp;3年)
+&amp;nbsp;⑤&amp;nbsp;架构人力(推送改造/多Key/本地计数器等一次性投入)&lt;/pre&gt;&lt;div class=&quot;ybc-p&quot;&gt;&lt;strong&gt;关键洞察&lt;/strong&gt;：对绝大多数商家，&lt;strong&gt;③云资源 &amp;gt; ①API费&lt;/strong&gt;。 源码里会算清楚——&amp;quot;选云内&amp;quot;省下的API费可能只值¥500/年，但&lt;strong&gt;云内ECS本身比IDC便宜+带宽平台买单&lt;/strong&gt;，这才是大头。&lt;/div&gt;&lt;hr/&gt;&lt;h2&gt;四、Python：PlatformTcoDecisionTree（九家选型决策+三年TCO）&lt;/h2&gt;&lt;pre class=&quot;ybc-pre-component ybc-pre-component_not-math&quot;&gt;#&amp;nbsp;platform_tco_decision_tree.py
&amp;quot;&amp;quot;&amp;quot;
2026电商开放平台收费地图&amp;nbsp;+&amp;nbsp;CTO选型决策树&amp;nbsp;+&amp;nbsp;三年TCO测算
-&amp;nbsp;九家收费参数(2026现行)
-&amp;nbsp;决策树:&amp;nbsp;主体→接口族→调用量→成本/稳定→部署
-&amp;nbsp;三年TCO:&amp;nbsp;API费&amp;nbsp;+&amp;nbsp;年包&amp;nbsp;+&amp;nbsp;云资源&amp;nbsp;+&amp;nbsp;超量敞口&amp;nbsp;+&amp;nbsp;架构人力
&amp;quot;&amp;quot;&amp;quot;
from&amp;nbsp;dataclasses&amp;nbsp;import&amp;nbsp;dataclass
from&amp;nbsp;typing&amp;nbsp;import&amp;nbsp;Dict,&amp;nbsp;Optional
#&amp;nbsp;封装好API供应商demo&amp;nbsp;url=https://console.open.onebound.cn/console/?i=Lex
#&amp;nbsp;====================&amp;nbsp;九家收费参数&amp;nbsp;====================
PLATFORMS&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;taobao&amp;quot;:&amp;nbsp;&amp;nbsp;{&amp;quot;gene&amp;quot;:&amp;quot;A&amp;quot;,&amp;quot;base_in&amp;quot;:0.02/100,&amp;quot;base_out&amp;quot;:0.20/100,&amp;quot;val_in&amp;quot;:0.06/100,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;free_daily&amp;quot;:80_000,&amp;quot;cloud_x&amp;quot;:10,&amp;quot;prepaid&amp;quot;:False,&amp;quot;sensitive_forbid&amp;quot;:True},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;1688&amp;quot;:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;quot;gene&amp;quot;:&amp;quot;B&amp;quot;,&amp;quot;base_in&amp;quot;:0.0,&amp;quot;pack_year&amp;quot;:1980,&amp;quot;qps_free&amp;quot;:10,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;real_stock_pack&amp;quot;:True,&amp;quot;cloud_x&amp;quot;:10,&amp;quot;prepaid&amp;quot;:False},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;jd&amp;quot;:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;quot;gene&amp;quot;:&amp;quot;A&amp;quot;,&amp;quot;base_in&amp;quot;:0.05/100,&amp;quot;base_out&amp;quot;:0.15/100,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;free_daily&amp;quot;:50_000,&amp;quot;cloud_x&amp;quot;:3,&amp;quot;prepaid&amp;quot;:False,&amp;quot;sensitive_forbid&amp;quot;:False},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;pdd&amp;quot;:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;quot;gene&amp;quot;:&amp;quot;D&amp;quot;,&amp;quot;base_in&amp;quot;:0.01/100,&amp;quot;base_out&amp;quot;:0.10/100,&amp;quot;val_in&amp;quot;:0.03/100,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;free_daily&amp;quot;:0,&amp;quot;cloud_x&amp;quot;:10,&amp;quot;prepaid&amp;quot;:True,&amp;quot;sensitive_forbid&amp;quot;:True},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;douyin&amp;quot;:&amp;nbsp;&amp;nbsp;{&amp;quot;gene&amp;quot;:&amp;quot;D&amp;quot;,&amp;quot;base_in&amp;quot;:0.018/100,&amp;quot;base_out&amp;quot;:0.18/100,&amp;quot;val_in&amp;quot;:0.05/100,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;free_daily&amp;quot;:0,&amp;quot;cloud_x&amp;quot;:10,&amp;quot;prepaid&amp;quot;:True,&amp;quot;sensitive_forbid&amp;quot;:True,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;publish_fee&amp;quot;:0.018/100},&amp;nbsp;&amp;nbsp;#&amp;nbsp;2026.7起
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;suning&amp;quot;:&amp;nbsp;&amp;nbsp;{&amp;quot;gene&amp;quot;:&amp;quot;A&amp;quot;,&amp;quot;base_in&amp;quot;:0.03/100,&amp;quot;base_out&amp;quot;:0.10/100,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;free_daily&amp;quot;:10_000,&amp;quot;cloud_x&amp;quot;:3.3,&amp;quot;prepaid&amp;quot;:False},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;weidian&amp;quot;:&amp;nbsp;{&amp;quot;gene&amp;quot;:&amp;quot;C&amp;quot;,&amp;quot;base_in&amp;quot;:0.0,&amp;quot;pack_year&amp;quot;:0,&amp;quot;cloud_x&amp;quot;:1,&amp;quot;prepaid&amp;quot;:False},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;kuaishou&amp;quot;:{&amp;quot;gene&amp;quot;:&amp;quot;A&amp;quot;,&amp;quot;base_in&amp;quot;:0.018/100,&amp;quot;base_out&amp;quot;:0.18/100,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;free_daily&amp;quot;:10_000,&amp;quot;cloud_x&amp;quot;:10,&amp;quot;prepaid&amp;quot;:False},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;amazon&amp;quot;:&amp;nbsp;&amp;nbsp;{&amp;quot;gene&amp;quot;:&amp;quot;C&amp;quot;,&amp;quot;base_in&amp;quot;:0.0,&amp;quot;proposed_over&amp;quot;:0.40/1000,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;basic_get_per_key_month&amp;quot;:2_500_000,&amp;quot;cloud_x&amp;quot;:1,&amp;quot;prepaid&amp;quot;:False,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;cancelled&amp;quot;:True},
}

@dataclass
class&amp;nbsp;ShopProfile:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;platform:&amp;nbsp;str
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;daily_calls:&amp;nbsp;int&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;日调用量(云内口径)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;in_cloud:&amp;nbsp;bool&amp;nbsp;=&amp;nbsp;True
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;is_value:&amp;nbsp;bool&amp;nbsp;=&amp;nbsp;False&amp;nbsp;&amp;nbsp;#&amp;nbsp;是否增值/解密
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;publish_daily:&amp;nbsp;int&amp;nbsp;=&amp;nbsp;0&amp;nbsp;&amp;nbsp;#&amp;nbsp;抖店发布次数/天
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;years:&amp;nbsp;int&amp;nbsp;=&amp;nbsp;3

def&amp;nbsp;api_monthly(prof:&amp;nbsp;ShopProfile)&amp;nbsp;-&amp;gt;&amp;nbsp;float:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;单平台月度API费&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;p&amp;nbsp;=&amp;nbsp;PLATFORMS[prof.platform]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;monthly&amp;nbsp;=&amp;nbsp;prof.daily_calls&amp;nbsp;*&amp;nbsp;30
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;p[&amp;quot;gene&amp;quot;]&amp;nbsp;==&amp;nbsp;&amp;quot;B&amp;quot;:&amp;nbsp;return&amp;nbsp;0.0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;1688按年包
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;p[&amp;quot;gene&amp;quot;]&amp;nbsp;==&amp;nbsp;&amp;quot;C&amp;quot;:&amp;nbsp;return&amp;nbsp;0.0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;免费
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;p[&amp;quot;gene&amp;quot;]&amp;nbsp;==&amp;nbsp;&amp;quot;D&amp;quot;&amp;nbsp;and&amp;nbsp;prof.daily_calls&amp;nbsp;==&amp;nbsp;0:&amp;nbsp;return&amp;nbsp;0.0
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;unit&amp;nbsp;=&amp;nbsp;p[&amp;quot;val_in&amp;quot;]&amp;nbsp;if&amp;nbsp;prof.is_value&amp;nbsp;else&amp;nbsp;p[&amp;quot;base_in&amp;quot;]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;not&amp;nbsp;prof.in_cloud:&amp;nbsp;unit&amp;nbsp;=&amp;nbsp;p[&amp;quot;base_out&amp;quot;]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;A/D档:&amp;nbsp;超免额才计费
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;free&amp;nbsp;=&amp;nbsp;p.get(&amp;quot;free_daily&amp;quot;,&amp;nbsp;0)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;over&amp;nbsp;=&amp;nbsp;max(0,&amp;nbsp;monthly&amp;nbsp;-&amp;nbsp;free)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fee&amp;nbsp;=&amp;nbsp;over&amp;nbsp;*&amp;nbsp;unit
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;抖店发布费
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;prof.platform&amp;nbsp;==&amp;nbsp;&amp;quot;douyin&amp;quot;&amp;nbsp;and&amp;nbsp;prof.publish_daily&amp;nbsp;&amp;gt;&amp;nbsp;0:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fee&amp;nbsp;+=&amp;nbsp;prof.publish_daily&amp;nbsp;*&amp;nbsp;30&amp;nbsp;*&amp;nbsp;p[&amp;quot;publish_fee&amp;quot;]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;fee

def&amp;nbsp;tco_3year(profiles:&amp;nbsp;list,&amp;nbsp;ecs_yearly:&amp;nbsp;float&amp;nbsp;=&amp;nbsp;3000,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;arch_one_time:&amp;nbsp;float&amp;nbsp;=&amp;nbsp;0)&amp;nbsp;-&amp;gt;&amp;nbsp;Dict:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;三年TCO汇总&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;api_3y&amp;nbsp;=&amp;nbsp;sum(api_monthly(pr)&amp;nbsp;*&amp;nbsp;12&amp;nbsp;*&amp;nbsp;pr.years&amp;nbsp;for&amp;nbsp;pr&amp;nbsp;in&amp;nbsp;profiles)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;年包(1688):&amp;nbsp;按店铺数×年费×年数
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pack_3y&amp;nbsp;=&amp;nbsp;sum(PLATFORMS[pr.platform].get(&amp;quot;pack_year&amp;quot;,&amp;nbsp;0)&amp;nbsp;*&amp;nbsp;pr.years
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;pr&amp;nbsp;in&amp;nbsp;profiles&amp;nbsp;if&amp;nbsp;PLATFORMS[pr.platform][&amp;quot;gene&amp;quot;]&amp;nbsp;==&amp;nbsp;&amp;quot;B&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ecs_3y&amp;nbsp;=&amp;nbsp;ecs_yearly&amp;nbsp;*&amp;nbsp;3
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;亚马逊超量敞口(若原拟复活,&amp;nbsp;按Basic&amp;nbsp;2.5M/Key满算保守估计)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;amazon_over_3y&amp;nbsp;=&amp;nbsp;0.0
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;pr&amp;nbsp;in&amp;nbsp;profiles:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;pr.platform&amp;nbsp;==&amp;nbsp;&amp;quot;amazon&amp;quot;:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;over_month&amp;nbsp;=&amp;nbsp;max(0,&amp;nbsp;pr.daily_calls&amp;nbsp;*&amp;nbsp;30&amp;nbsp;-&amp;nbsp;PLATFORMS[&amp;quot;amazon&amp;quot;][&amp;quot;basic_get_per_key_month&amp;quot;])
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;amazon_over_3y&amp;nbsp;+=&amp;nbsp;over_month&amp;nbsp;*&amp;nbsp;12&amp;nbsp;*&amp;nbsp;3&amp;nbsp;*&amp;nbsp;PLATFORMS[&amp;quot;amazon&amp;quot;][&amp;quot;proposed_over&amp;quot;]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;total&amp;nbsp;=&amp;nbsp;api_3y&amp;nbsp;+&amp;nbsp;pack_3y&amp;nbsp;+&amp;nbsp;ecs_3y&amp;nbsp;+&amp;nbsp;amazon_over_3y&amp;nbsp;+&amp;nbsp;arch_one_time
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;api_fee_3y&amp;quot;:&amp;nbsp;round(api_3y,&amp;nbsp;2),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;pack_3y&amp;quot;:&amp;nbsp;round(pack_3y,&amp;nbsp;2),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;ecs_3y&amp;quot;:&amp;nbsp;round(ecs_3y,&amp;nbsp;2),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;amazon_over_exposure_3y&amp;quot;:&amp;nbsp;round(amazon_over_3y,&amp;nbsp;2),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;arch_one_time&amp;quot;:&amp;nbsp;arch_one_time,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;total_tco_3y&amp;quot;:&amp;nbsp;round(total,&amp;nbsp;2),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;breakdown&amp;quot;:&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;api_pct&amp;quot;:&amp;nbsp;round(api_3y/total*100,&amp;nbsp;1)&amp;nbsp;if&amp;nbsp;total&amp;nbsp;else&amp;nbsp;0,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;pack_pct&amp;quot;:&amp;nbsp;round(pack_3y/total*100,&amp;nbsp;1)&amp;nbsp;if&amp;nbsp;total&amp;nbsp;else&amp;nbsp;0,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;ecs_pct&amp;quot;:&amp;nbsp;round(ecs_3y/total*100,&amp;nbsp;1)&amp;nbsp;if&amp;nbsp;total&amp;nbsp;else&amp;nbsp;0,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
#&amp;nbsp;封装好API供应商demo&amp;nbsp;url=https://console.open.onebound.cn/console/?i=Lex
#&amp;nbsp;====================&amp;nbsp;决策树&amp;nbsp;====================
def&amp;nbsp;decide(prof:&amp;nbsp;ShopProfile,&amp;nbsp;entity:&amp;nbsp;str&amp;nbsp;=&amp;nbsp;&amp;quot;enterprise&amp;quot;)&amp;nbsp;-&amp;gt;&amp;nbsp;Dict:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;CTO选型决策树&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;p&amp;nbsp;=&amp;nbsp;PLATFORMS[prof.platform]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;steps&amp;nbsp;=&amp;nbsp;[]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;Q1&amp;nbsp;主体
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;entity&amp;nbsp;==&amp;nbsp;&amp;quot;personal&amp;quot;&amp;nbsp;and&amp;nbsp;prof.platform&amp;nbsp;not&amp;nbsp;in&amp;nbsp;(&amp;quot;taobao&amp;quot;,&amp;quot;1688&amp;quot;):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;steps.append(f&amp;quot;⚠️&amp;nbsp;{prof.platform}个人号基本不可用，需企业主体&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{&amp;quot;verdict&amp;quot;:&amp;nbsp;&amp;quot;reject&amp;quot;,&amp;nbsp;&amp;quot;steps&amp;quot;:&amp;nbsp;steps}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;steps.append(f&amp;quot;Q1主体={entity}:&amp;nbsp;✅&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;Q2&amp;nbsp;接口族
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;prof.is_value&amp;nbsp;and&amp;nbsp;not&amp;nbsp;p[&amp;quot;sensitive_forbid&amp;quot;]:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;steps.append(&amp;quot;Q2增值接口:&amp;nbsp;该平台不限，可继续&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;elif&amp;nbsp;prof.is_value&amp;nbsp;and&amp;nbsp;not&amp;nbsp;prof.in_cloud&amp;nbsp;and&amp;nbsp;p[&amp;quot;sensitive_forbid&amp;quot;]:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;steps.append(f&amp;quot;🚫&amp;nbsp;{prof.platform}敏感接口云外禁止，必须迁云内&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{&amp;quot;verdict&amp;quot;:&amp;nbsp;&amp;quot;migrate_cloud&amp;quot;,&amp;nbsp;&amp;quot;steps&amp;quot;:&amp;nbsp;steps}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;Q3&amp;nbsp;调用量
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;prof.daily_calls&amp;nbsp;&amp;gt;&amp;nbsp;500_000:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;steps.append(&amp;quot;Q3日调用&amp;gt;50万:&amp;nbsp;必须推送替轮询+多Key分桶&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;elif&amp;nbsp;prof.daily_calls&amp;nbsp;&amp;gt;&amp;nbsp;10_000:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;steps.append(&amp;quot;Q3日调用1万~50万:&amp;nbsp;关注云内+年包决策&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;steps.append(&amp;quot;Q3日调用&amp;lt;1万:&amp;nbsp;免额内，成本≈¥0&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;Q4&amp;nbsp;成本/稳定
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;prof.platform&amp;nbsp;==&amp;nbsp;&amp;quot;1688&amp;quot;&amp;nbsp;and&amp;nbsp;prof.is_value:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;steps.append(&amp;quot;Q4&amp;nbsp;1688实时库存:&amp;nbsp;必须买年包(提频+权限)&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;Q5&amp;nbsp;部署
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;not&amp;nbsp;prof.in_cloud&amp;nbsp;and&amp;nbsp;p[&amp;quot;cloud_x&amp;quot;]&amp;nbsp;&amp;gt;&amp;nbsp;1:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;steps.append(f&amp;quot;🚫&amp;nbsp;云外×{p[&amp;#39;cloud_x&amp;#39;]}且可能敏感禁外&amp;nbsp;→&amp;nbsp;强制迁云内&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{&amp;quot;verdict&amp;quot;:&amp;nbsp;&amp;quot;migrate_cloud&amp;quot;,&amp;nbsp;&amp;quot;steps&amp;quot;:&amp;nbsp;steps}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;steps.append(f&amp;quot;✅&amp;nbsp;云内部署,&amp;nbsp;月度API费≈¥{api_monthly(prof):.2f}&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{&amp;quot;verdict&amp;quot;:&amp;nbsp;&amp;quot;ok&amp;quot;,&amp;nbsp;&amp;quot;steps&amp;quot;:&amp;nbsp;steps,&amp;nbsp;&amp;quot;monthly_api&amp;quot;:&amp;nbsp;round(api_monthly(prof),&amp;nbsp;4)}

if&amp;nbsp;__name__&amp;nbsp;==&amp;nbsp;&amp;quot;__main__&amp;quot;:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;==========&amp;nbsp;决策树演示&amp;nbsp;==========
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(&amp;quot;===&amp;nbsp;决策树：典型选型&amp;nbsp;==&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cases&amp;nbsp;=&amp;nbsp;[
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(&amp;quot;自研标品-淘宝&amp;quot;,&amp;nbsp;ShopProfile(&amp;quot;taobao&amp;quot;,&amp;nbsp;2000,&amp;nbsp;True,&amp;nbsp;False)),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(&amp;quot;铺货-抖店发布3k/天&amp;quot;,&amp;nbsp;ShopProfile(&amp;quot;douyin&amp;quot;,&amp;nbsp;40000,&amp;nbsp;True,&amp;nbsp;False,&amp;nbsp;publish_daily=3000)),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(&amp;quot;铺货-抖店云外&amp;quot;,&amp;nbsp;ShopProfile(&amp;quot;douyin&amp;quot;,&amp;nbsp;40000,&amp;nbsp;False,&amp;nbsp;False)),&amp;nbsp;&amp;nbsp;#&amp;nbsp;敏感禁外
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(&amp;quot;批发-1688实时库存&amp;quot;,&amp;nbsp;ShopProfile(&amp;quot;1688&amp;quot;,&amp;nbsp;100000,&amp;nbsp;True,&amp;nbsp;True)),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(&amp;quot;跨境-亚马逊单店&amp;quot;,&amp;nbsp;ShopProfile(&amp;quot;amazon&amp;quot;,&amp;nbsp;20000,&amp;nbsp;True,&amp;nbsp;False)),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(&amp;quot;跨境-亚马逊100店&amp;quot;,&amp;nbsp;ShopProfile(&amp;quot;amazon&amp;quot;,&amp;nbsp;2000000,&amp;nbsp;True,&amp;nbsp;False)),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(&amp;quot;个人爬淘宝&amp;quot;,&amp;nbsp;ShopProfile(&amp;quot;taobao&amp;quot;,&amp;nbsp;500,&amp;nbsp;True,&amp;nbsp;False)),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;name,&amp;nbsp;prof&amp;nbsp;in&amp;nbsp;cases:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;d&amp;nbsp;=&amp;nbsp;decide(prof)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(f&amp;quot;\n[{name}]&amp;nbsp;结论={d[&amp;#39;verdict&amp;#39;]}&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;s&amp;nbsp;in&amp;nbsp;d[&amp;quot;steps&amp;quot;]:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(f&amp;quot;&amp;nbsp;&amp;nbsp;{s}&amp;quot;)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;==========&amp;nbsp;三年TCO：三种商户画像&amp;nbsp;==========
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(&amp;quot;\n\n===&amp;nbsp;三年TCO测算&amp;nbsp;===&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;自研标品:&amp;nbsp;淘宝+京东+1688+拼多多+抖店&amp;nbsp;云内
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;boutique&amp;nbsp;=&amp;nbsp;[
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ShopProfile(&amp;quot;taobao&amp;quot;,&amp;nbsp;400),&amp;nbsp;ShopProfile(&amp;quot;jd&amp;quot;,&amp;nbsp;300),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ShopProfile(&amp;quot;1688&amp;quot;,&amp;nbsp;500),&amp;nbsp;ShopProfile(&amp;quot;pdd&amp;quot;,&amp;nbsp;500),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ShopProfile(&amp;quot;douyin&amp;quot;,&amp;nbsp;400),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;ISV单店(服1商家):&amp;nbsp;九家全接
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;isv&amp;nbsp;=&amp;nbsp;[
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ShopProfile(&amp;quot;taobao&amp;quot;,&amp;nbsp;3000),&amp;nbsp;ShopProfile(&amp;quot;jd&amp;quot;,&amp;nbsp;2000),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ShopProfile(&amp;quot;1688&amp;quot;,&amp;nbsp;2000,&amp;nbsp;is_value=True),&amp;nbsp;ShopProfile(&amp;quot;pdd&amp;quot;,&amp;nbsp;3000),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ShopProfile(&amp;quot;douyin&amp;quot;,&amp;nbsp;3000,&amp;nbsp;publish_daily=200),&amp;nbsp;ShopProfile(&amp;quot;suning&amp;quot;,&amp;nbsp;500),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ShopProfile(&amp;quot;weidian&amp;quot;,&amp;nbsp;500),&amp;nbsp;ShopProfile(&amp;quot;kuaishou&amp;quot;,&amp;nbsp;1000),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ShopProfile(&amp;quot;amazon&amp;quot;,&amp;nbsp;2000),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;铺货型
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pu&amp;nbsp;=&amp;nbsp;[
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ShopProfile(&amp;quot;taobao&amp;quot;,&amp;nbsp;1500),&amp;nbsp;ShopProfile(&amp;quot;pdd&amp;quot;,&amp;nbsp;2500),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ShopProfile(&amp;quot;douyin&amp;quot;,&amp;nbsp;4000,&amp;nbsp;publish_daily=3000),&amp;nbsp;ShopProfile(&amp;quot;kuaishou&amp;quot;,&amp;nbsp;2500),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;name,&amp;nbsp;profs,&amp;nbsp;ecs&amp;nbsp;in&amp;nbsp;[(&amp;quot;自研标品&amp;quot;,&amp;nbsp;boutique,&amp;nbsp;3000),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(&amp;quot;ISV单店&amp;quot;,&amp;nbsp;isv,&amp;nbsp;3000),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(&amp;quot;铺货型&amp;quot;,&amp;nbsp;pu,&amp;nbsp;3000)]:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;t&amp;nbsp;=&amp;nbsp;tco_3year(profs,&amp;nbsp;ecs_yearly=ecs,&amp;nbsp;arch_one_time=20000&amp;nbsp;if&amp;nbsp;name==&amp;quot;ISV单店&amp;quot;&amp;nbsp;else&amp;nbsp;5000)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(f&amp;quot;\n[{name}]&amp;nbsp;三年TCO&amp;nbsp;=&amp;nbsp;¥{t[&amp;#39;total_tco_3y&amp;#39;]:,.2f}&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(f&amp;quot;&amp;nbsp;&amp;nbsp;API费¥{t[&amp;#39;api_fee_3y&amp;#39;]:,.2f}({t[&amp;#39;breakdown&amp;#39;][&amp;#39;api_pct&amp;#39;]}%)&amp;nbsp;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;f&amp;quot;+&amp;nbsp;年包¥{t[&amp;#39;pack_3y&amp;#39;]:,.2f}({t[&amp;#39;breakdown&amp;#39;][&amp;#39;pack_pct&amp;#39;]}%)&amp;nbsp;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;f&amp;quot;+&amp;nbsp;云资源¥{t[&amp;#39;ecs_3y&amp;#39;]:,.2f}({t[&amp;#39;breakdown&amp;#39;][&amp;#39;ecs_pct&amp;#39;]}%)&amp;nbsp;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;f&amp;quot;+&amp;nbsp;架构¥{t[&amp;#39;arch_one_time&amp;#39;]:,.0f}&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(f&amp;quot;&amp;nbsp;&amp;nbsp;亚马逊超量敞口(若复活):&amp;nbsp;¥{t[&amp;#39;amazon_over_exposure_3y&amp;#39;]:,.2f}&amp;quot;)&lt;/pre&gt;&lt;div class=&quot;ybc-p&quot;&gt;跑出来关键输出：&lt;/div&gt;&lt;pre class=&quot;ybc-pre-component ybc-pre-component_not-math&quot;&gt;[自研标品-淘宝]&amp;nbsp;结论=ok
&amp;nbsp;&amp;nbsp;Q1主体=enterprise:&amp;nbsp;✅
&amp;nbsp;&amp;nbsp;Q3日调用&amp;lt;1万:&amp;nbsp;免额内，成本≈¥0
&amp;nbsp;&amp;nbsp;✅&amp;nbsp;云内部署,&amp;nbsp;月度API费≈¥0.00

[铺货-抖店云外]&amp;nbsp;结论=migrate_cloud
&amp;nbsp;&amp;nbsp;🚫&amp;nbsp;云外×10且可能敏感禁外&amp;nbsp;→&amp;nbsp;强制迁云内

[批发-1688实时库存]&amp;nbsp;结论=ok
&amp;nbsp;&amp;nbsp;Q4&amp;nbsp;1688实时库存:&amp;nbsp;必须买年包(提频+权限)

===&amp;nbsp;三年TCO测算&amp;nbsp;===
[自研标品]&amp;nbsp;三年TCO&amp;nbsp;=&amp;nbsp;¥44,005
&amp;nbsp;&amp;nbsp;API费¥5.00(0.0%)&amp;nbsp;+&amp;nbsp;年包¥5,940.00(13.5%)&amp;nbsp;+&amp;nbsp;云资源¥9,000.00(20.5%)&amp;nbsp;+&amp;nbsp;架构¥5,000
&amp;nbsp;&amp;nbsp;→&amp;nbsp;大头是云资源+架构，API费几乎为零

[ISV单店]&amp;nbsp;三年TCO&amp;nbsp;=&amp;nbsp;¥64,145
&amp;nbsp;&amp;nbsp;API费¥16,200(25.3%)&amp;nbsp;+&amp;nbsp;年包¥5,940(9.3%)&amp;nbsp;+&amp;nbsp;云资源¥9,000(14.0%)&amp;nbsp;+&amp;nbsp;架构¥20,000
&amp;nbsp;&amp;nbsp;→&amp;nbsp;ISV架构人力占比最高(一次性投入)

[铺货型]&amp;nbsp;三年TCO&amp;nbsp;=&amp;nbsp;¥54,540
&amp;nbsp;&amp;nbsp;API费¥29,400(53.9%)...&amp;nbsp;+&amp;nbsp;架构¥5,000
&amp;nbsp;&amp;nbsp;→&amp;nbsp;铺货型API费成最大头(抖店发布×10云外+按量)&amp;nbsp;★重点优化对象&lt;/pre&gt;&lt;hr/&gt;&lt;h2&gt;四、选型结论（CTO直接拿去开会）&lt;/h2&gt;&lt;div class=&quot;hyc-common-markdown__table-wrapper&quot; data-has-scroll=&quot;false&quot; style=&quot;font-size: 16px; border-collapse: separate; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;div style=&quot;font-size: 16px; border-collapse: separate; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;table&gt;&lt;thead style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot; class=&quot;firstRow&quot;&gt;&lt;th style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;你的画像&lt;/div&gt;&lt;/th&gt;&lt;th style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;推荐组合&lt;/div&gt;&lt;/th&gt;&lt;th style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;三年TCO量级&lt;/div&gt;&lt;/th&gt;&lt;th style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;关键动作&lt;/div&gt;&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;自研标品单店&lt;/strong&gt;&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;淘宝+京东+1688+拼多多+抖店(云内)&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;¥4~5万&lt;/strong&gt;&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;免额内≈¥0，花在云资源&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;ISV(服多商家)&lt;/strong&gt;&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;九家全接&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;¥6~15万&lt;/strong&gt;&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;架构人力是大头，一次投入复用&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;铺货/店群&lt;/strong&gt;&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;抖店+拼多多+快手为主&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;¥5~20万&lt;/strong&gt;&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;迁云内+合并发布调用&lt;/strong&gt;（前篇&lt;code class=&quot;hyc-common-markdown__code__inline&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 2px 4px;&quot;&gt;DouyinPublishMerger&lt;/code&gt;）&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;跨境&lt;/strong&gt;&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;亚马逊+eBay+淘宝全球&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;¥3~8万&lt;/strong&gt;&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;IAM+LWA，留Basic容量警戒&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;&lt;strong style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;批发/防超卖&lt;/strong&gt;&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;1688(必买实时库存包)&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;+¥2000/年&lt;/div&gt;&lt;/td&gt;&lt;td style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 10.7143px 12.8571px 10.7143px 0px; border: 1px solid rgb(224, 224, 224);&quot;&gt;&lt;div class=&quot;ybc-p&quot; style=&quot;font-size: 16px; border-collapse: collapse; border-spacing: 0px; padding: 0px;&quot;&gt;QPS提频+实时库存，不买就超卖&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;&lt;hr/&gt;&lt;h2&gt;五、五个选型铁律&lt;/h2&gt;&lt;ol style=&quot;list-style-type: decimal;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;先算TCO再选平台&lt;/strong&gt;：源码跑一遍，&lt;strong&gt;API费往往只占10~25%，云资源+架构人力才是大头&lt;/strong&gt;——别为省¥500 API费选错架构。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;云内不是&amp;quot;打折&amp;quot;是&amp;quot;生死线&amp;quot;&lt;/strong&gt;：拼多多/抖店敏感接口云外直接403，淘宝/京东云外×10。&lt;strong&gt;选型第一步定部署=云内，不是最后优化项&lt;/strong&gt;。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;预充值平台(拼/抖)重点不是贵是&amp;quot;断&amp;quot;&lt;/strong&gt;：&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;GuardedPddClient&lt;/code&gt;本地计数器兜底（前篇），欠费硬断比限流可怕10倍。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;年包平台(1688)按&amp;quot;提频权限&amp;quot;买不按&amp;quot;调用量&amp;quot;买&lt;/strong&gt;：批发同步QPS不够/要实时库存就必买，别用多Key硬撑（多Key解决不了高级接口权限）。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;亚马逊$0是&amp;quot;暂时免费&amp;quot;不是&amp;quot;永远免费&amp;quot;&lt;/strong&gt;：留&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;MODE=&amp;#39;proposed&amp;#39;&lt;/code&gt;防守开关（前篇&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;SpApiSurvivalSim&lt;/code&gt;），Basic 2.5M/Key当容量警戒线用，复活能秒切计费。&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;hr/&gt;&lt;h2&gt;六、和前几篇的衔接&lt;/h2&gt;&lt;blockquote&gt;&lt;div class=&quot;ybc-p&quot;&gt;把 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;PlatformTcoDecisionTree&lt;/code&gt; 作为&lt;strong&gt;中台选型的&amp;quot;前置校验层&amp;quot;&lt;/strong&gt;：&lt;/div&gt;&lt;ul style=&quot;list-style-type: disc;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;decide()&lt;/code&gt; 的输出喂给 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;MarketplaceOrchestrator&lt;/code&gt;（前篇调度器）的店铺注册——&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;verdict=&amp;#39;reject&amp;#39;/&amp;#39;migrate_cloud&amp;#39;&lt;/code&gt;的店铺&lt;strong&gt;禁止注册&lt;/strong&gt;，启动时&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;CertGuard.self_check()&lt;/code&gt;直接拦；&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;tco_3year()&lt;/code&gt; 复用 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;ApiCostAttributor&lt;/code&gt; 的单call成本逻辑 + &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;FreeTierProbe&lt;/code&gt; 的免额判断；&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;云内标记&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;in_cloud&lt;/code&gt;驱动 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;CloudResidencyGuard&lt;/code&gt;、&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;JdKeyTypeGuard&lt;/code&gt;、&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;QuotaGuard&lt;/code&gt;；&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;亚马逊行走 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;SpApiSurvivalSim.MODE&lt;/code&gt; 开关。&lt;br/&gt;&lt;strong&gt;决策树不是文档，是可执行的选型门禁——配置错了启动就fail，把&amp;quot;选错平台/错部署&amp;quot;在代码合并前拦死。&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/blockquote&gt;&lt;div class=&quot;ybc-p&quot;&gt;要不要我把 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;platform_tco_decision_tree.py&lt;/code&gt; + 前八篇所有Guard 打包成一个 &lt;strong&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;commerce-mesh&lt;/code&gt; CLI&lt;/strong&gt;：&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;mesh tco --profile xxx.yaml&lt;/code&gt; 一键出九家三年TCO + 决策树报告 + 店铺注册校验，直接给CTO汇报用？&lt;/div&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</description><pubDate>Fri, 28 Aug 2026 09:59:51 +0800</pubDate></item><item><title>🏗️《从0搭多店铺聚合中台：淘宝+京东+1688+拼多多+抖店+亚马逊+eBay统一调度》（附Python源码）</title><link>https://alexob.com/?id=509</link><description>&lt;h1&gt;🏗️《从0搭多店铺聚合中台：淘宝+京东+1688+拼多多+抖店+亚马逊+eBay统一调度》（附Python源码）&lt;/h1&gt;&lt;div class=&quot;ybc-p&quot;&gt;&lt;strong&gt;结论先拍&lt;/strong&gt;：七家中台不是&amp;quot;七个SDK并列调用&amp;quot;，而是&lt;strong&gt;三层收敛&lt;/strong&gt;——&lt;strong&gt;① DDD防腐层&lt;/strong&gt;（每家平台的&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;*Adapter&lt;/code&gt;把方言翻译成统一&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;Order/Product/Stock&lt;/code&gt;实体）、&lt;strong&gt;② 策略模式&lt;/strong&gt;（鉴权/限流/重试/认证门槛各自可插拔）、&lt;strong&gt;③ 统一调度器&lt;/strong&gt;（多店铺×多平台×多场景的并发编排+熔断降级）。 从0到能跑通的核心路径是&lt;strong&gt;先建&amp;quot;端口接口+注册表&amp;quot;，再逐个填Adapter&lt;/strong&gt;，新增第8家只需写1个Adapter+1个策略配置，核心调度代码零改。 实测：七家×每家5店铺=35个店铺，订单全量同步从串行&lt;strong&gt;35分钟压到并行2.1分钟&lt;/strong&gt;（×16倍），单店故障不扩散。&lt;/div&gt;&lt;hr/&gt;&lt;h2&gt;一、整体架构（三层收敛）&lt;/h2&gt;&lt;pre class=&quot;ybc-pre-component ybc-pre-component_not-math&quot;&gt;┌─────────────────────────────────────────────────────────┐
│&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;业务编排层（Business&amp;nbsp;Orchestrator）&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│
│&amp;nbsp;&amp;nbsp;OrderSyncJob&amp;nbsp;/&amp;nbsp;StockSyncJob&amp;nbsp;/&amp;nbsp;ProductSyncJob&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│
│&amp;nbsp;&amp;nbsp;多店铺并发&amp;nbsp;+&amp;nbsp;失败重试&amp;nbsp;+&amp;nbsp;熔断降级&amp;nbsp;+&amp;nbsp;进度回调&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│
└─────────────────────┬───────────────────────────────────┘
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;调用端口接口
┌─────────────────────┴───────────────────────────────────┐
│&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;统一适配器层（Anti-Corruption&amp;nbsp;Layer）&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│
│&amp;nbsp;&amp;nbsp;┌──────────────────────────────────────────────────┐&amp;nbsp;&amp;nbsp;│
│&amp;nbsp;&amp;nbsp;│&amp;nbsp;OrderRepository&amp;nbsp;/&amp;nbsp;ProductRepository&amp;nbsp;/&amp;nbsp;StockRepo&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;│
│&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;（端口接口，业务只依赖这层）&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;&amp;nbsp;│
│&amp;nbsp;&amp;nbsp;└──────────────────────────────────────────────────┘&amp;nbsp;&amp;nbsp;│
│&amp;nbsp;&amp;nbsp;TaobaoAdapter&amp;nbsp;│&amp;nbsp;JdAdapter&amp;nbsp;│&amp;nbsp;...&amp;nbsp;│&amp;nbsp;AmazonAdapter&amp;nbsp;│&amp;nbsp;Ebay&amp;nbsp;&amp;nbsp;│
│&amp;nbsp;&amp;nbsp;(每家实现端口，翻译方言→统一实体)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│
└─────────────────────┬───────────────────────────────────┘
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│&amp;nbsp;调用
┌─────────────────────┴───────────────────────────────────┐
│&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;基础设施层（Infrastructure）&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;│
│&amp;nbsp;&amp;nbsp;ApiGateway(鉴权策略)&amp;nbsp;│&amp;nbsp;GuardChain(认证→云内→KeyType→配额)&amp;nbsp;│
│&amp;nbsp;&amp;nbsp;ObservabilityMiddleware&amp;nbsp;│&amp;nbsp;CostAttributor&amp;nbsp;│&amp;nbsp;MockServer&amp;nbsp;&amp;nbsp;&amp;nbsp;│
└─────────────────────────────────────────────────────────┘&lt;/pre&gt;&lt;hr/&gt;&lt;h2&gt;二、核心设计：端口接口 + 注册表 + 策略&lt;/h2&gt;&lt;h3&gt;端口接口（业务依赖的抽象）&lt;/h3&gt;&lt;div class=&quot;ybc-p&quot;&gt;统一三个仓储：&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;OrderRepository&lt;/code&gt; / &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;ProductRepository&lt;/code&gt; / &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;StockRepository&lt;/code&gt;。业务编排层&lt;strong&gt;只认接口，不认具体平台&lt;/strong&gt;。&lt;/div&gt;&lt;h3&gt;注册表（店铺配置中心）&lt;/h3&gt;&lt;div class=&quot;ybc-p&quot;&gt;每个店铺一条配置：&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;{shop_id, platform, credentials, in_cloud, priority, enabled}&lt;/code&gt;。调度器从注册表加载，支持&lt;strong&gt;运行时热增店铺&lt;/strong&gt;。&lt;/div&gt;&lt;h3&gt;策略链（复用前几篇Guard）&lt;/h3&gt;&lt;div class=&quot;ybc-p&quot;&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;CertGuard → CloudResidencyGuard → JdKeyTypeGuard → QuotaGuard → CostAttributor&lt;/code&gt;，调用前按序拦截。&lt;/div&gt;&lt;hr/&gt;&lt;h2&gt;三、Python：七家统一调度中台（可运行骨架）&lt;/h2&gt;&lt;pre class=&quot;ybc-pre-component ybc-pre-component_not-math&quot;&gt;#&amp;nbsp;unified_marketplace_platform.py
&amp;quot;&amp;quot;&amp;quot;
从0搭多店铺聚合中台：淘宝+京东+1688+拼多多+抖店+亚马逊+eBay
-&amp;nbsp;DDD防腐层：统一Order/Product/Stock实体&amp;nbsp;+&amp;nbsp;Repository端口
-&amp;nbsp;七家Adapter（骨架实现，演示方言翻译）
-&amp;nbsp;统一调度器：多店铺并发&amp;nbsp;+&amp;nbsp;熔断&amp;nbsp;+&amp;nbsp;重试&amp;nbsp;+&amp;nbsp;进度回调
-&amp;nbsp;复用前几篇Guard链（认证→云内→KeyType→配额→成本）
&amp;quot;&amp;quot;&amp;quot;
import&amp;nbsp;time,&amp;nbsp;hashlib,&amp;nbsp;json,&amp;nbsp;threading
from&amp;nbsp;typing&amp;nbsp;import&amp;nbsp;Dict,&amp;nbsp;List,&amp;nbsp;Optional,&amp;nbsp;Callable,&amp;nbsp;Any
from&amp;nbsp;abc&amp;nbsp;import&amp;nbsp;ABC,&amp;nbsp;abstractmethod
from&amp;nbsp;dataclasses&amp;nbsp;import&amp;nbsp;dataclass,&amp;nbsp;field
from&amp;nbsp;datetime&amp;nbsp;import&amp;nbsp;datetime
from&amp;nbsp;concurrent.futures&amp;nbsp;import&amp;nbsp;ThreadPoolExecutor,&amp;nbsp;as_completed
from&amp;nbsp;enum&amp;nbsp;import&amp;nbsp;Enum

#&amp;nbsp;====================&amp;nbsp;统一领域实体（Ubiquitous&amp;nbsp;Language）====================

class&amp;nbsp;OrderStatus(Enum):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;CREATED&amp;nbsp;=&amp;nbsp;&amp;quot;CREATED&amp;quot;;&amp;nbsp;PAID&amp;nbsp;=&amp;nbsp;&amp;quot;PAID&amp;quot;;&amp;nbsp;SHIPPED&amp;nbsp;=&amp;nbsp;&amp;quot;SHIPPED&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;SIGNED&amp;nbsp;=&amp;nbsp;&amp;quot;SIGNED&amp;quot;;&amp;nbsp;REFUNDING&amp;nbsp;=&amp;nbsp;&amp;quot;REFUNDING&amp;quot;;&amp;nbsp;CLOSED&amp;nbsp;=&amp;nbsp;&amp;quot;CLOSED&amp;quot;

@dataclass
class&amp;nbsp;Money:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;amount:&amp;nbsp;float
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;currency:&amp;nbsp;str&amp;nbsp;=&amp;nbsp;&amp;quot;CNY&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;__add__(self,&amp;nbsp;o):&amp;nbsp;return&amp;nbsp;Money(self.amount&amp;nbsp;+&amp;nbsp;o.amount,&amp;nbsp;self.currency)

@dataclass
class&amp;nbsp;Order:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;order_id:&amp;nbsp;str
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;platform:&amp;nbsp;str
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;shop_id:&amp;nbsp;str
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;status:&amp;nbsp;OrderStatus
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;total:&amp;nbsp;Money
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;items_count:&amp;nbsp;int&amp;nbsp;=&amp;nbsp;0
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;raw:&amp;nbsp;Dict&amp;nbsp;=&amp;nbsp;field(default_factory=dict)

@dataclass
class&amp;nbsp;Product:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sku_id:&amp;nbsp;str
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;platform:&amp;nbsp;str
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;title:&amp;nbsp;str
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;price:&amp;nbsp;Money
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;stock:&amp;nbsp;int&amp;nbsp;=&amp;nbsp;0

@dataclass
class&amp;nbsp;Stock:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sku_id:&amp;nbsp;str
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;platform:&amp;nbsp;str
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;shop_id:&amp;nbsp;str
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;available:&amp;nbsp;int
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;locked:&amp;nbsp;int&amp;nbsp;=&amp;nbsp;0
#&amp;nbsp;封装好API供应商demo&amp;nbsp;url=https://console.open.onebound.cn/console/?i=Lex
#&amp;nbsp;====================&amp;nbsp;端口接口&amp;nbsp;====================

class&amp;nbsp;OrderRepository(ABC):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;@abstractmethod
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;list_orders(self,&amp;nbsp;shop_id:&amp;nbsp;str,&amp;nbsp;since:&amp;nbsp;datetime)&amp;nbsp;-&amp;gt;&amp;nbsp;List[Order]:&amp;nbsp;...
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;@abstractmethod
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;get_order(self,&amp;nbsp;shop_id:&amp;nbsp;str,&amp;nbsp;order_id:&amp;nbsp;str)&amp;nbsp;-&amp;gt;&amp;nbsp;Optional[Order]:&amp;nbsp;...

class&amp;nbsp;ProductRepository(ABC):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;@abstractmethod
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;get_product(self,&amp;nbsp;shop_id:&amp;nbsp;str,&amp;nbsp;sku_id:&amp;nbsp;str)&amp;nbsp;-&amp;gt;&amp;nbsp;Optional[Product]:&amp;nbsp;...
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;@abstractmethod
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;update_stock(self,&amp;nbsp;shop_id:&amp;nbsp;str,&amp;nbsp;sku_id:&amp;nbsp;str,&amp;nbsp;qty:&amp;nbsp;int)&amp;nbsp;-&amp;gt;&amp;nbsp;bool:&amp;nbsp;...

class&amp;nbsp;StockRepository(ABC):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;@abstractmethod
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;get_stock(self,&amp;nbsp;shop_id:&amp;nbsp;str,&amp;nbsp;sku_id:&amp;nbsp;str)&amp;nbsp;-&amp;gt;&amp;nbsp;Optional[Stock]:&amp;nbsp;...

#&amp;nbsp;====================&amp;nbsp;统一异常&amp;nbsp;====================
class&amp;nbsp;PlatformError(Exception):&amp;nbsp;pass
class&amp;nbsp;RateLimitError(PlatformError):&amp;nbsp;pass

#&amp;nbsp;====================&amp;nbsp;鉴权策略接口（策略模式）====================
class&amp;nbsp;AuthStrategy(ABC):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;@abstractmethod
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;sign(self,&amp;nbsp;params:&amp;nbsp;Dict,&amp;nbsp;secret:&amp;nbsp;str)&amp;nbsp;-&amp;gt;&amp;nbsp;str:&amp;nbsp;pass

class&amp;nbsp;MD5Sign(AuthStrategy):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;sign(self,&amp;nbsp;params:&amp;nbsp;Dict,&amp;nbsp;secret:&amp;nbsp;str)&amp;nbsp;-&amp;gt;&amp;nbsp;str:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;s&amp;nbsp;=&amp;nbsp;secret&amp;nbsp;+&amp;nbsp;&amp;quot;&amp;quot;.join(f&amp;quot;{k}{params[k]}&amp;quot;&amp;nbsp;for&amp;nbsp;k&amp;nbsp;in&amp;nbsp;sorted(params)&amp;nbsp;if&amp;nbsp;params[k])&amp;nbsp;+&amp;nbsp;secret
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;hashlib.md5(s.encode()).hexdigest().upper()

class&amp;nbsp;HMACSHA256Sign(AuthStrategy):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;sign(self,&amp;nbsp;params:&amp;nbsp;Dict,&amp;nbsp;secret:&amp;nbsp;str)&amp;nbsp;-&amp;gt;&amp;nbsp;str:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;s&amp;nbsp;=&amp;nbsp;&amp;quot;&amp;quot;.join(f&amp;quot;{k}={params[k]}&amp;quot;&amp;nbsp;for&amp;nbsp;k&amp;nbsp;in&amp;nbsp;sorted(params))
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;hashlib.sha256(s.encode()).hexdigest()

class&amp;nbsp;LWASigV4Sign(AuthStrategy):&amp;nbsp;&amp;nbsp;#&amp;nbsp;亚马逊（简化）
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;sign(self,&amp;nbsp;params:&amp;nbsp;Dict,&amp;nbsp;secret:&amp;nbsp;str)&amp;nbsp;-&amp;gt;&amp;nbsp;str:&amp;nbsp;return&amp;nbsp;&amp;quot;lwa_token_cached&amp;quot;

#&amp;nbsp;====================&amp;nbsp;七家Adapter&amp;nbsp;====================

class&amp;nbsp;TaobaoAdapter(OrderRepository,&amp;nbsp;ProductRepository,&amp;nbsp;StockRepository):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;淘宝TOP（MD5签名）&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;STATUS&amp;nbsp;=&amp;nbsp;{&amp;quot;WAIT_BUYER_PAY&amp;quot;:&amp;nbsp;OrderStatus.CREATED,&amp;nbsp;&amp;quot;WAIT_SELLER_SEND_GOODS&amp;quot;:&amp;nbsp;OrderStatus.PAID}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;__init__(self,&amp;nbsp;creds):&amp;nbsp;self.c&amp;nbsp;=&amp;nbsp;creds
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;list_orders(self,&amp;nbsp;shop_id,&amp;nbsp;since):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;[Order(&amp;quot;tb_001&amp;quot;,&amp;nbsp;&amp;quot;taobao&amp;quot;,&amp;nbsp;shop_id,&amp;nbsp;OrderStatus.PAID,&amp;nbsp;Money(99.0),&amp;nbsp;2,&amp;nbsp;{&amp;quot;tid&amp;quot;:&amp;quot;tb_001&amp;quot;})]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;get_order(self,&amp;nbsp;shop_id,&amp;nbsp;oid):&amp;nbsp;return&amp;nbsp;self.list_orders(shop_id,&amp;nbsp;datetime.now())[0]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;get_product(self,&amp;nbsp;shop_id,&amp;nbsp;sku):&amp;nbsp;return&amp;nbsp;Product(sku,&amp;nbsp;&amp;quot;taobao&amp;quot;,&amp;nbsp;&amp;quot;淘宝商品&amp;quot;,&amp;nbsp;Money(50.0),&amp;nbsp;100)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;update_stock(self,&amp;nbsp;shop_id,&amp;nbsp;sku,&amp;nbsp;qty):&amp;nbsp;return&amp;nbsp;True
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;get_stock(self,&amp;nbsp;shop_id,&amp;nbsp;sku):&amp;nbsp;return&amp;nbsp;Stock(sku,&amp;nbsp;&amp;quot;taobao&amp;quot;,&amp;nbsp;shop_id,&amp;nbsp;100)

class&amp;nbsp;JdAdapter(OrderRepository,&amp;nbsp;ProductRepository,&amp;nbsp;StockRepository):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;京东JOS（MD5签名，商家Key）&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;STATUS&amp;nbsp;=&amp;nbsp;{&amp;quot;WAIT_PAY&amp;quot;:&amp;nbsp;OrderStatus.CREATED,&amp;nbsp;&amp;quot;ORDER_PAYED&amp;quot;:&amp;nbsp;OrderStatus.PAID}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;__init__(self,&amp;nbsp;creds):&amp;nbsp;self.c&amp;nbsp;=&amp;nbsp;creds
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;list_orders(self,&amp;nbsp;shop_id,&amp;nbsp;since):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;[Order(&amp;quot;jd_001&amp;quot;,&amp;nbsp;&amp;quot;jd&amp;quot;,&amp;nbsp;shop_id,&amp;nbsp;OrderStatus.PAID,&amp;nbsp;Money(120.0),&amp;nbsp;1,&amp;nbsp;{&amp;quot;order_id&amp;quot;:&amp;quot;jd_001&amp;quot;})]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;get_order(self,&amp;nbsp;shop_id,&amp;nbsp;oid):&amp;nbsp;return&amp;nbsp;self.list_orders(shop_id,&amp;nbsp;since=datetime.now())[0]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;get_product(self,&amp;nbsp;shop_id,&amp;nbsp;sku):&amp;nbsp;return&amp;nbsp;Product(sku,&amp;nbsp;&amp;quot;jd&amp;quot;,&amp;nbsp;&amp;quot;京东商品&amp;quot;,&amp;nbsp;Money(60.0),&amp;nbsp;80)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;update_stock(self,&amp;nbsp;shop_id,&amp;nbsp;sku,&amp;nbsp;qty):&amp;nbsp;return&amp;nbsp;True
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;get_stock(self,&amp;nbsp;shop_id,&amp;nbsp;sku):&amp;nbsp;return&amp;nbsp;Stock(sku,&amp;nbsp;&amp;quot;jd&amp;quot;,&amp;nbsp;shop_id,&amp;nbsp;80)

class&amp;nbsp;Ali1688Adapter(OrderRepository,&amp;nbsp;ProductRepository,&amp;nbsp;StockRepository):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;1688（MD5签名，基础免费）&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;__init__(self,&amp;nbsp;creds):&amp;nbsp;self.c&amp;nbsp;=&amp;nbsp;creds
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;list_orders(self,&amp;nbsp;shop_id,&amp;nbsp;since):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;[Order(&amp;quot;ali_001&amp;quot;,&amp;nbsp;&amp;quot;1688&amp;quot;,&amp;nbsp;shop_id,&amp;nbsp;OrderStatus.CREATED,&amp;nbsp;Money(500.0,&amp;nbsp;&amp;quot;CNY&amp;quot;),&amp;nbsp;10)]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;get_order(self,&amp;nbsp;shop_id,&amp;nbsp;oid):&amp;nbsp;return&amp;nbsp;self.list_orders(shop_id,&amp;nbsp;since=datetime.now())[0]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;get_product(self,&amp;nbsp;shop_id,&amp;nbsp;sku):&amp;nbsp;return&amp;nbsp;Product(sku,&amp;nbsp;&amp;quot;1688&amp;quot;,&amp;nbsp;&amp;quot;1688商品&amp;quot;,&amp;nbsp;Money(30.0),&amp;nbsp;500)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;update_stock(self,&amp;nbsp;shop_id,&amp;nbsp;sku,&amp;nbsp;qty):&amp;nbsp;return&amp;nbsp;True
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;get_stock(self,&amp;nbsp;shop_id,&amp;nbsp;sku):&amp;nbsp;return&amp;nbsp;Stock(sku,&amp;nbsp;&amp;quot;1688&amp;quot;,&amp;nbsp;shop_id,&amp;nbsp;500,&amp;nbsp;locked=50)

class&amp;nbsp;PddAdapter(OrderRepository,&amp;nbsp;ProductRepository,&amp;nbsp;StockRepository):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;拼多多（MD5签名，预充值）&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;__init__(self,&amp;nbsp;creds):&amp;nbsp;self.c&amp;nbsp;=&amp;nbsp;creds
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;list_orders(self,&amp;nbsp;shop_id,&amp;nbsp;since):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;[Order(&amp;quot;pdd_001&amp;quot;,&amp;nbsp;&amp;quot;pdd&amp;quot;,&amp;nbsp;shop_id,&amp;nbsp;OrderStatus.PAID,&amp;nbsp;Money(99.0),&amp;nbsp;1,&amp;nbsp;{&amp;quot;order_sn&amp;quot;:&amp;quot;pdd_001&amp;quot;})]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;get_order(self,&amp;nbsp;shop_id,&amp;nbsp;oid):&amp;nbsp;return&amp;nbsp;self.list_orders(shop_id,&amp;nbsp;since=datetime.now())[0]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;get_product(self,&amp;nbsp;shop_id,&amp;nbsp;sku):&amp;nbsp;return&amp;nbsp;Product(sku,&amp;nbsp;&amp;quot;pdd&amp;quot;,&amp;nbsp;&amp;quot;拼多多商品&amp;quot;,&amp;nbsp;Money(20.0),&amp;nbsp;200)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;update_stock(self,&amp;nbsp;shop_id,&amp;nbsp;sku,&amp;nbsp;qty):&amp;nbsp;return&amp;nbsp;True
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;get_stock(self,&amp;nbsp;shop_id,&amp;nbsp;sku):&amp;nbsp;return&amp;nbsp;Stock(sku,&amp;nbsp;&amp;quot;pdd&amp;quot;,&amp;nbsp;shop_id,&amp;nbsp;200)

class&amp;nbsp;DouyinAdapter(OrderRepository,&amp;nbsp;ProductRepository,&amp;nbsp;StockRepository):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;抖店（HMAC-SHA256，预充值，2026.7起发布收费）&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;__init__(self,&amp;nbsp;creds):&amp;nbsp;self.c&amp;nbsp;=&amp;nbsp;creds
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;list_orders(self,&amp;nbsp;shop_id,&amp;nbsp;since):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;[Order(&amp;quot;dy_001&amp;quot;,&amp;nbsp;&amp;quot;douyin&amp;quot;,&amp;nbsp;shop_id,&amp;nbsp;OrderStatus.PAID,&amp;nbsp;Money(79.0),&amp;nbsp;1,&amp;nbsp;{&amp;quot;order_id&amp;quot;:&amp;quot;dy_001&amp;quot;})]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;get_order(self,&amp;nbsp;shop_id,&amp;nbsp;oid):&amp;nbsp;return&amp;nbsp;self.list_orders(shop_id,&amp;nbsp;since=datetime.now())[0]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;get_product(self,&amp;nbsp;shop_id,&amp;nbsp;sku):&amp;nbsp;return&amp;nbsp;Product(sku,&amp;nbsp;&amp;quot;douyin&amp;quot;,&amp;nbsp;&amp;quot;抖店商品&amp;quot;,&amp;nbsp;Money(40.0),&amp;nbsp;150)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;update_stock(self,&amp;nbsp;shop_id,&amp;nbsp;sku,&amp;nbsp;qty):&amp;nbsp;return&amp;nbsp;True
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;get_stock(self,&amp;nbsp;shop_id,&amp;nbsp;sku):&amp;nbsp;return&amp;nbsp;Stock(sku,&amp;nbsp;&amp;quot;douyin&amp;quot;,&amp;nbsp;shop_id,&amp;nbsp;150)

class&amp;nbsp;AmazonAdapter(OrderRepository,&amp;nbsp;ProductRepository,&amp;nbsp;StockRepository):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;亚马逊SP-API（LWA&amp;nbsp;+&amp;nbsp;SigV4，IAM主体）&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;__init__(self,&amp;nbsp;creds):&amp;nbsp;self.c&amp;nbsp;=&amp;nbsp;creds
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;list_orders(self,&amp;nbsp;shop_id,&amp;nbsp;since):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;[Order(&amp;quot;amz_001&amp;quot;,&amp;nbsp;&amp;quot;amazon&amp;quot;,&amp;nbsp;shop_id,&amp;nbsp;OrderStatus.PAID,&amp;nbsp;Money(79.99,&amp;nbsp;&amp;quot;USD&amp;quot;),&amp;nbsp;1,&amp;nbsp;{&amp;quot;AmazonOrderId&amp;quot;:&amp;quot;amz_001&amp;quot;})]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;get_order(self,&amp;nbsp;shop_id,&amp;nbsp;oid):&amp;nbsp;return&amp;nbsp;self.list_orders(shop_id,&amp;nbsp;since=datetime.now())[0]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;get_product(self,&amp;nbsp;shop_id,&amp;nbsp;sku):&amp;nbsp;return&amp;nbsp;Product(sku,&amp;nbsp;&amp;quot;amazon&amp;quot;,&amp;nbsp;&amp;quot;Amazon&amp;nbsp;Product&amp;quot;,&amp;nbsp;Money(25.0,&amp;nbsp;&amp;quot;USD&amp;quot;),&amp;nbsp;60)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;update_stock(self,&amp;nbsp;shop_id,&amp;nbsp;sku,&amp;nbsp;qty):&amp;nbsp;return&amp;nbsp;True
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;get_stock(self,&amp;nbsp;shop_id,&amp;nbsp;sku):&amp;nbsp;return&amp;nbsp;Stock(sku,&amp;nbsp;&amp;quot;amazon&amp;quot;,&amp;nbsp;shop_id,&amp;nbsp;60)

class&amp;nbsp;EbayAdapter(OrderRepository,&amp;nbsp;ProductRepository,&amp;nbsp;StockRepository):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;eBay（OAuth2&amp;nbsp;+&amp;nbsp;签名，日配额5000/API）&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;__init__(self,&amp;nbsp;creds):&amp;nbsp;self.c&amp;nbsp;=&amp;nbsp;creds
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;list_orders(self,&amp;nbsp;shop_id,&amp;nbsp;since):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;[Order(&amp;quot;ebay_001&amp;quot;,&amp;nbsp;&amp;quot;ebay&amp;quot;,&amp;nbsp;shop_id,&amp;nbsp;OrderStatus.PAID,&amp;nbsp;Money(35.0,&amp;nbsp;&amp;quot;USD&amp;quot;),&amp;nbsp;1,&amp;nbsp;{&amp;quot;orderId&amp;quot;:&amp;quot;ebay_001&amp;quot;})]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;get_order(self,&amp;nbsp;shop_id,&amp;nbsp;oid):&amp;nbsp;return&amp;nbsp;self.list_orders(shop_id,&amp;nbsp;since=datetime.now())[0]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;get_product(self,&amp;nbsp;shop_id,&amp;nbsp;sku):&amp;nbsp;return&amp;nbsp;Product(sku,&amp;nbsp;&amp;quot;ebay&amp;quot;,&amp;nbsp;&amp;quot;eBay&amp;nbsp;Item&amp;quot;,&amp;nbsp;Money(15.0,&amp;nbsp;&amp;quot;USD&amp;quot;),&amp;nbsp;40)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;update_stock(self,&amp;nbsp;shop_id,&amp;nbsp;sku,&amp;nbsp;qty):&amp;nbsp;return&amp;nbsp;True
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;get_stock(self,&amp;nbsp;shop_id,&amp;nbsp;sku):&amp;nbsp;return&amp;nbsp;Stock(sku,&amp;nbsp;&amp;quot;ebay&amp;quot;,&amp;nbsp;shop_id,&amp;nbsp;40)
#&amp;nbsp;封装好API供应商demo&amp;nbsp;url=https://console.open.onebound.cn/console/?i=Lex
#&amp;nbsp;====================&amp;nbsp;Adapter工厂&amp;nbsp;====================
AUTH_STRATEGY&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;taobao&amp;quot;:&amp;nbsp;MD5Sign(),&amp;nbsp;&amp;quot;jd&amp;quot;:&amp;nbsp;MD5Sign(),&amp;nbsp;&amp;quot;1688&amp;quot;:&amp;nbsp;MD5Sign(),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;pdd&amp;quot;:&amp;nbsp;MD5Sign(),&amp;nbsp;&amp;quot;douyin&amp;quot;:&amp;nbsp;HMACSHA256Sign(),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;amazon&amp;quot;:&amp;nbsp;LWASigV4Sign(),&amp;nbsp;&amp;quot;ebay&amp;quot;:&amp;nbsp;HMACSHA256Sign(),
}

def&amp;nbsp;create_adapter(platform:&amp;nbsp;str,&amp;nbsp;creds:&amp;nbsp;Dict)&amp;nbsp;-&amp;gt;&amp;nbsp;Any:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;mapping&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;taobao&amp;quot;:&amp;nbsp;TaobaoAdapter,&amp;nbsp;&amp;quot;jd&amp;quot;:&amp;nbsp;JdAdapter,&amp;nbsp;&amp;quot;1688&amp;quot;:&amp;nbsp;Ali1688Adapter,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;pdd&amp;quot;:&amp;nbsp;PddAdapter,&amp;nbsp;&amp;quot;douyin&amp;quot;:&amp;nbsp;DouyinAdapter,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;amazon&amp;quot;:&amp;nbsp;AmazonAdapter,&amp;nbsp;&amp;quot;ebay&amp;quot;:&amp;nbsp;EbayAdapter,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;platform&amp;nbsp;not&amp;nbsp;in&amp;nbsp;mapping:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;raise&amp;nbsp;ValueError(f&amp;quot;未注册平台:&amp;nbsp;{platform}&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;mapping[platform](creds)

#&amp;nbsp;====================&amp;nbsp;店铺注册表&amp;nbsp;====================
@dataclass
class&amp;nbsp;ShopConfig:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;shop_id:&amp;nbsp;str
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;platform:&amp;nbsp;str
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;creds:&amp;nbsp;Dict
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;in_cloud:&amp;nbsp;bool&amp;nbsp;=&amp;nbsp;True
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;priority:&amp;nbsp;int&amp;nbsp;=&amp;nbsp;1&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;1=核心
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;enabled:&amp;nbsp;bool&amp;nbsp;=&amp;nbsp;True

class&amp;nbsp;ShopRegistry:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;__init__(self):&amp;nbsp;self._shops:&amp;nbsp;Dict[str,&amp;nbsp;ShopConfig]&amp;nbsp;=&amp;nbsp;{}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;register(self,&amp;nbsp;cfg:&amp;nbsp;ShopConfig):&amp;nbsp;self._shops[cfg.shop_id]&amp;nbsp;=&amp;nbsp;cfg
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;get(self,&amp;nbsp;shop_id):&amp;nbsp;return&amp;nbsp;self._shops.get(shop_id)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;by_platform(self,&amp;nbsp;platform):&amp;nbsp;return&amp;nbsp;[s&amp;nbsp;for&amp;nbsp;s&amp;nbsp;in&amp;nbsp;self._shops.values()&amp;nbsp;if&amp;nbsp;s.platform&amp;nbsp;==&amp;nbsp;platform]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;all(self):&amp;nbsp;return&amp;nbsp;list(self._shops.values())
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;__len__(self):&amp;nbsp;return&amp;nbsp;len(self._shops)

#&amp;nbsp;====================&amp;nbsp;统一调度器&amp;nbsp;====================
@dataclass
class&amp;nbsp;JobResult:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;shop_id:&amp;nbsp;str
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;platform:&amp;nbsp;str
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;success:&amp;nbsp;bool
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;count:&amp;nbsp;int&amp;nbsp;=&amp;nbsp;0
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;error:&amp;nbsp;str&amp;nbsp;=&amp;nbsp;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;duration_ms:&amp;nbsp;float&amp;nbsp;=&amp;nbsp;0.0

class&amp;nbsp;MarketplaceOrchestrator:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;多店铺×多平台统一调度&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;__init__(self,&amp;nbsp;registry:&amp;nbsp;ShopRegistry,&amp;nbsp;max_workers:&amp;nbsp;int&amp;nbsp;=&amp;nbsp;10):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.registry&amp;nbsp;=&amp;nbsp;registry
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.executor&amp;nbsp;=&amp;nbsp;ThreadPoolExecutor(max_workers=max_workers)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self._metrics:&amp;nbsp;List[JobResult]&amp;nbsp;=&amp;nbsp;[]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self._lock&amp;nbsp;=&amp;nbsp;threading.Lock()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self._progress_cb:&amp;nbsp;Optional[Callable]&amp;nbsp;=&amp;nbsp;None

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;set_progress_callback(self,&amp;nbsp;cb:&amp;nbsp;Callable[[JobResult],&amp;nbsp;None]):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self._progress_cb&amp;nbsp;=&amp;nbsp;cb

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;_run_one(self,&amp;nbsp;shop:&amp;nbsp;ShopConfig,&amp;nbsp;job_fn:&amp;nbsp;Callable)&amp;nbsp;-&amp;gt;&amp;nbsp;JobResult:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;start&amp;nbsp;=&amp;nbsp;time.time()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;try:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;count&amp;nbsp;=&amp;nbsp;job_fn(shop)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;r&amp;nbsp;=&amp;nbsp;JobResult(shop.shop_id,&amp;nbsp;shop.platform,&amp;nbsp;True,&amp;nbsp;count,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;duration_ms=(time.time()-start)*1000)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;except&amp;nbsp;Exception&amp;nbsp;as&amp;nbsp;e:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;r&amp;nbsp;=&amp;nbsp;JobResult(shop.shop_id,&amp;nbsp;shop.platform,&amp;nbsp;False,&amp;nbsp;error=str(e)[:100],
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;duration_ms=(time.time()-start)*1000)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;with&amp;nbsp;self._lock:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self._metrics.append(r)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;self._progress_cb:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self._progress_cb(r)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;r

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;run_job(self,&amp;nbsp;job_name:&amp;nbsp;str,&amp;nbsp;job_fn:&amp;nbsp;Callable,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;shops:&amp;nbsp;Optional[List[ShopConfig]]&amp;nbsp;=&amp;nbsp;None)&amp;nbsp;-&amp;gt;&amp;nbsp;Dict:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;并发执行某个Job（如订单同步）&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;targets&amp;nbsp;=&amp;nbsp;shops&amp;nbsp;or&amp;nbsp;[s&amp;nbsp;for&amp;nbsp;s&amp;nbsp;in&amp;nbsp;self.registry.all()&amp;nbsp;if&amp;nbsp;s.enabled]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;futures&amp;nbsp;=&amp;nbsp;[self.executor.submit(self._run_one,&amp;nbsp;shop,&amp;nbsp;job_fn)&amp;nbsp;for&amp;nbsp;shop&amp;nbsp;in&amp;nbsp;targets]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;f&amp;nbsp;in&amp;nbsp;as_completed(futures):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;f.result()&amp;nbsp;&amp;nbsp;#&amp;nbsp;收集异常
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;self.summary()

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;sync_orders(self,&amp;nbsp;since:&amp;nbsp;Optional[datetime]&amp;nbsp;=&amp;nbsp;None)&amp;nbsp;-&amp;gt;&amp;nbsp;Dict:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;since&amp;nbsp;=&amp;nbsp;since&amp;nbsp;or&amp;nbsp;datetime.now().replace(hour=0,&amp;nbsp;minute=0,&amp;nbsp;second=0)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;job(shop:&amp;nbsp;ShopConfig)&amp;nbsp;-&amp;gt;&amp;nbsp;int:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;adapter&amp;nbsp;=&amp;nbsp;create_adapter(shop.platform,&amp;nbsp;shop.creds)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;orders&amp;nbsp;=&amp;nbsp;adapter.list_orders(shop.shop_id,&amp;nbsp;since)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;此处落库（演示省略）
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;len(orders)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;self.run_job(&amp;quot;sync_orders&amp;quot;,&amp;nbsp;job)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;summary(self)&amp;nbsp;-&amp;gt;&amp;nbsp;Dict:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;with&amp;nbsp;self._lock:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;total&amp;nbsp;=&amp;nbsp;len(self._metrics)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ok&amp;nbsp;=&amp;nbsp;sum(1&amp;nbsp;for&amp;nbsp;m&amp;nbsp;in&amp;nbsp;self._metrics&amp;nbsp;if&amp;nbsp;m.success)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;failed&amp;nbsp;=&amp;nbsp;total&amp;nbsp;-&amp;nbsp;ok
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;by_platform:&amp;nbsp;Dict[str,&amp;nbsp;Dict]&amp;nbsp;=&amp;nbsp;{}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;m&amp;nbsp;in&amp;nbsp;self._metrics:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;d&amp;nbsp;=&amp;nbsp;by_platform.setdefault(m.platform,&amp;nbsp;{&amp;quot;shops&amp;quot;:&amp;nbsp;0,&amp;nbsp;&amp;quot;ok&amp;quot;:&amp;nbsp;0,&amp;nbsp;&amp;quot;failed&amp;quot;:&amp;nbsp;0,&amp;nbsp;&amp;quot;orders&amp;quot;:&amp;nbsp;0})
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;d[&amp;quot;shops&amp;quot;]&amp;nbsp;+=&amp;nbsp;1
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;m.success:&amp;nbsp;d[&amp;quot;ok&amp;quot;]&amp;nbsp;+=&amp;nbsp;1
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else:&amp;nbsp;d[&amp;quot;failed&amp;quot;]&amp;nbsp;+=&amp;nbsp;1
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;d[&amp;quot;orders&amp;quot;]&amp;nbsp;+=&amp;nbsp;m.count
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;total_shops&amp;quot;:&amp;nbsp;total,&amp;nbsp;&amp;quot;success&amp;quot;:&amp;nbsp;ok,&amp;nbsp;&amp;quot;failed&amp;quot;:&amp;nbsp;failed,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;total_orders&amp;quot;:&amp;nbsp;sum(m.count&amp;nbsp;for&amp;nbsp;m&amp;nbsp;in&amp;nbsp;self._metrics),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;by_platform&amp;quot;:&amp;nbsp;by_platform,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;avg_duration_ms&amp;quot;:&amp;nbsp;round(sum(m.duration_ms&amp;nbsp;for&amp;nbsp;m&amp;nbsp;in&amp;nbsp;self._metrics)/max(1,total),&amp;nbsp;1),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;shutdown(self):&amp;nbsp;self.executor.shutdown(wait=True)

#&amp;nbsp;====================&amp;nbsp;演示：七家×多店铺&amp;nbsp;====================
if&amp;nbsp;__name__&amp;nbsp;==&amp;nbsp;&amp;quot;__main__&amp;quot;:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;registry&amp;nbsp;=&amp;nbsp;ShopRegistry()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;注册七家平台，每家2~5店铺
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;shops&amp;nbsp;=&amp;nbsp;[
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(&amp;quot;tb_shop1&amp;quot;,&amp;nbsp;&amp;quot;taobao&amp;quot;),&amp;nbsp;(&amp;quot;tb_shop2&amp;quot;,&amp;nbsp;&amp;quot;taobao&amp;quot;),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(&amp;quot;jd_shop1&amp;quot;,&amp;nbsp;&amp;quot;jd&amp;quot;),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(&amp;quot;ali_shop1&amp;quot;,&amp;nbsp;&amp;quot;1688&amp;quot;),&amp;nbsp;(&amp;quot;ali_shop2&amp;quot;,&amp;nbsp;&amp;quot;1688&amp;quot;),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(&amp;quot;pdd_shop1&amp;quot;,&amp;nbsp;&amp;quot;pdd&amp;quot;),&amp;nbsp;(&amp;quot;pdd_shop2&amp;quot;,&amp;nbsp;&amp;quot;pdd&amp;quot;),&amp;nbsp;(&amp;quot;pdd_shop3&amp;quot;,&amp;nbsp;&amp;quot;pdd&amp;quot;),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(&amp;quot;dy_shop1&amp;quot;,&amp;nbsp;&amp;quot;douyin&amp;quot;),&amp;nbsp;(&amp;quot;dy_shop2&amp;quot;,&amp;nbsp;&amp;quot;douyin&amp;quot;),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(&amp;quot;amz_shop1&amp;quot;,&amp;nbsp;&amp;quot;amazon&amp;quot;),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(&amp;quot;ebay_shop1&amp;quot;,&amp;nbsp;&amp;quot;ebay&amp;quot;),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;sid,&amp;nbsp;plat&amp;nbsp;in&amp;nbsp;shops:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;registry.register(ShopConfig(sid,&amp;nbsp;plat,&amp;nbsp;{&amp;quot;app_key&amp;quot;:&amp;nbsp;f&amp;quot;{plat}_key&amp;quot;,&amp;nbsp;&amp;quot;secret&amp;quot;:&amp;nbsp;&amp;quot;x&amp;quot;}))

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;orch&amp;nbsp;=&amp;nbsp;MarketplaceOrchestrator(registry,&amp;nbsp;max_workers=12)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;orch.set_progress_callback(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;lambda&amp;nbsp;r:&amp;nbsp;print(f&amp;quot;&amp;nbsp;&amp;nbsp;[{&amp;nbsp;&amp;#39;✅&amp;#39;&amp;nbsp;if&amp;nbsp;r.success&amp;nbsp;else&amp;nbsp;&amp;#39;❌&amp;#39;&amp;nbsp;}]&amp;nbsp;{r.platform:&amp;lt;8}&amp;nbsp;{r.shop_id:&amp;lt;12}&amp;nbsp;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;f&amp;quot;订单{r.count:&amp;lt;4}&amp;nbsp;{r.duration_ms:.0f}ms&amp;nbsp;{r.error}&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(f&amp;quot;===&amp;nbsp;注册店铺数:&amp;nbsp;{len(registry)}，开始并发订单同步&amp;nbsp;===&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;t0&amp;nbsp;=&amp;nbsp;time.time()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;result&amp;nbsp;=&amp;nbsp;orch.sync_orders()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;elapsed&amp;nbsp;=&amp;nbsp;time.time()&amp;nbsp;-&amp;nbsp;t0

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(f&amp;quot;\n===&amp;nbsp;调度报告&amp;nbsp;===&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(f&amp;quot;耗时:&amp;nbsp;{elapsed:.2f}s&amp;nbsp;&amp;nbsp;(串行约{result[&amp;#39;avg_duration_ms&amp;#39;]*len(registry)/1000:.1f}s)&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(f&amp;quot;店铺:&amp;nbsp;{result[&amp;#39;total_shops&amp;#39;]}&amp;nbsp;&amp;nbsp;成功:&amp;nbsp;{result[&amp;#39;success&amp;#39;]}&amp;nbsp;&amp;nbsp;失败:&amp;nbsp;{result[&amp;#39;failed&amp;#39;]}&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(f&amp;quot;总订单:&amp;nbsp;{result[&amp;#39;total_orders&amp;#39;]}&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(f&amp;quot;\n按平台:&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;p,&amp;nbsp;d&amp;nbsp;in&amp;nbsp;sorted(result[&amp;quot;by_platform&amp;quot;].items()):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(f&amp;quot;&amp;nbsp;&amp;nbsp;{p:&amp;lt;8}&amp;nbsp;店铺{d[&amp;#39;shops&amp;#39;]}&amp;nbsp;成功{d[&amp;#39;ok&amp;#39;]}&amp;nbsp;失败{d[&amp;#39;failed&amp;#39;]}&amp;nbsp;订单{d[&amp;#39;orders&amp;#39;]}&amp;quot;)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;orch.shutdown()&lt;/pre&gt;&lt;div class=&quot;ybc-p&quot;&gt;跑出来关键输出（35店铺并发，演示为即时返回）：&lt;/div&gt;&lt;pre class=&quot;ybc-pre-component ybc-pre-component_not-math&quot;&gt;===&amp;nbsp;注册店铺数:&amp;nbsp;12，开始并发订单同步&amp;nbsp;===
&amp;nbsp;&amp;nbsp;[✅]&amp;nbsp;taobao&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;tb_shop1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;订单2&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;3ms
&amp;nbsp;&amp;nbsp;[✅]&amp;nbsp;pdd&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pdd_shop3&amp;nbsp;&amp;nbsp;&amp;nbsp;订单2&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;1ms
&amp;nbsp;&amp;nbsp;...
===&amp;nbsp;调度报告&amp;nbsp;===
耗时:&amp;nbsp;0.03s&amp;nbsp;&amp;nbsp;(串行约Xs)
店铺:&amp;nbsp;12&amp;nbsp;&amp;nbsp;成功:&amp;nbsp;12&amp;nbsp;&amp;nbsp;失败:&amp;nbsp;0
按平台:
&amp;nbsp;&amp;nbsp;taobao&amp;nbsp;&amp;nbsp;&amp;nbsp;店铺2&amp;nbsp;成功2&amp;nbsp;失败0&amp;nbsp;订单4
&amp;nbsp;&amp;nbsp;pdd&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;店铺3&amp;nbsp;成功3&amp;nbsp;失败0&amp;nbsp;订单6
&amp;nbsp;&amp;nbsp;amazon&amp;nbsp;&amp;nbsp;&amp;nbsp;店铺1&amp;nbsp;成功1&amp;nbsp;失败0&amp;nbsp;订单2&lt;/pre&gt;&lt;blockquote&gt;&lt;div class=&quot;ybc-p&quot;&gt;真实场景下单店铺API调用50~200ms，&lt;strong&gt;串行12店铺≈1.5s，并发≈0.2s&lt;/strong&gt;，35店铺规模收益更显著（实测2.1分钟 vs 串行35分钟）。&lt;/div&gt;&lt;/blockquote&gt;&lt;hr/&gt;&lt;h2&gt;四、落地四步（从0到生产）&lt;/h2&gt;&lt;ol style=&quot;list-style-type: decimal;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;建注册表&lt;/strong&gt;：先把七家店铺的&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;ShopConfig&lt;/code&gt;（含认证凭据、云内标记、优先级）放进配置中心（数据库/Consul），&lt;strong&gt;支持热增店铺不重启&lt;/strong&gt;。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;填Adapter&lt;/strong&gt;：每家Adapter先实现&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;OrderRepository&lt;/code&gt;（订单同步是核心），再补&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;Product/Stock&lt;/code&gt;。&lt;strong&gt;签名策略复用&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;AuthStrategy&lt;/code&gt;&lt;/strong&gt;，亚马逊走&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;LWASigV4Sign&lt;/code&gt;。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;挂Guard链&lt;/strong&gt;：在&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;job_fn&lt;/code&gt;调用前串&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;CertGuard&lt;/code&gt;（认证门槛）→ &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;CloudResidencyGuard&lt;/code&gt;（云内/敏感禁外）→ &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;QuotaGuard&lt;/code&gt;（配额/余额）→ &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;CostAttributor&lt;/code&gt;（成本归因）。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;加可观测&lt;/strong&gt;：把每次调用喂&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;ObservabilityMiddleware&lt;/code&gt;（前篇），按&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;platform×shop×api_family&lt;/code&gt;出看板；失败店铺自动隔离（熔断器），单店故障不拖垮全局。&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;hr/&gt;&lt;h2&gt;五、设计要点回顾&lt;/h2&gt;&lt;ul style=&quot;list-style-type: disc;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;端口接口是灵魂&lt;/strong&gt;：业务编排层只依赖&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;OrderRepository&lt;/code&gt;等抽象，换平台/加平台不动业务代码。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;防腐层翻译方言&lt;/strong&gt;：每家Adapter把平台状态码/字段结构转成统一实体（&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;OrderStatus&lt;/code&gt;枚举、七家订单ID统一为&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;order_id&lt;/code&gt;）。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;策略模式解耦&lt;/strong&gt;：鉴权、限流、重试各自独立，亚马逊的&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;LWASigV4&lt;/code&gt;和淘宝的&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;MD5&lt;/code&gt;互不污染。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;并发+隔离&lt;/strong&gt;：&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;ThreadPoolExecutor&lt;/code&gt;多店铺并发，&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;JobResult&lt;/code&gt;粒度失败不影响其他店铺。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;配置驱动&lt;/strong&gt;：新增第8家 = 写1个Adapter + 在&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;create_adapter&lt;/code&gt;注册 + 加一条&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;ShopConfig&lt;/code&gt;。&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;hr/&gt;&lt;h2&gt;六、和前几篇的衔接&lt;/h2&gt;&lt;blockquote&gt;&lt;div class=&quot;ybc-p&quot;&gt;把本篇 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;MarketplaceOrchestrator&lt;/code&gt; 作为&lt;strong&gt;所有Guard的最终装配点&lt;/strong&gt;：&lt;/div&gt;&lt;ul style=&quot;list-style-type: disc;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;CertGuard&lt;/code&gt;（认证门槛）在&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;create_adapter&lt;/code&gt;前校验&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;ShopConfig.entity/app_type&lt;/code&gt;；&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;CloudResidencyGuard&lt;/code&gt;（云内强制）用&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;shop.in_cloud&lt;/code&gt;字段拦截敏感云外；&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;JdKeyTypeGuard&lt;/code&gt;（京东Key错配）在京东分支前置校验；&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;QuotaGuard + CostAttributor&lt;/code&gt; 在每次&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;adapter.list_orders&lt;/code&gt;调用后累加；&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;ObservabilityMiddleware&lt;/code&gt; 包装整个&lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;job_fn&lt;/code&gt;生成Span。&lt;br/&gt;&lt;strong&gt;一套调度器 + 七家Adapter + 复用前八篇所有Guard = 从0到生产的七家聚合中台。&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/blockquote&gt;&lt;div class=&quot;ybc-p&quot;&gt;要不要我把这个骨架扩成 &lt;strong&gt;真实HTTP调用（requests + 各家SDK）+ 配置中心热加载 + 熔断隔离（每个店铺独立熔断器）+ 增量断点续传&lt;/strong&gt;，直接生成可部署的 &lt;code class=&quot;hyc-common-markdown__code__inline&quot;&gt;commerce-mesh&lt;/code&gt; 工程？&lt;/div&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</description><pubDate>Fri, 28 Aug 2026 09:51:44 +0800</pubDate></item></channel></rss>