108 KiB
-- 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=禁用';
极速糖果领取流程简化 - 存量数据迁移
部署前执行(处理待决定记录)
-- 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 基础上额外随机增加 1random_seconds 秒,保证机器人错峰进房
ALTER TABLE tt_robot_fight_join_config ADD COLUMN random_seconds INT NOT NULL DEFAULT 10 COMMENT '机器人进房随机偏移秒数(在join_seconds基础上额外随机增加1randomSeconds秒)';
-- 机器人对战价格档位配置表
-- 含义:控制机器人为每种对战模式自动创建房间时,各价格档位需要维持的目标房间数量
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;