feat(pdd): 支持根据数据库已有订单自适应翻页拉取,防高峰漏单

1. 新增数据库批量排查已有订单接口 findExistingPlatformOrderIds,利用 B-Tree 索引毫秒级判定当前页订单是否存在;
2. 优化 syncStoreOrders 支持自适应翻页拉取:当第 1 页全部为新订单时,自适应向后递增翻页拉取(支持 maxPages 默认 5 页,平滑限速 300ms);
3. 翻页终止自适应判定:当拉取到包含数据库已有旧订单的页面时立即 break 停止翻页,兼顾高性能与不漏单;
4. 扩展全局配置支持 maxPages(自适应最大翻页页数),支持后台管理员在 UI 设置与立即拉单参数联动;
5. 新增单元测试 pdd-sync-service.test.ts,验证全部新订单自适应翻页与命中已有订单提前终止行为。
This commit is contained in:
yml2213
2026-09-12 16:25:37 +08:00
parent 1217da7393
commit ede9a87b97
9 changed files with 405 additions and 78 deletions
@@ -98,6 +98,7 @@ export function PddPlatformPanel() {
pollIntervalSeconds: 20,
orderType: 2,
pageSize: 50,
maxPages: 5,
stores: [],
})
@@ -168,6 +169,7 @@ export function PddPlatformPanel() {
try {
const response = await triggerAdminPddSync({
pageSize: config.pageSize || 50,
maxPages: config.maxPages || 5,
orderType: config.orderType ?? 2,
})
const data = response?.data as AdminPddSyncAllResponse | undefined
@@ -201,12 +203,14 @@ export function PddPlatformPanel() {
const response = await triggerAdminPddSync({
shopId: store.shopId,
pageSize: config.pageSize || 50,
maxPages: config.maxPages || 5,
orderType: config.orderType ?? 2,
})
const data = response?.data as AdminPddSyncResult | undefined
if (data) {
const pagesText = data.pagesFetched && data.pagesFetched > 1 ? `(自适应拉取 ${data.pagesFetched} 页)` : ""
showSuccess(
`店铺【${store.shopName}】同步完成:抓取 ${data.fetchedCount} 笔,入库/更新 ${data.upsertedCount} 笔`,
`店铺【${store.shopName}】同步完成${pagesText}:抓取 ${data.fetchedCount} 笔,入库/更新 ${data.upsertedCount} 笔`,
)
} else {
showSuccess(`店铺【${store.shopName}】同步已触发`)
@@ -786,8 +790,8 @@ export function PddPlatformPanel() {
</Space>
}
>
<Row gutter={[24, 16]} align="middle">
<Col xs={24} sm={12} md={6}>
<Row gutter={[16, 16]} align="middle">
<Col xs={24} sm={12} md={4}>
<Space direction="vertical" size={4}>
<Text strong>自动拉单调度状态</Text>
<Space align="center">
@@ -802,7 +806,7 @@ export function PddPlatformPanel() {
</Space>
</Col>
<Col xs={24} sm={12} md={6}>
<Col xs={24} sm={12} md={5}>
<Space direction="vertical" size={4} style={{ width: '100%' }}>
<Text strong>抓取订单状态</Text>
<Select
@@ -818,7 +822,7 @@ export function PddPlatformPanel() {
</Space>
</Col>
<Col xs={24} sm={12} md={6}>
<Col xs={24} sm={12} md={5}>
<Space direction="vertical" size={4} style={{ width: '100%' }}>
<Text strong>错峰轮询间隔</Text>
<InputNumber
@@ -837,14 +841,14 @@ export function PddPlatformPanel() {
</Space>
</Col>
<Col xs={24} sm={12} md={6}>
<Col xs={24} sm={12} md={5}>
<Space direction="vertical" size={4} style={{ width: '100%' }}>
<Text strong>单次拉单上限 (pageSize)</Text>
<Text strong>单页拉单数 (pageSize)</Text>
<InputNumber
min={10}
max={100}
style={{ width: '100%' }}
addonAfter="单/次"
addonAfter="单/页"
value={config.pageSize ?? 50}
onChange={(val) =>
setConfig((prev) => ({
@@ -855,6 +859,25 @@ export function PddPlatformPanel() {
/>
</Space>
</Col>
<Col xs={24} sm={12} md={5}>
<Space direction="vertical" size={4} style={{ width: '100%' }}>
<Text strong>自适应翻页上限 (maxPages)</Text>
<InputNumber
min={1}
max={20}
style={{ width: '100%' }}
addonAfter="页"
value={config.maxPages ?? 5}
onChange={(val) =>
setConfig((prev) => ({
...prev,
maxPages: Number(val || 5),
}))
}
/>
</Space>
</Col>
</Row>
<Alert
@@ -863,8 +886,9 @@ export function PddPlatformPanel() {
style={{ marginTop: 14 }}
message={
<span>
当前拉单规则:默认抓取<strong>【{orderTypeDesc}】</strong>订单,单次拉取最新
<strong>【{config.pageSize || 50}】</strong>单并持久化记录校验状态。
当前拉单规则:默认抓取<strong>【{orderTypeDesc}】</strong>订单,单页拉取最新
<strong>【{config.pageSize || 50}】</strong>单;已启用<strong>【自适应翻页拉取】</strong>(上限
<strong>【{config.maxPages || 5}】</strong>页),当第 1 页全为新订单时自动向后翻页直至命中数据库已有订单,避免高峰期漏单。
</span>
}
description="系统自动保存每家店铺上次 Cookie 的测活状态与时间戳。若在定时轮询或手动测试中检测到 Cookie 失效(或触发登录过期),系统将自动更新状态并向 Bark / Wpush 发送内部告警通知。"
@@ -42,7 +42,7 @@ export function testAdminPddCookie(payload: {
}
export function triggerAdminPddSync(
payload: { shopId?: string; pageSize?: number; orderType?: number } = {},
payload: { shopId?: string; pageSize?: number; maxPages?: number; orderType?: number } = {},
) {
return apiPost<AdminPddSyncAllResponse | AdminPddSyncResult>(
'/api/v1/admin/platform-config/pdd/sync',
@@ -22,6 +22,7 @@ export interface AdminPddConfig {
pollIntervalSeconds: number
orderType?: number // 0: 全部, 1: 待发货, 2: 已发货 (默认 2)
pageSize?: number // 单次拉取单数 (默认 50)
maxPages?: number // 自适应最大翻页数 (默认 5)
stores: AdminPddStoreItem[]
}
@@ -40,6 +41,7 @@ export interface AdminPddSyncResult {
upsertedCount: number
ignoredCount: number
failedCount: number
pagesFetched?: number
error?: string
}