All checks were successful
Build and Deploy / deploy (push) Successful in 1m0s
仓库地址增加排序/备注字段与迁移;用户创建时对邮箱冲突等给出明确中文提示。 Co-authored-by: Cursor <cursoragent@cursor.com>
668 lines
28 KiB
SQL
668 lines
28 KiB
SQL
-- =============================================================================
|
||
-- admin.sql
|
||
-- 存量库增量迁移合集(由 sql/ 下各 migrate_*.sql 合并,可重复执行)
|
||
-- 新环境请直接执行仓库根目录 db.sql,勿在有生产数据的库上 DROP 重建。
|
||
-- =============================================================================
|
||
|
||
-- =============================================================================
|
||
-- migrate_member_level_rolling_points.sql
|
||
-- 旧会员体系 → V0~V5(可重复执行)
|
||
-- old: normal/silver/gold/diamond
|
||
-- new: V0 普通 / V1 铜卡(新增) / V2 银卡 / V3 金卡 / V4 钻石 / V5 皇冠(新增)
|
||
-- =============================================================================
|
||
SET @db := DATABASE();
|
||
|
||
SET @col := (
|
||
SELECT COUNT(1)
|
||
FROM information_schema.COLUMNS
|
||
WHERE TABLE_SCHEMA = @db
|
||
AND TABLE_NAME = 't_member_level'
|
||
AND COLUMN_NAME = 'CanDowngrade'
|
||
);
|
||
SET @sql := IF(
|
||
@col = 0,
|
||
'ALTER TABLE `t_member_level`
|
||
ADD COLUMN `CanDowngrade` TINYINT(1) NOT NULL DEFAULT 0 COMMENT ''V4/V5 允许逐级降级'' AFTER `ExtraDiscountRate`',
|
||
'SELECT ''CanDowngrade already exists'' AS info'
|
||
);
|
||
PREPARE stmt FROM @sql;
|
||
EXECUTE stmt;
|
||
DEALLOCATE PREPARE stmt;
|
||
|
||
-- ---------- 把旧行升级成新编码(仅当目标 V* 还不存在)----------
|
||
UPDATE `t_member_level`
|
||
SET
|
||
`LevelCode` = 'V0',
|
||
`LevelName` = '普通会员',
|
||
`MinPoints` = 0,
|
||
`ExtraDiscountRate` = 0.00,
|
||
`CanDowngrade` = 0,
|
||
`Sort` = 0,
|
||
`BenefitDesc` = '新注册 / 小单试单卖家',
|
||
`Status` = 2,
|
||
`UpdateTime` = NOW()
|
||
WHERE `IsDeleted` = 0
|
||
AND LOWER(`LevelCode`) = 'normal'
|
||
AND NOT EXISTS (SELECT 1 FROM (SELECT 1 FROM `t_member_level` x WHERE x.`IsDeleted` = 0 AND x.`LevelCode` = 'V0') t);
|
||
|
||
UPDATE `t_member_level`
|
||
SET
|
||
`LevelCode` = 'V2',
|
||
`LevelName` = '银卡会员',
|
||
`MinPoints` = 60000,
|
||
`ExtraDiscountRate` = 0.02,
|
||
`CanDowngrade` = 0,
|
||
`Sort` = 2,
|
||
`BenefitDesc` = '主力中小卖家,基础运费 98 折',
|
||
`Status` = 2,
|
||
`UpdateTime` = NOW()
|
||
WHERE `IsDeleted` = 0
|
||
AND LOWER(`LevelCode`) = 'silver'
|
||
AND NOT EXISTS (SELECT 1 FROM (SELECT 1 FROM `t_member_level` x WHERE x.`IsDeleted` = 0 AND x.`LevelCode` = 'V2') t);
|
||
|
||
UPDATE `t_member_level`
|
||
SET
|
||
`LevelCode` = 'V3',
|
||
`LevelName` = '金卡会员',
|
||
`MinPoints` = 120000,
|
||
`ExtraDiscountRate` = 0.03,
|
||
`CanDowngrade` = 0,
|
||
`Sort` = 3,
|
||
`BenefitDesc` = '优质中型卖家,基础运费 97 折;此级及以下只升不降',
|
||
`Status` = 2,
|
||
`UpdateTime` = NOW()
|
||
WHERE `IsDeleted` = 0
|
||
AND LOWER(`LevelCode`) = 'gold'
|
||
AND NOT EXISTS (SELECT 1 FROM (SELECT 1 FROM `t_member_level` x WHERE x.`IsDeleted` = 0 AND x.`LevelCode` = 'V3') t);
|
||
|
||
UPDATE `t_member_level`
|
||
SET
|
||
`LevelCode` = 'V4',
|
||
`LevelName` = '钻石会员',
|
||
`MinPoints` = 240000,
|
||
`ExtraDiscountRate` = 0.04,
|
||
`CanDowngrade` = 1,
|
||
`Sort` = 4,
|
||
`BenefitDesc` = '中大卖家,基础运费 96 折;滚动积分不足可降到金卡',
|
||
`Status` = 2,
|
||
`UpdateTime` = NOW()
|
||
WHERE `IsDeleted` = 0
|
||
AND LOWER(`LevelCode`) = 'diamond'
|
||
AND NOT EXISTS (SELECT 1 FROM (SELECT 1 FROM `t_member_level` x WHERE x.`IsDeleted` = 0 AND x.`LevelCode` = 'V4') t);
|
||
|
||
-- ---------- 缺档则插入(铜卡、皇冠,以及未被旧行带过来的档)----------
|
||
INSERT INTO `t_member_level`
|
||
(`LevelCode`, `LevelName`, `MinPoints`, `ExtraDiscountRate`, `CanDowngrade`, `Sort`, `BenefitDesc`, `Status`, `IsDeleted`, `CreateTime`)
|
||
SELECT 'V0', '普通会员', 0, 0.00, 0, 0, '新注册 / 小单试单卖家', 2, 0, NOW()
|
||
WHERE NOT EXISTS (SELECT 1 FROM `t_member_level` WHERE `LevelCode` = 'V0' AND `IsDeleted` = 0);
|
||
|
||
INSERT INTO `t_member_level`
|
||
(`LevelCode`, `LevelName`, `MinPoints`, `ExtraDiscountRate`, `CanDowngrade`, `Sort`, `BenefitDesc`, `Status`, `IsDeleted`, `CreateTime`)
|
||
SELECT 'V1', '铜卡会员', 24000, 0.01, 0, 1, '起步稳定发货卖家,基础运费 99 折', 2, 0, NOW()
|
||
WHERE NOT EXISTS (SELECT 1 FROM `t_member_level` WHERE `LevelCode` = 'V1' AND `IsDeleted` = 0);
|
||
|
||
INSERT INTO `t_member_level`
|
||
(`LevelCode`, `LevelName`, `MinPoints`, `ExtraDiscountRate`, `CanDowngrade`, `Sort`, `BenefitDesc`, `Status`, `IsDeleted`, `CreateTime`)
|
||
SELECT 'V2', '银卡会员', 60000, 0.02, 0, 2, '主力中小卖家,基础运费 98 折', 2, 0, NOW()
|
||
WHERE NOT EXISTS (SELECT 1 FROM `t_member_level` WHERE `LevelCode` = 'V2' AND `IsDeleted` = 0);
|
||
|
||
INSERT INTO `t_member_level`
|
||
(`LevelCode`, `LevelName`, `MinPoints`, `ExtraDiscountRate`, `CanDowngrade`, `Sort`, `BenefitDesc`, `Status`, `IsDeleted`, `CreateTime`)
|
||
SELECT 'V3', '金卡会员', 120000, 0.03, 0, 3, '优质中型卖家,基础运费 97 折;此级及以下只升不降', 2, 0, NOW()
|
||
WHERE NOT EXISTS (SELECT 1 FROM `t_member_level` WHERE `LevelCode` = 'V3' AND `IsDeleted` = 0);
|
||
|
||
INSERT INTO `t_member_level`
|
||
(`LevelCode`, `LevelName`, `MinPoints`, `ExtraDiscountRate`, `CanDowngrade`, `Sort`, `BenefitDesc`, `Status`, `IsDeleted`, `CreateTime`)
|
||
SELECT 'V4', '钻石会员', 240000, 0.04, 1, 4, '中大卖家,基础运费 96 折;滚动积分不足可降到金卡', 2, 0, NOW()
|
||
WHERE NOT EXISTS (SELECT 1 FROM `t_member_level` WHERE `LevelCode` = 'V4' AND `IsDeleted` = 0);
|
||
|
||
INSERT INTO `t_member_level`
|
||
(`LevelCode`, `LevelName`, `MinPoints`, `ExtraDiscountRate`, `CanDowngrade`, `Sort`, `BenefitDesc`, `Status`, `IsDeleted`, `CreateTime`)
|
||
SELECT 'V5', '皇冠会员', 600000, 0.05, 1, 5, '顶级头部卖家,基础运费 95 折封顶;滚动积分不足可降到钻石', 2, 0, NOW()
|
||
WHERE NOT EXISTS (SELECT 1 FROM `t_member_level` WHERE `LevelCode` = 'V5' AND `IsDeleted` = 0);
|
||
|
||
-- ---------- 旧编码与新档并存时:客户挂到新档,旧行停用 ----------
|
||
UPDATE `t_customer` c
|
||
INNER JOIN `t_member_level` old ON old.`Id` = c.`MemberLevelId` AND old.`IsDeleted` = 0
|
||
INNER JOIN `t_member_level` canon ON canon.`IsDeleted` = 0 AND canon.`LevelCode` = CASE LOWER(old.`LevelCode`)
|
||
WHEN 'normal' THEN 'V0'
|
||
WHEN 'silver' THEN 'V2'
|
||
WHEN 'gold' THEN 'V3'
|
||
WHEN 'diamond' THEN 'V4'
|
||
ELSE NULL
|
||
END
|
||
SET c.`MemberLevelId` = canon.`Id`, c.`UpdateTime` = NOW()
|
||
WHERE LOWER(old.`LevelCode`) IN ('normal', 'silver', 'gold', 'diamond')
|
||
AND old.`Id` <> canon.`Id`;
|
||
|
||
UPDATE `t_member_level` old
|
||
INNER JOIN `t_member_level` canon ON canon.`IsDeleted` = 0 AND canon.`LevelCode` = CASE LOWER(old.`LevelCode`)
|
||
WHEN 'normal' THEN 'V0'
|
||
WHEN 'silver' THEN 'V2'
|
||
WHEN 'gold' THEN 'V3'
|
||
WHEN 'diamond' THEN 'V4'
|
||
ELSE NULL
|
||
END
|
||
SET
|
||
old.`IsDeleted` = 1,
|
||
old.`Status` = 1,
|
||
old.`UpdateTime` = NOW()
|
||
WHERE old.`IsDeleted` = 0
|
||
AND LOWER(old.`LevelCode`) IN ('normal', 'silver', 'gold', 'diamond')
|
||
AND old.`Id` <> canon.`Id`;
|
||
|
||
-- ---------- 校正 V0~V5 门槛/折扣(已占用客户的行 Id 不变)----------
|
||
UPDATE `t_member_level`
|
||
SET
|
||
`LevelName` = '普通会员',
|
||
`MinPoints` = 0,
|
||
`ExtraDiscountRate` = 0.00,
|
||
`CanDowngrade` = 0,
|
||
`Sort` = 0,
|
||
`BenefitDesc` = '新注册 / 小单试单卖家',
|
||
`Status` = 2,
|
||
`UpdateTime` = NOW()
|
||
WHERE `IsDeleted` = 0 AND `LevelCode` = 'V0';
|
||
|
||
UPDATE `t_member_level`
|
||
SET
|
||
`LevelName` = '铜卡会员',
|
||
`MinPoints` = 24000,
|
||
`ExtraDiscountRate` = 0.01,
|
||
`CanDowngrade` = 0,
|
||
`Sort` = 1,
|
||
`BenefitDesc` = '起步稳定发货卖家,基础运费 99 折',
|
||
`Status` = 2,
|
||
`UpdateTime` = NOW()
|
||
WHERE `IsDeleted` = 0 AND `LevelCode` = 'V1';
|
||
|
||
UPDATE `t_member_level`
|
||
SET
|
||
`LevelName` = '银卡会员',
|
||
`MinPoints` = 60000,
|
||
`ExtraDiscountRate` = 0.02,
|
||
`CanDowngrade` = 0,
|
||
`Sort` = 2,
|
||
`BenefitDesc` = '主力中小卖家,基础运费 98 折',
|
||
`Status` = 2,
|
||
`UpdateTime` = NOW()
|
||
WHERE `IsDeleted` = 0 AND `LevelCode` = 'V2';
|
||
|
||
UPDATE `t_member_level`
|
||
SET
|
||
`LevelName` = '金卡会员',
|
||
`MinPoints` = 120000,
|
||
`ExtraDiscountRate` = 0.03,
|
||
`CanDowngrade` = 0,
|
||
`Sort` = 3,
|
||
`BenefitDesc` = '优质中型卖家,基础运费 97 折;此级及以下只升不降',
|
||
`Status` = 2,
|
||
`UpdateTime` = NOW()
|
||
WHERE `IsDeleted` = 0 AND `LevelCode` = 'V3';
|
||
|
||
UPDATE `t_member_level`
|
||
SET
|
||
`LevelName` = '钻石会员',
|
||
`MinPoints` = 240000,
|
||
`ExtraDiscountRate` = 0.04,
|
||
`CanDowngrade` = 1,
|
||
`Sort` = 4,
|
||
`BenefitDesc` = '中大卖家,基础运费 96 折;滚动积分不足可降到金卡',
|
||
`Status` = 2,
|
||
`UpdateTime` = NOW()
|
||
WHERE `IsDeleted` = 0 AND `LevelCode` = 'V4';
|
||
|
||
UPDATE `t_member_level`
|
||
SET
|
||
`LevelName` = '皇冠会员',
|
||
`MinPoints` = 600000,
|
||
`ExtraDiscountRate` = 0.05,
|
||
`CanDowngrade` = 1,
|
||
`Sort` = 5,
|
||
`BenefitDesc` = '顶级头部卖家,基础运费 95 折封顶;滚动积分不足可降到钻石',
|
||
`Status` = 2,
|
||
`UpdateTime` = NOW()
|
||
WHERE `IsDeleted` = 0 AND `LevelCode` = 'V5';
|
||
|
||
-- =============================================================================
|
||
-- migrate_coupon_grant_system.sql
|
||
-- 优惠券发放体系:未解锁状态、到期提醒标记、新人/裂变券模板(可重复执行)
|
||
-- =============================================================================
|
||
SET @db := DATABASE();
|
||
|
||
SET @col := (
|
||
SELECT COUNT(1)
|
||
FROM information_schema.COLUMNS
|
||
WHERE TABLE_SCHEMA = @db
|
||
AND TABLE_NAME = 't_coupon_instance'
|
||
AND COLUMN_NAME = 'ExpiryNoticeSent'
|
||
);
|
||
SET @sql := IF(
|
||
@col = 0,
|
||
'ALTER TABLE `t_coupon_instance`
|
||
ADD COLUMN `ExpiryNoticeSent` TINYINT(1) NOT NULL DEFAULT 0 COMMENT ''到期前3天已提醒'' AFTER `LockExpireTime`',
|
||
'SELECT ''ExpiryNoticeSent already exists'' AS info'
|
||
);
|
||
PREPARE stmt FROM @sql;
|
||
EXECUTE stmt;
|
||
DEALLOCATE PREPARE stmt;
|
||
|
||
-- 新人首单券 15 元,领取后 15 天
|
||
INSERT INTO `t_coupon_template` (
|
||
`TemplateCode`, `TemplateName`, `CouponType`, `FaceValue`, `DiscountRate`, `MaxDiscountAmount`,
|
||
`MinOrderAmount`, `TotalQuantity`, `IssuedQuantity`, `PerCustomerLimit`,
|
||
`ValidType`, `ValidStartTime`, `ValidEndTime`, `ValidDaysAfterReceive`,
|
||
`ApplyScopeJson`, `GrantChannel`, `Status`, `Remark`,
|
||
`IsDeleted`, `CreateUserId`, `CreateTime`, `UpdateUserId`, `UpdateTime`
|
||
)
|
||
SELECT
|
||
'NEWCOMER_FIRST', '新人首单券', 'fixed_off', 15.00, NULL, NULL,
|
||
0, 0, 0, 1,
|
||
2, NULL, NULL, 15,
|
||
NULL, 'newcomer', 1, '注册自动下发,仅抵基础运费,退款不退回',
|
||
0, 0, NOW(), 0, NOW()
|
||
WHERE NOT EXISTS (
|
||
SELECT 1 FROM `t_coupon_template` x WHERE x.`IsDeleted` = 0 AND x.`TemplateCode` = 'NEWCOMER_FIRST'
|
||
);
|
||
|
||
-- 新人第二单券 15 元,满 150 基础运费,解锁后 30 天
|
||
INSERT INTO `t_coupon_template` (
|
||
`TemplateCode`, `TemplateName`, `CouponType`, `FaceValue`, `DiscountRate`, `MaxDiscountAmount`,
|
||
`MinOrderAmount`, `TotalQuantity`, `IssuedQuantity`, `PerCustomerLimit`,
|
||
`ValidType`, `ValidStartTime`, `ValidEndTime`, `ValidDaysAfterReceive`,
|
||
`ApplyScopeJson`, `GrantChannel`, `Status`, `Remark`,
|
||
`IsDeleted`, `CreateUserId`, `CreateTime`, `UpdateUserId`, `UpdateTime`
|
||
)
|
||
SELECT
|
||
'NEWCOMER_SECOND', '新人第二单券', 'fixed_off', 15.00, NULL, NULL,
|
||
150, 0, 0, 1,
|
||
3, NULL, NULL, 30,
|
||
NULL, 'newcomer', 1, '首单派送成功后解锁,实付基础运费满 150',
|
||
0, 0, NOW(), 0, NOW()
|
||
WHERE NOT EXISTS (
|
||
SELECT 1 FROM `t_coupon_template` x WHERE x.`IsDeleted` = 0 AND x.`TemplateCode` = 'NEWCOMER_SECOND'
|
||
);
|
||
|
||
-- 新人备货券 20 元,满 200,注册后 60 天
|
||
INSERT INTO `t_coupon_template` (
|
||
`TemplateCode`, `TemplateName`, `CouponType`, `FaceValue`, `DiscountRate`, `MaxDiscountAmount`,
|
||
`MinOrderAmount`, `TotalQuantity`, `IssuedQuantity`, `PerCustomerLimit`,
|
||
`ValidType`, `ValidStartTime`, `ValidEndTime`, `ValidDaysAfterReceive`,
|
||
`ApplyScopeJson`, `GrantChannel`, `Status`, `Remark`,
|
||
`IsDeleted`, `CreateUserId`, `CreateTime`, `UpdateUserId`, `UpdateTime`
|
||
)
|
||
SELECT
|
||
'NEWCOMER_STOCK', '新人备货券', 'fixed_off', 20.00, NULL, NULL,
|
||
200, 0, 0, 1,
|
||
2, NULL, NULL, 60,
|
||
NULL, 'newcomer', 1, '注册自动下发,实付基础运费满 200',
|
||
0, 0, NOW(), 0, NOW()
|
||
WHERE NOT EXISTS (
|
||
SELECT 1 FROM `t_coupon_template` x WHERE x.`IsDeleted` = 0 AND x.`TemplateCode` = 'NEWCOMER_STOCK'
|
||
);
|
||
|
||
-- 裂变:老客 20 元无门槛
|
||
INSERT INTO `t_coupon_template` (
|
||
`TemplateCode`, `TemplateName`, `CouponType`, `FaceValue`, `DiscountRate`, `MaxDiscountAmount`,
|
||
`MinOrderAmount`, `TotalQuantity`, `IssuedQuantity`, `PerCustomerLimit`,
|
||
`ValidType`, `ValidStartTime`, `ValidEndTime`, `ValidDaysAfterReceive`,
|
||
`ApplyScopeJson`, `GrantChannel`, `Status`, `Remark`,
|
||
`IsDeleted`, `CreateUserId`, `CreateTime`, `UpdateUserId`, `UpdateTime`
|
||
)
|
||
SELECT
|
||
'REFERRAL_INVITER', '邀请有礼券', 'fixed_off', 20.00, NULL, NULL,
|
||
0, 0, 0, 9999,
|
||
2, NULL, NULL, 30,
|
||
NULL, 'referral', 1, '被邀请人首单派送成功后发给邀请人(每位被邀请人最多触发一次)',
|
||
0, 0, NOW(), 0, NOW()
|
||
WHERE NOT EXISTS (
|
||
SELECT 1 FROM `t_coupon_template` x WHERE x.`IsDeleted` = 0 AND x.`TemplateCode` = 'REFERRAL_INVITER'
|
||
);
|
||
|
||
-- 已存在的邀请有礼券:放宽每人限领,避免仅首个被邀请人能给邀请人发券
|
||
UPDATE `t_coupon_template`
|
||
SET `PerCustomerLimit` = 9999,
|
||
`Remark` = '被邀请人首单派送成功后发给邀请人(每位被邀请人最多触发一次)',
|
||
`UpdateTime` = NOW()
|
||
WHERE `IsDeleted` = 0
|
||
AND `TemplateCode` = 'REFERRAL_INVITER'
|
||
AND `PerCustomerLimit` < 9999;
|
||
|
||
-- 裂变:新客额外 5 元
|
||
INSERT INTO `t_coupon_template` (
|
||
`TemplateCode`, `TemplateName`, `CouponType`, `FaceValue`, `DiscountRate`, `MaxDiscountAmount`,
|
||
`MinOrderAmount`, `TotalQuantity`, `IssuedQuantity`, `PerCustomerLimit`,
|
||
`ValidType`, `ValidStartTime`, `ValidEndTime`, `ValidDaysAfterReceive`,
|
||
`ApplyScopeJson`, `GrantChannel`, `Status`, `Remark`,
|
||
`IsDeleted`, `CreateUserId`, `CreateTime`, `UpdateUserId`, `UpdateTime`
|
||
)
|
||
SELECT
|
||
'REFERRAL_INVITEE', '邀请注册加赠券', 'fixed_off', 5.00, NULL, NULL,
|
||
0, 0, 0, 1,
|
||
2, NULL, NULL, 30,
|
||
NULL, 'referral', 1, '被邀请人注册即发 5 元券',
|
||
0, 0, NOW(), 0, NOW()
|
||
WHERE NOT EXISTS (
|
||
SELECT 1 FROM `t_coupon_template` x WHERE x.`IsDeleted` = 0 AND x.`TemplateCode` = 'REFERRAL_INVITEE'
|
||
);
|
||
|
||
-- =============================================================================
|
||
-- migrate_referral_invite_reward.sql
|
||
-- 邀请奖励:按实付基础运费百分比、T+N 工作日入运费余额、退款标记(可重复执行)
|
||
-- =============================================================================
|
||
SET @db := DATABASE();
|
||
|
||
-- ---------- t_order.IsRefunded ----------
|
||
SET @col := (
|
||
SELECT COUNT(1)
|
||
FROM information_schema.COLUMNS
|
||
WHERE TABLE_SCHEMA = @db
|
||
AND TABLE_NAME = 't_order'
|
||
AND COLUMN_NAME = 'IsRefunded'
|
||
);
|
||
SET @sql := IF(
|
||
@col = 0,
|
||
'ALTER TABLE `t_order`
|
||
ADD COLUMN `IsRefunded` TINYINT(1) NOT NULL DEFAULT 0 COMMENT ''是否已退款(分成计次排除)'' AFTER `IsPaid`',
|
||
'SELECT ''t_order.IsRefunded already exists'' AS info'
|
||
);
|
||
PREPARE stmt FROM @sql;
|
||
EXECUTE stmt;
|
||
DEALLOCATE PREPARE stmt;
|
||
|
||
-- ---------- t_referral_commission_rule 新字段 ----------
|
||
SET @col := (
|
||
SELECT COUNT(1)
|
||
FROM information_schema.COLUMNS
|
||
WHERE TABLE_SCHEMA = @db
|
||
AND TABLE_NAME = 't_referral_commission_rule'
|
||
AND COLUMN_NAME = 'MinInviteLevelCode'
|
||
);
|
||
SET @sql := IF(
|
||
@col = 0,
|
||
'ALTER TABLE `t_referral_commission_rule`
|
||
ADD COLUMN `MinInviteLevelCode` VARCHAR(16) NOT NULL DEFAULT ''V1'' COMMENT ''邀请资格最低等级'' AFTER `MonthlyCap`,
|
||
ADD COLUMN `MinPaidBaseFreight` DECIMAL(18,2) NOT NULL DEFAULT 50.00 COMMENT ''计奖最低实付基础运费'' AFTER `MinInviteLevelCode`,
|
||
ADD COLUMN `FirstOrderRate` DECIMAL(8,4) NOT NULL DEFAULT 0.0500 COMMENT ''首单奖励比例'' AFTER `MinPaidBaseFreight`,
|
||
ADD COLUMN `FirstOrderCap` DECIMAL(18,2) NOT NULL DEFAULT 50.00 COMMENT ''首单奖励封顶'' AFTER `FirstOrderRate`,
|
||
ADD COLUMN `FollowOrderRate` DECIMAL(8,4) NOT NULL DEFAULT 0.0300 COMMENT ''后续单奖励比例'' AFTER `FirstOrderCap`,
|
||
ADD COLUMN `FollowOrderCap` DECIMAL(18,2) NOT NULL DEFAULT 30.00 COMMENT ''后续单奖励封顶'' AFTER `FollowOrderRate`,
|
||
ADD COLUMN `FollowWindowDays` INT NOT NULL DEFAULT 90 COMMENT ''后续单注册后天数窗口'' AFTER `FollowOrderCap`,
|
||
ADD COLUMN `MaxRewardOrders` INT NOT NULL DEFAULT 6 COMMENT ''最多计奖订单数'' AFTER `FollowWindowDays`,
|
||
ADD COLUMN `SettleBusinessDays` INT NOT NULL DEFAULT 3 COMMENT ''派送成功后结算工作日'' AFTER `MaxRewardOrders`',
|
||
'SELECT ''t_referral_commission_rule reward columns already exist'' AS info'
|
||
);
|
||
PREPARE stmt FROM @sql;
|
||
EXECUTE stmt;
|
||
DEALLOCATE PREPARE stmt;
|
||
|
||
UPDATE `t_referral_commission_rule`
|
||
SET
|
||
`CommissionMode` = 'percent_of_paid_base_freight',
|
||
`SettleTriggerOrderStatus` = 'deliverySuccess',
|
||
`SettleBusinessDays` = CASE WHEN `SettleBusinessDays` > 0 THEN `SettleBusinessDays` ELSE 3 END,
|
||
`FreezeDays` = CASE WHEN `SettleBusinessDays` > 0 THEN `SettleBusinessDays` ELSE 3 END,
|
||
`UpdateTime` = NOW()
|
||
WHERE `IsDeleted` = 0;
|
||
|
||
-- ---------- t_referral_commission_detail ----------
|
||
SET @col := (
|
||
SELECT COUNT(1)
|
||
FROM information_schema.COLUMNS
|
||
WHERE TABLE_SCHEMA = @db
|
||
AND TABLE_NAME = 't_referral_commission_detail'
|
||
AND COLUMN_NAME = 'SettleDueTime'
|
||
);
|
||
SET @sql := IF(
|
||
@col = 0,
|
||
'ALTER TABLE `t_referral_commission_detail`
|
||
ADD COLUMN `SettleDueTime` DATETIME NULL COMMENT ''计划结算时间'' AFTER `EligibleTime`',
|
||
'SELECT ''SettleDueTime already exists'' AS info'
|
||
);
|
||
PREPARE stmt FROM @sql;
|
||
EXECUTE stmt;
|
||
DEALLOCATE PREPARE stmt;
|
||
|
||
SET @col := (
|
||
SELECT COUNT(1)
|
||
FROM information_schema.COLUMNS
|
||
WHERE TABLE_SCHEMA = @db
|
||
AND TABLE_NAME = 't_referral_commission_detail'
|
||
AND COLUMN_NAME = 'RewardOrderIndex'
|
||
);
|
||
SET @sql := IF(
|
||
@col = 0,
|
||
'ALTER TABLE `t_referral_commission_detail`
|
||
ADD COLUMN `RewardOrderIndex` INT NOT NULL DEFAULT 0 COMMENT ''被邀请人第几单'' AFTER `SettleDueTime`',
|
||
'SELECT ''RewardOrderIndex already exists'' AS info'
|
||
);
|
||
PREPARE stmt FROM @sql;
|
||
EXECUTE stmt;
|
||
DEALLOCATE PREPARE stmt;
|
||
|
||
UPDATE `t_coupon_template`
|
||
SET
|
||
`Remark` = '被邀请人注册即发 5 元券',
|
||
`UpdateTime` = NOW()
|
||
WHERE `IsDeleted` = 0
|
||
AND `TemplateCode` = 'REFERRAL_INVITEE';
|
||
|
||
-- =============================================================================
|
||
-- migrate_kpi_area_info_match.sql
|
||
-- 存量库:分区明细增加匹配维度/方式/前缀长度(可重复执行)
|
||
-- =============================================================================
|
||
SET @db := DATABASE();
|
||
|
||
SET @col := (
|
||
SELECT COUNT(1)
|
||
FROM information_schema.COLUMNS
|
||
WHERE TABLE_SCHEMA = @db
|
||
AND TABLE_NAME = 't_kpi_area_info'
|
||
AND COLUMN_NAME = 'MatchDim'
|
||
);
|
||
SET @sql := IF(
|
||
@col = 0,
|
||
'ALTER TABLE `t_kpi_area_info`
|
||
ADD COLUMN `MatchDim` VARCHAR(16) NOT NULL DEFAULT ''country'' COMMENT ''匹配维度:zip/state/city/country'' AFTER `RightPostcode`,
|
||
ADD COLUMN `MatchMode` VARCHAR(16) NOT NULL DEFAULT ''all'' COMMENT ''匹配方式:prefix/exact/range/all'' AFTER `MatchDim`,
|
||
ADD COLUMN `PrefixLen` INT NOT NULL DEFAULT 0 COMMENT ''邮编前缀长度(zip+prefix)'' AFTER `MatchMode`',
|
||
'SELECT ''kpi area match columns already exist'' AS info'
|
||
);
|
||
PREPARE stmt FROM @sql;
|
||
EXECUTE stmt;
|
||
DEALLOCATE PREPARE stmt;
|
||
|
||
SET @idx := (
|
||
SELECT COUNT(1)
|
||
FROM information_schema.STATISTICS
|
||
WHERE TABLE_SCHEMA = @db
|
||
AND TABLE_NAME = 't_kpi_area_info'
|
||
AND INDEX_NAME = 'idx_kpi_info_area_dim'
|
||
);
|
||
SET @sql := IF(
|
||
@idx = 0,
|
||
'ALTER TABLE `t_kpi_area_info` ADD KEY `idx_kpi_info_area_dim` (`AreaId`, `CountryCode`, `MatchDim`)',
|
||
'SELECT ''idx_kpi_info_area_dim already exists'' AS info'
|
||
);
|
||
PREPARE stmt FROM @sql;
|
||
EXECUTE stmt;
|
||
DEALLOCATE PREPARE stmt;
|
||
|
||
UPDATE `t_kpi_area_info`
|
||
SET
|
||
`MatchDim` = CASE
|
||
WHEN IFNULL(`LeftPostcode`, '') <> '' OR IFNULL(`RightPostcode`, '') <> '' THEN 'zip'
|
||
WHEN IFNULL(`City`, '') <> '' THEN 'city'
|
||
WHEN IFNULL(`Province`, '') <> '' THEN 'state'
|
||
ELSE 'country'
|
||
END,
|
||
`MatchMode` = CASE
|
||
WHEN IFNULL(`LeftPostcode`, '') <> '' AND IFNULL(`RightPostcode`, '') = '' THEN 'prefix'
|
||
WHEN IFNULL(`LeftPostcode`, '') <> '' AND `LeftPostcode` = `RightPostcode` THEN 'exact'
|
||
WHEN IFNULL(`LeftPostcode`, '') <> '' AND IFNULL(`RightPostcode`, '') <> '' THEN 'range'
|
||
WHEN IFNULL(`City`, '') <> '' OR IFNULL(`Province`, '') <> '' THEN 'exact'
|
||
ELSE 'all'
|
||
END,
|
||
`PrefixLen` = CASE
|
||
WHEN IFNULL(`LeftPostcode`, '') <> '' AND IFNULL(`RightPostcode`, '') = '' THEN CHAR_LENGTH(`LeftPostcode`)
|
||
WHEN IFNULL(`LeftPostcode`, '') <> '' AND `LeftPostcode` = `RightPostcode` THEN CHAR_LENGTH(`LeftPostcode`)
|
||
WHEN IFNULL(`LeftPostcode`, '') <> '' AND IFNULL(`RightPostcode`, '') <> '' THEN LEAST(CHAR_LENGTH(`LeftPostcode`), CHAR_LENGTH(`RightPostcode`))
|
||
ELSE 0
|
||
END
|
||
WHERE IFNULL(`MatchDim`, '') IN ('', 'country')
|
||
AND (
|
||
IFNULL(`LeftPostcode`, '') <> ''
|
||
OR IFNULL(`RightPostcode`, '') <> ''
|
||
OR IFNULL(`Province`, '') <> ''
|
||
OR IFNULL(`City`, '') <> ''
|
||
);
|
||
|
||
-- =============================================================================
|
||
-- migrate_kpi_area_info_area_id_index.sql
|
||
-- 分区明细按 AreaId 全量/分页查询时避免 filesort 打满 sort_buffer(查价 LIVE 路径易踩)
|
||
-- =============================================================================
|
||
SET @db := DATABASE();
|
||
|
||
SET @idx := (
|
||
SELECT COUNT(1)
|
||
FROM information_schema.STATISTICS
|
||
WHERE TABLE_SCHEMA = @db
|
||
AND TABLE_NAME = 't_kpi_area_info'
|
||
AND INDEX_NAME = 'idx_kpi_info_area_id'
|
||
);
|
||
SET @sql := IF(
|
||
@idx = 0,
|
||
'ALTER TABLE `t_kpi_area_info` ADD KEY `idx_kpi_info_area_id` (`AreaId`, `Id`)',
|
||
'SELECT ''idx_kpi_info_area_id already exists'' AS info'
|
||
);
|
||
PREPARE stmt FROM @sql;
|
||
EXECUTE stmt;
|
||
DEALLOCATE PREPARE stmt;
|
||
|
||
-- =============================================================================
|
||
-- migrate_kpi_area_publish_record.sql
|
||
-- 分区包发布表(价区 / 黑名单 / 偏远):卖价/规则发布钉包,计费按 version 加载
|
||
-- =============================================================================
|
||
SET @db := DATABASE();
|
||
|
||
SET @tbl := (
|
||
SELECT COUNT(1)
|
||
FROM information_schema.TABLES
|
||
WHERE TABLE_SCHEMA = @db
|
||
AND TABLE_NAME = 't_kpi_area_publish_record'
|
||
);
|
||
SET @sql := IF(
|
||
@tbl = 0,
|
||
'CREATE TABLE `t_kpi_area_publish_record` (
|
||
`Id` INT NOT NULL AUTO_INCREMENT COMMENT ''主键'',
|
||
`AreaId` INT NOT NULL COMMENT ''所属分区表 t_kpi_area.Id'',
|
||
`AreaType` VARCHAR(32) NOT NULL COMMENT ''分区类型:price=价格分区,blacklist=黑名单,remote=偏远'',
|
||
`Version` VARCHAR(32) NOT NULL COMMENT ''包版本号(yyyyMMddHHmmssfff)'',
|
||
`Status` TINYINT NOT NULL DEFAULT 1 COMMENT ''状态:1=生效 Active,2=失效 Inactive'',
|
||
`ContentHash` VARCHAR(64) NOT NULL COMMENT ''规范化分区明细 Content 的 SHA256(hex),同 AreaId+Hash 去重复用'',
|
||
`Content` JSON NULL COMMENT ''分区明细快照 JSON(KpiAreaSnapshotRuleDto 数组)'',
|
||
`PublishUser` VARCHAR(64) NOT NULL DEFAULT '''' COMMENT ''发布人'',
|
||
`PublishTime` DATETIME NOT NULL COMMENT ''发布时间'',
|
||
`Description` VARCHAR(512) NULL COMMENT ''发布说明'',
|
||
`IsDeleted` TINYINT(1) NOT NULL DEFAULT 0 COMMENT ''软删除:0=否,1=是'',
|
||
`CreateUserId` INT NOT NULL DEFAULT 0 COMMENT ''创建人'',
|
||
`CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT ''创建时间'',
|
||
`UpdateUserId` INT NULL COMMENT ''更新人'',
|
||
`UpdateTime` DATETIME NULL COMMENT ''更新时间'',
|
||
PRIMARY KEY (`Id`),
|
||
UNIQUE KEY `uk_kpi_pack_area_hash` (`AreaId`, `ContentHash`),
|
||
KEY `idx_kpi_pack_area_ver` (`AreaId`, `Version`),
|
||
KEY `idx_kpi_pack_area_type_time` (`AreaId`, `AreaType`, `PublishTime`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT=''KPI分区发布包(价区/黑名单/偏远明细不可变快照)''',
|
||
'SELECT ''t_kpi_area_publish_record already exists'' AS info'
|
||
);
|
||
PREPARE stmt FROM @sql;
|
||
EXECUTE stmt;
|
||
DEALLOCATE PREPARE stmt;
|
||
|
||
-- 表已存在时回填表/字段注释(可重复执行;不包进 PREPARE)
|
||
ALTER TABLE `t_kpi_area_publish_record`
|
||
COMMENT = 'KPI分区发布包(价区/黑名单/偏远明细不可变快照)',
|
||
MODIFY COLUMN `Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||
MODIFY COLUMN `AreaId` INT NOT NULL COMMENT '所属分区表 t_kpi_area.Id',
|
||
MODIFY COLUMN `AreaType` VARCHAR(32) NOT NULL COMMENT '分区类型:price=价格分区,blacklist=黑名单,remote=偏远',
|
||
MODIFY COLUMN `Version` VARCHAR(32) NOT NULL COMMENT '包版本号(yyyyMMddHHmmssfff)',
|
||
MODIFY COLUMN `Status` TINYINT NOT NULL DEFAULT 1 COMMENT '状态:1=生效 Active,2=失效 Inactive',
|
||
MODIFY COLUMN `ContentHash` VARCHAR(64) NOT NULL COMMENT '规范化分区明细 Content 的 SHA256(hex),同 AreaId+Hash 去重复用',
|
||
MODIFY COLUMN `Content` JSON NULL COMMENT '分区明细快照 JSON(KpiAreaSnapshotRuleDto 数组)',
|
||
MODIFY COLUMN `PublishUser` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '发布人',
|
||
MODIFY COLUMN `PublishTime` DATETIME NOT NULL COMMENT '发布时间',
|
||
MODIFY COLUMN `Description` VARCHAR(512) NULL COMMENT '发布说明',
|
||
MODIFY COLUMN `IsDeleted` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '软删除:0=否,1=是',
|
||
MODIFY COLUMN `CreateUserId` INT NOT NULL DEFAULT 0 COMMENT '创建人',
|
||
MODIFY COLUMN `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||
MODIFY COLUMN `UpdateUserId` INT NULL COMMENT '更新人',
|
||
MODIFY COLUMN `UpdateTime` DATETIME NULL COMMENT '更新时间';
|
||
|
||
-- =============================================================================
|
||
-- migrate_customer_export_qualification_comment.sql
|
||
-- 存量库:补 t_customer_export_qualification 表注释与字段注释(可重复执行)
|
||
-- 列类型、空值、默认值与 db.sql 一致,只回填 COMMENT。
|
||
-- 请直接执行本段,不要包进 PREPARE。
|
||
-- =============================================================================
|
||
ALTER TABLE `t_customer_export_qualification`
|
||
COMMENT = '客户出口资质备案',
|
||
MODIFY COLUMN `Id` INT NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||
MODIFY COLUMN `CustomerId` INT NOT NULL COMMENT '归属客户 t_customer.Id',
|
||
MODIFY COLUMN `CompanyName` VARCHAR(200) NOT NULL COMMENT '企业名称',
|
||
MODIFY COLUMN `SocialCreditCode` VARCHAR(64) NOT NULL COMMENT '企业社会信用代码',
|
||
MODIFY COLUMN `DomesticConsignor` VARCHAR(200) NOT NULL COMMENT '境内发货人',
|
||
MODIFY COLUMN `DomesticConsignorCustomsCode` VARCHAR(64) NULL COMMENT '境内发货人海关代码',
|
||
MODIFY COLUMN `ProducerName` VARCHAR(200) NOT NULL COMMENT '生产销售单位',
|
||
MODIFY COLUMN `ProducerCustomsCode` VARCHAR(64) NULL COMMENT '生产销售单位海关代码',
|
||
MODIFY COLUMN `CustomsPort` VARCHAR(100) NULL COMMENT '备案海关港口地',
|
||
MODIFY COLUMN `IsDefault` TINYINT NOT NULL DEFAULT 0 COMMENT '是否默认:0-否,1-是(同客户仅一条)',
|
||
MODIFY COLUMN `Remark` VARCHAR(512) NULL COMMENT '备注',
|
||
MODIFY COLUMN `IsDeleted` TINYINT NOT NULL DEFAULT 0 COMMENT '软删除:0-否,1-是',
|
||
MODIFY COLUMN `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()) COMMENT '并发戳',
|
||
MODIFY COLUMN `CreateUserId` INT NOT NULL DEFAULT 0 COMMENT '创建人',
|
||
MODIFY COLUMN `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||
MODIFY COLUMN `UpdateUserId` INT NULL COMMENT '更新人',
|
||
MODIFY COLUMN `UpdateTime` DATETIME NULL COMMENT '更新时间';
|
||
|
||
-- =============================================================================
|
||
-- migrate_warehouse_address_sort_remark.sql
|
||
-- 仓库地址:展示排序(选填<E98089><E5A1AB>? 备注(选填<E98089><E5A1AB>?
|
||
-- =============================================================================
|
||
SET @db := DATABASE();
|
||
|
||
SET @col := (
|
||
SELECT COUNT(1)
|
||
FROM information_schema.COLUMNS
|
||
WHERE TABLE_SCHEMA = @db
|
||
AND TABLE_NAME = 't_warehouse_address'
|
||
AND COLUMN_NAME = 'Sort'
|
||
);
|
||
SET @sql := IF(
|
||
@col = 0,
|
||
'ALTER TABLE `t_warehouse_address`
|
||
ADD COLUMN `Sort` INT NULL DEFAULT NULL COMMENT ''展示排序,越小越靠前'' AFTER `ShippingAddress`',
|
||
'SELECT ''Sort already exists'' AS info'
|
||
);
|
||
PREPARE stmt FROM @sql;
|
||
EXECUTE stmt;
|
||
DEALLOCATE PREPARE stmt;
|
||
|
||
SET @col := (
|
||
SELECT COUNT(1)
|
||
FROM information_schema.COLUMNS
|
||
WHERE TABLE_SCHEMA = @db
|
||
AND TABLE_NAME = 't_warehouse_address'
|
||
AND COLUMN_NAME = 'Remark'
|
||
);
|
||
SET @sql := IF(
|
||
@col = 0,
|
||
'ALTER TABLE `t_warehouse_address`
|
||
ADD COLUMN `Remark` VARCHAR(512) NULL DEFAULT NULL COMMENT ''备注'' AFTER `Sort`',
|
||
'SELECT ''Remark already exists'' AS info'
|
||
);
|
||
PREPARE stmt FROM @sql;
|
||
EXECUTE stmt;
|
||
DEALLOCATE PREPARE stmt;
|
||
|