添加Swagger/OpenAPI依赖并更新用户账户管理相关的API文档注释,优化用户和管理员账户控制器的接口描述,移除不必要的字段和参数,调整数据库映射以简化用户账户管理逻辑。

This commit is contained in:
zyh
2025-08-24 19:21:54 +08:00
parent 1b3ce1040a
commit 4664f1c487
64 changed files with 1688 additions and 171 deletions

100
docs/README.md Normal file
View File

@@ -0,0 +1,100 @@
# 游戏平台后端服务
基于 Spring Boot WebFlux + MyBatis + MySQL 的游戏平台后端服务。
## 🚀 快速开始
### 环境要求
- JDK 17+
- Maven 3.6+
- MySQL 8.0+
### 启动步骤
1. 配置数据库连接(`application.yml`
2. 运行 `mvn spring-boot:run`
3. 访问 http://localhost:8080
## 📚 API 文档
### Swagger UI
启动应用后,访问以下地址查看交互式 API 文档:
- **Swagger UI**: http://localhost:8080/swagger-ui.html
- **OpenAPI JSON**: http://localhost:8080/api-docs
- **OpenAPI YAML**: http://localhost:8080/api-docs.yaml
### 接口分组
- **管理员账户管理**: `/api/admin/accounts` 相关接口
- **用户账户管理**: `/api/users` 相关接口
### 使用说明
详细的使用说明请参考:[Swagger使用说明.md](docs/Swagger使用说明.md)
## 🔧 主要功能
### 用户管理
- 用户账户的增删改查
- 支持管理员和代理两种用户类型
- 账户状态管理(启用/禁用)
- 密码重置功能
### 认证授权
- JWT Token 认证
- 基于角色的权限控制
- 安全的密码加密存储
## 📁 项目结构
```
src/main/java/com/gameplatform/server/
├── config/ # 配置类
├── controller/ # 控制器
│ ├── admin/ # 管理员接口
│ └── ... # 其他接口
├── service/ # 业务逻辑
├── mapper/ # 数据访问层
├── model/ # 数据模型
│ ├── dto/ # 数据传输对象
│ └── entity/ # 实体类
└── security/ # 安全相关
```
## 🔐 认证说明
### JWT Token
- 访问令牌有效期30分钟
- 刷新令牌有效期7天
- 支持强制登出功能
### 权限控制
- 管理员接口需要管理员权限
- 用户接口支持公开访问仅限AGENT类型
## 📖 文档
- [API文档](docs/API文档.md) - 详细的API接口说明
- [Swagger使用说明](docs/Swagger使用说明.md) - Swagger文档使用指南
## 🛠️ 开发
### 编译
```bash
mvn compile
```
### 测试
```bash
mvn test
```
### 打包
```bash
mvn package
```
## 📝 更新日志
### v1.0.0
- 初始版本发布
- 基础的用户管理功能
- JWT认证系统
- Swagger API文档集成

171
docs/Swagger使用说明.md Normal file
View File

@@ -0,0 +1,171 @@
# Swagger API 文档使用说明
## 📖 概述
本项目已集成 Swagger/OpenAPI 3.0,提供交互式的 API 文档界面,方便开发者和测试人员查看和测试 API 接口。
## 🚀 访问地址
启动应用后,可以通过以下地址访问 Swagger 文档:
- **Swagger UI 界面**: http://localhost:8080/swagger-ui.html
- **OpenAPI JSON**: http://localhost:8080/api-docs
- **OpenAPI YAML**: http://localhost:8080/api-docs.yaml
## 📋 功能特性
### 1. 交互式文档
- 在线查看所有 API 接口
- 直接在浏览器中测试接口
- 支持请求参数验证
- 实时查看响应结果
### 2. 接口分组
- **管理员账户管理**: `/api/admin/accounts` 相关接口
- **用户账户管理**: `/api/users` 相关接口
### 3. 详细文档
- 接口描述和用途说明
- 请求参数详细说明
- 响应数据结构
- 错误码说明
## 🔧 配置说明
### 配置文件
```yaml
# application.yml
springdoc:
api-docs:
path: /api-docs
swagger-ui:
path: /swagger-ui.html
tags-sorter: alpha
operations-sorter: alpha
doc-expansion: none
disable-swagger-default-url: true
display-request-duration: true
packages-to-scan: com.gameplatform.server.controller
```
### 配置参数说明
- `tags-sorter: alpha`: 按字母顺序排序标签
- `operations-sorter: alpha`: 按字母顺序排序操作
- `doc-expansion: none`: 默认折叠所有接口
- `display-request-duration: true`: 显示请求耗时
## 📝 使用示例
### 1. 查看接口列表
1. 打开 http://localhost:8080/swagger-ui.html
2. 选择对应的接口分组(如"管理员账户管理"
3. 展开需要查看的接口
### 2. 测试接口
1. 点击接口右侧的"Try it out"按钮
2. 填写请求参数
3. 点击"Execute"执行请求
4. 查看响应结果
### 3. 复制接口信息
每个接口都提供了以下信息:
- **cURL 命令**: 可直接复制到终端执行
- **请求 URL**: 完整的请求地址
- **请求头**: 包含认证信息等
- **请求体**: JSON 格式的请求数据
- **响应示例**: 成功和失败的响应示例
## 🔐 认证说明
### Bearer Token 认证
对于需要认证的接口,在 Swagger UI 中:
1. 点击右上角的"Authorize"按钮
2. 在 "Value" 字段中输入 JWT Token
3. 格式:`Bearer your-jwt-token`
4. 点击"Authorize"确认
### 获取 Token
1. 使用登录接口获取 JWT Token
2. 复制响应中的 `accessToken` 字段
3. 在 Swagger UI 中配置认证
## 📊 接口文档结构
### 管理员账户管理接口
```
POST /api/admin/accounts # 创建账户
GET /api/admin/accounts # 获取账户列表
GET /api/admin/accounts/{id} # 获取账户详情
PATCH /api/admin/accounts/{id} # 更新账户
POST /api/admin/accounts/{id}/enable # 启用账户
POST /api/admin/accounts/{id}/disable # 禁用账户
POST /api/admin/accounts/{id}/reset-password # 重置密码
```
### 用户账户管理接口
```
POST /api/users # 创建用户
GET /api/users # 获取用户列表
GET /api/users/{id} # 获取用户详情
PUT /api/users/{id} # 更新用户
POST /api/users/{id}/enable # 启用用户
POST /api/users/{id}/disable # 禁用用户
```
## 🎯 最佳实践
### 1. 开发阶段
- 使用 Swagger UI 快速测试接口
- 验证请求参数和响应格式
- 调试认证和权限问题
### 2. 测试阶段
- 导出 OpenAPI 规范文件
- 使用 Postman 等工具导入接口
- 编写自动化测试用例
### 3. 文档维护
- 及时更新接口描述
- 添加详细的参数说明
- 提供完整的示例数据
## 🔧 自定义配置
### 添加新的接口分组
```java
@Tag(name = "新功能模块", description = "新功能模块的接口说明")
@RestController
@RequestMapping("/api/new-feature")
public class NewFeatureController {
// 接口实现
}
```
### 自定义接口描述
```java
@Operation(summary = "接口标题", description = "详细的接口描述")
@Parameter(description = "参数说明")
public ResponseEntity<?> methodName(@RequestParam String param) {
// 实现逻辑
}
```
## 📚 相关资源
- [OpenAPI 3.0 规范](https://swagger.io/specification/)
- [SpringDoc 官方文档](https://springdoc.org/)
- [Swagger UI 配置选项](https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration/)
## 🆘 常见问题
### Q: 无法访问 Swagger UI
A: 检查应用是否正常启动,确认端口 8080 未被占用
### Q: 接口显示不完整
A: 确认控制器类在 `com.gameplatform.server.controller` 包下
### Q: 认证失败
A: 检查 JWT Token 是否有效,格式是否正确
### Q: 参数验证失败
A: 查看接口文档中的参数要求,确保数据格式正确

View File

@@ -11,7 +11,7 @@
Target Server Version : 80043 (8.0.43)
File Encoding : 65001
Date: 24/08/2025 17:24:44
Date: 24/08/2025 19:08:50
*/
SET NAMES utf8mb4;
@@ -22,21 +22,21 @@ SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
DROP TABLE IF EXISTS `agent_points_tx`;
CREATE TABLE `agent_points_tx` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`account_id` bigint UNSIGNED NOT NULL,
`type` enum('ADD','DEDUCT') CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`before_points` bigint UNSIGNED NOT NULL,
`delta_points` bigint NOT NULL,
`after_points` bigint UNSIGNED NOT NULL,
`reason` enum('create_links','manual','refund_no_rollback','other') CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT 'other',
`ref_id` bigint UNSIGNED NULL DEFAULT NULL,
`operator_id` bigint UNSIGNED NULL DEFAULT NULL,
`created_at` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
PRIMARY KEY (`id`) USING BTREE,
INDEX `idx_apx_account_time`(`account_id` ASC, `created_at` ASC) USING BTREE,
INDEX `fk_apx_operator`(`operator_id` ASC) USING BTREE,
CONSTRAINT `fk_apx_account` FOREIGN KEY (`account_id`) REFERENCES `user_account` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
CONSTRAINT `fk_apx_operator` FOREIGN KEY (`operator_id`) REFERENCES `user_account` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`account_id` bigint UNSIGNED NOT NULL,
`type` enum('ADD','DEDUCT') CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`before_points` bigint UNSIGNED NOT NULL,
`delta_points` bigint NOT NULL,
`after_points` bigint UNSIGNED NOT NULL,
`reason` enum('create_links','manual','refund_no_rollback','other') CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT 'other',
`ref_id` bigint UNSIGNED NULL DEFAULT NULL,
`operator_id` bigint UNSIGNED NULL DEFAULT NULL,
`created_at` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
PRIMARY KEY (`id`) USING BTREE,
INDEX `idx_apx_account_time`(`account_id` ASC, `created_at` ASC) USING BTREE,
INDEX `fk_apx_operator`(`operator_id` ASC) USING BTREE,
CONSTRAINT `fk_apx_account` FOREIGN KEY (`account_id`) REFERENCES `user_account` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
CONSTRAINT `fk_apx_operator` FOREIGN KEY (`operator_id`) REFERENCES `user_account` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-- ----------------------------
@@ -44,14 +44,14 @@ CREATE TABLE `agent_points_tx` (
-- ----------------------------
DROP TABLE IF EXISTS `announcement`;
CREATE TABLE `announcement` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`title` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`content` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`enabled` tinyint(1) NOT NULL DEFAULT 1,
`jump_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`created_at` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
`updated_at` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
PRIMARY KEY (`id`) USING BTREE
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`title` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`content` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`enabled` tinyint(1) NOT NULL DEFAULT 1,
`jump_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`created_at` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
`updated_at` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-- ----------------------------
@@ -59,22 +59,22 @@ CREATE TABLE `announcement` (
-- ----------------------------
DROP TABLE IF EXISTS `link_batch`;
CREATE TABLE `link_batch` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`agent_id` bigint UNSIGNED NOT NULL,
`quantity` int UNSIGNED NOT NULL,
`times` int UNSIGNED NOT NULL,
`batch_size` int UNSIGNED NOT NULL,
`deduct_points` bigint UNSIGNED NOT NULL,
`operator_id` bigint UNSIGNED NULL DEFAULT NULL,
`created_at` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
PRIMARY KEY (`id`) USING BTREE,
INDEX `idx_lb_agent_time`(`agent_id` ASC, `created_at` ASC) USING BTREE,
INDEX `fk_lb_operator`(`operator_id` ASC) USING BTREE,
CONSTRAINT `fk_lb_agent` FOREIGN KEY (`agent_id`) REFERENCES `user_account` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
CONSTRAINT `fk_lb_operator` FOREIGN KEY (`operator_id`) REFERENCES `user_account` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
CONSTRAINT `chk_lb_batch_pos` CHECK (`batch_size` > 0),
CONSTRAINT `chk_lb_quantity_pos` CHECK (`quantity` > 0),
CONSTRAINT `chk_lb_times_pos` CHECK (`times` > 0)
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`agent_id` bigint UNSIGNED NOT NULL,
`quantity` int UNSIGNED NOT NULL,
`times` int UNSIGNED NOT NULL,
`batch_size` int UNSIGNED NOT NULL,
`deduct_points` bigint UNSIGNED NOT NULL,
`operator_id` bigint UNSIGNED NULL DEFAULT NULL,
`created_at` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
PRIMARY KEY (`id`) USING BTREE,
INDEX `idx_lb_agent_time`(`agent_id` ASC, `created_at` ASC) USING BTREE,
INDEX `fk_lb_operator`(`operator_id` ASC) USING BTREE,
CONSTRAINT `fk_lb_agent` FOREIGN KEY (`agent_id`) REFERENCES `user_account` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
CONSTRAINT `fk_lb_operator` FOREIGN KEY (`operator_id`) REFERENCES `user_account` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
CONSTRAINT `chk_lb_batch_pos` CHECK (`batch_size` > 0),
CONSTRAINT `chk_lb_quantity_pos` CHECK (`quantity` > 0),
CONSTRAINT `chk_lb_times_pos` CHECK (`times` > 0)
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-- ----------------------------
@@ -82,29 +82,29 @@ CREATE TABLE `link_batch` (
-- ----------------------------
DROP TABLE IF EXISTS `link_task`;
CREATE TABLE `link_task` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`batch_id` bigint UNSIGNED NOT NULL,
`agent_id` bigint UNSIGNED NOT NULL,
`code_no` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`token_hash` char(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`expire_at` datetime(3) NOT NULL,
`status` enum('NEW','USING','LOGGED_IN','REFUNDED','EXPIRED') CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT 'NEW',
`region` enum('Q','V') CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`machine_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`login_at` datetime(3) NULL DEFAULT NULL,
`refund_at` datetime(3) NULL DEFAULT NULL,
`revoked_at` datetime(3) NULL DEFAULT NULL,
`created_at` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
`updated_at` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `uk_code_no`(`code_no` ASC) USING BTREE,
UNIQUE INDEX `uk_token_hash`(`token_hash` ASC) USING BTREE,
INDEX `idx_agent_status`(`agent_id` ASC, `status` ASC) USING BTREE,
INDEX `idx_expire_at`(`expire_at` ASC) USING BTREE,
INDEX `idx_created_at`(`created_at` ASC) USING BTREE,
INDEX `fk_lt_batch`(`batch_id` ASC) USING BTREE,
CONSTRAINT `fk_lt_agent` FOREIGN KEY (`agent_id`) REFERENCES `user_account` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
CONSTRAINT `fk_lt_batch` FOREIGN KEY (`batch_id`) REFERENCES `link_batch` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`batch_id` bigint UNSIGNED NOT NULL,
`agent_id` bigint UNSIGNED NOT NULL,
`code_no` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`token_hash` char(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`expire_at` datetime(3) NOT NULL,
`status` enum('NEW','USING','LOGGED_IN','REFUNDED','EXPIRED') CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT 'NEW',
`region` enum('Q','V') CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`machine_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`login_at` datetime(3) NULL DEFAULT NULL,
`refund_at` datetime(3) NULL DEFAULT NULL,
`revoked_at` datetime(3) NULL DEFAULT NULL,
`created_at` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
`updated_at` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `uk_code_no`(`code_no` ASC) USING BTREE,
UNIQUE INDEX `uk_token_hash`(`token_hash` ASC) USING BTREE,
INDEX `idx_agent_status`(`agent_id` ASC, `status` ASC) USING BTREE,
INDEX `idx_expire_at`(`expire_at` ASC) USING BTREE,
INDEX `idx_created_at`(`created_at` ASC) USING BTREE,
INDEX `fk_lt_batch`(`batch_id` ASC) USING BTREE,
CONSTRAINT `fk_lt_agent` FOREIGN KEY (`agent_id`) REFERENCES `user_account` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
CONSTRAINT `fk_lt_batch` FOREIGN KEY (`batch_id`) REFERENCES `link_batch` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-- ----------------------------
@@ -112,18 +112,18 @@ CREATE TABLE `link_task` (
-- ----------------------------
DROP TABLE IF EXISTS `operation_log`;
CREATE TABLE `operation_log` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`actor_type` enum('admin','agent','system','user') CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`actor_id` bigint UNSIGNED NULL DEFAULT NULL,
`code_no` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`op` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`detail` json NULL,
`client_ip` varchar(45) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`user_agent` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`created_at` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
PRIMARY KEY (`id`) USING BTREE,
INDEX `idx_log_code_time`(`code_no` ASC, `created_at` ASC) USING BTREE,
INDEX `idx_log_time`(`created_at` ASC) USING BTREE
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`actor_type` enum('admin','agent','system','user') CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`actor_id` bigint UNSIGNED NULL DEFAULT NULL,
`code_no` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`op` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`detail` json NULL,
`client_ip` varchar(45) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`user_agent` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`created_at` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
PRIMARY KEY (`id`) USING BTREE,
INDEX `idx_log_code_time`(`code_no` ASC, `created_at` ASC) USING BTREE,
INDEX `idx_log_time`(`created_at` ASC) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-- ----------------------------
@@ -131,19 +131,17 @@ CREATE TABLE `operation_log` (
-- ----------------------------
DROP TABLE IF EXISTS `user_account`;
CREATE TABLE `user_account` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`user_type` enum('ADMIN','AGENT') CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`username` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`display_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`password_hash` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`role` enum('SUPER','ADMIN') CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`status` enum('ENABLED','DISABLED') CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT 'ENABLED',
`points_balance` bigint UNSIGNED NOT NULL DEFAULT 0,
`created_at` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
`updated_at` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `username`(`username` ASC) USING BTREE,
CONSTRAINT `chk_points_nonneg` CHECK (`points_balance` >= 0)
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`user_type` enum('ADMIN','AGENT') CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`username` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`password_hash` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`status` enum('ENABLED','DISABLED') CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT 'ENABLED',
`points_balance` bigint UNSIGNED NOT NULL DEFAULT 0,
`created_at` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
`updated_at` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `username`(`username` ASC) USING BTREE,
CONSTRAINT `chk_points_nonneg` CHECK (`points_balance` >= 0)
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
SET FOREIGN_KEY_CHECKS = 1;

View File

@@ -85,6 +85,13 @@
<optional>true</optional>
</dependency>
<!-- Swagger/OpenAPI Documentation -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webflux-ui</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>

View File

@@ -0,0 +1,39 @@
package com.gameplatform.server.config;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Contact;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.info.License;
import io.swagger.v3.oas.models.servers.Server;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.List;
@Configuration
public class SwaggerConfig {
@Bean
public OpenAPI customOpenAPI() {
return new OpenAPI()
.info(new Info()
.title("游戏平台 API 文档")
.description("游戏平台后端服务 API 接口文档")
.version("1.0.0")
.contact(new Contact()
.name("游戏平台开发团队")
.email("dev@gameplatform.com")
.url("https://gameplatform.com"))
.license(new License()
.name("MIT License")
.url("https://opensource.org/licenses/MIT")))
.servers(List.of(
new Server()
.url("http://localhost:8080")
.description("本地开发环境"),
new Server()
.url("https://api.gameplatform.com")
.description("生产环境")
));
}
}

View File

@@ -5,6 +5,9 @@ import com.gameplatform.server.model.dto.account.AccountResponse;
import com.gameplatform.server.model.dto.account.AccountUpdateRequest;
import com.gameplatform.server.model.dto.common.PageResult;
import com.gameplatform.server.service.account.AccountService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
@@ -16,6 +19,7 @@ import reactor.core.publisher.Mono;
*/
@RestController
@RequestMapping("/api/users")
@Tag(name = "用户账户管理", description = "用户账户的增删改查操作")
public class UserController {
private final AccountService accountService;
@@ -27,7 +31,8 @@ public class UserController {
* 根据ID获取用户账户信息
*/
@GetMapping("/{id}")
public Mono<AccountResponse> getById(@PathVariable Long id) {
@Operation(summary = "获取用户详情", description = "根据用户ID获取用户详细信息")
public Mono<AccountResponse> getById(@Parameter(description = "用户ID") @PathVariable Long id) {
return accountService.get(id);
}
@@ -35,15 +40,15 @@ public class UserController {
* 分页查询用户列表
*/
@GetMapping
@Operation(summary = "获取用户列表", description = "分页获取用户列表,支持按用户类型、状态、关键词筛选")
public Mono<PageResult<AccountResponse>> list(
@RequestParam(value = "userType", required = false) String userType,
@RequestParam(value = "status", required = false) String status,
@RequestParam(value = "role", required = false) String role,
@RequestParam(value = "keyword", required = false) String keyword,
@RequestParam(value = "page", defaultValue = "1") Integer page,
@RequestParam(value = "size", defaultValue = "20") Integer size
@Parameter(description = "用户类型ADMIN 或 AGENT") @RequestParam(value = "userType", required = false) String userType,
@Parameter(description = "账户状态ENABLED 或 DISABLED") @RequestParam(value = "status", required = false) String status,
@Parameter(description = "搜索关键词") @RequestParam(value = "keyword", required = false) String keyword,
@Parameter(description = "页码默认1") @RequestParam(value = "page", defaultValue = "1") Integer page,
@Parameter(description = "每页大小默认20") @RequestParam(value = "size", defaultValue = "20") Integer size
) {
return accountService.list(userType, status, role, keyword, page, size);
return accountService.list(userType, status, keyword, page, size);
}
/**
@@ -51,6 +56,7 @@ public class UserController {
*/
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
@Operation(summary = "创建用户", description = "创建新的代理用户账户")
public Mono<AccountResponse> create(@Valid @RequestBody AccountCreateRequest request) {
return accountService.create(request);
}
@@ -59,7 +65,8 @@ public class UserController {
* 更新用户账户信息
*/
@PutMapping("/{id}")
public Mono<AccountResponse> update(@PathVariable Long id, @Valid @RequestBody AccountUpdateRequest request) {
@Operation(summary = "更新用户", description = "更新用户账户信息")
public Mono<AccountResponse> update(@Parameter(description = "用户ID") @PathVariable Long id, @Valid @RequestBody AccountUpdateRequest request) {
return accountService.update(id, request);
}
@@ -68,7 +75,8 @@ public class UserController {
*/
@PostMapping("/{id}/enable")
@ResponseStatus(HttpStatus.NO_CONTENT)
public Mono<Void> enable(@PathVariable Long id) {
@Operation(summary = "启用用户", description = "启用指定用户账户")
public Mono<Void> enable(@Parameter(description = "用户ID") @PathVariable Long id) {
return accountService.setStatus(id, "ENABLED").then();
}
@@ -77,7 +85,8 @@ public class UserController {
*/
@PostMapping("/{id}/disable")
@ResponseStatus(HttpStatus.NO_CONTENT)
public Mono<Void> disable(@PathVariable Long id) {
@Operation(summary = "禁用用户", description = "禁用指定用户账户")
public Mono<Void> disable(@Parameter(description = "用户ID") @PathVariable Long id) {
return accountService.setStatus(id, "DISABLED").then();
}
}

View File

@@ -3,6 +3,9 @@ package com.gameplatform.server.controller.admin;
import com.gameplatform.server.model.dto.account.*;
import com.gameplatform.server.model.dto.common.PageResult;
import com.gameplatform.server.service.account.AccountService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
@@ -10,6 +13,7 @@ import reactor.core.publisher.Mono;
@RestController
@RequestMapping("/api/admin/accounts")
@Tag(name = "管理员账户管理", description = "管理员账户的增删改查操作")
public class AccountController {
private final AccountService accountService;
@@ -18,48 +22,54 @@ public class AccountController {
}
@GetMapping
@Operation(summary = "获取账户列表", description = "分页获取账户列表,支持按用户类型、状态、关键词筛选")
public Mono<PageResult<AccountResponse>> list(
@RequestParam(value = "userType", required = false) String userType,
@RequestParam(value = "status", required = false) String status,
@RequestParam(value = "role", required = false) String role,
@RequestParam(value = "keyword", required = false) String keyword,
@RequestParam(value = "page", required = false) Integer page,
@RequestParam(value = "size", required = false) Integer size
@Parameter(description = "用户类型ADMIN 或 AGENT") @RequestParam(value = "userType", required = false) String userType,
@Parameter(description = "账户状态ENABLED 或 DISABLED") @RequestParam(value = "status", required = false) String status,
@Parameter(description = "搜索关键词") @RequestParam(value = "keyword", required = false) String keyword,
@Parameter(description = "页码默认1") @RequestParam(value = "page", required = false) Integer page,
@Parameter(description = "每页大小默认20最大200") @RequestParam(value = "size", required = false) Integer size
) {
return accountService.list(userType, status, role, keyword, page, size);
return accountService.list(userType, status, keyword, page, size);
}
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
@Operation(summary = "创建账户", description = "创建新的管理员或代理账户")
public Mono<AccountResponse> create(@Valid @RequestBody AccountCreateRequest req) {
return accountService.create(req);
}
@GetMapping("/{id}")
public Mono<AccountResponse> detail(@PathVariable Long id) {
@Operation(summary = "获取账户详情", description = "根据账户ID获取账户详细信息")
public Mono<AccountResponse> detail(@Parameter(description = "账户ID") @PathVariable Long id) {
return accountService.get(id);
}
@PatchMapping("/{id}")
public Mono<AccountResponse> update(@PathVariable Long id, @Valid @RequestBody AccountUpdateRequest req) {
@Operation(summary = "更新账户", description = "更新账户信息")
public Mono<AccountResponse> update(@Parameter(description = "账户ID") @PathVariable Long id, @Valid @RequestBody AccountUpdateRequest req) {
return accountService.update(id, req);
}
@PostMapping("/{id}/enable")
@ResponseStatus(HttpStatus.NO_CONTENT)
public Mono<Void> enable(@PathVariable Long id) {
@Operation(summary = "启用账户", description = "启用指定账户")
public Mono<Void> enable(@Parameter(description = "账户ID") @PathVariable Long id) {
return accountService.setStatus(id, "ENABLED").then();
}
@PostMapping("/{id}/disable")
@ResponseStatus(HttpStatus.NO_CONTENT)
public Mono<Void> disable(@PathVariable Long id) {
@Operation(summary = "禁用账户", description = "禁用指定账户")
public Mono<Void> disable(@Parameter(description = "账户ID") @PathVariable Long id) {
return accountService.setStatus(id, "DISABLED").then();
}
@PostMapping("/{id}/reset-password")
@ResponseStatus(HttpStatus.NO_CONTENT)
public Mono<Void> resetPassword(@PathVariable Long id, @Valid @RequestBody ResetPasswordRequest req) {
@Operation(summary = "重置密码", description = "重置指定账户的密码")
public Mono<Void> resetPassword(@Parameter(description = "账户ID") @PathVariable Long id, @Valid @RequestBody ResetPasswordRequest req) {
return accountService.resetPassword(id, req.getNewPassword(), Boolean.TRUE.equals(req.getForceLogout()));
}
}

View File

@@ -15,12 +15,10 @@ public interface UserAccountMapper {
long countByFilter(@Param("userType") String userType,
@Param("status") String status,
@Param("role") String role,
@Param("keyword") String keyword);
java.util.List<UserAccount> listByFilter(@Param("userType") String userType,
@Param("status") String status,
@Param("role") String role,
@Param("keyword") String keyword,
@Param("size") int size,
@Param("offset") int offset);

View File

@@ -0,0 +1,29 @@
package com.gameplatform.server.mapper.admin;
import com.gameplatform.server.model.entity.admin.Announcement;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface AnnouncementMapper {
Announcement findById(@Param("id") Long id);
int insert(Announcement announcement);
int update(Announcement announcement);
int deleteById(@Param("id") Long id);
List<Announcement> findAll(@Param("size") int size,
@Param("offset") int offset);
long countAll();
List<Announcement> findByEnabled(@Param("enabled") Boolean enabled,
@Param("size") int size,
@Param("offset") int offset);
long countByEnabled(@Param("enabled") Boolean enabled);
int updateEnabled(@Param("id") Long id, @Param("enabled") Boolean enabled);
}

View File

@@ -0,0 +1,35 @@
package com.gameplatform.server.mapper.admin;
import com.gameplatform.server.model.entity.admin.OperationLog;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface OperationLogMapper {
OperationLog findById(@Param("id") Long id);
int insert(OperationLog operationLog);
List<OperationLog> findByCodeNo(@Param("codeNo") String codeNo,
@Param("size") int size,
@Param("offset") int offset);
long countByCodeNo(@Param("codeNo") String codeNo);
List<OperationLog> findByActorId(@Param("actorId") Long actorId,
@Param("size") int size,
@Param("offset") int offset);
long countByActorId(@Param("actorId") Long actorId);
List<OperationLog> findByActorType(@Param("actorType") String actorType,
@Param("size") int size,
@Param("offset") int offset);
long countByActorType(@Param("actorType") String actorType);
List<OperationLog> findAll(@Param("size") int size,
@Param("offset") int offset);
long countAll();
}

View File

@@ -0,0 +1,26 @@
package com.gameplatform.server.mapper.agent;
import com.gameplatform.server.model.entity.agent.AgentPointsTx;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface AgentPointsTxMapper {
AgentPointsTx findById(@Param("id") Long id);
int insert(AgentPointsTx agentPointsTx);
List<AgentPointsTx> findByAccountId(@Param("accountId") Long accountId,
@Param("size") int size,
@Param("offset") int offset);
long countByAccountId(@Param("accountId") Long accountId);
List<AgentPointsTx> findByAccountIdAndType(@Param("accountId") Long accountId,
@Param("type") String type,
@Param("size") int size,
@Param("offset") int offset);
long countByAccountIdAndType(@Param("accountId") Long accountId,
@Param("type") String type);
}

View File

@@ -0,0 +1,23 @@
package com.gameplatform.server.mapper.agent;
import com.gameplatform.server.model.entity.agent.LinkBatch;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface LinkBatchMapper {
LinkBatch findById(@Param("id") Long id);
int insert(LinkBatch linkBatch);
List<LinkBatch> findByAgentId(@Param("agentId") Long agentId,
@Param("size") int size,
@Param("offset") int offset);
long countByAgentId(@Param("agentId") Long agentId);
List<LinkBatch> findAll(@Param("size") int size,
@Param("offset") int offset);
long countAll();
}

View File

@@ -0,0 +1,50 @@
package com.gameplatform.server.mapper.agent;
import com.gameplatform.server.model.entity.agent.LinkTask;
import org.apache.ibatis.annotations.Param;
import java.time.LocalDateTime;
import java.util.List;
public interface LinkTaskMapper {
LinkTask findById(@Param("id") Long id);
LinkTask findByCodeNo(@Param("codeNo") String codeNo);
LinkTask findByTokenHash(@Param("tokenHash") String tokenHash);
int insert(LinkTask linkTask);
int update(LinkTask linkTask);
int updateStatus(@Param("id") Long id, @Param("status") String status);
int updateStatusAndMachine(@Param("id") Long id,
@Param("status") String status,
@Param("region") String region,
@Param("machineId") String machineId,
@Param("loginAt") LocalDateTime loginAt);
List<LinkTask> findByAgentId(@Param("agentId") Long agentId,
@Param("size") int size,
@Param("offset") int offset);
long countByAgentId(@Param("agentId") Long agentId);
List<LinkTask> findByAgentIdAndStatus(@Param("agentId") Long agentId,
@Param("status") String status,
@Param("size") int size,
@Param("offset") int offset);
long countByAgentIdAndStatus(@Param("agentId") Long agentId,
@Param("status") String status);
List<LinkTask> findByBatchId(@Param("batchId") Long batchId,
@Param("size") int size,
@Param("offset") int offset);
long countByBatchId(@Param("batchId") Long batchId);
List<LinkTask> findExpiredTasks(@Param("expireTime") LocalDateTime expireTime,
@Param("size") int size);
}

View File

@@ -1,20 +1,32 @@
package com.gameplatform.server.model.dto.account;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.*;
@Schema(description = "账户创建请求")
public class AccountCreateRequest {
@NotBlank
@Schema(description = "用户类型", example = "AGENT", allowableValues = {"ADMIN", "AGENT"})
@NotBlank(message = "userType 不能为空")
@Pattern(regexp = "^(ADMIN|AGENT)$", message = "userType 只能是 ADMIN 或 AGENT")
private String userType; // ADMIN | AGENT
@NotBlank
@Size(min = 3, max = 64)
@Schema(description = "用户名", example = "newuser", minLength = 3, maxLength = 64)
@NotBlank(message = "username 不能为空")
@Size(min = 3, max = 64, message = "username 长度必须在 3-64 字符之间")
@Pattern(regexp = "^[a-zA-Z0-9_]+$", message = "username 只能包含字母、数字、下划线")
private String username;
private String status = "ENABLED"; // ENABLED | DISABLED
@NotBlank
@Size(min = 6, max = 128)
@Schema(description = "密码", example = "123456", minLength = 6, maxLength = 128)
@NotBlank(message = "password 不能为空")
@Size(min = 6, max = 128, message = "password 长度必须在 6-128 字符之间")
private String password;
@Schema(description = "账户状态", example = "ENABLED", allowableValues = {"ENABLED", "DISABLED"}, defaultValue = "ENABLED")
private String status;
@Schema(description = "积分余额", example = "1000", minimum = "0", defaultValue = "0")
@Min(0)
private Long pointsBalance = 0L; // for AGENT
private Long pointsBalance; // for AGENT
public String getUserType() { return userType; }
public void setUserType(String userType) { this.userType = userType; }

View File

@@ -1,15 +1,30 @@
package com.gameplatform.server.model.dto.account;
import io.swagger.v3.oas.annotations.media.Schema;
import java.time.LocalDateTime;
@Schema(description = "账户响应")
public class AccountResponse {
@Schema(description = "账户ID", example = "1")
private Long id;
@Schema(description = "用户类型", example = "AGENT", allowableValues = {"ADMIN", "AGENT"})
private String userType;
@Schema(description = "用户名", example = "newuser")
private String username;
@Schema(description = "账户状态", example = "ENABLED", allowableValues = {"ENABLED", "DISABLED"})
private String status;
@Schema(description = "积分余额", example = "1000")
private Long pointsBalance;
@Schema(description = "创建时间", example = "2025-08-24T18:30:00.000")
private LocalDateTime createdAt;
@Schema(description = "更新时间", example = "2025-08-24T18:30:00.000")
private LocalDateTime updatedAt;
public Long getId() { return id; }

View File

@@ -1,10 +1,13 @@
package com.gameplatform.server.model.dto.account;
import jakarta.validation.constraints.Size;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.Pattern;
@Schema(description = "账户更新请求")
public class AccountUpdateRequest {
private String status; // ENABLED | DISABLED
@Schema(description = "账户状态", example = "ENABLED", allowableValues = {"ENABLED", "DISABLED"})
@Pattern(regexp = "^(ENABLED|DISABLED)$", message = "status 只能是 ENABLED DISABLED")
private String status;
public String getStatus() { return status; }

View File

@@ -1,12 +1,17 @@
package com.gameplatform.server.model.dto.account;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
@Schema(description = "重置密码请求")
public class ResetPasswordRequest {
@NotBlank
@Size(min = 6, max = 128)
@Schema(description = "新密码", example = "NewPassword123!", minLength = 6, maxLength = 128)
@NotBlank(message = "newPassword 不能为空")
@Size(min = 6, max = 128, message = "newPassword 长度必须在 6-128 字符之间")
private String newPassword;
@Schema(description = "是否强制登出", example = "true", defaultValue = "true")
private Boolean forceLogout = Boolean.TRUE;
public String getNewPassword() { return newPassword; }

View File

@@ -6,9 +6,7 @@ public class UserAccount {
private Long id;
private String userType; // ADMIN | AGENT
private String username; // 登录名admin/agent 共用)
private String passwordHash; // BCrypt 或 PLAIN:xxx初始化用
private String status; // ENABLED / DISABLED
private Long pointsBalance; // 仅 AGENT 使用
private LocalDateTime createdAt;
@@ -20,10 +18,8 @@ public class UserAccount {
public void setUserType(String userType) { this.userType = userType; }
public String getUsername() { return username; }
public void setUsername(String username) { this.username = username; }
public String getPasswordHash() { return passwordHash; }
public void setPasswordHash(String passwordHash) { this.passwordHash = passwordHash; }
public String getStatus() { return status; }
public void setStatus(String status) { this.status = status; }
public Long getPointsBalance() { return pointsBalance; }

View File

@@ -0,0 +1,34 @@
package com.gameplatform.server.model.entity.admin;
import java.time.LocalDateTime;
public class Announcement {
private Long id;
private String title;
private String content;
private Boolean enabled;
private String jumpUrl;
private LocalDateTime createdAt;
private LocalDateTime updatedAt;
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getTitle() { return title; }
public void setTitle(String title) { this.title = title; }
public String getContent() { return content; }
public void setContent(String content) { this.content = content; }
public Boolean getEnabled() { return enabled; }
public void setEnabled(Boolean enabled) { this.enabled = enabled; }
public String getJumpUrl() { return jumpUrl; }
public void setJumpUrl(String jumpUrl) { this.jumpUrl = jumpUrl; }
public LocalDateTime getCreatedAt() { return createdAt; }
public void setCreatedAt(LocalDateTime createdAt) { this.createdAt = createdAt; }
public LocalDateTime getUpdatedAt() { return updatedAt; }
public void setUpdatedAt(LocalDateTime updatedAt) { this.updatedAt = updatedAt; }
}

View File

@@ -0,0 +1,42 @@
package com.gameplatform.server.model.entity.admin;
import java.time.LocalDateTime;
public class OperationLog {
private Long id;
private String actorType; // admin | agent | system | user
private Long actorId;
private String codeNo;
private String op;
private String detail; // JSON字符串
private String clientIp;
private String userAgent;
private LocalDateTime createdAt;
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getActorType() { return actorType; }
public void setActorType(String actorType) { this.actorType = actorType; }
public Long getActorId() { return actorId; }
public void setActorId(Long actorId) { this.actorId = actorId; }
public String getCodeNo() { return codeNo; }
public void setCodeNo(String codeNo) { this.codeNo = codeNo; }
public String getOp() { return op; }
public void setOp(String op) { this.op = op; }
public String getDetail() { return detail; }
public void setDetail(String detail) { this.detail = detail; }
public String getClientIp() { return clientIp; }
public void setClientIp(String clientIp) { this.clientIp = clientIp; }
public String getUserAgent() { return userAgent; }
public void setUserAgent(String userAgent) { this.userAgent = userAgent; }
public LocalDateTime getCreatedAt() { return createdAt; }
public void setCreatedAt(LocalDateTime createdAt) { this.createdAt = createdAt; }
}

View File

@@ -0,0 +1,46 @@
package com.gameplatform.server.model.entity.agent;
import java.time.LocalDateTime;
public class AgentPointsTx {
private Long id;
private Long accountId;
private String type; // ADD | DEDUCT
private Long beforePoints;
private Long deltaPoints;
private Long afterPoints;
private String reason; // create_links | manual | refund_no_rollback | other
private Long refId;
private Long operatorId;
private LocalDateTime createdAt;
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public Long getAccountId() { return accountId; }
public void setAccountId(Long accountId) { this.accountId = accountId; }
public String getType() { return type; }
public void setType(String type) { this.type = type; }
public Long getBeforePoints() { return beforePoints; }
public void setBeforePoints(Long beforePoints) { this.beforePoints = beforePoints; }
public Long getDeltaPoints() { return deltaPoints; }
public void setDeltaPoints(Long deltaPoints) { this.deltaPoints = deltaPoints; }
public Long getAfterPoints() { return afterPoints; }
public void setAfterPoints(Long afterPoints) { this.afterPoints = afterPoints; }
public String getReason() { return reason; }
public void setReason(String reason) { this.reason = reason; }
public Long getRefId() { return refId; }
public void setRefId(Long refId) { this.refId = refId; }
public Long getOperatorId() { return operatorId; }
public void setOperatorId(Long operatorId) { this.operatorId = operatorId; }
public LocalDateTime getCreatedAt() { return createdAt; }
public void setCreatedAt(LocalDateTime createdAt) { this.createdAt = createdAt; }
}

View File

@@ -0,0 +1,38 @@
package com.gameplatform.server.model.entity.agent;
import java.time.LocalDateTime;
public class LinkBatch {
private Long id;
private Long agentId;
private Integer quantity;
private Integer times;
private Integer batchSize;
private Long deductPoints;
private Long operatorId;
private LocalDateTime createdAt;
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public Long getAgentId() { return agentId; }
public void setAgentId(Long agentId) { this.agentId = agentId; }
public Integer getQuantity() { return quantity; }
public void setQuantity(Integer quantity) { this.quantity = quantity; }
public Integer getTimes() { return times; }
public void setTimes(Integer times) { this.times = times; }
public Integer getBatchSize() { return batchSize; }
public void setBatchSize(Integer batchSize) { this.batchSize = batchSize; }
public Long getDeductPoints() { return deductPoints; }
public void setDeductPoints(Long deductPoints) { this.deductPoints = deductPoints; }
public Long getOperatorId() { return operatorId; }
public void setOperatorId(Long operatorId) { this.operatorId = operatorId; }
public LocalDateTime getCreatedAt() { return createdAt; }
public void setCreatedAt(LocalDateTime createdAt) { this.createdAt = createdAt; }
}

View File

@@ -0,0 +1,62 @@
package com.gameplatform.server.model.entity.agent;
import java.time.LocalDateTime;
public class LinkTask {
private Long id;
private Long batchId;
private Long agentId;
private String codeNo;
private String tokenHash;
private LocalDateTime expireAt;
private String status; // NEW | USING | LOGGED_IN | REFUNDED | EXPIRED
private String region; // Q | V
private String machineId;
private LocalDateTime loginAt;
private LocalDateTime refundAt;
private LocalDateTime revokedAt;
private LocalDateTime createdAt;
private LocalDateTime updatedAt;
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public Long getBatchId() { return batchId; }
public void setBatchId(Long batchId) { this.batchId = batchId; }
public Long getAgentId() { return agentId; }
public void setAgentId(Long agentId) { this.agentId = agentId; }
public String getCodeNo() { return codeNo; }
public void setCodeNo(String codeNo) { this.codeNo = codeNo; }
public String getTokenHash() { return tokenHash; }
public void setTokenHash(String tokenHash) { this.tokenHash = tokenHash; }
public LocalDateTime getExpireAt() { return expireAt; }
public void setExpireAt(LocalDateTime expireAt) { this.expireAt = expireAt; }
public String getStatus() { return status; }
public void setStatus(String status) { this.status = status; }
public String getRegion() { return region; }
public void setRegion(String region) { this.region = region; }
public String getMachineId() { return machineId; }
public void setMachineId(String machineId) { this.machineId = machineId; }
public LocalDateTime getLoginAt() { return loginAt; }
public void setLoginAt(LocalDateTime loginAt) { this.loginAt = loginAt; }
public LocalDateTime getRefundAt() { return refundAt; }
public void setRefundAt(LocalDateTime refundAt) { this.refundAt = refundAt; }
public LocalDateTime getRevokedAt() { return revokedAt; }
public void setRevokedAt(LocalDateTime revokedAt) { this.revokedAt = revokedAt; }
public LocalDateTime getCreatedAt() { return createdAt; }
public void setCreatedAt(LocalDateTime createdAt) { this.createdAt = createdAt; }
public LocalDateTime getUpdatedAt() { return updatedAt; }
public void setUpdatedAt(LocalDateTime updatedAt) { this.updatedAt = updatedAt; }
}

View File

@@ -46,15 +46,15 @@ public class UserService {
/**
* 分页查询用户列表
*/
public Mono<PageResult<AccountResponse>> list(String userType, String status, String role, String keyword,
public Mono<PageResult<AccountResponse>> list(String userType, String status, String keyword,
Integer page, Integer size) {
int p = (page == null || page < 1) ? 1 : page;
int s = (size == null || size < 1 || size > 200) ? 20 : size;
int offset = (p - 1) * s;
return Mono.fromCallable(() -> {
long total = userAccountMapper.countByFilter(userType, status, role, keyword);
List<UserAccount> list = userAccountMapper.listByFilter(userType, status, role, keyword, s, offset);
long total = userAccountMapper.countByFilter(userType, status, keyword);
List<UserAccount> list = userAccountMapper.listByFilter(userType, status, keyword, s, offset);
List<AccountResponse> items = list.stream()
.map(this::toAccountResponse)
.collect(Collectors.toList());
@@ -81,8 +81,6 @@ public class UserService {
response.setId(account.getId());
response.setUserType(account.getUserType());
response.setUsername(account.getUsername());
response.setDisplayName(account.getDisplayName());
response.setRole(account.getRole());
response.setStatus(account.getStatus());
response.setPointsBalance(account.getPointsBalance());
response.setCreatedAt(account.getCreatedAt());

View File

@@ -31,8 +31,8 @@ public class AccountService {
int s = (size == null || size < 1 || size > 200) ? 20 : size;
int offset = (p - 1) * s;
return Mono.fromCallable(() -> {
long total = mapper.countByFilter(userType, status, null, keyword);
List<UserAccount> list = mapper.listByFilter(userType, status, null, keyword, s, offset);
long total = mapper.countByFilter(userType, status, keyword);
List<UserAccount> list = mapper.listByFilter(userType, status, keyword, s, offset);
List<AccountResponse> items = list.stream().map(this::toResp).collect(Collectors.toList());
return new PageResult<>(items, total, p, s);
})

View File

@@ -38,7 +38,7 @@ public class AuthService {
if (acc == null) {
log.warn("login account not found username={}", req.getUsername());
} else {
log.debug("login account loaded id={}, status={}, role={} userType={}", acc.getId(), acc.getStatus(), acc.getRole(), acc.getUserType());
log.debug("login account loaded id={}, status={}, userType={}", acc.getId(), acc.getStatus(), acc.getUserType());
}
})
.flatMap(acc -> validatePasswordAndBuild(acc, req.getPassword()))
@@ -73,7 +73,7 @@ public class AuthService {
String token = jwtService.generateToken(
userType + ":" + acc.getId(),
userType, acc.getId(), acc.getUsername(),
"admin".equals(userType) ? Map.of("role", acc.getRole()) : Map.of("displayName", acc.getDisplayName())
Map.of()
);
LoginResponse resp = new LoginResponse();
resp.setAccessToken(token);

View File

@@ -40,3 +40,16 @@ security:
secret: "change-this-secret-to-a-long-random-string-please"
access-token-minutes: 30
refresh-token-days: 7
# Swagger/OpenAPI 配置
springdoc:
api-docs:
path: /api-docs
swagger-ui:
path: /swagger-ui.html
tags-sorter: alpha
operations-sorter: alpha
doc-expansion: none
disable-swagger-default-url: true
display-request-duration: true
packages-to-scan: com.gameplatform.server.controller

View File

@@ -5,9 +5,7 @@
<id property="id" column="id" />
<result property="userType" column="user_type" />
<result property="username" column="username" />
<result property="displayName" column="display_name" />
<result property="passwordHash" column="password_hash" />
<result property="role" column="role" />
<result property="status" column="status" />
<result property="pointsBalance" column="points_balance" />
<result property="createdAt" column="created_at" />
@@ -15,7 +13,7 @@
</resultMap>
<select id="findByUsernameAndType" resultMap="UserAccountMap">
SELECT id, user_type, username, display_name, password_hash, role, status, points_balance, created_at, updated_at
SELECT id, user_type, username, password_hash, status, points_balance, created_at, updated_at
FROM user_account
WHERE username = #{username}
AND user_type = #{userType}
@@ -23,30 +21,29 @@
</select>
<select id="findByUsername" resultMap="UserAccountMap">
SELECT id, user_type, username, display_name, password_hash, role, status, points_balance, created_at, updated_at
SELECT id, user_type, username, password_hash, status, points_balance, created_at, updated_at
FROM user_account
WHERE username = #{username}
LIMIT 1
</select>
<select id="findById" parameterType="long" resultMap="UserAccountMap">
SELECT id, user_type, username, display_name, password_hash, role, status, points_balance, created_at, updated_at
SELECT id, user_type, username, password_hash, status, points_balance, created_at, updated_at
FROM user_account
WHERE id = #{id}
LIMIT 1
</select>
<insert id="insert" parameterType="com.gameplatform.server.model.entity.account.UserAccount" useGeneratedKeys="true" keyProperty="id">
INSERT INTO user_account (user_type, username, display_name, password_hash, role, status, points_balance)
VALUES (#{userType}, #{username}, #{displayName}, #{passwordHash}, #{role}, #{status}, #{pointsBalance})
INSERT INTO user_account (user_type, username, password_hash, status, points_balance)
VALUES (#{userType}, #{username}, #{passwordHash}, #{status}, #{pointsBalance})
</insert>
<update id="update" parameterType="com.gameplatform.server.model.entity.account.UserAccount">
UPDATE user_account
<set>
<if test="displayName != null">display_name = #{displayName},</if>
<if test="role != null">role = #{role},</if>
<if test="status != null">status = #{status},</if>
<if test="pointsBalance != null">points_balance = #{pointsBalance},</if>
</set>
WHERE id = #{id}
</update>
@@ -64,22 +61,20 @@
<where>
<if test="userType != null and userType != ''">AND user_type = #{userType}</if>
<if test="status != null and status != ''">AND status = #{status}</if>
<if test="role != null and role != ''">AND role = #{role}</if>
<if test="keyword != null and keyword != ''">
AND (username LIKE CONCAT('%', #{keyword}, '%') OR display_name LIKE CONCAT('%', #{keyword}, '%'))
AND username LIKE CONCAT('%', #{keyword}, '%')
</if>
</where>
</select>
<select id="listByFilter" resultMap="UserAccountMap">
SELECT id, user_type, username, display_name, password_hash, role, status, points_balance, created_at, updated_at
SELECT id, user_type, username, password_hash, status, points_balance, created_at, updated_at
FROM user_account
<where>
<if test="userType != null and userType != ''">AND user_type = #{userType}</if>
<if test="status != null and status != ''">AND status = #{status}</if>
<if test="role != null and role != ''">AND role = #{role}</if>
<if test="keyword != null and keyword != ''">
AND (username LIKE CONCAT('%', #{keyword}, '%') OR display_name LIKE CONCAT('%', #{keyword}, '%'))
AND username LIKE CONCAT('%', #{keyword}, '%')
</if>
</where>
ORDER BY id DESC

View File

@@ -0,0 +1,67 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.gameplatform.server.mapper.admin.AnnouncementMapper">
<resultMap id="AnnouncementMap" type="com.gameplatform.server.model.entity.admin.Announcement">
<id property="id" column="id" />
<result property="title" column="title" />
<result property="content" column="content" />
<result property="enabled" column="enabled" />
<result property="jumpUrl" column="jump_url" />
<result property="createdAt" column="created_at" />
<result property="updatedAt" column="updated_at" />
</resultMap>
<select id="findById" parameterType="long" resultMap="AnnouncementMap">
SELECT id, title, content, enabled, jump_url, created_at, updated_at
FROM announcement
WHERE id = #{id}
LIMIT 1
</select>
<insert id="insert" parameterType="com.gameplatform.server.model.entity.admin.Announcement" useGeneratedKeys="true" keyProperty="id">
INSERT INTO announcement (title, content, enabled, jump_url)
VALUES (#{title}, #{content}, #{enabled}, #{jumpUrl})
</insert>
<update id="update" parameterType="com.gameplatform.server.model.entity.admin.Announcement">
UPDATE announcement
<set>
<if test="title != null">title = #{title},</if>
<if test="content != null">content = #{content},</if>
<if test="enabled != null">enabled = #{enabled},</if>
<if test="jumpUrl != null">jump_url = #{jumpUrl},</if>
</set>
WHERE id = #{id}
</update>
<delete id="deleteById" parameterType="long">
DELETE FROM announcement WHERE id = #{id}
</delete>
<select id="findAll" resultMap="AnnouncementMap">
SELECT id, title, content, enabled, jump_url, created_at, updated_at
FROM announcement
ORDER BY created_at DESC
LIMIT #{size} OFFSET #{offset}
</select>
<select id="countAll" resultType="long">
SELECT COUNT(1) FROM announcement
</select>
<select id="findByEnabled" resultMap="AnnouncementMap">
SELECT id, title, content, enabled, jump_url, created_at, updated_at
FROM announcement
WHERE enabled = #{enabled}
ORDER BY created_at DESC
LIMIT #{size} OFFSET #{offset}
</select>
<select id="countByEnabled" resultType="long">
SELECT COUNT(1) FROM announcement WHERE enabled = #{enabled}
</select>
<update id="updateEnabled">
UPDATE announcement SET enabled = #{enabled} WHERE id = #{id}
</update>
</mapper>

View File

@@ -0,0 +1,74 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.gameplatform.server.mapper.admin.OperationLogMapper">
<resultMap id="OperationLogMap" type="com.gameplatform.server.model.entity.admin.OperationLog">
<id property="id" column="id" />
<result property="actorType" column="actor_type" />
<result property="actorId" column="actor_id" />
<result property="codeNo" column="code_no" />
<result property="op" column="op" />
<result property="detail" column="detail" />
<result property="clientIp" column="client_ip" />
<result property="userAgent" column="user_agent" />
<result property="createdAt" column="created_at" />
</resultMap>
<select id="findById" parameterType="long" resultMap="OperationLogMap">
SELECT id, actor_type, actor_id, code_no, op, detail, client_ip, user_agent, created_at
FROM operation_log
WHERE id = #{id}
LIMIT 1
</select>
<insert id="insert" parameterType="com.gameplatform.server.model.entity.admin.OperationLog" useGeneratedKeys="true" keyProperty="id">
INSERT INTO operation_log (actor_type, actor_id, code_no, op, detail, client_ip, user_agent)
VALUES (#{actorType}, #{actorId}, #{codeNo}, #{op}, #{detail}, #{clientIp}, #{userAgent})
</insert>
<select id="findByCodeNo" resultMap="OperationLogMap">
SELECT id, actor_type, actor_id, code_no, op, detail, client_ip, user_agent, created_at
FROM operation_log
WHERE code_no = #{codeNo}
ORDER BY created_at DESC
LIMIT #{size} OFFSET #{offset}
</select>
<select id="countByCodeNo" resultType="long">
SELECT COUNT(1) FROM operation_log WHERE code_no = #{codeNo}
</select>
<select id="findByActorId" resultMap="OperationLogMap">
SELECT id, actor_type, actor_id, code_no, op, detail, client_ip, user_agent, created_at
FROM operation_log
WHERE actor_id = #{actorId}
ORDER BY created_at DESC
LIMIT #{size} OFFSET #{offset}
</select>
<select id="countByActorId" resultType="long">
SELECT COUNT(1) FROM operation_log WHERE actor_id = #{actorId}
</select>
<select id="findByActorType" resultMap="OperationLogMap">
SELECT id, actor_type, actor_id, code_no, op, detail, client_ip, user_agent, created_at
FROM operation_log
WHERE actor_type = #{actorType}
ORDER BY created_at DESC
LIMIT #{size} OFFSET #{offset}
</select>
<select id="countByActorType" resultType="long">
SELECT COUNT(1) FROM operation_log WHERE actor_type = #{actorType}
</select>
<select id="findAll" resultMap="OperationLogMap">
SELECT id, actor_type, actor_id, code_no, op, detail, client_ip, user_agent, created_at
FROM operation_log
ORDER BY created_at DESC
LIMIT #{size} OFFSET #{offset}
</select>
<select id="countAll" resultType="long">
SELECT COUNT(1) FROM operation_log
</select>
</mapper>

View File

@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.gameplatform.server.mapper.agent.AgentPointsTxMapper">
<resultMap id="AgentPointsTxMap" type="com.gameplatform.server.model.entity.agent.AgentPointsTx">
<id property="id" column="id" />
<result property="accountId" column="account_id" />
<result property="type" column="type" />
<result property="beforePoints" column="before_points" />
<result property="deltaPoints" column="delta_points" />
<result property="afterPoints" column="after_points" />
<result property="reason" column="reason" />
<result property="refId" column="ref_id" />
<result property="operatorId" column="operator_id" />
<result property="createdAt" column="created_at" />
</resultMap>
<select id="findById" parameterType="long" resultMap="AgentPointsTxMap">
SELECT id, account_id, type, before_points, delta_points, after_points, reason, ref_id, operator_id, created_at
FROM agent_points_tx
WHERE id = #{id}
LIMIT 1
</select>
<insert id="insert" parameterType="com.gameplatform.server.model.entity.agent.AgentPointsTx" useGeneratedKeys="true" keyProperty="id">
INSERT INTO agent_points_tx (account_id, type, before_points, delta_points, after_points, reason, ref_id, operator_id)
VALUES (#{accountId}, #{type}, #{beforePoints}, #{deltaPoints}, #{afterPoints}, #{reason}, #{refId}, #{operatorId})
</insert>
<select id="findByAccountId" resultMap="AgentPointsTxMap">
SELECT id, account_id, type, before_points, delta_points, after_points, reason, ref_id, operator_id, created_at
FROM agent_points_tx
WHERE account_id = #{accountId}
ORDER BY created_at DESC
LIMIT #{size} OFFSET #{offset}
</select>
<select id="countByAccountId" resultType="long">
SELECT COUNT(1) FROM agent_points_tx WHERE account_id = #{accountId}
</select>
<select id="findByAccountIdAndType" resultMap="AgentPointsTxMap">
SELECT id, account_id, type, before_points, delta_points, after_points, reason, ref_id, operator_id, created_at
FROM agent_points_tx
WHERE account_id = #{accountId} AND type = #{type}
ORDER BY created_at DESC
LIMIT #{size} OFFSET #{offset}
</select>
<select id="countByAccountIdAndType" resultType="long">
SELECT COUNT(1) FROM agent_points_tx WHERE account_id = #{accountId} AND type = #{type}
</select>
</mapper>

View File

@@ -0,0 +1,49 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.gameplatform.server.mapper.agent.LinkBatchMapper">
<resultMap id="LinkBatchMap" type="com.gameplatform.server.model.entity.agent.LinkBatch">
<id property="id" column="id" />
<result property="agentId" column="agent_id" />
<result property="quantity" column="quantity" />
<result property="times" column="times" />
<result property="batchSize" column="batch_size" />
<result property="deductPoints" column="deduct_points" />
<result property="operatorId" column="operator_id" />
<result property="createdAt" column="created_at" />
</resultMap>
<select id="findById" parameterType="long" resultMap="LinkBatchMap">
SELECT id, agent_id, quantity, times, batch_size, deduct_points, operator_id, created_at
FROM link_batch
WHERE id = #{id}
LIMIT 1
</select>
<insert id="insert" parameterType="com.gameplatform.server.model.entity.agent.LinkBatch" useGeneratedKeys="true" keyProperty="id">
INSERT INTO link_batch (agent_id, quantity, times, batch_size, deduct_points, operator_id)
VALUES (#{agentId}, #{quantity}, #{times}, #{batchSize}, #{deductPoints}, #{operatorId})
</insert>
<select id="findByAgentId" resultMap="LinkBatchMap">
SELECT id, agent_id, quantity, times, batch_size, deduct_points, operator_id, created_at
FROM link_batch
WHERE agent_id = #{agentId}
ORDER BY created_at DESC
LIMIT #{size} OFFSET #{offset}
</select>
<select id="countByAgentId" resultType="long">
SELECT COUNT(1) FROM link_batch WHERE agent_id = #{agentId}
</select>
<select id="findAll" resultMap="LinkBatchMap">
SELECT id, agent_id, quantity, times, batch_size, deduct_points, operator_id, created_at
FROM link_batch
ORDER BY created_at DESC
LIMIT #{size} OFFSET #{offset}
</select>
<select id="countAll" resultType="long">
SELECT COUNT(1) FROM link_batch
</select>
</mapper>

View File

@@ -0,0 +1,113 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.gameplatform.server.mapper.agent.LinkTaskMapper">
<resultMap id="LinkTaskMap" type="com.gameplatform.server.model.entity.agent.LinkTask">
<id property="id" column="id" />
<result property="batchId" column="batch_id" />
<result property="agentId" column="agent_id" />
<result property="codeNo" column="code_no" />
<result property="tokenHash" column="token_hash" />
<result property="expireAt" column="expire_at" />
<result property="status" column="status" />
<result property="region" column="region" />
<result property="machineId" column="machine_id" />
<result property="loginAt" column="login_at" />
<result property="refundAt" column="refund_at" />
<result property="revokedAt" column="revoked_at" />
<result property="createdAt" column="created_at" />
<result property="updatedAt" column="updated_at" />
</resultMap>
<select id="findById" parameterType="long" resultMap="LinkTaskMap">
SELECT id, batch_id, agent_id, code_no, token_hash, expire_at, status, region, machine_id, login_at, refund_at, revoked_at, created_at, updated_at
FROM link_task
WHERE id = #{id}
LIMIT 1
</select>
<select id="findByCodeNo" parameterType="string" resultMap="LinkTaskMap">
SELECT id, batch_id, agent_id, code_no, token_hash, expire_at, status, region, machine_id, login_at, refund_at, revoked_at, created_at, updated_at
FROM link_task
WHERE code_no = #{codeNo}
LIMIT 1
</select>
<select id="findByTokenHash" parameterType="string" resultMap="LinkTaskMap">
SELECT id, batch_id, agent_id, code_no, token_hash, expire_at, status, region, machine_id, login_at, refund_at, revoked_at, created_at, updated_at
FROM link_task
WHERE token_hash = #{tokenHash}
LIMIT 1
</select>
<insert id="insert" parameterType="com.gameplatform.server.model.entity.agent.LinkTask" useGeneratedKeys="true" keyProperty="id">
INSERT INTO link_task (batch_id, agent_id, code_no, token_hash, expire_at, status, region, machine_id, login_at, refund_at, revoked_at)
VALUES (#{batchId}, #{agentId}, #{codeNo}, #{tokenHash}, #{expireAt}, #{status}, #{region}, #{machineId}, #{loginAt}, #{refundAt}, #{revokedAt})
</insert>
<update id="update" parameterType="com.gameplatform.server.model.entity.agent.LinkTask">
UPDATE link_task
<set>
<if test="status != null">status = #{status},</if>
<if test="region != null">region = #{region},</if>
<if test="machineId != null">machine_id = #{machineId},</if>
<if test="loginAt != null">login_at = #{loginAt},</if>
<if test="refundAt != null">refund_at = #{refundAt},</if>
<if test="revokedAt != null">revoked_at = #{revokedAt},</if>
</set>
WHERE id = #{id}
</update>
<update id="updateStatus">
UPDATE link_task SET status = #{status} WHERE id = #{id}
</update>
<update id="updateStatusAndMachine">
UPDATE link_task
SET status = #{status}, region = #{region}, machine_id = #{machineId}, login_at = #{loginAt}
WHERE id = #{id}
</update>
<select id="findByAgentId" resultMap="LinkTaskMap">
SELECT id, batch_id, agent_id, code_no, token_hash, expire_at, status, region, machine_id, login_at, refund_at, revoked_at, created_at, updated_at
FROM link_task
WHERE agent_id = #{agentId}
ORDER BY created_at DESC
LIMIT #{size} OFFSET #{offset}
</select>
<select id="countByAgentId" resultType="long">
SELECT COUNT(1) FROM link_task WHERE agent_id = #{agentId}
</select>
<select id="findByAgentIdAndStatus" resultMap="LinkTaskMap">
SELECT id, batch_id, agent_id, code_no, token_hash, expire_at, status, region, machine_id, login_at, refund_at, revoked_at, created_at, updated_at
FROM link_task
WHERE agent_id = #{agentId} AND status = #{status}
ORDER BY created_at DESC
LIMIT #{size} OFFSET #{offset}
</select>
<select id="countByAgentIdAndStatus" resultType="long">
SELECT COUNT(1) FROM link_task WHERE agent_id = #{agentId} AND status = #{status}
</select>
<select id="findByBatchId" resultMap="LinkTaskMap">
SELECT id, batch_id, agent_id, code_no, token_hash, expire_at, status, region, machine_id, login_at, refund_at, revoked_at, created_at, updated_at
FROM link_task
WHERE batch_id = #{batchId}
ORDER BY created_at DESC
LIMIT #{size} OFFSET #{offset}
</select>
<select id="countByBatchId" resultType="long">
SELECT COUNT(1) FROM link_task WHERE batch_id = #{batchId}
</select>
<select id="findExpiredTasks" resultMap="LinkTaskMap">
SELECT id, batch_id, agent_id, code_no, token_hash, expire_at, status, region, machine_id, login_at, refund_at, revoked_at, created_at, updated_at
FROM link_task
WHERE expire_at &lt;= #{expireTime} AND status IN ('NEW', 'USING')
ORDER BY expire_at ASC
LIMIT #{size}
</select>
</mapper>

View File

@@ -40,3 +40,16 @@ security:
secret: "change-this-secret-to-a-long-random-string-please"
access-token-minutes: 30
refresh-token-days: 7
# Swagger/OpenAPI 配置
springdoc:
api-docs:
path: /api-docs
swagger-ui:
path: /swagger-ui.html
tags-sorter: alpha
operations-sorter: alpha
doc-expansion: none
disable-swagger-default-url: true
display-request-duration: true
packages-to-scan: com.gameplatform.server.controller

View File

@@ -5,9 +5,7 @@
<id property="id" column="id" />
<result property="userType" column="user_type" />
<result property="username" column="username" />
<result property="displayName" column="display_name" />
<result property="passwordHash" column="password_hash" />
<result property="role" column="role" />
<result property="status" column="status" />
<result property="pointsBalance" column="points_balance" />
<result property="createdAt" column="created_at" />
@@ -15,7 +13,7 @@
</resultMap>
<select id="findByUsernameAndType" resultMap="UserAccountMap">
SELECT id, user_type, username, display_name, password_hash, role, status, points_balance, created_at, updated_at
SELECT id, user_type, username, password_hash, status, points_balance, created_at, updated_at
FROM user_account
WHERE username = #{username}
AND user_type = #{userType}
@@ -23,30 +21,29 @@
</select>
<select id="findByUsername" resultMap="UserAccountMap">
SELECT id, user_type, username, display_name, password_hash, role, status, points_balance, created_at, updated_at
SELECT id, user_type, username, password_hash, status, points_balance, created_at, updated_at
FROM user_account
WHERE username = #{username}
LIMIT 1
</select>
<select id="findById" parameterType="long" resultMap="UserAccountMap">
SELECT id, user_type, username, display_name, password_hash, role, status, points_balance, created_at, updated_at
SELECT id, user_type, username, password_hash, status, points_balance, created_at, updated_at
FROM user_account
WHERE id = #{id}
LIMIT 1
</select>
<insert id="insert" parameterType="com.gameplatform.server.model.entity.account.UserAccount" useGeneratedKeys="true" keyProperty="id">
INSERT INTO user_account (user_type, username, display_name, password_hash, role, status, points_balance)
VALUES (#{userType}, #{username}, #{displayName}, #{passwordHash}, #{role}, #{status}, #{pointsBalance})
INSERT INTO user_account (user_type, username, password_hash, status, points_balance)
VALUES (#{userType}, #{username}, #{passwordHash}, #{status}, #{pointsBalance})
</insert>
<update id="update" parameterType="com.gameplatform.server.model.entity.account.UserAccount">
UPDATE user_account
<set>
<if test="displayName != null">display_name = #{displayName},</if>
<if test="role != null">role = #{role},</if>
<if test="status != null">status = #{status},</if>
<if test="pointsBalance != null">points_balance = #{pointsBalance},</if>
</set>
WHERE id = #{id}
</update>
@@ -64,22 +61,20 @@
<where>
<if test="userType != null and userType != ''">AND user_type = #{userType}</if>
<if test="status != null and status != ''">AND status = #{status}</if>
<if test="role != null and role != ''">AND role = #{role}</if>
<if test="keyword != null and keyword != ''">
AND (username LIKE CONCAT('%', #{keyword}, '%') OR display_name LIKE CONCAT('%', #{keyword}, '%'))
AND username LIKE CONCAT('%', #{keyword}, '%')
</if>
</where>
</select>
<select id="listByFilter" resultMap="UserAccountMap">
SELECT id, user_type, username, display_name, password_hash, role, status, points_balance, created_at, updated_at
SELECT id, user_type, username, password_hash, status, points_balance, created_at, updated_at
FROM user_account
<where>
<if test="userType != null and userType != ''">AND user_type = #{userType}</if>
<if test="status != null and status != ''">AND status = #{status}</if>
<if test="role != null and role != ''">AND role = #{role}</if>
<if test="keyword != null and keyword != ''">
AND (username LIKE CONCAT('%', #{keyword}, '%') OR display_name LIKE CONCAT('%', #{keyword}, '%'))
AND username LIKE CONCAT('%', #{keyword}, '%')
</if>
</where>
ORDER BY id DESC

View File

@@ -0,0 +1,67 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.gameplatform.server.mapper.admin.AnnouncementMapper">
<resultMap id="AnnouncementMap" type="com.gameplatform.server.model.entity.admin.Announcement">
<id property="id" column="id" />
<result property="title" column="title" />
<result property="content" column="content" />
<result property="enabled" column="enabled" />
<result property="jumpUrl" column="jump_url" />
<result property="createdAt" column="created_at" />
<result property="updatedAt" column="updated_at" />
</resultMap>
<select id="findById" parameterType="long" resultMap="AnnouncementMap">
SELECT id, title, content, enabled, jump_url, created_at, updated_at
FROM announcement
WHERE id = #{id}
LIMIT 1
</select>
<insert id="insert" parameterType="com.gameplatform.server.model.entity.admin.Announcement" useGeneratedKeys="true" keyProperty="id">
INSERT INTO announcement (title, content, enabled, jump_url)
VALUES (#{title}, #{content}, #{enabled}, #{jumpUrl})
</insert>
<update id="update" parameterType="com.gameplatform.server.model.entity.admin.Announcement">
UPDATE announcement
<set>
<if test="title != null">title = #{title},</if>
<if test="content != null">content = #{content},</if>
<if test="enabled != null">enabled = #{enabled},</if>
<if test="jumpUrl != null">jump_url = #{jumpUrl},</if>
</set>
WHERE id = #{id}
</update>
<delete id="deleteById" parameterType="long">
DELETE FROM announcement WHERE id = #{id}
</delete>
<select id="findAll" resultMap="AnnouncementMap">
SELECT id, title, content, enabled, jump_url, created_at, updated_at
FROM announcement
ORDER BY created_at DESC
LIMIT #{size} OFFSET #{offset}
</select>
<select id="countAll" resultType="long">
SELECT COUNT(1) FROM announcement
</select>
<select id="findByEnabled" resultMap="AnnouncementMap">
SELECT id, title, content, enabled, jump_url, created_at, updated_at
FROM announcement
WHERE enabled = #{enabled}
ORDER BY created_at DESC
LIMIT #{size} OFFSET #{offset}
</select>
<select id="countByEnabled" resultType="long">
SELECT COUNT(1) FROM announcement WHERE enabled = #{enabled}
</select>
<update id="updateEnabled">
UPDATE announcement SET enabled = #{enabled} WHERE id = #{id}
</update>
</mapper>

View File

@@ -0,0 +1,74 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.gameplatform.server.mapper.admin.OperationLogMapper">
<resultMap id="OperationLogMap" type="com.gameplatform.server.model.entity.admin.OperationLog">
<id property="id" column="id" />
<result property="actorType" column="actor_type" />
<result property="actorId" column="actor_id" />
<result property="codeNo" column="code_no" />
<result property="op" column="op" />
<result property="detail" column="detail" />
<result property="clientIp" column="client_ip" />
<result property="userAgent" column="user_agent" />
<result property="createdAt" column="created_at" />
</resultMap>
<select id="findById" parameterType="long" resultMap="OperationLogMap">
SELECT id, actor_type, actor_id, code_no, op, detail, client_ip, user_agent, created_at
FROM operation_log
WHERE id = #{id}
LIMIT 1
</select>
<insert id="insert" parameterType="com.gameplatform.server.model.entity.admin.OperationLog" useGeneratedKeys="true" keyProperty="id">
INSERT INTO operation_log (actor_type, actor_id, code_no, op, detail, client_ip, user_agent)
VALUES (#{actorType}, #{actorId}, #{codeNo}, #{op}, #{detail}, #{clientIp}, #{userAgent})
</insert>
<select id="findByCodeNo" resultMap="OperationLogMap">
SELECT id, actor_type, actor_id, code_no, op, detail, client_ip, user_agent, created_at
FROM operation_log
WHERE code_no = #{codeNo}
ORDER BY created_at DESC
LIMIT #{size} OFFSET #{offset}
</select>
<select id="countByCodeNo" resultType="long">
SELECT COUNT(1) FROM operation_log WHERE code_no = #{codeNo}
</select>
<select id="findByActorId" resultMap="OperationLogMap">
SELECT id, actor_type, actor_id, code_no, op, detail, client_ip, user_agent, created_at
FROM operation_log
WHERE actor_id = #{actorId}
ORDER BY created_at DESC
LIMIT #{size} OFFSET #{offset}
</select>
<select id="countByActorId" resultType="long">
SELECT COUNT(1) FROM operation_log WHERE actor_id = #{actorId}
</select>
<select id="findByActorType" resultMap="OperationLogMap">
SELECT id, actor_type, actor_id, code_no, op, detail, client_ip, user_agent, created_at
FROM operation_log
WHERE actor_type = #{actorType}
ORDER BY created_at DESC
LIMIT #{size} OFFSET #{offset}
</select>
<select id="countByActorType" resultType="long">
SELECT COUNT(1) FROM operation_log WHERE actor_type = #{actorType}
</select>
<select id="findAll" resultMap="OperationLogMap">
SELECT id, actor_type, actor_id, code_no, op, detail, client_ip, user_agent, created_at
FROM operation_log
ORDER BY created_at DESC
LIMIT #{size} OFFSET #{offset}
</select>
<select id="countAll" resultType="long">
SELECT COUNT(1) FROM operation_log
</select>
</mapper>

View File

@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.gameplatform.server.mapper.agent.AgentPointsTxMapper">
<resultMap id="AgentPointsTxMap" type="com.gameplatform.server.model.entity.agent.AgentPointsTx">
<id property="id" column="id" />
<result property="accountId" column="account_id" />
<result property="type" column="type" />
<result property="beforePoints" column="before_points" />
<result property="deltaPoints" column="delta_points" />
<result property="afterPoints" column="after_points" />
<result property="reason" column="reason" />
<result property="refId" column="ref_id" />
<result property="operatorId" column="operator_id" />
<result property="createdAt" column="created_at" />
</resultMap>
<select id="findById" parameterType="long" resultMap="AgentPointsTxMap">
SELECT id, account_id, type, before_points, delta_points, after_points, reason, ref_id, operator_id, created_at
FROM agent_points_tx
WHERE id = #{id}
LIMIT 1
</select>
<insert id="insert" parameterType="com.gameplatform.server.model.entity.agent.AgentPointsTx" useGeneratedKeys="true" keyProperty="id">
INSERT INTO agent_points_tx (account_id, type, before_points, delta_points, after_points, reason, ref_id, operator_id)
VALUES (#{accountId}, #{type}, #{beforePoints}, #{deltaPoints}, #{afterPoints}, #{reason}, #{refId}, #{operatorId})
</insert>
<select id="findByAccountId" resultMap="AgentPointsTxMap">
SELECT id, account_id, type, before_points, delta_points, after_points, reason, ref_id, operator_id, created_at
FROM agent_points_tx
WHERE account_id = #{accountId}
ORDER BY created_at DESC
LIMIT #{size} OFFSET #{offset}
</select>
<select id="countByAccountId" resultType="long">
SELECT COUNT(1) FROM agent_points_tx WHERE account_id = #{accountId}
</select>
<select id="findByAccountIdAndType" resultMap="AgentPointsTxMap">
SELECT id, account_id, type, before_points, delta_points, after_points, reason, ref_id, operator_id, created_at
FROM agent_points_tx
WHERE account_id = #{accountId} AND type = #{type}
ORDER BY created_at DESC
LIMIT #{size} OFFSET #{offset}
</select>
<select id="countByAccountIdAndType" resultType="long">
SELECT COUNT(1) FROM agent_points_tx WHERE account_id = #{accountId} AND type = #{type}
</select>
</mapper>

View File

@@ -0,0 +1,49 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.gameplatform.server.mapper.agent.LinkBatchMapper">
<resultMap id="LinkBatchMap" type="com.gameplatform.server.model.entity.agent.LinkBatch">
<id property="id" column="id" />
<result property="agentId" column="agent_id" />
<result property="quantity" column="quantity" />
<result property="times" column="times" />
<result property="batchSize" column="batch_size" />
<result property="deductPoints" column="deduct_points" />
<result property="operatorId" column="operator_id" />
<result property="createdAt" column="created_at" />
</resultMap>
<select id="findById" parameterType="long" resultMap="LinkBatchMap">
SELECT id, agent_id, quantity, times, batch_size, deduct_points, operator_id, created_at
FROM link_batch
WHERE id = #{id}
LIMIT 1
</select>
<insert id="insert" parameterType="com.gameplatform.server.model.entity.agent.LinkBatch" useGeneratedKeys="true" keyProperty="id">
INSERT INTO link_batch (agent_id, quantity, times, batch_size, deduct_points, operator_id)
VALUES (#{agentId}, #{quantity}, #{times}, #{batchSize}, #{deductPoints}, #{operatorId})
</insert>
<select id="findByAgentId" resultMap="LinkBatchMap">
SELECT id, agent_id, quantity, times, batch_size, deduct_points, operator_id, created_at
FROM link_batch
WHERE agent_id = #{agentId}
ORDER BY created_at DESC
LIMIT #{size} OFFSET #{offset}
</select>
<select id="countByAgentId" resultType="long">
SELECT COUNT(1) FROM link_batch WHERE agent_id = #{agentId}
</select>
<select id="findAll" resultMap="LinkBatchMap">
SELECT id, agent_id, quantity, times, batch_size, deduct_points, operator_id, created_at
FROM link_batch
ORDER BY created_at DESC
LIMIT #{size} OFFSET #{offset}
</select>
<select id="countAll" resultType="long">
SELECT COUNT(1) FROM link_batch
</select>
</mapper>

View File

@@ -0,0 +1,113 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.gameplatform.server.mapper.agent.LinkTaskMapper">
<resultMap id="LinkTaskMap" type="com.gameplatform.server.model.entity.agent.LinkTask">
<id property="id" column="id" />
<result property="batchId" column="batch_id" />
<result property="agentId" column="agent_id" />
<result property="codeNo" column="code_no" />
<result property="tokenHash" column="token_hash" />
<result property="expireAt" column="expire_at" />
<result property="status" column="status" />
<result property="region" column="region" />
<result property="machineId" column="machine_id" />
<result property="loginAt" column="login_at" />
<result property="refundAt" column="refund_at" />
<result property="revokedAt" column="revoked_at" />
<result property="createdAt" column="created_at" />
<result property="updatedAt" column="updated_at" />
</resultMap>
<select id="findById" parameterType="long" resultMap="LinkTaskMap">
SELECT id, batch_id, agent_id, code_no, token_hash, expire_at, status, region, machine_id, login_at, refund_at, revoked_at, created_at, updated_at
FROM link_task
WHERE id = #{id}
LIMIT 1
</select>
<select id="findByCodeNo" parameterType="string" resultMap="LinkTaskMap">
SELECT id, batch_id, agent_id, code_no, token_hash, expire_at, status, region, machine_id, login_at, refund_at, revoked_at, created_at, updated_at
FROM link_task
WHERE code_no = #{codeNo}
LIMIT 1
</select>
<select id="findByTokenHash" parameterType="string" resultMap="LinkTaskMap">
SELECT id, batch_id, agent_id, code_no, token_hash, expire_at, status, region, machine_id, login_at, refund_at, revoked_at, created_at, updated_at
FROM link_task
WHERE token_hash = #{tokenHash}
LIMIT 1
</select>
<insert id="insert" parameterType="com.gameplatform.server.model.entity.agent.LinkTask" useGeneratedKeys="true" keyProperty="id">
INSERT INTO link_task (batch_id, agent_id, code_no, token_hash, expire_at, status, region, machine_id, login_at, refund_at, revoked_at)
VALUES (#{batchId}, #{agentId}, #{codeNo}, #{tokenHash}, #{expireAt}, #{status}, #{region}, #{machineId}, #{loginAt}, #{refundAt}, #{revokedAt})
</insert>
<update id="update" parameterType="com.gameplatform.server.model.entity.agent.LinkTask">
UPDATE link_task
<set>
<if test="status != null">status = #{status},</if>
<if test="region != null">region = #{region},</if>
<if test="machineId != null">machine_id = #{machineId},</if>
<if test="loginAt != null">login_at = #{loginAt},</if>
<if test="refundAt != null">refund_at = #{refundAt},</if>
<if test="revokedAt != null">revoked_at = #{revokedAt},</if>
</set>
WHERE id = #{id}
</update>
<update id="updateStatus">
UPDATE link_task SET status = #{status} WHERE id = #{id}
</update>
<update id="updateStatusAndMachine">
UPDATE link_task
SET status = #{status}, region = #{region}, machine_id = #{machineId}, login_at = #{loginAt}
WHERE id = #{id}
</update>
<select id="findByAgentId" resultMap="LinkTaskMap">
SELECT id, batch_id, agent_id, code_no, token_hash, expire_at, status, region, machine_id, login_at, refund_at, revoked_at, created_at, updated_at
FROM link_task
WHERE agent_id = #{agentId}
ORDER BY created_at DESC
LIMIT #{size} OFFSET #{offset}
</select>
<select id="countByAgentId" resultType="long">
SELECT COUNT(1) FROM link_task WHERE agent_id = #{agentId}
</select>
<select id="findByAgentIdAndStatus" resultMap="LinkTaskMap">
SELECT id, batch_id, agent_id, code_no, token_hash, expire_at, status, region, machine_id, login_at, refund_at, revoked_at, created_at, updated_at
FROM link_task
WHERE agent_id = #{agentId} AND status = #{status}
ORDER BY created_at DESC
LIMIT #{size} OFFSET #{offset}
</select>
<select id="countByAgentIdAndStatus" resultType="long">
SELECT COUNT(1) FROM link_task WHERE agent_id = #{agentId} AND status = #{status}
</select>
<select id="findByBatchId" resultMap="LinkTaskMap">
SELECT id, batch_id, agent_id, code_no, token_hash, expire_at, status, region, machine_id, login_at, refund_at, revoked_at, created_at, updated_at
FROM link_task
WHERE batch_id = #{batchId}
ORDER BY created_at DESC
LIMIT #{size} OFFSET #{offset}
</select>
<select id="countByBatchId" resultType="long">
SELECT COUNT(1) FROM link_task WHERE batch_id = #{batchId}
</select>
<select id="findExpiredTasks" resultMap="LinkTaskMap">
SELECT id, batch_id, agent_id, code_no, token_hash, expire_at, status, region, machine_id, login_at, refund_at, revoked_at, created_at, updated_at
FROM link_task
WHERE expire_at &lt;= #{expireTime} AND status IN ('NEW', 'USING')
ORDER BY expire_at ASC
LIMIT #{size}
</select>
</mapper>

View File

@@ -0,0 +1,34 @@
com\gameplatform\server\mapper\agent\LinkTaskMapper.class
com\gameplatform\server\exception\GlobalExceptionHandler$2.class
com\gameplatform\server\model\entity\admin\Announcement.class
com\gameplatform\server\mapper\agent\AgentPointsTxMapper.class
com\gameplatform\server\config\CorsConfig.class
com\gameplatform\server\exception\GlobalExceptionHandler.class
com\gameplatform\server\model\dto\common\PageResult.class
com\gameplatform\server\service\UserService.class
com\gameplatform\server\controller\auth\AuthController.class
com\gameplatform\server\model\entity\agent\AgentPointsTx.class
com\gameplatform\server\controller\admin\AccountController.class
com\gameplatform\server\GamePlatformServerApplication.class
com\gameplatform\server\model\dto\auth\LoginRequest.class
com\gameplatform\server\model\entity\account\UserAccount.class
com\gameplatform\server\mapper\admin\AnnouncementMapper.class
com\gameplatform\server\model\dto\auth\LoginResponse.class
com\gameplatform\server\model\entity\agent\LinkTask.class
com\gameplatform\server\service\auth\AuthService.class
com\gameplatform\server\config\SwaggerConfig.class
com\gameplatform\server\exception\GlobalExceptionHandler$1.class
com\gameplatform\server\mapper\account\UserAccountMapper.class
com\gameplatform\server\mapper\agent\LinkBatchMapper.class
com\gameplatform\server\security\JwtService.class
com\gameplatform\server\mapper\admin\OperationLogMapper.class
com\gameplatform\server\model\entity\agent\LinkBatch.class
com\gameplatform\server\service\account\AccountService.class
com\gameplatform\server\controller\UserController.class
com\gameplatform\server\security\SecurityConfig.class
com\gameplatform\server\model\entity\admin\OperationLog.class
com\gameplatform\server\model\dto\account\AccountResponse.class
com\gameplatform\server\model\dto\account\AccountCreateRequest.class
com\gameplatform\server\model\dto\account\AccountUpdateRequest.class
com\gameplatform\server\controller\auth\AuthController$1.class
com\gameplatform\server\model\dto\account\ResetPasswordRequest.class

View File

@@ -1,20 +1,31 @@
D:\project\gamePlatform\server\src\main\java\com\gameplatform\server\GamePlatformServerApplication.java
D:\project\gamePlatform\server\src\main\java\com\gameplatform\server\mapper\agent\AgentPointsTxMapper.java
D:\project\gamePlatform\server\src\main\java\com\gameplatform\server\mapper\admin\AnnouncementMapper.java
D:\project\gamePlatform\server\src\main\java\com\gameplatform\server\security\SecurityConfig.java
D:\project\gamePlatform\server\src\main\java\com\gameplatform\server\model\dto\account\ResetPasswordRequest.java
D:\project\gamePlatform\server\src\main\java\com\gameplatform\server\service\account\AccountService.java
D:\project\gamePlatform\server\src\main\java\com\gameplatform\server\service\auth\AuthService.java
D:\project\gamePlatform\server\src\main\java\com\gameplatform\server\model\dto\account\AccountUpdateRequest.java
D:\project\gamePlatform\server\src\main\java\com\gameplatform\server\model\dto\auth\LoginRequest.java
D:\project\gamePlatform\server\src\main\java\com\gameplatform\server\controller\admin\AccountController.java
D:\project\gamePlatform\server\src\main\java\com\gameplatform\server\model\dto\auth\LoginResponse.java
D:\project\gamePlatform\server\src\main\java\com\gameplatform\server\controller\UserController.java
D:\project\gamePlatform\server\src\main\java\com\gameplatform\server\mapper\agent\LinkBatchMapper.java
D:\project\gamePlatform\server\src\main\java\com\gameplatform\server\mapper\agent\LinkTaskMapper.java
D:\project\gamePlatform\server\src\main\java\com\gameplatform\server\config\SwaggerConfig.java
D:\project\gamePlatform\server\src\main\java\com\gameplatform\server\model\dto\account\AccountResponse.java
D:\project\gamePlatform\server\src\main\java\com\gameplatform\server\model\entity\admin\OperationLog.java
D:\project\gamePlatform\server\src\main\java\com\gameplatform\server\service\UserService.java
D:\project\gamePlatform\server\src\main\java\com\gameplatform\server\controller\auth\AuthController.java
D:\project\gamePlatform\server\src\main\java\com\gameplatform\server\security\JwtService.java
D:\project\gamePlatform\server\src\main\java\com\gameplatform\server\config\CorsConfig.java
D:\project\gamePlatform\server\src\main\java\com\gameplatform\server\exception\GlobalExceptionHandler.java
D:\project\gamePlatform\server\src\main\java\com\gameplatform\server\model\dto\common\PageResult.java
D:\project\gamePlatform\server\src\main\java\com\gameplatform\server\GamePlatformServerApplication.java
D:\project\gamePlatform\server\src\main\java\com\gameplatform\server\model\entity\agent\LinkTask.java
D:\project\gamePlatform\server\src\main\java\com\gameplatform\server\model\dto\account\AccountUpdateRequest.java
D:\project\gamePlatform\server\src\main\java\com\gameplatform\server\model\entity\admin\Announcement.java
D:\project\gamePlatform\server\src\main\java\com\gameplatform\server\model\entity\agent\AgentPointsTx.java
D:\project\gamePlatform\server\src\main\java\com\gameplatform\server\model\dto\auth\LoginResponse.java
D:\project\gamePlatform\server\src\main\java\com\gameplatform\server\mapper\admin\OperationLogMapper.java
D:\project\gamePlatform\server\src\main\java\com\gameplatform\server\exception\GlobalExceptionHandler.java
D:\project\gamePlatform\server\src\main\java\com\gameplatform\server\model\entity\agent\LinkBatch.java
D:\project\gamePlatform\server\src\main\java\com\gameplatform\server\mapper\account\UserAccountMapper.java
D:\project\gamePlatform\server\src\main\java\com\gameplatform\server\model\dto\account\AccountCreateRequest.java
D:\project\gamePlatform\server\src\main\java\com\gameplatform\server\model\entity\account\UserAccount.java