热游飘屏处理
This commit is contained in:
parent
82339cc4e1
commit
02d435b618
@ -1,207 +0,0 @@
|
||||
# 房间红包功能开发完成清单
|
||||
|
||||
## ✅ 已完成文件列表
|
||||
|
||||
### 1. Domain层(11个文件)
|
||||
- ✅ RoomRedPacketType.java - 红包类型枚举
|
||||
- ✅ RoomRedPacketStatus.java - 红包状态枚举
|
||||
- ✅ RoomRedPacketSourceType.java - 红包来源类型枚举
|
||||
- ✅ RoomRedPacketRefundStatus.java - 退款状态枚举
|
||||
- ✅ RoomRedPacket.java - 红包领域对象
|
||||
- ✅ RoomRedPacketRecord.java - 红包记录领域对象
|
||||
- ✅ RoomRedPacketGateway.java - 红包网关接口
|
||||
- ✅ RoomRedPacketRecordGateway.java - 红包记录网关接口
|
||||
|
||||
### 2. Infrastructure层(13个文件)
|
||||
- ✅ RoomRedPacketEntity.java - 红包实体
|
||||
- ✅ RoomRedPacketRecordEntity.java - 红包记录实体
|
||||
- ✅ RoomRedPacketDAO.java - 红包DAO接口
|
||||
- ✅ RoomRedPacketRecordDAO.java - 红包记录DAO接口
|
||||
- ✅ RoomRedPacketDAO.xml - MyBatis映射文件
|
||||
- ✅ RoomRedPacketRecordDAO.xml - MyBatis映射文件
|
||||
- ✅ RoomRedPacketConvertor.java - 基础设施转换器
|
||||
- ✅ RoomRedPacketGatewayImpl.java - 红包网关实现
|
||||
- ✅ RoomRedPacketRecordGatewayImpl.java - 红包记录网关实现
|
||||
- ✅ RoomRedPacketKeys.java - Redis Key枚举
|
||||
- ✅ RoomRedPacketCacheService.java - Redis缓存服务接口
|
||||
- ✅ RoomRedPacketCacheServiceImpl.java - Redis缓存服务实现
|
||||
|
||||
### 3. Client层(10个文件)
|
||||
- ✅ SendRoomRedPacketCmd.java - 发红包命令
|
||||
- ✅ GrabRoomRedPacketCmd.java - 抢红包命令
|
||||
- ✅ QueryRoomRedPacketListCmd.java - 查询列表命令
|
||||
- ✅ QueryRoomRedPacketDetailCmd.java - 查询详情命令
|
||||
- ✅ RoomRedPacketCO.java - 红包CO
|
||||
- ✅ RoomRedPacketDetailCO.java - 红包详情CO
|
||||
- ✅ RoomRedPacketRecordCO.java - 红包记录CO
|
||||
- ✅ GrabRoomRedPacketResultCO.java - 抢红包结果CO
|
||||
- ✅ RoomRedPacketService.java - 服务接口
|
||||
|
||||
### 4. Application层(6个文件)
|
||||
- ✅ RoomRedPacketAppConvertor.java - 应用层转换器
|
||||
- ✅ SendRoomRedPacketCmdExe.java - 发红包执行器
|
||||
- ✅ GrabRoomRedPacketCmdExe.java - 抢红包执行器(高并发核心)
|
||||
- ✅ QueryRoomRedPacketListQryExe.java - 查询列表执行器
|
||||
- ✅ QueryRoomRedPacketDetailQryExe.java - 查询详情执行器
|
||||
- ✅ RoomRedPacketServiceImpl.java - 服务实现
|
||||
|
||||
### 5. Adapter层(1个文件)
|
||||
- ✅ RoomRedPacketRestController.java - REST控制器
|
||||
|
||||
### 6. Scheduler层(1个文件)
|
||||
- ✅ RoomRedPacketExpireTask.java - 过期退款定时任务
|
||||
|
||||
### 7. 错误码
|
||||
- ✅ OtherErrorCode.java - 已添加红包相关错误码(3260-3271)
|
||||
|
||||
### 8. 数据库SQL
|
||||
- ✅ room_red_packet_tables.sql - 数据库建表SQL
|
||||
|
||||
---
|
||||
|
||||
## 📊 统计
|
||||
- **总文件数**: 42个
|
||||
- **代码行数**: 约3500+行
|
||||
- **涉及模块**: 7个层级
|
||||
|
||||
---
|
||||
|
||||
## 🚀 API接口清单
|
||||
|
||||
### 1. 发送红包
|
||||
```
|
||||
POST /api/room/red-packet/send
|
||||
```
|
||||
**请求参数**:
|
||||
```json
|
||||
{
|
||||
"roomId": 123456,
|
||||
"packetType": 1, // 1-固定金额 2-拼手气
|
||||
"totalAmount": 1000, // 总金额(金币数量)
|
||||
"totalCount": 10, // 红包个数
|
||||
"expireMinutes": 3 // 过期分钟数:1/3/5
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 抢红包
|
||||
```
|
||||
POST /api/room/red-packet/grab
|
||||
```
|
||||
**请求参数**:
|
||||
```json
|
||||
{
|
||||
"packetId": "uuid-string"
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 查询房间红包列表
|
||||
```
|
||||
GET /api/room/red-packet/list?roomId=123456&limit=20
|
||||
```
|
||||
|
||||
### 4. 查询红包详情
|
||||
```
|
||||
GET /api/room/red-packet/detail?packetId=uuid-string
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 配置说明
|
||||
|
||||
### 1. Redis Key前缀
|
||||
所有Redis Key使用前缀 `ROOM:RED_PACKET:`
|
||||
|
||||
### 2. 错误码范围
|
||||
红包相关错误码:3260-3279
|
||||
|
||||
### 3. 定时任务
|
||||
- **过期退款任务**: 每分钟执行一次 (cron = "0 * * * * ?")
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ 待完成事项
|
||||
|
||||
### 1. 钱包服务GoldOrigin枚举
|
||||
需要在钱包服务的 `GoldOrigin` 枚举中添加以下事件类型:
|
||||
```java
|
||||
// 在 wallet-inner-model 的 GoldOrigin 枚举中添加
|
||||
RED_PACKET_SEND("red_packet_send", "发红包"),
|
||||
RED_PACKET_GRAB("red_packet_grab", "抢红包"),
|
||||
RED_PACKET_REFUND("red_packet_refund", "红包退款"),
|
||||
```
|
||||
|
||||
### 2. IM推送集成
|
||||
发红包时,如果金额>=10000,需要触发全服IM推送。代码中已预留TODO位置:
|
||||
```java
|
||||
// SendRoomRedPacketCmdExe.java 第94行
|
||||
// TODO: 调用IM服务触发全服推送
|
||||
```
|
||||
|
||||
### 3. WebSocket房间推送
|
||||
抢红包成功后,需要通过WebSocket推送消息到房间内其他用户。可选实现。
|
||||
|
||||
### 4. 用户信息补充
|
||||
在查询接口中,需要补充用户昵称和头像信息。建议调用user服务批量查询。
|
||||
|
||||
### 5. 房间权限校验
|
||||
发红包和抢红包前,需要校验用户是否在房间内。建议调用live服务校验。
|
||||
|
||||
---
|
||||
|
||||
## 📝 注意事项
|
||||
|
||||
### 1. 高并发保护
|
||||
- Redis防重标记
|
||||
- Lua脚本原子扣减
|
||||
- 异步写库提高响应速度
|
||||
|
||||
### 2. 幂等性保证
|
||||
- 发红包:使用packetId作为bizNo
|
||||
- 抢红包:使用recordId作为bizNo
|
||||
- 退款:使用packetId_refund作为bizNo
|
||||
|
||||
### 3. 数据一致性
|
||||
- 异步写库失败会记录日志
|
||||
- 可扩展异常日志表进行补偿
|
||||
|
||||
### 4. 性能优化
|
||||
- Redis缓存红包主数据
|
||||
- 拼手气金额预生成
|
||||
- 查询接口可加缓存
|
||||
|
||||
---
|
||||
|
||||
## 🧪 测试建议
|
||||
|
||||
### 1. 单元测试
|
||||
- 固定金额红包发送
|
||||
- 拼手气红包发送
|
||||
- 高并发抢红包(多线程)
|
||||
- 过期退款
|
||||
|
||||
### 2. 压力测试
|
||||
- 100人同时抢1个红包
|
||||
- 1000QPS发红包
|
||||
- Redis性能测试
|
||||
|
||||
### 3. 异常测试
|
||||
- 余额不足
|
||||
- 重复领取
|
||||
- 红包过期
|
||||
- 异步失败补偿
|
||||
|
||||
---
|
||||
|
||||
## 📦 部署步骤
|
||||
|
||||
1. 执行数据库SQL建表
|
||||
2. 确保Redis服务正常
|
||||
3. 在钱包服务添加GoldOrigin枚举
|
||||
4. 重启other服务
|
||||
5. 验证接口可用性
|
||||
|
||||
---
|
||||
|
||||
**开发完成时间**: 2025-11-25
|
||||
**开发者**: Leo
|
||||
**状态**: ✅ 核心功能完成,待集成测试
|
||||
@ -1,63 +0,0 @@
|
||||
-- 房间红包主表
|
||||
CREATE TABLE `room_red_packet` (
|
||||
`id` BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '主键ID',
|
||||
`packet_id` VARCHAR(32) UNIQUE NOT NULL COMMENT '红包ID(UUID)',
|
||||
`room_id` BIGINT NOT NULL COMMENT '房间ID',
|
||||
`user_id` BIGINT NOT NULL COMMENT '发起人ID',
|
||||
|
||||
`packet_type` TINYINT NOT NULL COMMENT '红包类型:1-固定金额 2-拼手气',
|
||||
`source_type` TINYINT NOT NULL DEFAULT 1 COMMENT '来源类型:1-用户红包 2-平台红包',
|
||||
`total_amount` BIGINT NOT NULL COMMENT '总金额(分)',
|
||||
`total_count` INT NOT NULL COMMENT '红包总个数',
|
||||
`remain_amount` BIGINT NOT NULL COMMENT '剩余金额(分)',
|
||||
`remain_count` INT NOT NULL COMMENT '剩余个数',
|
||||
|
||||
`expire_minutes` INT NOT NULL COMMENT '过期分钟数:1/3/5',
|
||||
`expire_time` DATETIME NOT NULL COMMENT '过期时间',
|
||||
|
||||
`status` TINYINT NOT NULL DEFAULT 1 COMMENT '状态:1-进行中 2-已抢完 3-已过期',
|
||||
`refund_status` TINYINT DEFAULT 0 COMMENT '退款状态:0-未退 1-已退 2-无需退款',
|
||||
|
||||
`is_broadcast` TINYINT DEFAULT 0 COMMENT '是否触发全服推送:0-否 1-是(10000+金币)',
|
||||
|
||||
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
|
||||
INDEX `idx_room_id` (`room_id`),
|
||||
INDEX `idx_user_id` (`user_id`),
|
||||
INDEX `idx_expire_time` (`expire_time`, `status`),
|
||||
INDEX `idx_status` (`status`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='房间红包主表';
|
||||
|
||||
-- 房间红包领取记录表
|
||||
CREATE TABLE `room_red_packet_record` (
|
||||
`id` BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '主键ID',
|
||||
`record_id` VARCHAR(32) UNIQUE NOT NULL COMMENT '记录ID(UUID)',
|
||||
`packet_id` VARCHAR(32) NOT NULL COMMENT '红包ID',
|
||||
`user_id` BIGINT NOT NULL COMMENT '领取人ID',
|
||||
`amount` BIGINT NOT NULL COMMENT '领取金额(分)',
|
||||
`grab_time` DATETIME NOT NULL COMMENT '抢红包时间',
|
||||
|
||||
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
|
||||
UNIQUE KEY `uk_packet_user` (`packet_id`, `user_id`) COMMENT '防止重复领取',
|
||||
INDEX `idx_packet_id` (`packet_id`),
|
||||
INDEX `idx_user_id` (`user_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='房间红包领取记录表';
|
||||
|
||||
-- 房间红包异常日志表(可选,用于补偿机制)
|
||||
CREATE TABLE `room_red_packet_error_log` (
|
||||
`id` BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '主键ID',
|
||||
`packet_id` VARCHAR(32) NOT NULL COMMENT '红包ID',
|
||||
`user_id` BIGINT COMMENT '用户ID',
|
||||
`error_type` VARCHAR(50) NOT NULL COMMENT '异常类型',
|
||||
`error_msg` TEXT COMMENT '异常信息',
|
||||
`retry_count` INT DEFAULT 0 COMMENT '重试次数',
|
||||
`status` TINYINT DEFAULT 0 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 '更新时间',
|
||||
|
||||
INDEX `idx_packet_id` (`packet_id`),
|
||||
INDEX `idx_status` (`status`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='房间红包异常日志表';
|
||||
@ -1,48 +0,0 @@
|
||||
-- ============================================
|
||||
-- 火箭系统数据库初始化脚本
|
||||
-- ============================================
|
||||
|
||||
-- 1. 创建火箭配置表
|
||||
CREATE TABLE IF NOT EXISTS `rocket_config` (
|
||||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID',
|
||||
`level` TINYINT UNSIGNED NOT NULL COMMENT '火箭等级 1/2/3',
|
||||
`max_energy` BIGINT UNSIGNED NOT NULL COMMENT '最大能量值',
|
||||
`reward_config` JSON DEFAULT NULL COMMENT '奖励配置(JSON,预留)',
|
||||
`contributor_reward_rate` DECIMAL(5,2) DEFAULT NULL COMMENT '贡献者奖励比例%',
|
||||
`normal_reward_config` JSON DEFAULT NULL COMMENT '普通用户奖励配置(JSON,预留)',
|
||||
`status` TINYINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '状态 1:启用 0:禁用',
|
||||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_level` (`level`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='火箭配置表';
|
||||
|
||||
-- 2. 插入初始配置数据
|
||||
INSERT INTO `rocket_config` (`level`, `max_energy`, `status`) VALUES
|
||||
(1, 150000, 1),
|
||||
(2, 500000, 1),
|
||||
(3, 1000000, 1)
|
||||
ON DUPLICATE KEY UPDATE `max_energy` = VALUES(`max_energy`);
|
||||
|
||||
-- 3. 创建奖励领取记录表
|
||||
CREATE TABLE IF NOT EXISTS `rocket_reward_claim_log` (
|
||||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID',
|
||||
`rocket_history_id` VARCHAR(32) NOT NULL COMMENT '火箭历史记录ID(MongoDB _id)',
|
||||
`room_id` BIGINT UNSIGNED NOT NULL COMMENT '房间ID',
|
||||
`user_id` BIGINT UNSIGNED NOT NULL COMMENT '用户ID',
|
||||
`rocket_level` TINYINT UNSIGNED NOT NULL COMMENT '火箭等级',
|
||||
`is_contributor` TINYINT UNSIGNED NOT NULL COMMENT '是否贡献者 1:是 0:否',
|
||||
`contribution_energy` BIGINT UNSIGNED DEFAULT 0 COMMENT '贡献能量值',
|
||||
`contribution_rate` DECIMAL(8,4) DEFAULT 0.0000 COMMENT '贡献率%',
|
||||
`reward_type` VARCHAR(32) NOT NULL COMMENT '奖励类型 GOLD/DIAMOND/PROP',
|
||||
`reward_item_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '奖励物品ID',
|
||||
`reward_amount` BIGINT UNSIGNED NOT NULL COMMENT '奖励数量',
|
||||
`wallet_biz_no` VARCHAR(64) DEFAULT NULL COMMENT '钱包业务单号',
|
||||
`claimed_at` DATETIME NOT NULL COMMENT '领取时间',
|
||||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_rocket_user` (`rocket_history_id`, `user_id`),
|
||||
KEY `idx_room_id` (`room_id`),
|
||||
KEY `idx_user_id` (`user_id`),
|
||||
KEY `idx_claimed_at` (`claimed_at`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='火箭奖励领取记录表';
|
||||
@ -1,82 +0,0 @@
|
||||
// ============================================
|
||||
// 火箭系统MongoDB索引初始化脚本
|
||||
// 执行方式: mongosh < rocket_mongo_init.js
|
||||
// ============================================
|
||||
|
||||
// 切换到likei数据库 (根据实际数据库名修改)
|
||||
use likei
|
||||
|
||||
print("开始创建火箭系统MongoDB索引...");
|
||||
|
||||
// 1. room_rocket_status 集合索引
|
||||
print("1. 创建 room_rocket_status 索引...");
|
||||
|
||||
// 唯一索引:房间ID+日期
|
||||
db.room_rocket_status.createIndex(
|
||||
{ "room_id": 1, "date": 1 },
|
||||
{ unique: true, name: "uk_room_date", background: true }
|
||||
);
|
||||
print(" ✓ 创建唯一索引 uk_room_date");
|
||||
|
||||
// 普通索引:状态
|
||||
db.room_rocket_status.createIndex(
|
||||
{ "status": 1 },
|
||||
{ name: "idx_status", background: true }
|
||||
);
|
||||
print(" ✓ 创建索引 idx_status");
|
||||
|
||||
// 普通索引:状态+过期时间 (用于定时任务清理)
|
||||
db.room_rocket_status.createIndex(
|
||||
{ "status": 1, "claim_expire_time": 1 },
|
||||
{ name: "idx_status_expire", background: true }
|
||||
);
|
||||
print(" ✓ 创建索引 idx_status_expire");
|
||||
|
||||
// TTL索引:30天自动过期
|
||||
db.room_rocket_status.createIndex(
|
||||
{ "updated_at": 1 },
|
||||
{ expireAfterSeconds: 2592000, name: "ttl_30days", background: true }
|
||||
);
|
||||
print(" ✓ 创建TTL索引 ttl_30days (30天过期)");
|
||||
|
||||
// 2. rocket_launch_history 集合索引
|
||||
print("2. 创建 rocket_launch_history 索引...");
|
||||
|
||||
// 普通索引:房间ID+发射时间 (倒序)
|
||||
db.rocket_launch_history.createIndex(
|
||||
{ "room_id": 1, "launch_time": -1 },
|
||||
{ name: "idx_room_launch_time", background: true }
|
||||
);
|
||||
print(" ✓ 创建索引 idx_room_launch_time");
|
||||
|
||||
// 普通索引:日期
|
||||
db.rocket_launch_history.createIndex(
|
||||
{ "date": 1 },
|
||||
{ name: "idx_date", background: true }
|
||||
);
|
||||
print(" ✓ 创建索引 idx_date");
|
||||
|
||||
// 普通索引:等级
|
||||
db.rocket_launch_history.createIndex(
|
||||
{ "level": 1 },
|
||||
{ name: "idx_level", background: true }
|
||||
);
|
||||
print(" ✓ 创建索引 idx_level");
|
||||
|
||||
// 普通索引:发射时间 (用于时间范围查询)
|
||||
db.rocket_launch_history.createIndex(
|
||||
{ "launch_time": -1 },
|
||||
{ name: "idx_launch_time", background: true }
|
||||
);
|
||||
print(" ✓ 创建索引 idx_launch_time");
|
||||
|
||||
print("\n索引创建完成!\n");
|
||||
|
||||
// 验证索引
|
||||
print("验证 room_rocket_status 索引:");
|
||||
printjson(db.room_rocket_status.getIndexes());
|
||||
|
||||
print("\n验证 rocket_launch_history 索引:");
|
||||
printjson(db.rocket_launch_history.getIndexes());
|
||||
|
||||
print("\n火箭系统MongoDB初始化完成!");
|
||||
@ -197,6 +197,11 @@ public class HotGameServiceImpl implements HotGameService {
|
||||
, param.getType());
|
||||
}
|
||||
|
||||
String sysOrigin = UserCredential.parseToken(param.getToken()).getSysOrigin();
|
||||
GameListConfig gameListConfig = gameListConfigService.getByGameId(param.getGameId(), GameOriginEnum.HOTGAME.name(), sysOrigin);
|
||||
sendBroadcast(param, gameListConfig);
|
||||
//累计游戏排行榜
|
||||
incGameRankingRecord(param, gameListConfig);
|
||||
return new HotGameResponse<HotGameCoin>()
|
||||
.setData(new HotGameCoin()
|
||||
.setBalanceCoin(res.getBalance().getDollarAmount().longValue())
|
||||
@ -213,17 +218,6 @@ public class HotGameServiceImpl implements HotGameService {
|
||||
log.error("ex:{}", Throwables.getStackTraceAsString(ex));
|
||||
}
|
||||
|
||||
try {
|
||||
String sysOrigin = UserCredential.parseToken(param.getToken()).getSysOrigin();
|
||||
GameListConfig gameListConfig = gameListConfigService.getByGameId(param.getGameId(), GameOriginEnum.HOTGAME.name(), sysOrigin);
|
||||
sendBroadcast(param, gameListConfig);
|
||||
|
||||
//累计游戏排行榜
|
||||
incGameRankingRecord(param, gameListConfig);
|
||||
} catch (Exception e) {
|
||||
log.error("hotgame游戏飘窗推送失败 ex:{}", e.getMessage());
|
||||
}
|
||||
|
||||
return new HotGameResponse<HotGameCoin>()
|
||||
.setErrorCode(HotGameErrorEnum.SERVER_ERROR.getErrorCode());
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user