chore: 更新.gitignore文件以排除日志、数据库临时文件和测试脚本,删除不再需要的文档和SQL脚本,优化项目结构

This commit is contained in:
yahaozhang
2025-10-11 14:12:50 +08:00
parent eb41a01190
commit 951b9ba2f1
12 changed files with 15 additions and 631 deletions

15
.gitignore vendored
View File

@@ -22,10 +22,23 @@ Thumbs.db
# Logs
*.log
logs/
*.log.*
*.log.gz
# Database temporary files
*.sql
!src/main/resources/db/migration/*.sql
!src/main/resources/schema.sql
# Test scripts
*.http
# Temporary files
*.tmp
*.temp
# Other temporary files
tatus
validation_logging_guide.md

2
.idea/misc.xml generated
View File

@@ -8,7 +8,7 @@
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="graalvm-jdk-21" project-jdk-type="JavaSDK">
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="graalvm-jdk-21 (2)" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

View File

@@ -1,99 +0,0 @@
/*
数据库优化脚本
解决设备冷却、游戏完成检测等问题
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for machine_cooldown
-- 解决问题1设备10分钟内重复调用
-- ----------------------------
DROP TABLE IF EXISTS `machine_cooldown`;
CREATE TABLE `machine_cooldown` (
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
`machine_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '设备ID',
`cooldown_start_time` datetime(3) NOT NULL COMMENT '冷却开始时间',
`cooldown_end_time` datetime(3) NOT NULL COMMENT '冷却结束时间',
`reason` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '冷却原因',
`link_task_id` bigint(20) UNSIGNED NULL DEFAULT NULL COMMENT '关联的链接任务ID',
`status` enum('ACTIVE','EXPIRED','MANUALLY_REMOVED') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'ACTIVE' COMMENT '冷却状态',
`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_machine_active`(`machine_id`, `status`) USING BTREE COMMENT '确保同一设备只有一个活跃冷却记录',
INDEX `idx_machine_end_time`(`machine_id`, `cooldown_end_time`) USING BTREE,
INDEX `idx_cooldown_end_time`(`cooldown_end_time`) USING BTREE,
INDEX `fk_mc_link_task`(`link_task_id`) USING BTREE,
CONSTRAINT `fk_mc_link_task` FOREIGN KEY (`link_task_id`) REFERENCES `link_task` (`id`) ON DELETE SET NULL ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '设备冷却状态表' ROW_FORMAT = DYNAMIC;
-- ----------------------------
-- Table structure for game_completion_log
-- 解决问题2误判游戏完成
-- ----------------------------
DROP TABLE IF EXISTS `game_completion_log`;
CREATE TABLE `game_completion_log` (
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
`link_task_id` bigint(20) UNSIGNED NOT NULL COMMENT '链接任务ID',
`machine_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '设备ID',
`detection_source` enum('TIMER_TASK','EVENT_LISTENER','REGION_SELECT','MANUAL') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '检测来源',
`device_status` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '设备状态',
`points_detected` int(10) UNSIGNED NULL DEFAULT NULL COMMENT '检测到的点数',
`completion_confidence` enum('HIGH','MEDIUM','LOW') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'MEDIUM' COMMENT '完成置信度',
`is_confirmed` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否已确认完成',
`confirmation_time` datetime(3) NULL DEFAULT NULL COMMENT '确认完成时间',
`created_at` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
PRIMARY KEY (`id`) USING BTREE,
INDEX `idx_link_task`(`link_task_id`) USING BTREE,
INDEX `idx_machine_time`(`machine_id`, `created_at`) USING BTREE,
INDEX `idx_source_confidence`(`detection_source`, `completion_confidence`) USING BTREE,
CONSTRAINT `fk_gcl_link_task` FOREIGN KEY (`link_task_id`) REFERENCES `link_task` (`id`) ON DELETE CASCADE ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '游戏完成检测日志表' ROW_FORMAT = DYNAMIC;
-- ----------------------------
-- 为link_task表添加更多索引优化
-- ----------------------------
ALTER TABLE `link_task`
ADD INDEX `idx_machine_status`(`machine_id`, `status`) USING BTREE COMMENT '按设备和状态查询优化',
ADD INDEX `idx_status_updated`(`status`, `updated_at`) USING BTREE COMMENT '按状态和更新时间查询优化',
ADD INDEX `idx_login_time`(`login_at`) USING BTREE COMMENT '登录时间查询优化';
-- ----------------------------
-- 添加唯一编号生成序列表(备用方案)
-- ----------------------------
DROP TABLE IF EXISTS `code_sequence`;
CREATE TABLE `code_sequence` (
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
`sequence_value` bigint(20) UNSIGNED NOT NULL DEFAULT 0 COMMENT '序列值',
`last_reset_date` date NOT NULL COMMENT '最后重置日期',
`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_unicode_ci COMMENT = '编号序列表(用于生成唯一编号)' ROW_FORMAT = DYNAMIC;
-- 初始化序列表
INSERT INTO `code_sequence` (`sequence_value`, `last_reset_date`) VALUES (0, CURDATE());
-- ----------------------------
-- 添加系统监控表
-- ----------------------------
DROP TABLE IF EXISTS `system_monitor`;
CREATE TABLE `system_monitor` (
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
`monitor_type` enum('DEVICE_STATUS','TASK_STATUS','COOLDOWN_STATUS','ERROR_LOG') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '监控类型',
`monitor_key` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '监控键',
`monitor_value` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '监控值',
`alert_level` enum('INFO','WARN','ERROR','CRITICAL') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'INFO' COMMENT '告警级别',
`is_resolved` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否已解决',
`resolved_at` datetime(3) NULL DEFAULT NULL COMMENT '解决时间',
`created_at` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
PRIMARY KEY (`id`) USING BTREE,
INDEX `idx_type_key`(`monitor_type`, `monitor_key`) USING BTREE,
INDEX `idx_level_resolved`(`alert_level`, `is_resolved`) USING BTREE,
INDEX `idx_created_at`(`created_at`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '系统监控表' ROW_FORMAT = DYNAMIC;
SET FOREIGN_KEY_CHECKS = 1;

View File

@@ -1,20 +0,0 @@
-- 添加设备优先前缀配置项
-- 该配置用于指定设备选择时的前缀优先级,逗号分隔
-- 例如:"xx,yy,zz" 表示优先选择 xx 开头的设备,其次 yy最后 zz
-- 同优先级内随机选择,实现负载均衡
INSERT INTO system_config (config_key, config_value, config_type, description, is_system, created_at, updated_at)
VALUES (
'device.priority_prefixes',
'',
'STRING',
'设备选择优先前缀逗号分隔例如xx,yy,zz。优先选择匹配前缀的设备同优先级内随机。为空则全随机',
1,
NOW(3),
NOW(3)
)
ON DUPLICATE KEY UPDATE
config_type = 'STRING',
description = '设备选择优先前缀逗号分隔例如xx,yy,zz。优先选择匹配前缀的设备同优先级内随机。为空则全随机',
updated_at = NOW(3);

View File

@@ -1,43 +0,0 @@
-- 设备状态变更记录清理测试脚本
-- 用于验证24小时清理功能
-- 1. 检查表结构
SELECT 'Table Structure:' as info;
DESC device_status_transition;
-- 2. 查看当前记录数
SELECT 'Current Records Count:' as info;
SELECT COUNT(*) as total_records FROM device_status_transition;
-- 3. 查看24小时前的记录数将被清理的记录
SELECT '24+ Hours Old Records (to be cleaned):' as info;
SELECT COUNT(*) as old_records
FROM device_status_transition
WHERE created_at < DATE_SUB(NOW(), INTERVAL 24 HOUR);
-- 4. 查看最近24小时的记录数将被保留的记录
SELECT 'Recent 24 Hours Records (to be kept):' as info;
SELECT COUNT(*) as recent_records
FROM device_status_transition
WHERE created_at >= DATE_SUB(NOW(), INTERVAL 24 HOUR);
-- 5. 查看记录的时间分布
SELECT 'Records Distribution:' as info;
SELECT
DATE(created_at) as date,
COUNT(*) as count
FROM device_status_transition
GROUP BY DATE(created_at)
ORDER BY date DESC
LIMIT 10;
-- 6. 预览将被删除的记录最多显示5条
SELECT 'Sample Records to be Deleted:' as info;
SELECT device_id, prev_status, new_status, created_at
FROM device_status_transition
WHERE created_at < DATE_SUB(NOW(), INTERVAL 24 HOUR)
ORDER BY created_at DESC
LIMIT 5;
-- 测试删除语句(注释掉,仅用于验证语法)
-- DELETE FROM device_status_transition WHERE created_at < DATE_SUB(NOW(), INTERVAL 24 HOUR);

1
tatus
View File

@@ -1 +0,0 @@
e9858bf (HEAD -> main) fix: 修复Spring Boot兼容性问题并添加链接删除功能

View File

@@ -1,82 +0,0 @@
### 按狀態批量刪除鏈接接口測試
# 需要先獲取JWT token
POST http://localhost:8080/api/auth/login
Content-Type: application/json
{
"username": "admin",
"password": "admin"
}
### 使用獲取到的token進行按狀態批量刪除
# 1. 刪除已過期的鏈接
POST http://localhost:8080/api/link/batch-delete-by-status
Content-Type: application/json
Authorization: Bearer {{token}}
{
"statusList": ["EXPIRED"],
"confirmDelete": true
}
### 2. 刪除已退款的鏈接
POST http://localhost:8080/api/link/batch-delete-by-status
Content-Type: application/json
Authorization: Bearer {{token}}
{
"statusList": ["REFUNDED"],
"confirmDelete": true
}
### 3. 同時刪除多種狀態的鏈接(已過期和已退款)
POST http://localhost:8080/api/link/batch-delete-by-status
Content-Type: application/json
Authorization: Bearer {{token}}
{
"statusList": ["EXPIRED", "REFUNDED"],
"confirmDelete": true
}
### 4. 測試錯誤情況:未確認刪除操作
POST http://localhost:8080/api/link/batch-delete-by-status
Content-Type: application/json
Authorization: Bearer {{token}}
{
"statusList": ["EXPIRED"],
"confirmDelete": false
}
### 5. 測試錯誤情況:無效的狀態值
POST http://localhost:8080/api/link/batch-delete-by-status
Content-Type: application/json
Authorization: Bearer {{token}}
{
"statusList": ["INVALID_STATUS"],
"confirmDelete": true
}
### 6. 測試錯誤情況:空狀態列表
POST http://localhost:8080/api/link/batch-delete-by-status
Content-Type: application/json
Authorization: Bearer {{token}}
{
"statusList": [],
"confirmDelete": true
}
### 7. 刪除新建狀態的鏈接(謹慎使用)
POST http://localhost:8080/api/link/batch-delete-by-status
Content-Type: application/json
Authorization: Bearer {{token}}
{
"statusList": ["NEW"],
"confirmDelete": true
}

View File

@@ -1,53 +0,0 @@
### 测试设备空闲状态配置项
### 测试前请确保已执行数据库迁移脚本: docs/database_migration_add_device_idle_status.sql
### 1. 获取设备空闲状态配置
GET http://localhost:8080/api/admin/config/key/device.idle_status
Authorization: Bearer {{token}}
### 2. 创建设备空闲状态配置(如果不存在)
POST http://localhost:8080/api/admin/config
Content-Type: application/json
Authorization: Bearer {{token}}
{
"configKey": "device.idle_status",
"configValue": "空闲",
"configType": "STRING",
"description": "设备空闲状态的字符串标识,用于判断设备是否处于空闲状态",
"isSystem": true
}
### 3. 更新设备空闲状态配置为其他值(测试灵活性)
PUT http://localhost:8080/api/admin/config/{{configId}}
Content-Type: application/json
Authorization: Bearer {{token}}
{
"configKey": "device.idle_status",
"configValue": "idle",
"configType": "STRING",
"description": "设备空闲状态的字符串标识,用于判断设备是否处于空闲状态",
"isSystem": true
}
### 4. 恢复默认值
PUT http://localhost:8080/api/admin/config/{{configId}}
Content-Type: application/json
Authorization: Bearer {{token}}
{
"configKey": "device.idle_status",
"configValue": "空闲",
"configType": "STRING",
"description": "设备空闲状态的字符串标识,用于判断设备是否处于空闲状态",
"isSystem": true
}
### 5. 获取所有系统配置查看是否包含新配置项
GET http://localhost:8080/api/admin/config/list?page=1&size=50
Authorization: Bearer {{token}}
### 6. 根据类型获取STRING类型配置
GET http://localhost:8080/api/admin/config/type/STRING
Authorization: Bearer {{token}}

View File

@@ -1,96 +0,0 @@
### 退单接口测试
# 变量定义
@baseUrl = http://localhost:8080
@jwt_token = YOUR_JWT_TOKEN_HERE
@test_code_no = YOUR_TEST_CODE_NO_HERE
### 1. 登录获取JWT令牌 (先执行这个获取token)
POST {{baseUrl}}/api/auth/login
Content-Type: application/json
{
"username": "your_username",
"password": "your_password"
}
###
### 2. 生成测试链接 (获取一个codeNo用于测试)
POST {{baseUrl}}/api/link/generate
Authorization: Bearer {{jwt_token}}
Content-Type: application/json
{
"times": 1,
"linkCount": 1
}
###
### 3. 查看链接当前状态 (退单前)
GET {{baseUrl}}/api/link/{{test_code_no}}/status
Accept: application/json
###
### 4. 执行退单操作 - 正常情况
POST {{baseUrl}}/api/link/{{test_code_no}}/refund
Authorization: Bearer {{jwt_token}}
Content-Type: application/json
###
### 5. 查看链接退单后状态 (应该是REFUNDED状态)
GET {{baseUrl}}/api/link/{{test_code_no}}/status
Accept: application/json
###
### 6. 重复退单测试 (应该返回错误: 链接已经退过单)
POST {{baseUrl}}/api/link/{{test_code_no}}/refund
Authorization: Bearer {{jwt_token}}
Content-Type: application/json
###
### 7. 测试不存在的链接退单 (应该返回错误: 链接不存在)
POST {{baseUrl}}/api/link/NOTEXIST123/refund
Authorization: Bearer {{jwt_token}}
Content-Type: application/json
###
### 8. 测试无认证退单 (应该返回401)
POST {{baseUrl}}/api/link/{{test_code_no}}/refund
Content-Type: application/json
###
### 9. 测试错误的JWT令牌 (应该返回401)
POST {{baseUrl}}/api/link/{{test_code_no}}/refund
Authorization: Bearer invalid_jwt_token
Content-Type: application/json
###
### 10. 查看链接列表 (验证退单状态)
GET {{baseUrl}}/api/link/list?page=1&pageSize=10&status=REFUNDED
Authorization: Bearer {{jwt_token}}
Accept: application/json
###
### 测试步骤说明:
# 1. 先执行登录接口获取JWT令牌
# 2. 将获取到的JWT令牌复制到上面的 @jwt_token 变量中
# 3. 生成一个测试链接,获取 codeNo
# 4. 将获取到的 codeNo 复制到上面的 @test_code_no 变量中
# 5. 依次执行后续的测试接口
#
# 预期结果:
# - 正常退单:返回 true
# - 重复退单:返回错误信息 "链接已经退过单"
# - 不存在链接:返回错误信息 "链接不存在"
# - 无认证访问:返回 401 状态码
# - 退单后链接状态变为 REFUNDED

View File

@@ -1,48 +0,0 @@
### 测试选区接口
# 测试选区API - 选择Q区
POST http://localhost:8080/api/link/select-region
Content-Type: application/json
{
"code": "66L8NM3L",
"region": "Q"
}
###
# 测试选区API - 选择V区
POST http://localhost:8080/api/link/select-region
Content-Type: application/json
{
"code": "66L8NM3L",
"region": "V"
}
###
# 测试链接状态API
GET http://localhost:8080/api/link/status?code=66L8NM3L
###
# 测试参数验证 - 无效region
POST http://localhost:8080/api/link/select-region
Content-Type: application/json
{
"code": "66L8NM3L",
"region": "X"
}
###
# 测试参数验证 - 空code
POST http://localhost:8080/api/link/select-region
Content-Type: application/json
{
"code": "",
"region": "Q"
}

View File

@@ -1,32 +0,0 @@
### 获取目标点数接口测试
# 测试获取目标点数
GET http://localhost:8080/api/link/target-score?codeNo=YOUR_CODE_NO_HERE
Accept: application/json
###
# 示例使用实际的codeNo测试
# GET http://localhost:8080/api/link/target-score?codeNo=ABC123DEF456
# Accept: application/json
###
# 响应格式示例:
# 成功时:
# {
# "success": true,
# "completedPoints": 13750,
# "machineId": "device123",
# "codeNo": "ABC123DEF456",
# "errorMessage": null
# }
#
# 失败时:
# {
# "success": false,
# "completedPoints": null,
# "machineId": "device123",
# "codeNo": "ABC123DEF456",
# "errorMessage": "网络繁忙,稍后再试"
# }

View File

@@ -1,155 +0,0 @@
# 用户积分余额接口文档
## 接口概述
获取当前登录用户的积分余额信息通过JWT token自动识别用户身份。
---
## 接口详情
### 基本信息
- **接口路径**: `/api/admin/accounts/me/points-balance`
- **请求方法**: `GET`
- **接口描述**: 根据token解析用户ID并获取当前用户的积分余额
- **认证方式**: JWT Bearer Token
---
## 请求参数
### Headers
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| Authorization | string | 是 | Bearer {token}JWT认证令牌 |
### 请求示例
```http
GET /api/admin/accounts/me/points-balance HTTP/1.1
Host: localhost:8080
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Content-Type: application/json
```
---
## 响应结果
### 成功响应 (200 OK)
```json
{
"userId": 12345,
"username": "agent001",
"userType": "AGENT",
"pointsBalance": 15000
}
```
### 响应字段说明
| 字段名 | 类型 | 说明 |
|--------|------|------|
| userId | Long | 用户ID |
| username | String | 用户名 |
| userType | String | 用户类型ADMIN管理员或 AGENT代理 |
| pointsBalance | Long | 积分余额(单位:积分点数) |
---
## 错误响应
### 401 未授权
```json
{
"error": "Unauthorized",
"message": "Authorization header is required"
}
```
### 400 请求错误
```json
{
"error": "Bad Request",
"message": "Invalid token: userId not found"
}
```
### 404 用户不存在
```json
{
"error": "Not Found",
"message": "用户不存在"
}
```
---
## 调用示例
### JavaScript (fetch)
```javascript
const token = 'your-jwt-token-here';
fetch('/api/admin/accounts/me/points-balance', {
method: 'GET',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
}
})
.then(response => response.json())
.then(data => {
console.log('用户积分余额:', data.pointsBalance);
console.log('用户信息:', data);
})
.catch(error => {
console.error('获取积分余额失败:', error);
});
```
### curl
```bash
curl -X GET "http://localhost:8080/api/admin/accounts/me/points-balance" \
-H "Authorization: Bearer your-jwt-token-here" \
-H "Content-Type: application/json"
```
### Java (Spring WebFlux)
```java
WebClient webClient = WebClient.create("http://localhost:8080");
Mono<PointsBalanceResponse> response = webClient
.get()
.uri("/api/admin/accounts/me/points-balance")
.header("Authorization", "Bearer " + jwtToken)
.retrieve()
.bodyToMono(PointsBalanceResponse.class);
response.subscribe(
pointsBalance -> System.out.println("积分余额: " + pointsBalance.getPointsBalance()),
error -> System.err.println("请求失败: " + error.getMessage())
);
```
---
## 注意事项
1. **Token有效性**: JWT token必须有效且未过期
2. **用户类型**:
- ADMIN用户的积分余额通常为0
- AGENT用户才有实际的积分余额
3. **权限控制**: 只能查询当前登录用户自己的积分余额
4. **数据格式**: 积分余额以长整型返回,单位为积分点数
---
## 状态码说明
| 状态码 | 说明 |
|--------|------|
| 200 | 请求成功,返回积分余额信息 |
| 400 | 请求参数错误或token无效 |
| 401 | 未提供认证信息或认证失败 |
| 404 | 用户不存在 |
| 500 | 服务器内部错误 |