fix: 修复LinkTaskMapper中target_score列不存在的SQL错误
- 移除LinkTaskMapper.xml中所有对不存在的target_score列的引用 - 修复因SQL查询不存在列导致的BadSqlGrammarException - 添加TargetScoreResponse DTO用于目标点数响应 - 更新LinkController添加获取目标点数接口 - 优化UserLinkStatusResponse添加machineId字段 - 更新数据库schema文档 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,29 +0,0 @@
|
||||
-- 数据库迁移脚本:添加完成时点数字段和COMPLETED状态
|
||||
-- 执行时间:2025-08-27
|
||||
|
||||
-- 1. 添加 completed_points 字段
|
||||
ALTER TABLE `link_task`
|
||||
ADD COLUMN `completed_points` int UNSIGNED NULL DEFAULT NULL COMMENT '完成时的点数'
|
||||
AFTER `first_region_select_at`;
|
||||
|
||||
-- 2. 修改 status 枚举,添加 COMPLETED 状态
|
||||
ALTER TABLE `link_task`
|
||||
MODIFY COLUMN `status` enum('NEW','USING','LOGGED_IN','COMPLETED','REFUNDED','EXPIRED')
|
||||
CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT 'NEW';
|
||||
|
||||
-- 3. 验证修改结果
|
||||
SELECT
|
||||
COLUMN_NAME,
|
||||
DATA_TYPE,
|
||||
COLUMN_TYPE,
|
||||
IS_NULLABLE,
|
||||
COLUMN_DEFAULT,
|
||||
COLUMN_COMMENT
|
||||
FROM INFORMATION_SCHEMA.COLUMNS
|
||||
WHERE TABLE_SCHEMA = DATABASE()
|
||||
AND TABLE_NAME = 'link_task'
|
||||
AND COLUMN_NAME IN ('status', 'completed_points')
|
||||
ORDER BY ORDINAL_POSITION;
|
||||
|
||||
-- 4. 检查表结构
|
||||
SHOW CREATE TABLE `link_task`;
|
||||
@@ -1,20 +0,0 @@
|
||||
-- 数据库迁移脚本:添加 COMPLETED 状态到 link_task 表
|
||||
-- 执行时间:请在维护窗口期间执行
|
||||
-- 影响:修改 link_task 表的 status 字段枚举值
|
||||
|
||||
-- 修改 link_task 表的 status 字段,添加 'COMPLETED' 状态
|
||||
-- 'COMPLETED' 状态表示用户正常完成了游戏任务
|
||||
ALTER TABLE `link_task`
|
||||
MODIFY COLUMN `status` enum('NEW','USING','LOGGED_IN','COMPLETED','REFUNDED','EXPIRED')
|
||||
CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT 'NEW'
|
||||
COMMENT '任务状态: NEW=新建, USING=使用中, LOGGED_IN=已登录, COMPLETED=正常完成, REFUNDED=已退款, EXPIRED=已过期';
|
||||
|
||||
-- 验证修改结果
|
||||
-- 查看表结构确认枚举值已更新
|
||||
DESCRIBE `link_task`;
|
||||
|
||||
-- 查看当前各状态的统计
|
||||
SELECT status, COUNT(*) as count
|
||||
FROM `link_task`
|
||||
GROUP BY status
|
||||
ORDER BY status;
|
||||
@@ -1,20 +0,0 @@
|
||||
-- 数据库迁移脚本:为link_task表添加完成图片字段
|
||||
-- 执行时间:2025-08-27
|
||||
-- 说明:添加completion_images字段用于存储任务完成时的4张图片URL(JSON格式)
|
||||
|
||||
-- 为link_task表添加完成图片字段
|
||||
ALTER TABLE `link_task`
|
||||
ADD COLUMN `completion_images` TEXT NULL DEFAULT NULL COMMENT '完成图片JSON(存储4张图片URL)' AFTER `completed_points`;
|
||||
|
||||
-- 验证表结构变更
|
||||
SELECT COLUMN_NAME, DATA_TYPE, IS_NULLABLE, COLUMN_DEFAULT, COLUMN_COMMENT
|
||||
FROM INFORMATION_SCHEMA.COLUMNS
|
||||
WHERE TABLE_SCHEMA = DATABASE()
|
||||
AND TABLE_NAME = 'link_task'
|
||||
AND COLUMN_NAME = 'completion_images'
|
||||
ORDER BY ORDINAL_POSITION;
|
||||
|
||||
-- 验证现有数据
|
||||
SELECT COUNT(*) as total_tasks,
|
||||
COUNT(completion_images) as tasks_with_images
|
||||
FROM `link_task`;
|
||||
@@ -1,26 +0,0 @@
|
||||
-- =====================================================
|
||||
-- 添加设备空闲状态检测系统配置项
|
||||
-- 创建日期: 2024-01-15
|
||||
-- 描述: 添加可配置的设备空闲状态字符串,用于检测设备是否空闲
|
||||
-- =====================================================
|
||||
|
||||
-- 插入设备空闲状态配置项
|
||||
INSERT INTO `system_config` (`config_key`, `config_value`, `config_type`, `description`, `is_system`, `created_at`, `updated_at`)
|
||||
VALUES
|
||||
(
|
||||
'device.idle_status',
|
||||
'空闲',
|
||||
'STRING',
|
||||
'设备空闲状态的字符串标识,用于判断设备是否处于空闲状态',
|
||||
1,
|
||||
CURRENT_TIMESTAMP(3),
|
||||
CURRENT_TIMESTAMP(3)
|
||||
)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
`config_value` = VALUES(`config_value`),
|
||||
`description` = VALUES(`description`),
|
||||
`is_system` = VALUES(`is_system`),
|
||||
`updated_at` = CURRENT_TIMESTAMP(3);
|
||||
|
||||
-- 验证插入结果
|
||||
SELECT * FROM `system_config` WHERE `config_key` = 'device.idle_status';
|
||||
@@ -1,34 +0,0 @@
|
||||
-- 数据库迁移脚本:为link_task表添加首次选区时间字段
|
||||
-- 执行时间:2025-01-XX
|
||||
-- 说明:记录链接首次选区的准确时间,便于跟踪和分析
|
||||
|
||||
-- 为link_task表添加首次选区时间字段
|
||||
ALTER TABLE `link_task`
|
||||
ADD COLUMN `first_region_select_at` datetime(3) NULL DEFAULT NULL COMMENT '首次选区时间' AFTER `qr_expire_at`;
|
||||
|
||||
-- 添加索引以优化查询性能
|
||||
ALTER TABLE `link_task`
|
||||
ADD INDEX `idx_first_region_select` (`first_region_select_at` ASC);
|
||||
|
||||
-- 为现有USING状态的记录回填首次选区时间(使用qr_created_at作为首次选区时间)
|
||||
UPDATE `link_task`
|
||||
SET `first_region_select_at` = `qr_created_at`
|
||||
WHERE `status` = 'USING'
|
||||
AND `qr_created_at` IS NOT NULL
|
||||
AND `first_region_select_at` IS NULL;
|
||||
|
||||
-- 验证表结构变更
|
||||
SELECT COLUMN_NAME, DATA_TYPE, IS_NULLABLE, COLUMN_DEFAULT, COLUMN_COMMENT
|
||||
FROM INFORMATION_SCHEMA.COLUMNS
|
||||
WHERE TABLE_SCHEMA = DATABASE()
|
||||
AND TABLE_NAME = 'link_task'
|
||||
AND COLUMN_NAME = 'first_region_select_at'
|
||||
ORDER BY ORDINAL_POSITION;
|
||||
|
||||
-- 验证数据回填结果
|
||||
SELECT
|
||||
COUNT(*) as total_using_links,
|
||||
COUNT(first_region_select_at) as links_with_first_select_time,
|
||||
COUNT(qr_created_at) as links_with_qr_time
|
||||
FROM `link_task`
|
||||
WHERE `status` = 'USING';
|
||||
@@ -1,33 +0,0 @@
|
||||
-- 数据库迁移脚本:为link_task表添加用户端需要的字段
|
||||
-- 执行时间:2025-01-XX
|
||||
-- 说明:为支持用户端链接状态查询功能添加字段
|
||||
|
||||
-- 为link_task表添加新字段
|
||||
ALTER TABLE `link_task`
|
||||
ADD COLUMN `need_refresh` tinyint(1) NULL DEFAULT 0 COMMENT '是否需要刷新(0否,1是)' AFTER `updated_at`,
|
||||
ADD COLUMN `refresh_time` datetime(3) NULL DEFAULT NULL COMMENT '刷新时间' AFTER `need_refresh`,
|
||||
ADD COLUMN `qr_created_at` datetime(3) NULL DEFAULT NULL COMMENT '二维码创建时间' AFTER `refresh_time`,
|
||||
ADD COLUMN `qr_expire_at` datetime(3) NULL DEFAULT NULL COMMENT '二维码过期时间' AFTER `qr_created_at`;
|
||||
|
||||
-- 添加索引以优化查询性能
|
||||
ALTER TABLE `link_task`
|
||||
ADD INDEX `idx_need_refresh` (`need_refresh` ASC),
|
||||
ADD INDEX `idx_qr_expire` (`qr_expire_at` ASC);
|
||||
|
||||
-- 更新系统配置,添加用户端相关配置
|
||||
INSERT INTO `system_config` (`config_key`, `config_value`, `config_type`, `description`, `is_system`) VALUES
|
||||
('user.qr_expire_seconds', '60', 'INTEGER', '用户端二维码有效期(秒)', 1),
|
||||
('user.refresh_wait_seconds', '10', 'INTEGER', '用户端刷新等待时间(秒)', 1),
|
||||
('user.link_expire_hours', '24', 'INTEGER', '用户端链接有效期(小时)', 1),
|
||||
('user.assets_base_url', 'http://36.138.184.60:12345', 'STRING', '用户端静态资源基础URL', 1)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
`config_value` = VALUES(`config_value`),
|
||||
`updated_at` = CURRENT_TIMESTAMP(3);
|
||||
|
||||
-- 验证表结构变更
|
||||
SELECT COLUMN_NAME, DATA_TYPE, IS_NULLABLE, COLUMN_DEFAULT, COLUMN_COMMENT
|
||||
FROM INFORMATION_SCHEMA.COLUMNS
|
||||
WHERE TABLE_SCHEMA = DATABASE()
|
||||
AND TABLE_NAME = 'link_task'
|
||||
AND COLUMN_NAME IN ('need_refresh', 'refresh_time', 'qr_created_at', 'qr_expire_at')
|
||||
ORDER BY ORDINAL_POSITION;
|
||||
156
docs/game.sql
156
docs/game.sql
@@ -1,17 +1,17 @@
|
||||
/*
|
||||
Navicat Premium Dump SQL
|
||||
|
||||
Source Server : localhost
|
||||
Source Server : 192.140.164.137_3306
|
||||
Source Server Type : MySQL
|
||||
Source Server Version : 80043 (8.0.43)
|
||||
Source Host : localhost:3306
|
||||
Source Server Version : 50744 (5.7.44-log)
|
||||
Source Host : 192.140.164.137:3306
|
||||
Source Schema : login_task_db
|
||||
|
||||
Target Server Type : MySQL
|
||||
Target Server Version : 80043 (8.0.43)
|
||||
Target Server Version : 50744 (5.7.44-log)
|
||||
File Encoding : 65001
|
||||
|
||||
Date: 27/08/2025 15:45:17
|
||||
Date: 29/08/2025 19:16:57
|
||||
*/
|
||||
|
||||
SET NAMES utf8mb4;
|
||||
@@ -22,72 +22,70 @@ 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,
|
||||
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`account_id` bigint(20) UNSIGNED NOT NULL,
|
||||
`type` enum('ADD','DEDUCT') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`before_points` bigint(20) UNSIGNED NOT NULL,
|
||||
`delta_points` bigint(20) NOT NULL,
|
||||
`after_points` bigint(20) UNSIGNED NOT NULL,
|
||||
`reason` enum('create_links','manual','refund_no_rollback','other') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'other',
|
||||
`ref_id` bigint(20) UNSIGNED NULL DEFAULT NULL,
|
||||
`operator_id` bigint(20) 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,
|
||||
INDEX `idx_apx_account_time`(`account_id`, `created_at`) USING BTREE,
|
||||
INDEX `fk_apx_operator`(`operator_id`) 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 AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = DYNAMIC;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for announcement
|
||||
-- ----------------------------
|
||||
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,
|
||||
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`title` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`content` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_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,
|
||||
`jump_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_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 AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = DYNAMIC;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for link_batch
|
||||
-- ----------------------------
|
||||
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,
|
||||
`operator_id` bigint UNSIGNED NULL DEFAULT NULL,
|
||||
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`agent_id` bigint(20) UNSIGNED NOT NULL,
|
||||
`quantity` int(10) UNSIGNED NOT NULL,
|
||||
`times` int(10) UNSIGNED NOT NULL,
|
||||
`operator_id` bigint(20) 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,
|
||||
INDEX `idx_lb_agent_time`(`agent_id`, `created_at`) USING BTREE,
|
||||
INDEX `fk_lb_operator`(`operator_id`) 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_quantity_pos` CHECK (`quantity` > 0),
|
||||
CONSTRAINT `chk_lb_times_pos` CHECK (`times` > 0)
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 13 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
|
||||
CONSTRAINT `fk_lb_operator` FOREIGN KEY (`operator_id`) REFERENCES `user_account` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 39 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = DYNAMIC;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for link_task
|
||||
-- ----------------------------
|
||||
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,
|
||||
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`batch_id` bigint(20) UNSIGNED NOT NULL,
|
||||
`agent_id` bigint(20) UNSIGNED NOT NULL,
|
||||
`code_no` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`token_hash` char(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`expire_at` datetime(3) NOT NULL,
|
||||
`status` enum('NEW','USING','LOGGED_IN','COMPLETED','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,
|
||||
`status` enum('NEW','USING','LOGGED_IN','COMPLETED','REFUNDED','EXPIRED') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'NEW',
|
||||
`region` enum('Q','V') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL,
|
||||
`machine_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_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,
|
||||
@@ -98,74 +96,74 @@ CREATE TABLE `link_task` (
|
||||
`qr_created_at` datetime(3) NULL DEFAULT NULL COMMENT '二维码创建时间',
|
||||
`qr_expire_at` datetime(3) NULL DEFAULT NULL COMMENT '二维码过期时间',
|
||||
`first_region_select_at` datetime(3) NULL DEFAULT NULL COMMENT '首次选区时间',
|
||||
`completed_points` int UNSIGNED NULL DEFAULT NULL COMMENT '完成时的点数',
|
||||
`completed_points` int(10) UNSIGNED NULL DEFAULT NULL COMMENT '完成时的点数',
|
||||
`completion_images` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL COMMENT '完成图片JSON(存储4张图片URL)',
|
||||
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,
|
||||
INDEX `idx_need_refresh`(`need_refresh` ASC) USING BTREE,
|
||||
INDEX `idx_qr_expire`(`qr_expire_at` ASC) USING BTREE,
|
||||
INDEX `idx_first_region_select`(`first_region_select_at` ASC) USING BTREE,
|
||||
UNIQUE INDEX `uk_code_no`(`code_no`) USING BTREE,
|
||||
UNIQUE INDEX `uk_token_hash`(`token_hash`) USING BTREE,
|
||||
INDEX `idx_agent_status`(`agent_id`, `status`) USING BTREE,
|
||||
INDEX `idx_expire_at`(`expire_at`) USING BTREE,
|
||||
INDEX `idx_created_at`(`created_at`) USING BTREE,
|
||||
INDEX `fk_lt_batch`(`batch_id`) USING BTREE,
|
||||
INDEX `idx_need_refresh`(`need_refresh`) USING BTREE,
|
||||
INDEX `idx_qr_expire`(`qr_expire_at`) USING BTREE,
|
||||
INDEX `idx_first_region_select`(`first_region_select_at`) 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 AUTO_INCREMENT = 34 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 78 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = DYNAMIC;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for operation_log
|
||||
-- ----------------------------
|
||||
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,
|
||||
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`actor_type` enum('admin','agent','system','user') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`actor_id` bigint(20) UNSIGNED NULL DEFAULT NULL,
|
||||
`code_no` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL,
|
||||
`op` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_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,
|
||||
`client_ip` varchar(45) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL,
|
||||
`user_agent` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_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 AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
|
||||
INDEX `idx_log_code_time`(`code_no`, `created_at`) USING BTREE,
|
||||
INDEX `idx_log_time`(`created_at`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = DYNAMIC;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for system_config
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `system_config`;
|
||||
CREATE TABLE `system_config` (
|
||||
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`config_key` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '配置键',
|
||||
`config_value` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '配置值',
|
||||
`config_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT 'STRING' COMMENT '配置类型:STRING, INTEGER, BOOLEAN, JSON',
|
||||
`description` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '配置描述',
|
||||
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`config_key` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '配置键',
|
||||
`config_value` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '配置值',
|
||||
`config_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'STRING' COMMENT '配置类型:STRING, INTEGER, BOOLEAN, JSON',
|
||||
`description` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '配置描述',
|
||||
`is_system` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否系统配置(1是,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 `uk_config_key`(`config_key` ASC) USING BTREE,
|
||||
INDEX `idx_config_type`(`config_type` ASC) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 13 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = DYNAMIC;
|
||||
UNIQUE INDEX `uk_config_key`(`config_key`) USING BTREE,
|
||||
INDEX `idx_config_type`(`config_type`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 15 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = DYNAMIC;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for user_account
|
||||
-- ----------------------------
|
||||
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,
|
||||
`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,
|
||||
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`user_type` enum('ADMIN','AGENT') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`username` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`password_hash` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`status` enum('ENABLED','DISABLED') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'ENABLED',
|
||||
`points_balance` bigint(20) 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;
|
||||
UNIQUE INDEX `username`(`username`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = DYNAMIC;
|
||||
|
||||
SET FOREIGN_KEY_CHECKS = 1;
|
||||
|
||||
@@ -12,6 +12,7 @@ import com.gameplatform.server.model.dto.link.PollLoginResponse;
|
||||
import com.gameplatform.server.model.dto.link.SelectRegionRequest;
|
||||
import com.gameplatform.server.model.dto.link.SelectRegionResponse;
|
||||
import com.gameplatform.server.model.dto.link.UserLinkStatusResponse;
|
||||
import com.gameplatform.server.model.dto.link.TargetScoreResponse;
|
||||
import com.gameplatform.server.service.link.LinkGenerationService;
|
||||
import com.gameplatform.server.service.link.LinkListService;
|
||||
import com.gameplatform.server.service.link.LinkStatusService;
|
||||
@@ -484,6 +485,31 @@ public Mono<Boolean> deleteLink(@PathVariable("codeNo") String codeNo, Authentic
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取目标点数接口
|
||||
*/
|
||||
@GetMapping("/target-score")
|
||||
@Operation(summary = "获取目标点数", description = "根据链接编号获取目标点数,如果返回的是数字则保存到数据库,否则提示网络繁忙")
|
||||
public Mono<TargetScoreResponse> getTargetScore(@RequestParam("codeNo") String codeNo) {
|
||||
log.info("=== 开始获取目标点数 ===");
|
||||
log.info("请求参数: codeNo={}", codeNo);
|
||||
|
||||
return linkStatusService.getTargetScore(codeNo)
|
||||
.doOnSuccess(response -> {
|
||||
if (response.isSuccess()) {
|
||||
log.info("目标点数获取成功: codeNo={}, machineId={}, targetScore={}",
|
||||
response.getCodeNo(), response.getMachineId(), response.getCompletedPoints());
|
||||
} else {
|
||||
log.warn("目标点数获取失败: codeNo={}, machineId={}, error={}",
|
||||
response.getCodeNo(), response.getMachineId(), response.getErrorMessage());
|
||||
}
|
||||
})
|
||||
.doOnError(error -> {
|
||||
log.error("获取目标点数时发生异常: codeNo={}, error={}",
|
||||
codeNo, error.getMessage(), error);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -352,7 +352,6 @@ public class QrProxyController {
|
||||
response.setTimes(linkBatch.getTimes());
|
||||
response.setTotalPoints(linkBatch.getQuantity() * linkBatch.getTimes());
|
||||
response.setCompletedPoints(linkTask.getCompletedPoints());
|
||||
|
||||
// 设置游戏区域信息
|
||||
response.setRegion(linkTask.getRegion());
|
||||
response.setRegionDesc(getRegionDescription(linkTask.getRegion()));
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
package com.gameplatform.server.model.dto.link;
|
||||
|
||||
/**
|
||||
* 目标点数响应DTO
|
||||
*/
|
||||
public class TargetScoreResponse {
|
||||
|
||||
/**
|
||||
* 是否成功获取目标点数
|
||||
*/
|
||||
private boolean success;
|
||||
|
||||
/**
|
||||
* 完成点数值(当success为true时有效)
|
||||
*/
|
||||
private Integer completedPoints;
|
||||
|
||||
/**
|
||||
* 错误消息(当success为false时)
|
||||
*/
|
||||
private String errorMessage;
|
||||
|
||||
/**
|
||||
* 设备ID
|
||||
*/
|
||||
private String machineId;
|
||||
|
||||
/**
|
||||
* 链接编号
|
||||
*/
|
||||
private String codeNo;
|
||||
|
||||
public TargetScoreResponse() {
|
||||
}
|
||||
|
||||
public TargetScoreResponse(boolean success, Integer completedPoints, String errorMessage) {
|
||||
this.success = success;
|
||||
this.completedPoints = completedPoints;
|
||||
this.errorMessage = errorMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* 成功响应
|
||||
*/
|
||||
public static TargetScoreResponse success(String codeNo, String machineId, Integer completedPoints) {
|
||||
TargetScoreResponse response = new TargetScoreResponse();
|
||||
response.setSuccess(true);
|
||||
response.setCodeNo(codeNo);
|
||||
response.setMachineId(machineId);
|
||||
response.setCompletedPoints(completedPoints);
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* 失败响应
|
||||
*/
|
||||
public static TargetScoreResponse error(String codeNo, String machineId, String errorMessage) {
|
||||
TargetScoreResponse response = new TargetScoreResponse();
|
||||
response.setSuccess(false);
|
||||
response.setCodeNo(codeNo);
|
||||
response.setMachineId(machineId);
|
||||
response.setErrorMessage(errorMessage);
|
||||
return response;
|
||||
}
|
||||
|
||||
public boolean isSuccess() {
|
||||
return success;
|
||||
}
|
||||
|
||||
public void setSuccess(boolean success) {
|
||||
this.success = success;
|
||||
}
|
||||
|
||||
public Integer getCompletedPoints() {
|
||||
return completedPoints;
|
||||
}
|
||||
|
||||
public void setCompletedPoints(Integer completedPoints) {
|
||||
this.completedPoints = completedPoints;
|
||||
}
|
||||
|
||||
public String getErrorMessage() {
|
||||
return errorMessage;
|
||||
}
|
||||
|
||||
public void setErrorMessage(String errorMessage) {
|
||||
this.errorMessage = errorMessage;
|
||||
}
|
||||
|
||||
public String getMachineId() {
|
||||
return machineId;
|
||||
}
|
||||
|
||||
public void setMachineId(String machineId) {
|
||||
this.machineId = machineId;
|
||||
}
|
||||
|
||||
public String getCodeNo() {
|
||||
return codeNo;
|
||||
}
|
||||
|
||||
public void setCodeNo(String codeNo) {
|
||||
this.codeNo = codeNo;
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,13 @@ public class UserLinkStatusResponse {
|
||||
@Schema(description = "链接状态", example = "NEW", allowableValues = {"NEW", "USING", "LOGGED_IN", "COMPLETED", "REFUNDED", "EXPIRED"})
|
||||
private String status;
|
||||
|
||||
@Schema(description = "机器ID")
|
||||
private String machineId;
|
||||
|
||||
// Getter and Setter
|
||||
public String getStatus() { return status; }
|
||||
public void setStatus(String status) { this.status = status; }
|
||||
|
||||
public String getMachineId() { return machineId; }
|
||||
public void setMachineId(String machineId) { this.machineId = machineId; }
|
||||
}
|
||||
|
||||
@@ -68,6 +68,8 @@ public class LinkTask {
|
||||
@TableField("completion_images")
|
||||
private String completionImages; // JSON格式存储4张图片URL
|
||||
|
||||
|
||||
|
||||
public Long getId() { return id; }
|
||||
public void setId(Long id) { this.id = id; }
|
||||
|
||||
@@ -130,4 +132,6 @@ public class LinkTask {
|
||||
|
||||
public String getCompletionImages() { return completionImages; }
|
||||
public void setCompletionImages(String completionImages) { this.completionImages = completionImages; }
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import com.gameplatform.server.model.dto.link.LinkStatusResponse;
|
||||
import com.gameplatform.server.model.dto.link.PollLoginResponse;
|
||||
import com.gameplatform.server.model.dto.link.SelectRegionResponse;
|
||||
import com.gameplatform.server.model.dto.link.UserLinkStatusResponse;
|
||||
import com.gameplatform.server.model.dto.link.TargetScoreResponse;
|
||||
import com.gameplatform.server.model.entity.agent.LinkBatch;
|
||||
import com.gameplatform.server.model.entity.agent.LinkTask;
|
||||
|
||||
@@ -521,7 +522,7 @@ public class LinkStatusService {
|
||||
// 如果状态是USING,返回NEW给用户端
|
||||
String statusToReturn = "USING".equals(linkTask.getStatus()) ? "NEW" : linkTask.getStatus();
|
||||
response.setStatus(statusToReturn);
|
||||
|
||||
response.setMachineId(linkTask.getMachineId());
|
||||
return response;
|
||||
}
|
||||
|
||||
@@ -900,4 +901,93 @@ public class LinkStatusService {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取目标点数
|
||||
* @param codeNo 链接编号
|
||||
* @return 目标点数响应
|
||||
*/
|
||||
public Mono<TargetScoreResponse> getTargetScore(String codeNo) {
|
||||
return Mono.fromCallable(() -> doGetTargetScore(codeNo))
|
||||
.subscribeOn(Schedulers.boundedElastic());
|
||||
}
|
||||
|
||||
private TargetScoreResponse doGetTargetScore(String codeNo) {
|
||||
log.info("=== 开始获取目标点数 ===");
|
||||
log.info("链接编号: {}", codeNo);
|
||||
|
||||
try {
|
||||
// 1. 验证参数
|
||||
if (codeNo == null || codeNo.trim().isEmpty()) {
|
||||
log.error("参数验证失败: codeNo不能为空");
|
||||
return TargetScoreResponse.error(codeNo, null, "链接编号不能为空");
|
||||
}
|
||||
|
||||
// 2. 查询链接任务,获取machineId
|
||||
LinkTask linkTask = linkTaskMapper.findByCodeNo(codeNo.trim());
|
||||
if (linkTask == null) {
|
||||
log.error("链接任务不存在: codeNo={}", codeNo);
|
||||
return TargetScoreResponse.error(codeNo, null, "链接不存在");
|
||||
}
|
||||
|
||||
String machineId = linkTask.getMachineId();
|
||||
if (machineId == null || machineId.trim().isEmpty()) {
|
||||
log.error("链接未关联设备: codeNo={}", codeNo);
|
||||
return TargetScoreResponse.error(codeNo, null, "链接未关联设备");
|
||||
}
|
||||
|
||||
log.info("查询到设备ID: codeNo={}, machineId={}", codeNo, machineId);
|
||||
|
||||
// 3. 调用脚本端获取目标分数
|
||||
log.info("调用脚本端获取目标分数: machineId={}", machineId);
|
||||
String targetScoreStr = scriptClient.getTargetScore(machineId).block();
|
||||
log.info("脚本端返回结果: machineId={}, result={}", machineId, targetScoreStr);
|
||||
|
||||
// 4. 解析返回结果
|
||||
if (targetScoreStr == null || targetScoreStr.trim().isEmpty()) {
|
||||
log.warn("脚本端返回空结果: machineId={}", machineId);
|
||||
return TargetScoreResponse.error(codeNo, machineId, "网络繁忙,稍后再试");
|
||||
}
|
||||
|
||||
String trimmedResult = targetScoreStr.trim();
|
||||
|
||||
// 检查是否为数字
|
||||
try {
|
||||
Integer targetScore = Integer.parseInt(trimmedResult);
|
||||
log.info("解析到数字目标分数: {}", targetScore);
|
||||
|
||||
// 5. 保存到数据库
|
||||
linkTask.setCompletedPoints(targetScore);
|
||||
linkTask.setUpdatedAt(LocalDateTime.now());
|
||||
int updateResult = linkTaskMapper.update(linkTask);
|
||||
|
||||
if (updateResult > 0) {
|
||||
log.info("目标分数保存成功: codeNo={}, machineId={}, targetScore={}",
|
||||
codeNo, machineId, targetScore);
|
||||
return TargetScoreResponse.success(codeNo, machineId, targetScore);
|
||||
} else {
|
||||
log.error("目标分数保存失败: codeNo={}, machineId={}, targetScore={}",
|
||||
codeNo, machineId, targetScore);
|
||||
return TargetScoreResponse.error(codeNo, machineId, "保存目标分数失败");
|
||||
}
|
||||
|
||||
} catch (NumberFormatException e) {
|
||||
// 不是数字,检查特殊状态
|
||||
log.info("脚本端返回非数字结果: {}", trimmedResult);
|
||||
|
||||
if ("空的".equals(trimmedResult) || "空闲".equals(trimmedResult) || "已运行".equals(trimmedResult)) {
|
||||
log.info("设备状态为: {}", trimmedResult);
|
||||
return TargetScoreResponse.error(codeNo, machineId, "网络繁忙,稍后再试");
|
||||
} else {
|
||||
log.warn("未知的返回结果: {}", trimmedResult);
|
||||
return TargetScoreResponse.error(codeNo, machineId, "网络繁忙,稍后再试");
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("=== 获取目标点数失败 ===");
|
||||
log.error("错误详情: codeNo={}, error={}", codeNo, e.getMessage(), e);
|
||||
return TargetScoreResponse.error(codeNo, null, "系统异常,请稍后再试");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user