1748 lines
108 KiB
Markdown
1748 lines
108 KiB
Markdown
-- VIP等级表新增流水返利百分比字段
|
||
ALTER TABLE tt_vip_level ADD COLUMN flow_rebate_percent DECIMAL(10,4) DEFAULT 0.0000 COMMENT 'VIP流水返利百分比(%),如 2.0000 代表 2%';
|
||
|
||
新增疯狂转盘/极速糖果维护配置
|
||
INSERT INTO sys_config (config_name, config_key, config_value, config_type, create_by, create_time, remark)
|
||
VALUES ('疯狂转盘维护', 'wheelMaintenance', '0', 'Y', 'admin', NOW(), '疯狂转盘维护开关 0正常 1维护');
|
||
|
||
INSERT INTO sys_config (config_name, config_key, config_value, config_type, create_by, create_time, remark)
|
||
VALUES ('极速糖果维护', 'sweetMaintenance', '0', 'Y', 'admin', NOW(), '极速糖果维护开关 0正常 1维护');
|
||
|
||
新增充值维护配置
|
||
INSERT INTO sys_config (config_name, config_key, config_value, config_type, create_by, create_time, remark)
|
||
VALUES ('充值维护', 'rechargeMaintenance', '0', 'Y', 'admin', NOW(), '充值维护开关 0正常 1维护');
|
||
|
||
添加公告类型
|
||
ALTER TABLE tt_announcement
|
||
ADD COLUMN `type` TINYINT NOT NULL DEFAULT 0 COMMENT '公告类型 0用户公告 1系统公告' AFTER content;
|
||
|
||
ALTER TABLE tt_announcement MODIFY COLUMN title VARCHAR(255) NULL;
|
||
|
||
|
||
添加索引
|
||
ALTER TABLE tt_box_records
|
||
ADD INDEX idx_tbr_holder_status_time (holder_user_id, status, create_time);
|
||
|
||
ALTER TABLE tt_upgrade_record
|
||
ADD INDEX idx_tur_victory_gain (is_victory, gain_ornaments_price);
|
||
|
||
|
||
添加公告目标用户
|
||
ALTER TABLE tt_announcement ADD COLUMN target_user_id BIGINT DEFAULT NULL COMMENT '目标用户ID,NULL表示全部用户';
|
||
|
||
公告加对个人
|
||
ALTER TABLE tt_box_type ADD COLUMN is_show VARCHAR(2) DEFAULT '0' COMMENT '是否前端显示 0-显示 1-隐藏';
|
||
|
||
增加字典数据
|
||
INSERT INTO sys_config (config_name, config_key, config_value, config_type, create_by, create_time, remark)
|
||
VALUES ('西部对决维护', 'westernDuelMaintenance', '0', 'Y', 'admin', NOW(), '西部对决维护开关 0正常 1维护');
|
||
|
||
INSERT INTO sys_config (config_name, config_key, config_value, config_type, create_by, create_time, remark)
|
||
VALUES ('幸运升级维护', 'luckyUpgradeMaintenance', '0', 'Y', 'admin', NOW(), '幸运升级维护开关 0正常 1维护');
|
||
|
||
-- 推广后台角色菜单权限表(按用户类型分配菜单,支持排序)
|
||
CREATE TABLE `promo_role_menu` (
|
||
`id` INT NOT NULL AUTO_INCREMENT,
|
||
`role_type` VARCHAR(10) NOT NULL COMMENT '用户类型: 01=主播, 04=招商, 05=卡商',
|
||
`menu_path` VARCHAR(255) NOT NULL COMMENT '菜单路径',
|
||
`sort_order` INT DEFAULT 0 COMMENT '排序序号,越小越靠前',
|
||
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||
PRIMARY KEY (`id`),
|
||
UNIQUE KEY `uk_role_menu` (`role_type`, `menu_path`),
|
||
KEY `idx_role_type` (`role_type`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='推广后台角色菜单权限表';
|
||
|
||
-- 推广后台管理员表(独立于tt_user前端用户表)
|
||
CREATE TABLE `promo_admin` (
|
||
`id` INT NOT NULL AUTO_INCREMENT,
|
||
`username` VARCHAR(50) NOT NULL COMMENT '登录账号(手机号)',
|
||
`password` VARCHAR(100) NOT NULL COMMENT '密码(BCrypt加密)',
|
||
`nick_name` VARCHAR(50) DEFAULT '管理员' COMMENT '昵称',
|
||
`phone_number` VARCHAR(20) DEFAULT NULL COMMENT '手机号',
|
||
`email` VARCHAR(64) DEFAULT NULL COMMENT '邮箱',
|
||
`avatar` TEXT DEFAULT NULL COMMENT '头像(base64 dataURL)',
|
||
`status` CHAR(1) DEFAULT '0' COMMENT '状态 0正常 1停用',
|
||
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||
PRIMARY KEY (`id`),
|
||
UNIQUE KEY `uk_username` (`username`),
|
||
KEY `idx_phone_number` (`phone_number`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='推广后台管理员表';
|
||
|
||
-- 老库升级(已存在 promo_admin 表时执行这几条 + 回填手机号)
|
||
-- ALTER TABLE promo_admin ADD COLUMN phone_number VARCHAR(20) DEFAULT NULL COMMENT '手机号' AFTER nick_name;
|
||
-- ALTER TABLE promo_admin ADD COLUMN email VARCHAR(64) DEFAULT NULL COMMENT '邮箱' AFTER phone_number;
|
||
-- ALTER TABLE promo_admin ADD COLUMN avatar TEXT DEFAULT NULL COMMENT '头像(base64 dataURL)' AFTER email;
|
||
-- ALTER TABLE promo_admin ADD KEY idx_phone_number (phone_number);
|
||
-- UPDATE promo_admin SET phone_number = username WHERE phone_number IS NULL OR phone_number = '';
|
||
|
||
-- 插入超级管理员账号(密码: admin123)
|
||
-- BCrypt加密后的值需根据实际环境生成,这里给出模板
|
||
INSERT INTO promo_admin (username, password, nick_name, status, create_time)
|
||
VALUES ('admin', '$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2', '超级管理员', '0', NOW());
|
||
|
||
-- 卡商卡密表(推广后台独立卡密系统)
|
||
CREATE TABLE `promo_card_key` (
|
||
`id` BIGINT NOT NULL AUTO_INCREMENT,
|
||
`card_code` VARCHAR(32) NOT NULL COMMENT '卡密编码(唯一)',
|
||
`amount` DECIMAL(10,2) NOT NULL COMMENT '面值金额',
|
||
`recharge_list_id` INT DEFAULT NULL COMMENT '充值列表ID',
|
||
`creator_id` BIGINT NOT NULL COMMENT '创建者ID(卡商)',
|
||
`creator_name` VARCHAR(50) DEFAULT '' COMMENT '创建者名称',
|
||
`used_by_id` BIGINT DEFAULT NULL COMMENT '使用者ID',
|
||
`used_by_name` VARCHAR(50) DEFAULT NULL COMMENT '使用者名称',
|
||
`used_time` DATETIME DEFAULT NULL COMMENT '使用时间',
|
||
`status` TINYINT NOT NULL DEFAULT 0 COMMENT '状态: 0=未使用, 1=已使用',
|
||
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||
PRIMARY KEY (`id`),
|
||
UNIQUE KEY `uk_card_code` (`card_code`),
|
||
KEY `idx_creator_id` (`creator_id`),
|
||
KEY `idx_status` (`status`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='卡商卡密表';
|
||
|
||
-- 推广后台菜单配置表(所有可分配的菜单从这里读取,不再硬编码)
|
||
CREATE TABLE `promo_menu_config` (
|
||
`id` INT NOT NULL AUTO_INCREMENT,
|
||
`menu_path` VARCHAR(255) NOT NULL COMMENT '菜单路径',
|
||
`menu_label` VARCHAR(100) NOT NULL COMMENT '菜单显示名称',
|
||
`sort_order` INT DEFAULT 0 COMMENT '排序序号',
|
||
PRIMARY KEY (`id`),
|
||
UNIQUE KEY `uk_menu_path` (`menu_path`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='推广后台菜单配置表';
|
||
|
||
-- 初始菜单数据(menu_label必须与前端路由title一致)
|
||
INSERT INTO promo_menu_config (menu_path, menu_label, sort_order) VALUES
|
||
('/home/index', '首页', 1),
|
||
('/dashboard/index', '数据面板', 2),
|
||
('/user/index', '个人信息', 3),
|
||
('/mymoney/index', '我的统计', 4),
|
||
('/turnover/index', '流水明细', 5),
|
||
('/subFlow/index', '下级流水', 6),
|
||
('/cardMerchant/index', '卡密管理', 7),
|
||
('/permission/index', '权限管理', 8),
|
||
('/businessManage/index', '招商管理', 9),
|
||
('/anchorManage/index', '主播管理', 10),
|
||
('/cardMerchantManage/index', '卡商管理', 11);
|
||
|
||
-- 修正已有菜单标签(如果表中已有数据,执行以下UPDATE)
|
||
UPDATE promo_menu_config SET menu_label = '数据面板' WHERE menu_path = '/dashboard/index';
|
||
UPDATE promo_menu_config SET menu_label = '我的统计' WHERE menu_path = '/mymoney/index';
|
||
UPDATE promo_menu_config SET menu_label = '流水明细' WHERE menu_path = '/turnover/index';
|
||
UPDATE promo_menu_config SET menu_label = '下级流水' WHERE menu_path = '/subFlow/index';
|
||
|
||
-- 新增超管专属页面菜单
|
||
INSERT IGNORE INTO promo_menu_config (menu_path, menu_label, sort_order) VALUES
|
||
('/businessManage/index', '招商管理', 9),
|
||
('/anchorManage/index', '主播管理', 10),
|
||
('/cardMerchantManage/index', '卡商管理', 11);
|
||
|
||
-- 新增9个页面菜单配置
|
||
INSERT IGNORE INTO promo_menu_config (menu_path, menu_label, sort_order) VALUES
|
||
('/mySubordinates/index', '我的下级', 12),
|
||
('/flowRecord/index', '流水记录', 13),
|
||
('/cdkeyCreate/index', '创建CDKEY记录', 14),
|
||
('/cdkeyRedeem/index', '兑换CDKEY记录', 15),
|
||
('/cdkeyCreateDaily/index', '创建CDKEY日报', 16),
|
||
('/cdkeyRedeemDaily/index', '兑换CDKEY日报', 17),
|
||
('/rollRoom/index', 'ROLL房管理', 18),
|
||
('/commissionReport/index', '返点报表', 19),
|
||
('/subordinateRecharge/index', '下级充值报表', 20);
|
||
|
||
-- 新增「管理员管理」菜单
|
||
-- ① 菜单注册表(前端路由 + 权限管理页可勾选列表都从这里读)
|
||
INSERT IGNORE INTO promo_menu_config (menu_path, menu_label, sort_order) VALUES
|
||
('/adminManage/index', '管理员管理', 21);
|
||
|
||
-- ② 给超级管理员角色授权(role_type=99 已有配置行时必须补这行,否则侧边栏不显示;
|
||
-- 也可以直接去「权限管理 → 超级管理员 → 勾选管理员管理 → 保存权限」)
|
||
INSERT IGNORE INTO promo_role_menu (role_type, menu_path, sort_order) VALUES
|
||
('99', '/adminManage/index', 21);
|
||
|
||
-- 修复 user_type 字典:补充卡商类型(05)
|
||
INSERT IGNORE INTO sys_dict_data (dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, status, create_by, create_time, remark)
|
||
VALUES (5, '卡商', '05', 'user_type', '', '', 'N', '0', 'admin', NOW(), '卡商用户类型');
|
||
|
||
-- tt_user 表新增卡商专用余额字段
|
||
ALTER TABLE tt_user ADD COLUMN merchant_balance DECIMAL(18,2) DEFAULT 0.00 COMMENT '卡商专用余额(仅卡商用户使用)';
|
||
|
||
|
||
ALTER TABLE tt_box_ornaments ADD COLUMN odds_percentum VARCHAR(20) DEFAULT NULL COMMENT '显示爆率百分比';
|
||
|
||
ALTER TABLE tt_recharge_record ADD COLUMN card_merchant_id INT DEFAULT 0 COMMENT '卡商ID,默认0表示非卡商充值';
|
||
|
||
|
||
ALTER TABLE tt_user
|
||
ADD COLUMN new_game_commission_rate DECIMAL(10,4) DEFAULT NULL COMMENT '西部对决新游戏消费返点比例',
|
||
ADD COLUMN classic_game_commission_rate DECIMAL(10,4) DEFAULT NULL COMMENT '经典玩法游戏消费返点比例';
|
||
|
||
-- 推广CDKEY创建记录表
|
||
CREATE TABLE `promo_cdkey` (
|
||
`id` BIGINT NOT NULL AUTO_INCREMENT,
|
||
`title` VARCHAR(255) DEFAULT NULL COMMENT 'CDKEY标题',
|
||
`cdkey_code` VARCHAR(100) NOT NULL COMMENT 'CDKEY码(唯一)',
|
||
`amount_min` DECIMAL(12,2) NOT NULL DEFAULT 0 COMMENT '最低金额(金币)',
|
||
`amount_max` DECIMAL(12,2) NOT NULL DEFAULT 0 COMMENT '最高金额(金币)',
|
||
`num` INT NOT NULL DEFAULT 1 COMMENT '每个码可用次数',
|
||
`usable_count` INT NOT NULL DEFAULT 1 COMMENT '可用次数',
|
||
`used_count` INT NOT NULL DEFAULT 0 COMMENT '已用次数',
|
||
`description` VARCHAR(500) DEFAULT NULL COMMENT '描述',
|
||
`opening_time` DATETIME DEFAULT NULL COMMENT '开启时间',
|
||
`validity` DATETIME DEFAULT NULL COMMENT '有效期',
|
||
`status` TINYINT NOT NULL DEFAULT 0 COMMENT '状态: 0=进行中, 1=已结束',
|
||
`creator_id` BIGINT NOT NULL COMMENT '创建者ID',
|
||
`creator_name` VARCHAR(100) DEFAULT NULL COMMENT '创建者名称',
|
||
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||
PRIMARY KEY (`id`),
|
||
UNIQUE KEY `uk_cdkey_code` (`cdkey_code`),
|
||
KEY `idx_creator_id` (`creator_id`),
|
||
KEY `idx_status` (`status`),
|
||
KEY `idx_create_time` (`create_time`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='推广CDKEY创建记录表';
|
||
|
||
-- 推广CDKEY兑换记录表
|
||
CREATE TABLE `promo_cdkey_redeem` (
|
||
`id` BIGINT NOT NULL AUTO_INCREMENT,
|
||
`cdkey_id` BIGINT NOT NULL COMMENT '关联promo_cdkey.id',
|
||
`cdkey_code` VARCHAR(100) NOT NULL COMMENT 'CDKEY码',
|
||
`redeemer_id` BIGINT NOT NULL COMMENT '兑换者ID',
|
||
`redeemer_name` VARCHAR(100) DEFAULT NULL COMMENT '兑换者名称',
|
||
`unit_value` DECIMAL(12,2) NOT NULL COMMENT '单个价值(金币)',
|
||
`redeem_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '兑换时间',
|
||
PRIMARY KEY (`id`),
|
||
KEY `idx_cdkey_id` (`cdkey_id`),
|
||
KEY `idx_redeemer_id` (`redeemer_id`),
|
||
KEY `idx_redeem_time` (`redeem_time`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='推广CDKEY兑换记录表';
|
||
|
||
-- tt_recharge_card 表新增空白卡密标识字段
|
||
ALTER TABLE tt_recharge_card ADD COLUMN is_blank TINYINT DEFAULT 0 COMMENT '是否空白卡密: 0=否, 1=是(空白卡密用户使用后仅加余额,不计入充值记录)';
|
||
|
||
-- tt_recharge_record 表新增空白卡密标记字段(空白卡密产生的充值记录在充值记录列表中不展示)
|
||
ALTER TABLE tt_recharge_record ADD COLUMN is_blank_card TINYINT DEFAULT 0 COMMENT '是否空白卡密产生的充值记录: 0=否, 1=是';
|
||
|
||
-- tt_roll_jackpot_ornaments 表新增指定获奖用户字段(多个用户ID用英文逗号分隔)
|
||
ALTER TABLE tt_roll_jackpot_ornaments ADD COLUMN designated_user_id VARCHAR(500) DEFAULT NULL COMMENT '指定获奖用户ID,多个用英文逗号分隔,NULL表示不指定(随机分配)';
|
||
|
||
-- tt_user 表新增白号标识字段(白号:可正常游戏、可出现在榜单,但提货虚假成功、充值不计真实充值、不触发返佣)
|
||
ALTER TABLE tt_user ADD COLUMN is_blank_account TINYINT DEFAULT 0 COMMENT '是否白号: 0=否, 1=是';
|
||
|
||
-- 疯狂转盘返奖饰品表
|
||
CREATE TABLE game_wheel_prize_ornament (
|
||
id BIGINT NOT NULL AUTO_INCREMENT,
|
||
game_type VARCHAR(32) DEFAULT 'wheel',
|
||
name VARCHAR(100) NOT NULL,
|
||
image_url VARCHAR(500) DEFAULT NULL,
|
||
grade INT DEFAULT 1,
|
||
is_fallback TINYINT DEFAULT 0 COMMENT '是否兜底: 0否 1是',
|
||
sort INT DEFAULT 0,
|
||
status CHAR(1) DEFAULT '1',
|
||
create_time DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||
PRIMARY KEY (id)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='疯狂转盘返奖饰品';
|
||
|
||
CREATE TABLE game_wheel_prize_range (
|
||
id BIGINT NOT NULL AUTO_INCREMENT,
|
||
game_type VARCHAR(32) DEFAULT 'wheel',
|
||
win_low DECIMAL(14,2) NOT NULL DEFAULT 0.00 COMMENT '返奖金额下限',
|
||
win_high DECIMAL(14,2) NOT NULL DEFAULT 0.00 COMMENT '返奖金额上限',
|
||
ornament_id BIGINT NOT NULL,
|
||
sort INT DEFAULT 0,
|
||
PRIMARY KEY (id)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='疯狂转盘返奖区间';
|
||
|
||
-- 疯狂转盘返奖区间初始数据
|
||
INSERT INTO game_wheel_prize_range (game_type, win_low, win_high, ornament_id, sort) VALUES
|
||
('wheel', 0.01, 0.02, 1, 1),
|
||
('wheel', 0.02, 10.00, 2, 2),
|
||
('wheel', 10.00, 50.00, 3, 3),
|
||
('wheel', 50.00, 200.00, 4, 4),
|
||
('wheel', 200.00, 500.00, 5, 5),
|
||
('wheel', 500.00, 1000.00, 6, 6),
|
||
('wheel', 1000.00, 2000.00, 7, 7),
|
||
('wheel', 2000.00, 5000.00, 8, 8),
|
||
('wheel', 5000.00, 99999999.00, 9, 9);
|
||
|
||
-- 对战出金数据
|
||
ALTER TABLE tt_fight ADD COLUMN gold_drop JSON DEFAULT NULL COMMENT 'first gold ornament drop info for hall display';
|
||
|
||
-- 极速糖果步骤表:新增消除位置、下落数据、填充数据字段
|
||
ALTER TABLE game_sweet_step
|
||
ADD COLUMN removed_positions JSON DEFAULT NULL COMMENT '消除位置 [pos,...]' AFTER symbol_links,
|
||
ADD COLUMN drop_data JSON DEFAULT NULL COMMENT '下落数据 [{"from":int,"to":int,"symbol":"A"},...]' AFTER removed_positions,
|
||
ADD COLUMN fill_data JSON DEFAULT NULL COMMENT '填充数据 [{"pos":int,"symbol":"A"},...]' AFTER drop_data;
|
||
|
||
-- 推广后台:网站设置新增"支付公司"配置项
|
||
INSERT INTO sys_config (config_id, config_name, config_key, config_value, config_type, create_by, create_time, remark)
|
||
SELECT 135, '支付公司', 'payCompany', 'chengduhipay', 'Y', 'admin', NOW(), '充值对接支付平台选择'
|
||
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM sys_config WHERE config_key = 'payCompany');
|
||
|
||
-- 推广后台:网站设置新增"支付公司权重"配置项
|
||
INSERT INTO sys_config (config_id, config_name, config_key, config_value, config_type, create_by, create_time, remark)
|
||
SELECT 136, '支付公司权重', 'payCompanyWeights', '[{"name":"chengduhipay","weight":10}]', 'Y', 'admin', NOW(), '支付公司权重分配,JSON格式'
|
||
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM sys_config WHERE config_key = 'payCompanyWeights');
|
||
|
||
-- ROLL房奖项模板表
|
||
CREATE TABLE `tt_roll_prize_template` (
|
||
`id` INT NOT NULL AUTO_INCREMENT,
|
||
`template_name` VARCHAR(100) NOT NULL COMMENT '模板名称',
|
||
`create_by` VARCHAR(50) DEFAULT NULL COMMENT '创建者',
|
||
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||
`update_time` DATETIME DEFAULT NULL,
|
||
PRIMARY KEY (`id`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='ROLL房奖项模板';
|
||
|
||
-- ROLL房奖项模板明细表(模板内每个饰品)
|
||
CREATE TABLE `tt_roll_prize_template_detail` (
|
||
`id` INT NOT NULL AUTO_INCREMENT,
|
||
`template_id` INT NOT NULL COMMENT '关联tt_roll_prize_template.id',
|
||
`ornament_id` BIGINT NOT NULL COMMENT '饰品ID',
|
||
`ornament_name` VARCHAR(255) DEFAULT NULL COMMENT '饰品名称',
|
||
`img_url` VARCHAR(500) DEFAULT NULL COMMENT '饰品图片',
|
||
`price` DECIMAL(12,2) DEFAULT NULL COMMENT '饰品价格',
|
||
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||
PRIMARY KEY (`id`),
|
||
KEY `idx_template_id` (`template_id`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='ROLL房奖项模板明细';
|
||
|
||
-- 奖项模板明细表新增饰品数量字段
|
||
ALTER TABLE tt_roll_prize_template_detail ADD COLUMN ornaments_num INT DEFAULT 1 COMMENT '饰品数量';
|
||
|
||
-- 极速糖果:游戏记录表新增结算/补发字段
|
||
ALTER TABLE game_sweet_record
|
||
ADD COLUMN settled TINYINT DEFAULT 0 COMMENT '是否已结算 0未1已',
|
||
ADD COLUMN mode_type VARCHAR(20) DEFAULT NULL COMMENT '游戏模式 normal/ante/buy_fs/buy_super_fs',
|
||
ADD COLUMN auto_dismantle TINYINT DEFAULT 0 COMMENT '开局自动分解快照 0关1开',
|
||
ADD COLUMN reward_type VARCHAR(10) DEFAULT NULL COMMENT '发放类型 gold/ornament',
|
||
ADD COLUMN settled_win DECIMAL(10,2) DEFAULT 0.00 COMMENT '本局价值(金币金额=饰品价格)',
|
||
ADD COLUMN prize_id BIGINT DEFAULT NULL COMMENT '饰品ID game_sweet_prize_ornament.id',
|
||
ADD COLUMN prize_image_url VARCHAR(500) DEFAULT NULL COMMENT '饰品图片URL',
|
||
ADD COLUMN prize_level_img VARCHAR(500) DEFAULT NULL COMMENT '品质图片URL',
|
||
ADD COLUMN settle_source VARCHAR(20) DEFAULT NULL COMMENT '结算来源 finish/reconnect/scheduled';
|
||
|
||
-- 极速糖果:返奖饰品表新增品质名称字段
|
||
ALTER TABLE game_sweet_prize_ornament
|
||
ADD COLUMN exterior_name VARCHAR(100) DEFAULT NULL COMMENT '品质名称 崭新出厂/略有磨损/久经沙场/破损不堪/战痕累累';
|
||
|
||
-- 极速糖果:未结算记录兜底补发定时任务(后台:系统监控>定时任务)
|
||
INSERT INTO sys_job (job_name, job_group, invoke_target, cron_expression, misfire_policy, concurrent, status, create_by, create_time, remark)
|
||
VALUES ('极速糖果未结算补发', 'SWEET', 'sweetSettleTask.scheduledSettle()', '0 */10 * * * ?', '1', '0', '0', 'admin', NOW(), '每10分钟扫描超35分钟未结算记录并补发金币/饰品');
|
||
|
||
-- RichKu:支付宝金额<300强制走richku,>=300按权重分配(chengduhipay:richku=7:3),银联仅走chengduhipay
|
||
UPDATE sys_config
|
||
SET config_value = '[{"name":"chengduhipay","weight":7},{"name":"richku","weight":3,"payType":1}]'
|
||
WHERE config_key = 'payCompanyWeights';
|
||
|
||
-- itpay:接入新支付渠道并纳入权重分配(权重值按需调整;payType 可选:1=支付宝,2=银联,不填=全渠道)
|
||
-- 示例:chengduhipay:5、richku:3(仅支付宝)、itpay:2
|
||
UPDATE sys_config
|
||
SET config_value = '[{"name":"chengduhipay","weight":5},{"name":"richku","weight":3,"payType":1},{"name":"itpay","weight":2}]'
|
||
WHERE config_key = 'payCompanyWeights';
|
||
|
||
-- 极速糖果:饰品桶新增已消耗回合数(库存配额计数),剩余 = count - used
|
||
-- 玩家抽奖消耗对应桶一个回合(used+1);整盒回合抽干时自动重算、或后台手动重算分布时 used 归 0(剩余回归满,玩家可重新抽奖)
|
||
ALTER TABLE game_sweet_box_ornament
|
||
ADD COLUMN used INT DEFAULT 0 COMMENT '已消耗回合数,剩余=count-used' AFTER count;
|
||
|
||
-- 极速糖果:奖品饰品表填充磨损度名称(根据 grade 映射)
|
||
UPDATE game_sweet_prize_ornament SET exterior_name = '崭新出厂' WHERE grade = 1 AND (exterior_name IS NULL OR exterior_name = '');
|
||
UPDATE game_sweet_prize_ornament SET exterior_name = '略有磨损' WHERE grade = 2 AND (exterior_name IS NULL OR exterior_name = '');
|
||
UPDATE game_sweet_prize_ornament SET exterior_name = '久经沙场' WHERE grade = 3 AND (exterior_name IS NULL OR exterior_name = '');
|
||
UPDATE game_sweet_prize_ornament SET exterior_name = '破损不堪' WHERE grade = 4 AND (exterior_name IS NULL OR exterior_name = '');
|
||
UPDATE game_sweet_prize_ornament SET exterior_name = '战痕累累' WHERE grade = 5 AND (exterior_name IS NULL OR exterior_name = '');
|
||
|
||
-- 白号管理目录及子页面菜单
|
||
INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, query, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
|
||
VALUES (3100, '白号管理', 0, 5, 'blank', NULL, NULL, 1, 0, 'M', '0', '0', '', 'peoples', 'admin', NOW(), '', NULL, '白号管理目录');
|
||
|
||
INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, query, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
|
||
VALUES (3101, '白号用户', 3100, 1, 'blankAccount', 'skins/blankAccount/index', NULL, 1, 0, 'C', '0', '0', 'admin:blankAccount:list', 'user', 'admin', NOW(), '', NULL, '白号用户列表');
|
||
|
||
INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, query, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
|
||
VALUES (3102, '生成空白卡密', 3100, 2, 'blankCardKey', 'skins/blankCardKey/index', NULL, 1, 0, 'C', '0', '0', 'admin:blankCardKey:list', 'edit', 'admin', NOW(), '', NULL, '空白卡密管理');
|
||
|
||
-- 空白卡密表(管理后台独立生成,与卡商卡密表 promo_card_key 分离)
|
||
-- 表名规范化:加 tt_ 前缀(原 blank_card_key)
|
||
CREATE TABLE `tt_blank_card_key` (
|
||
`id` BIGINT NOT NULL AUTO_INCREMENT,
|
||
`card_code` VARCHAR(32) NOT NULL COMMENT '卡密编码(唯一)',
|
||
`amount` DECIMAL(10,2) NOT NULL COMMENT '面值金额',
|
||
`used_by_id` BIGINT DEFAULT NULL COMMENT '使用者ID',
|
||
`used_by_name` VARCHAR(50) DEFAULT NULL COMMENT '使用者名称',
|
||
`used_time` DATETIME DEFAULT NULL COMMENT '使用时间',
|
||
`status` TINYINT NOT NULL DEFAULT 0 COMMENT '状态: 0=未使用, 1=已使用',
|
||
`creator_name` VARCHAR(50) DEFAULT '' COMMENT '创建者名称',
|
||
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||
PRIMARY KEY (`id`),
|
||
UNIQUE KEY `uk_card_code` (`card_code`),
|
||
KEY `idx_status` (`status`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='空白卡密表(管理后台生成)';
|
||
|
||
-- 已上线库执行(老库表名规范化,幂等:表不存在时执行 rename 报错可忽略/或先判断)
|
||
RENAME TABLE blank_card_key TO tt_blank_card_key;
|
||
|
||
-- 饰品表新增商城价格字段(独立于 usePrice,专供前端商城展示)
|
||
ALTER TABLE tt_ornament ADD COLUMN store_price DECIMAL(18,2) DEFAULT NULL COMMENT '商城价格(= 第三方价格 × 汇率 × 溢价率)';
|
||
|
||
|
||
ALTER TABLE game_wheel_round_bet ADD COLUMN settled INT DEFAULT 1 COMMENT '0=等决定 1=已结算';
|
||
|
||
-- 疯狂转盘:奖品饰品表新增磨损度字段
|
||
ALTER TABLE game_wheel_prize_ornament
|
||
ADD COLUMN exterior_name VARCHAR(100) DEFAULT NULL COMMENT '磨损度名称 崭新出厂/略有磨损/久经沙场/破损不堪/战痕累累';
|
||
|
||
-- 疯狂转盘:奖品饰品表填充磨损度名称(根据 grade 映射)
|
||
UPDATE game_wheel_prize_ornament SET exterior_name = '崭新出厂' WHERE grade = 1 AND (exterior_name IS NULL OR exterior_name = '');
|
||
UPDATE game_wheel_prize_ornament SET exterior_name = '略有磨损' WHERE grade = 2 AND (exterior_name IS NULL OR exterior_name = '');
|
||
UPDATE game_wheel_prize_ornament SET exterior_name = '久经沙场' WHERE grade = 3 AND (exterior_name IS NULL OR exterior_name = '');
|
||
UPDATE game_wheel_prize_ornament SET exterior_name = '破损不堪' WHERE grade = 4 AND (exterior_name IS NULL OR exterior_name = '');
|
||
UPDATE game_wheel_prize_ornament SET exterior_name = '战痕累累' WHERE grade = 5 AND (exterior_name IS NULL OR exterior_name = '');
|
||
|
||
|
||
-- 西部对决 → 荒野争锋:更新 sys_config 维护开关显示名
|
||
UPDATE sys_config SET config_name = '荒野争锋维护', remark = '荒野争锋维护开关 0正常 1维护' WHERE config_key = 'westernDuelMaintenance';
|
||
|
||
-- 新增用户流水管理页面菜单
|
||
INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, menu_type, visible, status, perms, icon, create_by, create_time, remark)
|
||
VALUES ('用户流水', 2000, 10, 'userTurnover', 'skins/ttuser/userTurnover', 'C', '0', '0', 'system:user:turnover', 'money', 'admin', NOW(), '用户流水统计页面');
|
||
|
||
-- ========== 招商主播报表系统 ==========
|
||
|
||
-- 1. 用户来源日报表(按user_id+source+report_date统计累计流水)
|
||
CREATE TABLE `tt_user_source_report` (
|
||
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||
`user_id` INT NOT NULL COMMENT '用户ID',
|
||
`parent_id` INT DEFAULT NULL COMMENT '邀请人ID(来自tt_user.parent_id)',
|
||
`source` INT NOT NULL COMMENT '来源source码(对应TtAccountRecordSource.code)',
|
||
`total` DECIMAL(18,2) NOT NULL DEFAULT 0.00 COMMENT '截至当日的累计金额绝对值总和',
|
||
`report_date` DATE NOT NULL COMMENT '报表日期',
|
||
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||
`update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||
PRIMARY KEY (`id`),
|
||
UNIQUE KEY `uk_user_source_date` (`user_id`, `source`, `report_date`),
|
||
KEY `idx_parent_id` (`parent_id`),
|
||
KEY `idx_source` (`source`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户来源日报表(按user_id+source统计累计流水)';
|
||
|
||
-- 2. 流水归档表(存储7天前的历史流水数据)
|
||
CREATE TABLE `tt_user_blend_ercash_archive` (
|
||
`id` BIGINT NOT NULL COMMENT '与原表id一致',
|
||
`user_id` INT DEFAULT NULL,
|
||
`amount` DECIMAL(18,2) DEFAULT NULL,
|
||
`final_amount` DECIMAL(18,2) DEFAULT NULL,
|
||
`credits` DECIMAL(18,2) DEFAULT NULL,
|
||
`final_credits` DECIMAL(18,2) DEFAULT NULL,
|
||
`total` DECIMAL(18,2) DEFAULT NULL,
|
||
`source` INT DEFAULT NULL,
|
||
`type` INT DEFAULT NULL,
|
||
`remark` VARCHAR(500) DEFAULT NULL,
|
||
`create_time` DATETIME DEFAULT NULL,
|
||
`update_time` DATETIME DEFAULT NULL,
|
||
`archive_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '归档时间',
|
||
PRIMARY KEY (`id`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='流水归档表(7天前的历史流水)';
|
||
|
||
-- 3. 注册定时任务到 sys_job 表
|
||
|
||
-- 用户来源日报表生成(每天凌晨3点,增量递推统计各用户各source累计流水)
|
||
INSERT INTO sys_job (job_name, job_group, invoke_target, cron_expression, misfire_policy, concurrent, status, create_by, create_time, remark)
|
||
VALUES ('用户来源日报表生成', 'REPORT', 'userSourceReportTask.generateDailyReport()', '0 0 3 * * ?', '3', '1', '0', 'admin', NOW(), '每天凌晨3点生成用户来源日报表,增量递推统计累计流水');
|
||
|
||
-- 流水数据归档(每天凌晨5点,将7天前的流水迁移到归档表)
|
||
INSERT INTO sys_job (job_name, job_group, invoke_target, cron_expression, misfire_policy, concurrent, status, create_by, create_time, remark)
|
||
VALUES ('流水数据归档', 'ARCHIVE', 'flowArchiveTask.archiveOldData()', '0 0 5 * * ?', '3', '1', '0', 'admin', NOW(), '每天凌晨5点将7天前的流水数据迁移到归档表,分批1000条');
|
||
|
||
-- 荒野争锋(西部对决)奖励池同步(每5分钟执行一次)
|
||
INSERT INTO sys_job (job_name, job_group, invoke_target, cron_expression, misfire_policy, concurrent, status, create_by, create_time, remark)
|
||
VALUES ('荒野争锋奖励池同步', 'BULLET', 'bulletSettleTask.syncRewardPool()', '0 */5 * * * ?', '3', '1', '0', 'admin', NOW(), '每5分钟把Redis奖励池增量同步到game_bullet_win表');
|
||
|
||
-- 荒野争锋(西部对决)未结算兜底(每5分钟执行一次)
|
||
INSERT INTO sys_job (job_name, job_group, invoke_target, cron_expression, misfire_policy, concurrent, status, create_by, create_time, remark)
|
||
VALUES ('荒野争锋未结算兜底', 'BULLET', 'bulletSettleTask.closeTimeoutRecords()', '0 */5 * * * ?', '3', '1', '0', 'admin', NOW(), '每5分钟扫描超30分钟未结算的status=0记录并自动兜底结算');
|
||
|
||
-- VIP流水返利发放(每天凌晨0点10分,按昨日游戏流水总额 × VIP等级 flow_rebate_percent 统一发放,取代原实时发放)
|
||
INSERT INTO sys_job (job_name, job_group, invoke_target, cron_expression, misfire_policy, concurrent, status, create_by, create_time, remark)
|
||
VALUES ('VIP流水返利发放', 'VIP_REBATE', 'vipFlowRebateTask.grantDailyVipRebate()', '0 10 0 * * ?', '3', '1', '0', 'admin', NOW(), '每天凌晨0点10分发放昨日游戏流水的VIP返利,白号不发放,含当日幂等保护');
|
||
|
||
-- 修复 tt_user_blend_ercash_archive 与 tt_user_blend_ercash 排序规则不一致导致的 UNION 报错
|
||
ALTER TABLE tt_user_blend_ercash_archive CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
|
||
|
||
-- ========== 流水归档保留天数可配置化 ==========
|
||
|
||
-- 推广后台:网站设置新增“流水归档保留天数”配置项(兜底 7 天,超过该天数的流水迁移至归档表)
|
||
INSERT INTO sys_config (config_id, config_name, config_key, config_value, config_type, create_by, create_time, remark)
|
||
SELECT 137, '流水归档保留天数', 'flowArchiveRetainDays', '7', 'Y', 'admin', NOW(), '流水归档保留天数,超过该天数的流水迁移至归档表,兜底 7'
|
||
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM sys_config WHERE config_key = 'flowArchiveRetainDays');
|
||
|
||
|
||
-- 归档明细页菜单:余额变动-归档 / 积分变动-归档
|
||
INSERT INTO `chengdu`.`sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (3104, '余额变动-归档', 2000, 11, 'blendErcashArchiveAmount', 'skins/ttuser/blendErcashArchive', NULL, 1, 0, 'C', '0', '0', 'admin:blendErcash:archiveList', 'money', 'admin', '2026-07-07 14:46:52', '', NULL, '余额变动归档明细页(仅归档表)');
|
||
INSERT INTO `chengdu`.`sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (3105, '积分变动-归档', 2000, 12, 'blendErcashArchiveCredits', 'skins/ttuser/blendErcashArchive', NULL, 1, 0, 'C', '0', '0', 'admin:blendErcash:archiveList', 'star', 'admin', '2026-07-07 14:46:57', '', NULL, '积分变动归档明细页(仅归档表)');
|
||
|
||
|
||
-- 对战宝箱-查看奖项 页面性能优化:tt_box_records 复合索引
|
||
ALTER TABLE tt_box_records
|
||
ADD INDEX idx_tbr_box_ornament_time (box_id, ornament_id, create_time);
|
||
|
||
-- /admin/blendErcash/list 收支明细页面性能优化:tt_user_blend_ercash 索引
|
||
-- 执行前先 SHOW INDEX FROM tt_user_blend_ercash; 确认无等价索引;
|
||
-- 1) 默认打开页面无筛选时按 create_time 倒序分页,解决全表扫描+filesort(核心)
|
||
ALTER TABLE tt_user_blend_ercash
|
||
ADD INDEX idx_tube_ctime (create_time);
|
||
-- 2) 常见「按用户ID查流水」+ 时间倒序场景
|
||
ALTER TABLE tt_user_blend_ercash
|
||
ADD INDEX idx_tube_user_ctime (user_id, create_time);
|
||
-- 3) 归档表 /admin/blendErcash/archive/list 同样按 create_time 倒序,归档表当前仅有主键
|
||
ALTER TABLE tt_user_blend_ercash_archive
|
||
ADD INDEX idx_tubea_ctime (create_time);
|
||
ALTER TABLE tt_user_blend_ercash_archive
|
||
ADD INDEX idx_tubea_user_ctime (user_id, create_time);
|
||
|
||
-- 首页统计折线图 /admin/rechargeRecord/chartData 性能优化:tt_user_blend_ercash 按 source+时间聚合
|
||
-- 执行前先 SHOW INDEX FROM tt_user_blend_ercash; 确认无等价索引;
|
||
-- 命中 WHERE source = ? AND create_time >= ? AND create_time < ? GROUP BY source(等值列 source 在前、范围列 create_time 在后)
|
||
ALTER TABLE tt_user_blend_ercash
|
||
ADD INDEX idx_tube_source_ctime (source, create_time);
|
||
|
||
-- 首页折线图按周维度(近4周=28天)会 UNION 归档表聚合:归档表补 (source, create_time) 复合索引,
|
||
-- 让 UNION 归档侧的按 source+时间聚合也走索引(归档表原本仅有 create_time / user_id+create_time 索引)
|
||
ALTER TABLE tt_user_blend_ercash_archive
|
||
ADD INDEX idx_tubea_source_ctime (source, create_time);
|
||
|
||
-- ========== 招商佣金周结改造 ==========
|
||
|
||
-- 扩展佣金结算表,记录结算周期与流水快照
|
||
ALTER TABLE tt_commission_record
|
||
ADD COLUMN settlement_start_time DATETIME DEFAULT NULL COMMENT '结算周期开始时间',
|
||
ADD COLUMN settlement_end_time DATETIME DEFAULT NULL COMMENT '结算周期结束时间',
|
||
ADD COLUMN total_flow DECIMAL(18,2) DEFAULT 0.00 COMMENT '结算周期内参与计算的流水总额',
|
||
ADD COLUMN rate DECIMAL(10,4) DEFAULT 0.0000 COMMENT '结算时综合费率快照(%)';
|
||
|
||
-- 注册招商佣金周结定时任务(后台:系统监控 > 定时任务)
|
||
INSERT INTO sys_job (job_name, job_group, invoke_target, cron_expression, misfire_policy, concurrent, status, create_by, create_time, remark)
|
||
VALUES ('招商佣金周结', 'PROMO', 'commissionSettlementTask.settleWeeklyCommission()', '0 30 0 ? * MON', '0', '1', '0', 'admin', NOW(), '每周一 00:30 结算招商账号上周佣金(上周一 00:00 ~ 本周一 00:00)');
|
||
|
||
-- ========== 极速糖果箱子饰品分布模板持久化(模板从前端 localStorage 迁移到后端) ==========
|
||
-- 用途:保存每个箱子的饰品回合分布模板;箱子库存抽干时,按该箱子「最近一次应用的生效模板(is_active=1)」重新填桶并重算总回合。
|
||
CREATE TABLE IF NOT EXISTS game_sweet_box_template (
|
||
id BIGINT NOT NULL AUTO_INCREMENT COMMENT 'PK',
|
||
box_id BIGINT NOT NULL COMMENT '所属箱子ID',
|
||
name VARCHAR(100) NOT NULL COMMENT '模板名称(同一箱子内唯一)',
|
||
total_rounds INT NOT NULL DEFAULT 0 COMMENT '总回合数 = items 各 count 之和',
|
||
items_json TEXT NOT NULL COMMENT '饰品分布JSON: [{"ornamentId":1,"count":100},...]',
|
||
is_active TINYINT NOT NULL DEFAULT 0 COMMENT '是否为该箱子生效模板(抽干补桶依据): 1=是 0=否',
|
||
create_time DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||
PRIMARY KEY (id),
|
||
UNIQUE KEY uk_box_name (box_id, name),
|
||
KEY idx_box_active (box_id, is_active)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='极速糖果箱子饰品分布模板';
|
||
|
||
-- ========== 修复:Roll房奖池饰品ID列存不下饰品雪花大ID(如金币饰品 1783581913332) ==========
|
||
-- 根因:tt_roll_jackpot_ornaments.ornaments_id 旧表定义为 int,无法存储 tt_ornament.id(BIGINT大值),
|
||
-- 创建Roll房填充奖池时报错:Out of range value for column 'ornaments_id'。改为 BIGINT 与实体 Long 对齐。
|
||
ALTER TABLE tt_roll_jackpot_ornaments MODIFY COLUMN ornaments_id BIGINT COMMENT 'Roll房奖池饰品ID';
|
||
|
||
-- ========== 修复:指定获奖用户列类型错误导致写入截断 ==========
|
||
-- 根因:tt_roll_jackpot_ornaments.designated_user_id 实际列类型为数值型(int/bigint),
|
||
-- 而实体字段为 String 且业务支持多个用户ID用英文逗号分隔(如 '874624,123456'),
|
||
-- 推广后台"指定获奖用户"保存时报错:Data truncated for column 'designated_user_id'。
|
||
-- 改为 VARCHAR(500) 与实体定义及第198行的ADD COLUMN定义对齐。
|
||
ALTER TABLE tt_roll_jackpot_ornaments MODIFY COLUMN designated_user_id VARCHAR(500) DEFAULT NULL COMMENT '指定获奖用户ID,多个用英文逗号分隔,NULL表示不指定(随机分配)';
|
||
|
||
-- ========== 修复:机器人VIP等级统一固定为 1-10(保证大厅/房间/观战/所有提示显示一致) ==========
|
||
-- 根因:机器人创建时未设置 vip_level(为 NULL),而对战落座时曾用 ThreadLocalRandom 随机 0-13,
|
||
-- 大厅列表与观战又从 tt_user.vip_level 读取(NULL→0),导致同一机器人在不同场景 VIP 显示不一致。
|
||
-- 现改为:机器人 VIP 在创建时固定入库为 1-10,所有场景统一读 tt_user.vip_level。
|
||
-- 本脚本为历史机器人(user_type='03')补齐固定的 1-10 随机 VIP(每个机器人固定一个值,不再动态变化)。
|
||
UPDATE tt_user
|
||
SET vip_level = FLOOR(1 + RAND() * 10)
|
||
WHERE user_type = '03' AND (vip_level IS NULL OR vip_level < 1 OR vip_level > 10);
|
||
|
||
-- ========== 修复:管理后台Roll房奖池 total_price 存量数据(填货后未维护导致为0) ==========
|
||
-- 根因:管理后台批量填货/单个新增/删除奖池饰品时未重算 tt_roll_jackpot.total_price,
|
||
-- 导致奖池总价值一直为0,前端显示“奖池总价值 0”且主播房创建时不扣款。
|
||
-- 代码已修复(填货/新增/删除后都会重算),本脚本用于一次性修复历史存量奖池。
|
||
UPDATE tt_roll_jackpot j
|
||
SET j.total_price = (
|
||
SELECT COALESCE(SUM(o.price * o.ornaments_num), 0)
|
||
FROM tt_roll_jackpot_ornaments o
|
||
WHERE o.jackpot_id = j.jackpot_id
|
||
);
|
||
|
||
|
||
ALTER TABLE tt_roll ADD COLUMN deduct_credits DECIMAL(10,2) NOT NULL DEFAULT 0.00
|
||
COMMENT '主播房创建时实际扣除的积分,用于开奖/删除按比例退还';
|
||
|
||
-- ========== 每日福利箱子发放:@Scheduled 迁移到 sys_job 统一调度 ==========
|
||
-- 原 WelfareBoxTask.autoIssueDailyWelfareBox() 使用硬编码 @Scheduled(cron="0 0 0 * * ?"),
|
||
-- 现改为 sys_job 可配置调度,便于后台系统监控>定时任务动态启停/调整 cron。
|
||
INSERT INTO sys_job (job_name, job_group, invoke_target, cron_expression, misfire_policy, concurrent, status, create_by, create_time, remark)
|
||
VALUES ('每日福利箱子发放', 'WELFARE', 'welfareBoxTask.autoIssueDailyWelfareBox()', '0 0 0 * * ?', '3', '1', '0', 'admin', NOW(), '每天0点为所有正常用户发放对应VIP等级的福利箱子');
|
||
|
||
-- ========== 官方周期Roll房:配置驱动 + 定时自动创建 ==========
|
||
-- 需求:官方周roll(一周一次)、日roll(一天一次)自动创建,创建时按周期设置充值统计起点(recharge_start_time)
|
||
-- 与开奖时间(end_time)。日roll统计"今日充值",周roll统计"本周充值",门槛复用 tt_roll.min_recharge。
|
||
-- 复用现有 tt_roll 房间体系、加入校验(joinRollCheck)与到期开奖(RollTask),不引入并行体系。
|
||
|
||
-- 1. 官方周期Roll配置表(模板,可配置多条,各自按周期自动再生房间)
|
||
CREATE TABLE `tt_official_roll_config` (
|
||
`id` INT NOT NULL AUTO_INCREMENT,
|
||
`config_name` VARCHAR(100) NOT NULL COMMENT '配置标识(便于后台识别)',
|
||
`jackpot_id` INT NOT NULL COMMENT '指定奖池ID(tt_roll_jackpot.jackpot_id)',
|
||
`period_type` VARCHAR(16) NOT NULL COMMENT '周期类型: DAILY=每日, WEEKLY=每周',
|
||
`room_name` VARCHAR(100) NOT NULL COMMENT '生成的Roll房名称',
|
||
`description` VARCHAR(500) DEFAULT NULL COMMENT '房间描述',
|
||
`roll_password` VARCHAR(50) DEFAULT NULL COMMENT '参与密码(可空)',
|
||
`min_recharge` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '充值门槛金额,0=无门槛(日=今日充值,周=本周充值)',
|
||
`vip_level` INT DEFAULT 0 COMMENT 'VIP等级门槛,0=不限',
|
||
`people_num` INT NOT NULL DEFAULT 100 COMMENT '人数上限',
|
||
`sort_by` INT DEFAULT 0 COMMENT '排序依据',
|
||
`status` CHAR(1) NOT NULL DEFAULT '0' COMMENT '状态: 0=启用, 1=停用',
|
||
`last_generate_time` DATETIME DEFAULT NULL COMMENT '上次成功生成房间的时间(幂等辅助)',
|
||
`create_by` VARCHAR(50) DEFAULT NULL COMMENT '创建者',
|
||
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||
`update_by` VARCHAR(50) DEFAULT NULL COMMENT '更新者',
|
||
`update_time` DATETIME DEFAULT NULL,
|
||
`del_flag` CHAR(1) DEFAULT '0' COMMENT '删除标志: 0=存在, 2=删除',
|
||
PRIMARY KEY (`id`),
|
||
KEY `idx_status_period` (`status`, `period_type`),
|
||
KEY `idx_jackpot_id` (`jackpot_id`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='官方周期Roll房配置模板';
|
||
|
||
-- 2. tt_roll 增列 official_config_id:标记该房由哪条配置生成(溯源 + 幂等去重键的一部分)
|
||
ALTER TABLE tt_roll ADD COLUMN official_config_id INT DEFAULT NULL COMMENT '官方周期Roll配置ID(tt_official_roll_config.id),手动创建的房间为NULL';
|
||
-- 幂等去重键:同一配置 + 同一充值统计起点 至多生成一个房间
|
||
ALTER TABLE tt_roll ADD INDEX idx_official_config_start (official_config_id, recharge_start_time);
|
||
|
||
-- 3. 注册定时任务(后台:系统监控 > 定时任务)
|
||
-- 日roll生成:每天 00:01 为所有启用的 DAILY 配置创建当日房间
|
||
INSERT INTO sys_job (job_name, job_group, invoke_target, cron_expression, misfire_policy, concurrent, status, create_by, create_time, remark)
|
||
VALUES ('官方日Roll生成', 'ROLL', 'officialRollTask.generateDailyRolls()', '0 1 0 * * ?', '3', '1', '0', 'admin', NOW(), '每天00:01为启用的DAILY配置创建官方日roll房,起点=当天0点,开奖=次日0点');
|
||
|
||
-- 周roll生成:每周一 00:10 为所有启用的 WEEKLY 配置创建本周房间
|
||
INSERT INTO sys_job (job_name, job_group, invoke_target, cron_expression, misfire_policy, concurrent, status, create_by, create_time, remark)
|
||
VALUES ('官方周Roll生成', 'ROLL', 'officialRollTask.generateWeeklyRolls()', '0 10 0 ? * MON', '3', '1', '0', 'admin', NOW(), '每周一00:10为启用的WEEKLY配置创建官方周roll房,起点=本周一0点,开奖=下周一0点');
|
||
|
||
-- 4. 后台菜单:在“Roll房列表”所在目录下新增“官方周期Roll配置”页面(作为其兄弟菜单,parent 自动取现有Roll房列表页的父级)
|
||
-- 菜单驱动路由:component 指向前端 src/views/skins/ttRoll/officialRollConfig.vue
|
||
INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, remark)
|
||
SELECT '官方周期Roll配置', m.parent_id, 20, 'officialRollConfig', 'skins/ttRoll/officialRollConfig', 1, 0, 'C', '0', '0', 'admin:officialRollConfig:list', 'time', 'admin', NOW(), '官方周期Roll配置页面(定时自动创建官方日/周Roll房)'
|
||
FROM (SELECT parent_id FROM sys_menu WHERE component = 'skins/ttRoll/index' LIMIT 1) m;
|
||
|
||
INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, remark)
|
||
SELECT '支付订单', m.menu_id, 13, 'ttOrder', 'skins/ttOrder/index', 1, 0, 'C', '0', '0', 'admin:order:list', 'money', 'admin', NOW(), '网站支付订单查询页面(可按状态查看订单)'
|
||
FROM (SELECT menu_id FROM sys_menu WHERE path = 'currency' AND menu_type = 'M' LIMIT 1) m;
|
||
|
||
-- ========== 主播推广CDKEY 过期/兑完 精确退还 ==========
|
||
-- 需求:CDK创建时按 amountMax×num×createNum 等额预扣主播金币+积分;兑换时仅随机派发 min~max 金币。
|
||
-- 当CDK过期(validity到期)或兑完(usable_count用尽)后,按「预扣总额 - 实际已派发金币总额」精确返还
|
||
-- 主播的金币与积分(同额),由定时任务统一兜底,refund_time 幂等防重复。
|
||
|
||
-- 1. promo_cdkey 增加退还标记字段(MySQL 不支持 ADD COLUMN IF NOT EXISTS,直接 ADD)
|
||
ALTER TABLE promo_cdkey
|
||
ADD COLUMN refund_amount DECIMAL(18,2) NULL COMMENT 'CDK结束退还金额(金币/积分同额)',
|
||
ADD COLUMN refund_time DATETIME NULL COMMENT '退还时间(NULL=未退还)';
|
||
|
||
-- 2. 注册定时任务(后台:系统监控 > 定时任务):每10分钟扫描已结束(过期/兑完)且未退还的CDK并精确退还
|
||
INSERT INTO sys_job (job_name, job_group, invoke_target, cron_expression, misfire_policy, concurrent, status, create_by, create_time, remark)
|
||
VALUES ('CDK结束退还', 'PROMO', 'promoCdkeyRefundTask.settleEndedCdkeyRefunds()', '0 0/10 * * * ?', '3', '1', '0', 'admin', NOW(), '每10分钟扫描已过期或已兑完且未退还的CDK,按预扣-实际派发精确返还主播金币/积分并通知');
|
||
|
||
|
||
-- 转赠申请表
|
||
CREATE TABLE IF NOT EXISTS `tt_transfer_apply` (
|
||
`id` INT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID',
|
||
`batch_id` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '转赠批次号(同一批次内多个饰品一起审核)',
|
||
`box_record_id` BIGINT NULL COMMENT '背包记录ID(tt_box_records.id)',
|
||
`from_user_id` INT NOT NULL COMMENT '转赠人用户ID',
|
||
`to_user_id` INT NOT NULL COMMENT '受赠人用户ID',
|
||
`vip_level` INT NOT NULL DEFAULT 0 COMMENT '提交转赠时的VIP等级',
|
||
`ornament_id` BIGINT NULL COMMENT '饰品ID',
|
||
`ornament_name` VARCHAR(255) NULL COMMENT '饰品名称',
|
||
`ornament_image_url` VARCHAR(500) NULL COMMENT '饰品图片URL',
|
||
`ornament_price` DECIMAL(10,2) NOT NULL COMMENT '饰品价格(单件超过1000才可转赠)',
|
||
`status` TINYINT DEFAULT 0 COMMENT '状态:0-待审核,1-审核通过,2-审核驳回',
|
||
`reject_reason` VARCHAR(500) NULL COMMENT '驳回原因',
|
||
`create_by` VARCHAR(64) NULL COMMENT '创建者',
|
||
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||
`update_by` VARCHAR(64) NULL COMMENT '更新者',
|
||
`update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||
INDEX `idx_batch_id` (`batch_id`),
|
||
INDEX `idx_from_user_id` (`from_user_id`),
|
||
INDEX `idx_to_user_id` (`to_user_id`),
|
||
INDEX `idx_status` (`status`),
|
||
INDEX `idx_create_time` (`create_time`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='转赠申请表(按批次聚合审核)';
|
||
|
||
-- 如果表已存在但缺少 box_record_id 列,执行以下语句:
|
||
-- ALTER TABLE `tt_transfer_apply` ADD COLUMN `box_record_id` BIGINT NULL COMMENT '背包记录ID(tt_box_records.id)' AFTER `id`;
|
||
|
||
-- ============================================================
|
||
-- 菜单配置(请根据实际数据库中的父菜单ID调整 parent_id)
|
||
-- 查找"三方发货链路"父菜单ID:SELECT menu_id, menu_name FROM sys_menu WHERE menu_name LIKE '%三方发货%' OR menu_name LIKE '%发货%';
|
||
-- ============================================================
|
||
|
||
-- 新增"转赠申请"菜单项(menu_type=C 表示菜单)
|
||
-- 注意:parent_id 需替换为实际的"三方发货链路"目录菜单ID
|
||
-- component 路径对应 ruoyi-ui/src/views/skins/delivery/transferApply.vue
|
||
INSERT INTO `sys_menu` (
|
||
`menu_name`,
|
||
`parent_id`,
|
||
`order_num`,
|
||
`path`,
|
||
`component`,
|
||
`is_frame`,
|
||
`is_cache`,
|
||
`menu_type`,
|
||
`visible`,
|
||
`status`,
|
||
`perms`,
|
||
`icon`,
|
||
`create_by`,
|
||
`create_time`,
|
||
`remark`
|
||
)
|
||
VALUES
|
||
(
|
||
'转赠申请',
|
||
( SELECT menu_id FROM ( SELECT menu_id FROM sys_menu WHERE menu_name LIKE '%三方发货%' LIMIT 1 ) AS tmp ),-- 替换为实际的父菜单ID
|
||
10,
|
||
'transferApply',
|
||
'skins/delivery/transferApply',
|
||
1,
|
||
0,
|
||
'C',
|
||
'0',
|
||
'0',
|
||
'skins:delivery:transferApply',
|
||
'transfer',
|
||
'admin',
|
||
NOW( ),
|
||
'转赠申请管理页面'
|
||
);-- 新增按钮权限
|
||
-- 同意按钮
|
||
INSERT INTO `sys_menu` (
|
||
`menu_name`,
|
||
`parent_id`,
|
||
`order_num`,
|
||
`path`,
|
||
`component`,
|
||
`is_frame`,
|
||
`is_cache`,
|
||
`menu_type`,
|
||
`visible`,
|
||
`status`,
|
||
`perms`,
|
||
`icon`,
|
||
`create_by`,
|
||
`create_time`,
|
||
`remark`
|
||
)
|
||
VALUES
|
||
(
|
||
'转赠审核通过',
|
||
( SELECT menu_id FROM ( SELECT menu_id FROM sys_menu WHERE menu_name = '转赠申请' LIMIT 1 ) AS tmp ),
|
||
1,
|
||
'',
|
||
NULL,
|
||
1,
|
||
0,
|
||
'F',
|
||
'0',
|
||
'0',
|
||
'skins:delivery:transferApply:approve',
|
||
'#',
|
||
'admin',
|
||
NOW( ),
|
||
''
|
||
);-- 驳回按钮
|
||
INSERT INTO `sys_menu` (
|
||
`menu_name`,
|
||
`parent_id`,
|
||
`order_num`,
|
||
`path`,
|
||
`component`,
|
||
`is_frame`,
|
||
`is_cache`,
|
||
`menu_type`,
|
||
`visible`,
|
||
`status`,
|
||
`perms`,
|
||
`icon`,
|
||
`create_by`,
|
||
`create_time`,
|
||
`remark`
|
||
)
|
||
VALUES
|
||
(
|
||
'转赠审核驳回',
|
||
( SELECT menu_id FROM ( SELECT menu_id FROM sys_menu WHERE menu_name = '转赠申请' LIMIT 1 ) AS tmp ),
|
||
2,
|
||
'',
|
||
NULL,
|
||
1,
|
||
0,
|
||
'F',
|
||
'0',
|
||
'0',
|
||
'skins:delivery:transferApply:reject',
|
||
'#',
|
||
'admin',
|
||
NOW( ),
|
||
''
|
||
);
|
||
|
||
-- 新增"已处理转赠申请"菜单项(与"转赠申请"同级)
|
||
-- component 路径对应 ruoyi-ui/src/views/skins/delivery/transferApplyProcessed.vue
|
||
INSERT INTO `sys_menu` (
|
||
`menu_name`,
|
||
`parent_id`,
|
||
`order_num`,
|
||
`path`,
|
||
`component`,
|
||
`is_frame`,
|
||
`is_cache`,
|
||
`menu_type`,
|
||
`visible`,
|
||
`status`,
|
||
`perms`,
|
||
`icon`,
|
||
`create_by`,
|
||
`create_time`,
|
||
`remark`
|
||
)
|
||
VALUES
|
||
(
|
||
'已处理转赠申请',
|
||
( SELECT menu_id FROM ( SELECT menu_id FROM sys_menu WHERE menu_name LIKE '%三方发货%' LIMIT 1 ) AS tmp ),
|
||
11,
|
||
'transferApplyProcessed',
|
||
'skins/delivery/transferApplyProcessed',
|
||
1,
|
||
0,
|
||
'C',
|
||
'0',
|
||
'0',
|
||
'skins:delivery:transferApplyProcessed',
|
||
'transfer',
|
||
'admin',
|
||
NOW( ),
|
||
'已处理转赠申请管理页面'
|
||
);
|
||
|
||
-- 全服背包饰品批量分解定时任务(每天凌晨2点,分解所有用户背包中的饰品,等额返还金币和积分,跳过正在提货中的饰品和机器人用户)
|
||
-- 分解记录通过 tt_user_blend_ercash 流水表记录(source=10 背包分解饰品收入)
|
||
INSERT INTO sys_job (job_name, job_group, invoke_target, cron_expression, misfire_policy, concurrent, status, create_by, create_time, remark)
|
||
VALUES ('全服背包饰品分解', 'DECOMPOSE', 'boxRecordsDecomposeTask.decomposeAllUserPackSack()', '0 0 2 * * ?', '3', '1', '1', 'admin', NOW(), '每天凌晨2点分解所有用户背包中的饰品(status IN 0,2),等额增加金币和积分,写入分解流水记录;跳过正在提货中的饰品和机器人用户');
|
||
|
||
-- ========== 转赠记录增加状态列 ==========
|
||
-- 前端「赠送记录」三态:0-审核中,1-成功,2-失败
|
||
ALTER TABLE `tt_box_transfer_record` ADD COLUMN `status` TINYINT NOT NULL DEFAULT 0 COMMENT '转赠状态:0-审核中,1-成功,2-失败';
|
||
ALTER TABLE `tt_box_transfer_record` ADD INDEX `idx_status` (`status`);
|
||
|
||
-- 删除唯一索引:同一个饰品可多次转赠给同一副号(如驳回后再转赠),每次应独立成记录
|
||
ALTER TABLE `tt_box_transfer_record` DROP INDEX `idx_src_dst_boxid`;
|
||
|
||
-- 对战机器人爆率分离:新增欧皇/非酋独立爆率字段
|
||
ALTER TABLE tt_box_ornaments ADD COLUMN robot_odds_lucky INT DEFAULT 0 COMMENT '机器人欧皇模式爆率';
|
||
ALTER TABLE tt_box_ornaments ADD COLUMN robot_odds_unlucky INT DEFAULT 0 COMMENT '机器人非酋模式爆率';
|
||
|
||
-- 数据回填:初始值等于原 robot_odds
|
||
UPDATE tt_box_ornaments SET robot_odds_lucky = robot_odds, robot_odds_unlucky = robot_odds;
|
||
|
||
-- ========== VIP 等级新增每日转赠次数配置 ==========
|
||
ALTER TABLE tt_vip_level ADD COLUMN transfer_count INT NOT NULL DEFAULT 0 COMMENT '达到该VIP等级后每日可转赠次数';
|
||
|
||
-- ========== VIP 等级新增每日提货次数配置 ==========
|
||
ALTER TABLE tt_vip_level ADD COLUMN delivery_count INT NOT NULL DEFAULT 0 COMMENT '达到该VIP等级后每日可提货次数';
|
||
|
||
-- ========== 用户每日转赠次数记录 ==========
|
||
-- 按 (用户ID, VIP等级, 日期) 记录,升级后不同 VIP 等级的次数独立计算
|
||
CREATE TABLE IF NOT EXISTS tt_user_transfer_daily (
|
||
id BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键ID',
|
||
user_id INT NOT NULL COMMENT '用户ID',
|
||
vip_level INT NOT NULL DEFAULT 0 COMMENT '提交/生效时的VIP等级(tt_vip_level.id)',
|
||
stat_date DATE NOT NULL COMMENT '统计日期',
|
||
total_count INT NOT NULL DEFAULT 0 COMMENT '该VIP等级当日转赠次数上限',
|
||
used_count INT NOT NULL DEFAULT 0 COMMENT '该VIP等级当日已成功转赠次数',
|
||
pending_count INT NOT NULL DEFAULT 0 COMMENT '该VIP等级当日审核中预扣次数',
|
||
delivery_total_count INT NOT NULL DEFAULT 0 COMMENT '该VIP等级当日提货次数上限',
|
||
delivery_used_count INT NOT NULL DEFAULT 0 COMMENT '该VIP等级当日已成功提货次数',
|
||
delivery_pending_count INT NOT NULL DEFAULT 0 COMMENT '该VIP等级当日审核中提货预扣次数',
|
||
create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||
PRIMARY KEY (id),
|
||
UNIQUE KEY uk_user_vip_date (user_id, vip_level, stat_date),
|
||
INDEX idx_stat_date (stat_date)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='用户每日转赠/提货次数记录(按VIP等级隔离)';
|
||
|
||
-- 若此前已按旧结构 (user_id, stat_date) 建表,执行以下迁移语句
|
||
-- ALTER TABLE tt_user_transfer_daily DROP PRIMARY KEY;
|
||
-- ALTER TABLE tt_user_transfer_daily ADD COLUMN id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST;
|
||
-- ALTER TABLE tt_user_transfer_daily ADD UNIQUE KEY uk_user_vip_date (user_id, vip_level, stat_date);
|
||
|
||
-- ========== 转赠/提货次数拆分上线初始化 ==========
|
||
-- 1. 把 VIP 等级表中的 delivery_count 初始化为和 transfer_count 一致(避免上线后用户无法提货)
|
||
UPDATE tt_vip_level SET delivery_count = transfer_count WHERE delivery_count = 0;
|
||
|
||
-- 2. 把已有每日次数记录中的 delivery_total_count 初始化为对应 VIP 等级的 delivery_count
|
||
UPDATE tt_user_transfer_daily t
|
||
JOIN tt_vip_level v ON t.vip_level = v.id
|
||
SET t.delivery_total_count = v.delivery_count
|
||
WHERE t.delivery_total_count = 0;
|
||
|
||
-- 转赠申请表记录提交时的 VIP 等级,审核时按该等级扣/返次数
|
||
ALTER TABLE tt_transfer_apply ADD COLUMN vip_level INT NOT NULL DEFAULT 0 COMMENT '提交转赠时的VIP等级';
|
||
|
||
-- 转赠申请表增加批次号,同一批次内的饰品需整体审核通过/驳回
|
||
ALTER TABLE tt_transfer_apply ADD COLUMN batch_id VARCHAR(64) NOT NULL DEFAULT '' COMMENT '转赠批次号(同一批次内多个饰品一起审核)';
|
||
ALTER TABLE tt_transfer_apply ADD INDEX idx_batch_id (batch_id);
|
||
|
||
-- 用户表新增赠送状态:0=启用(可被赠送),1=禁用(不可被赠送)
|
||
ALTER TABLE tt_user ADD COLUMN gift_status VARCHAR(1) NOT NULL DEFAULT '0' COMMENT '赠送状态:0=启用,1=禁用';
|
||
## 极速糖果领取流程简化 - 存量数据迁移
|
||
|
||
### 部署前执行(处理待决定记录)
|
||
|
||
```sql
|
||
-- 1. 查看待处理记录数量(先确认影响范围)
|
||
SELECT COUNT(*) AS pending_count FROM game_sweet_record
|
||
WHERE settled = 0 AND auto_dismantle = 0 AND prize_name IS NOT NULL;
|
||
|
||
-- 2. 将待处理记录标记为已结算(reward_type=ornament)
|
||
UPDATE game_sweet_record
|
||
SET settled = 1,
|
||
reward_type = 'ornament',
|
||
settle_source = 'data_migration'
|
||
WHERE settled = 0
|
||
AND auto_dismantle = 0
|
||
AND prize_name IS NOT NULL;
|
||
|
||
-- 3. 补写背包记录(对于有 prize_id 的记录写入 tt_box_records)
|
||
INSERT INTO tt_box_records (user_id, holder_user_id, box_id, box_name, ornament_id,
|
||
ornament_name, ornaments_price, image_url, ornaments_level_id, source, status, is_show, create_time)
|
||
SELECT user_id, user_id, box_id, 'SWEET', prize_id, prize_name, settled_win,
|
||
prize_image_url, 1, 11, 0, 1, NOW()
|
||
FROM game_sweet_record
|
||
WHERE settle_source = 'data_migration' AND prize_id IS NOT NULL;
|
||
|
||
-- 4. 验证迁移结果
|
||
SELECT COUNT(*) AS migrated_records FROM game_sweet_record WHERE settle_source = 'data_migration';
|
||
SELECT COUNT(*) AS new_box_records FROM tt_box_records WHERE source = 11 AND DATE(create_time) = CURDATE();
|
||
```
|
||
|
||
新增推广后台维护配置
|
||
INSERT INTO sys_config (config_name, config_key, config_value, config_type, create_by, create_time, remark)
|
||
VALUES ('推广后台维护', 'promoMaintenance', '0', 'Y', 'admin', NOW(), '推广后台维护开关 0正常 1维护');
|
||
|
||
|
||
-- 推广后台-Roll房中奖详情接口性能优化:tt_box_records 复合索引
|
||
-- 查询模式:WHERE roll_id = ? AND source = ? ORDER BY create_time(等值列在前、排序列在后)
|
||
-- 执行前先 SHOW INDEX FROM tt_box_records; 确认无等价索引;大表请加索引在低峰期执行
|
||
ALTER TABLE tt_box_records
|
||
ADD INDEX idx_tbr_roll_source_time (roll_id, source, create_time);
|
||
|
||
-- 疯狂转盘全服中奖记录过滤白号和机器人
|
||
ALTER TABLE game_wheel_round_bet ADD INDEX idx_win_filter (win, user_id);
|
||
-- 优化查询性能:WHERE win > 0 AND user 状态过滤
|
||
|
||
|
||
-- VIP归档兼容性修复:tt_user增加累计充值缓存字段(避免归档后VIP归零和未充值误判)
|
||
ALTER TABLE tt_user ADD COLUMN total_recharge_amount DECIMAL(14,2) NOT NULL DEFAULT 0.00 COMMENT '累计充值金额(缓存,充值时原子递增)';
|
||
|
||
-- 初始化回填:从主表+归档表计算历史充值总额(仅更新有充值记录的用户,避免全表扫描)
|
||
UPDATE tt_user u SET u.total_recharge_amount = (
|
||
SELECT COALESCE(SUM(sub.total), 0) FROM (
|
||
SELECT total FROM tt_user_blend_ercash WHERE user_id = u.user_id AND type = 0 AND source = 1
|
||
UNION ALL
|
||
SELECT total FROM tt_user_blend_ercash_archive WHERE user_id = u.user_id AND type = 0 AND source = 1
|
||
) sub
|
||
)
|
||
WHERE EXISTS (
|
||
SELECT 1 FROM tt_user_blend_ercash WHERE user_id = u.user_id AND type = 0 AND source = 1
|
||
) OR EXISTS (
|
||
SELECT 1 FROM tt_user_blend_ercash_archive WHERE user_id = u.user_id AND type = 0 AND source = 1
|
||
);
|
||
|
||
-- 2026-07-22 修复CDK兑换重复检查并发漏洞,添加唯一索引兄底
|
||
ALTER TABLE promo_cdkey_redeem
|
||
ADD UNIQUE KEY uk_cdkey_redeemer (cdkey_id, redeemer_id);
|
||
|
||
-- 2026-07-22 修复口令红包重复领取漏洞,添加唯一索引兄底
|
||
ALTER TABLE tt_red_packet_record
|
||
ADD UNIQUE KEY uk_packet_user (red_packet_id, user_id);
|
||
|
||
-- 2026-07-22 后台菜单:在“cdk管理”目录下新增“推广CDK记录”子菜单
|
||
INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, remark)
|
||
SELECT '推广CDK记录', m.parent_id, 4, 'promoCdkeyRedeem', 'skins/promoCdkeyRedeem/index', 1, 0, 'C', '0', '0', '', '#', 'admin', NOW(), '推广后台CDKEY兑换记录'
|
||
FROM (SELECT parent_id FROM sys_menu WHERE component = 'skins/ttGenerateCard/index' LIMIT 1) m;
|
||
|
||
|
||
-- 2026-07-22 百佳与历史接口性能优化索引
|
||
ALTER TABLE tt_box_records ADD INDEX idx_tbr_fight_id (fight_id);
|
||
ALTER TABLE tt_fight ADD INDEX idx_ttf_status_model_endtime (status, model, end_time);
|
||
ALTER TABLE tt_fight_user ADD INDEX idx_tfu_user_fight (user_id, fight_id);
|
||
|
||
-- 2026-07-24 极速糖果一轮内RTP动态收敛:箱子新增收敛回合占比(空=默认0.15,逐箱可配)
|
||
ALTER TABLE game_sweet_box ADD COLUMN rtp_converge_ratio DECIMAL(4,3) NULL COMMENT '一轮收敛回合占比,空=默认0.15';
|
||
|
||
-- 2026-07-25 abkpay:接入新代收支付渠道并纳入统一支付权重分配
|
||
-- 说明:abkpay 是否被 /api/recharge/unifiedPay 路由选中由本配置决定(PayCompanyRouter 读取 payCompanyWeights);
|
||
-- 不在列表或 weight<=0 视为停用;weight 按需调整;payType 可选(1=支付宝,2=银联,不填=全渠道,abkpay 不限渠道故不填)。
|
||
-- 注意:本语句为整段 JSON 覆盖,若线上权重已被运营调整过,请以现有值为基础追加 {"name":"abkpay","weight":N} 项后再执行。
|
||
-- 示例:chengduhipay:5、richku:3(仅支付宝)、itpay:2、abkpay:2
|
||
UPDATE sys_config
|
||
SET config_value = '[{"name":"chengduhipay","weight":5},{"name":"richku","weight":3,"payType":1},{"name":"itpay","weight":2},{"name":"abkpay","weight":2}]'
|
||
WHERE config_key = 'payCompanyWeights';
|
||
|
||
-- 2026-07-25 支付路由按金额分层调整:<300 默认走 itpay(取代原“支付宝<300强制 richku”规则),>=300 按权重分配;
|
||
-- abkpay 内部再按金额选产品编码(yml 配置:300<=金额<800 用 wayCode=8012,金额>=800 用 wayCodeHigh=8003)。
|
||
-- 注意:itpay 权重必须>0,否则 <300 默认规则失效回落到权重选择;itpay 的权重同时决定其在 >=300 流量中的占比。
|
||
-- 示例:itpay:2、abkpay:8 → <300 全部 itpay;>=300 按 2:8 分流(若希望 >=300 基本全走 abkpay,可改配 itpay:1、abkpay:9)
|
||
UPDATE sys_config
|
||
SET config_value = '[{"name":"itpay","weight":2},{"name":"abkpay","weight":8}]'
|
||
WHERE config_key = 'payCompanyWeights';
|
||
|
||
-- 2026-07-25 VIP等级奖励防重复领取修复(配合代码:归档任务 selectArchiveIds 永久跳过 source=30)
|
||
-- 背景:VIP等级达标奖励(source=30)的领取判重只查主表 tt_user_blend_ercash,
|
||
-- 领取流水被归档后主表查不到,玩家重新登录可重复领取。
|
||
-- 方案:领取凭证永久保留在主表;存量已归档的凭证从归档表搬回主表(同一事务先插后删,避免 UNION 双算)。
|
||
-- 【踩坑订正】TtAccountRecordType 枚举:INPUT(收入)=1、OUTPUT(支出)=0,与直觉相反!
|
||
-- 初版 SQL 误写 type=0 导致回填 0 行;凭证是收入流水,此处直接不限 type(source=30 只会以收入入账)。
|
||
START TRANSACTION;
|
||
|
||
-- 1) 回填主表(id 与归档表一致,IGNORE 防止极端情况下主键冲突报错)
|
||
INSERT IGNORE INTO tt_user_blend_ercash
|
||
(id, user_id, amount, final_amount, credits, final_credits, total, source, type, remark, create_time, update_time)
|
||
SELECT id, user_id, amount, final_amount, credits, final_credits, total, source, type, remark, create_time, update_time
|
||
FROM tt_user_blend_ercash_archive
|
||
WHERE source = 30;
|
||
|
||
-- 2) 从归档表删除,避免主表+归档表 UNION ALL 查询时同一条记录双算
|
||
DELETE FROM tt_user_blend_ercash_archive
|
||
WHERE source = 30
|
||
AND id IN (SELECT id FROM tt_user_blend_ercash WHERE source = 30);
|
||
|
||
COMMIT;
|
||
|
||
-- 排查:找出已重复领取的玩家(同一用户同一等级 remark 领取超过 1 次,跨主表+归档表),用于追损
|
||
SELECT t.user_id, t.remark, COUNT(*) AS claim_count, SUM(t.amount) AS total_claimed,
|
||
MIN(t.create_time) AS first_claim, MAX(t.create_time) AS last_claim
|
||
FROM (
|
||
SELECT user_id, remark, amount, create_time FROM tt_user_blend_ercash WHERE source = 30
|
||
UNION ALL
|
||
SELECT user_id, remark, amount, create_time FROM tt_user_blend_ercash_archive WHERE source = 30
|
||
) t
|
||
GROUP BY t.user_id, t.remark
|
||
HAVING COUNT(*) > 1
|
||
ORDER BY claim_count DESC, total_claimed DESC;
|
||
|
||
|
||
|
||
## 2026-07-26 机器人对战饰品清出机器人背包
|
||
|
||
-- 背景:对战结算时曾把整场 tt_box_records 统一置为 status=0(在背包显示),导致机器人(user_type=03)
|
||
-- 赢得的对战饰品进入机器人背包。代码已修复(FightStateManager.settleFight / ApiFightServiceImpl.fightEnd /
|
||
-- fightTask.refreshDayTask 三处结算排除机器人持有记录),此 SQL 清理存量:机器人持有的对战来源饰品
|
||
-- 翻回 status=1(背包不显示),不影响前端对战结果展示(结果查询不按 status 过滤)。
|
||
UPDATE tt_box_records tbr
|
||
JOIN tt_user tu ON tbr.holder_user_id = tu.user_id
|
||
SET tbr.status = 1, tbr.update_time = NOW()
|
||
WHERE tu.user_type = '03'
|
||
AND tbr.fight_id IS NOT NULL
|
||
AND tbr.status = 0;
|
||
|
||
-- 验证:应返回 0
|
||
SELECT COUNT(*) FROM tt_box_records tbr
|
||
JOIN tt_user tu ON tbr.holder_user_id = tu.user_id
|
||
WHERE tu.user_type = '03' AND tbr.fight_id IS NOT NULL AND tbr.status = 0;
|
||
|
||
|
||
|
||
## 2026-07-26 招商周结防重复结算唯一索引
|
||
|
||
-- 背景:CommissionSettlementTask 幂等仅靠 countCommissionRecord 先查后插,
|
||
-- 存在并发窗口可能重复结算。数据库层面加唯一索引兜底:
|
||
-- 同一招商(user_id) + 同一结算周期起点(settlement_start_time) 只允许一条记录。
|
||
-- 注意:执行前先用下方排查 SQL 确认无存量重复数据,否则建索引会失败。
|
||
|
||
-- 排查存量重复(应返回空)
|
||
SELECT user_id, settlement_start_time, COUNT(*) AS cnt
|
||
FROM tt_commission_record
|
||
GROUP BY user_id, settlement_start_time
|
||
HAVING COUNT(*) > 1;
|
||
|
||
-- 新增唯一索引
|
||
ALTER TABLE tt_commission_record
|
||
ADD UNIQUE INDEX uk_commission_user_period (user_id, settlement_start_time);
|
||
|
||
|
||
|
||
## 2026-07-26 疯狂转盘注单表增加 date 列并重建唯一键
|
||
|
||
-- 背景:注单改为 doBet 扣款事务内即落库(settled=0),但 round_id 每日重置,
|
||
-- 原唯一键 uk_round_user_symbol(round_id,user_id,bet_symbol) 不含日期,
|
||
-- 跨天同 roundId+用户+符号会插入冲突导致下注失败。
|
||
-- 增加 date 列(yyyyMMdd)并将唯一键改为 (date, round_id, user_id, bet_symbol)。
|
||
-- 同步修复 selectByDateAndRoundId 改为直接按注单 date 列过滤。
|
||
|
||
-- 1. 增加 date 列
|
||
ALTER TABLE game_wheel_round_bet
|
||
ADD COLUMN `date` varchar(10) NOT NULL DEFAULT '' COMMENT '所属日期yyyyMMdd(roundId每日重置,需与date联合定位回合)' AFTER `round_id`;
|
||
|
||
-- 2. 回填存量数据(按创建时间推断所属日期)
|
||
UPDATE game_wheel_round_bet SET `date` = DATE_FORMAT(create_time, '%Y%m%d') WHERE `date` = '';
|
||
|
||
-- 3. 排查新唯一键的存量重复(应返回空;若有重复需先人工处理,否则建索引失败)
|
||
SELECT `date`, round_id, user_id, bet_symbol, COUNT(*) AS cnt
|
||
FROM game_wheel_round_bet
|
||
GROUP BY `date`, round_id, user_id, bet_symbol
|
||
HAVING COUNT(*) > 1;
|
||
|
||
-- 4. 重建唯一键
|
||
ALTER TABLE game_wheel_round_bet
|
||
DROP INDEX uk_round_user_symbol,
|
||
ADD UNIQUE INDEX uk_date_round_user_symbol (`date`, round_id, user_id, bet_symbol);
|
||
|
||
|
||
## 2026-07-27 修复用户积分为负数的存量数据
|
||
|
||
-- 背景:TtUserMapper.subtractAccountAmount 原 SQL 为
|
||
-- set account_amount = account_amount - #{money},
|
||
-- account_credits = LEAST(account_credits, account_amount - #{money})
|
||
-- MySQL 的 SET 子句从左到右求值,第二个赋值中的 account_amount 已是扣减后的新值,
|
||
-- 实际执行等价于 LEAST(积分, 原金币 - 2×扣款额),单笔扣款超过金币余额一半时积分被扣成负数。
|
||
-- 代码已修复(积分赋值前置 + GREATEST 兜底防负),存量负积分数据需执行以下 SQL 归零。
|
||
|
||
-- 排查存量负积分用户
|
||
SELECT user_id, user_name, account_amount, account_credits
|
||
FROM tt_user
|
||
WHERE account_credits < 0;
|
||
|
||
-- 修复:负积分归零
|
||
UPDATE tt_user SET account_credits = 0 WHERE account_credits < 0;
|
||
|
||
|
||
## 2026-07-28 SnapPay代收渠道接入:新增后台开关配置
|
||
|
||
-- 背景:SnapPay(snappay168)代收渠道不参与 payCompanyWeights 权重池,
|
||
-- 充值金额 1000-50000 时强制路由到 SnapPay(ApiRechargeController.unifiedPay);
|
||
-- 本开关控制该强制路由:1=启用,0=停用(停用/下单失败时自动回落权重路由)。
|
||
-- 后台入口:推广后台 → 网站设置 → 支付设置 → SnapPay开关(未执行本SQL时页面保存会自动跳过该项,代码兜底视为启用)。
|
||
INSERT INTO sys_config (config_id, config_name, config_key, config_value, config_type, create_by, create_time, remark)
|
||
SELECT 139, 'SnapPay开关', 'snappayEnabled', '1', 'Y', 'admin', NOW(), 'SnapPay代收开关:1=启用(1000-50000强制走SnapPay),0=停用(回落权重路由)'
|
||
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM sys_config WHERE config_key = 'snappayEnabled');
|
||
|
||
|
||
## 2026-07-30 对战新增2v2组队模式
|
||
|
||
-- 背景:欧皇/非酋对战新增2v2组队玩法。座位0/1为一队、座位2/3为二队,
|
||
-- 按队伍累计掉落总价值判胜(欧皇高者胜、非酋低者胜);
|
||
-- 胜方两人各自保留自己的掉落,并平分败方掉落总价值(复用平分奖机制);
|
||
-- 败方仅获得安慰奖(fightLoserPrize 配置)。
|
||
-- team_mode:0或NULL=个人对战(存量数据不受影响),1=2v2组队(创建时强制 player_num=4)。
|
||
ALTER TABLE tt_fight ADD COLUMN team_mode TINYINT DEFAULT 0 COMMENT '组队模式:0=个人对战 1=2v2组队(座位0/1一队、座位2/3二队)';
|
||
|
||
|
||
## 2026-07-31 Olympus 电子游戏模块建表
|
||
|
||
-- 背景:新增 Olympus 消除类电子游戏(类 sweet 体系)。全量 DDL 见 olympus-py/schema.sql,已在本地开发库执行。
|
||
-- 表清单(11张,前缀 game_olympus_):box / ornament(17档桶 0x~1000x 含种子) / box_ornament(含 used)
|
||
-- / round / step / record(建表即带 settled 等结算字段) / user / win / prize_ornament / prize_range / box_template
|
||
-- 设计要点:三模式互斥 normal|ante|buy_fs(CM=1/2/20);单局封顶 1000x;
|
||
-- step 表自带 accumulator_before/after(跨回合炸弹累计)与 win_capped(封顶截断标记)。
|
||
-- Java 服务接入时再执行(语句注释在 schema.sql 尾部):
|
||
-- sys_config 新增 olympusMaintenance 维护开关。
|
||
|
||
|
||
## 2026-08-01 Olympus Java 服务接入(game-olympus-service)
|
||
|
||
-- 背景:olympus Java 游戏服务已建成并编译通过。以下为上线需执行的配置。
|
||
-- 账户流水源:TtAccountRecordSource 新增 OLYMPUS_SPIN(60,消费) / OLYMPUS_REWARD(61,奖励);
|
||
-- 背包源 TtboxRecordSource 新增 OLYMPUS_BOX(13)。(枚举已在代码中,无需 SQL)
|
||
|
||
-- 1) 维护开关
|
||
INSERT INTO sys_config (config_name, config_key, config_value, config_type, create_by, create_time, remark)
|
||
VALUES ('奥林匹斯维护', 'olympusMaintenance', '0', 'Y', 'admin', NOW(), '奥林匹斯维护开关 0正常 1维护');
|
||
|
||
-- 2) 后台菜单(ruoyi-ui 动态菜单,component 对应 src/views/game/olympus/*/index.vue)
|
||
-- 自动挂到“游戏管理”下(与极速糖果同级);定位失败则挂到顶级根目录,可在后台菜单管理里拖动。
|
||
SET @sweet_dir := (SELECT parent_id FROM sys_menu WHERE component = 'game/sweet/box/index' LIMIT 1);
|
||
SET @game_root := (SELECT parent_id FROM sys_menu WHERE menu_id = @sweet_dir LIMIT 1);
|
||
|
||
INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, remark)
|
||
VALUES ('奥林匹斯', IFNULL(@game_root, 0), 5, 'olympus', '', 1, 0, 'M', '0', '0', '', 'star', 'admin', NOW(), '奥林匹斯电子游戏管理');
|
||
SET @oly_dir := LAST_INSERT_ID();
|
||
|
||
INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, remark) VALUES
|
||
('箱子配置', @oly_dir, 1, 'box', 'game/olympus/box/index', 1, 0, 'C', '0', '0', 'game:olympus:box', 'shopping', 'admin', NOW(), '奥林匹斯箱子配置与身份桶分布'),
|
||
('饰品列表', @oly_dir, 2, 'ornament', 'game/olympus/ornament/index', 1, 0, 'C', '0', '0', 'game:olympus:ornament', 'star', 'admin', NOW(), '奥林匹斯 17 档饰品桶定义'),
|
||
('回合管理', @oly_dir, 3, 'round', 'game/olympus/round/index', 1, 0, 'C', '0', '0', 'game:olympus:round', 'documentation', 'admin', NOW(), '奥林匹斯预生成回合查询'),
|
||
('奖池水位', @oly_dir, 4, 'rewardPool', 'game/olympus/rewardPool/index', 1, 0, 'C', '0', '0', 'game:olympus:pool', 'money', 'admin', NOW(), '奥林匹斯按箱奖池水位(注水/抽水/批量/重置)'),
|
||
('玩家记录', @oly_dir, 5, 'record', 'game/olympus/record/index', 1, 0, 'C', '0', '0', 'game:olympus:record', 'list', 'admin', NOW(), '奥林匹斯游戏记录'),
|
||
('每日统计', @oly_dir, 6, 'dailywin', 'game/olympus/dailywin/index', 1, 0, 'C', '0', '0', 'game:olympus:win', 'chart', 'admin', NOW(), '奥林匹斯每日盈亏统计'),
|
||
('奖品管理', @oly_dir, 7, 'prize', 'game/olympus/prize/index', 1, 0, 'C', '0', '0', 'game:olympus:prize', 'gift', 'admin', NOW(), '奥林匹斯返奖饰品与区间配置');
|
||
|
||
-- 前端页面文件(已在 ruoyi-ui 创建,7 页对齐糖果):
|
||
-- src/api/game/olympus/{box,ornament,round,rewardPool,record,dailywin,prize}/api.js
|
||
-- src/views/game/olympus/{box,ornament,round,rewardPool,record,dailywin,prize}/index.vue
|
||
|
||
-- 3) 【返奖饰品】从极速糖果整套导入到奥林匹斯
|
||
-- 幂等:先清空 olympus 两张返奖表再导入;会覆盖 olympus 现有返奖饰品配置。保留原 id 以保持区间映射。
|
||
DELETE FROM game_olympus_prize_range;
|
||
DELETE FROM game_olympus_prize_ornament;
|
||
|
||
INSERT INTO game_olympus_prize_ornament
|
||
(id, game_type, name, image_url, grade, exterior_name, sort, status, is_fallback, create_time)
|
||
SELECT id, 'OLYMPUS', name, image_url, grade, exterior_name, sort, status, is_fallback, NOW()
|
||
FROM game_sweet_prize_ornament;
|
||
|
||
-- 糖果 range 用 ornament_id,olympus range 用 prize_id,一一对应
|
||
INSERT INTO game_olympus_prize_range (prize_id, win_low, win_high)
|
||
SELECT ornament_id, win_low, win_high
|
||
FROM game_sweet_prize_range;
|
||
|
||
-- 4) 【奖池水位调整日志】新增审计表
|
||
CREATE TABLE IF NOT EXISTS game_olympus_reward_log (
|
||
id BIGINT NOT NULL AUTO_INCREMENT COMMENT 'PK',
|
||
box_id BIGINT DEFAULT NULL COMMENT '箱子ID(批量/重置为汇总,可空)',
|
||
box_name VARCHAR(100) DEFAULT NULL COMMENT '箱子名/汇总描述',
|
||
type TINYINT NOT NULL COMMENT '1注水 2抽水 3重置',
|
||
amount DECIMAL(14,2) NOT NULL DEFAULT '0.00' COMMENT '调整金额(绝对值)',
|
||
balance_before DECIMAL(14,2) DEFAULT NULL COMMENT '调整前水位',
|
||
balance_after DECIMAL(14,2) DEFAULT NULL COMMENT '调整后水位',
|
||
pool_balance DECIMAL(14,2) DEFAULT NULL COMMENT '操作后总池余额',
|
||
operator VARCHAR(64) DEFAULT NULL COMMENT '操作人',
|
||
remark VARCHAR(200) DEFAULT NULL COMMENT '备注',
|
||
create_time DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||
PRIMARY KEY (id),
|
||
KEY idx_create (create_time)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='Olympus奖池水位调整日志';
|
||
-- 本地也可跑:cd olympus-py && python _create_reward_log.py(需 DB 可连)。前端奖池水位页已对齐 bullet:说明面板/本轮RTP进度/收敛占比/备注/预估/调整后预览/调整历史。
|
||
-- 【已建过该表的环境】补列(总池余额):
|
||
ALTER TABLE game_olympus_reward_log ADD COLUMN pool_balance DECIMAL(14,2) DEFAULT NULL COMMENT '操作后总池余额' AFTER balance_after;
|
||
|
||
-- 5) 【奖池水位拆身份】奖池由「按箱 1 个池」改为「按 箱子 × 身份 4 个池」(common/anchor/robot/white)
|
||
-- bet/win 由 game_olympus_record + tt_user 按身份派生(口径同 OlympusAudience.resolve),历史数据自动分流,无需回填。
|
||
ALTER TABLE game_olympus_reward_log ADD COLUMN audience VARCHAR(16) NOT NULL DEFAULT 'common' COMMENT '身份 common/anchor/robot/white' AFTER box_name;
|
||
ALTER TABLE game_olympus_reward_log ADD KEY idx_audience (audience);
|
||
|
||
## 2026-08-01 经典开箱管理菜单(复用宝箱列表/开箱记录,按 isFight=1 / source=1 过滤)
|
||
|
||
-- 背景:新增独立“经典开箱管理”菜单模块。复用现有页面 skins/ttBox/index 与 skins/ttBox/boxRecords,
|
||
-- 通过菜单 query 传 isFight=1(仅经典宝箱)与 source=1(仅经典开箱记录)过滤;不改数据模型。
|
||
-- 说明:顶级目录 parent_id=0(可在后台“菜单管理”拖动到合适位置);两个子菜单 is_cache=1(不做 keep-alive 缓存),
|
||
-- 避免与原“宝箱管理”下同组件菜单共享实例导致 query 过滤失效。按钮权限沿用 admin:box:add / admin:box:edit。
|
||
INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, query, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, remark)
|
||
VALUES ('经典开箱管理', 0, 8, 'classicBox', '', NULL, 1, 0, 'M', '0', '0', '', 'box', 'admin', NOW(), '经典开箱管理目录');
|
||
SET @classic_dir := LAST_INSERT_ID();
|
||
INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, query, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, remark) VALUES
|
||
('经典宝箱列表', @classic_dir, 1, 'classicBoxList', 'skins/ttBox/index', '{"isFight":"1"}', 1, 1, 'C', '0', '0', 'admin:box:list', 'list', 'admin', NOW(), '仅展示经典开箱宝箱(isFight=1)'),
|
||
('经典开箱记录', @classic_dir, 2, 'classicBoxRecords', 'skins/ttBox/boxRecords', '{"source":"1"}', 1, 1, 'C', '0', '0', '', 'documentation', 'admin', NOW(), '仅展示经典开箱记录(source=1)');
|
||
|
||
|
||
-- 2026-08-05 对战宝箱查看奖项增加白号爆率列
|
||
-- 对战宝箱饰品表增加白号数量字段
|
||
ALTER TABLE tt_box_ornaments ADD COLUMN white_odds INT DEFAULT 0 COMMENT '白号数量(白号爆率池)';
|
||
|
||
|
||
## 2026-08-01 经典开箱管理补充:经典宝箱分类 + 临时倍率迁移
|
||
-- (type=0=对战分类、type=1=经典分类、不传=全部),boxType.vue 已加 $route 监听避免串味。
|
||
SET @classic_dir := (SELECT menu_id FROM sys_menu WHERE menu_name = '经典开箱管理' AND menu_type = 'M' LIMIT 1);
|
||
|
||
-- 1) 新增“经典宝箱分类”:复用 skins/ttBox/boxType,query type=1(仅经典分类 isFightType=1)。is_cache=1 不缓存。
|
||
INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, query, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, remark)
|
||
VALUES ('经典宝箱分类', @classic_dir, 3, 'classicBoxType', 'skins/ttBox/boxType', '{"type":"1"}', 1, 1, 'C', '0', '0', '', 'component', 'admin', NOW(), '仅展示经典宝箱分类(isFightType=1)');
|
||
|
||
-- 2) 将“临时倍率”从“宝箱管理”迁移到“经典开箱管理”下(仅改归属与排序,组件/权限不变)。
|
||
UPDATE sys_menu SET parent_id = @classic_dir, order_num = 4 WHERE menu_name = '临时倍率';
|
||
|
||
|
||
## 2026-08-05 充值维护拆分为充值渠道维护 + 卡密充值维护
|
||
|
||
-- 业务原因 rechargeMaintenance 同时控制卡密充值 (cardPay) 和充值渠道 (unifiedPay)
|
||
-- 两个开关会同时生效,无法独立维护,互不影响。
|
||
|
||
-- 1) 将原"充值维护"重命名为"充值渠道维护",仅控制第三方支付渠道 unifiedPay
|
||
UPDATE sys_config
|
||
SET config_name = '充值渠道维护',
|
||
remark = '充值渠道维护开关 0 正常 1 维护(仅控制第三方支付渠道)'
|
||
WHERE config_key = 'rechargeMaintenance';
|
||
|
||
-- 2) 新增"卡密充值维护"配置,仅控制卡密充值 cardPay
|
||
INSERT INTO sys_config (config_name, config_key, config_value, config_type, create_by, create_time, remark)
|
||
VALUES ('卡密充值维护', 'cardRechargeMaintenance', '0', 'Y', 'admin', NOW(), '卡密充值维护开关 0 正常 1 维护(仅控制卡密充值)')
|
||
ON DUPLICATE KEY UPDATE config_value = config_value;
|
||
|
||
## 2026-08-05 用户ID改为8位随机数字
|
||
|
||
-- 1) 取消 tt_user.user_id 的自增属性,改为程序生成
|
||
ALTER TABLE tt_user MODIFY COLUMN user_id INT NOT NULL COMMENT '用户ID';
|
||
|
||
-- 2) 说明:新注册用户/后台生成账号的 user_id 将由程序生成 10000000~99999999 之间的8位随机数字,并保证不与已有用户ID及副号绑定记录重复
|
||
|
||
## 2026-08-06 白号管理支持生成白号用户
|
||
|
||
-- 1) 在 user_type 字典中新增“白号”选项(键值 06)
|
||
INSERT INTO sys_dict_data (dict_sort, dict_label, dict_value, dict_type, status, create_by, create_time, remark)
|
||
SELECT 6, '白号', '06', 'user_type', '0', 'admin', NOW(), '白号用户'
|
||
FROM dual
|
||
WHERE NOT EXISTS (SELECT 1 FROM sys_dict_data WHERE dict_type = 'user_type' AND dict_value = '06');
|
||
|
||
|
||
## 2026-08-06 对战房间房主昵称入库(用户被物理删除后仍可展示)
|
||
|
||
-- 背景:owner_nick_name 原为 @TableField(exist=false) 不入库字段,每次查询时从 tt_user 实时填充。
|
||
-- 用户被物理删除(forceDelete)后,tt_user 查不到,对战大厅/历史记录中的房主昵称显示为空。
|
||
-- 现将 owner_nick_name 入库,创建对战时写入昵称快照;enrichOwnerNickNames 方法仅在用户存在时
|
||
-- 用实时昵称覆盖(用户改了昵称能同步),用户被删除时保留入库快照。
|
||
ALTER TABLE tt_fight ADD COLUMN owner_nick_name VARCHAR(100) DEFAULT NULL COMMENT '房主昵称快照(创建时写入,用户被物理删除后仍可展示)';
|
||
|
||
-- 回填存量数据:从 tt_user 把现有对战的房主昵称填入 owner_nick_name
|
||
UPDATE tt_fight tf
|
||
LEFT JOIN tt_user tu ON tf.user_id = tu.user_id
|
||
SET tf.owner_nick_name = COALESCE(tf.owner_nick_name, tu.nick_name)
|
||
WHERE tf.owner_nick_name IS NULL;
|
||
|
||
|
||
## 2026-08-06 流水抽奖系统建表及菜单
|
||
|
||
-- ========== 1. 流水抽奖活动表 ==========
|
||
CREATE TABLE IF NOT EXISTS `tt_turnover_lottery` (
|
||
`id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键 ID',
|
||
`lottery_name` VARCHAR(200) NOT NULL COMMENT '抽奖名称',
|
||
`status` INT DEFAULT 0 COMMENT '状态:0=关闭,1=开启',
|
||
`lottery_type` INT DEFAULT 1 COMMENT '类型:0=普通宝箱,1=流水抽奖',
|
||
`turnover_threshold` INT DEFAULT 3000 COMMENT '流水门槛(多少流水可抽1次)',
|
||
`image_url` VARCHAR(500) DEFAULT NULL COMMENT '宝箱封面图',
|
||
`sort` INT DEFAULT 0 COMMENT '排序',
|
||
`total_value` DECIMAL(18,2) DEFAULT NULL COMMENT '奖品总价值',
|
||
`profit_per_round` INT DEFAULT NULL COMMENT '每轮利润',
|
||
`profit_rate` DECIMAL(10,4) DEFAULT NULL COMMENT '利润率',
|
||
`create_by` VARCHAR(64) DEFAULT NULL COMMENT '创建者',
|
||
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||
`update_by` VARCHAR(64) DEFAULT NULL COMMENT '更新者',
|
||
`update_time` DATETIME DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||
`del_flag` INT DEFAULT 0 COMMENT '删除标志:0=存在,2=删除',
|
||
PRIMARY KEY (`id`),
|
||
KEY `idx_status` (`status`),
|
||
KEY `idx_sort` (`sort`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='流水抽奖活动表';
|
||
|
||
-- ========== 2. 流水抽奖奖品表 ==========
|
||
CREATE TABLE IF NOT EXISTS `tt_turnover_lottery_prize` (
|
||
`id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键 ID',
|
||
`lottery_id` BIGINT(20) NOT NULL COMMENT '关联抽奖活动 ID',
|
||
`ornament_id` BIGINT(20) DEFAULT NULL COMMENT '饰品 ID(已废弃,奖品改为自定义)',
|
||
`ornament_name` VARCHAR(200) DEFAULT NULL COMMENT '饰品名称/自定义名称',
|
||
`image_url` VARCHAR(500) DEFAULT NULL COMMENT '图片 URL',
|
||
`price` DECIMAL(18,2) DEFAULT NULL COMMENT '饰品价格',
|
||
`ornament_level` INT DEFAULT NULL COMMENT '饰品等级 ID(关联 tt_ornaments_level)',
|
||
`display_count` INT DEFAULT 10 COMMENT '展示数量(前端库存显示)',
|
||
`real_count` INT DEFAULT 10 COMMENT '真实数量(实际权重,当前剩余)',
|
||
`initial_real_count` INT DEFAULT 10 COMMENT '初始真实数量(重置奖池时恢复值)',
|
||
`sort` INT DEFAULT 0 COMMENT '展示排序',
|
||
`total_count` INT DEFAULT 0 COMMENT '已发放次数',
|
||
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||
`update_time` DATETIME DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||
PRIMARY KEY (`id`),
|
||
KEY `idx_lottery_id` (`lottery_id`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='流水抽奖奖品表';
|
||
|
||
-- 已创建表的环境补充字段( ornaments_id 改为可空,新增 ornament_level、initial_real_count)
|
||
ALTER TABLE `tt_turnover_lottery_prize`
|
||
MODIFY COLUMN `ornament_id` BIGINT(20) DEFAULT NULL COMMENT '饰品 ID(已废弃,奖品改为自定义)',
|
||
ADD COLUMN `ornament_level` INT DEFAULT NULL COMMENT '饰品等级 ID(关联 tt_ornaments_level)',
|
||
ADD COLUMN `initial_real_count` INT DEFAULT 10 COMMENT '初始真实数量(重置奖池时恢复值)';
|
||
|
||
-- 历史数据初始化:已存在的奖品把初始真实数量同步为当前真实数量
|
||
UPDATE `tt_turnover_lottery_prize` SET `initial_real_count` = `real_count` WHERE `initial_real_count` = 10;
|
||
|
||
-- 2026-08-08 流水抽奖奖品新增磨损度字段(自定义饰品可配置磨损度,发放入背包时写入 tt_box_records.exterior_name)
|
||
ALTER TABLE `tt_turnover_lottery_prize`
|
||
ADD COLUMN `exterior_name` VARCHAR(20) DEFAULT NULL COMMENT '磨损度名称(崭新出厂/略有磨损/久经沙场/破损不堪/战痕累累/无涂装)';
|
||
|
||
-- ========== 3. 流水抽奖记录表 ==========
|
||
CREATE TABLE IF NOT EXISTS `tt_turnover_lottery_record` (
|
||
`id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键 ID',
|
||
`user_id` INT NOT NULL COMMENT '用户 ID',
|
||
`lottery_id` BIGINT(20) NOT NULL COMMENT '抽奖活动 ID',
|
||
`prize_id` BIGINT(20) DEFAULT NULL COMMENT '奖品 ID',
|
||
`ornament_id` BIGINT(20) DEFAULT NULL COMMENT '饰品 ID',
|
||
`ornament_name` VARCHAR(200) DEFAULT NULL COMMENT '饰品名称',
|
||
`image_url` VARCHAR(500) DEFAULT NULL COMMENT '图片 URL',
|
||
`ornaments_price` DECIMAL(18,2) DEFAULT NULL COMMENT '奖品价值',
|
||
`cost_turnover` INT DEFAULT NULL COMMENT '消耗的流水值',
|
||
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||
PRIMARY KEY (`id`),
|
||
KEY `idx_user_id` (`user_id`),
|
||
KEY `idx_lottery_id` (`lottery_id`),
|
||
KEY `idx_create_time` (`create_time`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='流水抽奖记录表';
|
||
|
||
-- 2026-08-08 全服中奖记录接口(/api/turnoverLottery/globalRecords)性能优化
|
||
-- 查询模式:WHERE lottery_id = ? AND ornaments_price >= ? ORDER BY create_time DESC
|
||
-- 单列 idx_lottery_id / idx_create_time 无法同时命中「按宝箱过滤 + 按时间倒序」,补复合索引
|
||
-- 执行前先 SHOW INDEX FROM tt_turnover_lottery_record; 确认无等价索引
|
||
ALTER TABLE `tt_turnover_lottery_record`
|
||
ADD INDEX `idx_ttlr_lottery_ctime` (`lottery_id`, `create_time`);
|
||
|
||
-- ========== 4. 后台菜单 ==========
|
||
-- 流水抽奖目录
|
||
INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, remark)
|
||
VALUES ('流水抽奖', 0, 9, 'turnoverLottery', '', 1, 0, 'M', '0', '0', '', 'gift', 'admin', NOW(), '流水抽奖管理目录');
|
||
|
||
SET @lottery_dir := LAST_INSERT_ID();
|
||
|
||
-- 抽奖活动列表
|
||
INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, remark)
|
||
VALUES ('抽奖活动', @lottery_dir, 1, 'lotteryList', 'turnoverLottery/list', 1, 0, 'C', '0', '0', 'system:turnoverLottery:list', 'list', 'admin', NOW(), '流水抽奖活动管理');
|
||
|
||
-- 抽奖记录查询
|
||
INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, remark)
|
||
VALUES ('抽奖记录', @lottery_dir, 2, 'lotteryRecords', 'turnoverLottery/records', 1, 0, 'C', '0', '0', 'system:turnoverLotteryRecord:list', 'documentation', 'admin', NOW(), '流水抽奖记录查询');
|
||
|
||
-- 奖项配置页面 (隐藏菜单,通过抽奖活动列表“查看奖项”按钮跳转)
|
||
INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, remark)
|
||
VALUES ('奖项配置', @lottery_dir, 3, 'prize', 'turnoverLottery/prize', 1, 0, 'C', '1', '0', 'system:turnoverLotteryPrize:list', '#', 'admin', NOW(), '流水抽奖奖项配置页面');
|
||
|
||
-- 按钮权限 (menu_type='F',不显示在左侧导航)
|
||
INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, remark)
|
||
VALUES
|
||
('抽奖新增', @lottery_dir, 4, '', NULL, 1, 0, 'F', '1', '0', 'system:turnoverLottery:add', '#', 'admin', NOW(), ''),
|
||
('抽奖修改', @lottery_dir, 5, '', NULL, 1, 0, 'F', '1', '0', 'system:turnoverLottery:edit', '#', 'admin', NOW(), ''),
|
||
('抽奖删除', @lottery_dir, 6, '', NULL, 1, 0, 'F', '1', '0', 'system:turnoverLottery:remove', '#', 'admin', NOW(), '');
|
||
|
||
-- ========== 5. 消息分类字段 ==========
|
||
ALTER TABLE `tt_notice`
|
||
ADD COLUMN `category` VARCHAR(50) DEFAULT NULL COMMENT '消息分类:GAME_*/SYS_*';
|
||
|
||
ALTER TABLE `tt_announcement`
|
||
ADD COLUMN `category` VARCHAR(50) DEFAULT NULL COMMENT '消息分类:GAME_*/SYS_*';
|
||
|
||
|
||
-- ========== 6. 转赠/提货次数数据库幂等字段 ==========
|
||
-- 用于防止 Redis 防重标记过期后重复扣/放次数
|
||
|
||
ALTER TABLE `tt_delivery_record`
|
||
ADD COLUMN `times_deducted` TINYINT NOT NULL DEFAULT 0 COMMENT '该批次次数是否已处理:0=未处理,1=已处理(扣次或释放)';
|
||
|
||
ALTER TABLE `tt_transfer_apply`
|
||
ADD COLUMN `times_deducted` TINYINT NOT NULL DEFAULT 0 COMMENT '该批次次数是否已处理:0=未处理,1=已处理(扣次或释放)';
|
||
|
||
-- 上线后:历史已审核订单的 times_deducted 默认为 0,但因为 Redis 标记可能已过期,
|
||
-- 如果再次对历史订单操作,需要先把已完结的批次标记为已处理,避免重复扣/放次数。
|
||
-- 以下 SQL 把状态为已完成(10)或已取消(11)的提货批次标记为已处理:
|
||
UPDATE `tt_delivery_record`
|
||
SET `times_deducted` = 1
|
||
WHERE `status` IN (10, 11)
|
||
AND `times_deducted` = 0;
|
||
|
||
-- 以下 SQL 把状态为已通过(1)或已驳回(2)的转赠批次标记为已处理:
|
||
UPDATE `tt_transfer_apply`
|
||
SET `times_deducted` = 1
|
||
WHERE `status` IN (1, 2)
|
||
AND `times_deducted` = 0;
|
||
|
||
|
||
-- ========================================================================
|
||
-- 疯狂转盘(彩虹旋风)内圈玩法改造 DDL
|
||
-- 详见 docs/疯狂转盘内圈玩法设计.md
|
||
-- ========================================================================
|
||
-- 执行前务必先选中数据库,否则会报 1046 - No database selected
|
||
USE `changzhou`;
|
||
|
||
-- 1) 新建奖励矩阵表(方案B自定义饰品:10档 × 3内圈色 × 4外圈符号 = 120条)
|
||
CREATE TABLE `game_wheel_reward_matrix` (
|
||
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||
`bet_amount` INT NOT NULL COMMENT '下注额层:5/10/20/50/100/200/500/1000/2000/5000',
|
||
`color` VARCHAR(16) NOT NULL COMMENT '内圈颜色:gold/red/purple',
|
||
`symbol` VARCHAR(8) NOT NULL COMMENT '外圈符号:A/B/C/D',
|
||
`multiplier` INT NOT NULL COMMENT '倍率(后台可配,12个跨下注额共用)',
|
||
`prize_value` DECIMAL(18,2) NOT NULL DEFAULT 0.00 COMMENT '价值=下注额×倍率(自动算)',
|
||
`prize_name` VARCHAR(200) NOT NULL DEFAULT '' COMMENT '饰品名称(自定义)',
|
||
`prize_grade` INT NULL COMMENT '品质等级(自定义,对应tt_ornaments_level.id)',
|
||
`prize_exterior` VARCHAR(64) NULL COMMENT '磨损度(自定义)',
|
||
`prize_image` VARCHAR(500) NULL COMMENT '饰品图片(自定义)',
|
||
`status` CHAR(1) NOT NULL DEFAULT '1' COMMENT '0停用 1启用',
|
||
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||
PRIMARY KEY (`id`),
|
||
UNIQUE KEY `uk_combo` (`bet_amount`,`color`,`symbol`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='疯狂转盘奖励矩阵(自定义饰品120条)';
|
||
|
||
-- 2) 回合表 game_wheel_round 改造
|
||
-- period_no:全局唯一期号 = date(yyyyMMdd) × 100000 + 当日序号(round_id),作为业务主键替代 date+round_id 复合键
|
||
-- inner_colors:本轮内圈24色随机排布快照(外圈 symbols 已存在,为固定布局)
|
||
-- result 扩容以容纳4池结果JSON,如 {"real":3,"robot":10,"blank":7,"promo":15}
|
||
ALTER TABLE `game_wheel_round`
|
||
ADD COLUMN `period_no` BIGINT NOT NULL DEFAULT 0 COMMENT '全局唯一期号=date×100000+当日序号' AFTER `round_id`,
|
||
ADD COLUMN `inner_colors` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '本轮内圈24色随机排布快照' AFTER `symbols`,
|
||
MODIFY COLUMN `result` VARCHAR(128) NOT NULL DEFAULT '' COMMENT '4池开奖结果JSON {real,robot,blank,promo}';
|
||
-- 历史数据回填 period_no(date 为 yyyyMMdd 文本;新数据由代码直接写入 period_no)
|
||
UPDATE `game_wheel_round` SET `period_no` = CAST(`date` AS UNSIGNED) * 100000 + `round_id` WHERE `period_no` = 0;
|
||
ALTER TABLE `game_wheel_round` ADD UNIQUE KEY `uk_period_no` (`period_no`);
|
||
|
||
-- 3) 下注表 game_wheel_round_bet 改造
|
||
-- period_no:关联回合的全局唯一期号(查询/结算/判重单列定位)
|
||
-- color:下注内圈颜色;pool_type:落库定池 real/robot/blank/promo
|
||
-- multiplier/prize_id:下注时快照倍率与命中奖品矩阵行ID(防中途改配置影响已下注)
|
||
-- credits_cut:下注时实际扣减的积分额(退款按此原路退回;仅金币扣款时为0)
|
||
ALTER TABLE `game_wheel_round_bet`
|
||
ADD COLUMN `period_no` BIGINT NOT NULL DEFAULT 0 COMMENT '全局唯一期号' AFTER `round_id`,
|
||
ADD COLUMN `color` VARCHAR(16) NOT NULL DEFAULT '' COMMENT '下注内圈颜色 gold/red/purple' AFTER `bet_symbol`,
|
||
ADD COLUMN `pool_type` VARCHAR(16) NOT NULL DEFAULT '' COMMENT '决策池 real/robot/blank/promo',
|
||
ADD COLUMN `multiplier` INT NOT NULL DEFAULT 0 COMMENT '下注时快照倍率',
|
||
ADD COLUMN `prize_id` BIGINT NULL COMMENT '命中奖品矩阵行ID(game_wheel_reward_matrix.id)快照',
|
||
ADD COLUMN `credits_cut` DECIMAL(10,2) NOT NULL DEFAULT 0.00 COMMENT '下注实际扣减积分额(退款原路退回)';
|
||
UPDATE `game_wheel_round_bet` SET `period_no` = CAST(`date` AS UNSIGNED) * 100000 + `round_id` WHERE `period_no` = 0;
|
||
ALTER TABLE `game_wheel_round_bet` ADD KEY `idx_period_no` (`period_no`);
|
||
-- 移除旧唯一键:新玩法每次下注独立一条、绝不累加(同格同额也各记一条),
|
||
-- 旧 uk_date_round_user_symbol 会阻止同用户同符号多注独立落库,必须删除
|
||
ALTER TABLE `game_wheel_round_bet` DROP INDEX `uk_date_round_user_symbol`;
|
||
|
||
-- 4) 账变来源:疯狂转盘退款(孤儿局无法开奖时静默退本金)在 TtAccountRecordSource 枚举新增来源码即可,
|
||
-- 账变写入 tt_user_blend_ercash 复用现有结构,无需额外DDL。
|
||
-- 新玩法余额变动仅两类:下注扣款(LUCKLY_WHEEL_SPIN) 与 退本金(新增退款来源);
|
||
-- 中奖与安慰奖均发饰品进背包(source=WHEEL_BOX),不动余额。
|
||
|
||
-- 5) 奖励矩阵种子:生成 120 行骨架(10档 × 3色 × 4符号),
|
||
-- multiplier 按默认倍率、prize_value = bet_amount × multiplier 自动计算,
|
||
-- prize_name/prize_grade/prize_exterior/prize_image 留空由后台配置(本 INSERT 为一次性,uk_combo 保证不重复)。
|
||
INSERT INTO `game_wheel_reward_matrix`
|
||
(`bet_amount`, `color`, `symbol`, `multiplier`, `prize_value`, `prize_name`, `prize_grade`, `prize_exterior`, `prize_image`, `status`)
|
||
SELECT b.amount, m.color, m.symbol, m.mult, b.amount * m.mult, '', NULL, NULL, NULL, '1'
|
||
FROM (
|
||
SELECT 5 amount UNION ALL SELECT 10 UNION ALL SELECT 20 UNION ALL SELECT 50 UNION ALL SELECT 100
|
||
UNION ALL SELECT 200 UNION ALL SELECT 500 UNION ALL SELECT 1000 UNION ALL SELECT 2000 UNION ALL SELECT 5000
|
||
) b
|
||
CROSS JOIN (
|
||
SELECT 'gold' color, 'A' symbol, 44 mult
|
||
UNION ALL SELECT 'gold','B',26 UNION ALL SELECT 'gold','C',11 UNION ALL SELECT 'gold','D',8
|
||
UNION ALL SELECT 'red','A',33 UNION ALL SELECT 'red','B',21 UNION ALL SELECT 'red','C',8 UNION ALL SELECT 'red','D',6
|
||
UNION ALL SELECT 'purple','A',27 UNION ALL SELECT 'purple','B',17 UNION ALL SELECT 'purple','C',7 UNION ALL SELECT 'purple','D',5
|
||
) m;
|
||
|
||
-- 6) 生产配置 sys_config(game.wheel.setting) 迁移为新结构
|
||
-- 现有旧结构(symbols/symbol_scores/special_effects)已不适用新玩法。
|
||
-- 最稳妥方式:删除该配置行,应用下次 newRound/getGameConfig 检测到缺失会
|
||
-- 由 CommonWheelService 自动按新结构(内圈分布/外圈布局/12倍率/10档下注/奖池比例0.6/RTP0.9)重建,无需手拼 JSON。
|
||
DELETE FROM `sys_config` WHERE `config_key` = 'game.wheel.setting';
|
||
|
||
-- 机器人对战进房时间配置表新增随机秒数字段
|
||
-- 含义:在 join_seconds 基础上额外随机增加 1~random_seconds 秒,保证机器人错峰进房
|
||
ALTER TABLE tt_robot_fight_join_config ADD COLUMN random_seconds INT NOT NULL DEFAULT 10 COMMENT '机器人进房随机偏移秒数(在join_seconds基础上额外随机增加1~randomSeconds秒)';
|
||
|
||
-- 机器人对战价格档位配置表
|
||
-- 含义:控制机器人为每种对战模式自动创建房间时,各价格档位需要维持的目标房间数量
|
||
CREATE TABLE `tt_robot_fight_price_config` (
|
||
`id` INT NOT NULL AUTO_INCREMENT COMMENT '主键ID',
|
||
`price_limit` DECIMAL(15,2) NOT NULL COMMENT '价格上限(房间宝箱总金额 <= price_limit 命中该档位)',
|
||
`target_count` INT NOT NULL COMMENT '该档位目标房间数量',
|
||
`sort_order` INT NOT NULL COMMENT '排序序号(越小越靠前)',
|
||
`status` CHAR(1) NOT NULL DEFAULT '0' COMMENT '状态 0启用 1停用',
|
||
`remark` VARCHAR(255) DEFAULT NULL COMMENT '备注',
|
||
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||
`update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||
PRIMARY KEY (`id`),
|
||
KEY `idx_status_sort` (`status`, `sort_order`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='机器人对战价格档位配置表';
|
||
|
||
-- 默认初始化数据,与原硬编码配置保持一致:200档6个、800档4个、1500档1个
|
||
INSERT INTO `tt_robot_fight_price_config` (`price_limit`, `target_count`, `sort_order`, `status`, `remark`, `create_time`, `update_time`)
|
||
VALUES
|
||
(200.00, 6, 1, '0', '0-200金额房间', NOW(), NOW()),
|
||
(800.00, 4, 2, '0', '200-800金额房间', NOW(), NOW()),
|
||
(1500.00, 1, 3, '0', '800-1500金额房间', NOW(), NOW());
|
||
|
||
-- 机器人对战分组表新增价格档位配置ID字段
|
||
-- 含义:每个机器人对战分组关联一个价格档位,用于按档位目标数量创建房间
|
||
ALTER TABLE tt_robot_fight_group ADD COLUMN price_config_id INT DEFAULT NULL COMMENT '价格档位配置ID(关联 tt_robot_fight_price_config.id)';
|
||
|
||
-- =====================================================
|
||
-- 提货次数管理功能 - 数据库迁移脚本
|
||
-- 创建时间:2025-08-05
|
||
-- 说明:添加批次号、申请时VIP等级、次数扣减状态字段
|
||
-- =====================================================
|
||
|
||
-- =====================================================
|
||
-- 幸运升级新增"幸运值"(累计原始概率)字段
|
||
-- 说明:按用户类型区分,玩家每次拉取累加前端原始概率(如90),出货成功清0重置;返回给前端cocos展示
|
||
-- =====================================================
|
||
ALTER TABLE tt_upgrade_ornaments
|
||
ADD COLUMN probability_invested INT NOT NULL DEFAULT 0 COMMENT '普通用户累计原始概率(幸运值),出货成功清0',
|
||
ADD COLUMN anchor_probability_invested INT NOT NULL DEFAULT 0 COMMENT '主播累计原始概率(幸运值),出货成功清0';
|
||
|
||
-- =====================================================
|
||
-- 幸运升级记录页:持久化每条记录的"幸运值"快照 + 分页查询索引
|
||
-- 说明:tt_upgrade_ornaments.probability_invested 只保存"当前累计值",
|
||
-- 历史每条记录的幸运值需单独持久化;新增列后历史旧数据为 NULL(前端显示0)
|
||
-- =====================================================
|
||
ALTER TABLE tt_upgrade_record
|
||
ADD COLUMN lucky_value INT DEFAULT NULL COMMENT '本次升级幸运值(累计原始概率)快照' AFTER probability;
|
||
|
||
-- 记录分页排序索引(open_time 倒序)
|
||
-- 全服+当前饰品
|
||
ALTER TABLE tt_upgrade_record ADD INDEX idx_upgrade_opentime (target_upgrade_id, open_time);
|
||
-- 我的+当前饰品
|
||
ALTER TABLE tt_upgrade_record ADD INDEX idx_user_upgrade_opentime (user_id, target_upgrade_id, open_time);
|
||
-- 注:我的+全部饰品依赖已有 (user_id, open_time);全服+全部饰品依赖 open_time 排序
|
||
|
||
-- 第 1 个字段
|
||
ALTER TABLE `tt_user_blend_ercash`
|
||
ADD COLUMN `anchor_id` INT COMMENT '上级主播 ID(消费时的直属上级主播)' AFTER `user_id`;
|
||
|
||
-- 第 2 个字段
|
||
ALTER TABLE `tt_user_blend_ercash`
|
||
ADD COLUMN `business_id` INT COMMENT '最终招商 ID(上级主播所属的招商)' AFTER `anchor_id`;
|
||
|
||
-- 创建索引
|
||
CREATE INDEX idx_business_commission ON tt_user_blend_ercash (business_id, create_time, source);
|
||
CREATE INDEX idx_anchor_commission ON tt_user_blend_ercash (anchor_id, create_time, source);
|
||
|
||
|
||
-- 1. 先检查字段是否已存在
|
||
DESCRIBE tt_user_blend_ercash_archive;
|
||
|
||
-- 2. 如果 anchor_id 和 business_id 列不存在,就执行下面的语句:
|
||
ALTER TABLE `tt_user_blend_ercash_archive`
|
||
ADD COLUMN `anchor_id` INT COMMENT '上级主播 ID' AFTER `user_id`;
|
||
|
||
ALTER TABLE `tt_user_blend_ercash_archive`
|
||
ADD COLUMN `business_id` INT COMMENT '最终招商 ID' AFTER `anchor_id`;
|
||
|
||
-- 3. 创建索引
|
||
CREATE INDEX idx_business_commission_archive ON tt_user_blend_ercash_archive (business_id, create_time, source);
|
||
CREATE INDEX idx_anchor_commission_archive ON tt_user_blend_ercash_archive (anchor_id, create_time, source);
|
||
|
||
|
||
CREATE INDEX idx_olympus_record_box_settled ON game_olympus_record (box_id, settled);
|
||
|
||
|
||
-- 为 tt_box_records 表添加 period_no 字段,用于精确匹配转盘记录
|
||
ALTER TABLE tt_box_records
|
||
ADD COLUMN period_no BIGINT NULL COMMENT '转盘期号(WHEEL专用)' AFTER box_price;
|
||
|
||
-- 为 period_no 添加索引,加速查询
|
||
CREATE INDEX idx_period_no ON tt_box_records(period_no);
|
||
|
||
|
||
-- 疯狂转盘奖池调节记录表
|
||
CREATE TABLE IF NOT EXISTS game_wheel_pool_adjustment (
|
||
id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '主键ID',
|
||
pool_type VARCHAR(20) NOT NULL COMMENT '池类型(real/display)',
|
||
adjustment_amount DECIMAL(12,2) NOT NULL COMMENT '调整金额(正数=注水,负数=抽水)',
|
||
balance_before DECIMAL(12,2) NOT NULL COMMENT '调整前余额',
|
||
balance_after DECIMAL(12,2) NOT NULL COMMENT '调整后余额',
|
||
reason VARCHAR(200) DEFAULT NULL COMMENT '调整原因',
|
||
operator VARCHAR(50) DEFAULT NULL COMMENT '操作人',
|
||
create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||
INDEX idx_pool_type (pool_type),
|
||
INDEX idx_create_time (create_time)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='疯狂转盘奖池调节记录';
|
||
|
||
-- ========== tt_user 新增安全密码字段(提货时校验,与登录密码 password 独立) ==========
|
||
ALTER TABLE tt_user ADD COLUMN safe_password VARCHAR(100) DEFAULT NULL COMMENT '安全密码(6位数字,BCrypt加密,提货时校验;NULL=未设置)';
|
||
-- 安全密码明文:仅供后台用户详情展示与编辑回填(与 password 明文存 remark 同一约定)
|
||
ALTER TABLE tt_user ADD COLUMN safe_password_plain VARCHAR(16) DEFAULT NULL COMMENT '安全密码明文(仅后台展示/回填,不参与校验)';
|
||
|
||
|
||
-- ========== 玫瑰女郎:删除 game_olympus_record.auto_dismantle(历史列,已无代码读写) ==========
|
||
-- 背景:自动分解改为「前端开关 + 末帧前端调 /api/userPackSack/decompose」,后端不再记录该快照,
|
||
-- 实体 OlympusRecord.autoDismantle 字段已删除;该列历史上也从未被写过非 0 值(旧 Redis 开关无入口),全为默认 0。
|
||
-- 执行前确认列是否还在(MySQL 不支持 DROP COLUMN IF EXISTS,先查可避免 1091 报错):
|
||
SELECT COLUMN_NAME FROM information_schema.COLUMNS
|
||
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'game_olympus_record' AND COLUMN_NAME = 'auto_dismantle';
|
||
|
||
-- 确认存在后再执行:
|
||
ALTER TABLE game_olympus_record DROP COLUMN auto_dismantle;
|
||
|
||
|
||
-- =====================================================
|
||
-- 幸运升级:白号独立幸运池(幸运值 + 独立幸运区间)
|
||
-- 背景:白号原先走"纯概率"分支(不写任何共享字段),但记录/界面里的幸运值读的是普通池
|
||
-- (tt_upgrade_ornaments.probability_invested),导致白号看到的是别人的数(恒 0 或别人垫出来的值)。
|
||
-- 现改为:白号有自己的幸运值列 + 自己的幸运区间,进度与判定都走白号池
|
||
-- (Redis key 用 userType=06,白号之间共享这一个池,与宝箱白号池/奥林匹斯 white audience 口径一致)。
|
||
-- blank_luck_section 为空时回退普通 luck_section(后台「幸运升级饰品」编辑接口已支持传该字段)。
|
||
-- =====================================================
|
||
ALTER TABLE tt_upgrade_ornaments
|
||
ADD COLUMN blank_luck_section VARCHAR(20) DEFAULT NULL COMMENT '白号幸运区间[min,max),NULL/空=回退普通luck_section',
|
||
ADD COLUMN blank_probability_invested INT NOT NULL DEFAULT 0 COMMENT '白号累计原始概率(幸运值),出货成功清0',
|
||
ADD COLUMN blank_amount_invested DECIMAL(19,2) NOT NULL DEFAULT 0 COMMENT '白号本轮已投金额(实际扣款口径),出货成功清0',
|
||
ADD COLUMN blank_effective_amount_invested DECIMAL(19,2) NOT NULL DEFAULT 0 COMMENT '白号本轮已投金额(真实计算口径),出货成功清0';
|
||
|
||
-- =====================================================
|
||
-- 疯狂转盘:注单增加"是否退过本金"标记
|
||
-- 背景:game_wheel_round_bet.settled 只有两态(0=未结算 / 1=已结算),
|
||
-- 正常发奖与兜底退本金在库里长得完全一样,事后无法逐注区分,客服/对账只能靠流水 source=64 反推。
|
||
-- 退款时额外打 refunded=1(ApiWheelService.refundBets 内与 settled 一起 CAS 更新)。
|
||
-- =====================================================
|
||
ALTER TABLE game_wheel_round_bet
|
||
ADD COLUMN refunded TINYINT NOT NULL DEFAULT 0 COMMENT '是否走过退本金 0=否 1=是(settled=1 时用于区分发奖/退款)';
|
||
|
||
|
||
-- =====================================================
|
||
-- 亏损返水(玩家可见名:亏损返利)—— 每半个月给亏损玩家自动发返水 CDK
|
||
-- =====================================================
|
||
|
||
-- 1. 结算明细表(后台「CDK管理 - 亏损返水」页的数据源)
|
||
CREATE TABLE IF NOT EXISTS `tt_loss_rebate` (
|
||
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||
`period` VARCHAR(32) NOT NULL COMMENT '期次 yyyy-MM-dd~yyyy-MM-dd',
|
||
`user_id` INT NOT NULL COMMENT '用户ID',
|
||
`user_name` VARCHAR(64) DEFAULT NULL COMMENT '用户账号',
|
||
`nick_name` VARCHAR(64) DEFAULT NULL COMMENT '用户昵称',
|
||
`bet_amount` DECIMAL(19,2) NOT NULL DEFAULT 0 COMMENT '本期游戏投入',
|
||
`win_amount` DECIMAL(19,2) NOT NULL DEFAULT 0 COMMENT '本期游戏产出',
|
||
`loss_amount` DECIMAL(19,2) NOT NULL DEFAULT 0 COMMENT '净亏=投入-产出',
|
||
`rebate_amount` DECIMAL(19,2) NOT NULL DEFAULT 0 COMMENT '应返水=净亏×比例(人工发放时可能被下调为实发金额)',
|
||
`status` TINYINT NOT NULL DEFAULT 0 COMMENT '0=待人工发放(超单期上限) 1=已自动发放 2=已人工发放 3=自动发放失败',
|
||
`red_packet_id` INT DEFAULT NULL COMMENT '关联 tt_red_packet.id',
|
||
`cdkey` VARCHAR(64) DEFAULT NULL COMMENT '发放的CDK口令',
|
||
`grant_time` DATETIME DEFAULT NULL COMMENT '发放时间',
|
||
`grant_by` VARCHAR(64) DEFAULT NULL COMMENT '发放人(自动发放为 lossRebate,人工发放为管理员账号)',
|
||
`remark` VARCHAR(255) DEFAULT NULL COMMENT '备注',
|
||
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||
`update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||
PRIMARY KEY (`id`),
|
||
UNIQUE KEY `uk_period_user` (`period`, `user_id`),
|
||
KEY `idx_status` (`status`),
|
||
KEY `idx_period` (`period`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='亏损返水结算明细(亏损返利)';
|
||
|
||
-- 1b. ⚠ 排序规则必须跟库里其他表一致(tt_red_packet / tt_notice / tt_user_blend_ercash 都是 utf8mb4_general_ci)。
|
||
-- 2026-09-16 首次建表时漏了 COLLATE,MySQL 8 默认给了 utf8mb4_0900_ai_ci,
|
||
-- 导致「tt_red_packet.description LIKE tt_loss_rebate.period」这类跨表字符串比较直接报
|
||
-- Illegal mix of collations。(Java 绑定参数的查询不受影响,但跨表关联会炸,必须修。)
|
||
-- 已建过表的环境执行这一条;新建环境上面的 CREATE TABLE 已带 COLLATE,不用跑。
|
||
ALTER TABLE tt_loss_rebate CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
|
||
|
||
-- 2. 后台菜单:CDK管理 → 亏损返水(父菜单按名字找;若报错先确认「CDK管理」的 menu_name)
|
||
INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, remark)
|
||
SELECT '亏损返水', menu_id, 4, 'lossRebate', 'skins/ttredPacket/lossRebate', 1, 0, 'C', '0', '0', 'admin:lossRebate:list', 'money', 'admin', NOW(), '亏损返水结算明细,超单期上限的记录在此人工发放CDK'
|
||
FROM (SELECT menu_id FROM sys_menu WHERE menu_name = 'CDK管理' AND menu_type = 'M' LIMIT 1) m;
|
||
|
||
-- 3. 注册定时任务(每月 1 日与 16 日 01:30,结算上一个自然半月)
|
||
INSERT INTO sys_job (job_name, job_group, invoke_target, cron_expression, misfire_policy, concurrent, status, create_by, create_time, remark)
|
||
VALUES ('亏损返水结算', 'LOSS_REBATE', 'lossRebateService.generateHalfMonthLossRebate()', '0 30 1 1,16 * ?', '3', '1', '0', 'admin', NOW(), '每月1日与16日01:30结算上一个自然半月:返水≤上限自动发CDK+站内信,超上限转后台人工发放;白号/机器人不参与');
|
||
|
||
-- 4. 可选:比例 / 最低发放金额 / 单期上限 / CDK有效期。不建这四条也能跑,代码内兜底 5% / 1元 / 500元 / 30天。
|
||
INSERT INTO sys_config (config_name, config_key, config_value, config_type, create_by, create_time, remark)
|
||
VALUES ('亏损返水比例', 'lossRebateRate', '0.05', 'N', 'admin', NOW(), '0.05=5%,玩家可见的「亏损返利」返水比例'),
|
||
('亏损返水最低发放金额', 'lossRebateMinAmount', '1', 'N', 'admin', NOW(), '返水低于该金额不结算,避免几毛钱的码刷屏'),
|
||
('亏损返水单期上限', 'lossRebateMaxAmount', '500', 'N', 'admin', NOW(), '返水超过该金额不自动发放,转「CDK管理-亏损返水」页人工发放;填 0 表示不设上限'),
|
||
('亏损返利CDK有效期(天)', 'lossRebateValidDays', '30', 'N', 'admin', NOW(), 'CDK有效期 = 生成时刻 + N 天');
|
||
|
||
-- 5. 改名(回血红包 → 亏损返利):只在已建过旧数据的环境执行,新环境不用跑。
|
||
-- 代码里红包标题=「亏损返利CDK」、站内信标题=「亏损返利」,执行后历史数据与新数据命名一致。
|
||
UPDATE tt_red_packet SET title = '亏损返利CDK' WHERE title = '回血红包';
|
||
UPDATE tt_notice SET title = '亏损返利' WHERE category = 'SYS_LOSS_REBATE' AND title = '回血红包';
|
||
UPDATE sys_job SET job_name = '亏损返水结算' WHERE invoke_target = 'lossRebateService.generateHalfMonthLossRebate()' AND job_name = '亏损返水回血红包';
|
||
UPDATE sys_config SET config_name = '亏损返利CDK有效期(天)' WHERE config_key = 'lossRebateValidDays' AND config_name = '回血红包有效期(天)';
|
||
|
||
-- 6. 亏损返利CDK 绑定收款人(只有指定用户能兑,口令被转发/截图也兑不走)
|
||
-- ⚠ 必须先执行这条 ALTER,再重启后端:新代码建红包时会写 receiver_user_id,列不存在会插入失败(服务本身能起来)。
|
||
ALTER TABLE tt_red_packet
|
||
ADD COLUMN receiver_user_id INT DEFAULT NULL COMMENT '指定领取人用户ID:NULL=不限用户(平台/主播红包原有行为);非NULL=仅该用户可领(亏损返利CDK)';
|
||
|
||
-- 历史数据不用回填:这列是 NULL 时行为不变(不限用户)。
|
||
-- 已发出的那几条测试返利红包如果也想绑上收款人,可以从明细表按 red_packet_id 关联回填:
|
||
-- UPDATE tt_red_packet p INNER JOIN tt_loss_rebate r ON r.red_packet_id = p.id SET p.receiver_user_id = r.user_id WHERE p.title = '亏损返利CDK' AND p.receiver_user_id IS NULL; |