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:
@@ -0,0 +1,110 @@
|
||||
-- ============================================================================
|
||||
-- 012_rock_fulfillment.sql: Rock 发货平台 (0666.pro) 代理接入与库存风控数据表与商品目录
|
||||
-- ============================================================================
|
||||
|
||||
-- 1) Rock 平台系统配置表
|
||||
CREATE TABLE IF NOT EXISTS rock_configs (
|
||||
id BIGINT PRIMARY KEY DEFAULT 1,
|
||||
auto_delivery_enabled BOOLEAN NOT NULL DEFAULT true,
|
||||
base_url VARCHAR(255) NOT NULL DEFAULT 'https://0666.pro',
|
||||
bearer_token TEXT NOT NULL DEFAULT '',
|
||||
username VARCHAR(128) NOT NULL DEFAULT '',
|
||||
points NUMERIC(12, 2) NOT NULL DEFAULT 0.00,
|
||||
min_points_warning NUMERIC(12, 2) NOT NULL DEFAULT 1050.00,
|
||||
token_warning_stock INT NOT NULL DEFAULT 10,
|
||||
auto_purchase_enabled BOOLEAN NOT NULL DEFAULT false,
|
||||
auto_purchase_count INT NOT NULL DEFAULT 50,
|
||||
purchase_cooldown_minutes INT NOT NULL DEFAULT 10,
|
||||
last_purchased_at TIMESTAMPTZ,
|
||||
last_heartbeat_at TIMESTAMPTZ,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
-- 初始化默认配置行(固定 ID=1)
|
||||
INSERT INTO rock_configs (id, auto_delivery_enabled, base_url, bearer_token, min_points_warning, token_warning_stock, auto_purchase_enabled, auto_purchase_count)
|
||||
VALUES (1, true, 'https://0666.pro', '', 1050.00, 10, false, 50)
|
||||
ON CONFLICT (id) DO NOTHING;
|
||||
|
||||
-- 2) Rock 通用 Token 本地库存池表
|
||||
CREATE TABLE IF NOT EXISTS rock_tokens (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
upstream_token_id VARCHAR(64) NOT NULL DEFAULT '',
|
||||
token TEXT NOT NULL,
|
||||
redeem_code VARCHAR(64) NOT NULL,
|
||||
color VARCHAR(32) NOT NULL DEFAULT 'black',
|
||||
region VARCHAR(64) NOT NULL DEFAULT 'Q/V可用',
|
||||
status VARCHAR(32) NOT NULL DEFAULT 'available',
|
||||
assigned_order_no VARCHAR(128),
|
||||
expected_uid VARCHAR(64),
|
||||
actual_role_name VARCHAR(128),
|
||||
actual_role_id VARCHAR(64),
|
||||
actual_channel VARCHAR(64),
|
||||
initial_bound_snapshot TEXT,
|
||||
upstream_fulfill_id BIGINT,
|
||||
target_skin VARCHAR(128),
|
||||
target_currency VARCHAR(64) NOT NULL DEFAULT '幸运币',
|
||||
target_currency_quantity INT NOT NULL DEFAULT 0,
|
||||
mismatch_at TIMESTAMPTZ,
|
||||
mismatch_reason VARCHAR(255),
|
||||
claimed_at TIMESTAMPTZ,
|
||||
bound_at TIMESTAMPTZ,
|
||||
redeemed_at TIMESTAMPTZ,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_rock_tokens_status_color ON rock_tokens (status, color);
|
||||
CREATE INDEX IF NOT EXISTS idx_rock_tokens_assigned_order ON rock_tokens (assigned_order_no);
|
||||
CREATE INDEX IF NOT EXISTS idx_rock_tokens_redeem_code ON rock_tokens (redeem_code);
|
||||
CREATE INDEX IF NOT EXISTS idx_rock_tokens_mismatch ON rock_tokens (status, mismatch_at);
|
||||
|
||||
-- 3) 插入 Rock 皮肤到商品目录 (products 表与自营 merchant_products 表)
|
||||
WITH rock_products(sku, name, category, default_price, fulfillment_config) AS (
|
||||
VALUES
|
||||
('rock_black_tshirt', '黑色ROCK长袖T恤', '服饰', 2500, '{"routing_mode":"rock","priority":["rock"],"delivery_type":"LINK_BINDING"}'),
|
||||
('rock_blue_sportswear', '蓝色运动服上衣', '服饰', 2500, '{"routing_mode":"rock","priority":["rock"],"delivery_type":"LINK_BINDING"}')
|
||||
)
|
||||
INSERT INTO products (code, name, category, status)
|
||||
SELECT p.sku, p.name, p.category, 'active'
|
||||
FROM rock_products p
|
||||
ON CONFLICT (code) DO UPDATE
|
||||
SET
|
||||
name = EXCLUDED.name,
|
||||
category = EXCLUDED.category,
|
||||
status = 'active';
|
||||
|
||||
WITH rock_products(sku, name, category, default_price, fulfillment_config) AS (
|
||||
VALUES
|
||||
('rock_black_tshirt', '黑色ROCK长袖T恤', '服饰', 2500, '{"routing_mode":"rock","priority":["rock"],"delivery_type":"LINK_BINDING"}'),
|
||||
('rock_blue_sportswear', '蓝色运动服上衣', '服饰', 2500, '{"routing_mode":"rock","priority":["rock"],"delivery_type":"LINK_BINDING"}')
|
||||
),
|
||||
self_merchant AS (
|
||||
SELECT id FROM merchants WHERE code = 'self-operated' LIMIT 1
|
||||
)
|
||||
INSERT INTO merchant_products (
|
||||
merchant_id, product_id, sku, display_name,
|
||||
price_amount, cost_amount, currency, stock, status, fulfillment_config
|
||||
)
|
||||
SELECT
|
||||
sm.id,
|
||||
p.id,
|
||||
rp.sku,
|
||||
rp.name,
|
||||
rp.default_price,
|
||||
rp.default_price,
|
||||
'POINT',
|
||||
-1,
|
||||
'active',
|
||||
rp.fulfillment_config
|
||||
FROM rock_products rp
|
||||
JOIN products p ON p.code = rp.sku
|
||||
CROSS JOIN self_merchant sm
|
||||
ON CONFLICT (merchant_id, sku) DO UPDATE
|
||||
SET
|
||||
display_name = EXCLUDED.display_name,
|
||||
price_amount = EXCLUDED.price_amount,
|
||||
cost_amount = EXCLUDED.cost_amount,
|
||||
fulfillment_config = EXCLUDED.fulfillment_config,
|
||||
status = 'active',
|
||||
deleted_at = NULL;
|
||||
Reference in New Issue
Block a user