refactor(migration): 整合分销迁移至终态定义并清理零散改表与测试种子数据

This commit is contained in:
yml2213
2026-09-10 19:45:00 +08:00
parent 140c538d4f
commit 403d20cabd
7 changed files with 10 additions and 164 deletions
+2 -2
View File
@@ -20,8 +20,8 @@
- 主站前台地址:`http://localhost:5189`
- 主站后台地址:`http://localhost:5189/admin/login`(超级管理员默认 `admin` / `admin123456`)
- 分销管理后台:`http://localhost:5190`(分销操作员 `test_fx1`)
- 分销专属前台:`http://localhost:5191`(独立端口隔离,默认直连 `test_1` 分销站)
- 分销管理后台:`http://localhost:5190`(在主站后台“分销站点”开通站点并配置分销操作员登录)
- 分销专属前台:`http://localhost:5191`(独立端口隔离,支持 Host 域名与 X-Distribution-Site 头识别站点)
如需拆分调试,可手动执行:
@@ -61,7 +61,7 @@ func mustCreateDraftBatch(t *testing.T, db *gorm.DB, siteID uint64, batchNo stri
return batch
}
// TestSettlementItemOrderPartyUniqueKey 断言 000070 唯一键生效:
// TestSettlementItemOrderPartyUniqueKey 断言 (order_id, party_id) 唯一键生效:
// 同一 (order_id, party_id) 插入第二条结算明细必须失败。
func TestSettlementItemOrderPartyUniqueKey(t *testing.T) {
db := distributionTestDB(t)
@@ -12,6 +12,7 @@ CREATE TABLE distribution_sites (
domain VARCHAR(255) NOT NULL,
status VARCHAR(16) NOT NULL DEFAULT 'active',
display_account_enabled TINYINT(1) NOT NULL DEFAULT 1,
settlement_hold_days INT NOT NULL DEFAULT 7 COMMENT '订单完成后结算释放冷却天数,0=立即释放',
logo_url VARCHAR(512) NOT NULL DEFAULT '',
favicon_url VARCHAR(512) NOT NULL DEFAULT '',
banners_json TEXT NULL,
@@ -111,12 +112,15 @@ CREATE TABLE distribution_order_financials (
split_base_amount_cent BIGINT NOT NULL DEFAULT 0,
rounding_adjustment_cent BIGINT NOT NULL DEFAULT 0,
settlement_status VARCHAR(24) NOT NULL DEFAULT 'pending',
release_at DATETIME(6) NULL COMMENT '预计释放时间(订单完成时间+站点冷却期)',
released_at DATETIME(6) NULL COMMENT '实际释放入账时间',
settled_at DATETIME NULL,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY uk_distribution_order_financial_order (order_id),
KEY idx_distribution_order_financial_site_status (site_id, settlement_status),
KEY idx_distribution_financial_release (settlement_status, release_at),
CONSTRAINT fk_distribution_order_financial_order FOREIGN KEY (order_id) REFERENCES rental_orders (id),
CONSTRAINT fk_distribution_order_financial_site FOREIGN KEY (site_id) REFERENCES distribution_sites (id),
CONSTRAINT fk_distribution_order_financial_rule FOREIGN KEY (rule_version_id) REFERENCES distribution_rule_versions (id)
@@ -172,6 +176,7 @@ CREATE TABLE distribution_settlement_items (
created_at DATETIME NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY uk_distribution_settlement_item (batch_id, order_id, party_id),
UNIQUE KEY uk_distribution_settlement_item_party (order_id, party_id),
KEY idx_distribution_settlement_items_order (order_id),
CONSTRAINT fk_distribution_settlement_items_batch FOREIGN KEY (batch_id) REFERENCES distribution_settlement_batches (id),
CONSTRAINT fk_distribution_settlement_items_order FOREIGN KEY (order_id) REFERENCES rental_orders (id),
@@ -286,7 +291,8 @@ INSERT INTO distribution_rule_versions (
) VALUES
(NULL, 'two_party_distributor_receive', 1, 'active', 0, 40, 35, 0, 0, 0, 25, 'percent', 50, 0, 100, NOW(), NOW()),
(NULL, 'two_party_platform_receive', 1, 'active', 35, 0, 0, 40, 0, 0, 25, 'percent', 50, 0, 100, NOW(), NOW()),
(NULL, 'three_party', 1, 'active', 0, 0, 0, 0, 35, 40, 25, 'percent', 50, 0, 100, NOW(), NOW());
(NULL, 'three_party', 1, 'active', 0, 0, 0, 0, 35, 40, 25, 'percent', 50, 0, 100, NOW(), NOW()),
(NULL, 'site_self_sell', 1, 'active', 0, 0, 0, 75, 0, 0, 25, 'percent', 50, 0, 100, NOW(), NOW());
-- +goose Down
@@ -1,101 +0,0 @@
-- +goose Up
-- 初始化本地测试分销站点 test_1、分销管理员 test_fx1 (密码 admin123456) 以及对应的金库钱包与商品货架
-- 1. 插入或激活测试分销站点 test_1
INSERT INTO distribution_sites (
site_code, site_name, domain, status, display_account_enabled, tax_enabled, tax_rate_bps, created_at, updated_at
) VALUES (
'test_1', '测试分销商1', 'test_1.localhost', 'active', 1, 0, 100, NOW(), NOW()
) ON DUPLICATE KEY UPDATE
site_name = VALUES(site_name),
domain = VALUES(domain),
status = 'active',
display_account_enabled = 1,
updated_at = NOW();
-- 2. 插入或激活测试分销管理员 test_fx1 (初始密码: admin123456)
INSERT INTO admin_users (
username, password_hash, nickname, status, created_at, updated_at
) VALUES (
'test_fx1',
'$2a$10$zj3KqZJArsYVKVjA7uHDbeP7sWML20xjxRfb3a100xBx.f20Gu.8O',
'分销操作员1',
'active',
NOW(),
NOW()
) ON DUPLICATE KEY UPDATE
status = 'active',
password_hash = VALUES(password_hash),
updated_at = NOW();
-- 3. 关联分销商成员 (operator 角色)
INSERT INTO distribution_site_members (
site_id, admin_user_id, member_type, status, data_scope, created_at, updated_at
)
SELECT s.id, u.id, 'operator', 'active', 'site', NOW(), NOW()
FROM distribution_sites s
JOIN admin_users u ON u.username = 'test_fx1'
WHERE s.site_code = 'test_1'
ON DUPLICATE KEY UPDATE
status = 'active',
member_type = 'operator',
updated_at = NOW();
-- 4. 初始化 test_1 分销站金库钱包账户 (user_id = 0, distribution_site_id = site.id)
INSERT INTO wallet_accounts (
user_id, distribution_site_id, available_balance_cent, frozen_balance_cent, status, created_at, updated_at
)
SELECT 0, s.id, 0, 0, 'active', NOW(), NOW()
FROM distribution_sites s
WHERE s.site_code = 'test_1'
ON DUPLICATE KEY UPDATE status = 'active';
-- 5. 初始化 test_1 分销站点专属规则版本 (两方-分销卖出,收号 35%、卖出 40%、服务费 25%)
INSERT INTO distribution_rule_versions (
site_id, mode, version, status,
platform_receive_ratio, distributor_sell_ratio, service_fee_value, service_fee_unit, payment_fee_bps,
effective_from, created_at
)
SELECT s.id, 'two_party_platform_receive', 1, 'active',
35, 40, 25, 'percent', 50,
NOW(), NOW()
FROM distribution_sites s
WHERE s.site_code = 'test_1'
ON DUPLICATE KEY UPDATE
status = 'active',
platform_receive_ratio = 35,
distributor_sell_ratio = 40,
service_fee_value = 25;
-- 6. 默认将当前已发布的合规商品直接铺入 test_1 货架
INSERT IGNORE INTO distribution_site_accounts (
site_id, account_id, listing_id, display_status, markup_amount_cent, shelf_ratio_delta, created_at, updated_at
)
SELECT s.id, l.account_id, l.id, 'enabled', 0, 0, NOW(), NOW()
FROM distribution_sites s
CROSS JOIN rental_listings l
WHERE s.site_code = 'test_1'
AND l.status = 'published'
AND l.review_status = 'approved';
-- +goose Down
DELETE dsa FROM distribution_site_accounts dsa
JOIN distribution_sites s ON s.id = dsa.site_id
WHERE s.site_code = 'test_1';
DELETE drv FROM distribution_rule_versions drv
JOIN distribution_sites s ON s.id = drv.site_id
WHERE s.site_code = 'test_1';
DELETE wa FROM wallet_accounts wa
JOIN distribution_sites s ON s.id = wa.distribution_site_id
WHERE s.site_code = 'test_1' AND wa.user_id = 0;
DELETE dsm FROM distribution_site_members dsm
JOIN distribution_sites s ON s.id = dsm.site_id
WHERE s.site_code = 'test_1';
DELETE FROM admin_users WHERE username = 'test_fx1';
DELETE FROM distribution_sites WHERE site_code = 'test_1';
@@ -1,30 +0,0 @@
-- +goose Up
-- 分销站点结算冷却期:订单完成后 N 天自动释放到可提现余额,0 表示立即释放。
ALTER TABLE distribution_sites
ADD COLUMN settlement_hold_days INT NOT NULL DEFAULT 7 COMMENT '订单完成后结算释放冷却天数,0=立即释放';
-- 财务快照记录释放时间:release_at 为订单完成时间 + 站点冷却期,released_at 为实际入账时间。
ALTER TABLE distribution_order_financials
ADD COLUMN release_at DATETIME(6) NULL COMMENT '预计释放时间(订单完成时间+站点冷却期)',
ADD COLUMN released_at DATETIME(6) NULL COMMENT '实际释放入账时间',
ADD KEY idx_distribution_financial_release (settlement_status, release_at);
-- 回填历史已完成订单的释放时间,使其纳入自动释放。
UPDATE distribution_order_financials f
JOIN rental_orders ro ON ro.id = f.order_id
JOIN distribution_sites s ON s.id = f.site_id
SET f.release_at = DATE_ADD(COALESCE(ro.settled_at, f.created_at), INTERVAL s.settlement_hold_days DAY)
WHERE f.settlement_status = 'pending'
AND f.release_at IS NULL
AND ro.status = 'completed';
-- +goose Down
ALTER TABLE distribution_order_financials
DROP KEY idx_distribution_financial_release,
DROP COLUMN released_at,
DROP COLUMN release_at;
ALTER TABLE distribution_sites
DROP COLUMN settlement_hold_days;
@@ -1,12 +0,0 @@
-- +goose Up
-- 同一订单同一参与方只允许一条结算明细,防止自动释放与手工批次并发重复入账。
-- 自动释放按 NOT EXISTS 选参与方,并发下两条路径可能同时落明细并各自入账,
-- 由该唯一键兜底,写明细失败重复错误时跳过该参与方。
ALTER TABLE distribution_settlement_items
ADD UNIQUE KEY uk_distribution_settlement_item_party (order_id, party_id);
-- +goose Down
ALTER TABLE distribution_settlement_items
DROP KEY uk_distribution_settlement_item_party;
@@ -1,17 +0,0 @@
-- +goose Up
-- 000069 回填历史释放时间时只覆盖了 completed,遗漏了同样是可释放终态的 closed 订单,
-- 导致不退款关单(AdminRejectRefund close、AdminSeal 等)的订单 release_at 永久为 NULL。
-- 这里补齐 closed,使这些订单重新纳入自动释放扫描。
UPDATE distribution_order_financials f
JOIN rental_orders ro ON ro.id = f.order_id
JOIN distribution_sites s ON s.id = f.site_id
SET f.release_at = DATE_ADD(COALESCE(ro.settled_at, f.created_at), INTERVAL s.settlement_hold_days DAY)
WHERE f.settlement_status = 'pending'
AND f.release_at IS NULL
AND ro.status IN ('completed', 'closed');
-- +goose Down
-- 回填不可逆:无法区分补写的 release_at 与原有值,Down 用占位语句保持 goose 格式。
SELECT 1;