-- +goose Up -- 分销站点、规则、分账、结算,以及主站表上的租户隔离列。 -- 分成字段存百分数:收号 35、卖出 40、服务费 25。 -- 货架调价存 shelf_ratio_delta(分站 1 元兑换哈夫币比例相对主站的增量)。 -- 同时把 rental_orders 的业务时间列提到微秒精度(见下方第二条 ALTER)。 CREATE TABLE distribution_sites ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, site_code VARCHAR(64) NOT NULL, site_name VARCHAR(128) NOT NULL, 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, announcements_json TEXT NULL, footer_info_json TEXT NULL, default_support_group_id BIGINT UNSIGNED NULL, tax_enabled TINYINT(1) NOT NULL DEFAULT 0, tax_rate_bps BIGINT NOT NULL DEFAULT 100, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL, PRIMARY KEY (id), UNIQUE KEY uk_distribution_sites_code (site_code), UNIQUE KEY uk_distribution_sites_domain (domain), KEY idx_distribution_sites_status (status) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='分销网站主体'; CREATE TABLE distribution_site_members ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, site_id BIGINT UNSIGNED NOT NULL, admin_user_id BIGINT UNSIGNED NOT NULL, member_type VARCHAR(32) NOT NULL, status VARCHAR(16) NOT NULL DEFAULT 'active', data_scope VARCHAR(32) NOT NULL DEFAULT 'site', created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL, PRIMARY KEY (id), UNIQUE KEY uk_distribution_site_member (site_id, admin_user_id), KEY idx_distribution_site_members_admin (admin_user_id, status), CONSTRAINT fk_distribution_site_members_site FOREIGN KEY (site_id) REFERENCES distribution_sites (id), CONSTRAINT fk_distribution_site_members_admin FOREIGN KEY (admin_user_id) REFERENCES admin_users (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='分销网站后台成员'; CREATE TABLE distribution_site_accounts ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, site_id BIGINT UNSIGNED NOT NULL, account_id BIGINT UNSIGNED NOT NULL, listing_id BIGINT UNSIGNED NOT NULL, display_status VARCHAR(16) NOT NULL DEFAULT 'enabled', markup_amount_cent BIGINT NOT NULL DEFAULT 0, shelf_ratio_delta DECIMAL(10,2) NOT NULL DEFAULT 0, display_started_at DATETIME NULL, display_ended_at DATETIME NULL, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL, PRIMARY KEY (id), UNIQUE KEY uk_distribution_site_account (site_id, account_id), KEY idx_distribution_site_accounts_listing (listing_id), KEY idx_distribution_site_accounts_display (site_id, display_status), CONSTRAINT fk_distribution_site_accounts_site FOREIGN KEY (site_id) REFERENCES distribution_sites (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='分销网站账号展示关系'; CREATE TABLE distribution_rule_versions ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, site_id BIGINT UNSIGNED NULL, mode VARCHAR(32) NOT NULL, version INT NOT NULL, status VARCHAR(16) NOT NULL DEFAULT 'draft', platform_receive_ratio DECIMAL(10,2) NOT NULL DEFAULT 0, platform_sell_ratio DECIMAL(10,2) NOT NULL DEFAULT 0, distributor_receive_ratio DECIMAL(10,2) NOT NULL DEFAULT 0, distributor_sell_ratio DECIMAL(10,2) NOT NULL DEFAULT 0, distributor_a_ratio DECIMAL(10,2) NOT NULL DEFAULT 0, distributor_b_ratio DECIMAL(10,2) NOT NULL DEFAULT 0, service_fee_value DECIMAL(12,4) NOT NULL DEFAULT 0, service_fee_unit VARCHAR(24) NOT NULL DEFAULT 'percent', payment_fee_bps BIGINT NOT NULL DEFAULT 50, tax_enabled TINYINT(1) NOT NULL DEFAULT 0, tax_rate_bps BIGINT NOT NULL DEFAULT 100, effective_from DATETIME NOT NULL, effective_to DATETIME NULL, created_by BIGINT UNSIGNED NULL, created_at DATETIME NOT NULL, PRIMARY KEY (id), UNIQUE KEY uk_distribution_rule_version (site_id, mode, version), KEY idx_distribution_rule_effective (site_id, mode, status, effective_from), CONSTRAINT fk_distribution_rule_site FOREIGN KEY (site_id) REFERENCES distribution_sites (id), CONSTRAINT fk_distribution_rule_admin FOREIGN KEY (created_by) REFERENCES admin_users (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='分销分账规则版本'; CREATE TABLE distribution_order_financials ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, order_id BIGINT UNSIGNED NOT NULL, site_id BIGINT UNSIGNED NOT NULL, rule_version_id BIGINT UNSIGNED NOT NULL, gross_paid_amount_cent BIGINT NOT NULL DEFAULT 0, refund_amount_cent BIGINT NOT NULL DEFAULT 0, net_paid_amount_cent BIGINT NOT NULL DEFAULT 0, payment_fee_bps BIGINT NOT NULL DEFAULT 50, payment_fee_cent BIGINT NOT NULL DEFAULT 0, service_fee_value DECIMAL(12,4) NOT NULL DEFAULT 0, service_fee_unit VARCHAR(24) NOT NULL DEFAULT 'percent', service_fee_cent BIGINT NOT NULL DEFAULT 0, markup_amount_cent BIGINT NOT NULL DEFAULT 0, tax_enabled TINYINT(1) NOT NULL DEFAULT 0, tax_rate_bps BIGINT NOT NULL DEFAULT 100, tax_amount_cent BIGINT NOT NULL DEFAULT 0, 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) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='分销正常订单财务快照'; CREATE TABLE distribution_order_parties ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, order_id BIGINT UNSIGNED NOT NULL, site_id BIGINT UNSIGNED NOT NULL, party_role VARCHAR(32) NOT NULL, party_type VARCHAR(16) NOT NULL, party_id BIGINT UNSIGNED NOT NULL, ratio DECIMAL(10,2) NOT NULL DEFAULT 0, income_amount_cent BIGINT NOT NULL DEFAULT 0, cost_amount_cent BIGINT NOT NULL DEFAULT 0, profit_amount_cent BIGINT NOT NULL DEFAULT 0, tax_amount_cent BIGINT NOT NULL DEFAULT 0, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL, PRIMARY KEY (id), KEY idx_distribution_order_parties_order (order_id), KEY idx_distribution_order_parties_site_role (site_id, party_role), CONSTRAINT fk_distribution_order_parties_order FOREIGN KEY (order_id) REFERENCES rental_orders (id), CONSTRAINT fk_distribution_order_parties_site FOREIGN KEY (site_id) REFERENCES distribution_sites (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='分销订单参与方快照'; CREATE TABLE distribution_settlement_batches ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, site_id BIGINT UNSIGNED NOT NULL, batch_no VARCHAR(64) NOT NULL, period_start DATETIME NOT NULL, period_end DATETIME NOT NULL, total_amount_cent BIGINT NOT NULL DEFAULT 0, status VARCHAR(16) NOT NULL DEFAULT 'draft', created_by BIGINT UNSIGNED NULL, settled_at DATETIME NULL, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL, PRIMARY KEY (id), UNIQUE KEY uk_distribution_settlement_batch_no (batch_no), KEY idx_distribution_settlement_batches_site_status (site_id, status), CONSTRAINT fk_distribution_settlement_batches_site FOREIGN KEY (site_id) REFERENCES distribution_sites (id), CONSTRAINT fk_distribution_settlement_batches_admin FOREIGN KEY (created_by) REFERENCES admin_users (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='分销结算批次'; CREATE TABLE distribution_settlement_items ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, batch_id BIGINT UNSIGNED NOT NULL, order_id BIGINT UNSIGNED NOT NULL, party_id BIGINT UNSIGNED NOT NULL, amount_cent BIGINT NOT NULL DEFAULT 0, status VARCHAR(16) NOT NULL DEFAULT 'pending', 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), CONSTRAINT fk_distribution_settlement_items_party FOREIGN KEY (party_id) REFERENCES distribution_order_parties (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='分销结算明细'; CREATE TABLE distribution_site_payment_channels ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, site_id BIGINT UNSIGNED NOT NULL, config_id BIGINT UNSIGNED NOT NULL, priority INT NOT NULL DEFAULT 0, status VARCHAR(16) NOT NULL DEFAULT 'active', created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL, PRIMARY KEY (id), UNIQUE KEY uk_distribution_site_payment (site_id, config_id), KEY idx_distribution_site_payment_status (site_id, status, priority), CONSTRAINT fk_distribution_site_payment_site FOREIGN KEY (site_id) REFERENCES distribution_sites (id), CONSTRAINT fk_distribution_site_payment_config FOREIGN KEY (config_id) REFERENCES payment_merchant_configs (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='分销网站收款通道绑定'; ALTER TABLE rental_orders ADD COLUMN base_price_cent BIGINT NOT NULL DEFAULT 0 AFTER platform_fee_cent, ADD COLUMN shelf_markup_cent BIGINT NOT NULL DEFAULT 0 AFTER base_price_cent, ADD COLUMN markup_site_id BIGINT UNSIGNED NOT NULL DEFAULT 0 AFTER shelf_markup_cent, ADD COLUMN shelf_ratio DECIMAL(10,2) NOT NULL DEFAULT 0 AFTER markup_site_id, ADD COLUMN shelf_ratio_delta DECIMAL(10,2) NOT NULL DEFAULT 0 AFTER shelf_ratio, ADD COLUMN distribution_site_id BIGINT UNSIGNED NULL AFTER source_channel, ADD COLUMN distribution_mode VARCHAR(32) NOT NULL DEFAULT '' AFTER distribution_site_id, ADD COLUMN distribution_rule_version_id BIGINT UNSIGNED NULL AFTER distribution_mode, ADD KEY idx_rental_orders_markup_site (markup_site_id), ADD KEY idx_rental_orders_distribution_site (distribution_site_id, distribution_mode), ADD CONSTRAINT fk_rental_orders_distribution_site FOREIGN KEY (distribution_site_id) REFERENCES distribution_sites (id), ADD CONSTRAINT fk_rental_orders_distribution_rule FOREIGN KEY (distribution_rule_version_id) REFERENCES distribution_rule_versions (id); -- 顺带把订单业务时间列提到微秒精度:秒级 DATETIME 会静默截断 Go 侧写入的时间, -- 影响租用时长计算与结算时点回读比对。与分销字段同表,合并成一次 ALTER。 ALTER TABLE rental_orders MODIFY COLUMN rented_at DATETIME(6) NULL COMMENT '租用开始时间', MODIFY COLUMN handoff_started_at DATETIME(6) NULL COMMENT '进入待号主交接的时间,用于计算交接超时', MODIFY COLUMN growth_points_awarded_at DATETIME(6) NULL COMMENT '成长积分发放时间', MODIFY COLUMN offline_settled_at DATETIME(6) NULL COMMENT '线下结算确认时间', MODIFY COLUMN refunded_at DATETIME(6) NULL COMMENT '退款完成时间', MODIFY COLUMN deposit_held_at DATETIME(6) NULL COMMENT '暂扣时间', MODIFY COLUMN deposit_hold_released_at DATETIME(6) NULL COMMENT '押金归还时间', MODIFY COLUMN owner_settled_at DATETIME(6) NULL COMMENT '号主结算时间', MODIFY COLUMN settled_at DATETIME(6) NULL COMMENT '订单结算时间'; ALTER TABLE rental_listings ADD COLUMN distribution_site_id BIGINT UNSIGNED NULL AFTER managed_admin_id, ADD COLUMN source_channel VARCHAR(64) NOT NULL DEFAULT '' AFTER distribution_site_id, ADD KEY idx_rental_listings_distribution_site (distribution_site_id, status); ALTER TABLE chat_qrcode_pool ADD COLUMN distribution_site_id BIGINT UNSIGNED NULL AFTER group_name, ADD KEY idx_chat_qrcode_distribution_site (distribution_site_id, status), ADD CONSTRAINT fk_chat_qrcode_distribution_site FOREIGN KEY (distribution_site_id) REFERENCES distribution_sites (id); ALTER TABLE chat_conversations ADD COLUMN distribution_site_id BIGINT UNSIGNED NULL AFTER listing_id, ADD KEY idx_chat_conversations_distribution_site (distribution_site_id, status); ALTER TABLE wallet_accounts ADD COLUMN distribution_site_id BIGINT UNSIGNED NOT NULL DEFAULT 0 AFTER user_id, DROP KEY uk_wallet_accounts_user_id, ADD UNIQUE KEY uk_wallet_accounts_user_site (user_id, distribution_site_id); ALTER TABLE wallet_ledger ADD COLUMN distribution_site_id BIGINT UNSIGNED NOT NULL DEFAULT 0 AFTER user_id, ADD KEY idx_wallet_ledger_user_site (user_id, distribution_site_id); ALTER TABLE withdrawal_requests ADD COLUMN distribution_site_id BIGINT UNSIGNED NOT NULL DEFAULT 0 AFTER user_id, ADD KEY idx_withdrawal_user_site (user_id, distribution_site_id); ALTER TABLE notifications ADD COLUMN distribution_site_id BIGINT UNSIGNED NULL AFTER biz_id, ADD KEY idx_notifications_user_site (user_id, distribution_site_id, id); INSERT INTO permissions (code, name, resource, action) VALUES ('distribution:site_view', '查看分销网站', 'distribution', 'site_view'), ('distribution:site_manage', '管理分销网站', 'distribution', 'site_manage'), ('distribution:order_view', '查看分销订单', 'distribution', 'order_view'), ('distribution:settlement_view', '查看分销结算', 'distribution', 'settlement_view'), ('distribution:settlement_manage', '管理分销结算', 'distribution', 'settlement_manage'), ('distribution:rule_view', '查看分销规则', 'distribution', 'rule_view'), ('distribution:rule_manage', '管理分销规则', 'distribution', 'rule_manage'), ('distribution:account_view', '查看分销账号', 'distribution', 'account_view'), ('distribution:account_display', '管理分销账号展示', 'distribution', 'account_display'), ('distribution:payment_view', '查看分销支付通道', 'distribution', 'payment_view'), ('distribution:payment_manage', '管理分销支付通道', 'distribution', 'payment_manage'), ('distribution:all_view', '查看全部分销站点', 'distribution', 'all_view') ON DUPLICATE KEY UPDATE name = VALUES(name), resource = VALUES(resource), action = VALUES(action); INSERT IGNORE INTO role_permissions (role_id, permission_id) SELECT r.id, p.id FROM roles r CROSS JOIN permissions p WHERE r.code = 'super_admin' AND p.code LIKE 'distribution:%'; INSERT IGNORE INTO role_permissions (role_id, permission_id) SELECT r.id, p.id FROM roles r CROSS JOIN permissions p WHERE r.code IN ('ops', 'finance') AND p.code LIKE 'distribution:%' AND p.code <> 'distribution:all_view'; INSERT INTO distribution_rule_versions ( site_id, mode, version, status, platform_receive_ratio, platform_sell_ratio, distributor_receive_ratio, distributor_sell_ratio, distributor_a_ratio, distributor_b_ratio, service_fee_value, service_fee_unit, payment_fee_bps, tax_enabled, tax_rate_bps, effective_from, created_at ) 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, 'site_self_sell', 1, 'active', 0, 0, 0, 75, 0, 0, 25, 'percent', 50, 0, 100, NOW(), NOW()); -- +goose Down ALTER TABLE notifications DROP KEY idx_notifications_user_site, DROP COLUMN distribution_site_id; ALTER TABLE withdrawal_requests DROP KEY idx_withdrawal_user_site, DROP COLUMN distribution_site_id; ALTER TABLE wallet_ledger DROP KEY idx_wallet_ledger_user_site, DROP COLUMN distribution_site_id; DELETE FROM wallet_accounts WHERE distribution_site_id <> 0; ALTER TABLE wallet_accounts DROP KEY uk_wallet_accounts_user_site, DROP COLUMN distribution_site_id, ADD UNIQUE KEY uk_wallet_accounts_user_id (user_id); ALTER TABLE chat_conversations DROP KEY idx_chat_conversations_distribution_site, DROP COLUMN distribution_site_id; ALTER TABLE chat_qrcode_pool DROP FOREIGN KEY fk_chat_qrcode_distribution_site, DROP KEY idx_chat_qrcode_distribution_site, DROP COLUMN distribution_site_id; ALTER TABLE rental_listings DROP KEY idx_rental_listings_distribution_site, DROP COLUMN source_channel, DROP COLUMN distribution_site_id; ALTER TABLE rental_orders MODIFY COLUMN rented_at DATETIME NULL COMMENT '租用开始时间', MODIFY COLUMN handoff_started_at DATETIME NULL COMMENT '进入待号主交接的时间,用于计算交接超时', MODIFY COLUMN growth_points_awarded_at DATETIME NULL COMMENT '成长积分发放时间', MODIFY COLUMN offline_settled_at DATETIME NULL COMMENT '线下结算确认时间', MODIFY COLUMN refunded_at DATETIME NULL COMMENT '退款完成时间', MODIFY COLUMN deposit_held_at DATETIME NULL COMMENT '暂扣时间', MODIFY COLUMN deposit_hold_released_at DATETIME NULL COMMENT '押金归还时间', MODIFY COLUMN owner_settled_at DATETIME NULL COMMENT '号主结算时间', MODIFY COLUMN settled_at DATETIME NULL COMMENT '订单结算时间'; ALTER TABLE rental_orders DROP FOREIGN KEY fk_rental_orders_distribution_rule, DROP FOREIGN KEY fk_rental_orders_distribution_site, DROP KEY idx_rental_orders_distribution_site, DROP KEY idx_rental_orders_markup_site, DROP COLUMN distribution_rule_version_id, DROP COLUMN distribution_mode, DROP COLUMN distribution_site_id, DROP COLUMN shelf_ratio_delta, DROP COLUMN shelf_ratio, DROP COLUMN markup_site_id, DROP COLUMN shelf_markup_cent, DROP COLUMN base_price_cent; DROP TABLE IF EXISTS distribution_settlement_items; DROP TABLE IF EXISTS distribution_settlement_batches; DROP TABLE IF EXISTS distribution_order_financials; DROP TABLE IF EXISTS distribution_order_parties; DROP TABLE IF EXISTS distribution_site_payment_channels; DROP TABLE IF EXISTS distribution_rule_versions; DROP TABLE IF EXISTS distribution_site_accounts; DROP TABLE IF EXISTS distribution_site_members; DROP TABLE IF EXISTS distribution_sites; DELETE rp FROM role_permissions rp JOIN permissions p ON p.id = rp.permission_id WHERE p.code LIKE 'distribution:%'; DELETE FROM permissions WHERE code LIKE 'distribution:%';