feat(fulfillment): 接入Rock发货平台(0666.pro)代理履约、通用库存池与UID强一致风控

1. 数据库新增 012_rock_fulfillment 迁移,创建 rock_configs 配置表与 rock_tokens 通用库存表,补齐黑色ROCK长袖T恤与蓝色运动服上衣商品目录;
2. 封装 RockClient 与 RockService,实现 0666.pro 平台 Bearer Token 极简连通校验、批量采购50个入库、水位监控巡检与自动补货;
3. 新增 RockProvider 实现标准履约路由,引入 Anti-Ghost 旧绑定基线比对与 UID 强一致门禁,扫错号硬阻断并记录为 mismatch 状态;
4. 针对黑色ROCK与蓝色运动服实现动态发货(绑定后发货前动态选择 skin),并提取腾讯官方发货流水号 fulfillId 对账;
5. 新增全局自动发货总开关(Kill Switch),支持一键软熔断降级转人工接单处理;
6. 前端新增 PlatformRock 管理大屏,提供总开关切换、Token配置与连通测试、库存监控、一键补货及错单解冻重置。
This commit is contained in:
yml2213
2026-10-05 14:56:11 +08:00
parent 46ec3574ae
commit ef7f67dd0c
16 changed files with 3421 additions and 2 deletions
+67
View File
@@ -252,4 +252,71 @@ export const lewanApi = {
request.put(`/platform/products/${id}/routing`, data).then((r) => r.data.data as { updated: boolean }),
}
export interface RockConfig {
id: number
auto_delivery_enabled: boolean
base_url: string
bearer_token: string
username: string
points: number
min_points_warning: number
token_warning_stock: number
auto_purchase_enabled: boolean
auto_purchase_count: number
purchase_cooldown_minutes: number
last_purchased_at?: string
last_heartbeat_at?: string
}
export interface RockStats {
available_stock: number
using_stock: number
bound_stock: number
redeemed_stock: number
mismatch_stock: number
abnormal_stock: number
upstream_points: number
auto_delivery_enabled: boolean
token_warning_stock: number
auto_purchase_enabled: boolean
username: string
last_heartbeat_at?: string
}
export interface RockTokenItem {
id: number
upstream_token_id: string
redeem_code: string
color: string
region: string
status: string
assigned_order_no?: string
expected_uid?: string
actual_role_name?: string
actual_role_id?: string
actual_channel?: string
upstream_fulfill_id?: number
target_skin?: string
target_currency?: string
target_currency_quantity?: number
mismatch_at?: string
mismatch_reason?: string
claimed_at?: string
bound_at?: string
redeemed_at?: string
created_at: string
}
export const rockApi = {
getConfig: () => request.get('/platform/rock/config').then((r) => r.data.data as RockConfig),
updateConfig: (data: Partial<RockConfig>) => request.put('/platform/rock/config', data).then((r) => r.data.data as RockConfig),
testConnection: (bearer_token?: string) => request.post('/platform/rock/test-conn', { bearer_token }).then((r) => r.data.data),
getStats: () => request.get('/platform/rock/stats').then((r) => r.data.data as RockStats),
purchaseTokens: (count = 50) => request.post('/platform/rock/purchase', { count }).then((r) => r.data.data),
listTokens: (params?: { page?: number; page_size?: number; status?: string; search?: string }) =>
request.get('/platform/rock/tokens', { params }).then((r) => r.data.data as { list: RockTokenItem[]; total: number; page: number; page_size: number }),
resetToken: (id: number) => request.post(`/platform/rock/tokens/${id}/reset`).then((r) => r.data.data),
}