diff --git a/.idea/vcs.xml b/.idea/vcs.xml index d843f34..94a25f7 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -1,4 +1,6 @@ - + + + \ No newline at end of file diff --git a/.kiro/specs/file-transfer-service/requirements.md b/.kiro/specs/file-transfer-service/requirements.md new file mode 100644 index 0000000..66d3a91 --- /dev/null +++ b/.kiro/specs/file-transfer-service/requirements.md @@ -0,0 +1,86 @@ +# Requirements Document + +## Introduction + +文件转存服务是一个允许用户通过API Key认证上传文件到腾讯云COS的功能。该服务支持图片文件上传,文件保留15天后自动删除,每次上传固定扣除30积分。服务使用独立的COS存储桶(上海地域),并提供文件记录管理和查询功能。 + +## Glossary + +- **File_Transfer_Service**: 文件转存服务,负责处理文件上传、存储、查询和自动清理的核心服务 +- **Transfer_File**: 转存文件实体,记录上传文件的元数据信息 +- **COS_Client**: 腾讯云对象存储客户端,用于与COS存储桶交互 +- **API_Key_Auth**: API密钥认证机制,用于验证用户身份 +- **Points_Service**: 积分服务,用于扣除用户积分 +- **File_Cleanup_Scheduler**: 文件清理调度器,负责定时删除过期文件 + +## Requirements + +### Requirement 1: 文件上传 + +**User Story:** As a user, I want to upload image files to COS through API Key authentication, so that I can store files temporarily for external access. + +#### Acceptance Criteria + +1. WHEN a user provides a valid API Key and uploads an image file, THE File_Transfer_Service SHALL authenticate the user and accept the file +2. WHEN a user uploads a file, THE File_Transfer_Service SHALL validate that the file type is an image (jpg, jpeg, png, gif, webp, bmp) +3. WHEN a user uploads an image file exceeding 20MB, THE File_Transfer_Service SHALL reject the upload and return an error message +4. WHEN a valid image file is uploaded, THE File_Transfer_Service SHALL store the file in COS bucket "apidatafile-1302947942" in region "ap-shanghai" +5. WHEN a file is successfully uploaded, THE File_Transfer_Service SHALL generate a unique file key with format "transfer/{userId}/{timestamp}_{uuid}.{extension}" +6. WHEN a file is successfully uploaded, THE File_Transfer_Service SHALL return the file access URL to the user + +### Requirement 2: 积分扣除 + +**User Story:** As a system administrator, I want to charge users 30 points per file upload, so that the service usage is properly metered. + +#### Acceptance Criteria + +1. WHEN a user initiates a file upload, THE Points_Service SHALL verify the user has at least 30 points before processing +2. IF a user has insufficient points, THEN THE File_Transfer_Service SHALL reject the upload and return an insufficient points error +3. WHEN a file is successfully uploaded to COS, THE Points_Service SHALL deduct 30 points from the user's balance +4. WHEN points are deducted, THE Points_Service SHALL create a consumption log with type "file_transfer" and description containing the file name + +### Requirement 3: 文件记录管理 + +**User Story:** As a user, I want my uploaded files to be recorded in the database, so that I can track and query my file history. + +#### Acceptance Criteria + +1. WHEN a file is successfully uploaded, THE File_Transfer_Service SHALL create a Transfer_File record in the database +2. THE Transfer_File record SHALL contain: id, user_id, file_key, original_filename, file_size, content_type, cos_url, expire_time, status, create_time, update_time +3. THE Transfer_File record SHALL set expire_time to 15 days from upload time +4. THE Transfer_File record SHALL set initial status to "active" + +### Requirement 4: 文件查询 + +**User Story:** As a user, I want to query my uploaded files, so that I can view my file history and access URLs. + +#### Acceptance Criteria + +1. WHEN a user requests their file list with valid API Key, THE File_Transfer_Service SHALL return paginated list of their Transfer_File records +2. WHEN querying files, THE File_Transfer_Service SHALL support filtering by status (active, expired, deleted) +3. WHEN returning file list, THE File_Transfer_Service SHALL include file_key, original_filename, file_size, content_type, cos_url, expire_time, status, create_time +4. WHEN a file has expired, THE File_Transfer_Service SHALL mark its status as "expired" in query results + +### Requirement 5: 文件自动清理 + +**User Story:** As a system administrator, I want expired files to be automatically deleted from COS, so that storage costs are minimized and data retention policies are enforced. + +#### Acceptance Criteria + +1. THE File_Cleanup_Scheduler SHALL run periodically (every hour) to check for expired files +2. WHEN a Transfer_File record has expire_time before current time and status is "active", THE File_Cleanup_Scheduler SHALL delete the file from COS +3. WHEN a file is successfully deleted from COS, THE File_Cleanup_Scheduler SHALL update the Transfer_File status to "deleted" +4. IF file deletion from COS fails, THEN THE File_Cleanup_Scheduler SHALL log the error and retry in the next scheduled run +5. THE File_Cleanup_Scheduler SHALL process files in batches to avoid overwhelming the COS API + +### Requirement 6: 错误处理 + +**User Story:** As a user, I want clear error messages when file upload fails, so that I can understand and resolve issues. + +#### Acceptance Criteria + +1. IF API Key authentication fails, THEN THE File_Transfer_Service SHALL return HTTP 401 with message "Invalid or inactive API Key" +2. IF file type is not supported, THEN THE File_Transfer_Service SHALL return HTTP 400 with message "Unsupported file type. Allowed types: jpg, jpeg, png, gif, webp, bmp" +3. IF file size exceeds 20MB, THEN THE File_Transfer_Service SHALL return HTTP 400 with message "File size exceeds maximum limit of 20MB" +4. IF points are insufficient, THEN THE File_Transfer_Service SHALL return HTTP 400 with message "Insufficient points. Required: 30 points" +5. IF COS upload fails, THEN THE File_Transfer_Service SHALL return HTTP 500 with message "File upload failed, please try again" diff --git a/1818ai.sql b/1818ai.sql new file mode 100644 index 0000000..058807d --- /dev/null +++ b/1818ai.sql @@ -0,0 +1,1139 @@ +/* + Navicat Premium Dump SQL + + Source Server : 116.62.4.26 + Source Server Type : MySQL + Source Server Version : 50740 (5.7.40-log) + Source Host : 116.62.4.26:3306 + Source Schema : 1818ai + + Target Server Type : MySQL + Target Server Version : 50740 (5.7.40-log) + File Encoding : 65001 + + Date: 06/12/2025 15:20:26 +*/ + +SET NAMES utf8mb4; +SET FOREIGN_KEY_CHECKS = 0; + +-- ---------------------------- +-- Table structure for admin_user +-- ---------------------------- +DROP TABLE IF EXISTS `admin_user`; +CREATE TABLE `admin_user` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键', + `username` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '管理员用户名', + `password_hash` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '哈希后的密码', + `role` tinyint(4) NOT NULL COMMENT '角色(0工作人员/1管理员)', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `is_deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除标识', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `username`(`username`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for ai_task +-- ---------------------------- +DROP TABLE IF EXISTS `ai_task`; +CREATE TABLE `ai_task` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键', + `task_no` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '任务编号 (系统生成的唯一ID)', + `user_id` bigint(20) NOT NULL COMMENT '关联的用户ID', + `model_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '请求的模型名称 (如: sora_image)', + `task_type` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '任务类型 (image/video)', + `provider_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'AI服务提供商类型', + `provider_task_id` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '服务商返回的任务ID', + `provider_response` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '服务商原始响应(JSON)', + `prompt` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '用户提交的提示词', + `image_url` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '参考图片URL(用于图生视频)', + `image_base64` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '参考图片Base64编码(用于图生视频)', + `input_images` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '输入图片列表(JSON格式,用于图生视频)', + `aspect_ratio` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '图片比例(如: 2:3, 3:2, 1:1,仅图片生成使用)', + `duration` int(11) NULL DEFAULT NULL COMMENT '视频时长(秒,仅视频生成使用)', + `status` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'created' COMMENT '任务状态 (created, queued, processing, completed, failed, cancelled)', + `progress` int(11) NULL DEFAULT 0 COMMENT '生成进度百分比 (0-100)', + `progress_message` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '当前进度文本描述', + `points_frozen` int(11) NOT NULL COMMENT '本次任务冻结的积分', + `points_consumed` int(11) NULL DEFAULT 0 COMMENT '任务成功后实际消耗的积分', + `result_url` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '生成结果的URL', + `error_message` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '任务失败时的错误信息', + `queue_time` datetime NULL DEFAULT NULL COMMENT '进入队列的时间', + `start_time` datetime NULL DEFAULT NULL COMMENT '开始处理的时间', + `complete_time` datetime NULL DEFAULT NULL COMMENT '任务完成或失败的时间', + `expire_time` datetime NULL DEFAULT NULL COMMENT '结果URL的过期时间 (根据第三方API策略设定)', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '任务创建时间', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后更新时间', + `is_deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除标识', + `provider_pid` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '服务商返回的PID,用于速创Sora2的续作ID', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `task_no`(`task_no`) USING BTREE, + UNIQUE INDEX `uk_task_no`(`task_no`) USING BTREE, + INDEX `idx_user_status`(`user_id`, `status`) USING BTREE, + INDEX `idx_status_time`(`status`, `create_time`) USING BTREE, + INDEX `idx_provider_task_id`(`provider_task_id`) USING BTREE, + INDEX `idx_provider_type_status`(`provider_type`, `status`) USING BTREE, + INDEX `idx_task_type`(`task_type`) USING BTREE, + CONSTRAINT `ai_task_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE RESTRICT +) ENGINE = InnoDB AUTO_INCREMENT = 1876 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'AI生成任务表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for api_key +-- ---------------------------- +DROP TABLE IF EXISTS `api_key`; +CREATE TABLE `api_key` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键', + `user_id` bigint(20) NOT NULL COMMENT '用户ID', + `key_value` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'API密钥值', + `is_active` tinyint(1) NOT NULL DEFAULT 1 COMMENT '是否启用', + `last_used_at` datetime NULL DEFAULT NULL COMMENT '最后使用时间', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `is_deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除标识', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `key_value`(`key_value`) USING BTREE, + UNIQUE INDEX `uk_api_key_user`(`user_id`) USING BTREE, + INDEX `idx_api_key_value`(`key_value`) USING BTREE, + INDEX `idx_api_key_active`(`is_active`) USING BTREE, + CONSTRAINT `api_key_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE RESTRICT +) ENGINE = InnoDB AUTO_INCREMENT = 76 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for banner +-- ---------------------------- +DROP TABLE IF EXISTS `banner`; +CREATE TABLE `banner` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键', + `image` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '图片URL', + `title` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '标题', + `description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '描述', + `button_text` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '按钮文字', + `link_type` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'internal' COMMENT '链接类型 (internal: 内部路由跳转, external: 外部链接跳转)', + `link` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '跳转链接', + `sort_order` int(11) NOT NULL DEFAULT 0 COMMENT '排序字段', + `is_enabled` tinyint(1) NOT NULL DEFAULT 1 COMMENT '是否启用(0禁用/1启用)', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `is_deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除标识', + PRIMARY KEY (`id`) USING BTREE, + INDEX `idx_banner_enabled`(`is_enabled`) USING BTREE, + INDEX `idx_banner_sort`(`sort_order`) USING BTREE, + INDEX `idx_banner_create_time`(`create_time`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 6 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for category +-- ---------------------------- +DROP TABLE IF EXISTS `category`; +CREATE TABLE `category` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键', + `name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '类目名称', + `type` tinyint(4) NOT NULL COMMENT '类目类型(1课程分类/2工作流分类)', + `description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '类目描述', + `sort_order` int(11) NOT NULL DEFAULT 0 COMMENT '排序字段', + `is_enabled` tinyint(1) NOT NULL DEFAULT 1 COMMENT '是否启用(0禁用/1启用)', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `is_deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除标识', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `uk_category_name_type`(`name`, `type`) USING BTREE, + INDEX `idx_category_type`(`type`) USING BTREE, + INDEX `idx_category_enabled`(`is_enabled`) USING BTREE, + INDEX `idx_category_sort`(`sort_order`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 18 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '类目表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for content_revenue +-- ---------------------------- +DROP TABLE IF EXISTS `content_revenue`; +CREATE TABLE `content_revenue` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键', + `user_id` bigint(20) NOT NULL COMMENT '内容创作者ID', + `content_type` tinyint(4) NOT NULL COMMENT '内容类型 (1工作流/2视频)', + `content_id` bigint(20) NOT NULL COMMENT '内容ID', + `revenue_source` tinyint(4) NOT NULL COMMENT '收益来源 (1购买/2复制/3观看)', + `source_value` decimal(10, 2) NULL DEFAULT 0.00 COMMENT '来源基础价值', + `quantity` int(11) NOT NULL DEFAULT 0 COMMENT '数量', + `commission_rate` decimal(5, 4) NOT NULL DEFAULT 0.0000 COMMENT '分成比例', + `revenue_amount` decimal(10, 2) NOT NULL DEFAULT 0.00 COMMENT '创作者实际收益金额', + `status` tinyint(4) NOT NULL DEFAULT 0 COMMENT '收益状态 (0待结算/1已结算)', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '收益产生时间', + `settled_at` datetime NULL DEFAULT NULL COMMENT '结算时间', + `is_deleted` tinyint(1) NOT NULL DEFAULT 0, + PRIMARY KEY (`id`) USING BTREE, + INDEX `idx_user_id`(`user_id`) USING BTREE, + INDEX `idx_content`(`content_type`, `content_id`) USING BTREE, + INDEX `idx_create_time`(`create_time`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for content_revenue_stage +-- ---------------------------- +DROP TABLE IF EXISTS `content_revenue_stage`; +CREATE TABLE `content_revenue_stage` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键', + `content_type` tinyint(4) NOT NULL COMMENT '内容类型 (1工作流/2视频)', + `content_id` bigint(20) NOT NULL COMMENT '内容ID', + `user_id` bigint(20) NOT NULL COMMENT '创作者ID', + `stage_level` int(11) NOT NULL COMMENT '阶段等级 (1,2,3...)', + `stage_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '阶段名称', + `target_count` int(11) NOT NULL COMMENT '目标数量 (复制次数/观看次数)', + `reward_amount` decimal(10, 2) NOT NULL COMMENT '奖励金额', + `current_count` int(11) NOT NULL DEFAULT 0 COMMENT '当前数量', + `is_achieved` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否已达到 (0未达到/1已达到)', + `achieved_at` datetime NULL DEFAULT NULL COMMENT '达到时间', + `is_withdrawn` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否已提现 (0未提现/1已提现)', + `withdrawn_at` datetime NULL DEFAULT NULL COMMENT '提现时间', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `is_deleted` tinyint(1) NOT NULL DEFAULT 0, + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `uk_content_stage`(`content_type`, `content_id`, `stage_level`) USING BTREE, + INDEX `idx_user_id`(`user_id`) USING BTREE, + INDEX `idx_content`(`content_type`, `content_id`) USING BTREE, + INDEX `idx_achieved`(`is_achieved`) USING BTREE, + INDEX `idx_withdrawn`(`is_withdrawn`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 58 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for course +-- ---------------------------- +DROP TABLE IF EXISTS `course`; +CREATE TABLE `course` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键', + `title` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '课程标题', + `description` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '课程的富文本描述', + `cover_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '封面图URL', + `detail_gallery` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '详情图集(JSON格式存储多张图片URL)', + `price` decimal(10, 2) NOT NULL DEFAULT 0.00 COMMENT '价格', + `level` tinyint(4) NOT NULL DEFAULT 0 COMMENT '访问课程所需的最低用户级别', + `audit_status` tinyint(4) NOT NULL DEFAULT 0 COMMENT '审核状态(0待审核/1通过/2拒绝)', + `category` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '课程分类', + `category_id` bigint(20) NULL DEFAULT NULL COMMENT '关联类目ID', + `reject_reason` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '拒绝原因', + `review_time` datetime NULL DEFAULT NULL COMMENT '审核时间', + `user_id` bigint(20) NULL DEFAULT NULL COMMENT '创建者ID', + `is_free` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否免费(0收费/1免费)', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `is_deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除标识', + PRIMARY KEY (`id`) USING BTREE, + INDEX `idx_course_category_id`(`category_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 37 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for course_chapter +-- ---------------------------- +DROP TABLE IF EXISTS `course_chapter`; +CREATE TABLE `course_chapter` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键', + `course_id` bigint(20) NOT NULL COMMENT '所属课程ID', + `title` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '章节标题', + `description` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '章节描述', + `order_num` int(11) NOT NULL DEFAULT 0 COMMENT '章节排序编号', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `is_deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除标识', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 40 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for course_favorite +-- ---------------------------- +DROP TABLE IF EXISTS `course_favorite`; +CREATE TABLE `course_favorite` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键', + `user_id` bigint(20) NOT NULL COMMENT '收藏用户ID', + `course_id` bigint(20) NOT NULL COMMENT '被收藏的课程ID', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '收藏时间', + `is_deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除标识', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `uk_user_course_favorite`(`user_id`, `course_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for course_like +-- ---------------------------- +DROP TABLE IF EXISTS `course_like`; +CREATE TABLE `course_like` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键', + `user_id` bigint(20) NOT NULL COMMENT '点赞用户ID', + `course_id` bigint(20) NOT NULL COMMENT '被点赞的课程ID', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '点赞时间', + `is_deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除标识', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `uk_user_course_like`(`user_id`, `course_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for course_video +-- ---------------------------- +DROP TABLE IF EXISTS `course_video`; +CREATE TABLE `course_video` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键', + `chapter_id` bigint(20) NOT NULL COMMENT '所属章节ID', + `title` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '视频标题', + `video_id` bigint(20) NULL DEFAULT NULL COMMENT '阿里云视频点播ID', + `duration_sec` int(11) NULL DEFAULT 0 COMMENT '视频时长(秒)', + `order_num` int(11) NOT NULL DEFAULT 0 COMMENT '视频在章节内的排序编号', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `is_deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除标识', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 40 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for fan_promotion_commission +-- ---------------------------- +DROP TABLE IF EXISTS `fan_promotion_commission`; +CREATE TABLE `fan_promotion_commission` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键', + `promoter_id` bigint(20) NOT NULL COMMENT '推广人ID', + `fan_id` bigint(20) NOT NULL COMMENT '粉丝用户ID', + `order_id` bigint(20) NOT NULL COMMENT '关联的订单ID', + `order_amount` decimal(10, 2) NOT NULL COMMENT '粉丝订单金额', + `commission_rate` decimal(5, 4) NOT NULL COMMENT '提成比例', + `commission_level` tinyint(4) NOT NULL COMMENT '提成发生时推广人的等级', + `commission_amount` decimal(10, 2) NOT NULL COMMENT '推广人实际提成金额', + `status` tinyint(4) NOT NULL DEFAULT 0 COMMENT '提成状态 (0待结算/1已结算)', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '提成产生时间', + `settled_at` datetime NULL DEFAULT NULL COMMENT '结算时间', + `is_deleted` tinyint(1) NOT NULL DEFAULT 0, + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `uk_promoter_fan`(`promoter_id`, `fan_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for gift_code +-- ---------------------------- +DROP TABLE IF EXISTS `gift_code`; +CREATE TABLE `gift_code` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键', + `code` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '礼品码,唯一', + `name` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '礼品码名称', + `description` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '礼品码描述', + `type` tinyint(4) NOT NULL COMMENT '礼品码类型 (1-积分卡/2-会员卡)', + `points` int(11) NULL DEFAULT NULL COMMENT '积分数量(积分卡类型)', + `points_expire_days` int(11) NULL DEFAULT NULL COMMENT '积分有效期天数(积分卡类型)', + `target_role` tinyint(4) NULL DEFAULT NULL COMMENT '目标角色等级(会员卡类型)', + `duration_days` int(11) NULL DEFAULT NULL COMMENT '会员有效期天数(会员卡类型)', + `total_count` int(11) NOT NULL DEFAULT 1 COMMENT '总可用次数', + `used_count` int(11) NOT NULL DEFAULT 0 COMMENT '已使用次数', + `is_active` tinyint(1) NOT NULL DEFAULT 1 COMMENT '是否启用', + `expire_time` datetime NULL DEFAULT NULL COMMENT '礼品码过期时间', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `is_deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除标识', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `code`(`code`) USING BTREE, + INDEX `idx_gift_code_code`(`code`) USING BTREE, + INDEX `idx_gift_code_type`(`type`) USING BTREE, + INDEX `idx_gift_code_active`(`is_active`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 69 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for gift_code_usage +-- ---------------------------- +DROP TABLE IF EXISTS `gift_code_usage`; +CREATE TABLE `gift_code_usage` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键', + `gift_code_id` bigint(20) NOT NULL COMMENT '礼品码ID', + `user_id` bigint(20) NOT NULL COMMENT '使用用户ID', + `code` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '使用的礼品码', + `type` tinyint(4) NOT NULL COMMENT '礼品码类型 (1-积分卡/2-会员卡)', + `points` int(11) NULL DEFAULT NULL COMMENT '积分数量', + `points_expire_days` int(11) NULL DEFAULT NULL COMMENT '积分有效期天数', + `target_role` tinyint(4) NULL DEFAULT NULL COMMENT '目标角色等级', + `duration_days` int(11) NULL DEFAULT NULL COMMENT '会员有效期天数', + `old_role` tinyint(4) NULL DEFAULT NULL COMMENT '用户原角色', + `new_role` tinyint(4) NULL DEFAULT NULL COMMENT '用户新角色', + `old_points` int(11) NULL DEFAULT NULL COMMENT '用户原积分', + `new_points` int(11) NULL DEFAULT NULL COMMENT '用户新积分', + `old_points_expires_at` datetime NULL DEFAULT NULL COMMENT '用户原积分过期时间', + `new_points_expires_at` datetime NULL DEFAULT NULL COMMENT '用户新积分过期时间', + `old_expires_at` datetime NULL DEFAULT NULL COMMENT '用户原会员到期时间', + `new_expires_at` datetime NULL DEFAULT NULL COMMENT '用户新会员到期时间', + `status` tinyint(4) NOT NULL DEFAULT 1 COMMENT '使用状态 (1-成功/0-失败)', + `error_message` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '错误信息', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '使用时间', + `is_deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除标识', + PRIMARY KEY (`id`) USING BTREE, + INDEX `idx_gift_code_usage_user`(`user_id`) USING BTREE, + INDEX `idx_gift_code_usage_code`(`gift_code_id`) USING BTREE, + INDEX `idx_gift_code_usage_time`(`create_time`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 83 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for membership_plan +-- ---------------------------- +DROP TABLE IF EXISTS `membership_plan`; +CREATE TABLE `membership_plan` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键', + `name` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '套餐名称', + `description` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '套餐的详细描述', + `price` decimal(10, 2) NOT NULL COMMENT '价格', + `duration_days` int(11) NOT NULL COMMENT '有效期天数', + `target_role` tinyint(4) NOT NULL COMMENT '购买后达到的角色等级', + `discount_percentage` decimal(5, 2) NULL DEFAULT 0.00 COMMENT '优惠百分比率(0-100,如10.50表示10.5%的优惠)', + `is_active` tinyint(1) NOT NULL DEFAULT 1 COMMENT '是否上架', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `is_deleted` tinyint(1) NOT NULL DEFAULT 0, + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for order +-- ---------------------------- +DROP TABLE IF EXISTS `order`; +CREATE TABLE `order` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键', + `order_no` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '系统生成的唯一订单号', + `order_type` tinyint(4) NOT NULL DEFAULT 1 COMMENT '订单类型(1-会员订单/2-积分订单)', + `user_id` bigint(20) NOT NULL COMMENT '购买用户ID', + `plan_id` bigint(20) NULL DEFAULT NULL COMMENT '购买的套餐ID', + `points_package_id` bigint(20) NULL DEFAULT NULL COMMENT '积分套餐ID(积分订单)', + `points_amount` int(11) NULL DEFAULT NULL COMMENT '积分数量(积分订单)', + `original_price` decimal(10, 2) NULL DEFAULT NULL COMMENT '套餐原价', + `amount` decimal(10, 2) NOT NULL COMMENT '订单最终金额(实际支付金额)', + `actual_duration_days` int(11) NULL DEFAULT NULL COMMENT '实际获得的会员天数', + `discount_type` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '优惠类型 (NONE/CONTINUOUS_MONTHLY/CONTINUOUS_YEARLY/FIRST_PURCHASE/SPECIAL_OFFER)', + `discount_amount` decimal(10, 2) NULL DEFAULT NULL COMMENT '优惠金额', + `discount_description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '优惠描述', + `status` tinyint(4) NOT NULL DEFAULT 0 COMMENT '订单状态 (0待支付/1已完成/2已取消/3支付失败)', + `payment_method` tinyint(4) NULL DEFAULT NULL COMMENT '支付方式 (1支付宝/2微信支付)', + `paid_at` datetime NULL DEFAULT NULL COMMENT '支付成功时间', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `is_deleted` tinyint(1) NOT NULL DEFAULT 0, + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `order_no`(`order_no`) USING BTREE, + INDEX `idx_order_discount_type`(`discount_type`) USING BTREE, + INDEX `idx_order_user_id_status`(`user_id`, `status`) USING BTREE, + INDEX `idx_order_type`(`order_type`) USING BTREE, + INDEX `idx_order_points_package`(`points_package_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 152 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for payment_transaction +-- ---------------------------- +DROP TABLE IF EXISTS `payment_transaction`; +CREATE TABLE `payment_transaction` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键', + `order_no` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '关联的系统订单号', + `transaction_no` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '第三方支付平台返回的流水号', + `payment_gateway` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '支付网关', + `amount` decimal(10, 2) NOT NULL COMMENT '支付金额', + `status` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '第三方支付平台返回的状态', + `raw_data` json NULL COMMENT '第三方支付平台通知的完整原始数据', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `is_deleted` tinyint(1) NOT NULL DEFAULT 0, + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for plaza_work +-- ---------------------------- +DROP TABLE IF EXISTS `plaza_work`; +CREATE TABLE `plaza_work` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `work_no` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '作品编号(唯一标识)', + `user_id` bigint(20) NOT NULL COMMENT '发布者用户ID', + `task_no` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '关联的任务编号', + `task_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '任务类型:text_to_image/image_to_image/text_to_video/image_to_video等', + `model_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '使用的模型名称', + `prompt` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '生成提示词', + `result_url` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '作品结果URL(图片或视频)', + `image_url` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '参考图URL(图生图/图生视频任务使用)', + `aspect_ratio` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '宽高比:1:1/2:3/3:2/9:16/16:9等', + `title` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '作品标题(可选)', + `description` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL COMMENT '作品描述(可选)', + `tags` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '标签(JSON数组字符串)', + `view_count` int(11) NULL DEFAULT 0 COMMENT '浏览次数', + `like_count` int(11) NULL DEFAULT 0 COMMENT '点赞数', + `share_count` int(11) NULL DEFAULT 0 COMMENT '分享数', + `comment_count` int(11) NULL DEFAULT 0 COMMENT '评论数(预留)', + `is_public` tinyint(1) NULL DEFAULT 1 COMMENT '是否公开:0-仅自己可见,1-公开', + `status` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT 'published' COMMENT '状态:draft-草稿,published-已发布,hidden-已隐藏', + `audit_status` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'pending' COMMENT '审核状态:pending-待审核, approved-已通过, rejected-已拒绝', + `audit_admin_id` bigint(20) NULL DEFAULT NULL COMMENT '审核管理员ID', + `audit_time` datetime NULL DEFAULT NULL COMMENT '审核时间', + `audit_remark` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL COMMENT '审核备注(拒绝原因等)', + `create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `is_deleted` tinyint(1) NULL DEFAULT 0 COMMENT '是否删除:0-未删除,1-已删除', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `uk_work_no`(`work_no`) USING BTREE, + INDEX `idx_user_id`(`user_id`) USING BTREE, + INDEX `idx_task_no`(`task_no`) USING BTREE, + INDEX `idx_task_type`(`task_type`) USING BTREE, + INDEX `idx_create_time`(`create_time`) USING BTREE, + INDEX `idx_like_count`(`like_count`) USING BTREE, + INDEX `idx_status_public`(`status`, `is_public`, `is_deleted`) USING BTREE, + INDEX `idx_type_like_time`(`task_type`, `like_count`, `create_time`) USING BTREE, + INDEX `idx_status_public_time`(`status`, `is_public`, `create_time`) USING BTREE, + INDEX `idx_audit_status`(`audit_status`) USING BTREE, + INDEX `idx_audit_time`(`audit_time`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 63 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '广场作品表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for plaza_work_audit_log +-- ---------------------------- +DROP TABLE IF EXISTS `plaza_work_audit_log`; +CREATE TABLE `plaza_work_audit_log` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `work_no` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '作品编号', + `work_id` bigint(20) NOT NULL COMMENT '作品ID', + `audit_status` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '审核结果:approved-通过, rejected-拒绝', + `audit_admin_id` bigint(20) NOT NULL COMMENT '审核管理员ID', + `audit_admin_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '审核管理员名称', + `audit_remark` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '审核备注', + `audit_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '审核时间', + PRIMARY KEY (`id`) USING BTREE, + INDEX `idx_work_no`(`work_no`) USING BTREE, + INDEX `idx_work_id`(`work_id`) USING BTREE, + INDEX `idx_audit_admin_id`(`audit_admin_id`) USING BTREE, + INDEX `idx_audit_time`(`audit_time`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 68 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '广场作品审核记录表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for plaza_work_like +-- ---------------------------- +DROP TABLE IF EXISTS `plaza_work_like`; +CREATE TABLE `plaza_work_like` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `work_id` bigint(20) NOT NULL COMMENT '作品ID', + `user_id` bigint(20) NOT NULL COMMENT '点赞用户ID', + `create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '点赞时间', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `uk_work_user`(`work_id`, `user_id`) USING BTREE, + INDEX `idx_user_id`(`user_id`) USING BTREE, + INDEX `idx_create_time`(`create_time`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 80 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '广场作品点赞表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for plaza_work_report +-- ---------------------------- +DROP TABLE IF EXISTS `plaza_work_report`; +CREATE TABLE `plaza_work_report` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `report_no` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '投诉编号(唯一标识)', + `work_id` bigint(20) NOT NULL COMMENT '被投诉的作品ID', + `work_no` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '被投诉的作品编号', + `reporter_id` bigint(20) NOT NULL COMMENT '投诉人用户ID', + `report_type` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '投诉类型:political-政治敏感,pornographic-色情低俗,violent-暴力血腥,dangerous-危险行为,uncomfortable-引人不适,other-其他', + `report_reason` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL COMMENT '投诉原因描述(可选)', + `report_status` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT 'pending' COMMENT '投诉状态:pending-待审核,approved-投诉成立,rejected-投诉不成立', + `audit_admin_id` bigint(20) NULL DEFAULT NULL COMMENT '审核管理员ID', + `audit_admin_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '审核管理员名称', + `audit_remark` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL COMMENT '审核备注(处理说明)', + `audit_time` datetime NULL DEFAULT NULL COMMENT '审核时间', + `create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '投诉时间', + `update_time` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `is_deleted` tinyint(1) NULL DEFAULT 0 COMMENT '是否删除:0-未删除,1-已删除', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `uk_report_no`(`report_no`) USING BTREE, + INDEX `idx_work_id`(`work_id`) USING BTREE, + INDEX `idx_work_no`(`work_no`) USING BTREE, + INDEX `idx_reporter_id`(`reporter_id`) USING BTREE, + INDEX `idx_report_type`(`report_type`) USING BTREE, + INDEX `idx_report_status`(`report_status`) USING BTREE, + INDEX `idx_audit_admin_id`(`audit_admin_id`) USING BTREE, + INDEX `idx_create_time`(`create_time`) USING BTREE, + INDEX `idx_work_reporter`(`work_id`, `reporter_id`, `is_deleted`) USING BTREE, + INDEX `idx_status_time`(`report_status`, `create_time`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '广场作品投诉表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for plaza_work_report_limit +-- ---------------------------- +DROP TABLE IF EXISTS `plaza_work_report_limit`; +CREATE TABLE `plaza_work_report_limit` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `user_id` bigint(20) NOT NULL COMMENT '用户ID', + `report_count` int(11) NULL DEFAULT 0 COMMENT '今日投诉次数', + `last_report_time` datetime NULL DEFAULT NULL COMMENT '最后投诉时间', + `reset_date` date NOT NULL COMMENT '重置日期(用于每日重置计数)', + `create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `uk_user_id`(`user_id`) USING BTREE, + INDEX `idx_reset_date`(`reset_date`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '广场作品投诉限制表(防止恶意投诉)' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for plaza_work_view +-- ---------------------------- +DROP TABLE IF EXISTS `plaza_work_view`; +CREATE TABLE `plaza_work_view` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `work_id` bigint(20) NOT NULL COMMENT '作品ID', + `user_id` bigint(20) NULL DEFAULT NULL COMMENT '浏览用户ID(可为空,支持匿名浏览)', + `ip_address` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT 'IP地址', + `user_agent` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '用户代理', + `view_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '浏览时间', + PRIMARY KEY (`id`) USING BTREE, + INDEX `idx_work_id`(`work_id`) USING BTREE, + INDEX `idx_user_id`(`user_id`) USING BTREE, + INDEX `idx_view_time`(`view_time`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '广场作品浏览记录表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for points_config +-- ---------------------------- +DROP TABLE IF EXISTS `points_config`; +CREATE TABLE `points_config` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键', + `model_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '模型名称 (如: sora_image)', + `model_category` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'text' COMMENT '模型类别:text(文本), image(图片), video(视频), audio(音频)', + `points_cost` int(11) NOT NULL COMMENT '调用一次消耗的积分', + `description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '模型描述', + `is_enabled` tinyint(1) NOT NULL DEFAULT 1 COMMENT '是否启用 (0:禁用, 1:启用)', + `provider_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'openai' COMMENT 'AI服务提供商类型:openai, ', + `provider_config` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '服务商特定配置(JSON格式)', + `task_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '任务类型:text_to_image(文生图)/image_to_image(图生图)/text_to_video(文生视频)/image_to_video(图生视频)/llm(大语言模型)/text_to_audio(文生音频)/image_to_text(图生文)/other(其他)', + `sort_order` int(11) NULL DEFAULT 0 COMMENT '排序顺序(用于前端展示)', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后更新时间', + `is_deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除标识', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `model_name`(`model_name`) USING BTREE, + INDEX `idx_points_config_task_type`(`task_type`) USING BTREE, + INDEX `idx_points_config_provider_task`(`provider_type`, `task_type`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 116 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '积分消费配置表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for points_consumption_log +-- ---------------------------- +DROP TABLE IF EXISTS `points_consumption_log`; +CREATE TABLE `points_consumption_log` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键', + `user_id` bigint(20) NOT NULL COMMENT '关联的用户ID', + `task_no` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '关联的AI任务编号', + `change_type` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '变动类型 (recharge:充值, consume:消费, refund:退款, expire:过期, admin_adjust:管理员调整)', + `change_amount` int(11) NOT NULL COMMENT '变动积分数量 (正数表示增加,负数表示减少)', + `balance_before` int(11) NOT NULL COMMENT '变动前积分余额', + `balance_after` int(11) NOT NULL COMMENT '变动后积分余额', + `description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '变动描述', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '记录创建时间', + `is_deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除标识', + PRIMARY KEY (`id`) USING BTREE, + INDEX `idx_user_id_type`(`user_id`, `change_type`) USING BTREE, + CONSTRAINT `points_consumption_log_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE RESTRICT +) ENGINE = InnoDB AUTO_INCREMENT = 2534 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '积分消费记录表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for points_package +-- ---------------------------- +DROP TABLE IF EXISTS `points_package`; +CREATE TABLE `points_package` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键', + `name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '套餐名称', + `description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '套餐描述', + `points` int(11) NOT NULL COMMENT '基础积分数量', + `bonus_points` int(11) NOT NULL DEFAULT 0 COMMENT '赠送积分数量', + `total_points` int(11) NOT NULL COMMENT '总积分(基础+赠送)', + `price` decimal(10, 2) NOT NULL COMMENT '价格(元)', + `original_price` decimal(10, 2) NULL DEFAULT NULL COMMENT '原价(用于显示优惠)', + `points_expire_days` int(11) NOT NULL DEFAULT 365 COMMENT '积分有效期(天)', + `discount_label` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '优惠标签(如:首充特惠、限时优惠)', + `sort_order` int(11) NOT NULL DEFAULT 0 COMMENT '排序(数字越小越靠前)', + `is_hot` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否热门推荐', + `is_active` tinyint(1) NOT NULL DEFAULT 1 COMMENT '是否上架', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `is_deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除标识', + PRIMARY KEY (`id`) USING BTREE, + INDEX `idx_points_package_active`(`is_active`) USING BTREE, + INDEX `idx_points_package_sort`(`sort_order`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 13 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '积分套餐表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for promotion_level_config +-- ---------------------------- +DROP TABLE IF EXISTS `promotion_level_config`; +CREATE TABLE `promotion_level_config` ( + `id` tinyint(4) NOT NULL AUTO_INCREMENT COMMENT '等级ID', + `level_name` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '等级名称', + `min_paid_fans` int(11) NOT NULL COMMENT '达到该等级所需的最低付费粉丝数量', + `commission_rate` decimal(5, 4) NOT NULL COMMENT '该等级对应的基础提成比例', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `is_deleted` tinyint(1) NOT NULL DEFAULT 0, + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for promotion_poster +-- ---------------------------- +DROP TABLE IF EXISTS `promotion_poster`; +CREATE TABLE `promotion_poster` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键', + `title` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '海报标题', + `description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '海报描述', + `image_url` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '海报图片URL', + `sort_order` int(11) NOT NULL DEFAULT 0 COMMENT '排序字段', + `is_enabled` tinyint(1) NOT NULL DEFAULT 1 COMMENT '是否启用(0禁用/1启用)', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `is_deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除标识', + PRIMARY KEY (`id`) USING BTREE, + INDEX `idx_promotion_poster_enabled`(`is_enabled`) USING BTREE, + INDEX `idx_promotion_poster_sort`(`sort_order`) USING BTREE, + INDEX `idx_promotion_poster_create_time`(`create_time`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for revenue_config +-- ---------------------------- +DROP TABLE IF EXISTS `revenue_config`; +CREATE TABLE `revenue_config` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键', + `config_key` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '配置键', + `config_type` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '配置类型(video/workflow/promotion)', + `target_count` int(11) NULL DEFAULT NULL COMMENT '目标次数(视频播放次数/工作流复制次数)', + `reward_amount` decimal(10, 2) NULL DEFAULT NULL COMMENT '奖励金额', + `level` int(11) NULL DEFAULT NULL COMMENT '推广等级', + `level_name` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '推广等级名称', + `min_fans` int(11) NULL DEFAULT NULL COMMENT '最小粉丝数', + `commission_rate` decimal(5, 4) NULL DEFAULT NULL COMMENT '提成比例', + `config_value` decimal(10, 4) NULL DEFAULT NULL COMMENT '配置值', + `description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '配置说明', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `is_deleted` tinyint(1) NOT NULL DEFAULT 0, + PRIMARY KEY (`id`) USING BTREE, + INDEX `idx_revenue_config_type`(`config_type`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 8 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for system_config +-- ---------------------------- +DROP TABLE IF EXISTS `system_config`; +CREATE TABLE `system_config` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键', + `config_key` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '配置键 (如: ai.queue.max_concurrent)', + `config_value` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '配置值', + `description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '配置说明', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后更新时间', + `is_deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除标识', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `config_key`(`config_key`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 13 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '系统配置表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for system_message +-- ---------------------------- +DROP TABLE IF EXISTS `system_message`; +CREATE TABLE `system_message` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键', + `user_id` bigint(20) NOT NULL COMMENT '接收用户ID', + `title` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '消息标题', + `content` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '消息内容', + `is_read` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否已读', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `is_deleted` tinyint(1) NOT NULL DEFAULT 0, + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for user +-- ---------------------------- +DROP TABLE IF EXISTS `user`; +CREATE TABLE `user` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键', + `phone` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '手机号,唯一(微信登录用户可为空)', + `wechat_openid` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '微信openid,用于微信登录', + `username` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '用户名,唯一', + `real_username` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '真实用户名', + `id_number` varchar(18) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '身份证号码', + `password_jwt` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'JWT加密密码(微信登录用户可为空)', + `role` tinyint(4) NOT NULL DEFAULT 1 COMMENT '角色(0游客/1普通/2VIP/3SVIP)', + `membership_expires_at` datetime NULL DEFAULT NULL COMMENT '会员到期时间', + `avatar_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '头像URL', + `is_verified` tinyint(4) NOT NULL DEFAULT 0 COMMENT '是否实名认证 (0-未认证, 1-已认证)', + `invite_code` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '推广码', + `inviter_id` bigint(20) NULL DEFAULT NULL COMMENT '邀请人ID', + `promotion_level` tinyint(4) NOT NULL DEFAULT 0 COMMENT '推广等级', + `points` int(11) NOT NULL DEFAULT 0 COMMENT '积分余额', + `points_expires_at` datetime NULL DEFAULT NULL COMMENT '积分过期时间', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '注册时间', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `is_deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除标识', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `username`(`username`) USING BTREE, + UNIQUE INDEX `phone`(`phone`) USING BTREE, + UNIQUE INDEX `invite_code`(`invite_code`) USING BTREE, + UNIQUE INDEX `uk_user_wechat_openid`(`wechat_openid`) USING BTREE, + INDEX `idx_user_wechat_openid`(`wechat_openid`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 17650006271322432 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for user_balance +-- ---------------------------- +DROP TABLE IF EXISTS `user_balance`; +CREATE TABLE `user_balance` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键', + `user_id` bigint(20) NOT NULL COMMENT '用户ID', + `balance` decimal(10, 2) NOT NULL DEFAULT 0.00 COMMENT '当前余额', + `total_income` decimal(10, 2) NOT NULL DEFAULT 0.00 COMMENT '累计总收入', + `total_withdrawn` decimal(10, 2) NOT NULL DEFAULT 0.00 COMMENT '累计提现总额', + `frozen_amount` decimal(10, 2) NOT NULL DEFAULT 0.00 COMMENT '冻结金额(提现中)', + `last_updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '最后更新时间', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `is_deleted` tinyint(1) NOT NULL DEFAULT 0, + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `uk_user_balance`(`user_id`) USING BTREE, + INDEX `idx_user_balance_user_id`(`user_id`) USING BTREE, + INDEX `idx_user_balance_balance`(`balance`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 78 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for user_balance_log +-- ---------------------------- +DROP TABLE IF EXISTS `user_balance_log`; +CREATE TABLE `user_balance_log` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键', + `user_id` bigint(20) NOT NULL COMMENT '用户ID', + `change_type` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '变动类型(income/withdraw/freeze/unfreeze)', + `change_amount` decimal(10, 2) NOT NULL COMMENT '变动金额(正数为增加,负数为减少)', + `balance_before` decimal(10, 2) NOT NULL COMMENT '变动前余额', + `balance_after` decimal(10, 2) NOT NULL COMMENT '变动后余额', + `source_type` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '来源类型(promotion/workflow/video/withdraw)', + `source_id` bigint(20) NULL DEFAULT NULL COMMENT '来源ID(订单ID、提现ID等)', + `description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '变动描述', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `is_deleted` tinyint(1) NOT NULL DEFAULT 0, + PRIMARY KEY (`id`) USING BTREE, + INDEX `idx_user_balance_log_user_id`(`user_id`) USING BTREE, + INDEX `idx_user_balance_log_change_type`(`change_type`) USING BTREE, + INDEX `idx_user_balance_log_create_time`(`create_time`) USING BTREE, + INDEX `idx_user_balance_log_source`(`source_type`, `source_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 78 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for user_video_progress +-- ---------------------------- +DROP TABLE IF EXISTS `user_video_progress`; +CREATE TABLE `user_video_progress` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键', + `user_id` bigint(20) NOT NULL, + `course_id` bigint(20) NOT NULL, + `chapter_id` bigint(20) NOT NULL, + `video_id` bigint(20) NOT NULL, + `progress_sec` int(11) NOT NULL DEFAULT 0 COMMENT '已观看秒数', + `progress_pct` float NOT NULL DEFAULT 0 COMMENT '进度百分比', + `last_watch_at` datetime NULL DEFAULT NULL COMMENT '最后观看时间', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `is_deleted` tinyint(1) NOT NULL DEFAULT 0, + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for video +-- ---------------------------- +DROP TABLE IF EXISTS `video`; +CREATE TABLE `video` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键', + `title` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '视频标题', + `description` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '视频描述', + `owner_id` bigint(20) NOT NULL COMMENT '创建者ID', + `cover_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '封面图片URL', + `vod_video_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '阿里云VOD视频ID', + `duration` int(11) NULL DEFAULT NULL COMMENT '视频时长(秒)', + `view_count` int(11) NOT NULL DEFAULT 0 COMMENT '观看次数', + `like_count` int(11) NOT NULL DEFAULT 0 COMMENT '点赞数量', + `is_public` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否公开', + `audit_status` tinyint(4) NOT NULL DEFAULT 0 COMMENT '审核状态(0待审核/1通过/2拒绝)', + `category` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '视频分类', + `reject_reason` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '拒绝原因', + `review_time` datetime NULL DEFAULT NULL COMMENT '审核时间', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `is_deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除标识', + PRIMARY KEY (`id`) USING BTREE, + INDEX `idx_owner_id`(`owner_id`) USING BTREE, + INDEX `idx_category`(`category`) USING BTREE, + INDEX `idx_audit_status`(`audit_status`) USING BTREE, + INDEX `idx_vod_video_id`(`vod_video_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 144 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for video_view_stat +-- ---------------------------- +DROP TABLE IF EXISTS `video_view_stat`; +CREATE TABLE `video_view_stat` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键', + `video_id` bigint(20) NOT NULL COMMENT '视频ID', + `owner_id` bigint(20) NOT NULL COMMENT '视频创建者ID', + `view_user_id` bigint(20) NOT NULL COMMENT '观看用户ID', + `view_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '观看时间', + `view_duration` int(11) NULL DEFAULT 0 COMMENT '观看时长(秒)', + `is_deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除标识', + PRIMARY KEY (`id`) USING BTREE, + INDEX `idx_video_owner`(`owner_id`) USING BTREE, + INDEX `idx_video_id`(`video_id`) USING BTREE, + INDEX `idx_view_time`(`view_time`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 156 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for wechat_keyword_reply +-- ---------------------------- +DROP TABLE IF EXISTS `wechat_keyword_reply`; +CREATE TABLE `wechat_keyword_reply` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '关键词回复ID', + `keyword` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '关键词', + `match_type` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT 'exact' COMMENT '匹配类型:exact-精确匹配,fuzzy-模糊匹配,regex-正则匹配', + `template_id` bigint(20) NOT NULL COMMENT '关联的消息模板ID', + `is_enabled` tinyint(4) NULL DEFAULT 1 COMMENT '是否启用:0-禁用,1-启用', + `priority` int(11) NULL DEFAULT 0 COMMENT '优先级,数字越大优先级越高', + `create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + PRIMARY KEY (`id`) USING BTREE, + INDEX `idx_keyword`(`keyword`) USING BTREE, + INDEX `idx_match_type`(`match_type`) USING BTREE, + INDEX `idx_template_id`(`template_id`) USING BTREE, + INDEX `idx_enabled`(`is_enabled`) USING BTREE, + INDEX `idx_priority`(`priority`) USING BTREE, + CONSTRAINT `wechat_keyword_reply_ibfk_1` FOREIGN KEY (`template_id`) REFERENCES `wechat_message_template` (`id`) ON DELETE CASCADE ON UPDATE RESTRICT +) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '微信关键词回复配置表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for wechat_menu +-- ---------------------------- +DROP TABLE IF EXISTS `wechat_menu`; +CREATE TABLE `wechat_menu` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '菜单ID', + `parent_id` bigint(20) NULL DEFAULT 0 COMMENT '父菜单ID,0表示顶级菜单', + `menu_name` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '菜单名称,最多16个字符', + `menu_type` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '菜单类型:click/view/miniprogram/scancode_push/scancode_waitmsg/pic_sysphoto/pic_photo_or_album/pic_weixin/location_select', + `menu_key` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '菜单KEY值,click类型必须', + `menu_url` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '网页链接,view类型必须', + `media_id` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '媒体文件ID', + `appid` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '小程序appid,miniprogram类型必须', + `pagepath` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '小程序页面路径,miniprogram类型必须', + `sort_order` int(11) NULL DEFAULT 0 COMMENT '排序顺序', + `is_enabled` tinyint(4) NULL DEFAULT 1 COMMENT '是否启用:0-禁用,1-启用', + `description` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '菜单描述', + `create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + PRIMARY KEY (`id`) USING BTREE, + INDEX `idx_parent_id`(`parent_id`) USING BTREE, + INDEX `idx_sort_order`(`sort_order`) USING BTREE, + INDEX `idx_menu_key`(`menu_key`) USING BTREE, + INDEX `idx_enabled`(`is_enabled`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 10 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '微信菜单配置表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for wechat_menu_publish_history +-- ---------------------------- +DROP TABLE IF EXISTS `wechat_menu_publish_history`; +CREATE TABLE `wechat_menu_publish_history` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '发布历史ID', + `menu_config` json NOT NULL COMMENT '菜单配置JSON', + `publish_status` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '发布状态:success/failed', + `error_message` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '错误信息', + `publish_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '发布时间', + `operator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '操作人', + PRIMARY KEY (`id`) USING BTREE, + INDEX `idx_publish_status`(`publish_status`) USING BTREE, + INDEX `idx_publish_time`(`publish_time`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '微信菜单发布历史表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for wechat_message_template +-- ---------------------------- +DROP TABLE IF EXISTS `wechat_message_template`; +CREATE TABLE `wechat_message_template` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '模板ID', + `template_key` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '模板标识键', + `template_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '模板名称', + `template_type` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '模板类型:text/news/image/voice/video/music', + `trigger_type` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '触发类型:subscribe/unsubscribe/scan/click/view/keyword', + `trigger_value` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '触发值(如菜单key、关键词等)', + `content` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '文本内容', + `media_id` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '媒体文件ID', + `title` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '标题(图文消息用)', + `description` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '描述(图文消息用)', + `pic_url` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '图片链接', + `url` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '跳转链接', + `music_url` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '音乐链接', + `hq_music_url` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '高质量音乐链接', + `thumb_media_id` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '缩略图媒体ID', + `is_enabled` tinyint(4) NULL DEFAULT 1 COMMENT '是否启用:0-禁用,1-启用', + `priority` int(11) NULL DEFAULT 0 COMMENT '优先级,数字越大优先级越高', + `create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `template_key`(`template_key`) USING BTREE, + INDEX `idx_template_key`(`template_key`) USING BTREE, + INDEX `idx_trigger_type`(`trigger_type`) USING BTREE, + INDEX `idx_trigger_value`(`trigger_value`) USING BTREE, + INDEX `idx_enabled`(`is_enabled`) USING BTREE, + INDEX `idx_priority`(`priority`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 9 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '微信消息模板配置表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for wechat_news_article +-- ---------------------------- +DROP TABLE IF EXISTS `wechat_news_article`; +CREATE TABLE `wechat_news_article` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '文章ID', + `template_id` bigint(20) NOT NULL COMMENT '关联的消息模板ID', + `title` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '文章标题', + `author` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '作者', + `digest` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '摘要', + `content` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '文章内容', + `content_source_url` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '原文链接', + `thumb_media_id` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '缩略图媒体ID', + `show_cover_pic` tinyint(4) NULL DEFAULT 0 COMMENT '是否显示封面:0-不显示,1-显示', + `url` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '点击跳转链接', + `thumb_url` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '缩略图URL', + `need_open_comment` tinyint(4) NULL DEFAULT 0 COMMENT '是否打开评论:0-不打开,1-打开', + `only_fans_can_comment` tinyint(4) NULL DEFAULT 0 COMMENT '是否粉丝才可评论:0-所有人,1-仅粉丝', + `sort_order` int(11) NULL DEFAULT 0 COMMENT '排序顺序', + `create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + PRIMARY KEY (`id`) USING BTREE, + INDEX `idx_template_id`(`template_id`) USING BTREE, + INDEX `idx_sort_order`(`sort_order`) USING BTREE, + CONSTRAINT `wechat_news_article_ibfk_1` FOREIGN KEY (`template_id`) REFERENCES `wechat_message_template` (`id`) ON DELETE CASCADE ON UPDATE RESTRICT +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '微信图文消息文章表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for wechat_qr_code +-- ---------------------------- +DROP TABLE IF EXISTS `wechat_qr_code`; +CREATE TABLE `wechat_qr_code` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键', + `qr_code_url` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '二维码图片URL', + `description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '二维码描述', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `is_deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除标识', + PRIMARY KEY (`id`) USING BTREE, + INDEX `idx_wechat_qr_create_time`(`create_time`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for withdraw_request +-- ---------------------------- +DROP TABLE IF EXISTS `withdraw_request`; +CREATE TABLE `withdraw_request` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键', + `user_id` bigint(20) NOT NULL COMMENT '用户ID', + `amount` decimal(10, 2) NOT NULL COMMENT '提现金额', + `withdraw_type` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '提现类型(promotion/workflow/video)', + `content_id` bigint(20) NULL DEFAULT NULL COMMENT '作品ID(工作流或视频提现时)', + `account_type` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '收款账户类型(alipay/wechat/bank)', + `account` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '收款账户(支付宝账号/微信ID/银行卡号)', + `account_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '收款人姓名', + `bank_name` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '开户行名称(银行卡提现时必填)', + `bank_branch` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '支行名称(银行卡提现时可选)', + `status` tinyint(4) NOT NULL DEFAULT 0 COMMENT '状态(0待审核/1通过/2拒绝)', + `reason` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '拒绝原因', + `reviewer_id` bigint(20) NULL DEFAULT NULL COMMENT '审核人ID', + `transaction_no` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '第三方交易流水号', + `fee_amount` decimal(10, 2) NULL DEFAULT 0.00 COMMENT '手续费金额', + `actual_amount` decimal(10, 2) NULL DEFAULT NULL COMMENT '实际到账金额', + `processed_at` datetime NULL DEFAULT NULL COMMENT '处理完成时间', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '申请时间', + `reviewed_at` datetime NULL DEFAULT NULL COMMENT '审核时间', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `is_deleted` tinyint(1) NOT NULL DEFAULT 0, + PRIMARY KEY (`id`) USING BTREE, + INDEX `idx_withdraw_user_id`(`user_id`) USING BTREE, + INDEX `idx_withdraw_status`(`status`) USING BTREE, + INDEX `idx_withdraw_create_time`(`create_time`) USING BTREE, + INDEX `idx_withdraw_type`(`withdraw_type`) USING BTREE, + INDEX `idx_withdraw_content_id`(`content_id`) USING BTREE, + INDEX `idx_withdraw_reviewer`(`reviewer_id`) USING BTREE, + INDEX `idx_withdraw_transaction_no`(`transaction_no`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for workflow +-- ---------------------------- +DROP TABLE IF EXISTS `workflow`; +CREATE TABLE `workflow` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键', + `name` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '工作流名称', + `description` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '工作流的详细描述', + `owner_id` bigint(20) NOT NULL COMMENT '创建者ID', + `cover_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '封面图片URL', + `detail_gallery` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '详情图集(JSON格式存储多张图片URL)', + `video_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '关联预览视频ID(阿里云VOD视频ID)', + `data` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '存储工作流核心逻辑的JSON字符串', + `data_file_url` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '工作流依赖文件地址(文件上传时的URL)', + `like_count` int(11) NOT NULL DEFAULT 0 COMMENT '点赞数量', + `is_public` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否公开', + `full_access_role` tinyint(4) NOT NULL DEFAULT 1 COMMENT '查看完整data所需最低角色', + `copy_access_role` tinyint(4) NOT NULL DEFAULT 1 COMMENT '复制所需最低角色', + `price` decimal(10, 2) NOT NULL DEFAULT 0.00 COMMENT '价格', + `audit_status` tinyint(4) NOT NULL DEFAULT 0 COMMENT '审核状态(0待审核/1通过/2拒绝)', + `category` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '工作流分类', + `category_id` bigint(20) NULL DEFAULT NULL COMMENT '关联类目ID', + `rating` int(11) NULL DEFAULT NULL COMMENT '评分(1-5)', + `reject_reason` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '拒绝原因', + `review_time` datetime NULL DEFAULT NULL COMMENT '审核时间', + `is_free` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否免费(0收费/1免费)', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `is_deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除标识', + PRIMARY KEY (`id`) USING BTREE, + INDEX `idx_workflow_category_id`(`category_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 105 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for workflow_copy_stat +-- ---------------------------- +DROP TABLE IF EXISTS `workflow_copy_stat`; +CREATE TABLE `workflow_copy_stat` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键', + `workflow_id` bigint(20) NOT NULL COMMENT '工作流ID', + `owner_id` bigint(20) NOT NULL COMMENT '工作流创建者ID', + `copy_user_id` bigint(20) NOT NULL COMMENT '复制用户ID', + `copy_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '复制时间', + `is_deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除标识', + PRIMARY KEY (`id`) USING BTREE, + INDEX `idx_workflow_owner`(`owner_id`) USING BTREE, + INDEX `idx_workflow_id`(`workflow_id`) USING BTREE, + INDEX `idx_copy_time`(`copy_time`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 1620 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for workflow_like +-- ---------------------------- +DROP TABLE IF EXISTS `workflow_like`; +CREATE TABLE `workflow_like` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键', + `user_id` bigint(20) NOT NULL COMMENT '点赞用户ID', + `workflow_id` bigint(20) NOT NULL COMMENT '被点赞的工作流ID', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '点赞时间', + `is_deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除标识', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `uk_user_workflow`(`user_id`, `workflow_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 30 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- View structure for v_plaza_latest_works +-- ---------------------------- +DROP VIEW IF EXISTS `v_plaza_latest_works`; +CREATE ALGORITHM = UNDEFINED SQL SECURITY DEFINER VIEW `v_plaza_latest_works` AS select `pw`.`id` AS `id`,`pw`.`work_no` AS `work_no`,`pw`.`user_id` AS `user_id`,`pw`.`task_no` AS `task_no`,`pw`.`task_type` AS `task_type`,`pw`.`model_name` AS `model_name`,`pw`.`prompt` AS `prompt`,`pw`.`result_url` AS `result_url`,`pw`.`image_url` AS `image_url`,`pw`.`aspect_ratio` AS `aspect_ratio`,`pw`.`title` AS `title`,`pw`.`description` AS `description`,`pw`.`tags` AS `tags`,`pw`.`view_count` AS `view_count`,`pw`.`like_count` AS `like_count`,`pw`.`share_count` AS `share_count`,`pw`.`comment_count` AS `comment_count`,`pw`.`is_public` AS `is_public`,`pw`.`status` AS `status`,`pw`.`audit_status` AS `audit_status`,`pw`.`audit_admin_id` AS `audit_admin_id`,`pw`.`audit_time` AS `audit_time`,`pw`.`audit_remark` AS `audit_remark`,`pw`.`create_time` AS `create_time`,`pw`.`update_time` AS `update_time`,`pw`.`is_deleted` AS `is_deleted` from `plaza_work` `pw` where ((`pw`.`status` = 'published') and (`pw`.`audit_status` = 'approved') and (`pw`.`is_deleted` = 0)) order by `pw`.`create_time` desc; + +-- ---------------------------- +-- View structure for v_plaza_pending_works +-- ---------------------------- +DROP VIEW IF EXISTS `v_plaza_pending_works`; +CREATE ALGORITHM = UNDEFINED SQL SECURITY DEFINER VIEW `v_plaza_pending_works` AS select `pw`.`id` AS `id`,`pw`.`work_no` AS `work_no`,`pw`.`user_id` AS `user_id`,`pw`.`task_no` AS `task_no`,`pw`.`task_type` AS `task_type`,`pw`.`model_name` AS `model_name`,`pw`.`prompt` AS `prompt`,`pw`.`result_url` AS `result_url`,`pw`.`image_url` AS `image_url`,`pw`.`aspect_ratio` AS `aspect_ratio`,`pw`.`title` AS `title`,`pw`.`description` AS `description`,`pw`.`tags` AS `tags`,`pw`.`view_count` AS `view_count`,`pw`.`like_count` AS `like_count`,`pw`.`share_count` AS `share_count`,`pw`.`comment_count` AS `comment_count`,`pw`.`is_public` AS `is_public`,`pw`.`status` AS `status`,`pw`.`audit_status` AS `audit_status`,`pw`.`audit_admin_id` AS `audit_admin_id`,`pw`.`audit_time` AS `audit_time`,`pw`.`audit_remark` AS `audit_remark`,`pw`.`create_time` AS `create_time`,`pw`.`update_time` AS `update_time`,`pw`.`is_deleted` AS `is_deleted`,`u`.`username` AS `author_name`,`u`.`phone` AS `author_phone` from (`plaza_work` `pw` left join `user` `u` on((`pw`.`user_id` = `u`.`id`))) where ((`pw`.`audit_status` = 'pending') and (`pw`.`is_deleted` = 0)) order by `pw`.`create_time`; + +-- ---------------------------- +-- View structure for v_points_recharge_stats +-- ---------------------------- +DROP VIEW IF EXISTS `v_points_recharge_stats`; +CREATE ALGORITHM = UNDEFINED SQL SECURITY DEFINER VIEW `v_points_recharge_stats` AS select cast(`o`.`create_time` as date) AS `recharge_date`,count(`o`.`id`) AS `order_count`,sum(`o`.`amount`) AS `total_amount`,sum(`o`.`points_amount`) AS `total_points`,avg(`o`.`amount`) AS `avg_amount` from `order` `o` where ((`o`.`order_type` = 2) and (`o`.`status` = 1) and (`o`.`is_deleted` = 0)) group by cast(`o`.`create_time` as date) order by `recharge_date` desc; + +SET FOREIGN_KEY_CHECKS = 1; diff --git a/ADMIN_AI_POINTS_API_GUIDE.md b/ADMIN_AI_POINTS_API_GUIDE.md deleted file mode 100644 index 2ee2f6b..0000000 --- a/ADMIN_AI_POINTS_API_GUIDE.md +++ /dev/null @@ -1,587 +0,0 @@ -# 管理端 - AI积分与模型配置 API 接口文档 - -## 📋 目录 - -1. [概述](#概述) -2. [认证说明](#认证说明) -3. [积分配置管理](#积分配置管理) -4. [系统配置管理](#系统配置管理) -5. [AI任务监控](#ai任务监控) -6. [业务流程说明](#业务流程说明) -7. [常见问题](#常见问题) - ---- - -## 概述 - -本文档描述了管理员如何通过后台接口管理AI模型的积分价格、系统参数配置以及监控所有用户的AI任务。 - -### 基础信息 - -- **Base URL**: `https://your-domain.com` -- **接口前缀**: `/admin` -- **认证方式**: JWT Token (需要 ADMIN 角色) -- **数据格式**: JSON - -### 积分与人民币兑换标准 - -根据系统设计,积分兑换标准如下: - -``` -1 元人民币 = 100 积分 -``` - -**定价策略:** 在第三方API成本的基础上加价 50% - ---- - -## 认证说明 - -### 获取管理员Token - -**接口**: `POST /admin/auth/login` - -**请求示例**: -```json -{ - "username": "admin", - "password": "your_password" -} -``` - -**响应示例**: -```json -{ - "code": 200, - "message": "登录成功", - "data": { - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", - "userId": 1, - "username": "admin", - "role": 1 - } -} -``` - -### 后续请求认证 - -所有管理端API请求都需要在HTTP Header中携带Token: - -``` -Authorization: Bearer -``` - ---- - -## 积分配置管理 - -管理员可以动态调整每个AI模型的积分消费价格。 - -### 1. 获取所有积分配置 - -**接口**: `GET /admin/configs/points` - -**描述**: 获取所有AI模型的积分配置列表 - -**请求示例**: -```bash -curl -X GET "https://your-domain.com/admin/configs/points" \ - -H "Authorization: Bearer " -``` - -**响应示例**: -```json -{ - "code": 200, - "message": "查询成功", - "data": [ - { - "id": 1, - "modelName": "sora_image", - "pointsCost": 11, - "description": "Sora高质量图片生成", - "isEnabled": 1, - "createTime": "2025-10-19T10:00:00", - "updateTime": "2025-10-19T10:00:00" - }, - { - "id": 2, - "modelName": "sora_video2", - "pointsCost": 160, - "description": "Sora视频生成 (竖屏10秒)", - "isEnabled": 1, - "createTime": "2025-10-19T10:00:00", - "updateTime": "2025-10-19T10:00:00" - } - ] -} -``` - -### 2. 创建新的积分配置 - -**接口**: `POST /admin/configs/points` - -**描述**: 为新的AI模型添加积分配置 - -**请求示例**: -```json -{ - "modelName": "dalle-3", - "pointsCost": 50, - "description": "DALL-E 3图片生成", - "isEnabled": 1 -} -``` - -**字段说明**: -- `modelName` (必填): 模型唯一标识,需与第三方API的模型名称一致 -- `pointsCost` (必填): 调用一次该模型需要消耗的积分数 -- `description` (可选): 模型的描述信息 -- `isEnabled` (必填): 是否启用 (1=启用, 0=禁用) - -**响应示例**: -```json -{ - "code": 200, - "message": "配置创建成功", - "data": { - "id": 8, - "modelName": "dalle-3", - "pointsCost": 50, - "description": "DALL-E 3图片生成", - "isEnabled": 1 - } -} -``` - -### 3. 更新积分配置 - -**接口**: `PUT /admin/configs/points/{id}` - -**描述**: 修改现有模型的积分价格或其他配置 - -**请求示例**: -```bash -curl -X PUT "https://your-domain.com/admin/configs/points/1" \ - -H "Authorization: Bearer " \ - -H "Content-Type: application/json" \ - -d '{ - "pointsCost": 15, - "description": "Sora高质量图片生成(已调价)", - "isEnabled": 1 - }' -``` - -**响应示例**: -```json -{ - "code": 200, - "message": "配置更新成功", - "data": { - "id": 1, - "modelName": "sora_image", - "pointsCost": 15, - "description": "Sora高质量图片生成(已调价)", - "isEnabled": 1 - } -} -``` - -### 4. 删除积分配置 - -**接口**: `DELETE /admin/configs/points/{id}` - -**描述**: 删除指定的积分配置(逻辑删除) - -**请求示例**: -```bash -curl -X DELETE "https://your-domain.com/admin/configs/points/8" \ - -H "Authorization: Bearer " -``` - -**响应示例**: -```json -{ - "code": 200, - "message": "配置删除成功" -} -``` - ---- - -## 系统配置管理 - -管理员可以调整AI队列、任务超时等系统级参数。 - -### 1. 获取所有系统配置 - -**接口**: `GET /admin/configs/system` - -**描述**: 获取所有系统配置项 - -**请求示例**: -```bash -curl -X GET "https://your-domain.com/admin/configs/system" \ - -H "Authorization: Bearer " -``` - -**响应示例**: -```json -{ - "code": 200, - "message": "查询成功", - "data": [ - { - "id": 1, - "configKey": "ai.queue.max_concurrent", - "configValue": "50", - "description": "每个AI模型的最大并发处理数", - "createTime": "2025-10-19T10:00:00", - "updateTime": "2025-10-19T10:00:00" - }, - { - "id": 2, - "configKey": "ai.queue.max_user_concurrent", - "configValue": "3", - "description": "单个用户的最大并发任务数", - "createTime": "2025-10-19T10:00:00", - "updateTime": "2025-10-19T10:00:00" - }, - { - "id": 3, - "configKey": "ai.task.timeout_minutes", - "configValue": "10", - "description": "任务处理超时时间(分钟)", - "createTime": "2025-10-19T10:00:00", - "updateTime": "2025-10-19T10:00:00" - } - ] -} -``` - -### 2. 创建系统配置 - -**接口**: `POST /admin/configs/system` - -**请求示例**: -```json -{ - "configKey": "ai.queue.scan_interval", - "configValue": "3000", - "description": "队列扫描间隔(毫秒)" -} -``` - -### 3. 更新系统配置 - -**接口**: `PUT /admin/configs/system/{id}` - -**描述**: 修改系统配置值 - -**请求示例**: -```json -{ - "configValue": "100", - "description": "每个AI模型的最大并发处理数(已调整)" -} -``` - -**⚠️ 重要提示**: -- 修改 `ai.queue.max_concurrent` 等配置后,系统会**立即生效**(通过缓存刷新机制) -- 但 `application.yml` 中的配置(如 `ai.queue.scan-interval`)需要**重启服务**才能生效 - -### 4. 删除系统配置 - -**接口**: `DELETE /admin/configs/system/{id}` - ---- - -## AI任务监控 - -管理员可以查看和管理所有用户的AI生成任务。 - -### 1. 获取任务列表(分页) - -**接口**: `GET /admin/ai/tasks/list` - -**描述**: 分页查询所有AI任务,支持多条件筛选 - -**查询参数**: -- `page` (可选): 页码,默认 1 -- `size` (可选): 每页数量,默认 10 -- `userId` (可选): 按用户ID筛选 -- `status` (可选): 按状态筛选 (created, queued, processing, completed, failed, cancelled) -- `modelName` (可选): 按模型名称筛选 -- `taskNo` (可选): 按任务编号模糊搜索 - -**请求示例**: -```bash -curl -X GET "https://your-domain.com/admin/ai/tasks/list?page=1&size=20&status=completed" \ - -H "Authorization: Bearer " -``` - -**响应示例**: -```json -{ - "code": 200, - "message": "查询成功", - "data": { - "total": 156, - "pages": 8, - "pageNum": 1, - "pageSize": 20, - "list": [ - { - "taskNo": "TASK20251019143022ABC123", - "userId": 1001, - "modelName": "sora_image", - "taskType": "image", - "prompt": "一只可爱的猫咪在花园里玩耍", - "status": "completed", - "progress": 100, - "progressMessage": "任务已成功完成。", - "pointsFrozen": 11, - "pointsConsumed": 11, - "resultUrl": "https://cdn.example.com/generated/abc123.jpg", - "queueTime": "2025-10-19T14:30:25", - "startTime": "2025-10-19T14:30:30", - "completeTime": "2025-10-19T14:31:15", - "createTime": "2025-10-19T14:30:22", - "updateTime": "2025-10-19T14:31:15" - } - ] - } -} -``` - -### 2. 获取单个任务详情 - -**接口**: `GET /admin/ai/tasks/{taskNo}` - -**描述**: 查询指定任务的详细信息 - -**请求示例**: -```bash -curl -X GET "https://your-domain.com/admin/ai/tasks/TASK20251019143022ABC123" \ - -H "Authorization: Bearer " -``` - -### 3. 强制取消任务 - -**接口**: `POST /admin/ai/tasks/{taskNo}/cancel` - -**描述**: 手动取消一个处于排队中(queued)的任务,并退还用户积分 - -**请求示例**: -```bash -curl -X POST "https://your-domain.com/admin/ai/tasks/TASK20251019143022ABC123/cancel" \ - -H "Authorization: Bearer " -``` - -**响应示例**: -```json -{ - "code": 200, - "message": "任务 TASK20251019143022ABC123 已成功取消。" -} -``` - -**⚠️ 注意**: -- 只有状态为 `queued` 的任务可以被取消 -- 已经在 `processing` 状态的任务无法取消 -- 取消后,冻结的积分会全额退还给用户 - ---- - -## 业务流程说明 - -### 1. 积分定价流程 - -以 Sora Image 为例,完整的定价计算过程: - -``` -第三方API成本: $0.01/张 -↓ -人民币成本: 0.01 × 7.3 (汇率) = 0.073 元 -↓ -加价50%: 0.073 × 1.5 = 0.1095 元 -↓ -向上取整: 0.11 元 -↓ -转换为积分: 0.11 × 100 = 11 积分 -``` - -**当前系统中的定价标准**: - -| 模型名称 | 第三方成本 | 我方定价 | 积分价格 | -|---------|----------|---------|---------| -| sora_image | $0.01 | ¥0.11 | 11积分 | -| gpt-4o-image | $0.01 | ¥0.11 | 11积分 | -| sora_video2 | $0.15 | ¥1.60 | 160积分 | -| sora_video2-landscape | $0.15 | ¥1.60 | 160积分 | -| sora_video2-15s | $0.25 | ¥2.60 | 260积分 | -| sora_video2-landscape-15s | $0.25 | ¥2.60 | 260积分 | -| sora-2-pro-all | $0.40 | ¥4.20 | 420积分 | - -### 2. 用户调用AI模型的完整流程 - -``` -1. 用户提交任务 - ↓ -2. 系统检查用户积分是否充足 - ↓ -3. 冻结所需积分 (points_frozen) - ↓ -4. 创建任务记录 (status: created) - ↓ -5. 将任务放入Redis队列 (status: queued) - ↓ -6. 调度器检测到可用槽位 - ↓ -7. 从队列取出任务,开始处理 (status: processing) - ↓ -8. 异步调用第三方API - ↓ -9a. 成功: 标记任务为completed,记录result_url,消耗积分 -9b. 失败: 标记任务为failed,全额退还积分 - ↓ -10. 通过WebSocket实时推送进度给用户 -``` - -### 3. 任务超时保护机制 - -系统有完善的超时保护机制,防止任务卡死: - -- **超时检查间隔**: 每60秒检查一次(可在 `application.yml` 中配置 `ai.task.timeout-scan-interval`) -- **超时判定标准**: 任务在 `processing` 状态下超过10分钟(可在数据库 `system_config` 表中修改 `ai.task.timeout_minutes`) -- **超时处理**: 自动标记为 `failed`,全额退还积分 - -### 4. 并发控制说明 - -**模型级并发控制**: -- 每个AI模型独立计数 -- 默认最大并发数: 50(在 `application.yml` 中配置为 `ai.queue.max-concurrent: 50`) -- 当前正在处理的任务数达到上限时,新任务会在队列中等待 - -**用户级并发控制** (可选,已在 `system_config` 中预留配置): -- 单个用户最多同时处理3个任务(`ai.queue.max_user_concurrent`) -- 防止单个用户占用过多资源 - ---- - -## 常见问题 - -### Q1: 如何修改某个模型的积分价格? - -**A**: 使用 `PUT /admin/configs/points/{id}` 接口更新 `pointsCost` 字段。修改后立即生效,影响所有后续创建的任务。 - -### Q2: 积分配置修改后,正在处理的任务会受影响吗? - -**A**: 不会。每个任务在创建时就已经记录了 `points_frozen`(冻结的积分数),这个值不会因为后续的价格调整而改变。 - -### Q3: 如何临时禁用某个AI模型? - -**A**: 将该模型的 `isEnabled` 字段设置为 `0`。禁用后,用户提交该模型的任务时会收到错误提示,但不影响已经在队列中或正在处理的任务。 - -### Q4: 如何提高系统的处理能力? - -**A**: 有两种方式: -1. **修改 `application.yml`**: 增加 `ai.queue.max-concurrent` 的值(需要重启服务) -2. **修改数据库**: 更新 `system_config` 表中 `ai.queue.max_concurrent` 的配置值(立即生效,无需重启) - -**推荐使用方式2**,因为它更加灵活,可以根据服务器负载动态调整。 - -### Q5: 用户的积分是如何退款的? - -**A**: 系统在以下情况会自动退还积分: -- 任务失败(`status: failed`) -- 任务超时 -- 管理员手动取消任务 -- API调用异常 - -退款会记录在 `points_consumption_log` 表中,`change_type` 为 `refund`。 - -### Q6: WebSocket推送是如何工作的? - -**A**: -1. 用户连接到 WebSocket 端点: `wss://your-domain.com/ws` -2. 用户订阅自己的进度频道: `/user/queue/tasks-progress` -3. 任务状态变化时(创建、开始处理、完成、失败),系统自动推送JSON格式的进度数据 -4. 前端接收数据并更新UI(如进度条、状态文本) - -### Q7: 如何查看系统当前的运行状态? - -**A**: 可以通过以下方式监控: -1. 使用 `GET /admin/ai/tasks/list?status=processing` 查看当前正在处理的任务数量 -2. 使用 `GET /admin/ai/tasks/list?status=queued` 查看队列中等待的任务数量 -3. 检查 Redis 中的队列长度(技术手段) - -### Q8: 如何备份和恢复积分配置? - -**A**: -- **备份**: 导出 `points_config` 和 `system_config` 表的数据 -- **恢复**: 使用 SQL 的 `INSERT ... ON DUPLICATE KEY UPDATE` 语句批量导入 - -系统在 `V2__add_ai_task_and_points_schema.sql` 中已经提供了初始化数据的示例。 - ---- - -## 附录:数据库表结构 - -### points_config 表 - -| 字段 | 类型 | 说明 | -|-----|------|------| -| id | bigint | 主键 | -| model_name | varchar(64) | 模型名称(唯一) | -| points_cost | int | 积分消耗 | -| description | varchar(255) | 模型描述 | -| is_enabled | tinyint(1) | 是否启用 | -| create_time | datetime | 创建时间 | -| update_time | datetime | 更新时间 | -| is_deleted | tinyint(1) | 逻辑删除标识 | - -### system_config 表 - -| 字段 | 类型 | 说明 | -|-----|------|------| -| id | bigint | 主键 | -| config_key | varchar(64) | 配置键(唯一) | -| config_value | varchar(512) | 配置值 | -| description | varchar(255) | 配置说明 | -| create_time | datetime | 创建时间 | -| update_time | datetime | 更新时间 | - -### ai_task 表 - -| 字段 | 类型 | 说明 | -|-----|------|------| -| id | bigint | 主键 | -| task_no | varchar(64) | 任务编号(唯一) | -| user_id | bigint | 用户ID | -| model_name | varchar(64) | 模型名称 | -| task_type | varchar(32) | 任务类型 | -| prompt | text | 提示词 | -| status | varchar(32) | 任务状态 | -| progress | int | 进度百分比 | -| progress_message | varchar(255) | 进度描述 | -| points_frozen | int | 冻结积分 | -| points_consumed | int | 实际消耗积分 | -| result_url | varchar(512) | 结果URL | -| error_message | text | 错误信息 | -| queue_time | datetime | 入队时间 | -| start_time | datetime | 开始处理时间 | -| complete_time | datetime | 完成时间 | -| create_time | datetime | 创建时间 | -| update_time | datetime | 更新时间 | -| is_deleted | tinyint(1) | 逻辑删除标识 | - ---- - -## 技术支持 - -如有任何问题,请联系技术团队。 - -**文档版本**: v1.0 -**最后更新**: 2025-10-19 - diff --git a/AI_API_KEY_INTEGRATION_GUIDE.md b/AI_API_KEY_INTEGRATION_GUIDE.md deleted file mode 100644 index 2839041..0000000 --- a/AI_API_KEY_INTEGRATION_GUIDE.md +++ /dev/null @@ -1,353 +0,0 @@ -# AI任务API集成指南 - -## 📋 概述 - -本系统现已支持通过**API Key**调用AI生成服务,无需JWT Token认证。所有用户(会员和非会员)都可以: - -1. ✅ 生成个人专属的API Key -2. ✅ 使用API Key + 积分调用AI服务 -3. ✅ 支持文生图、文生视频、图生视频三种模式 - ---- - -## 🔑 获取API Key - -### 方式一:通过Web界面生成(需要登录) - -```http -POST /user/v1/api-key/generate -Authorization: Bearer {JWT_TOKEN} -``` - -**响应示例:** -```json -{ - "code": 200, - "message": "success", - "data": { - "keyValue": "ak_1234567890abcdef1234567890abcdef", - "isActive": true, - "createTime": "2025-10-20T10:00:00", - "userRole": 0 - } -} -``` - -### 方式二:查看现有API Key - -```http -GET /user/v1/api-key/info -Authorization: Bearer {JWT_TOKEN} -``` - ---- - -## 🚀 使用API Key调用AI服务 - -### 认证方式 - -所有AI任务接口都支持以下两种认证方式: - -| 方式 | 适用场景 | Header格式 | -|------|----------|-----------| -| **JWT Token** | Web端用户 | `Authorization: Bearer {jwt_token}` | -| **API Key** | 开发者/第三方集成 | `Authorization: Bearer {api_key}` | - -> 💡 **提示**:系统会自动识别Token类型(JWT或API Key),无需额外配置。 - ---- - -## 📝 API接口说明 - -### 1. 提交AI任务 - -#### 文生图(Text to Image) - -```http -POST /user/ai/tasks/submit -Authorization: Bearer ak_your_api_key_here -Content-Type: application/json - -{ - "modelName": "sora_image", - "prompt": "一只可爱的猫咪在花园里玩耍" -} -``` - -#### 文生视频(Text to Video) - -```http -POST /user/ai/tasks/submit -Authorization: Bearer ak_your_api_key_here -Content-Type: application/json - -{ - "modelName": "sora_video2", - "prompt": "一只猫咪在夕阳下奔跑,镜头缓缓推进" -} -``` - -#### 图生视频(Image to Video) - -**方式1:使用图片URL** -```http -POST /user/ai/tasks/submit -Authorization: Bearer ak_your_api_key_here -Content-Type: application/json - -{ - "modelName": "sora_video2", - "prompt": "让这个场景动起来,添加生动的细节", - "imageUrl": "https://example.com/image.jpg" -} -``` - -**方式2:使用Base64编码** -```http -POST /user/ai/tasks/submit -Authorization: Bearer ak_your_api_key_here -Content-Type: application/json - -{ - "modelName": "sora_video2", - "prompt": "让这个场景动起来,添加生动的细节", - "imageBase64": "data:image/jpeg;base64,/9j/4AAQSkZJRg..." -} -``` - -**响应示例:** -```json -{ - "code": 200, - "message": "任务提交成功", - "data": { - "taskNo": "TASK20251020143022ABC123", - "status": "queued", - "queuePosition": 3, - "estimatedWaitTime": 90, - "message": "任务创建成功,请通过任务编号查询进度" - } -} -``` - -### 2. 查询任务详情 - -```http -GET /user/ai/tasks/{taskNo} -Authorization: Bearer ak_your_api_key_here -``` - -**响应示例:** -```json -{ - "code": 200, - "message": "success", - "data": { - "taskNo": "TASK20251020143022ABC123", - "modelName": "sora_image", - "status": "completed", - "progress": 100, - "promptSnippet": "一只可爱的猫咪在花园里玩耍", - "resultUrl": "https://example.com/result.jpg", - "createTime": "2025-10-20T14:30:22", - "completeTime": "2025-10-20T14:31:00" - } -} -``` - -### 3. 查询任务列表 - -```http -GET /user/ai/tasks/list?page=1&size=10&status=completed -Authorization: Bearer ak_your_api_key_here -``` - ---- - -## 💰 积分消费规则 - -| 模型名称 | 描述 | 积分消耗 | 对应价格 | -|---------|------|---------|---------| -| `sora_image` | Sora高质量图片生成 | 11积分 | ¥0.015 | -| `gpt-4o-image` | GPT-4o图片生成 | 11积分 | ¥0.015 | -| `sora_video2` | Sora视频生成(竖屏10秒) | 160积分 | ¥0.225 | -| `sora_video2-landscape` | Sora视频生成(横屏10秒) | 160积分 | ¥0.225 | -| `sora_video2-15s` | Sora视频生成(竖屏15秒) | 260积分 | ¥0.375 | -| `sora_video2-landscape-15s` | Sora视频生成(横屏15秒) | 260积分 | ¥0.375 | -| `sora-2-pro-all` | Sora Pro高清视频 | 420积分 | ¥0.60 | - -> 💡 **说明**:1人民币 = 1000积分,系统在第三方API价格基础上加价50% - ---- - -## ⚠️ 错误码说明 - -| 状态码 | 说明 | 解决方案 | -|--------|------|----------| -| `200` | 成功 | - | -| `400` | 参数错误 | 检查请求参数是否正确 | -| `401` | 未认证 | 检查API Key是否有效 | -| `402` | 积分不足 | 充值积分后重试 | -| `404` | 任务不存在 | 检查任务编号是否正确 | -| `500` | 服务器错误 | 联系技术支持 | - ---- - -## 🔒 安全建议 - -1. **保护API Key**:不要在客户端代码或公开仓库中硬编码API Key -2. **使用环境变量**:将API Key存储在环境变量中 -3. **定期刷新**:定期刷新API Key以提高安全性 -4. **监控使用**:定期检查API Key的使用情况 - ---- - -## 💻 代码示例 - -### Python示例 - -```python -import requests - -API_KEY = "ak_your_api_key_here" -BASE_URL = "https://your-domain.com" - -def submit_task(model_name, prompt, image_url=None): - """提交AI任务""" - headers = { - "Authorization": f"Bearer {API_KEY}", - "Content-Type": "application/json" - } - - payload = { - "modelName": model_name, - "prompt": prompt - } - - if image_url: - payload["imageUrl"] = image_url - - response = requests.post( - f"{BASE_URL}/user/ai/tasks/submit", - headers=headers, - json=payload - ) - - return response.json() - -def get_task_status(task_no): - """查询任务状态""" - headers = { - "Authorization": f"Bearer {API_KEY}" - } - - response = requests.get( - f"{BASE_URL}/user/ai/tasks/{task_no}", - headers=headers - ) - - return response.json() - -# 使用示例 -result = submit_task("sora_image", "一只可爱的猫咪") -print(f"任务编号: {result['data']['taskNo']}") - -status = get_task_status(result['data']['taskNo']) -print(f"任务状态: {status['data']['status']}") -``` - -### Node.js示例 - -```javascript -const axios = require('axios'); - -const API_KEY = 'ak_your_api_key_here'; -const BASE_URL = 'https://your-domain.com'; - -async function submitTask(modelName, prompt, imageUrl = null) { - const headers = { - 'Authorization': `Bearer ${API_KEY}`, - 'Content-Type': 'application/json' - }; - - const payload = { - modelName, - prompt - }; - - if (imageUrl) { - payload.imageUrl = imageUrl; - } - - const response = await axios.post( - `${BASE_URL}/user/ai/tasks/submit`, - payload, - { headers } - ); - - return response.data; -} - -async function getTaskStatus(taskNo) { - const headers = { - 'Authorization': `Bearer ${API_KEY}` - }; - - const response = await axios.get( - `${BASE_URL}/user/ai/tasks/${taskNo}`, - { headers } - ); - - return response.data; -} - -// 使用示例 -(async () => { - const result = await submitTask('sora_image', '一只可爱的猫咪'); - console.log(`任务编号: ${result.data.taskNo}`); - - const status = await getTaskStatus(result.data.taskNo); - console.log(`任务状态: ${status.data.status}`); -})(); -``` - -### cURL示例 - -```bash -# 提交任务 -curl -X POST "https://your-domain.com/user/ai/tasks/submit" \ - -H "Authorization: Bearer ak_your_api_key_here" \ - -H "Content-Type: application/json" \ - -d '{ - "modelName": "sora_image", - "prompt": "一只可爱的猫咪在花园里玩耍" - }' - -# 查询任务状态 -curl -X GET "https://your-domain.com/user/ai/tasks/TASK20251020143022ABC123" \ - -H "Authorization: Bearer ak_your_api_key_here" -``` - ---- - -## 🎯 最佳实践 - -1. **轮询查询**:任务提交后,建议每5-10秒轮询一次任务状态 -2. **超时处理**:设置合理的超时时间(建议5-10分钟) -3. **错误重试**:遇到网络错误时实现指数退避重试 -4. **并发控制**:单用户最多同时运行3个任务 -5. **结果缓存**:completed状态的任务结果可以缓存,避免重复查询 - ---- - -## 📞 技术支持 - -如有问题,请联系: -- 📧 Email: support@1818ai.com -- 💬 技术文档: https://docs.1818ai.com -- 🐛 问题反馈: https://github.com/1818ai/issues - ---- - -**最后更新时间:2025-10-20** - diff --git a/AI_MODEL_API_GUIDE.md b/AI_MODEL_API_GUIDE.md deleted file mode 100644 index e4e57a6..0000000 --- a/AI_MODEL_API_GUIDE.md +++ /dev/null @@ -1,437 +0,0 @@ -# AI模型查询接口使用指南 - -## 概述 - -系统提供了完整的用户端AI模型查询接口,支持多种查询和分组方式。所有接口均为公开访问,无需认证。 - -## 接口列表 - -### 1. 获取模型列表(支持筛选) - -**接口地址**: `GET /user/ai/models` - -**描述**: 获取所有可用的AI模型列表,支持按任务类型和厂商筛选 - -**请求参数**: -- `taskType` (可选): 任务类型 - - `image` - 图片生成 - - `video` - 视频生成 - - `audio` - 音频生成 - - `text` - 文本生成 -- `provider` (可选): 服务提供商 - - `openai` - OpenAI - - `runninghub` - RunningHub -- `enabledOnly` (可选): 是否只返回已启用的模型,默认 `true` - -**响应示例**: -```json -{ - "code": 200, - "message": "success", - "data": [ - { - "id": 1, - "modelName": "sora_image", - "displayName": "Sora高质量图片生成", - "description": "Sora高质量图片生成", - "pointsCost": 11, - "providerType": "openai", - "taskType": "image", - "isEnabled": true, - "extendedConfig": {} - }, - { - "id": 2, - "modelName": "sora_video2", - "displayName": "Sora视频生成 (竖屏10秒)", - "description": "Sora视频生成 (竖屏10秒)", - "pointsCost": 160, - "providerType": "runninghub", - "taskType": "video", - "isEnabled": true, - "extendedConfig": { - "webappId": "1973555977595301890", - "defaultDuration": 10 - } - } - ] -} -``` - -**使用示例**: -```javascript -// 获取所有已启用的模型 -GET /user/ai/models - -// 获取所有图片生成模型 -GET /user/ai/models?taskType=image - -// 获取OpenAI的所有模型 -GET /user/ai/models?provider=openai - -// 获取RunningHub的视频生成模型 -GET /user/ai/models?taskType=video&provider=runninghub - -// 获取所有模型(包括未启用的) -GET /user/ai/models?enabledOnly=false -``` - ---- - -### 2. 按类型分组获取模型 - -**接口地址**: `GET /user/ai/models/group-by-type` - -**描述**: 获取按任务类型分组的AI模型列表 - -**请求参数**: -- `provider` (可选): 服务提供商筛选 -- `enabledOnly` (可选): 是否只返回已启用的模型,默认 `true` - -**响应示例**: -```json -{ - "code": 200, - "message": "success", - "data": [ - { - "taskType": "image", - "taskTypeName": "图片生成", - "count": 2, - "models": [ - { - "id": 1, - "modelName": "sora_image", - "displayName": "Sora高质量图片生成", - "pointsCost": 11, - "providerType": "openai", - "taskType": "image", - "isEnabled": true - }, - { - "id": 2, - "modelName": "gpt-4o-image", - "displayName": "GPT-4o图片生成", - "pointsCost": 11, - "providerType": "openai", - "taskType": "image", - "isEnabled": true - } - ] - }, - { - "taskType": "video", - "taskTypeName": "视频生成", - "count": 4, - "models": [ - { - "id": 3, - "modelName": "sora_video2", - "displayName": "Sora视频生成 (竖屏10秒)", - "pointsCost": 160, - "providerType": "runninghub", - "taskType": "video", - "isEnabled": true - } - // ... 更多视频模型 - ] - } - ] -} -``` - -**使用示例**: -```javascript -// 获取所有按类型分组的模型 -GET /user/ai/models/group-by-type - -// 获取OpenAI的按类型分组的模型 -GET /user/ai/models/group-by-type?provider=openai - -// 获取所有模型按类型分组(包括未启用的) -GET /user/ai/models/group-by-type?enabledOnly=false -``` - ---- - -### 3. 按厂商分组获取模型 - -**接口地址**: `GET /user/ai/models/group-by-provider` - -**描述**: 获取按服务提供商分组的AI模型列表 - -**请求参数**: -- `taskType` (可选): 任务类型筛选 -- `enabledOnly` (可选): 是否只返回已启用的模型,默认 `true` - -**响应示例**: -```json -{ - "code": 200, - "message": "success", - "data": [ - { - "providerType": "openai", - "providerName": "OpenAI", - "count": 2, - "models": [ - { - "id": 1, - "modelName": "sora_image", - "displayName": "Sora高质量图片生成", - "pointsCost": 11, - "providerType": "openai", - "taskType": "image", - "isEnabled": true - }, - { - "id": 2, - "modelName": "gpt-4o-image", - "displayName": "GPT-4o图片生成", - "pointsCost": 11, - "providerType": "openai", - "taskType": "image", - "isEnabled": true - } - ] - }, - { - "providerType": "runninghub", - "providerName": "RunningHub", - "count": 5, - "models": [ - { - "id": 3, - "modelName": "sora_video2", - "displayName": "Sora视频生成 (竖屏10秒)", - "pointsCost": 160, - "providerType": "runninghub", - "taskType": "video", - "isEnabled": true - } - // ... 更多RunningHub模型 - ] - } - ] -} -``` - -**使用示例**: -```javascript -// 获取所有按厂商分组的模型 -GET /user/ai/models/group-by-provider - -// 获取视频生成的按厂商分组 -GET /user/ai/models/group-by-provider?taskType=video - -// 获取图片生成的按厂商分组 -GET /user/ai/models/group-by-provider?taskType=image -``` - ---- - -### 4. 获取模型统计信息 - -**接口地址**: `GET /user/ai/models/stats` - -**描述**: 获取系统中AI模型的统计信息 - -**响应示例**: -```json -{ - "code": 200, - "message": "success", - "data": { - "totalModels": 10, - "enabledModels": 8, - "countByType": { - "image": 2, - "video": 5, - "audio": 1 - }, - "countByProvider": { - "openai": 3, - "runninghub": 5 - } - } -} -``` - ---- - -## 前端集成示例 - -### Vue 3 + TypeScript 示例 - -```typescript -// api/aiModel.ts -import axios from 'axios'; - -interface ModelInfo { - id: number; - modelName: string; - displayName: string; - description: string; - pointsCost: number; - providerType: string; - taskType: string; - isEnabled: boolean; - extendedConfig?: Record; -} - -interface ModelsByType { - taskType: string; - taskTypeName: string; - count: number; - models: ModelInfo[]; -} - -export const aiModelApi = { - // 获取所有模型 - getAllModels(params?: { - taskType?: string; - provider?: string; - enabledOnly?: boolean; - }) { - return axios.get<{ data: ModelInfo[] }>('/user/ai/models', { params }); - }, - - // 按类型分组获取 - getModelsByType(params?: { - provider?: string; - enabledOnly?: boolean; - }) { - return axios.get<{ data: ModelsByType[] }>('/user/ai/models/group-by-type', { params }); - }, - - // 按厂商分组获取 - getModelsByProvider(params?: { - taskType?: string; - enabledOnly?: boolean; - }) { - return axios.get<{ data: any[] }>('/user/ai/models/group-by-provider', { params }); - }, - - // 获取统计信息 - getModelStats() { - return axios.get('/user/ai/models/stats'); - } -}; -``` - -### 使用示例(Vue组件) - -```vue - - - - - {{ typeGroup.taskTypeName }} ({{ typeGroup.count }}) - - - {{ model.displayName }} - {{ model.description }} - {{ model.pointsCost }} 积分 - {{ model.providerType }} - - - - - - - -``` - ---- - -## 常见使用场景 - -### 场景1: 模型选择器(ALL模式) -展示所有可用模型供用户选择: -```javascript -GET /user/ai/models?enabledOnly=true -``` - -### 场景2: 按类型筛选(文生图) -用户想要生成图片,只显示图片生成模型: -```javascript -GET /user/ai/models?taskType=image -``` - -### 场景3: 按厂商分类展示 -展示不同AI服务商的模型,方便用户对比: -```javascript -GET /user/ai/models/group-by-provider -``` - -### 场景4: 特定厂商的特定类型 -显示RunningHub的视频生成模型: -```javascript -GET /user/ai/models?taskType=video&provider=runninghub -``` - -### 场景5: 模型统计Dashboard -显示系统模型概览: -```javascript -GET /user/ai/models/stats -``` - ---- - -## 数据模型说明 - -### 任务类型 (taskType) -- `image` - 图片生成(文生图、图生图等) -- `video` - 视频生成(文生视频、图生视频等) -- `audio` - 音频生成 -- `text` - 文本生成 -- `other` - 其他类型 - -### 服务提供商 (providerType) -- `openai` - OpenAI -- `runninghub` - RunningHub -- `anthropic` - Anthropic -- `google` - Google -- 其他自定义提供商 - -### 扩展配置 (extendedConfig) -JSON格式的模型特定配置,例如: -```json -{ - "webappId": "1973555977595301890", - "defaultDuration": 10, - "supportedSizes": ["portrait", "landscape"], - "maxDuration": 15 -} -``` - ---- - -## 注意事项 - -1. **公开访问**: 所有模型查询接口均为公开访问,无需登录 -2. **默认过滤**: 默认只返回已启用的模型(`enabledOnly=true`) -3. **智能推断**: 系统会根据模型名称自动推断任务类型 -4. **灵活组合**: 可以组合多个参数进行精确筛选 -5. **分组查询**: 提供按类型和按厂商两种分组方式,方便前端展示 - diff --git a/COS_POST_FORM_UPLOAD_FIXED.md b/COS_POST_FORM_UPLOAD_FIXED.md new file mode 100644 index 0000000..482256b --- /dev/null +++ b/COS_POST_FORM_UPLOAD_FIXED.md @@ -0,0 +1,312 @@ +# COS POST 表单上传 - 完整修复版 + +## ✅ 问题已修复 + +已修复 COS POST 表单上传的签名问题: +- ✅ 添加了 `q-key-time` 字段 +- ✅ 添加了 `q-sign-time` 字段 +- ✅ Policy 中包含必需的签名条件 +- ✅ 使用正确的 COS 签名算法 + +--- + +## 📋 前端正确的上传代码 + +### Vue 3 + Element Plus 完整示例 + +```vue + + + 上传图片 + + + + +``` + +--- + +### 原生 JavaScript 示例 + +```javascript +async function uploadFileToCOS(file, userId) { + try { + // 1. 获取 POST 签名 + const signResponse = await fetch('/user/oss/post-signature', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Authorization': 'Bearer ' + localStorage.getItem('token') + }, + body: JSON.stringify({ + fileName: file.name, + userId: userId + }) + }); + + const signResult = await signResponse.json(); + if (signResult.code !== 200) { + throw new Error(signResult.message); + } + + const data = signResult.data; + + // 2. 构造表单数据(COS 标准字段) + const formData = new FormData(); + const fileKey = data.dir + Date.now() + '_' + file.name; + + formData.append('key', fileKey); // 文件路径 + formData.append('policy', data.policy); // Policy + formData.append('q-sign-algorithm', data['q-sign-algorithm']); // 签名算法 + formData.append('q-ak', data['q-ak']); // SecretId + formData.append('q-key-time', data['q-key-time']); // KeyTime(必需) + formData.append('q-signature', data['q-signature']); // 签名 + formData.append('file', file); // 文件(必须最后) + + // 3. 上传到 COS + const uploadResponse = await fetch(data.host, { + method: 'POST', + body: formData + }); + + if (!uploadResponse.ok) { + const errorText = await uploadResponse.text(); + console.error('COS 返回错误:', errorText); + throw new Error('上传失败: ' + uploadResponse.status); + } + + // 4. 上传成功 + const fileUrl = data.host + '/' + fileKey; + console.log('上传成功,文件地址:', fileUrl); + return fileUrl; + + } catch (error) { + console.error('上传失败:', error); + throw error; + } +} + +// 使用示例 +document.getElementById('fileInput').addEventListener('change', async (e) => { + const file = e.target.files[0]; + if (file) { + try { + const fileUrl = await uploadFileToCOS(file, '123'); + alert('上传成功: ' + fileUrl); + } catch (error) { + alert('上传失败: ' + error.message); + } + } +}); +``` + +--- + +## 📡 后端返回的签名数据 + +```json +{ + "code": 200, + "message": "POST签名生成成功", + "data": { + "policy": "eyJleHBpcmF0aW9uIjoi...", + "q-sign-algorithm": "sha1", + "q-ak": "AKIDVY1HLBnDZhbHkz0mLhgT3TgePXHNErLC", + "q-key-time": "1733472660;1733476260", + "q-sign-time": "1733472660;1733476260", + "q-signature": "7758dc9a832e9d301dca704cacbf9d9f8172abcd", + "host": "https://oss-1818ai-user-img-1302947942.cos.ap-guangzhou.myqcloud.com", + "dir": "user_img/", + "fileName": "avatar.jpg", + "fileType": "image", + "maxFileSize": 10485760, + "maxFileSizeMB": 10 + } +} +``` + +--- + +## 🔑 必需的表单字段 + +前端提交表单时**必须包含**以下字段: + +| 字段名 | 说明 | 示例值 | +|--------|------|--------| +| `key` | 文件路径 | `user_img/1733472660_avatar.jpg` | +| `policy` | Base64 编码的 Policy | `eyJleHBpcmF0aW9uIjoi...` | +| `q-sign-algorithm` | 签名算法 | `sha1` | +| `q-ak` | SecretId | `AKIDVY1HLBnDZhbHkz0mLhgT3TgePXHNErLC` | +| `q-key-time` | 密钥有效时间 | `1733472660;1733476260` | +| `q-signature` | 签名 | `7758dc9a832e9d301dca704cacbf9d9f8172abcd` | +| `file` | 文件内容 | (二进制数据,必须最后) | + +--- + +## ⚠️ 常见错误和解决方案 + +### 1. SignatureDoesNotMatch - q-key-time is required + +**错误信息:** +```xml + + SignatureDoesNotMatch + form field q-key-time is required,but not found or empty. + +``` + +**原因:** 表单中缺少 `q-key-time` 字段 + +**解决:** 确保表单包含: +```javascript +formData.append('q-key-time', data['q-key-time']); +``` + +--- + +### 2. InvalidPolicyDocument - q-sign-time is required + +**错误信息:** +```xml + + InvalidPolicyDocument + policy condition q-sign-time is required,but not found. + +``` + +**原因:** Policy 中缺少 `q-sign-time` 条件 + +**解决:** 后端已修复,重新编译部署即可 + +--- + +### 3. SignatureDoesNotMatch - 签名不匹配 + +**原因:** 签名计算错误或字段值不匹配 + +**解决:** +1. 确保 `q-key-time` 和 `q-sign-time` 的值相同 +2. 确保 `key` 字段以 `dir` 开头 +3. 确保所有字段值与后端返回的完全一致 + +--- + +### 4. CORS 错误 + +**解决:** 在腾讯云 COS 控制台配置 CORS: +- 来源:`*` 或具体域名 +- 方法:`GET, POST, PUT, HEAD` +- Allow-Headers:`*` + +--- + +## 🧪 测试上传 + +### 使用 curl 测试 + +```bash +# 1. 获取签名 +curl -X POST http://localhost:8083/user/oss/post-signature \ + -H "Content-Type: application/json" \ + -d '{"userId":"123","fileName":"test.jpg"}' + +# 2. 使用返回的签名上传(替换实际值) +curl -X POST "https://oss-1818ai-user-img-1302947942.cos.ap-guangzhou.myqcloud.com/" \ + -F "key=user_img/test.jpg" \ + -F "policy=<返回的policy>" \ + -F "q-sign-algorithm=sha1" \ + -F "q-ak=<返回的q-ak>" \ + -F "q-key-time=<返回的q-key-time>" \ + -F "q-signature=<返回的q-signature>" \ + -F "file=@/path/to/test.jpg" +``` + +--- + +## 📚 参考文档 + +- [腾讯云 COS POST Object 官方文档](https://cloud.tencent.com/document/product/436/14690) +- [COS 请求签名算法](https://cloud.tencent.com/document/product/436/7778) + +--- + +## ✅ 总结 + +修复后的签名已经完全符合 COS 规范: +- ✅ 包含所有必需字段 +- ✅ 签名算法正确 +- ✅ Policy 格式正确 +- ✅ 前端代码简单明了 + +**重新编译部署后即可正常使用!** diff --git a/COS_POST_UPLOAD_GUIDE.md b/COS_POST_UPLOAD_GUIDE.md new file mode 100644 index 0000000..1521292 --- /dev/null +++ b/COS_POST_UPLOAD_GUIDE.md @@ -0,0 +1,130 @@ +# COS POST 表单上传指南 + +## 问题说明 + +如果出现 403 错误,通常是因为前端提交的表单字段名不符合 COS 要求。 + +--- + +## ✅ 正确的前端上传代码 + +### 方式1:使用 COS 标准字段(推荐) + +```javascript +// 1. 获取签名 +const response = await fetch('/user/oss/post-signature', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + userId: '123', + fileName: 'avatar.jpg' + }) +}); + +const signData = await response.json(); +const data = signData.data; + +// 2. 构造表单数据(COS 标准字段) +const formData = new FormData(); +formData.append('key', data.dir + 'your-file-name.jpg'); // 文件路径 +formData.append('policy', data.policy); // Policy +formData.append('q-sign-algorithm', 'sha1'); // 签名算法 +formData.append('q-ak', data['q-ak']); // SecretId +formData.append('q-signature', data['q-signature']); // 签名 +formData.append('file', file); // 文件(必须最后) + +// 3. 上传到 COS +const uploadResponse = await fetch(data.host, { + method: 'POST', + body: formData +}); + +if (uploadResponse.ok) { + const fileUrl = data.host + '/' + data.dir + 'your-file-name.jpg'; + console.log('上传成功:', fileUrl); +} +``` + +--- + +### 方式2:兼容 OSS 的字段名 + +```javascript +// 如果前端代码还在用 OSS 的字段名,可以这样: +const formData = new FormData(); +formData.append('key', data.dir + 'your-file-name.jpg'); +formData.append('policy', data.policy); +formData.append('OSSAccessKeyId', data.accessKeyId); // 兼容 OSS +formData.append('signature', data.signature); // 兼容 OSS +formData.append('file', file); + +// 但这种方式可能不被 COS 接受,建议使用方式1 +``` + +--- + +## 📋 后端返回的字段说明 + +| 字段名 | 用途 | 说明 | +|--------|------|------| +| `policy` | Policy Base64 | 必须 | +| `q-sign-algorithm` | 签名算法 | 固定为 "sha1" | +| `q-ak` | SecretId | COS 密钥 ID | +| `q-signature` | 签名 | HMAC-SHA1 签名 | +| `host` | 上传地址 | COS 存储桶域名 | +| `dir` | 文件目录 | 文件存储路径前缀 | + +--- + +## ⚠️ 常见错误 + +### 1. 403 Forbidden - 签名错误 +**原因:** 表单字段名不对或缺少必要字段 + +**解决:** 确保使用 COS 标准字段名: +- ✅ `q-ak`(不是 `accessKeyId` 或 `OSSAccessKeyId`) +- ✅ `q-signature`(不是 `signature`) +- ✅ `q-sign-algorithm` + +### 2. 403 Forbidden - Key 不匹配 +**原因:** `key` 字段的值不符合 Policy 中的前缀限制 + +**解决:** 确保 `key` 以 `data.dir` 开头: +```javascript +formData.append('key', data.dir + fileName); // ✅ 正确 +formData.append('key', fileName); // ❌ 错误 +``` + +### 3. CORS 错误 +**原因:** COS 存储桶未配置跨域规则 + +**解决:** 在腾讯云 COS 控制台配置 CORS(见主文档) + +--- + +## 🧪 测试上传 + +使用以下 curl 命令测试: + +```bash +# 1. 获取签名 +curl -X POST http://localhost:8083/user/oss/post-signature \ + -H "Content-Type: application/json" \ + -d '{"userId":"123","fileName":"test.jpg"}' + +# 2. 使用返回的签名上传文件 +curl -X POST "https://oss-1818ai-user-img-1302947942.cos.ap-guangzhou.myqcloud.com/" \ + -F "key=user_img/test.jpg" \ + -F "policy=<返回的policy>" \ + -F "q-sign-algorithm=sha1" \ + -F "q-ak=<返回的q-ak>" \ + -F "q-signature=<返回的q-signature>" \ + -F "file=@/path/to/test.jpg" +``` + +--- + +## 📚 参考文档 + +- [腾讯云 COS POST 表单上传](https://cloud.tencent.com/document/product/436/14690) +- [COS 签名算法](https://cloud.tencent.com/document/product/436/7778) diff --git a/COS_PRESIGNED_URL_UPLOAD_GUIDE.md b/COS_PRESIGNED_URL_UPLOAD_GUIDE.md new file mode 100644 index 0000000..b2f5e3f --- /dev/null +++ b/COS_PRESIGNED_URL_UPLOAD_GUIDE.md @@ -0,0 +1,356 @@ +# COS 预签名 URL 直传指南(推荐方式) + +## 🎯 为什么使用预签名 URL? + +相比 POST 表单上传,预签名 URL 直传更简单: +- ✅ **无需复杂的表单字段** - 只需要一个 URL +- ✅ **前端代码更简洁** - 直接 PUT 文件即可 +- ✅ **自动处理 CORS** - 预签名 URL 包含签名,不受 CORS 限制 +- ✅ **更安全** - URL 有过期时间,临时授权 + +--- + +## 📋 完整的前端上传代码 + +### Vue 3 + Element Plus 示例 + +```vue + + + 选择图片 + + + + +``` + +--- + +### 原生 JavaScript 示例 + +```javascript +async function uploadFile(file, userId) { + try { + // 1. 获取预签名 URL + const signResponse = await fetch('/user/oss/presigned-url', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Authorization': 'Bearer ' + localStorage.getItem('token') + }, + body: JSON.stringify({ + fileName: file.name, + userId: userId + }) + }); + + const signResult = await signResponse.json(); + if (signResult.code !== 200) { + throw new Error(signResult.message); + } + + const { uploadUrl, fileUrl } = signResult.data; + + // 2. 直接 PUT 文件到预签名 URL + const uploadResponse = await fetch(uploadUrl, { + method: 'PUT', + body: file, + headers: { + 'Content-Type': file.type + } + }); + + if (!uploadResponse.ok) { + throw new Error('上传失败'); + } + + // 3. 上传成功,返回文件访问地址 + console.log('上传成功,文件地址:', fileUrl); + return fileUrl; + + } catch (error) { + console.error('上传失败:', error); + throw error; + } +} + +// 使用示例 +document.getElementById('fileInput').addEventListener('change', async (e) => { + const file = e.target.files[0]; + if (file) { + try { + const fileUrl = await uploadFile(file, '123'); + alert('上传成功: ' + fileUrl); + } catch (error) { + alert('上传失败: ' + error.message); + } + } +}); +``` + +--- + +### React 示例 + +```jsx +import { useState } from 'react'; +import { message } from 'antd'; + +function FileUpload() { + const [uploading, setUploading] = useState(false); + + const handleUpload = async (file) => { + setUploading(true); + try { + // 1. 获取预签名 URL + const signResponse = await fetch('/user/oss/presigned-url', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${localStorage.getItem('token')}` + }, + body: JSON.stringify({ + fileName: file.name, + userId: '123' + }) + }); + + const signResult = await signResponse.json(); + if (signResult.code !== 200) { + throw new Error(signResult.message); + } + + const { uploadUrl, fileUrl } = signResult.data; + + // 2. PUT 文件到预签名 URL + const uploadResponse = await fetch(uploadUrl, { + method: 'PUT', + body: file, + headers: { + 'Content-Type': file.type + } + }); + + if (!uploadResponse.ok) { + throw new Error('上传失败'); + } + + message.success('上传成功'); + console.log('文件地址:', fileUrl); + return fileUrl; + + } catch (error) { + console.error('上传失败:', error); + message.error('上传失败: ' + error.message); + } finally { + setUploading(false); + } + }; + + return ( + handleUpload(e.target.files[0])} + disabled={uploading} + /> + ); +} +``` + +--- + +## 📡 API 接口说明 + +### 接口地址 +``` +POST /user/oss/presigned-url +GET /user/oss/presigned-url +``` + +### 请求参数(POST 方式) + +```json +{ + "fileName": "avatar.jpg", + "userId": "123" +} +``` + +### 响应数据 + +```json +{ + "code": 200, + "message": "预签名URL生成成功", + "data": { + "uploadUrl": "https://oss-1818ai-user-img-1302947942.cos.ap-guangzhou.myqcloud.com/user_img/xxx.jpg?sign=...", + "fileUrl": "https://oss-1818ai-user-img-1302947942.cos.ap-guangzhou.myqcloud.com/user_img/xxx.jpg", + "fileName": "avatar.jpg", + "expiresIn": 3600 + } +} +``` + +### 字段说明 + +| 字段 | 说明 | +|------|------| +| `uploadUrl` | 预签名上传 URL(包含签名,有效期1小时) | +| `fileUrl` | 文件访问地址(永久有效) | +| `fileName` | 文件名 | +| `expiresIn` | 签名有效期(秒) | + +--- + +## 🔧 上传流程 + +``` +┌─────────┐ 1. 请求预签名URL ┌─────────┐ +│ │ ────────────────────────> │ │ +│ 前端 │ │ 后端 │ +│ │ <──────────────────────── │ │ +└─────────┘ 2. 返回预签名URL └─────────┘ + │ + │ 3. PUT 文件到预签名URL + ↓ +┌─────────┐ +│ COS │ +│ 存储桶 │ +└─────────┘ +``` + +--- + +## ✅ 优势对比 + +| 特性 | 预签名 URL 直传 | POST 表单上传 | +|------|----------------|--------------| +| **前端代码** | ✅ 简单(一个 PUT 请求) | ❌ 复杂(多个表单字段) | +| **CORS 配置** | ✅ 不需要(签名在 URL 中) | ❌ 需要配置 | +| **字段匹配** | ✅ 无需关心字段名 | ❌ 必须匹配 COS 字段名 | +| **错误排查** | ✅ 简单 | ❌ 复杂(403 签名错误) | +| **安全性** | ✅ URL 有过期时间 | ✅ Policy 有过期时间 | + +--- + +## ⚠️ 注意事项 + +1. **预签名 URL 有效期** + - 默认 1 小时(3600 秒) + - 过期后需要重新获取 + +2. **Content-Type** + - PUT 请求时建议设置正确的 Content-Type + - 例如:`image/jpeg`, `image/png` + +3. **文件大小限制** + - 默认最大 100MB + - 可在后端配置中调整 + +4. **文件命名** + - 后端会自动生成唯一文件名(UUID) + - 避免文件名冲突 + +--- + +## 🧪 测试命令 + +```bash +# 1. 获取预签名 URL +curl -X POST http://localhost:8083/user/oss/presigned-url \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer YOUR_TOKEN" \ + -d '{"fileName":"test.jpg","userId":"123"}' + +# 2. 使用预签名 URL 上传文件 +curl -X PUT "<返回的uploadUrl>" \ + -H "Content-Type: image/jpeg" \ + --data-binary "@/path/to/test.jpg" + +# 3. 访问文件 +curl "<返回的fileUrl>" +``` + +--- + +## 🎉 总结 + +使用预签名 URL 直传是最简单、最可靠的方式: +- ✅ 前端只需两步:获取 URL → PUT 文件 +- ✅ 无需配置 CORS +- ✅ 无需关心复杂的表单字段 +- ✅ 错误排查简单 + +**强烈推荐使用这种方式!** diff --git a/COS_SIGNATURE_DEBUG.md b/COS_SIGNATURE_DEBUG.md new file mode 100644 index 0000000..2eff1e6 --- /dev/null +++ b/COS_SIGNATURE_DEBUG.md @@ -0,0 +1,296 @@ +# COS POST 签名算法详解与调试 + +## 🔍 签名计算步骤(已修正) + +根据腾讯云官方文档,COS POST Object 的签名计算步骤如下: + +### 步骤 1:生成 KeyTime + +``` +KeyTime = StartTimestamp;EndTimestamp +``` + +**示例:** +``` +1567064374;1567071574 +``` + +--- + +### 步骤 2:构造 Policy(JSON 格式) + +```json +{ + "expiration": "2019-08-29T09:39:34.471Z", + "conditions": [ + { "bucket": "examplebucket-1250000000" }, + [ "content-length-range", 1, 10485760 ], + [ "starts-with", "$key", "user_img" ], + { "q-sign-algorithm": "sha1" }, + { "q-ak": "************************************" }, + { "q-sign-time": "1567064374;1567071574" } + ] +} +``` + +--- + +### 步骤 3:生成 SignKey + +``` +SignKey = HMAC-SHA1(SecretKey, KeyTime) +``` + +**注意:** 结果是**十六进制小写字符串** + +**示例:** +``` +SignKey = HMAC-SHA1("your-secret-key", "1567064374;1567071574") + = "39acc8c9f34ba5b19bce4e965b370cd3f62d2fba" +``` + +--- + +### 步骤 4:生成 StringToSign + +**关键:** StringToSign 是 **Policy JSON 原文**的 SHA1 哈希值 + +``` +StringToSign = SHA1(Policy JSON 原文) +``` + +**注意:** +- ✅ 使用 **Policy 的 JSON 原文**(未 Base64 编码) +- ✅ 结果是**十六进制小写字符串** + +**示例:** +``` +Policy JSON: {"expiration":"2019-08-29T09:39:34.471Z","conditions":[...]} +StringToSign = SHA1(Policy JSON) + = "d5d903b8360468bc81c1311f134989bc8c8b5b89" +``` + +--- + +### 步骤 5:生成 Signature + +``` +Signature = HMAC-SHA1(SignKey, StringToSign) +``` + +**注意:** 结果是**十六进制小写字符串** + +**示例:** +``` +Signature = HMAC-SHA1("39acc8c9f34ba5b19bce4e965b370cd3f62d2fba", "d5d903b8360468bc81c1311f134989bc8c8b5b89") + = "7758dc9a832e9d301dca704cacbf9d9f8172abcd" +``` + +--- + +## ✅ 正确的代码实现 + +```java +// 1. 生成 KeyTime +long currentSeconds = System.currentTimeMillis() / 1000; +long expireSeconds = currentSeconds + 3600; +String keyTime = currentSeconds + ";" + expireSeconds; + +// 2. 构造 Policy +Map policy = new HashMap<>(); +policy.put("expiration", generateExpiration(3600L)); +List conditions = new ArrayList<>(); +conditions.add(Map.of("bucket", "your-bucket")); +conditions.add(Arrays.asList("content-length-range", 1, 10485760)); +conditions.add(Arrays.asList("starts-with", "$key", "user_img")); +conditions.add(Map.of("q-sign-algorithm", "sha1")); +conditions.add(Map.of("q-ak", secretId)); +conditions.add(Map.of("q-sign-time", keyTime)); +policy.put("conditions", conditions); + +String jsonPolicy = mapper.writeValueAsString(policy); + +// 3. 生成 SignKey +String signKey = hmacSha1(secretKey, keyTime); + +// 4. 生成 StringToSign(Policy JSON 原文的 SHA1) +String stringToSign = sha1(jsonPolicy); + +// 5. 生成 Signature +String signature = hmacSha1(signKey, stringToSign); + +// 6. Base64 编码 Policy(用于表单提交) +String encodedPolicy = Base64.encodeBase64String(jsonPolicy.getBytes(StandardCharsets.UTF_8)); +``` + +--- + +## 🔧 辅助方法 + +```java +/** + * HMAC-SHA1(返回十六进制小写字符串) + */ +private String hmacSha1(String key, String data) { + SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "HmacSHA1"); + Mac mac = Mac.getInstance("HmacSHA1"); + mac.init(secretKeySpec); + byte[] hmacBytes = mac.doFinal(data.getBytes(StandardCharsets.UTF_8)); + return toHexString(hmacBytes); // 十六进制小写 +} + +/** + * SHA1(返回十六进制小写字符串) + */ +private String sha1(String data) { + MessageDigest digest = MessageDigest.getInstance("SHA-1"); + byte[] hash = digest.digest(data.getBytes(StandardCharsets.UTF_8)); + return toHexString(hash); // 十六进制小写 +} + +/** + * 字节数组转十六进制小写字符串 + */ +private String toHexString(byte[] bytes) { + StringBuilder sb = new StringBuilder(); + for (byte b : bytes) { + sb.append(String.format("%02x", b)); + } + return sb.toString(); +} +``` + +--- + +## 🧪 调试步骤 + +### 1. 启用 DEBUG 日志 + +在 `application.yml` 中添加: + +```yaml +logging: + level: + com.dora.service.OssPostSignatureService: DEBUG +``` + +### 2. 查看日志输出 + +重新请求签名接口后,查看日志: + +``` +COS POST signature calculation: + KeyTime: 1733472660;1733476260 + Policy JSON: {"expiration":"2025-12-06T12:51:00.000Z","conditions":[...]} + StringToSign (SHA1 of Policy): 93e7e253c53fc6513ce0dc1c0dd34af925ad028f + SignKey: 39acc8c9f34ba5b19bce4e965b370cd3f62d2fba + Signature: 7758dc9a832e9d301dca704cacbf9d9f8172abcd +``` + +### 3. 对比 COS 返回的错误 + +如果 COS 返回签名错误,会显示它计算的 StringToSign: + +```xml + + SignatureDoesNotMatch + The Signature you specified is invalid. + 93e7e253c53fc6513ce0dc1c0dd34af925ad028f + +``` + +**对比:** +- 如果 `StringToSign` 相同,说明 Policy 正确,但 Signature 计算错误 +- 如果 `StringToSign` 不同,说明 Policy 构造有问题 + +--- + +## ⚠️ 常见错误 + +### 错误 1:使用 Base64 编码后的 Policy 计算 StringToSign + +❌ **错误:** +```java +String encodedPolicy = Base64.encodeBase64String(jsonPolicy.getBytes()); +String stringToSign = sha1(encodedPolicy); // 错误! +``` + +✅ **正确:** +```java +String stringToSign = sha1(jsonPolicy); // 使用 JSON 原文 +String encodedPolicy = Base64.encodeBase64String(jsonPolicy.getBytes()); +``` + +--- + +### 错误 2:HMAC-SHA1 返回 Base64 而不是十六进制 + +❌ **错误:** +```java +return Base64.encodeBase64String(hmacBytes); // 错误! +``` + +✅ **正确:** +```java +return toHexString(hmacBytes); // 十六进制小写 +``` + +--- + +### 错误 3:Policy 中缺少必需的签名条件 + +❌ **错误:** +```json +{ + "conditions": [ + { "bucket": "xxx" } + // 缺少 q-sign-algorithm, q-ak, q-sign-time + ] +} +``` + +✅ **正确:** +```json +{ + "conditions": [ + { "bucket": "xxx" }, + { "q-sign-algorithm": "sha1" }, + { "q-ak": "AKID..." }, + { "q-sign-time": "1567064374;1567071574" } + ] +} +``` + +--- + +## 📚 参考文档 + +- [腾讯云 COS POST Object 官方文档](https://cloud.tencent.com/document/product/436/14690) +- [COS 请求签名算法](https://cloud.tencent.com/document/product/436/7778) +- [COS 签名工具(在线验证)](https://cloud.tencent.com/document/product/436/30442) + +--- + +## ✅ 验证清单 + +在部署前,确认以下几点: + +- [ ] KeyTime 格式正确:`StartTimestamp;EndTimestamp` +- [ ] Policy 包含所有必需条件 +- [ ] StringToSign = SHA1(Policy JSON 原文) +- [ ] SignKey = HMAC-SHA1(SecretKey, KeyTime) +- [ ] Signature = HMAC-SHA1(SignKey, StringToSign) +- [ ] 所有哈希值都是十六进制小写字符串 +- [ ] 表单提交时包含所有必需字段 + +--- + +## 🎯 总结 + +**关键点:** +1. StringToSign 是 **Policy JSON 原文**的 SHA1,不是 Base64 后的 +2. 所有哈希值都是**十六进制小写字符串**,不是 Base64 +3. Policy 中必须包含 `q-sign-algorithm`, `q-ak`, `q-sign-time` 条件 +4. 表单中必须包含 `q-key-time` 字段 + +**修复后重新编译部署即可!** diff --git a/DEPLOYMENT_CHECKLIST.md b/DEPLOYMENT_CHECKLIST.md deleted file mode 100644 index d2713db..0000000 --- a/DEPLOYMENT_CHECKLIST.md +++ /dev/null @@ -1,445 +0,0 @@ -# RunningHub集成部署检查清单 - -**版本:** v2.1.0 -**日期:** 2025-10-20 - ---- - -## ✅ 部署前检查 - -### 1. 代码文件完整性 - -- [ ] **Provider核心接口** (5个文件) - - [ ] `src/main/java/com/dora/service/provider/AIProvider.java` - - [ ] `src/main/java/com/dora/dto/provider/ProviderTaskRequest.java` - - [ ] `src/main/java/com/dora/dto/provider/ProviderTaskResponse.java` - - [ ] `src/main/java/com/dora/dto/provider/ProviderTaskStatus.java` - - [ ] `src/main/java/com/dora/dto/provider/ProviderTaskResult.java` - -- [ ] **Provider实现** (2个文件) - - [ ] `src/main/java/com/dora/service/provider/impl/OpenAIProviderImpl.java` - - [ ] `src/main/java/com/dora/service/provider/impl/RunningHubProviderImpl.java` - -- [ ] **RunningHub DTO** (5个文件) - - [ ] `src/main/java/com/dora/dto/runninghub/RunningHubSubmitRequest.java` - - [ ] `src/main/java/com/dora/dto/runninghub/RunningHubNodeInfo.java` - - [ ] `src/main/java/com/dora/dto/runninghub/RunningHubSubmitResponse.java` - - [ ] `src/main/java/com/dora/dto/runninghub/RunningHubStatusResponse.java` - - [ ] `src/main/java/com/dora/dto/runninghub/RunningHubOutputResponse.java` - -- [ ] **核心服务** (2个文件) - - [ ] `src/main/java/com/dora/service/AIProviderService.java` - - [ ] `src/main/java/com/dora/scheduler/RunningHubPollingScheduler.java` - -- [ ] **修改的文件** (7个文件) - - [ ] `src/main/resources/application.yml` - 添加providers配置 - - [ ] `src/main/java/com/dora/entity/AiTask.java` - 添加provider字段 - - [ ] `src/main/java/com/dora/entity/PointsConfig.java` - 添加provider字段 - - [ ] `src/main/java/com/dora/mapper/AiTaskMapper.java` - 添加查询方法 - - [ ] `src/main/resources/mapper/AiTaskMapper.xml` - 更新SQL - - [ ] `src/main/java/com/dora/service/impl/AiTaskServiceImpl.java` - 集成Provider - - [ ] `V5__add_provider_support.sql` - 数据库迁移脚本 - -### 2. 配置文件检查 - -```bash -# 检查application.yml中的RunningHub配置 -grep -A 10 "runninghub:" src/main/resources/application.yml -``` - -**必须包含:** -```yaml -runninghub: - enabled: true - base-url: https://www.runninghub.cn - submit-url: /task/openapi/ai-app/run - status-url: /task/openapi/status - output-url: /task/openapi/outputs - default-webapp-id: "1973555977595301890" - api-key: "5c44cef12da3470e9f24da70c63787dc" - polling-interval: 5000 - max-polling-times: 120 -``` - ---- - -## 🗄️ 数据库部署 - -### 1. 执行迁移脚本 - -```bash -# 1. 备份数据库 -mysqldump -u root -p 1818ai > backup_before_v5_$(date +%Y%m%d_%H%M%S).sql - -# 2. 执行迁移 -mysql -u root -p 1818ai < V5__add_provider_support.sql - -# 3. 验证表结构 -mysql -u root -p 1818ai -e "DESC ai_task;" | grep provider -mysql -u root -p 1818ai -e "DESC points_config;" | grep provider -``` - -**预期输出:** -``` -provider_type | varchar(50) | YES | | NULL | -provider_task_id | varchar(100) | YES | | NULL | -provider_response | text | YES | | NULL | -``` - -### 2. 验证模型配置 - -```sql --- 查看插入的RunningHub模型数量 -SELECT COUNT(*) as rh_model_count -FROM points_config -WHERE provider_type = 'runninghub'; --- 预期结果:12 - --- 查看所有模型 -SELECT model_name, description, points_cost, provider_type -FROM points_config -WHERE provider_type = 'runninghub' -ORDER BY points_cost; -``` - ---- - -## 🔧 编译部署 - -### 1. 编译项目 - -```bash -# 清理并编译 -mvn clean package -DskipTests - -# 检查编译结果 -ls -lh target/1818_user_server-1.0-SNAPSHOT.jar -``` - -### 2. 部署到服务器 - -```bash -# 1. 停止服务 -sudo systemctl stop spring_1818_user_server - -# 2. 备份当前版本 -sudo cp /www/wwwroot/1818_user_server/1818_user_server-1.0-SNAPSHOT.jar \ - /www/wwwroot/1818_user_server/backups/1818_user_server-$(date +%Y%m%d_%H%M%S).jar - -# 3. 部署新版本 -sudo cp target/1818_user_server-1.0-SNAPSHOT.jar \ - /www/wwwroot/1818_user_server/ - -# 4. 启动服务 -sudo systemctl start spring_1818_user_server - -# 5. 查看启动日志 -sudo journalctl -u spring_1818_user_server -f --lines=100 -``` - ---- - -## ✅ 部署后验证 - -### 1. 服务启动检查 - -```bash -# 1. 检查进程 -ps aux | grep spring_1818_user_server - -# 2. 检查端口 -netstat -tlnp | grep 8081 - -# 3. 检查日志中的Provider注册 -sudo journalctl -u spring_1818_user_server | grep "注册AI Provider" -``` - -**预期日志输出:** -``` -注册AI Provider: openai, 异步: false -注册AI Provider: runninghub, 异步: true -``` - -### 2. Provider初始化检查 - -```bash -# 查看日志确认Provider初始化成功 -sudo journalctl -u spring_1818_user_server | grep -E "(Provider|AIProviderService)" | tail -20 -``` - -**预期日志:** -``` -INFO AIProviderService - 注册AI Provider: openai, 异步: false -INFO AIProviderService - 注册AI Provider: runninghub, 异步: true -INFO RunningHubPollingScheduler - RunningHub轮询调度器已启动 -``` - -### 3. API健康检查 - -```bash -# 检查服务健康 -curl http://localhost:8081/actuator/health - -# 预期响应 -{"status":"UP"} -``` - ---- - -## 🧪 功能测试 - -### 测试1:OpenAI模型(兼容性测试) - -```bash -# 提交OpenAI模型任务 -curl -X POST "http://localhost:8081/user/ai/tasks/submit" \ - -H "Authorization: Bearer YOUR_JWT_TOKEN" \ - -H "Content-Type: application/json" \ - -d '{ - "modelName": "sora_image", - "prompt": "测试猫咪图片" - }' | jq '.' -``` - -**验证点:** -- [ ] 返回200状态码 -- [ ] 返回taskNo -- [ ] status为"queued"或"processing" -- [ ] 30秒内任务完成 - -### 测试2:RunningHub文生视频 - -```bash -# 提交RunningHub文生视频任务 -RESPONSE=$(curl -X POST "http://localhost:8081/user/ai/tasks/submit" \ - -H "Authorization: Bearer YOUR_JWT_TOKEN" \ - -H "Content-Type: application/json" \ - -d '{ - "modelName": "rh_sora2_text_portrait", - "prompt": "一个人在海边奔跑" - }') - -echo $RESPONSE | jq '.' - -# 提取taskNo -TASK_NO=$(echo $RESPONSE | jq -r '.data.taskNo') -echo "TaskNo: $TASK_NO" -``` - -**验证点:** -- [ ] 返回200状态码 -- [ ] 返回taskNo -- [ ] status为"processing" -- [ ] 查看数据库确认provider_type='runninghub' - -```sql -SELECT task_no, model_name, provider_type, provider_task_id, status -FROM ai_task -WHERE task_no = 'YOUR_TASK_NO'; -``` - -### 测试3:RunningHub图生视频 - -```bash -# 提交RunningHub图生视频任务 -curl -X POST "http://localhost:8081/user/ai/tasks/submit" \ - -H "Authorization: Bearer YOUR_JWT_TOKEN" \ - -H "Content-Type: application/json" \ - -d '{ - "modelName": "rh_sora2_img_landscape", - "prompt": "让场景动起来", - "imageUrl": "https://example.com/test-image.jpg" - }' | jq '.' -``` - -**验证点:** -- [ ] 返回200状态码 -- [ ] 任务提交成功 -- [ ] 查看日志确认image节点包含完整URL - -```bash -sudo journalctl -u spring_1818_user_server | grep "RunningHub Provider - 请求体" | tail -1 -``` - -### 测试4:轮询机制 - -```bash -# 实时查看轮询日志 -sudo journalctl -u spring_1818_user_server -f | grep "RunningHub轮询" -``` - -**验证点:** -- [ ] 每5秒输出一次轮询日志 -- [ ] 显示待处理任务数量 -- [ ] 任务状态正确更新(QUEUED → RUNNING → SUCCESS) - ---- - -## 📊 监控指标 - -### 1. 任务状态分布 - -```sql -SELECT - provider_type, - status, - COUNT(*) as count -FROM ai_task -WHERE create_time > DATE_SUB(NOW(), INTERVAL 1 HOUR) -GROUP BY provider_type, status; -``` - -### 2. 平均处理时间 - -```sql -SELECT - provider_type, - model_name, - AVG(TIMESTAMPDIFF(SECOND, start_time, complete_time)) as avg_seconds, - COUNT(*) as total_tasks -FROM ai_task -WHERE status = 'completed' - AND create_time > DATE_SUB(NOW(), INTERVAL 24 HOUR) -GROUP BY provider_type, model_name; -``` - -### 3. 失败任务分析 - -```sql -SELECT - provider_type, - error_message, - COUNT(*) as error_count -FROM ai_task -WHERE status = 'failed' - AND create_time > DATE_SUB(NOW(), INTERVAL 24 HOUR) -GROUP BY provider_type, error_message -ORDER BY error_count DESC; -``` - ---- - -## 🔧 常见问题排查 - -### 问题1:Provider未注册 - -**症状:** 日志中没有"注册AI Provider" -**排查:** -```bash -# 检查是否有编译错误 -sudo journalctl -u spring_1818_user_server | grep -i "error" | tail -20 - -# 检查Provider类是否加载 -sudo journalctl -u spring_1818_user_server | grep "Provider" | tail -30 -``` - -### 问题2:RunningHub任务卡在processing - -**排查:** -```bash -# 1. 检查轮询是否正常 -sudo journalctl -u spring_1818_user_server | grep "轮询" | tail -10 - -# 2. 检查网络连接 -curl -I https://www.runninghub.cn/task/openapi/status - -# 3. 手动查询任务状态 -curl -X POST "https://www.runninghub.cn/task/openapi/status" \ - -H "Content-Type: application/json" \ - -d '{ - "apiKey": "YOUR_API_KEY", - "taskId": "PROVIDER_TASK_ID" - }' | jq '.' -``` - -### 问题3:图生视频失败 - -**排查:** -```bash -# 查看详细错误日志 -sudo journalctl -u spring_1818_user_server | grep -A 5 "图生视频" - -# 检查提交的请求体 -sudo journalctl -u spring_1818_user_server | grep "RunningHub Provider - 请求体" -``` - -**常见原因:** -- 图片URL无法访问 -- 图片包含真人(RunningHub不支持) -- 未提供imageUrl或imageBase64 - ---- - -## 📋 回滚方案 - -如果部署后发现问题,可以快速回滚: - -```bash -# 1. 停止服务 -sudo systemctl stop spring_1818_user_server - -# 2. 恢复旧版本 -sudo cp /www/wwwroot/1818_user_server/backups/1818_user_server_BACKUP_TIME.jar \ - /www/wwwroot/1818_user_server/1818_user_server-1.0-SNAPSHOT.jar - -# 3. 回滚数据库(如果需要) -mysql -u root -p 1818ai < backup_before_v5_TIMESTAMP.sql - -# 4. 启动服务 -sudo systemctl start spring_1818_user_server -``` - ---- - -## ✅ 部署成功标志 - -全部验证通过后,确认以下所有项: - -- [x] **服务正常启动** - - 进程存在 - - 端口8081监听 - - 日志无ERROR - -- [x] **Provider注册成功** - - 日志显示openai和runninghub都已注册 - - AIProviderService初始化完成 - -- [x] **数据库表结构正确** - - ai_task包含provider_*字段 - - points_config包含provider_*字段 - - 12个RunningHub模型已插入 - -- [x] **OpenAI模型正常**(兼容性) - - 能提交任务 - - 能正常完成 - - 积分正确扣除 - -- [x] **RunningHub文生视频正常** - - 能提交任务 - - provider_task_id正确保存 - - 轮询机制工作 - - 2-5分钟后获得结果 - -- [x] **RunningHub图生视频正常** - - 支持imageUrl参数 - - image节点正确构建 - - 能够完成任务 - -- [x] **轮询调度器正常** - - 每5秒执行一次 - - 正确更新任务状态 - - 失败任务自动退款 - ---- - -## 📞 技术支持 - -如有问题,请提供以下信息: - -1. 错误日志(最近100行) -2. 数据库中的任务记录 -3. 具体的API请求和响应 -4. 环境信息(Java版本、MySQL版本等) - -**祝部署顺利!** 🚀 - diff --git a/FIX_V5_provider_type.sql b/FIX_V5_provider_type.sql deleted file mode 100644 index 11b4ccd..0000000 --- a/FIX_V5_provider_type.sql +++ /dev/null @@ -1,20 +0,0 @@ --- ============================================================ --- 修复脚本:更新V5中provider_type的值 --- 问题:V5插入的RunningHub模型provider_type为空字符串,应为'runninghub' --- 执行时间:2025-10-20 --- ============================================================ - --- 更新所有RunningHub模型的provider_type -UPDATE `points_config` -SET `provider_type` = 'runninghub' -WHERE `model_name` LIKE 'rh_sora2_%' - AND (`provider_type` = '' OR `provider_type` IS NULL); - --- 验证更新结果 -SELECT model_name, provider_type, description -FROM `points_config` -WHERE `model_name` LIKE 'rh_sora2_%'; - --- 预期结果:所有RunningHub模型的provider_type应为'runninghub' - - diff --git a/FIX_ai_task_type.sql b/FIX_ai_task_type.sql deleted file mode 100644 index 5d1ef5b..0000000 --- a/FIX_ai_task_type.sql +++ /dev/null @@ -1,25 +0,0 @@ --- ============================================================ --- 修复AI任务的task_type字段 --- 描述: 将ai_task表中的task_type从points_config表中同步过来 --- 作者: 1818AI --- 日期: 2025-10-23 --- ============================================================ - -USE `1818ai`; - --- 更新ai_task表的task_type字段,从points_config表中获取正确的值 -UPDATE ai_task a -INNER JOIN points_config p ON a.model_name = p.model_name -SET a.task_type = p.task_type -WHERE a.task_type IN ('unknown', 'video', 'image', 'other') - AND p.task_type IS NOT NULL - AND p.task_type != ''; - --- 查看更新结果 -SELECT - model_name, - task_type, - COUNT(*) as count -FROM ai_task -GROUP BY model_name, task_type -ORDER BY model_name; diff --git a/FIX_task_type_data.sql b/FIX_task_type_data.sql deleted file mode 100644 index e312cf2..0000000 --- a/FIX_task_type_data.sql +++ /dev/null @@ -1,67 +0,0 @@ --- ================================================================= --- 修复 points_config 表的 task_type 数据 --- 时间: 2025-10-22 --- 描述: 修正所有模型的 task_type 分类 --- ================================================================= - --- 指定数据库 -USE `1818_user_server`; - --- 1. 修正 RunningHub Sora2 文生视频模型 -UPDATE `points_config` -SET `task_type` = 'text_to_video' -WHERE `model_name` IN ( - 'rh_sora2_text_portrait', -- RunningHub 文生视频-竖屏 - 'rh_sora2_text_landscape', -- RunningHub 文生视频-横屏 - 'rh_sora2_text_portrait_hd', -- RunningHub 文生视频-高清竖屏 - 'rh_sora2_text_landscape_hd', -- RunningHub 文生视频-高清横屏 - 'rh_sora2_text_portrait_15s', -- RunningHub 文生视频-竖屏15秒 - 'rh_sora2_text_landscape_15s' -- RunningHub 文生视频-横屏15秒 -); - --- 2. 修正 RunningHub Sora2 图生视频模型 -UPDATE `points_config` -SET `task_type` = 'image_to_video' -WHERE `model_name` IN ( - 'rh_sora2_img_portrait', -- RunningHub 图生视频-竖屏 - 'rh_sora2_img_landscape', -- RunningHub 图生视频-横屏 - 'rh_sora2_img_portrait_hd', -- RunningHub 图生视频-高清竖屏 - 'rh_sora2_img_landscape_hd', -- RunningHub 图生视频-高清横屏 - 'rh_sora2_img_portrait_15s', -- RunningHub 图生视频-竖屏15秒 - 'rh_sora2_img_landscape_15s' -- RunningHub 图生视频-横屏15秒 -); - --- 3. 修正其他已知模型 -UPDATE `points_config` -SET `task_type` = 'text_to_image' -WHERE `model_name` IN ('sora_image', 'gpt-4o-image'); - -UPDATE `points_config` -SET `task_type` = 'text_to_video' -WHERE `model_name` IN ( - 'sora_video2', -- 竖屏10秒 - 'sora_video2-landscape', -- 横屏10秒 - 'sora_video2-15s', -- 竖屏15秒 - 'sora_video2-landscape-15s', -- 横屏15秒 - 'sora-2-pro-all' -- Sora Pro高清视频 -); - --- 4. 验证更新结果 -SELECT - model_name, - provider_type, - task_type, - description -FROM points_config -WHERE is_deleted = 0 -ORDER BY provider_type, task_type, model_name; - --- 5. 统计各类型的模型数量 -SELECT - task_type, - provider_type, - COUNT(*) as count -FROM points_config -WHERE is_deleted = 0 AND is_enabled = 1 -GROUP BY task_type, provider_type -ORDER BY task_type, provider_type; diff --git a/IMPLEMENTATION_SUMMARY.md b/IMPLEMENTATION_SUMMARY.md deleted file mode 100644 index 0320958..0000000 --- a/IMPLEMENTATION_SUMMARY.md +++ /dev/null @@ -1,406 +0,0 @@ -# 积分充值系统实现总结 - -## ✅ 功能完成情况 - -### 已完成的功能模块 - -#### 1. 数据库层 ✅ -- ✅ 创建 `points_package` 表(积分套餐) -- ✅ 扩展 `order` 表支持积分订单 -- ✅ 插入6个默认积分套餐 -- ✅ 添加系统配置参数 -- ✅ 创建充值统计视图 - -**文件**:`V6__add_points_recharge_system.sql` - ---- - -#### 2. 实体类层 ✅ -- ✅ `PointsPackage` - 积分套餐实体 -- ✅ `Order` - 扩展支持积分订单字段 -- ✅ `PointsRechargeDto` - 充值相关DTO - -**文件**: -- `src/main/java/com/dora/entity/PointsPackage.java` -- `src/main/java/com/dora/entity/Order.java`(已扩展) -- `src/main/java/com/dora/dto/PointsRechargeDto.java` - ---- - -#### 3. 数据访问层 ✅ -- ✅ `PointsPackageMapper` - 套餐CRUD -- ✅ `OrderMapper` - 扩展积分订单查询 -- ✅ `OrderMapperExt.xml` - 积分订单XML映射 - -**文件**: -- `src/main/java/com/dora/mapper/PointsPackageMapper.java` -- `src/main/java/com/dora/mapper/OrderMapper.java`(已扩展) -- `src/main/resources/mapper/OrderMapperExt.xml` - ---- - -#### 4. 业务逻辑层 ✅ -- ✅ `PointsRechargeService` - 充值服务接口 -- ✅ `PointsRechargeServiceImpl` - 充值服务实现 - - ✅ 套餐查询 - - ✅ 订单创建 - - ✅ 首充奖励(10%) - - ✅ 支付成功处理 - - ✅ 积分到账 - - ✅ 充值记录 - - ✅ 充值统计 - -**文件**: -- `src/main/java/com/dora/service/PointsRechargeService.java` -- `src/main/java/com/dora/service/impl/PointsRechargeServiceImpl.java` - ---- - -#### 5. 控制器层 ✅ -- ✅ `PointsRechargeController` - 用户端充值接口 - - ✅ 获取套餐列表 - - ✅ 获取热门套餐 - - ✅ 创建充值订单 - - ✅ 查询充值记录 - - ✅ 查询充值统计 -- ✅ `PaymentCallbackController` - 支付回调接口 - - ✅ 支付宝回调 - - ✅ 微信支付回调 - - ✅ 测试回调(开发用) - -**文件**: -- `src/main/java/com/dora/controller/PointsRechargeController.java` -- `src/main/java/com/dora/controller/PaymentCallbackController.java` - ---- - -#### 6. 安全配置 ✅ -- ✅ 开放套餐浏览接口(公开访问) -- ✅ 开放支付回调接口(第三方调用) -- ✅ 保护充值操作接口(需要登录) - -**文件**:`src/main/java/com/dora/config/SecurityConfig.java`(已更新) - ---- - -## 📊 数据表结构 - -### points_package(积分套餐表) - -| 字段 | 类型 | 说明 | -|------|------|------| -| id | bigint | 主键 | -| name | varchar(64) | 套餐名称 | -| points | int | 基础积分 | -| bonus_points | int | 赠送积分 | -| total_points | int | 总积分 | -| price | decimal(10,2) | 价格 | -| original_price | decimal(10,2) | 原价 | -| is_hot | tinyint(1) | 是否热门 | -| is_active | tinyint(1) | 是否上架 | - -### order(订单表 - 已扩展) - -| 新增字段 | 类型 | 说明 | -|---------|------|------| -| order_type | tinyint | 1-会员订单/2-积分订单 | -| points_package_id | bigint | 积分套餐ID | -| points_amount | int | 积分数量 | - ---- - -## 🔌 API接口清单 - -### 用户端接口 - -| 接口 | 方法 | 权限 | 说明 | -|------|------|------|------| -| /user/points/packages | GET | 公开 | 获取套餐列表 | -| /user/points/packages/hot | GET | 公开 | 获取热门套餐 | -| /user/points/packages/{id} | GET | 公开 | 获取套餐详情 | -| /user/points/recharge | POST | 登录 | 创建充值订单 | -| /user/points/recharge/records | GET | 登录 | 获取充值记录 | -| /user/points/recharge/stats | GET | 登录 | 获取充值统计 | - -### 支付回调接口 - -| 接口 | 方法 | 权限 | 说明 | -|------|------|------|------| -| /payment/callback/alipay | POST | 公开 | 支付宝回调 | -| /payment/callback/wechat | POST | 公开 | 微信支付回调 | -| /payment/callback/test | POST | 公开 | 测试回调 | - ---- - -## 🔄 业务流程 - -### 充值流程 - -``` -1. 用户浏览套餐 - ↓ -2. 选择套餐,选择支付方式 - ↓ -3. 创建订单(计算首充奖励) - ↓ -4. 生成支付参数 - ↓ -5. 调起支付(支付宝/微信) - ↓ -6. 用户完成支付 - ↓ -7. 支付平台回调通知 - ↓ -8. 验证签名 - ↓ -9. 更新用户积分 - ↓ -10. 更新订单状态 - ↓ -11. 记录变动日志 - ↓ -12. 用户查看充值成功 -``` - ---- - -## 💡 核心特性 - -### 1. 首充奖励 -- 自动识别首次充值 -- 额外赠送10%积分 -- 记录在订单的 `discountDescription` 字段 - -### 2. 套餐赠送 -- 每个套餐可配置赠送积分 -- `total_points = points + bonus_points` -- 示例:标准包 500基础+50赠送=550积分 - -### 3. 积分有效期 -- 默认365天 -- 可配置 -- 支持延长(多次充值累加) - -### 4. 安全机制 -- JWT身份认证 -- 支付签名验证 -- 订单防重复处理 -- 事务保证一致性 - ---- - -## 📁 项目文件清单 - -### 新增文件(18个) - -#### 数据库 -- `V6__add_points_recharge_system.sql` - -#### 实体类 -- `src/main/java/com/dora/entity/PointsPackage.java` - -#### DTO -- `src/main/java/com/dora/dto/PointsRechargeDto.java` - -#### Mapper -- `src/main/java/com/dora/mapper/PointsPackageMapper.java` -- `src/main/resources/mapper/OrderMapperExt.xml` - -#### Service -- `src/main/java/com/dora/service/PointsRechargeService.java` -- `src/main/java/com/dora/service/impl/PointsRechargeServiceImpl.java` - -#### Controller -- `src/main/java/com/dora/controller/PointsRechargeController.java` -- `src/main/java/com/dora/controller/PaymentCallbackController.java` - -#### 文档 -- `POINTS_RECHARGE_GUIDE.md` - 完整使用指南 -- `QUICK_START_POINTS_RECHARGE.md` - 快速启动 -- `IMPLEMENTATION_SUMMARY.md` - 实现总结(本文件) - -### 修改文件(3个) - -- `src/main/java/com/dora/entity/Order.java` - 添加积分订单字段 -- `src/main/java/com/dora/mapper/OrderMapper.java` - 添加积分订单查询方法 -- `src/main/java/com/dora/config/SecurityConfig.java` - 开放充值相关接口 - ---- - -## 🧪 测试清单 - -### 单元测试 -- [ ] PointsPackageMapper CRUD测试 -- [ ] OrderMapper 积分订单查询测试 -- [ ] PointsRechargeService 业务逻辑测试 - -### 集成测试 -- [x] 套餐列表查询 -- [x] 充值订单创建 -- [x] 支付回调处理 -- [x] 积分到账验证 -- [x] 首充奖励计算 -- [x] 充值记录查询 - -### 性能测试 -- [ ] 并发充值测试 -- [ ] 支付回调并发测试 -- [ ] 数据库连接池压力测试 - ---- - -## 🔧 待完善功能 - -### 1. 支付接口对接(重要) - -当前状态: -- ✅ 接口框架已完成 -- ❌ 支付宝SDK未集成 -- ❌ 微信支付SDK未集成 - -需要做: -```java -// TODO: 在 PointsRechargeServiceImpl 中实现 -private String generatePaymentParams(Order order, Integer paymentMethod) { - if (paymentMethod == 1) { - // 对接支付宝SDK - return generateAlipayParams(order); - } else { - // 对接微信支付SDK - return generateWechatPayParams(order); - } -} -``` - -### 2. 支付回调签名验证(重要) - -当前状态: -- ✅ 回调接口已完成 -- ❌ 签名验证未实现 - -需要做: -```java -// TODO: 在 PaymentCallbackController 中实现 -// 支付宝签名验证 -boolean signVerified = AlipaySignature.rsaCheckV1(params, ...); - -// 微信签名验证 -boolean signVerified = WXPayUtil.isSignatureValid(params, ...); -``` - -### 3. 订单超时处理 - -建议添加: -- 定时任务扫描超时未支付订单 -- 自动取消超时订单 -- 释放冻结资源 - -### 4. 支付失败重试 - -建议添加: -- 支付失败订单重试机制 -- 重试次数限制 -- 失败原因记录 - -### 5. 管理员功能 - -建议添加: -- 积分套餐管理(CRUD) -- 充值订单查询 -- 充值数据统计 -- 异常订单处理 - ---- - -## 📈 性能优化建议 - -### 1. 数据库优化 -- ✅ 已添加必要索引 -- 建议:分表存储历史订单(按月/年) -- 建议:Redis缓存热门套餐 - -### 2. 接口优化 -- 建议:套餐列表接口加缓存(Redis) -- 建议:充值记录分页优化 -- 建议:使用消息队列处理回调 - -### 3. 安全优化 -- 建议:限流防刷(单用户充值频率) -- 建议:订单防重(幂等性) -- 建议:支付回调IP白名单 - ---- - -## 🎯 部署检查清单 - -### 开发环境 -- [x] 数据库迁移脚本执行 -- [x] 默认套餐数据插入 -- [x] 接口功能测试 -- [x] 测试回调功能正常 - -### 生产环境(重要!) -- [ ] 支付宝商户配置 -- [ ] 微信支付商户配置 -- [ ] 支付回调URL配置(HTTPS) -- [ ] 支付密钥配置 -- [ ] 小额充值测试(¥0.01) -- [ ] 监控日志配置 -- [ ] 异常告警配置 - ---- - -## 📞 技术支持 - -### 遇到问题? - -1. **查看文档**: - - `POINTS_RECHARGE_GUIDE.md` - 完整指南 - - `QUICK_START_POINTS_RECHARGE.md` - 快速上手 - -2. **检查日志**: - ```bash - tail -f logs/application.log | grep "points\|recharge\|payment" - ``` - -3. **数据库检查**: - ```sql - -- 检查订单状态 - SELECT * FROM `order` WHERE order_type = 2 ORDER BY create_time DESC LIMIT 10; - - -- 检查用户积分 - SELECT id, username, points, points_expires_at FROM user WHERE id = ?; - - -- 检查积分变动 - SELECT * FROM points_consumption_log WHERE user_id = ? ORDER BY create_time DESC; - ``` - ---- - -## 🎉 总结 - -### 已实现 ✅ -- ✅ 完整的积分套餐系统 -- ✅ 充值订单创建流程 -- ✅ 支付回调处理框架 -- ✅ 积分自动到账 -- ✅ 首充奖励机制 -- ✅ 充值记录查询 -- ✅ 充值统计功能 -- ✅ 安全认证配置 - -### 待对接 ⏳ -- ⏳ 支付宝SDK集成 -- ⏳ 微信支付SDK集成 -- ⏳ 签名验证实现 - -### 建议扩展 💡 -- 💡 管理员套餐管理 -- 💡 订单超时处理 -- 💡 充值数据分析 -- 💡 营销活动支持 - ---- - -**系统已经可以运行,核心功能完整,只需对接真实支付接口即可上线!** 🚀 - diff --git a/MULTI_VENDOR_ADAPTER_DESIGN.md b/MULTI_VENDOR_ADAPTER_DESIGN.md deleted file mode 100644 index 6301170..0000000 --- a/MULTI_VENDOR_ADAPTER_DESIGN.md +++ /dev/null @@ -1,242 +0,0 @@ -# 多厂商AI API适配器设计方案 - -## 📋 目标 - -支持接入多个AI服务提供商,包括: -1. **OpenAI格式API**(当前使用的api.apiyi.com) -2. **RunningHub API** -3. 未来的其他厂商 - -## 🏗️ 架构设计 - -``` -┌─────────────────────────────────────────────────────────┐ -│ AiTaskService │ -│ (业务逻辑层,不变) │ -└────────────────────┬────────────────────────────────────┘ - │ - ▼ -┌─────────────────────────────────────────────────────────┐ -│ AIProviderService (新增) │ -│ 根据模型配置选择对应的Provider │ -└────────────────────┬────────────────────────────────────┘ - │ - ┌───────────┴───────────┐ - ▼ ▼ -┌──────────────────┐ ┌──────────────────┐ -│ OpenAIProvider │ │ RunningHubProvider│ -│ (适配器1) │ │ (适配器2) │ -└──────────────────┘ └──────────────────┘ - │ │ - ▼ ▼ -┌──────────────────┐ ┌──────────────────┐ -│ api.apiyi.com │ │ www.runninghub.cn│ -│ (第三方API) │ │ (第三方API) │ -└──────────────────┘ └──────────────────┘ -``` - -## 📝 实现步骤 - -### 1. 定义统一的Provider接口 - -```java -public interface AIProvider { - /** - * 提交任务到AI服务商 - * @return 统一的任务响应对象 - */ - ProviderTaskResponse submitTask(ProviderTaskRequest request); - - /** - * 查询任务状态 - */ - ProviderTaskStatus queryTaskStatus(String providerTaskId); - - /** - * 获取任务结果 - */ - ProviderTaskResult getTaskResult(String providerTaskId); - - /** - * 获取服务商名称 - */ - String getProviderName(); -} -``` - -### 2. 扩展数据库表 - -#### points_config表新增字段 -```sql -ALTER TABLE `points_config` -ADD COLUMN `provider_type` VARCHAR(50) NOT NULL DEFAULT 'openai' - COMMENT 'AI服务提供商类型:openai, runninghub', -ADD COLUMN `provider_config` TEXT NULL - COMMENT '服务商特定配置(JSON格式)'; -``` - -#### ai_task表新增字段 -```sql -ALTER TABLE `ai_task` -ADD COLUMN `provider_type` VARCHAR(50) NULL - COMMENT 'AI服务提供商类型', -ADD COLUMN `provider_task_id` VARCHAR(100) NULL - COMMENT '服务商返回的任务ID', -ADD COLUMN `provider_response` TEXT NULL - COMMENT '服务商原始响应(JSON)'; -``` - -### 3. 配置文件扩展 - -```yaml -# application.yml -ai: - providers: - openai: - enabled: true - base-url: https://api.apiyi.com/v1/chat/completions - api-key: sk-xxx - timeout: 300000 - runninghub: - enabled: true - base-url: https://www.runninghub.cn - submit-url: /task/openapi/ai-app/run - status-url: /task/openapi/status - output-url: /task/openapi/outputs - default-webapp-id: "1973555977595301890" - api-key: 5c44cef12da3470e9f24da70c63787dc - polling-interval: 5000 # 轮询间隔(毫秒) - max-polling-times: 120 # 最大轮询次数(10分钟) -``` - -## 🔧 RunningHub特殊处理 - -### 模型映射配置 - -在`points_config`表中配置RunningHub模型: - -```sql -INSERT INTO `points_config` -(model_name, points_cost, description, is_enabled, provider_type, provider_config) -VALUES -('rh_sora2_portrait', 160, 'RunningHub Sora2 竖屏视频', 1, 'runninghub', - '{"webappId":"1973555977595301890","duration":10,"model":"portrait"}'), - -('rh_sora2_landscape', 160, 'RunningHub Sora2 横屏视频', 1, 'runninghub', - '{"webappId":"1973555977595301890","duration":10,"model":"landscape"}'), - -('rh_sora2_portrait_hd', 420, 'RunningHub Sora2 高清竖屏', 1, 'runninghub', - '{"webappId":"1973555977595301890","duration":10,"model":"portrait-hd"}'); -``` - -### 异步任务处理流程 - -RunningHub是异步API,需要特殊处理: - -``` -1. 提交任务 → 获得taskId -2. 更新数据库:provider_task_id = taskId, status = 'processing' -3. 启动轮询任务: - - 每5秒查询一次状态 - - RUNNING → 继续轮询 - - SUCCESS → 获取结果 → 更新status='completed' - - FAILED → 更新status='failed' - - 超时 → 更新status='failed' -``` - -## 📦 核心类设计 - -### ProviderTaskRequest(统一请求) -```java -@Data -public class ProviderTaskRequest { - private String modelName; - private String prompt; - private String imageUrl; - private String imageBase64; - private String aspectRatio; - private Integer duration; // 视频时长 - private Map extraParams; // 扩展参数 -} -``` - -### ProviderTaskResponse(统一响应) -```java -@Data -public class ProviderTaskResponse { - private String providerTaskId; // 服务商任务ID - private TaskSubmitStatus status; // SUBMITTED, PROCESSING, COMPLETED, FAILED - private String resultUrl; // 如果是同步返回,直接有结果 - private String errorMessage; - private Map rawResponse; // 原始响应 -} -``` - -### RunningHubNodeInfo(RunningHub请求节点) -```java -@Data -public class RunningHubNodeInfo { - private String nodeId; - private String fieldName; - private String fieldValue; - private String fieldData; // 可选 - private String description; -} -``` - -## 🔄 任务轮询设计 - -### 新增定时任务 -```java -@Scheduled(fixedDelay = 5000) // 每5秒执行一次 -public void pollAsyncTasks() { - // 1. 查询所有 status='processing' 且 provider_type='runninghub' 的任务 - // 2. 对每个任务调用 queryTaskStatus - // 3. 根据状态更新数据库 - // 4. 如果完成,调用 getTaskResult 获取结果 -} -``` - -## 📊 数据流转 - -### OpenAI格式(同步) -``` -用户提交 → OpenAIProvider.submitTask() - → 直接返回结果URL - → 更新status='completed' -``` - -### RunningHub格式(异步) -``` -用户提交 → RunningHubProvider.submitTask() - → 返回taskId,status='RUNNING' - → 定时任务轮询 - → 检测到SUCCESS - → getTaskResult()获取结果URL - → 更新status='completed' -``` - -## ⚠️ 注意事项 - -1. **配置隔离**:不同厂商的配置独立管理 -2. **错误处理**:统一异常类型,便于业务层处理 -3. **日志记录**:记录每次API调用的原始请求和响应 -4. **超时控制**:异步任务需要设置最大轮询次数 -5. **并发控制**:轮询任务需要考虑并发和限流 -6. **配置热更新**:支持动态切换服务商 - -## 🎯 优势 - -1. ✅ **扩展性**:新增厂商只需实现AIProvider接口 -2. ✅ **解耦**:业务层无需关心底层API差异 -3. ✅ **灵活性**:同一个模型类型可以配置多个厂商 -4. ✅ **可维护性**:每个厂商的逻辑独立封装 -5. ✅ **容错性**:某个厂商故障不影响其他厂商 - -## 📈 未来扩展 - -- 支持厂商负载均衡 -- 支持厂商降级和熔断 -- 支持厂商价格对比和智能选择 -- 支持多厂商并行调用(取最快) - diff --git a/OPTIMIZATION_COMPLETE_v2.2.0.md b/OPTIMIZATION_COMPLETE_v2.2.0.md deleted file mode 100644 index ec939f7..0000000 --- a/OPTIMIZATION_COMPLETE_v2.2.0.md +++ /dev/null @@ -1,498 +0,0 @@ -# RunningHub优化完成总结 - v2.2.0 - -**完成时间:** 2025-10-20 -**任务状态:** ✅ 全部完成 -**版本号:** v2.2.0 - ---- - -## 🎯 任务回顾 - -### 用户需求 -> "要求runninghub同时只能轮询100个任务,超过就放队列中,等待轮询队列出现空位再继续提交任务。优化系统。" - -### 实现目标 -1. ✅ 限制RunningHub并发轮询任务数为100个 -2. ✅ 超出任务自动进入等待队列 -3. ✅ 任务完成后自动处理等待队列 -4. ✅ 提供管理员监控接口 -5. ✅ 完善的日志和文档 - ---- - -## 📦 交付成果 - -### 1. 核心代码(7个文件) - -#### 新增文件(4个) - -✅ **`RunningHubQueueService.java`** (62行) -- 队列管理服务接口 -- 定义核心队列操作方法 - -✅ **`RunningHubQueueServiceImpl.java`** (313行) -- 队列管理服务实现 -- 并发控制逻辑 -- 自动提交/退款机制 - -✅ **`RunningHubQueueProcessor.java`** (70行) -- 定时队列处理器 -- 每5秒检查等待队列 -- 自动提交新任务 - -✅ **`AdminRunningHubQueueController.java`** (103行) -- 管理员监控接口 -- 队列状态查询 -- 手动处理队列 - -#### 修改文件(3个) - -✅ **`application.yml`** -- 添加 `max-polling-tasks: 100` -- 添加 `queue-check-interval: 5000` - -✅ **`AiTaskServiceImpl.java`** -- 注入 `RunningHubQueueService` -- 使用队列服务提交任务 - -✅ **`RunningHubPollingScheduler.java`** -- 任务完成时通知队列服务 -- 触发等待队列处理 - -### 2. 文档(4个) - -✅ **`RUNNINGHUB_QUEUE_OPTIMIZATION.md`** (~600行) -- 问题分析 -- 架构设计 -- 实现细节 -- 性能对比 -- 配置调优 -- 故障排查 - -✅ **`RELEASE_NOTES_v2.2.0.md`** (~500行) -- 版本亮点 -- 性能对比 -- 新增功能详解 -- 部署指南 -- 升级注意事项 - -✅ **`QUICK_REFERENCE.md`** (更新) -- 添加队列监控命令 -- 更新常见问题解答 -- 添加队列相关说明 - -✅ **`OPTIMIZATION_COMPLETE_v2.2.0.md`** (本文档) -- 任务总结 -- 技术亮点 -- 测试验证 - ---- - -## 💡 技术亮点 - -### 1. 并发控制架构 - -``` -┌─────────────────────────────────────────────────┐ -│ 用户提交任务 │ -└─────────────────┬───────────────────────────────┘ - ↓ -┌─────────────────────────────────────────────────┐ -│ RunningHubQueueService.enqueueOrSubmit() │ -├─────────────────────────────────────────────────┤ -│ 检查当前轮询任务数 │ -│ ├─ <100 → 立即提交到RunningHub │ -│ │ 加入pollingTasks集合 │ -│ │ 返回"processing" │ -│ │ │ -│ └─ >=100 → 加入waitingQueue │ -│ 返回"queued" │ -└─────────────────┬───────────────────────────────┘ - ↓ -┌─────────────────────────────────────────────────┐ -│ 任务在RunningHub处理(2-5分钟) │ -└─────────────────┬───────────────────────────────┘ - ↓ -┌─────────────────────────────────────────────────┐ -│ RunningHubPollingScheduler检测到完成 │ -├─────────────────────────────────────────────────┤ -│ 更新任务状态 → 发送通知 │ -│ 调用 onTaskCompleted(taskNo) │ -│ ↓ │ -│ 从pollingTasks移除 │ -│ 调用 processWaitingQueue() │ -│ ↓ │ -│ 从waitingQueue取出任务 → 提交到RunningHub │ -└─────────────────────────────────────────────────┘ -``` - -### 2. 线程安全保证 - -**使用 `synchronized` 保证原子操作:** - -```java -public synchronized boolean enqueueOrSubmit(AiTask task) { - // 原子操作:检查 + 提交/入队 - if (pollingTasks.size() < maxPollingTasks) { - 提交(); - pollingTasks.put(taskNo, task); - return true; - } - waitingQueue.offer(task); - return false; -} - -public synchronized void onTaskCompleted(String taskNo) { - // 原子操作:移除 + 处理队列 - pollingTasks.remove(taskNo); - processWaitingQueue(); -} -``` - -**线程安全的数据结构:** -- `ConcurrentHashMap` - 存储轮询任务 -- `LinkedBlockingQueue` - 存储等待队列 - -### 3. 自动调度机制 - -**两个定时任务:** - -1. **队列处理器**(5秒间隔) - ```java - @Scheduled(fixedDelay = 5000) - public void processWaitingQueue() { - if (有空位 && 队列不为空) { - 从队列提交新任务(); - } - } - ``` - -2. **轮询调度器**(10秒间隔) - ```java - @Scheduled(fixedDelay = 10000) - public void pollRunningHubTasks() { - 查询所有processing任务的状态(); - if (完成) { - 通知队列服务(); // 触发等待队列处理 - } - } - ``` - -### 4. 监控与可观测性 - -**管理员接口:** -```bash -# 查看队列状态 -GET /admin/runninghub/queue/status - -响应: -{ - "maxPollingTasks": 100, - "currentPollingTasks": 85, - "waitingQueueSize": 120, - "availableSlots": 15, - "utilizationRate": "85.0%" -} - -# 手动处理队列 -GET /admin/runninghub/queue/process -``` - -**日志记录:** -``` -RunningHub队列状态 - 正在轮询: 85/100, 等待队列: 120 -任务 TASK_001 立即提交到RunningHub,当前轮询数: 86/100 -任务 TASK_002 加入等待队列,队列位置: 121 -从等待队列提交任务 TASK_003 到RunningHub,当前轮询: 100/100, 剩余队列: 120 -任务 TASK_001 已完成,从轮询列表移除,当前轮询: 99/100 -``` - ---- - -## 📊 性能验证 - -### 测试场景:500并发任务 - -| 指标 | v2.1.1(旧) | v2.2.0(新) | 改善 | -|-----|------------|------------|-----| -| CPU使用率 | 50% | 10% | ↓80% | -| 内存占用 | 5GB | 2GB | ↓60% | -| 轮询任务数 | 500 | 100 | 固定 | -| 等待队列 | 0 | 400 | 自动管理 | -| 系统状态 | 过载 | 正常 | ✅ 稳定 | -| 崩溃风险 | 高 | 无 | ✅ 消除 | - -### 实际测试结果 - -```bash -# 提交500个任务 -for i in {1..500}; do - curl -X POST "http://localhost:8081/user/ai/tasks/submit" \ - -H "Authorization: Bearer $TOKEN" \ - -d '{"modelName":"rh_sora2_text_portrait","prompt":"测试'$i'"}' -done - -# 查看队列状态 -curl "http://localhost:8081/admin/runninghub/queue/status" - -# 结果: -{ - "maxPollingTasks": 100, - "currentPollingTasks": 100, // 轮询满载 - "waitingQueueSize": 400, // 400个等待 - "availableSlots": 0, - "utilizationRate": "100.0%" -} - -# 系统资源: -CPU: 10% (稳定) -内存: 2.1GB (可控) -``` - ---- - -## ✅ 完成清单 - -### 功能实现 - -- [x] 轮询任务数限制(100个上限) -- [x] 等待队列管理(FIFO) -- [x] 自动任务调度(任务完成后提交新任务) -- [x] 线程安全保证(synchronized + 并发数据结构) -- [x] 监控接口(队列状态查询) -- [x] 手动干预(管理员处理队列) -- [x] 日志记录(详细的队列操作日志) -- [x] 用户通知(队列位置和预计等待时间) - -### 代码质量 - -- [x] 代码注释完整(中文) -- [x] 异常处理完善 -- [x] 日志记录详细 -- [x] 命名规范统一 -- [x] 线程安全保证 - -### 文档完整性 - -- [x] 架构设计文档 -- [x] 实现细节说明 -- [x] 配置调优指南 -- [x] 部署升级文档 -- [x] 故障排查手册 -- [x] 版本发布说明 - ---- - -## 🔧 部署验证 - -### 验证步骤 - -```bash -# 1. 编译检查 -mvn clean compile -DskipTests -# ✅ 编译成功,无错误 - -# 2. 检查配置文件 -grep -A 5 "runninghub:" src/main/resources/application.yml -# ✅ 包含 max-polling-tasks 和 queue-check-interval - -# 3. 检查新增文件 -find src/main/java/com/dora -name "*Queue*" -type f -# ✅ 4个新文件存在 - -# 4. 检查调度器启用 -grep "@EnableScheduling" src/main/java/com/dora/Application.java -# ✅ 已启用调度 - -# 5. 运行测试(准备部署) -mvn clean package -DskipTests -# ✅ 打包成功 -``` - ---- - -## 📚 文档索引 - -### 核心文档 - -1. **`RUNNINGHUB_QUEUE_OPTIMIZATION.md`** - **必读** - - 队列优化方案完整说明 - - 适合开发和运维人员 - -2. **`RELEASE_NOTES_v2.2.0.md`** - **必读** - - 版本更新说明 - - 部署升级指南 - -3. **`QUICK_REFERENCE.md`** - - 快速参考手册 - - 日常使用指南 - -### 其他相关文档 - -4. **`RUNNINGHUB_USAGE_GUIDE.md`** - - 12个模型使用指南 - -5. **`RUNNINGHUB_CONCURRENCY_ANALYSIS.md`** - - 并发能力深度分析 - -6. **`POLLING_INTERVAL_OPTIMIZATION.md`** - - 轮询间隔优化说明 - ---- - -## 💡 最佳实践建议 - -### 1. 监控建议 - -**每日检查:** -```sql --- 查看队列积压情况 -SELECT - DATE_FORMAT(create_time, '%Y-%m-%d %H:00') as hour, - COUNT(CASE WHEN status='queued' THEN 1 END) as queued, - COUNT(CASE WHEN status='processing' THEN 1 END) as processing, - COUNT(CASE WHEN status='completed' THEN 1 END) as completed -FROM ai_task -WHERE provider_type = 'runninghub' - AND create_time > DATE_SUB(NOW(), INTERVAL 24 HOUR) -GROUP BY hour -ORDER BY hour DESC; -``` - -**告警规则:** -```yaml -# 等待队列过长 -if (waitingQueueSize > 500) { - 发送告警通知(); - 考虑增加max_polling_tasks到150(); -} - -# 队列处理效率低 -if (完成任务数/小时 < 50) { - 检查RunningHub API状态(); -} -``` - -### 2. 配置建议 - -**低流量期(夜间):** -```yaml -max-polling-tasks: 50 # 降低并发,节省资源 -``` - -**高流量期(白天):** -```yaml -max-polling-tasks: 150 # 提高并发,快速处理 -``` - -**动态调整(可选):** -```java -// 根据RunningHub API响应时间动态调整 -if (平均响应时间 > 5秒) { - 减少max_polling_tasks(); -} else if (等待队列很长 && 响应正常) { - 增加max_polling_tasks(); -} -``` - ---- - -## 🎯 后续优化方向 - -### v2.3.0 计划功能 - -1. **优先级队列** - - VIP用户任务优先处理 - - 支持紧急任务插队 - -2. **Redis队列** - - 持久化队列数据 - - 支持分布式部署 - - 服务重启不丢失任务 - -3. **动态限流** - - 根据API响应时间自动调整并发 - - 智能熔断保护 - -4. **监控面板** - - 实时队列可视化 - - 任务处理趋势图 - - 性能指标仪表盘 - ---- - -## 📞 技术支持 - -### 常见问题 - -**Q1:队列一直堆积怎么办?** -```bash -# 1. 查看队列状态 -curl "http://localhost:8081/admin/runninghub/queue/status" - -# 2. 手动处理队列 -curl "http://localhost:8081/admin/runninghub/queue/process" - -# 3. 临时提高并发上限 -# 修改 application.yml: max-polling-tasks: 150 -# 重启服务 -``` - -**Q2:如何查看某个任务在队列中的位置?** -```sql -SELECT - task_no, - status, - queue_time, - @rank := @rank + 1 as queue_position -FROM ai_task, (SELECT @rank := 0) r -WHERE status = 'queued' - AND provider_type = 'runninghub' -ORDER BY queue_time; -``` - -**Q3:服务重启后队列任务会丢失吗?** -A:v2.2.0中会丢失(内存队列)。v2.3.0将使用Redis持久化解决此问题。 - ---- - -## ✅ 总结 - -### 优化成果 - -✅ **并发控制**:轮询任务固定在100个,CPU使用率稳定在10% -✅ **队列管理**:超出任务自动排队,支持无限并发 -✅ **自动调度**:任务完成后立即处理等待队列 -✅ **监控完善**:实时队列状态,管理员可手动干预 -✅ **文档齐全**:详细的设计、部署、运维文档 - -### 关键指标 - -| 指标 | 优化前 | 优化后 | 改善幅度 | -|-----|-------|-------|---------| -| 最大轮询任务数 | 无限制 | 100 | ✅ 可控 | -| 500并发CPU | 50% | 10% | ↓80% | -| 500并发内存 | 5GB | 2GB | ↓60% | -| 系统崩溃风险 | 高 | 无 | ✅ 消除 | -| 支持最大并发 | ~200 | 无限 | ✅ 无限 | - -### 用户体验 - -✅ 第1-100个任务:立即提交,无延迟 -✅ 第101+个任务:自动排队,可查看队列位置 -✅ 任务完成后:自动提交新任务,无需等待 -✅ 透明度高:管理员可实时监控队列状态 - ---- - -**RunningHub队列优化 v2.2.0 完成!** 🎉 -**系统现在可以安全处理任意数量的并发任务!** 🚀 - ---- - -**完成时间:** 2025-10-20 -**交付团队:** 1818AI技术团队 -**版本号:** v2.2.0 -**状态:** ✅ 已完成,可部署 - - diff --git a/POINTS_AND_MODELS_SUMMARY.md b/POINTS_AND_MODELS_SUMMARY.md deleted file mode 100644 index 34f255d..0000000 --- a/POINTS_AND_MODELS_SUMMARY.md +++ /dev/null @@ -1,556 +0,0 @@ -# 积分系统与AI模型管理完整功能总结 - -## 📋 目录 -1. [积分消费查询功能](#1-积分消费查询功能) -2. [AI模型列表查询功能](#2-ai模型列表查询功能) -3. [数据库迁移脚本](#3-数据库迁移脚本) -4. [API接口列表](#4-api接口列表) -5. [前端调用示例](#5-前端调用示例) - ---- - -## 1. 积分消费查询功能 - -### 功能概述 -用户可以查看自己的积分余额、消费明细和统计信息。 - -### 核心接口 - -#### 1.1 获取积分余额 -```http -GET /user/points/consumption/balance -Authorization: Bearer {token} -``` - -**响应示例:** -```json -{ - "code": 200, - "message": "success", - "data": { - "currentPoints": 1500, - "pointsExpiresAt": "2025-12-31T23:59:59", - "willExpireSoon": false, - "daysUntilExpire": 120 - } -} -``` - -#### 1.2 获取积分消费记录(分页) -```http -GET /user/points/consumption/logs?page=1&size=10&changeType=consume -Authorization: Bearer {token} -``` - -**参数说明:** -- `page`: 页码(默认1) -- `size`: 每页数量(默认10,最大100) -- `changeType`: 变动类型(可选) - - `recharge`: 充值 - - `consume`: 消费 - - `refund`: 退款 - - `admin_adjust`: 管理员调整 - -**响应示例:** -```json -{ - "code": 200, - "message": "success", - "data": { - "records": [ - { - "id": 1, - "taskNo": "TASK202510221234567890", - "changeType": "consume", - "changeTypeName": "消费", - "changeAmount": -10, - "balanceBefore": 1510, - "balanceAfter": 1500, - "description": "AI图片生成消费", - "createTime": "2025-10-22T10:30:00" - } - ], - "total": 100, - "page": 1, - "size": 10, - "totalPages": 10 - } -} -``` - -#### 1.3 获取积分统计 -```http -GET /user/points/consumption/stats -Authorization: Bearer {token} -``` - -**响应示例:** -```json -{ - "code": 200, - "message": "success", - "data": { - "currentPoints": 1500, - "totalRechargePoints": 2000, - "totalConsumePoints": 500, - "totalRefundPoints": 0, - "pointsExpiresAt": "2025-12-31T23:59:59" - } -} -``` - ---- - -## 2. AI模型列表查询功能 - -### 功能概述 -用户可以查看系统中所有可用的AI模型,支持按任务类型、厂商分组查询。 - -### 任务类型分类 - -#### 细致分类(数据库 task_type 字段) -- `text_to_image`: 文生图 -- `image_to_image`: 图生图 -- `text_to_video`: 文生视频 -- `image_to_video`: 图生视频 -- `llm`: 大语言模型 -- `text_to_audio`: 文生音频 -- `image_to_text`: 图生文 -- `other`: 其他 - -#### 粗略分类(兼容旧接口) -- `image`: 图片生成(包括 text_to_image 和 image_to_image) -- `video`: 视频生成(包括 text_to_video 和 image_to_video) -- `audio`: 音频生成 -- `text`: 文本生成 - -### 核心接口 - -#### 2.1 获取模型列表(支持筛选) -```http -GET /user/ai/models?taskType=text_to_image&provider=openai&enabledOnly=true -``` - -**参数说明:** -- `taskType`: 任务类型(可选) -- `provider`: 服务提供商(可选:openai/runninghub) -- `enabledOnly`: 是否只返回已启用的模型(默认true) - -**响应示例:** -```json -{ - "code": 200, - "message": "success", - "data": [ - { - "id": 1, - "modelName": "sora_image", - "displayName": "Sora高质量图片生成", - "description": "Sora高质量图片生成", - "pointsCost": 11, - "providerType": "openai", - "taskType": "text_to_image", - "isEnabled": true, - "extendedConfig": {} - } - ] -} -``` - -#### 2.2 按任务类型分组获取模型 -```http -GET /user/ai/models/group-by-type?provider=&enabledOnly=true -``` - -**响应示例:** -```json -{ - "code": 200, - "message": "success", - "data": [ - { - "taskType": "text_to_image", - "taskTypeName": "文生图", - "models": [ - { - "id": 1, - "modelName": "sora_image", - "displayName": "Sora高质量图片生成", - "pointsCost": 11, - "providerType": "openai", - "taskType": "text_to_image", - "isEnabled": true - } - ], - "count": 2 - }, - { - "taskType": "text_to_video", - "taskTypeName": "文生视频", - "models": [...], - "count": 4 - } - ] -} -``` - -#### 2.3 按厂商分组获取模型 -```http -GET /user/ai/models/group-by-provider?taskType=&enabledOnly=true -``` - -**响应示例:** -```json -{ - "code": 200, - "message": "success", - "data": [ - { - "providerType": "openai", - "providerName": "OpenAI", - "models": [...], - "count": 3 - }, - { - "providerType": "runninghub", - "providerName": "RunningHub", - "models": [...], - "count": 5 - } - ] -} -``` - -#### 2.4 获取模型统计 -```http -GET /user/ai/models/stats -``` - -**响应示例:** -```json -{ - "code": 200, - "message": "success", - "data": { - "totalModels": 10, - "enabledModels": 8, - "countByType": { - "text_to_image": 2, - "text_to_video": 4, - "image_to_video": 1, - "llm": 1 - }, - "countByProvider": { - "openai": 3, - "runninghub": 5 - } - } -} -``` - ---- - -## 3. 数据库迁移脚本 - -### V6: 积分充值系统 -- 创建 `points_package` 表(积分套餐) -- 扩展 `order` 表支持积分订单 -- 更新 `points_consumption_log` 表支持充值类型 - -### V7: 任务类型细分 -- 为 `points_config` 表添加 `task_type` 字段 -- 根据现有模型名称更新任务类型 -- 添加多种模型类型示例数据 -- 添加索引优化查询性能 - ---- - -## 4. API接口列表 - -### 4.1 积分消费查询(需要登录) -| 接口 | 方法 | 路径 | 说明 | -|------|------|------|------| -| 获取积分余额 | GET | `/user/points/consumption/balance` | 当前积分和过期时间 | -| 获取消费记录 | GET | `/user/points/consumption/logs` | 分页查询消费明细 | -| 获取积分统计 | GET | `/user/points/consumption/stats` | 累计充值、消费、退款 | - -### 4.2 AI模型查询(公开访问) -| 接口 | 方法 | 路径 | 说明 | -|------|------|------|------| -| 获取模型列表 | GET | `/user/ai/models` | 支持筛选和过滤 | -| 按类型分组 | GET | `/user/ai/models/group-by-type` | 按任务类型分组 | -| 按厂商分组 | GET | `/user/ai/models/group-by-provider` | 按服务提供商分组 | -| 获取统计信息 | GET | `/user/ai/models/stats` | 模型数量统计 | - ---- - -## 5. 前端调用示例 - -### 5.1 Vue 3 + TypeScript 示例 - -```typescript -// api/points.ts -import request from '@/utils/request' - -// 获取积分余额 -export function getPointsBalance() { - return request({ - url: '/user/points/consumption/balance', - method: 'get' - }) -} - -// 获取积分消费记录 -export function getConsumptionLogs(params: { - page?: number - size?: number - changeType?: 'recharge' | 'consume' | 'refund' | 'admin_adjust' -}) { - return request({ - url: '/user/points/consumption/logs', - method: 'get', - params - }) -} - -// 获取积分统计 -export function getConsumptionStats() { - return request({ - url: '/user/points/consumption/stats', - method: 'get' - }) -} - -// api/models.ts -import request from '@/utils/request' - -// 获取所有模型 -export function getAllModels(params: { - taskType?: string - provider?: string - enabledOnly?: boolean -}) { - return request({ - url: '/user/ai/models', - method: 'get', - params - }) -} - -// 按类型分组获取模型 -export function getModelsByType(params: { - provider?: string - enabledOnly?: boolean -}) { - return request({ - url: '/user/ai/models/group-by-type', - method: 'get', - params - }) -} - -// 按厂商分组获取模型 -export function getModelsByProvider(params: { - taskType?: string - enabledOnly?: boolean -}) { - return request({ - url: '/user/ai/models/group-by-provider', - method: 'get', - params - }) -} - -// 获取模型统计 -export function getModelStats() { - return request({ - url: '/user/ai/models/stats', - method: 'get' - }) -} -``` - -### 5.2 React 示例 - -```typescript -// hooks/usePoints.ts -import { useState, useEffect } from 'react' -import { getPointsBalance, getConsumptionLogs } from '@/api/points' - -export function usePointsBalance() { - const [balance, setBalance] = useState(null) - const [loading, setLoading] = useState(true) - - useEffect(() => { - getPointsBalance().then(res => { - setBalance(res.data) - setLoading(false) - }) - }, []) - - return { balance, loading } -} - -// hooks/useModels.ts -import { useState, useEffect } from 'react' -import { getModelsByType } from '@/api/models' - -export function useModelsByType(provider?: string) { - const [models, setModels] = useState([]) - const [loading, setLoading] = useState(true) - - useEffect(() => { - getModelsByType({ provider, enabledOnly: true }).then(res => { - setModels(res.data) - setLoading(false) - }) - }, [provider]) - - return { models, loading } -} -``` - -### 5.3 使用场景示例 - -```vue - - - - - 当前积分 - {{ balance?.currentPoints || 0 }} - - {{ balance.willExpireSoon ? '即将过期' : '有效期至' }}: - {{ formatDate(balance.pointsExpiresAt) }} - - - - - 消费记录 - - {{ log.changeTypeName }} - {{ log.description }} - - {{ log.changeAmount > 0 ? '+' : '' }}{{ log.changeAmount }} - - {{ formatDate(log.createTime) }} - - - - - - -``` - -```vue - - - - - - 全部类型 - 文生图 - 文生视频 - 图生视频 - - - - 全部厂商 - OpenAI - RunningHub - - - - - - {{ model.displayName }} - {{ model.description }} - - 选择 - - - - - - -``` - ---- - -## 📌 总结 - -### 已实现功能 -1. ✅ 用户积分余额查询 -2. ✅ 用户积分消费记录查询(分页、筛选) -3. ✅ 用户积分统计信息 -4. ✅ AI模型列表查询(支持筛选) -5. ✅ 按任务类型分组查询模型 -6. ✅ 按厂商分组查询模型 -7. ✅ 模型统计信息 - -### 技术特点 -- 支持细致的任务类型分类(文生图、图生图、图生视频等) -- 向后兼容粗略分类(image、video等) -- 公开访问的模型列表接口,无需登录 -- 需要登录的积分查询接口,保护用户隐私 -- 完整的分页支持 -- 灵活的筛选和分组功能 - -### 数据库优化 -- 添加 `task_type` 字段用于精确分类 -- 添加索引提升查询性能 -- 支持逻辑删除 - -### 安全性 -- 积分相关接口需要用户认证 -- 模型列表接口公开访问,方便前端展示 -- 完整的权限控制配置 - ---- - -**文档版本:** v1.0 -**最后更新:** 2025-10-22 - diff --git a/POINTS_RECHARGE_GUIDE.md b/POINTS_RECHARGE_GUIDE.md deleted file mode 100644 index 66924e0..0000000 --- a/POINTS_RECHARGE_GUIDE.md +++ /dev/null @@ -1,698 +0,0 @@ -# 积分充值系统使用指南 - -## 📋 功能概述 - -本系统实现了完整的积分直接购买功能,用户可以通过支付宝/微信支付直接购买积分,无需依赖礼品码。 - -### ✨ 核心特性 - -- ✅ **多套餐选择**:支持不同价格和数量的积分套餐 -- ✅ **首充奖励**:首次充值额外赠送10%积分 -- ✅ **赠送积分**:每个套餐可配置赠送积分 -- ✅ **支付方式**:支持支付宝和微信支付 -- ✅ **充值记录**:完整的充值历史记录 -- ✅ **自动到账**:支付成功后自动充值到账 -- ✅ **积分有效期**:可配置积分有效期(默认365天) - ---- - -## 🗂️ 数据库结构 - -### 新增表 - -#### 1. `points_package` - 积分套餐表 -```sql -CREATE TABLE `points_package` ( - `id` bigint PRIMARY KEY AUTO_INCREMENT, - `name` varchar(64) NOT NULL COMMENT '套餐名称', - `points` int NOT NULL COMMENT '基础积分', - `bonus_points` int DEFAULT 0 COMMENT '赠送积分', - `total_points` int NOT NULL COMMENT '总积分', - `price` decimal(10,2) NOT NULL COMMENT '价格', - `original_price` decimal(10,2) COMMENT '原价', - `points_expire_days` int DEFAULT 365 COMMENT '有效期', - `discount_label` varchar(32) COMMENT '优惠标签', - `is_hot` tinyint(1) DEFAULT 0 COMMENT '是否热门', - `is_active` tinyint(1) DEFAULT 1 COMMENT '是否上架' -); -``` - -**默认数据**: -| 套餐名称 | 积分 | 赠送 | 总计 | 价格 | 原价 | -|---------|------|------|------|------|------| -| 体验包 | 100 | 0 | 100 | ¥10 | - | -| 标准包 | 500 | 50 | 550 | ¥48 | ¥50 | -| 超值包 | 1000 | 150 | 1150 | ¥88 | ¥100 | -| 豪华包 | 3000 | 500 | 3500 | ¥258 | ¥300 | -| 至尊包 | 5000 | 1000 | 6000 | ¥398 | ¥500 | -| 旗舰包 | 10000 | 3000 | 13000 | ¥688 | ¥1000 | - -### 扩展表 - -#### 2. `order` 表扩展 -新增字段: -```sql -ALTER TABLE `order` -ADD COLUMN `order_type` tinyint DEFAULT 1 COMMENT '1-会员订单/2-积分订单', -ADD COLUMN `points_package_id` bigint COMMENT '积分套餐ID', -ADD COLUMN `points_amount` int COMMENT '积分数量'; -``` - ---- - -## 🔌 API接口文档 - -### 用户端接口(`/user/points`) - -#### 1. 获取积分套餐列表 - -**接口**:`GET /user/points/packages` - -**权限**:公开访问(无需登录) - -**响应示例**: -```json -{ - "code": 200, - "message": "成功", - "data": [ - { - "id": 2, - "name": "标准包", - "description": "日常使用推荐", - "points": 500, - "bonusPoints": 50, - "totalPoints": 550, - "price": 48.00, - "originalPrice": 50.00, - "pointsExpireDays": 365, - "discountLabel": "赠送50积分", - "isHot": true, - "isActive": true - } - ] -} -``` - ---- - -#### 2. 获取热门套餐 - -**接口**:`GET /user/points/packages/hot?limit=3` - -**权限**:公开访问 - -**参数**: -- `limit`:数量限制,默认3 - ---- - -#### 3. 创建充值订单 ⭐ - -**接口**:`POST /user/points/recharge` - -**权限**:需要登录 - -**请求体**: -```json -{ - "packageId": 2, - "paymentMethod": 2 -} -``` - -**参数说明**: -- `packageId`:套餐ID(必填) -- `paymentMethod`:支付方式(必填) - - `1` = 支付宝 - - `2` = 微信支付 - -**响应示例**: -```json -{ - "code": 200, - "message": "成功", - "data": { - "orderNo": "ORD20251021123456", - "amount": 48.00, - "pointsAmount": 605, - "paymentMethod": 2, - "paymentParams": "{\"prepay_id\":\"wx2025102112345678\"}", - "createTime": "2025-10-21T12:34:56" - } -} -``` - -**注意**: -- 首次充值会额外赠送10%积分 -- `pointsAmount` = 基础积分 + 赠送积分 + 首充奖励(如果是首次) -- `paymentParams` 需要传给前端调起支付 - ---- - -#### 4. 获取充值记录 - -**接口**:`GET /user/points/recharge/records?page=1&size=10` - -**权限**:需要登录 - -**响应示例**: -```json -{ - "code": 200, - "message": "成功", - "data": [ - { - "orderNo": "ORD20251021123456", - "packageName": "标准包", - "pointsAmount": 605, - "amount": 48.00, - "paymentMethodName": "微信支付", - "statusName": "已完成", - "createTime": "2025-10-21T12:34:56", - "paidAt": "2025-10-21T12:35:10" - } - ] -} -``` - ---- - -#### 5. 获取充值统计 - -**接口**:`GET /user/points/recharge/stats` - -**权限**:需要登录 - -**响应示例**: -```json -{ - "code": 200, - "message": "成功", - "data": { - "totalRechargeCount": 5, - "totalAmount": 240.00, - "totalPoints": 3025, - "isFirstRecharge": false, - "lastRechargeTime": "2025-10-21T12:35:10" - } -} -``` - ---- - -### 支付回调接口(`/payment/callback`) - -#### 1. 支付宝回调 - -**接口**:`POST /payment/callback/alipay` - -**权限**:公开访问(支付宝服务器调用) - -**处理流程**: -1. 验证支付宝签名 -2. 检查交易状态(`TRADE_SUCCESS` 或 `TRADE_FINISHED`) -3. 调用充值处理逻辑 -4. 返回 `success` 给支付宝 - ---- - -#### 2. 微信支付回调 - -**接口**:`POST /payment/callback/wechat` - -**权限**:公开访问(微信服务器调用) - -**处理流程**: -1. 解析XML数据 -2. 验证微信签名 -3. 检查支付结果 -4. 调用充值处理逻辑 -5. 返回XML响应给微信 - ---- - -#### 3. 测试回调(仅开发环境) - -**接口**:`POST /payment/callback/test?orderNo=ORD20251021123456` - -**权限**:公开访问 - -**用途**:在没有真实支付的情况下测试充值流程 - -**示例**: -```bash -curl -X POST "http://localhost:8080/payment/callback/test?orderNo=ORD20251021123456" -``` - ---- - -## 🔄 业务流程 - -### 完整充值流程 - -``` -用户端 后端 支付平台 - | | | - | 1. 浏览套餐列表 | | - |------------------------>| | - | GET /packages | | - |<------------------------| | - | | | - | 2. 创建充值订单 | | - |------------------------>| | - | POST /recharge | | - | {packageId: 2} | | - | | 3. 生成订单 | - | | 4. 生成支付参数 | - |<------------------------| | - | {orderNo, paymentParams} | - | | | - | 5. 调起支付 | | - |-------------------------------------------------->| - | | | - | | 6. 支付成功 | - | |<---------------------------| - | | POST /callback/alipay | - | | | - | | 7. 验证签名 | - | | 8. 增加用户积分 | - | | 9. 更新订单状态 | - | | 10. 记录变动日志 | - | |-------------------------->| - | | 返回 "success" | - | | | - | 11. 查询充值记录 | | - |------------------------>| | - |<------------------------| | -``` - ---- - -## 💻 前端集成示例 - -### 1. 获取套餐列表 - -```javascript -// 获取积分套餐 -async function getPackages() { - const response = await fetch('/user/points/packages'); - const result = await response.json(); - - if (result.code === 200) { - displayPackages(result.data); - } -} -``` - ---- - -### 2. 创建充值订单 - -```javascript -// 创建充值订单 -async function recharge(packageId, paymentMethod) { - const response = await fetch('/user/points/recharge', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'Authorization': 'Bearer ' + getToken() - }, - body: JSON.stringify({ - packageId: packageId, - paymentMethod: paymentMethod // 1=支付宝, 2=微信 - }) - }); - - const result = await response.json(); - - if (result.code === 200) { - const { orderNo, paymentParams } = result.data; - - // 调起支付 - if (paymentMethod === 1) { - // 支付宝支付 - alipay(paymentParams); - } else { - // 微信支付 - wechatPay(paymentParams); - } - } -} -``` - ---- - -### 3. 支付宝支付(示例) - -```javascript -function alipay(paymentParams) { - // 创建表单并提交 - const form = document.createElement('form'); - form.action = 'https://openapi.alipay.com/gateway.do'; - form.method = 'POST'; - form.innerHTML = paymentParams; // 支付宝SDK生成的表单 - document.body.appendChild(form); - form.submit(); -} -``` - ---- - -### 4. 微信支付(示例) - -```javascript -function wechatPay(paymentParams) { - const params = JSON.parse(paymentParams); - - // 调起微信支付 - WeixinJSBridge.invoke('getBrandWCPayRequest', { - appId: params.appId, - timeStamp: params.timeStamp, - nonceStr: params.nonceStr, - package: params.package, - signType: params.signType, - paySign: params.paySign - }, function(res) { - if (res.err_msg === 'get_brand_wcpay_request:ok') { - // 支付成功,跳转到充值记录页面 - window.location.href = '/points/records'; - } - }); -} -``` - ---- - -## 🔧 后端开发说明 - -### 1. 支付接口对接 - -目前 `generatePaymentParams()` 方法返回的是模拟数据,需要对接真实的支付宝/微信SDK: - -#### 支付宝SDK集成 - -```xml - - - com.alipay.sdk - alipay-sdk-java - 4.38.0.ALL - -``` - -```java -// 生成支付宝支付参数 -private String generateAlipayParams(Order order) { - AlipayClient alipayClient = new DefaultAlipayClient( - "https://openapi.alipay.com/gateway.do", - APP_ID, - PRIVATE_KEY, - "json", - "UTF-8", - ALIPAY_PUBLIC_KEY, - "RSA2" - ); - - AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest(); - request.setNotifyUrl("https://yourdomain.com/payment/callback/alipay"); - - JSONObject bizContent = new JSONObject(); - bizContent.put("out_trade_no", order.getOrderNo()); - bizContent.put("total_amount", order.getAmount()); - bizContent.put("subject", "积分充值"); - bizContent.put("product_code", "QUICK_MSECURITY_PAY"); - - request.setBizContent(bizContent.toString()); - - AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request); - return response.getBody(); -} -``` - -#### 微信支付SDK集成 - -```xml - - - com.github.wechatpay-apiv3 - wechatpay-java - 0.2.12 - -``` - -```java -// 生成微信支付参数 -private String generateWechatPayParams(Order order) { - // 使用微信支付SDK创建预支付订单 - // 返回prepay_id等参数 -} -``` - ---- - -### 2. 回调签名验证 - -#### 支付宝签名验证 - -```java -@PostMapping("/alipay") -public String alipayCallback(HttpServletRequest request) { - Map params = new HashMap<>(); - Map requestParams = request.getParameterMap(); - - for (String name : requestParams.keySet()) { - params.put(name, request.getParameter(name)); - } - - // 验证签名 - boolean signVerified = AlipaySignature.rsaCheckV1( - params, - ALIPAY_PUBLIC_KEY, - "UTF-8", - "RSA2" - ); - - if (!signVerified) { - return "fail"; - } - - // 验证通过,处理业务 - String orderNo = params.get("out_trade_no"); - String tradeStatus = params.get("trade_status"); - - if ("TRADE_SUCCESS".equals(tradeStatus)) { - pointsRechargeService.handleRechargePaymentSuccess(orderNo); - } - - return "success"; -} -``` - -#### 微信支付签名验证 - -```java -@PostMapping("/wechat") -public String wechatCallback(@RequestBody String xmlData) { - // 解析XML - Map params = WXPayUtil.xmlToMap(xmlData); - - // 验证签名 - boolean signVerified = WXPayUtil.isSignatureValid( - params, - WECHAT_API_KEY - ); - - if (!signVerified) { - return errorXml(); - } - - // 验证通过,处理业务 - String orderNo = params.get("out_trade_no"); - String resultCode = params.get("result_code"); - - if ("SUCCESS".equals(resultCode)) { - pointsRechargeService.handleRechargePaymentSuccess(orderNo); - } - - return successXml(); -} -``` - ---- - -## 📊 数据库迁移 - -### 执行迁移脚本 - -```bash -# 1. 备份数据库 -mysqldump -u root -p 1818ai > backup_$(date +%Y%m%d).sql - -# 2. 执行V6迁移脚本 -mysql -u root -p 1818ai < V6__add_points_recharge_system.sql - -# 3. 验证结果 -mysql -u root -p 1818ai -e "SELECT * FROM points_package;" -mysql -u root -p 1818ai -e "DESC \`order\`;" -``` - ---- - -## 🧪 测试流程 - -### 1. 开发环境测试 - -```bash -# 1. 获取套餐列表 -curl -X GET "http://localhost:8080/user/points/packages" - -# 2. 创建充值订单(需要登录token) -curl -X POST "http://localhost:8080/user/points/recharge" \ - -H "Authorization: Bearer YOUR_TOKEN" \ - -H "Content-Type: application/json" \ - -d '{"packageId":2,"paymentMethod":2}' - -# 3. 模拟支付成功(测试用) -curl -X POST "http://localhost:8080/payment/callback/test?orderNo=ORD20251021123456" - -# 4. 查看充值记录 -curl -X GET "http://localhost:8080/user/points/recharge/records?page=1&size=10" \ - -H "Authorization: Bearer YOUR_TOKEN" - -# 5. 查看用户积分 -curl -X GET "http://localhost:8080/user/info" \ - -H "Authorization: Bearer YOUR_TOKEN" -``` - -### 2. 生产环境验证 - -1. ✅ 确认支付宝/微信支付配置正确 -2. ✅ 确认回调URL可以被外网访问 -3. ✅ 小额充值测试(¥0.01) -4. ✅ 验证积分到账是否正确 -5. ✅ 验证首充奖励是否生效 -6. ✅ 验证充值记录是否正确 - ---- - -## 🛡️ 安全配置 - -### SecurityConfig 配置说明 - -```java -// 公开接口(无需登录) -"/user/points/packages/**" // 套餐浏览 -"/payment/callback/**" // 支付回调 - -// 需要登录的接口 -"/user/points/recharge" // 创建充值订单 -"/user/points/recharge/**" // 充值记录、统计 -``` - ---- - -## 📈 运营建议 - -### 1. 套餐定价策略 - -- **体验包**:吸引新用户尝试 -- **标准包**:日常充值主力 -- **超值包**:性价比标杆,设置为热门 -- **豪华包/至尊包**:满足重度用户 -- **旗舰包**:年度大额充值,最高性价比 - -### 2. 营销活动 - -- **首充奖励**:已自动实现,首次充值额外赠送10% -- **限时优惠**:通过 `discount_label` 标签展示 -- **热门推荐**:将主推套餐设置为 `is_hot=1` -- **节日活动**:临时调整 `bonus_points` 赠送比例 - -### 3. 数据分析 - -查看充值统计视图: -```sql -SELECT * FROM v_points_recharge_stats -ORDER BY recharge_date DESC -LIMIT 30; -``` - ---- - -## ❓ 常见问题 - -### Q1: 支付成功但积分没到账? - -**检查步骤**: -1. 查看订单状态:`SELECT * FROM order WHERE order_no = 'xxx';` -2. 查看支付回调日志:检查 `/payment/callback/alipay` 日志 -3. 查看用户积分:`SELECT points FROM user WHERE id = xxx;` -4. 查看积分变动日志:`SELECT * FROM points_consumption_log WHERE user_id = xxx;` - -**手动补单**: -```bash -curl -X POST "http://localhost:8080/payment/callback/test?orderNo=xxx" -``` - ---- - -### Q2: 如何修改套餐价格? - -```sql -UPDATE points_package -SET price = 45.00, - update_time = NOW() -WHERE id = 2; -``` - ---- - -### Q3: 如何下架某个套餐? - -```sql -UPDATE points_package -SET is_active = 0, - update_time = NOW() -WHERE id = 6; -``` - ---- - -### Q4: 如何查看用户充值历史? - -```sql -SELECT - o.order_no, - o.amount, - o.points_amount, - pp.name as package_name, - o.create_time, - o.paid_at, - CASE o.status - WHEN 0 THEN '待支付' - WHEN 1 THEN '已完成' - WHEN 2 THEN '已取消' - WHEN 3 THEN '支付失败' - END as status_name -FROM `order` o -LEFT JOIN points_package pp ON o.points_package_id = pp.id -WHERE o.user_id = 123 - AND o.order_type = 2 -ORDER BY o.create_time DESC; -``` - ---- - -## 🎯 总结 - -✅ **功能完整**:支持套餐管理、订单创建、支付回调、充值到账全流程 - -✅ **安全可靠**:JWT认证、订单防重、支付签名验证 - -✅ **易于扩展**:支持新增支付方式、调整套餐策略 - -✅ **数据完整**:充值记录、变动日志、统计分析 - -现在用户可以直接购买积分,不再依赖礼品码!🎉 - diff --git a/POINTS_SYSTEM_DESIGN.md b/POINTS_SYSTEM_DESIGN.md deleted file mode 100644 index 66d2e67..0000000 --- a/POINTS_SYSTEM_DESIGN.md +++ /dev/null @@ -1,299 +0,0 @@ -# 积分与AI任务系统设计文档 - -## 1. 项目概述 - -### 1.1 背景与目标 - -为集成第三方AI模型(如Sora Image/Video),并建立一套商业化积分体系,本项目旨在设计并开发一个稳定、可扩展、安全的积分消费与AI任务管理系统。 - -**核心目标:** - -- **商业化闭环:** 建立用户充值、积分兑换、模型消费的完整商业流程。 -- **任务持久化:** 保证用户提交的AI生成任务不因刷新或关闭页面而丢失,可随时查看历史记录。 -- **高效队列管理:** 解决API并发限制问题,通过队列机制保证服务稳定性和用户体验。 -- **实时反馈:** 为用户提供任务的实时进度更新,提升交互体验。 -- **安全可靠:** 保证积分和交易数据的安全,防止恶意攻击和滥用。 - -### 1.2 设计原则 - -- **高内聚低耦合:** 各模块(积分、任务、队列、API调用)职责清晰,易于维护和扩展。 -- **异步化处理:** 核心AI任务采用异步处理,避免长时间阻塞,提高系统吞吐量。 -- **状态驱动:** 任务和积分为状态驱动,保证数据一致性和流程可追溯性。 -- **用户为中心:** 优化从提交任务到获取结果的全流程体验。 -- **安全第一:** 在设计、开发、部署各环节贯彻安全思想。 - ---- - -## 2. 系统架构 - -系统采用微服务化的思想,将核心功能模块化,通过API和消息队列进行通信。 - -```mermaid -graph TD - subgraph 用户端 (Web/App) - A[用户界面] - end - - subgraph 服务端 (Backend) - B[API网关] - C[积分服务 PointsService] - D[AI任务服务 AiTaskService] - E[队列管理器 QueueManager] - F[定时任务 Scheduler] - G[WebSocket服务] - end - - subgraph 第三方服务 - H[中转站AI API] - end - - subgraph 基础设施 - I[MySQL数据库] - J[Redis缓存/队列] - end - - A -- REST API --> B - B -- 调用 --> C - B -- 调用 --> D - - D -- 操作任务 --> I - D -- 添加任务到 --> E - D -- 更新积分 --> C - - C -- 操作积分 --> I - - E -- 使用 --> J - E -- 触发 --> D - - F -- 扫描 --> E - F -- 清理 --> D - - D -- 推送进度 --> G - G -- WebSocket --> A - - D -- 调用 --> H -``` - -**核心流程:** -1. 用户通过**API网关**提交AI任务。 -2. **AI任务服务**接收请求,调用**积分服务**冻结相应积分。 -3. 任务服务将任务信息持久化到**MySQL**,并交给**队列管理器**。 -4. **队列管理器**基于**Redis**实现任务排队,并根据并发限制(50个)决定是否立即处理。 -5. **定时任务**周期性扫描队列,将排队的任务交给任务服务处理。 -6. 任务服务异步调用**中转站AI API**,并通过**WebSocket**向用户实时推送进度。 -7. 任务完成后,更新数据库状态,并调用积分服务进行最终的扣除或退款。 - ---- - -## 3. 核心功能设计 - -### 3.1 积分体系设计 - -#### 3.1.1 兑换与定价 - -- **兑换比例:** `1 元人民币 = 100 积分` -- **模型定价:** 在中转站价格基础上加价50%。 - -**图片模型定价 (示例)** -| 模型名称 | 中转站价格 | 我方价格 (USD) | 我方价格 (CNY) | 积分消耗 | -|---|---|---|---|---| -| sora_image | $0.01 | $0.015 | ~¥0.11 | **11 积分/张** | -| gpt-4o-image | $0.01 | $0.015 | ~¥0.11 | **11 积分/张** | - -**视频模型定价 (示例)** -| 模型名称 | 中转站价格 | 我方价格 (USD) | 我方价格 (CNY) | 积分消耗 | -|---|---|---|---|---| -| sora_video2 | $0.15 | $0.225 | ~¥1.6 | **160 积分/次** | -| sora_video2-15s | $0.25 | $0.375 | ~¥2.6 | **260 积分/次** | -| sora-2-pro-all | $0.40 | $0.60 | ~¥4.2 | **420 积分/次** | -*(注: CNY价格按汇率7.2估算,最终积分以CNY价格为准,取整)* - -#### 3.1.2 充值与会员 - -- **充值档位:** 设计多档位充值套餐,提供不同比例的积分赠送。 -- **会员体系:** VIP/SVIP会员可享受每日免费积分、生成任务折扣等权益。 - -### 3.2 AI任务管理 - -#### 3.2.1 任务生命周期 - -```mermaid -stateDiagram-v2 - [*] --> created: 用户提交 - created --> queued: 进入队列 - created --> processing: 队列有空位 - queued --> processing: 轮到处理 - processing --> completed: 生成成功 - processing --> failed: 生成失败 - queued --> cancelled: 用户取消 - processing --> cancelled: 用户取消(不支持) - failed --> processing: 系统重试 - completed --> [*] - failed --> [*] - cancelled --> [*] -``` -- **created:** 任务已创建,积分已冻结。 -- **queued:** 系统繁忙,任务在队列中等待。 -- **processing:** 任务正在被AI模型处理。 -- **completed:** 任务成功,结果已生成。 -- **failed:** 任务失败,积分将退还。 -- **cancelled:** 用户主动取消(仅排队中可取消)。 - -#### 3.2.2 队列管理 - -- **系统并发限制:** 每个模型最多同时处理50个任务。 -- **用户并发限制:** 每个用户最多同时进行3个任务。 -- **优先级策略:** SVIP > VIP > 普通用户 > 等待时间。 -- **超时机制:** `processing`状态超过10分钟的任务将被标记为失败,并自动退款。 - ---- - -## 4. 数据库设计 - -为支持以上功能,需新增以下核心表: - -```sql --- AI生成任务表 (核心) -CREATE TABLE IF NOT EXISTS `ai_task` ( - `id` bigint NOT NULL AUTO_INCREMENT, - `task_no` varchar(64) UNIQUE NOT NULL COMMENT '任务编号', - `user_id` bigint NOT NULL, - `model_name` varchar(64) NOT NULL, - `task_type` varchar(32) NOT NULL COMMENT '任务类型 (image/video)', - `prompt` text NOT NULL, - `status` varchar(32) NOT NULL DEFAULT 'created' COMMENT '任务状态 (created, queued, processing, completed, failed, cancelled)', - `progress` int DEFAULT 0 COMMENT '进度百分比', - `progress_message` varchar(255) DEFAULT NULL, - `points_frozen` int NOT NULL COMMENT '冻结积分', - `points_consumed` int DEFAULT 0 COMMENT '实际消耗积分', - `result_url` varchar(512) DEFAULT NULL, - `error_message` text DEFAULT NULL, - `queue_time` datetime DEFAULT NULL, - `start_time` datetime DEFAULT NULL, - `complete_time` datetime DEFAULT NULL, - `expire_time` datetime DEFAULT NULL COMMENT '结果过期时间', - `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, - `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - `is_deleted` tinyint(1) NOT NULL DEFAULT 0, - PRIMARY KEY (`id`), - UNIQUE KEY `uk_task_no` (`task_no`), - KEY `idx_user_status` (`user_id`, `status`), - KEY `idx_status_time` (`status`, `create_time`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='AI生成任务表'; - --- 积分消费配置表 -CREATE TABLE IF NOT EXISTS `points_config` ( - `id` bigint NOT NULL AUTO_INCREMENT, - `model_name` varchar(64) UNIQUE NOT NULL COMMENT '模型名称', - `points_cost` int NOT NULL COMMENT '积分消耗', - `description` varchar(255) DEFAULT NULL, - `is_enabled` tinyint(1) NOT NULL DEFAULT 1, - `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='积分消费配置表'; - --- 积分消费记录表 -CREATE TABLE IF NOT EXISTS `points_consumption_log` ( - `id` bigint NOT NULL AUTO_INCREMENT, - `user_id` bigint NOT NULL, - `task_no` varchar(64) DEFAULT NULL, - `change_type` varchar(32) NOT NULL COMMENT '(consume, refund)', - `change_amount` int NOT NULL, - `balance_before` int NOT NULL, - `balance_after` int NOT NULL, - `description` varchar(255) DEFAULT NULL, - `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, - PRIMARY KEY (`id`), - KEY `idx_user_id` (`user_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='积分消费记录表'; - --- 系统配置表 -CREATE TABLE IF NOT EXISTS `system_config` ( - `id` bigint NOT NULL AUTO_INCREMENT, - `config_key` varchar(64) UNIQUE NOT NULL, - `config_value` varchar(512) NOT NULL, - `description` varchar(255) DEFAULT NULL, - `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='系统配置表'; -``` - ---- - -## 5. 安全设计 - -安全是本系统的重中之重,需在多个层面进行防御。 - -### 5.1 防滥用与攻击 - -- **接口频率限制:** 对任务提交、状态查询等核心接口进行IP和用户级别的双重限流,防止CC攻击。 -- **图形验证码:** 在登录、充值、提交任务等关键操作前,引入图形验证码,防止机器人批量操作。 -- **输入校验:** 对所有用户输入(特别是`prompt`)进行严格的XSS和SQL注入过滤,防止恶意脚本和敏感信息泄露。 -- **API密钥保护:** 中转站的API Key必须存储在安全的环境变量或配置中心,绝不能硬编码在代码中。所有对外的API调用需在服务端完成,严禁在前端暴露密钥。 - -### 5.2 数据与交易安全 - -- **事务一致性:** 积分的冻结、扣除、退款操作必须与任务状态变更在同一个数据库事务中完成,保证数据原子性,防止出现"钱扣了任务没创建"等问题。 -- **防并发竞争 (Race Condition):** 在扣减积分、更新任务状态等操作时,使用乐观锁(增加`version`字段)或悲观锁(`SELECT ... FOR UPDATE`),防止并发请求导致的数据错乱(如一笔积分被消费两次)。 -- **敏感数据加密:** 数据库中存储的密码、API密钥等敏感信息必须使用强哈希算法(如Argon2, bcrypt)进行加密存储。 -- **日志审计:** 对所有积分变更、管理员操作进行详细的日志记录,便于审计和问题追溯。 - -### 5.3 访问控制 - -- **权限分离:** 严格区分用户和管理员的API接口,使用基于角色的访问控制(RBAC)。普通用户不能访问任何管理接口。 -- **水平越权防护:** 所有查询和操作用户数据的接口,必须严格校验当前登录用户ID与要操作的数据归属ID是否一致,防止用户A操作用户B的任务或积分。 -- **CSRF防护:** 对所有状态变更的POST/PUT请求(如取消任务、修改配置)启用CSRF Token验证。 - ---- - -## 6. 开发功能清单 - -### 第一阶段:核心后台 (15人日) -- [ ] 数据库表结构设计与创建 -- [ ] 实体类与Mapper层代码生成 -- [ ] 积分核心服务 (查询、冻结、扣除、退款) -- [ ] AI任务核心服务 (创建、状态更新) -- [ ] 积分与任务的事务性保证 -- [ ] 中转站API客户端封装 - -### 第二阶段:队列与异步 (10人日) -- [ ] 基于Redis的队列管理器实现 -- [ ] 任务优先级算法实现 -- [ ] 异步处理任务的`@Async`配置 -- [ ] 队列扫描、超时检查、过期清理的定时任务 -- [ ] WebSocket服务基础搭建 - -### 第三阶段:API与前端 (12人日) -- [ ] 用户端API接口开发 (提交、查询、列表、取消) -- [ ] WebSocket实时进度推送实现 -- [ ] 管理端API接口开发 (任务监控、队列配置) -- [ ] 详细的API文档编写 (Swagger/OpenAPI) -- [ ] 前端任务提交与结果展示页面 -- [ ] 前端任务历史列表与状态展示 - -### 第四阶段:安全与测试 (8人日) -- [ ] 单元测试与集成测试编写 -- [ ] 安全加固 (限流、输入校验、权限检查) -- [ ] 压力测试 (模拟高并发提交任务) -- [ ] 部署脚本编写与上线 - ---- - -## 7. 任务进度计划 (甘特图) - -| 阶段 | 任务 | 负责人 | 预估工时 | W1 | W2 | W3 | W4 | W5 | 状态 | -|:---|:---|:---|:---:|:---:|:---:|:---:|:---:|:---:|:---| -| **P1: 核心后台** | 数据库设计与创建 | 后端A | 2d | ██ | | | | | ✅ | -| | 核心服务开发 | 后端A | 8d | ████ | ████ | | | | 진행중 | -| | API客户端封装 | 后端B | 3d | ███ | | | | | ✅ | -| | 单元测试(P1) | 后端A/B | 2d | | | ██ | | | 대기 | -| **P2: 队列与异步** | 队列管理器实现 | 后端B | 5d | | ███ | ██ | | | 대기 | -| | 定时任务开发 | 后端A | 3d | | | | ███ | | 대기 | -| | WebSocket搭建 | 后端B | 2d | | | | | ██ | 대기 | -| **P3: API与前端** | 用户端API开发 | 后端A | 4d | | | ████ | | | 대기 | -| | 管理端API开发 | 后端B | 2d | | | | ██ | | 대기 | -| | 前端页面开发 | 前端C | 6d | | | ██ | ████ | | 대기 | -| **P4: 测试与部署** | 集成与压力测试 | 测试D | 5d | | | | | █████ | 대기 | -| | 安全加固与部署 | 运维E | 3d | | | | | | ███ | - -*(注: d=人日, 一个█代表1人日)* diff --git a/POLLING_INTERVAL_OPTIMIZATION.md b/POLLING_INTERVAL_OPTIMIZATION.md deleted file mode 100644 index bfa013f..0000000 --- a/POLLING_INTERVAL_OPTIMIZATION.md +++ /dev/null @@ -1,295 +0,0 @@ -# RunningHub 轮询间隔优化说明 - -**版本:** v2.1.1 -**优化时间:** 2025-10-20 -**优化类型:** 性能优化 & 成本优化 - ---- - -## 📊 优化对比 - -### 原配置(v2.1.0) - -```yaml -ai: - providers: - runninghub: - polling-interval: 5000 # 5秒轮询 - max-polling-times: 120 # 最大轮询120次 = 10分钟 -``` - -```java -@Scheduled(fixedDelay = 5000) // 固定5秒延迟 -``` - -**特点:** -- ✅ 实时性强:任务完成后平均5秒内获得结果 -- ❌ API调用频繁:每个任务最多120次API调用 -- ❌ 服务器负载高:高并发时压力大 -- ❌ 成本较高:可能触发RunningHub API限流 - ---- - -### 新配置(v2.1.1,当前) - -```yaml -ai: - providers: - runninghub: - polling-interval: 10000 # 10秒轮询 - max-polling-times: 60 # 最大轮询60次 = 10分钟 -``` - -```java -@Scheduled(fixedDelayString = "${ai.providers.runninghub.polling-interval:10000}") -``` - -**特点:** -- ✅ 成本优化:API调用量减少50% -- ✅ 负载降低:服务器CPU、网络压力减半 -- ✅ 动态配置:可通过配置文件调整,无需修改代码 -- ✅ 防止堆积:使用`fixedDelay`而非`fixedRate` -- ⚠️ 实时性降低:任务完成后平均10秒内获得结果(可接受) - ---- - -## 🔍 详细分析 - -### 1. API调用量对比 - -假设一个任务从提交到完成需要3分钟(180秒): - -| 配置 | 轮询间隔 | 轮询次数 | API调用量 | -|-----|---------|---------|----------| -| 原配置 | 5秒 | 180÷5 = 36次 | **36次** | -| 新配置 | 10秒 | 180÷10 = 18次 | **18次** | -| **减少** | - | - | **↓ 50%** | - -**100个并发任务的API调用量:** -- 原配置:100 × 36 = **3600次/3分钟** → **1200次/分钟** -- 新配置:100 × 18 = **1800次/3分钟** → **600次/分钟** - ---- - -### 2. 网络流量对比 - -假设每次状态查询请求+响应 = 2KB: - -| 并发任务数 | 原配置(5秒) | 新配置(10秒) | 节省流量 | -|-----------|--------------|---------------|---------| -| 10 | 720KB/3分钟 | 360KB/3分钟 | 50% | -| 50 | 3.6MB/3分钟 | 1.8MB/3分钟 | 50% | -| 100 | 7.2MB/3分钟 | 3.6MB/3分钟 | 50% | -| 200 | 14.4MB/3分钟 | 7.2MB/3分钟 | 50% | - -**每日流量节省(假设100并发持续运行):** -``` -原配置:7.2MB × (1440分钟 ÷ 3分钟) = 3.46GB/天 -新配置:3.6MB × (1440分钟 ÷ 3分钟) = 1.73GB/天 -节省:1.73GB/天 = 51.9GB/月 -``` - ---- - -### 3. 服务器负载对比 - -**CPU使用率(100并发):** -``` -原配置:轮询600次/分钟 × 数据库查询+更新+WebSocket通知 - CPU使用率:~20% - -新配置:轮询300次/分钟 × 数据库查询+更新+WebSocket通知 - CPU使用率:~10% - -减少:50% CPU负载 -``` - -**数据库连接数:** -``` -原配置:每5秒查询100个任务 → 100次查询/5秒 = 20 QPS -新配置:每10秒查询100个任务 → 100次查询/10秒 = 10 QPS - -减少:50% 数据库压力 -``` - ---- - -### 4. 用户体验影响 - -**任务完成到用户收到通知的延迟:** - -| 配置 | 平均延迟 | 最大延迟 | 用户感知 | -|-----|---------|---------|---------| -| 原配置(5秒) | 2.5秒 | 5秒 | 几乎实时 ✅ | -| 新配置(10秒) | 5秒 | 10秒 | 仍然很快 ✅ | - -**结论:** -- 从用户角度看,5秒和10秒的差异不明显 -- RunningHub任务本身需要2-5分钟,多等5秒可以接受 -- 用户更关心任务是否成功,而非秒级的通知延迟 - ---- - -## 🎯 为什么选择10秒? - -### 对比不同轮询间隔 - -| 间隔 | API调用量 | 服务器负载 | 用户体验 | 风险 | -|-----|----------|-----------|---------|-----| -| 5秒 | 高(100%) | 高(100%) | 优秀 | 可能触发限流 | -| **10秒** | **中(50%)** | **低(50%)** | **良好** | **平衡最佳** ✅ | -| 15秒 | 低(33%) | 低(33%) | 一般 | 延迟可能被用户察觉 | -| 30秒 | 极低(17%) | 极低(17%) | 较差 | 用户会感觉"卡顿" | - -**10秒是最佳平衡点:** -1. ✅ 显著降低成本(50%) -2. ✅ 用户体验仍然良好(<10秒延迟) -3. ✅ 降低触发RunningHub限流的风险 -4. ✅ 服务器负载减半,支持更多并发 - ---- - -## 🔧 技术实现优化 - -### 使用 `fixedDelay` 而非 `fixedRate` - -**原因:** 防止任务堆积 - -```java -// ❌ 不推荐:fixedRate(固定速率) -@Scheduled(fixedRate = 10000) -// 问题:如果一次轮询耗时15秒,下一次会立即触发,导致任务堆积 - -// ✅ 推荐:fixedDelay(固定延迟) -@Scheduled(fixedDelayString = "${ai.providers.runninghub.polling-interval:10000}") -// 优势:上一次执行完成后,等待10秒再执行下一次 -``` - -**执行时序对比:** - -``` -fixedRate(固定速率): -T0: 开始轮询(耗时15秒) -T10: 调度器触发,但上次未完成 → 排队等待 -T15: 第一次完成 -T15: 立即开始第二次(堆积) -T20: 第二次应该触发,但第二次还在执行 → 继续堆积 - -fixedDelay(固定延迟): -T0: 开始轮询(耗时15秒) -T15: 第一次完成 -T25: 等待10秒后,开始第二次 → 平滑执行 ✅ -``` - ---- - -## 📈 性能测试数据 - -### 测试场景:100个并发任务 - -| 指标 | 原配置(5秒) | 新配置(10秒) | 改善 | -|-----|--------------|---------------|-----| -| API调用量 | 1200次/分钟 | 600次/分钟 | ↓50% | -| 网络流量 | 2.4MB/分钟 | 1.2MB/分钟 | ↓50% | -| CPU使用率 | 20% | 10% | ↓50% | -| 内存占用 | 1.8GB | 1.5GB | ↓17% | -| 平均延迟 | 2.5秒 | 5秒 | ↑2.5秒 | -| 任务成功率 | 99.2% | 99.5% | ↑0.3% | - -**结论:** -- 成本降低50%,延迟仅增加2.5秒 -- 性能与用户体验的完美平衡 ✅ - ---- - -## 🛡️ 风险分析 - -### 潜在问题 - -**Q1:10秒会不会太慢,导致用户投诉?** - -**A:** 不会。理由: -1. RunningHub任务本身需要2-5分钟(120-300秒) -2. 多等5秒(从5秒变10秒)只占总时长的2% -3. 用户更关心"任务能否成功",而非"通知是否立即" -4. 可以在前端显示"预计3分钟完成",降低用户焦虑 - -**Q2:如果RunningHub任务很快完成(30秒),10秒轮询会不会浪费时间?** - -**A:** 不会浪费,反而是优势: -1. 快速任务(<1分钟):平均延迟5秒,用户感知良好 -2. 正常任务(2-5分钟):多等5秒不影响体验 -3. 慢速任务(>5分钟):10秒轮询避免过多无效查询 - -**Q3:高峰期100+并发,10秒够吗?** - -**A:** 足够且更安全: -1. 10秒轮询降低服务器压力,支持更多并发 -2. 100并发 × 10秒 = 每10秒处理100个任务,吞吐量6000任务/小时 -3. 如果用5秒,高并发时可能触发RunningHub限流 - ---- - -## 📋 配置建议 - -### 不同业务场景的推荐配置 - -#### 场景1:低并发(<50任务) - -```yaml -polling-interval: 5000 # 5秒,追求实时性 -max-polling-times: 120 -``` - -适用:初期产品,用户量少,强调用户体验 - ---- - -#### 场景2:中等并发(50-200任务) ✅ **推荐** - -```yaml -polling-interval: 10000 # 10秒,平衡性能与体验 -max-polling-times: 60 -``` - -适用:当前阶段,性价比最高 - ---- - -#### 场景3:高并发(200+任务) - -```yaml -polling-interval: 15000 # 15秒,优先稳定性 -max-polling-times: 40 -batch-size: 50 # 分批轮询,每批50个 -``` - -适用:大规模部署,需要严格控制服务器负载 - ---- - -## ✅ 总结 - -### 优化效果 - -| 维度 | 改善程度 | 说明 | -|-----|---------|-----| -| 成本 | ↓50% | API调用量减半 | -| 性能 | ↓50% | CPU、网络、数据库压力减半 | -| 稳定性 | ↑ | 降低触发限流风险,防止任务堆积 | -| 用户体验 | ↓2.5秒 | 延迟从2.5秒增加到5秒,可接受 | - -### 建议 - -1. ✅ **立即采用10秒配置**(已完成) -2. ✅ 监控用户反馈,如无投诉则保持 -3. ⚠️ 如果未来并发超过200,考虑调整为15秒 -4. ⚠️ 如果RunningHub提供webhook回调,立即切换(零轮询) - ---- - -**优化完成!** 🎯 - -轮询间隔已从5秒优化为10秒,配置更灵活,性能更优,成本更低! - - diff --git a/PromotionLevelManager.java b/PromotionLevelManager.java deleted file mode 100644 index cc63828..0000000 --- a/PromotionLevelManager.java +++ /dev/null @@ -1,318 +0,0 @@ -package com.dora.manager; - -import com.dora.entity.RevenueConfig; -import com.dora.entity.User; -import com.dora.event.PromotionLevelChangedEvent; -import com.dora.mapper.RevenueConfigMapper; -import com.dora.mapper.UserMapper; -import lombok.Builder; -import lombok.Getter; -import lombok.RequiredArgsConstructor; -import lombok.Singular; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.cache.annotation.Cacheable; -import org.springframework.context.ApplicationEventPublisher; -import org.springframework.context.annotation.Lazy; -import org.springframework.stereotype.Component; -import org.springframework.transaction.annotation.Transactional; - -import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; -import java.util.stream.Collectors; - -/** - * 推广等级统一管理器 - * 解决多个地方更新推广等级的问题 - */ -@Component -@RequiredArgsConstructor -@Slf4j -public class PromotionLevelManager { - - private final UserMapper userMapper; - private final RevenueConfigMapper revenueConfigMapper; - private final ApplicationEventPublisher eventPublisher; - - @Autowired - @Lazy - private PromotionLevelManager self; - - // 用户级别的锁,防止并发更新同一用户 - private final ConcurrentHashMap userLocks = new ConcurrentHashMap<>(); - - /** - * 推广等级计算策略枚举 - */ - public enum CalculationStrategy { - PAID_FANS_ONLY("paid_fans", "仅付费粉丝数"), - TOTAL_FANS_ONLY("total_fans", "仅总粉丝数"), - WEIGHTED_AVERAGE("weighted", "加权平均"); - - @Getter - private final String code; - @Getter - private final String description; - - CalculationStrategy(String code, String description) { - this.code = code; - this.description = description; - } - } - - /** - * 推广等级更新结果 - */ - @Getter - @Builder - public static class PromotionLevelUpdateResult { - private final boolean updated; - private final Integer oldLevel; - private final Integer newLevel; - private final String triggerSource; - private final LocalDateTime updateTime; - } - - /** - * 统一的推广等级更新方法 - * - * @param userId 用户ID - * @param strategy 计算策略 - * @param triggerSource 触发源 - * @return 更新结果 - */ - @Transactional - public PromotionLevelUpdateResult updatePromotionLevel( - Long userId, - CalculationStrategy strategy, - String triggerSource) { - - Lock userLock = userLocks.computeIfAbsent(userId, k -> new ReentrantLock()); - userLock.lock(); - - try { - log.info("开始更新用户推广等级 - userId: {}, strategy: {}, source: {}", - userId, strategy.getCode(), triggerSource); - - // 1. 获取用户当前信息 - User user = userMapper.selectById(userId); - if (user == null) { - log.warn("用户不存在 - userId: {}", userId); - return createFailedResult(triggerSource); - } - - Integer currentLevel = user.getPromotionLevel(); - - // 2. 根据策略计算新等级 - int newLevel = calculateLevelByStrategy(user, strategy); - - // 3. 检查等级是否发生变化 - if (Objects.equals(currentLevel, newLevel)) { - log.debug("用户推广等级未发生变化 - userId: {}, level: {}", userId, currentLevel); - return createUnchangedResult(currentLevel, triggerSource); - } - - // 4. 更新数据库 - int updatedRows = userMapper.updatePromotionLevel(userId, newLevel); - if (updatedRows == 0) { - log.warn("更新用户推广等级失败,可能存在并发更新 - userId: {}", userId); - //可以选择返回失败或者重新尝试 - return createFailedResult(triggerSource); - } - - // 5. 记录审计日志 - recordAuditLog(userId, currentLevel, newLevel, strategy, triggerSource); - - // 6. 发布等级变化事件 - publishLevelChangedEvent(userId, currentLevel, newLevel, triggerSource); - - log.info("用户推广等级更新成功 - userId: {}, level: {} -> {}, strategy: {}, source: {}", - userId, currentLevel, newLevel, strategy.getCode(), triggerSource); - - return createSuccessResult(currentLevel, newLevel, triggerSource); - - } finally { - userLock.unlock(); - // 当锁没有其他等待线程时,从map中移除,避免内存泄漏 - userLocks.compute(userId, (k, v) -> (v != null && v.hasQueuedThreads()) ? v : null); - } - } - - /** - * 根据策略计算推广等级 - */ - private int calculateLevelByStrategy(User user, CalculationStrategy strategy) { - int fansCount; - Long userId = user.getId(); - - switch (strategy) { - case TOTAL_FANS_ONLY: - fansCount = userMapper.countFansByInviterId(userId); - break; - case WEIGHTED_AVERAGE: - // 加权策略:付费粉丝权重 * 2 + 总粉丝权重 * 1 - // TODO: 可以优化为一次数据库查询返回两个字段 - int paidFans = userMapper.countPaidFansByInviterId(userId); - int totalFans = userMapper.countFansByInviterId(userId); - fansCount = (paidFans * 2) + totalFans; - break; - case PAID_FANS_ONLY: - default: - fansCount = userMapper.countPaidFansByInviterId(userId); - } - - return calculatePromotionLevel(fansCount); - } - - /** - * 根据粉丝数计算推广等级 - */ - private int calculatePromotionLevel(int fansCount) { - try { - List configs = self.getPromotionRevenueConfigs(); - - return configs.stream() - .filter(config -> config.getMinFans() != null && fansCount >= config.getMinFans()) - .mapToInt(RevenueConfig::getLevel) - .max() - .orElse(1); - - } catch (Exception e) { - log.error("计算推广等级失败 - fansCount: {}", fansCount, e); - return 1; // 默认返回1级 - } - } - - /** - * 获取并缓存推广收益配置 - */ - @Cacheable("revenueConfigs") - public List getPromotionRevenueConfigs() { - return revenueConfigMapper.selectByConfigType("promotion"); - } - - /** - * 记录审计日志 - */ - private void recordAuditLog(Long userId, Integer oldLevel, Integer newLevel, - CalculationStrategy strategy, String triggerSource) { - // 这里可以记录到专门的审计日志表 - String strategyCode = (strategy != null) ? strategy.getCode() : "admin_override"; - log.info("推广等级变化审计 - userId: {}, level: {} -> {}, strategy: {}, source: {}, time: {}", - userId, oldLevel, newLevel, strategyCode, triggerSource, LocalDateTime.now()); - } - - /** - * 发布等级变化事件 - */ - private void publishLevelChangedEvent(Long userId, Integer oldLevel, Integer newLevel, String triggerSource) { - try { - PromotionLevelChangedEvent event = new PromotionLevelChangedEvent( - this, userId, oldLevel, newLevel, triggerSource); - eventPublisher.publishEvent(event); - } catch (Exception e) { - log.error("发布推广等级变化事件失败 - userId: {}", userId, e); - } - } - - /** - * 批量更新推广等级(管理员操作) - */ - @Transactional - public BatchUpdateResult batchUpdatePromotionLevel(List userIds, Integer targetLevel, String adminId) { - log.info("管理员批量更新推广等级 - adminId: {}, userCount: {}, targetLevel: {}", - adminId, userIds.size(), targetLevel); - - BatchUpdateResult.BatchUpdateResultBuilder resultBuilder = BatchUpdateResult.builder(); - - if (userIds == null || userIds.isEmpty()) { - return resultBuilder.build(); - } - - List users = userMapper.selectBatchIds(userIds); - Map userMap = users.stream().collect(Collectors.toMap(User::getId, user -> user)); - - for (Long userId : userIds) { - User user = userMap.get(userId); - if (user == null) { - resultBuilder.failedUser(userId, "用户不存在"); - continue; - } - - Integer oldLevel = user.getPromotionLevel(); - if (Objects.equals(oldLevel, targetLevel)) { - resultBuilder.skippedUser(userId, "等级未变化"); - continue; - } - - int updatedRows = userMapper.updatePromotionLevel(userId, targetLevel); - if (updatedRows > 0) { - resultBuilder.successUser(userId); - recordAuditLog(userId, oldLevel, targetLevel, null, "admin_batch_update:" + adminId); - publishLevelChangedEvent(userId, oldLevel, targetLevel, "admin_batch_update"); - } else { - resultBuilder.failedUser(userId, "数据库更新失败"); - } - } - - BatchUpdateResult result = resultBuilder.build(); - log.info("批量更新推广等级完成 - 成功: {}, 失败: {}, 跳过: {}", - result.getSuccessCount(), result.getFailedCount(), result.getSkippedCount()); - - return result; - } - - // 辅助方法创建结果对象 - private PromotionLevelUpdateResult createSuccessResult(Integer oldLevel, Integer newLevel, String triggerSource) { - return PromotionLevelUpdateResult.builder() - .updated(true) - .oldLevel(oldLevel) - .newLevel(newLevel) - .triggerSource(triggerSource) - .updateTime(LocalDateTime.now()) - .build(); - } - - private PromotionLevelUpdateResult createUnchangedResult(Integer level, String triggerSource) { - return PromotionLevelUpdateResult.builder() - .updated(false) - .oldLevel(level) - .newLevel(level) - .triggerSource(triggerSource) - .updateTime(LocalDateTime.now()) - .build(); - } - - private PromotionLevelUpdateResult createFailedResult(String triggerSource) { - return PromotionLevelUpdateResult.builder() - .updated(false) - .triggerSource(triggerSource) - .updateTime(LocalDateTime.now()) - .build(); - } - - /** - * 批量更新结果 - */ - @Getter - @Builder - public static class BatchUpdateResult { - @Singular - private final List successUsers; - @Singular - private final Map failedUsers; - @Singular - private final Map skippedUsers; - - public int getSuccessCount() { return successUsers.size(); } - public int getFailedCount() { return failedUsers.size(); } - public int getSkippedCount() { return skippedUsers.size(); } - } -} diff --git a/PromotionLevelManager_Optimization_Example.java b/PromotionLevelManager_Optimization_Example.java deleted file mode 100644 index 8b13789..0000000 --- a/PromotionLevelManager_Optimization_Example.java +++ /dev/null @@ -1 +0,0 @@ - diff --git a/QUICK_FIX.md b/QUICK_FIX.md deleted file mode 100644 index a3484b9..0000000 --- a/QUICK_FIX.md +++ /dev/null @@ -1,68 +0,0 @@ -# V5数据库迁移问题快速修复 - -**错误:** `#1060 - Duplicate column name 'provider_type'` - ---- - -## 🚀 一键修复 - -### 方案1:修复现有数据(推荐) - -```bash -# 1. 执行修复SQL -mysql -u root -p 1818ai << 'EOF' --- 更新RunningHub模型的provider_type -UPDATE `points_config` -SET `provider_type` = 'runninghub' -WHERE `model_name` LIKE 'rh_sora2_%' - AND (`provider_type` = '' OR `provider_type` IS NULL); - --- 验证结果 -SELECT model_name, provider_type, points_cost -FROM `points_config` -WHERE `model_name` LIKE 'rh_sora2_%'; -EOF - -# 2. 验证:应该看到12个模型,provider_type都是'runninghub' -``` - ---- - -### 方案2:使用修复脚本 - -```bash -# 执行修复脚本 -mysql -u root -p 1818ai < FIX_V5_provider_type.sql - -# 查看结果 -mysql -u root -p 1818ai -e "SELECT model_name, provider_type FROM points_config WHERE model_name LIKE 'rh_sora2_%';" -``` - ---- - -## ✅ 验证修复成功 - -```sql --- 所有12个模型的provider_type应该都是'runninghub' -SELECT - COUNT(*) as total_models, - SUM(CASE WHEN provider_type = 'runninghub' THEN 1 ELSE 0 END) as correct_count -FROM `points_config` -WHERE `model_name` LIKE 'rh_sora2_%'; - --- 预期结果: --- total_models: 12 --- correct_count: 12 -``` - ---- - -## 📋 如果还有问题 - -查看详细文档:`V5_MIGRATION_FIX_GUIDE.md` - ---- - -**修复完成后,系统就可以正常使用RunningHub功能了!** ✅ - - diff --git a/QUICK_REFERENCE.md b/QUICK_REFERENCE.md deleted file mode 100644 index 781471e..0000000 --- a/QUICK_REFERENCE.md +++ /dev/null @@ -1,164 +0,0 @@ -# RunningHub集成快速参考卡 - -**版本:** v2.2.0 | **更新:** 2025-10-20 - ---- - -## 🎯 一分钟快速了解 - -### 完成的功能 -- ✅ 集成RunningHub Sora2 API(文生视频 + 图生视频) -- ✅ 12个预配置模型(竖屏/横屏 × 普通/高清 × 10秒/15秒) -- ✅ 多厂商架构(OpenAI + RunningHub无缝切换) -- ✅ 10秒轮询优化(成本降低50%) -- ✅ 完整URL支持(图生视频无需预先上传) -- ✅ **并发控制**(最多100个轮询任务) -- ✅ **队列管理**(超出自动排队) - -### 核心配置 - -```yaml -# application.yml -ai.providers.runninghub: - polling-interval: 10000 # 10秒轮询 - max-polling-times: 60 # 最大10分钟 - max-polling-tasks: 100 # 最多100个并发轮询 - queue-check-interval: 5000 # 5秒检查队列 - api-key: "5c44cef12da3470e9f24da70c63787dc" -``` - ---- - -## 📝 快速测试 - -### 1. 文生视频(竖屏10秒) - -```bash -curl -X POST "http://localhost:8081/user/ai/tasks/submit" \ - -H "Authorization: Bearer YOUR_TOKEN" \ - -H "Content-Type: application/json" \ - -d '{ - "modelName": "rh_sora2_text_portrait", - "prompt": "一个人在海边奔跑" - }' -``` - -### 2. 图生视频(横屏高清) - -```bash -curl -X POST "http://localhost:8081/user/ai/tasks/submit" \ - -H "Authorization: Bearer YOUR_TOKEN" \ - -H "Content-Type: application/json" \ - -d '{ - "modelName": "rh_sora2_img_landscape_hd", - "prompt": "让场景动起来", - "imageUrl": "https://example.com/image.jpg" - }' -``` - ---- - -## 📊 模型列表(12个) - -| 模型名称 | 类型 | 时长 | 分辨率 | 积分 | -|---------|------|------|--------|------| -| rh_sora2_text_portrait | 文生视频 | 10秒 | 竖屏 | 160 | -| rh_sora2_text_landscape | 文生视频 | 10秒 | 横屏 | 160 | -| rh_sora2_text_portrait_hd | 文生视频 | 10秒 | 高清竖屏 | 420 | -| rh_sora2_text_landscape_hd | 文生视频 | 10秒 | 高清横屏 | 420 | -| rh_sora2_text_portrait_15s | 文生视频 | 15秒 | 竖屏 | 260 | -| rh_sora2_text_landscape_15s | 文生视频 | 15秒 | 横屏 | 260 | -| rh_sora2_img_portrait | 图生视频 | 10秒 | 竖屏 | 180 | -| rh_sora2_img_landscape | 图生视频 | 10秒 | 横屏 | 180 | -| rh_sora2_img_portrait_hd | 图生视频 | 10秒 | 高清竖屏 | 480 | -| rh_sora2_img_landscape_hd | 图生视频 | 10秒 | 高清横屏 | 480 | -| rh_sora2_img_portrait_15s | 图生视频 | 15秒 | 竖屏 | 280 | -| rh_sora2_img_landscape_15s | 图生视频 | 15秒 | 横屏 | 280 | - ---- - -## 🚀 部署步骤(3步) - -```bash -# 1. 数据库迁移 -mysql -u root -p 1818ai < V5__add_provider_support.sql - -# 2. 编译部署 -mvn clean package -DskipTests -sudo systemctl restart spring_1818_user_server - -# 3. 验证 -sudo journalctl -u spring_1818_user_server | grep "注册AI Provider" -# 应看到:openai + runninghub -``` - ---- - -## 🔍 监控命令 - -```bash -# 查看队列状态(管理员接口) -curl "http://localhost:8081/admin/runninghub/queue/status" \ - -H "Authorization: Bearer $ADMIN_TOKEN" - -# 查看处理中的任务数 -mysql -u root -p 1818ai -e "SELECT COUNT(*) FROM ai_task WHERE status='processing' AND provider_type='runninghub';" - -# 查看等待队列中的任务数 -mysql -u root -p 1818ai -e "SELECT COUNT(*) FROM ai_task WHERE status='queued' AND provider_type='runninghub';" - -# 实时轮询日志 -sudo journalctl -u spring_1818_user_server -f | grep -E "(RunningHub|队列)" - -# 手动处理队列(管理员操作) -curl "http://localhost:8081/admin/runninghub/queue/process" \ - -H "Authorization: Bearer $ADMIN_TOKEN" -``` - ---- - -## 📚 完整文档 - -| 文档 | 说明 | -|-----|------| -| `RUNNINGHUB_FINAL_SUMMARY.md` | **总览**(推荐首读) | -| `RUNNINGHUB_QUEUE_OPTIMIZATION.md` | **队列优化方案**(v2.2.0新增) | -| `RUNNINGHUB_USAGE_GUIDE.md` | 使用指南(12个模型详解) | -| `RUNNINGHUB_CONCURRENCY_ANALYSIS.md` | 并发能力分析 | -| `POLLING_INTERVAL_OPTIMIZATION.md` | 轮询优化说明 | -| `DEPLOYMENT_CHECKLIST.md` | 部署检查清单 | -| `MULTI_VENDOR_ADAPTER_DESIGN.md` | 架构设计 | - ---- - -## ⚠️ 注意事项 - -1. **图生视频不支持真人图像** -2. **轮询任务上限100个**(超出自动进入等待队列) -3. **imageUrl支持完整HTTP/HTTPS地址** -4. **任务失败自动退还积分** -5. **等待队列自动处理**(每5秒检查一次) - ---- - -## 💡 常见问题 - -**Q:任务一直processing?** -A:正常,RunningHub需要2-5分钟处理。查看轮询日志确认。 - -**Q:任务卡在queued状态?** -A:说明当前轮询任务已满(100个),正在等待队列。任务完成后会自动提交。 - -**Q:如何查看队列状态?** -A:使用管理员接口:`GET /admin/runninghub/queue/status` - -**Q:如何调整并发上限?** -A:修改 `application.yml` 中的 `max-polling-tasks`(默认100) - -**Q:等待队列会堆积吗?** -A:不会。任务完成后自动从队列提交新任务,队列持续消化。 - ---- - -**快速参考完毕!详细信息请查看完整文档。** 📖 - diff --git a/QUICK_START_POINTS_RECHARGE.md b/QUICK_START_POINTS_RECHARGE.md deleted file mode 100644 index a554ff0..0000000 --- a/QUICK_START_POINTS_RECHARGE.md +++ /dev/null @@ -1,284 +0,0 @@ -# 积分充值系统 - 快速启动 - -## 🚀 5分钟快速上手 - -### 1️⃣ 执行数据库迁移 - -```bash -mysql -u root -p 1818ai < V6__add_points_recharge_system.sql -``` - -**验证**: -```sql --- 检查套餐数据 -SELECT name, points, bonus_points, total_points, price FROM points_package; --- 应该看到6个套餐 - --- 检查order表新字段 -DESC `order`; --- 应该包含 order_type, points_package_id, points_amount -``` - ---- - -### 2️⃣ 启动应用 - -```bash -mvn spring-boot:run -``` - -或者 - -```bash -mvn clean package -java -jar target/1818_user_server-0.0.1-SNAPSHOT.jar -``` - ---- - -### 3️⃣ 测试接口 - -#### 步骤1:获取套餐列表(无需登录) - -```bash -curl -X GET "http://localhost:8080/user/points/packages" -``` - -**预期响应**: -```json -{ - "code": 200, - "data": [ - { - "id": 1, - "name": "体验包", - "points": 100, - "price": 10.00, - ... - } - ] -} -``` - ---- - -#### 步骤2:用户登录获取Token - -```bash -curl -X POST "http://localhost:8080/user/auth/login" \ - -H "Content-Type: application/json" \ - -d '{"phone":"13800138000","password":"123456"}' -``` - -**获取token**: -```json -{ - "code": 200, - "data": { - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." - } -} -``` - ---- - -#### 步骤3:创建充值订单(需要登录) - -```bash -curl -X POST "http://localhost:8080/user/points/recharge" \ - -H "Authorization: Bearer YOUR_TOKEN_HERE" \ - -H "Content-Type: application/json" \ - -d '{"packageId":2,"paymentMethod":2}' -``` - -**预期响应**: -```json -{ - "code": 200, - "data": { - "orderNo": "ORD20251021123456", - "amount": 48.00, - "pointsAmount": 605, - "paymentMethod": 2 - } -} -``` - -**注意**: -- `pointsAmount` 可能是 605(500基础+50赠送+55首充奖励) -- 如果是首次充值,会有10%的额外奖励 - ---- - -#### 步骤4:模拟支付成功(测试用) - -```bash -curl -X POST "http://localhost:8080/payment/callback/test?orderNo=ORD20251021123456" -``` - -**预期响应**:`success` - ---- - -#### 步骤5:查看用户积分 - -```bash -curl -X GET "http://localhost:8080/user/info" \ - -H "Authorization: Bearer YOUR_TOKEN_HERE" -``` - -**验证积分是否到账**: -```json -{ - "code": 200, - "data": { - "points": 605, - "pointsExpiresAt": "2026-10-21T12:35:10" - } -} -``` - ---- - -#### 步骤6:查看充值记录 - -```bash -curl -X GET "http://localhost:8080/user/points/recharge/records?page=1&size=10" \ - -H "Authorization: Bearer YOUR_TOKEN_HERE" -``` - ---- - -## 📝 前端快速集成 - -### HTML示例 - -```html - - - - 积分充值 - - - 积分充值 - - - - - - - -``` - ---- - -## 🔐 Swagger测试 - -访问:`http://localhost:8080/doc.html` - -### 测试步骤: - -1. **获取套餐** → `GET /user/points/packages` -2. **用户登录** → `POST /user/auth/login` → 获取token -3. **点击右上角🔑图标** → 输入 `Bearer YOUR_TOKEN` -4. **创建充值订单** → `POST /user/points/recharge` -5. **测试支付回调** → `POST /payment/callback/test` -6. **查看充值记录** → `GET /user/points/recharge/records` - ---- - -## ✅ 完成检查清单 - -- [ ] 数据库迁移成功(6个套餐) -- [ ] 能够获取套餐列表 -- [ ] 能够创建充值订单 -- [ ] 测试支付回调成功 -- [ ] 用户积分正确到账 -- [ ] 充值记录正常显示 -- [ ] 首充奖励正确计算 - ---- - -## 🎉 成功! - -现在用户可以: -- ✅ 浏览积分套餐 -- ✅ 选择支付方式充值 -- ✅ 查看充值历史 -- ✅ 享受首充奖励 - -**下一步**:对接真实的支付宝/微信支付接口 - -详细文档请查看:`POINTS_RECHARGE_GUIDE.md` - diff --git a/RELEASE_NOTES_v2.2.0.md b/RELEASE_NOTES_v2.2.0.md deleted file mode 100644 index 4427563..0000000 --- a/RELEASE_NOTES_v2.2.0.md +++ /dev/null @@ -1,473 +0,0 @@ -# RunningHub集成 v2.2.0 发布说明 - -**发布日期:** 2025-10-20 -**版本类型:** 重要功能更新 -**升级优先级:** 🔥 高(推荐立即升级) - ---- - -## 🎉 版本亮点 - -### 核心功能:RunningHub并发控制与队列管理 - -本次更新解决了RunningHub任务无限制轮询导致的系统过载问题,引入了智能队列管理系统。 - -**关键改进:** -- ✅ **轮询任务上限**:最多同时轮询100个RunningHub任务 -- ✅ **自动队列管理**:超出限制的任务自动进入等待队列 -- ✅ **智能调度**:任务完成后自动提交队列中的新任务 -- ✅ **实时监控**:管理员可查看队列状态和手动干预 - ---- - -## 📊 性能对比 - -### v2.1.1(旧版本) - -| 并发任务数 | CPU使用率 | 内存占用 | 系统状态 | -|-----------|----------|---------|---------| -| 100 | 10% | 1.5GB | ✅ 正常 | -| 200 | 20% | 2.5GB | ⚠️ 压力 | -| 500 | 50% | 5GB | ❌ 过载 | -| 1000 | 80%+ | 10GB+ | ❌ 崩溃 | - -### v2.2.0(新版本) - -| 总任务数 | 轮询任务 | 等待队列 | CPU使用率 | 内存占用 | 系统状态 | -|---------|---------|---------|----------|---------|---------| -| 100 | 100 | 0 | 10% | 1.5GB | ✅ 正常 | -| 200 | 100 | 100 | 10% | 1.6GB | ✅ 正常 | -| 500 | 100 | 400 | 10% | 2GB | ✅ 正常 | -| 1000 | 100 | 900 | 10% | 3GB | ✅ 正常 | - -**改进效果:** -- ✅ CPU使用率固定在10%,不随并发增加 -- ✅ 内存占用可控,最多3GB(1000并发) -- ✅ 系统稳定性100%,无崩溃风险 -- ✅ 支持无限并发任务(通过队列) - ---- - -## 🆕 新增功能 - -### 1. RunningHub队列管理服务 - -**新增文件:** -- `RunningHubQueueService.java` - 队列管理接口 -- `RunningHubQueueServiceImpl.java` - 队列管理实现 - -**核心功能:** -- 管理正在轮询的任务集合(最多100个) -- 管理等待队列(FIFO顺序) -- 自动提交/取消任务 -- 线程安全保证 - -**使用示例:** -```java -// 提交任务(自动判断是立即提交还是加入队列) -boolean submitted = runningHubQueueService.enqueueOrSubmit(task); - -// 任务完成后通知队列服务 -runningHubQueueService.onTaskCompleted(taskNo); - -// 查看队列状态 -int pollingCount = runningHubQueueService.getPollingTaskCount(); -int waitingCount = runningHubQueueService.getWaitingQueueSize(); -``` - ---- - -### 2. 队列处理调度器 - -**新增文件:** -- `RunningHubQueueProcessor.java` - -**功能:** -- 每5秒检查一次等待队列 -- 当有空位时自动提交新任务 -- 每分钟记录队列状态日志 - -**调度策略:** -``` -每5秒执行: - if (轮询任务数 < 100 && 等待队列不为空) { - 提交新任务(); - } - -每60秒执行: - 记录队列状态日志(); -``` - ---- - -### 3. 管理员监控接口 - -**新增文件:** -- `AdminRunningHubQueueController.java` - -**接口列表:** - -#### GET `/admin/runninghub/queue/status` -查看RunningHub队列状态 - -**响应示例:** -```json -{ - "code": 200, - "data": { - "maxPollingTasks": 100, - "currentPollingTasks": 85, - "waitingQueueSize": 120, - "availableSlots": 15, - "utilizationRate": "85.0%", - "pollingTaskNos": ["TASK_001", "TASK_002", ...] - }, - "message": "success" -} -``` - -#### GET `/admin/runninghub/queue/process` -手动触发队列处理 - -**响应示例:** -```json -{ - "code": 200, - "data": { - "submittedTasks": 15, - "beforePolling": 85, - "afterPolling": 100, - "beforeWaiting": 120, - "afterWaiting": 105 - }, - "message": "已处理等待队列,提交了15个任务" -} -``` - ---- - -## 🔧 配置更新 - -### application.yml 新增配置 - -```yaml -ai: - providers: - runninghub: - max-polling-tasks: 100 # 新增:最大并发轮询任务数 - queue-check-interval: 5000 # 新增:队列检查间隔(毫秒) -``` - -### 默认值 - -| 配置项 | 默认值 | 说明 | -|-------|-------|------| -| `max-polling-tasks` | 100 | 最多同时轮询100个任务 | -| `queue-check-interval` | 5000 | 每5秒检查一次队列 | -| `polling-interval` | 10000 | 每10秒轮询一次任务状态 | -| `max-polling-times` | 60 | 最多轮询60次(10分钟) | - ---- - -## 📝 代码修改 - -### 修改的文件(3个) - -1. **`AiTaskServiceImpl.java`** - - 注入 `RunningHubQueueService` - - 使用队列服务提交RunningHub任务 - - ```java - // 旧代码 - if ("runninghub".equals(providerType)) { - submitToRunningHub(task, pointsConfig); - } - - // 新代码 - if ("runninghub".equals(providerType)) { - runningHubQueueService.enqueueOrSubmit(task); - } - ``` - -2. **`RunningHubPollingScheduler.java`** - - 任务完成时通知队列服务 - - ```java - // 任务成功完成 - notificationService.notifyTaskCompleted(...); - runningHubQueueService.onTaskCompleted(taskNo); // 新增 - - // 任务失败 - notificationService.notifyTaskFailed(...); - runningHubQueueService.onTaskCompleted(taskNo); // 新增 - ``` - -3. **`NotificationServiceImpl.java`** - - 修复缺失的 `notifyTaskProgress`、`notifyTaskCompleted`、`notifyTaskFailed` 方法 - ---- - -## 🚀 部署指南 - -### 1. 前置条件 - -- ✅ 已部署 v2.1.0 或 v2.1.1 -- ✅ 数据库已执行 `V5__add_provider_support.sql` -- ✅ 配置文件已包含 RunningHub 相关配置 - -### 2. 升级步骤 - -```bash -# 1. 停止服务 -sudo systemctl stop spring_1818_user_server - -# 2. 备份当前版本 -sudo cp /www/wwwroot/1818_user_server/1818_user_server-1.0-SNAPSHOT.jar \ - /www/wwwroot/1818_user_server/backups/v2.1.1_$(date +%Y%m%d_%H%M%S).jar - -# 3. 更新配置文件 -vim /www/wwwroot/1818_user_server/application.yml -# 添加: -# max-polling-tasks: 100 -# queue-check-interval: 5000 - -# 4. 部署新版本 -sudo cp target/1818_user_server-1.0-SNAPSHOT.jar \ - /www/wwwroot/1818_user_server/ - -# 5. 启动服务 -sudo systemctl start spring_1818_user_server - -# 6. 验证部署 -sudo journalctl -u spring_1818_user_server -f | grep -E "(队列|Queue|Provider)" -``` - -### 3. 验证清单 - -```bash -# ✅ 检查Provider注册 -sudo journalctl -u spring_1818_user_server | grep "注册AI Provider" -# 预期:openai + runninghub - -# ✅ 检查队列处理器启动 -sudo journalctl -u spring_1818_user_server | grep "RunningHubQueueProcessor" - -# ✅ 测试队列状态接口 -curl "http://localhost:8081/admin/runninghub/queue/status" \ - -H "Authorization: Bearer $ADMIN_TOKEN" - -# ✅ 提交测试任务 -curl -X POST "http://localhost:8081/user/ai/tasks/submit" \ - -H "Authorization: Bearer $USER_TOKEN" \ - -H "Content-Type: application/json" \ - -d '{"modelName":"rh_sora2_text_portrait","prompt":"测试队列"}' - -# ✅ 观察日志 -sudo journalctl -u spring_1818_user_server -f | grep "RunningHub队列" -``` - ---- - -## 📖 文档更新 - -### 新增文档 - -1. **`RUNNINGHUB_QUEUE_OPTIMIZATION.md`** - 队列优化方案详解 - - 问题分析 - - 架构设计 - - 性能对比 - - 配置调优 - - 故障排查 - -2. **`RELEASE_NOTES_v2.2.0.md`** - 本文档 - -### 更新文档 - -1. **`QUICK_REFERENCE.md`** - 快速参考 - - 更新版本号为 v2.2.0 - - 添加队列管理说明 - - 添加新的监控命令 - -2. **`RUNNINGHUB_FINAL_SUMMARY.md`** - 需要更新(推荐) - ---- - -## ⚠️ 注意事项 - -### 1. 兼容性 - -- ✅ **向后兼容**:v2.1.x 可直接升级到 v2.2.0 -- ✅ **配置兼容**:旧配置仍然有效 -- ✅ **数据库兼容**:无需执行新的迁移脚本 - -### 2. 行为变化 - -**旧版本(v2.1.1):** -- 用户提交任务 → 立即提交到RunningHub → 立即开始轮询 -- 100个并发 → 100个轮询 -- 500个并发 → 500个轮询(系统过载) - -**新版本(v2.2.0):** -- 用户提交任务 → 检查轮询数 - - ≤100 → 立即提交 → 开始轮询 - - >100 → 加入等待队列 → 等待空位 -- 100个并发 → 100个轮询 -- 500个并发 → 100个轮询 + 400个等待 - -**影响:** -- ✅ 第101个及以后的任务会经历短暂的 `queued` 状态 -- ✅ 用户可以看到队列位置和预计等待时间 -- ✅ 任务完成后会自动从队列提交,无需人工干预 - -### 3. 性能影响 - -- ✅ **CPU使用率**:固定在10%,不会随并发增加 -- ✅ **内存占用**:略微增加(队列对象开销),1000并发时约3GB -- ✅ **响应时间**:第1-100个任务无影响,第101+个任务需等待 -- ✅ **系统稳定性**:显著提升,无崩溃风险 - ---- - -## 🔧 配置建议 - -### 场景1:低并发(<50任务/小时) - -```yaml -max-polling-tasks: 50 # 降低上限节省资源 -queue-check-interval: 10000 # 降低检查频率 -``` - -### 场景2:中等并发(50-200任务/小时)✅ **推荐** - -```yaml -max-polling-tasks: 100 # 默认配置 -queue-check-interval: 5000 -``` - -### 场景3:高并发(200+任务/小时) - -```yaml -max-polling-tasks: 150 # 提高上限 -queue-check-interval: 3000 # 加快检查频率 -``` - -**注意:** `max-polling-tasks` 不建议超过200,否则可能触发RunningHub限流。 - ---- - -## 📊 监控与告警 - -### 关键指标 - -```sql --- 1. 轮询任务数(应≤100) -SELECT COUNT(*) as polling_tasks -FROM ai_task -WHERE status = 'processing' - AND provider_type = 'runninghub' - AND is_deleted = 0; - --- 2. 等待队列长度 -SELECT COUNT(*) as waiting_tasks -FROM ai_task -WHERE status = 'queued' - AND provider_type = 'runninghub' - AND is_deleted = 0; - --- 3. 队列处理效率(每分钟完成任务数) -SELECT COUNT(*) / 60 as tasks_per_minute -FROM ai_task -WHERE status = 'completed' - AND provider_type = 'runninghub' - AND complete_time > DATE_SUB(NOW(), INTERVAL 1 HOUR); -``` - -### 告警规则 - -```yaml -alerts: - - name: "RunningHub等待队列过长" - condition: waiting_tasks > 500 - action: 发送通知 + 考虑增加max-polling-tasks - - - name: "队列处理效率低" - condition: tasks_per_minute < 10 - action: 检查RunningHub API状态 -``` - ---- - -## 🐛 已知问题 - -### 1. 队列顺序 - -**问题:** 等待队列按FIFO顺序处理,不支持优先级。 - -**影响:** VIP用户和普通用户任务混在一起排队。 - -**解决方案:** v2.3.0 将引入优先级队列。 - -### 2. 队列持久化 - -**问题:** 等待队列存储在内存中,服务重启后丢失。 - -**影响:** 服务重启时,等待中的任务需要重新提交。 - -**解决方案:** v2.3.0 将使用Redis持久化队列。 - ---- - -## 🎯 下一步计划(v2.3.0) - -1. **优先级队列** - VIP用户任务优先处理 -2. **Redis队列** - 队列持久化,服务重启不丢失 -3. **动态限流** - 根据RunningHub API响应时间自动调整并发数 -4. **分布式部署** - 支持多个轮询服务实例 - ---- - -## 📞 技术支持 - -### 遇到问题? - -1. **查看文档** - - `RUNNINGHUB_QUEUE_OPTIMIZATION.md` - 队列优化详解 - - `QUICK_REFERENCE.md` - 快速参考 - -2. **检查日志** - ```bash - sudo journalctl -u spring_1818_user_server -f | grep -E "(队列|Queue|ERROR)" - ``` - -3. **查看队列状态** - ```bash - curl "http://localhost:8081/admin/runninghub/queue/status" \ - -H "Authorization: Bearer $ADMIN_TOKEN" - ``` - -4. **手动处理队列** - ```bash - curl "http://localhost:8081/admin/runninghub/queue/process" \ - -H "Authorization: Bearer $ADMIN_TOKEN" - ``` - ---- - -## ✅ 总结 - -**v2.2.0 是一个重要的稳定性更新**,解决了RunningHub任务无限制轮询导致的系统过载问题。 - -**升级收益:** -- ✅ 系统稳定性提升90%+ -- ✅ CPU/内存占用可控 -- ✅ 支持无限并发任务 -- ✅ 完善的监控和管理功能 - -**推荐所有v2.1.x用户立即升级到v2.2.0!** 🚀 - ---- - -**发布团队:** 1818AI技术团队 -**发布时间:** 2025-10-20 -**版本号:** v2.2.0 - diff --git a/RUNNINGHUB_CONCURRENCY_ANALYSIS.md b/RUNNINGHUB_CONCURRENCY_ANALYSIS.md deleted file mode 100644 index 249a469..0000000 --- a/RUNNINGHUB_CONCURRENCY_ANALYSIS.md +++ /dev/null @@ -1,580 +0,0 @@ -# RunningHub 并发能力分析与优化方案 - -**版本:** v2.1.0 -**更新时间:** 2025-10-20 -**分析人员:** AI架构团队 - ---- - -## 📊 一、RunningHub API并发能力评估 - -### 1.1 API架构分析 - -RunningHub采用**异步任务处理模式**,这种架构天然支持高并发: - -``` -客户端请求 → 提交任务(秒级响应) → 返回TaskID → 客户端轮询 → 获取结果 -``` - -**优势:** -- ✅ 提交接口无需等待任务完成,可快速响应 -- ✅ 任务在后台队列中处理,不占用HTTP连接 -- ✅ 理论上可同时提交大量任务 - ---- - -### 1.2 并发限制因素 - -#### A. API Key限制(未知,需测试) - -RunningHub未公开以下限制: -- ❓ 每秒最大请求数(QPS) -- ❓ 每分钟最大请求数(QPM) -- ❓ 单个API Key的并发任务数 -- ❓ 账户级别的任务队列限制 - -**建议测试方案:** -```bash -# 逐步压力测试 -1. 同时提交10个任务 → 观察响应 -2. 同时提交50个任务 → 观察是否限流 -3. 同时提交100个任务 → 找到阈值 -``` - -#### B. 任务处理能力 - -根据API文档分析: -- **文生视频(10秒):** 预计处理时间 2-5分钟 -- **图生视频(10秒):** 预计处理时间 2-5分钟 -- **高清视频:** 预计处理时间 5-10分钟 - -**并发处理能力估算:** -假设RunningHub后台有100个GPU实例,平均处理时间3分钟: -``` -理论最大并发 = 100个GPU × (60秒 / 3分钟) = 约2000个任务/小时 -``` - -#### C. 网络带宽限制 - -- **请求体大小:** - - 文生视频:~2KB(prompt + 配置) - - 图生视频:~10KB-500KB(包含图片URL或Base64) - -- **响应体大小:** - - 提交响应:~500B - - 状态查询:~300B - - 结果获取:~1KB(只返回URL) - -**预计带宽需求(100并发):** -``` -上传:100 × 500KB = 50MB -下载(轮询10次/任务):100 × 10 × 1KB = 1MB -总计:~51MB(一次性峰值) -``` - ---- - -## 🔧 二、当前系统并发配置 - -### 2.1 系统参数 - -```yaml -# application.yml -ai: - providers: - runninghub: - polling-interval: 10000 # 轮询间隔 10秒(已优化) - max-polling-times: 60 # 最大轮询60次 = 10分钟 - queue: - max-concurrent: 50 # 每个模型最大并发50个 -``` - -### 2.2 并发能力计算 - -#### A. 系统级并发 - -**RunningHub模型数量:** 12个 -``` -rh_sora2_text_portrait (文生视频-竖屏) -rh_sora2_text_landscape (文生视频-横屏) -rh_sora2_text_portrait_hd (文生视频-高清竖屏) -rh_sora2_text_landscape_hd (文生视频-高清横屏) -rh_sora2_text_portrait_15s (文生视频-竖屏15秒) -rh_sora2_text_landscape_15s (文生视频-横屏15秒) -rh_sora2_img_portrait (图生视频-竖屏) -rh_sora2_img_landscape (图生视频-横屏) -rh_sora2_img_portrait_hd (图生视频-高清竖屏) -rh_sora2_img_landscape_hd (图生视频-高清横屏) -rh_sora2_img_portrait_15s (图生视频-竖屏15秒) -rh_sora2_img_landscape_15s (图生视频-横屏15秒) -``` - -**理论最大并发:** -``` -12个模型 × 50个/模型 = 600个并发任务 -``` - -**但实际上:** -- RunningHub任务不走我们的队列系统(直接提交) -- 只受RunningHub API限制,不受我们的max-concurrent限制 - -**实际并发能力:** **无限制**(取决于RunningHub服务端) - -#### B. 轮询调度器负载 - -```java -@Scheduled(fixedRateString = "${ai.providers.runninghub.polling-interval:10000}") -public void pollRunningHubTasks() { - // 查询所有processing状态的RunningHub任务 - List processingTasks = aiTaskMapper.findProcessingTasksByProvider("runninghub"); - - // 每10秒轮询一次 - for (AiTask task : processingTasks) { - // 查询状态 → 更新数据库 → 发送WebSocket通知 - } -} -``` - -**轮询负载分析(10秒间隔):** - -| 并发任务数 | 每次轮询耗时 | CPU使用率 | 网络流量/分钟 | -|-----------|------------|----------|--------------| -| 10 | ~1秒 | <5% | ~180KB | -| 50 | ~5秒 | ~10% | ~900KB | -| 100 | ~10秒 | ~20% | ~1.8MB | -| 200 | ~20秒 | ~40% | ~3.6MB | -| 500 | ~50秒 | ~80% | ~9MB | - -**安全阈值:** 建议不超过**200个并发任务**,否则轮询调度器可能积压 - ---- - -## ⚠️ 三、潜在风险与瓶颈 - -### 3.1 轮询调度器阻塞 - -**问题:** 如果并发任务过多,单次轮询时间超过10秒,会导致任务堆积。 - -**示例:** -``` -T0: 开始轮询200个任务(预计20秒) -T10: 第二次调度触发,但上一次还没结束 → 跳过或阻塞 -T20: 第一次轮询完成 -T30: 第三次调度触发 -``` - -**解决方案:** -1. 使用 `@Scheduled(fixedDelay = 10000)` 替代 `fixedRate` -2. 增加线程池,并发查询状态 - -### 3.2 数据库连接池耗尽 - -**当前连接池配置(默认):** HikariCP 默认10个连接 - -**风险:** -``` -200个并发任务 × 每个任务3次数据库操作(查询+更新+日志) = 600次DB操作/10秒 -``` - -**解决方案:** -```yaml -spring: - datasource: - hikari: - maximum-pool-size: 50 # 增加连接池大小 - minimum-idle: 10 - connection-timeout: 30000 -``` - -### 3.3 WebSocket连接数 - -**问题:** 每个在线用户需要一个WebSocket连接来接收实时通知。 - -**并发用户数 vs WebSocket连接:** -``` -100个并发用户 = 100个WebSocket连接 -500个并发用户 = 500个WebSocket连接 -``` - -**Tomcat默认限制:** 200个线程 - -**解决方案:** -```yaml -server: - tomcat: - threads: - max: 500 # 增加最大线程数 - min-spare: 50 -``` - ---- - -## 🚀 四、并发优化方案 - -### 方案A:保守配置(推荐用于初期) - -**目标:** 稳定性优先,支持 **100个并发任务** - -```yaml -ai: - providers: - runninghub: - polling-interval: 10000 # 10秒轮询 - max-polling-times: 60 - -spring: - datasource: - hikari: - maximum-pool-size: 30 - minimum-idle: 10 - -server: - tomcat: - threads: - max: 300 - min-spare: 50 -``` - -**预期性能:** -- ✅ 轮询时间:~10秒/轮 -- ✅ CPU使用率:<20% -- ✅ 内存占用:<2GB -- ✅ 网络带宽:~2MB/分钟 - ---- - -### 方案B:高并发配置(成熟期) - -**目标:** 性能优先,支持 **500个并发任务** - -```yaml -ai: - providers: - runninghub: - polling-interval: 15000 # 15秒轮询(减少频率) - max-polling-times: 40 # 最大轮询40次 = 10分钟 - batch-size: 50 # 分批查询,每批50个 - -spring: - datasource: - hikari: - maximum-pool-size: 100 - minimum-idle: 20 - -server: - tomcat: - threads: - max: 1000 - min-spare: 100 - - # 异步线程池配置 - task: - execution: - pool: - core-size: 50 - max-size: 200 - queue-capacity: 500 -``` - -**优化代码(分批轮询):** -```java -@Scheduled(fixedDelay = 15000) -public void pollRunningHubTasks() { - List allTasks = aiTaskMapper.findProcessingTasksByProvider("runninghub"); - - // 分批处理,每批50个 - int batchSize = 50; - for (int i = 0; i < allTasks.size(); i += batchSize) { - List batch = allTasks.subList(i, Math.min(i + batchSize, allTasks.size())); - - // 并发查询这批任务 - batch.parallelStream().forEach(task -> { - try { - pollSingleTask(task); - } catch (Exception e) { - log.error("轮询任务失败: {}", task.getTaskNo(), e); - } - }); - } -} -``` - -**预期性能:** -- ✅ 轮询时间:~15秒/轮(分批并发) -- ✅ CPU使用率:<50% -- ✅ 内存占用:<4GB -- ✅ 网络带宽:~10MB/分钟 - ---- - -### 方案C:极致优化(企业级) - -**目标:** 支持 **2000+并发任务** - -**架构升级:** -1. **Redis消息队列** 替代数据库轮询 -2. **独立轮询服务** 部署多个实例 -3. **负载均衡** 分散WebSocket连接 -4. **限流熔断** 保护RunningHub API - -```mermaid -graph LR - A[用户请求] --> B[API网关] - B --> C[业务服务集群] - C --> D[Redis队列] - D --> E1[轮询服务1] - D --> E2[轮询服务2] - D --> E3[轮询服务3] - E1 --> F[RunningHub API] - E2 --> F - E3 --> F - F --> G[MySQL主从] - C --> H[WebSocket集群] -``` - ---- - -## 📈 五、RunningHub API限流策略 - -### 5.1 客户端限流(防止自身被封) - -```java -@Component -public class RunningHubRateLimiter { - - private final RateLimiter submitLimiter = RateLimiter.create(10.0); // 每秒10个提交 - private final RateLimiter queryLimiter = RateLimiter.create(50.0); // 每秒50个查询 - - public void beforeSubmit() { - submitLimiter.acquire(); // 阻塞直到获得许可 - } - - public void beforeQuery() { - queryLimiter.acquire(); - } -} -``` - -### 5.2 熔断降级(RunningHub故障时) - -```java -@Service -public class RunningHubProviderImpl implements AIProvider { - - @HystrixCommand( - fallbackMethod = "submitTaskFallback", - commandProperties = { - @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "10000"), - @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "20"), - @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "50") - } - ) - public ProviderTaskResponse submitTask(ProviderTaskRequest request) { - // 正常提交逻辑 - } - - public ProviderTaskResponse submitTaskFallback(ProviderTaskRequest request) { - log.error("RunningHub服务降级,任务提交失败"); - return ProviderTaskResponse.builder() - .status(TaskSubmitStatus.FAILED) - .errorMessage("RunningHub服务暂时不可用,请稍后重试") - .build(); - } -} -``` - ---- - -## 🧪 六、压力测试方案 - -### 6.1 测试工具 - -**JMeter测试脚本:** -```xml - - localhost - 8081 - /user/ai/tasks/submit - POST - true - - 100 - 10 - 1 - - -``` - -### 6.2 测试场景 - -#### 场景1:渐进式压力测试 - -```bash -# 阶段1:10并发,持续1分钟 -# 阶段2:50并发,持续5分钟 -# 阶段3:100并发,持续10分钟 -# 阶段4:200并发,持续10分钟 -``` - -**观察指标:** -- API响应时间(P50、P95、P99) -- 轮询延迟 -- 数据库连接池使用率 -- CPU/内存使用率 -- RunningHub API错误率 - -#### 场景2:峰值冲击测试 - -```bash -# 突然提交500个任务,观察系统恢复能力 -ab -n 500 -c 100 -T 'application/json' \ - -H "Authorization: Bearer TEST_TOKEN" \ - -p task_payload.json \ - http://localhost:8081/user/ai/tasks/submit -``` - ---- - -## 📊 七、监控与告警 - -### 7.1 关键指标 - -```sql --- 实时并发任务数 -SELECT COUNT(*) as running_tasks -FROM ai_task -WHERE provider_type = 'runninghub' - AND status = 'processing'; - --- 平均处理时间 -SELECT AVG(TIMESTAMPDIFF(SECOND, start_time, complete_time)) as avg_seconds -FROM ai_task -WHERE provider_type = 'runninghub' - AND status = 'completed' - AND complete_time > DATE_SUB(NOW(), INTERVAL 1 HOUR); - --- 失败率 -SELECT - COUNT(CASE WHEN status = 'failed' THEN 1 END) * 100.0 / COUNT(*) as failure_rate -FROM ai_task -WHERE provider_type = 'runninghub' - AND create_time > DATE_SUB(NOW(), INTERVAL 1 HOUR); -``` - -### 7.2 告警规则 - -```yaml -alerts: - - name: "RunningHub并发过高" - condition: running_tasks > 200 - action: 发送邮件/短信通知 - - - name: "RunningHub失败率过高" - condition: failure_rate > 10% - action: 触发熔断,停止新任务提交 - - - name: "轮询延迟过高" - condition: polling_delay > 30s - action: 重启轮询调度器 -``` - ---- - -## 💡 八、最佳实践建议 - -### 8.1 初期部署(100并发以内) - -1. ✅ 使用**方案A配置** -2. ✅ 轮询间隔设置为 **10秒**(已调整) -3. ✅ 监控RunningHub API响应时间 -4. ✅ 每日检查失败任务并分析原因 - -### 8.2 业务增长期(100-500并发) - -1. ✅ 升级到**方案B配置** -2. ✅ 实施分批轮询优化 -3. ✅ 增加数据库连接池和Tomcat线程数 -4. ✅ 引入限流和熔断机制 - -### 8.3 大规模部署(500+并发) - -1. ✅ 采用**方案C架构** -2. ✅ 独立部署轮询服务集群 -3. ✅ 使用Redis消息队列 -4. ✅ 实施全链路监控和自动告警 - ---- - -## 📝 九、RunningHub API费用估算 - -### 9.1 任务成本分析 - -根据 `V5__add_provider_support.sql` 中的积分配置: - -| 模型类型 | 积分消耗 | 实际成本(假设1元=100积分) | -|---------|---------|---------------------------| -| 文生视频(10秒,普通) | 160 | 1.6元 | -| 文生视频(10秒,高清) | 420 | 4.2元 | -| 图生视频(10秒,普通) | 180 | 1.8元 | -| 图生视频(10秒,高清) | 480 | 4.8元 | - -### 9.2 并发成本估算 - -**场景:100个并发任务/小时** - -假设任务分布: -- 60% 文生视频(普通):60 × 1.6元 = 96元 -- 20% 文生视频(高清):20 × 4.2元 = 84元 -- 15% 图生视频(普通):15 × 1.8元 = 27元 -- 5% 图生视频(高清):5 × 4.8元 = 24元 - -**总计:231元/小时** 或 **5544元/天** - -**建议:** -- 对于高频用户,设置每日任务数量限制 -- 引入会员等级,高级会员享受折扣 -- 批量购买积分时提供优惠 - ---- - -## ✅ 十、总结与建议 - -### 当前配置(已优化) - -```yaml -polling-interval: 10000 # ✅ 已改为10秒 -max-polling-times: 60 # ✅ 已调整为60次 -``` - -### 并发能力评估 - -| 并发任务数 | 系统负载 | 推荐配置 | 风险等级 | -|-----------|---------|---------|---------| -| 0-100 | 低 | 方案A | ✅ 安全 | -| 100-200 | 中 | 方案A | ⚠️ 注意 | -| 200-500 | 高 | 方案B | ⚠️ 风险 | -| 500+ | 极高 | 方案C | ❌ 需重构 | - -### 下一步行动 - -1. **短期(1周内):** - - [ ] 部署当前配置(10秒轮询) - - [ ] 监控前100个任务的表现 - - [ ] 收集RunningHub API响应时间数据 - -2. **中期(1个月内):** - - [ ] 进行渐进式压力测试 - - [ ] 找到RunningHub API的并发阈值 - - [ ] 根据实际情况调整轮询间隔 - -3. **长期(3个月内):** - - [ ] 如果并发超过200,实施方案B - - [ ] 引入Redis队列和独立轮询服务 - - [ ] 建立完善的监控和告警体系 - ---- - -**RunningHub并发分析完成!** 🎯 - -当前配置已优化为10秒轮询,建议从小规模开始,逐步增加并发,实时监控系统表现。 - diff --git a/RUNNINGHUB_FINAL_SUMMARY.md b/RUNNINGHUB_FINAL_SUMMARY.md deleted file mode 100644 index 22e5b8d..0000000 --- a/RUNNINGHUB_FINAL_SUMMARY.md +++ /dev/null @@ -1,400 +0,0 @@ -# RunningHub集成最终汇总 - v2.1.1 - -**项目:** 1818AI用户服务端 -**功能:** RunningHub Sora2 多厂商AI集成 -**完成时间:** 2025-10-20 -**版本:** v2.1.1(轮询优化版) - ---- - -## ✅ 完成状态:100% - -所有任务已完成,系统已就绪,可立即部署! - ---- - -## 📦 交付成果 - -### 1. 核心代码文件(19个新增 + 7个修改) - -#### 新增文件(19个) - -**Provider核心架构(5个)** -- ✅ `src/main/java/com/dora/service/provider/AIProvider.java` -- ✅ `src/main/java/com/dora/dto/provider/ProviderTaskRequest.java` -- ✅ `src/main/java/com/dora/dto/provider/ProviderTaskResponse.java` -- ✅ `src/main/java/com/dora/dto/provider/ProviderTaskStatus.java` -- ✅ `src/main/java/com/dora/dto/provider/ProviderTaskResult.java` - -**Provider实现(2个)** -- ✅ `src/main/java/com/dora/service/provider/impl/OpenAIProviderImpl.java` -- ✅ `src/main/java/com/dora/service/provider/impl/RunningHubProviderImpl.java` - -**RunningHub专用DTO(5个)** -- ✅ `src/main/java/com/dora/dto/runninghub/RunningHubSubmitRequest.java` -- ✅ `src/main/java/com/dora/dto/runninghub/RunningHubNodeInfo.java` -- ✅ `src/main/java/com/dora/dto/runninghub/RunningHubSubmitResponse.java` -- ✅ `src/main/java/com/dora/dto/runninghub/RunningHubStatusResponse.java` -- ✅ `src/main/java/com/dora/dto/runninghub/RunningHubOutputResponse.java` - -**核心服务(2个)** -- ✅ `src/main/java/com/dora/service/AIProviderService.java` -- ✅ `src/main/java/com/dora/scheduler/RunningHubPollingScheduler.java` - -**文档(5个)** -- ✅ `MULTI_VENDOR_ADAPTER_DESIGN.md` - 架构设计文档 -- ✅ `RUNNINGHUB_USAGE_GUIDE.md` - 使用指南(12个模型详解) -- ✅ `RUNNINGHUB_CONCURRENCY_ANALYSIS.md` - 并发能力分析 -- ✅ `POLLING_INTERVAL_OPTIMIZATION.md` - 轮询优化说明 -- ✅ `DEPLOYMENT_CHECKLIST.md` - 部署检查清单 - -#### 修改文件(7个) - -- ✅ `V5__add_provider_support.sql` - 数据库迁移(12个模型配置) -- ✅ `src/main/resources/application.yml` - 多厂商配置 + 10秒轮询 -- ✅ `src/main/java/com/dora/entity/AiTask.java` - 添加provider字段 -- ✅ `src/main/java/com/dora/entity/PointsConfig.java` - 添加provider字段 -- ✅ `src/main/java/com/dora/mapper/AiTaskMapper.java` - 查询方法 -- ✅ `src/main/resources/mapper/AiTaskMapper.xml` - SQL更新 -- ✅ `src/main/java/com/dora/service/impl/AiTaskServiceImpl.java` - Provider集成 - ---- - -## 🎯 核心功能 - -### 1. 多厂商支持 - -| 服务商 | 类型 | 模型数量 | 状态 | -|-------|------|---------|-----| -| OpenAI | 同步API | 原有模型 | ✅ 兼容 | -| RunningHub | 异步API | 12个Sora2 | ✅ 已集成 | - -### 2. RunningHub模型列表 - -#### 文生视频(6个) - -| 模型名称 | 时长 | 分辨率 | 积分 | webappId | -|---------|------|--------|------|----------| -| rh_sora2_text_portrait | 10秒 | 竖屏 | 160 | 1973555977595301890 | -| rh_sora2_text_landscape | 10秒 | 横屏 | 160 | 1973555977595301890 | -| rh_sora2_text_portrait_hd | 10秒 | 高清竖屏 | 420 | 1973555977595301890 | -| rh_sora2_text_landscape_hd | 10秒 | 高清横屏 | 420 | 1973555977595301890 | -| rh_sora2_text_portrait_15s | 15秒 | 竖屏 | 260 | 1973555977595301890 | -| rh_sora2_text_landscape_15s | 15秒 | 横屏 | 260 | 1973555977595301890 | - -#### 图生视频(6个) - -| 模型名称 | 时长 | 分辨率 | 积分 | webappId | -|---------|------|--------|------|----------| -| rh_sora2_img_portrait | 10秒 | 竖屏 | 180 | 1973555366057390081 | -| rh_sora2_img_landscape | 10秒 | 横屏 | 180 | 1973555366057390081 | -| rh_sora2_img_portrait_hd | 10秒 | 高清竖屏 | 480 | 1973555366057390081 | -| rh_sora2_img_landscape_hd | 10秒 | 高清横屏 | 480 | 1973555366057390081 | -| rh_sora2_img_portrait_15s | 15秒 | 竖屏 | 280 | 1973555366057390081 | -| rh_sora2_img_landscape_15s | 15秒 | 横屏 | 280 | 1973555366057390081 | - -### 3. 关键参数配置 - -```yaml -# application.yml -ai: - providers: - runninghub: - enabled: true - base-url: https://www.runninghub.cn - api-key: "5c44cef12da3470e9f24da70c63787dc" - polling-interval: 10000 # ✅ 10秒轮询(已优化) - max-polling-times: 60 # ✅ 最大10分钟 -``` - ---- - -## 🚀 技术亮点 - -### 1. 智能任务路由 - -```java -// 系统根据模型配置自动选择Provider -String providerType = pointsConfig.getProviderType(); -if ("runninghub".equals(providerType)) { - submitToRunningHub(task, pointsConfig); // 异步提交 -} else { - queueService.enqueue(task); // 队列处理 -} -``` - -### 2. 图片参数支持 - -**支持完整URL(无需预先上传)** -```json -{ - "modelName": "rh_sora2_img_landscape", - "prompt": "让场景动起来", - "imageUrl": "https://example.com/my-image.jpg" // ✅ 完整URL -} -``` - -**发送到RunningHub的请求:** -```json -{ - "nodeInfoList": [ - { - "nodeId": "2", - "fieldName": "image", - "fieldValue": "https://example.com/my-image.jpg" // ✅ 直接使用完整URL - } - ] -} -``` - -### 3. 防堆积轮询 - -```java -// ✅ 使用fixedDelay而非fixedRate -@Scheduled(fixedDelayString = "${ai.providers.runninghub.polling-interval:10000}") -public void pollRunningHubTasks() { - // 上一次执行完成后,等待10秒再执行下一次 - // 防止高并发时任务堆积 -} -``` - -### 4. 自动任务类型识别 - -```java -// 根据providerConfig自动识别文生视频/图生视频 -String taskType = (String) providerConfig.get("taskType"); -if ("image2video".equals(taskType)) { - // 构建图生视频nodeInfoList(包含image节点) -} else { - // 构建文生视频nodeInfoList(只有prompt节点) -} -``` - ---- - -## 📊 性能指标 - -### 1. 并发能力 - -| 并发任务数 | 轮询负载 | CPU使用率 | 状态 | -|-----------|---------|----------|-----| -| 0-100 | 轻 | <10% | ✅ 推荐 | -| 100-200 | 中 | 10-20% | ⚠️ 可用 | -| 200-500 | 高 | 20-50% | ⚠️ 需优化 | -| 500+ | 极高 | >50% | ❌ 需架构升级 | - -### 2. 轮询优化效果 - -| 指标 | 5秒轮询 | 10秒轮询 | 改善 | -|-----|---------|---------|-----| -| API调用量 | 1200次/分钟 | 600次/分钟 | ↓50% | -| 网络流量 | 2.4MB/分钟 | 1.2MB/分钟 | ↓50% | -| CPU使用率 | 20% | 10% | ↓50% | -| 平均延迟 | 2.5秒 | 5秒 | ↑2.5秒 | - -**结论:** 成本降低50%,延迟仅增加2.5秒,完美平衡 ✅ - ---- - -## 🧪 测试示例 - -### 文生视频测试 - -```bash -curl -X POST "http://localhost:8081/user/ai/tasks/submit" \ - -H "Authorization: Bearer YOUR_JWT_TOKEN" \ - -H "Content-Type: application/json" \ - -d '{ - "modelName": "rh_sora2_text_portrait", - "prompt": "一个人在海边奔跑,镜头从远到近" - }' -``` - -### 图生视频测试(完整URL) - -```bash -curl -X POST "http://localhost:8081/user/ai/tasks/submit" \ - -H "Authorization: Bearer YOUR_JWT_TOKEN" \ - -H "Content-Type: application/json" \ - -d '{ - "modelName": "rh_sora2_img_landscape", - "prompt": "让这个场景动起来", - "imageUrl": "https://example.com/city-skyline.jpg" - }' -``` - ---- - -## 📋 部署步骤 - -### 1. 数据库迁移 - -```bash -# 备份数据库 -mysqldump -u root -p 1818ai > backup_$(date +%Y%m%d).sql - -# 执行迁移 -mysql -u root -p 1818ai < V5__add_provider_support.sql - -# 验证 -mysql -u root -p 1818ai -e "SELECT COUNT(*) FROM points_config WHERE provider_type='runninghub';" -# 预期结果:12 -``` - -### 2. 编译部署 - -```bash -# 编译 -mvn clean package -DskipTests - -# 部署 -sudo systemctl stop spring_1818_user_server -sudo cp target/1818_user_server-1.0-SNAPSHOT.jar /www/wwwroot/1818_user_server/ -sudo systemctl start spring_1818_user_server - -# 查看日志 -sudo journalctl -u spring_1818_user_server -f | grep "Provider" -``` - -### 3. 验证 - -```bash -# 检查Provider注册 -sudo journalctl -u spring_1818_user_server | grep "注册AI Provider" -# 预期输出: -# 注册AI Provider: openai, 异步: false -# 注册AI Provider: runninghub, 异步: true - -# 检查轮询调度器 -sudo journalctl -u spring_1818_user_server | grep "RunningHub轮询" -``` - ---- - -## 📚 文档导航 - -| 文档 | 用途 | 读者 | -|-----|------|-----| -| `MULTI_VENDOR_ADAPTER_DESIGN.md` | 架构设计 | 开发人员 | -| `RUNNINGHUB_USAGE_GUIDE.md` | 使用指南 | 开发/测试人员 | -| `RUNNINGHUB_CONCURRENCY_ANALYSIS.md` | 并发分析 | 运维人员 | -| `POLLING_INTERVAL_OPTIMIZATION.md` | 轮询优化 | 技术负责人 | -| `DEPLOYMENT_CHECKLIST.md` | 部署清单 | 运维人员 | - ---- - -## ⚠️ 重要提醒 - -### 1. 图片要求 - -- ❌ **不支持真人图像**作为图生视频的输入 -- ✅ 建议使用:风景、物体、场景类图片 -- ✅ 支持完整URL,无需预先上传到RunningHub - -### 2. 并发控制 - -- 当前配置支持**100个并发任务** -- 如果超过200个并发,请参考 `RUNNINGHUB_CONCURRENCY_ANALYSIS.md` 升级配置 -- 监控 `ai_task` 表中 `status='processing'` 的数量 - -### 3. 成本控制 - -- 普通视频:1.6-2.6元/个 -- 高清视频:4.2-4.8元/个 -- 建议设置用户每日任务数量限制 - ---- - -## 🔧 配置优化建议 - -### 低并发(<50任务) - -```yaml -polling-interval: 5000 # 追求实时性 -max-polling-times: 120 -``` - -### 中等并发(50-200任务)✅ **当前配置** - -```yaml -polling-interval: 10000 # 平衡性能与体验 -max-polling-times: 60 -``` - -### 高并发(200+任务) - -```yaml -polling-interval: 15000 # 优先稳定性 -max-polling-times: 40 -# 并建议实施分批轮询优化 -``` - ---- - -## 📞 技术支持 - -### 常见问题排查 - -1. **Provider未注册?** - - 检查日志:`sudo journalctl -u spring_1818_user_server | grep "Provider"` - - 确认类路径正确:`com.dora.service.provider.impl.*` - -2. **任务卡在processing?** - - 查看轮询日志:`grep "RunningHub轮询"` - - 手动查询RunningHub状态API - - 检查网络连接 - -3. **图生视频失败?** - - 确认图片URL可访问 - - 确认图片不包含真人 - - 查看 `provider_response` 字段的错误信息 - ---- - -## ✅ 最终检查清单 - -部署前请确认: - -- [x] 数据库迁移脚本已执行(12个模型已插入) -- [x] application.yml配置正确(10秒轮询) -- [x] 所有26个文件已提交到代码仓库 -- [x] OpenAI模型仍能正常工作(兼容性测试) -- [x] RunningHub Provider已注册 -- [x] 轮询调度器正常启动 -- [x] WebSocket通知正常工作 -- [x] 失败任务能自动退还积分 - ---- - -## 🎉 总结 - -**RunningHub Sora2 集成 v2.1.1 完成!** - -### 核心成果 - -1. ✅ **12个RunningHub模型**已配置(文生视频 + 图生视频) -2. ✅ **多厂商架构**实现(OpenAI + RunningHub无缝切换) -3. ✅ **异步轮询机制**优化(10秒间隔,防堆积) -4. ✅ **完整URL支持**(图生视频无需预先上传) -5. ✅ **完整文档**(5篇共1600+行) - -### 性能优化 - -- API调用量减少 **50%** -- 服务器负载降低 **50%** -- 支持 **100个并发任务** -- 用户延迟仅增加 **2.5秒** - -### 下一步 - -1. 部署到测试环境 -2. 执行压力测试 -3. 监控1周,收集数据 -4. 根据实际情况调优 - ---- - -**系统已就绪,可立即部署!** 🚀 - -如有问题,请参考对应文档或联系技术团队。 - diff --git a/RUNNINGHUB_IMPLEMENTATION_TODO.md b/RUNNINGHUB_IMPLEMENTATION_TODO.md deleted file mode 100644 index 2ed3f79..0000000 --- a/RUNNINGHUB_IMPLEMENTATION_TODO.md +++ /dev/null @@ -1,295 +0,0 @@ -# RunningHub集成实现清单 - -## ✅ 已完成 - -1. ✅ 创建Provider接口和DTO -2. ✅ 数据库表扩展(V5迁移脚本) -3. ✅ 配置文件扩展 -4. ✅ 实体类更新 - -## 🔨 待实现(按优先级) - -### 1. 实现OpenAIProvider适配器 -**文件:** `src/main/java/com/dora/service/provider/impl/OpenAIProviderImpl.java` - -```java -@Service -@Slf4j -@RequiredArgsConstructor -public class OpenAIProviderImpl implements AIProvider { - - private final ThirdPartyApiService thirdPartyApiService; - - @Override - public ProviderTaskResponse submitTask(ProviderTaskRequest request) { - // 调用现有的 thirdPartyApiService - // 同步返回结果 - } - - @Override - public String getProviderName() { - return "openai"; - } - - @Override - public boolean isAsyncProvider() { - return false; // OpenAI是同步API - } -} -``` - -### 2. 实现RunningHubProvider适配器 -**文件:** `src/main/java/com/dora/service/provider/impl/RunningHubProviderImpl.java` - -**关键逻辑:** -```java -@Override -public ProviderTaskResponse submitTask(ProviderTaskRequest request) { - // 1. 从providerConfig中获取webappId - // 2. 构建nodeInfoList - // - prompt节点 - // - model节点(portrait/landscape等) - // - duration_seconds节点 - // 3. POST到 /task/openapi/ai-app/run - // 4. 解析响应获取taskId - // 5. 返回ProviderTaskResponse,status=PROCESSING -} - -@Override -public ProviderTaskStatus queryTaskStatus(String providerTaskId) { - // POST到 /task/openapi/status - // 解析响应:QUEUED/RUNNING/FAILED/SUCCESS -} - -@Override -public ProviderTaskResult getTaskResult(String providerTaskId) { - // POST到 /task/openapi/outputs - // 解析data数组,获取fileUrl -} -``` - -**RunningHub请求DTO:** -```java -@Data -class RunningHubSubmitRequest { - private String webappId; - private String apiKey; - private List nodeInfoList; -} - -@Data -class RunningHubNodeInfo { - private String nodeId; - private String fieldName; - private String fieldValue; - private String fieldData; // 可选 - private String description; -} -``` - -### 3. 创建AIProviderService路由服务 -**文件:** `src/main/java/com/dora/service/AIProviderService.java` - -```java -@Service -@Slf4j -@RequiredArgsConstructor -public class AIProviderService { - - private final Map providerMap; - private final PointsConfigMapper pointsConfigMapper; - - @PostConstruct - public void init() { - // 初始化providerMap,key为providerType - } - - public AIProvider getProvider(String modelName) { - // 1. 从points_config表查询模型配置 - // 2. 获取providerType - // 3. 从providerMap中获取对应的Provider - PointsConfig config = pointsConfigMapper.findByModelName(modelName); - String providerType = config.getProviderType(); - return providerMap.get(providerType); - } -} -``` - -### 4. 添加RunningHub轮询定时器 -**文件:** `src/main/java/com/dora/scheduler/RunningHubPollingScheduler.java` - -```java -@Component -@Slf4j -@RequiredArgsConstructor -public class RunningHubPollingScheduler { - - private final AiTaskMapper aiTaskMapper; - private final AIProviderService providerService; - private final AiTaskService aiTaskService; - - @Scheduled(fixedDelay = 5000) // 每5秒执行一次 - public void pollRunningHubTasks() { - // 1. 查询 status='processing' 且 provider_type='runninghub' 的任务 - List tasks = aiTaskMapper.findProcessingTasksByProvider("runninghub"); - - for (AiTask task : tasks) { - try { - AIProvider provider = providerService.getProvider(task.getModelName()); - - // 2. 查询任务状态 - ProviderTaskStatus status = provider.queryTaskStatus(task.getProviderTaskId()); - - // 3. 根据状态更新 - if (status.getStatus() == Status.SUCCESS) { - // 获取结果 - ProviderTaskResult result = provider.getTaskResult(task.getProviderTaskId()); - // 更新任务为completed - aiTaskService.markTaskCompleted(task.getTaskNo(), result.getFiles().get(0).getFileUrl()); - } else if (status.getStatus() == Status.FAILED) { - // 标记为失败 - aiTaskService.markTaskFailed(task.getTaskNo(), status.getErrorMessage()); - } - } catch (Exception e) { - log.error("轮询RunningHub任务失败: {}", task.getTaskNo(), e); - } - } - } -} -``` - -### 5. 更新AiTaskMapper -**文件:** `src/main/resources/mapper/AiTaskMapper.xml` - -```xml - - - SELECT * FROM ai_task - WHERE status = 'processing' - AND provider_type = #{providerType} - AND is_deleted = 0 - ORDER BY update_time ASC - LIMIT 100 - - - - - INSERT INTO ai_task ( - task_no, user_id, model_name, task_type, provider_type, provider_task_id, provider_response, - prompt, image_url, image_base64, aspect_ratio, - status, progress, progress_message, points_frozen, points_consumed, result_url, - error_message, queue_time, start_time, complete_time, expire_time - ) - VALUES ( - #{taskNo}, #{userId}, #{modelName}, #{taskType}, #{providerType}, #{providerTaskId}, #{providerResponse}, - #{prompt}, #{imageUrl}, #{imageBase64}, #{aspectRatio}, - #{status}, #{progress}, #{progressMessage}, #{pointsFrozen}, #{pointsConsumed}, #{resultUrl}, - #{errorMessage}, #{queueTime}, #{startTime}, #{completeTime}, #{expireTime} - ) - -``` - -### 6. 更新AiTaskServiceImpl -**文件:** `src/main/java/com/dora/service/impl/AiTaskServiceImpl.java` - -```java -@Override -@Transactional(rollbackFor = Exception.class) -public AiTask createTask(CreateTaskDto createTaskDto) { - // 1. 验证模型并获取价格 - PointsConfig pointsConfig = pointsConfigMapper.findByModelName(createTaskDto.getModelName()); - - // 2. 扣除积分 - // ... - - // 3. 创建任务 - AiTask task = new AiTask(); - // ... 设置基本字段 - task.setProviderType(pointsConfig.getProviderType()); // 设置provider类型 - aiTaskMapper.insert(task); - - // 4. 判断provider类型 - if ("runninghub".equals(pointsConfig.getProviderType())) { - // RunningHub:直接提交到服务商 - submitToRunningHub(task, pointsConfig); - } else { - // OpenAI:加入队列,由原有流程处理 - queueService.enqueue(task.getModelName(), task.getTaskNo()); - updateTaskStatus(task.getTaskNo(), "queued", "任务已进入等待队列"); - } - - return task; -} - -private void submitToRunningHub(AiTask task, PointsConfig config) { - try { - AIProvider provider = aiProviderService.getProvider(task.getModelName()); - - // 构建请求 - ProviderTaskRequest request = ProviderTaskRequest.builder() - .modelName(task.getModelName()) - .prompt(task.getPrompt()) - .imageUrl(task.getImageUrl()) - .imageBase64(task.getImageBase64()) - .providerConfig(parseProviderConfig(config.getProviderConfig())) - .build(); - - // 提交任务 - ProviderTaskResponse response = provider.submitTask(request); - - // 更新任务 - task.setProviderTaskId(response.getProviderTaskId()); - task.setProviderResponse(JSON.toJSONString(response.getRawResponse())); - task.setStatus("processing"); - task.setStartTime(LocalDateTime.now()); - aiTaskMapper.update(task); - - } catch (Exception e) { - log.error("提交RunningHub任务失败: {}", task.getTaskNo(), e); - markTaskFailed(task.getTaskNo(), "提交失败: " + e.getMessage()); - } -} -``` - -## 🧪 测试步骤 - -### 1. 数据库迁移 -```bash -mysql -u root -p your_database < V5__add_provider_support.sql -``` - -### 2. 配置RunningHub API Key -修改`application.yml`中的`ai.providers.runninghub.api-key` - -### 3. 测试RunningHub模型 -```bash -curl -X POST "http://localhost:8081/user/ai/tasks/submit" \ - -H "Authorization: Bearer YOUR_JWT_OR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "modelName": "rh_sora2_portrait", - "prompt": "测试视频生成" - }' -``` - -### 4. 查看轮询日志 -```bash -tail -f logs/application.log | grep "RunningHub" -``` - -## 📝 注意事项 - -1. **配置管理**:RunningHub的webappId需要从数据库的provider_config中读取 -2. **错误处理**:RunningHub API可能返回各种错误,需要完善异常处理 -3. **超时控制**:设置最大轮询次数,防止任务无限轮询 -4. **并发限制**:轮询时要控制并发数,避免给RunningHub造成压力 -5. **日志记录**:详细记录每次API调用的请求和响应,便于排查问题 - -## 🎯 预期效果 - -完成后,系统将支持: -- ✅ OpenAI格式的同步API(原有功能,无影响) -- ✅ RunningHub的异步API(新功能) -- ✅ 用户无感切换,根据模型自动选择服务商 -- ✅ 统一的任务管理和状态追踪 - diff --git a/RUNNINGHUB_INTEGRATION_COMPLETE.md b/RUNNINGHUB_INTEGRATION_COMPLETE.md deleted file mode 100644 index e586e69..0000000 --- a/RUNNINGHUB_INTEGRATION_COMPLETE.md +++ /dev/null @@ -1,391 +0,0 @@ -# RunningHub集成完成报告 - -**完成时间:** 2025-10-20 -**版本号:** v2.1.0 - ---- - -## ✅ 实现完成清单 - -### 1. 核心接口和DTO ✅ - -| 文件 | 说明 | 状态 | -|------|------|------| -| `AIProvider.java` | 统一服务商接口 | ✅ 完成 | -| `ProviderTaskRequest.java` | 统一请求DTO | ✅ 完成 | -| `ProviderTaskResponse.java` | 统一响应DTO | ✅ 完成 | -| `ProviderTaskStatus.java` | 任务状态DTO | ✅ 完成 | -| `ProviderTaskResult.java` | 任务结果DTO | ✅ 完成 | - -### 2. RunningHub专用DTO ✅ - -| 文件 | 说明 | 状态 | -|------|------|------| -| `RunningHubSubmitRequest.java` | 提交请求 | ✅ 完成 | -| `RunningHubNodeInfo.java` | 节点信息 | ✅ 完成 | -| `RunningHubSubmitResponse.java` | 提交响应 | ✅ 完成 | -| `RunningHubStatusResponse.java` | 状态查询响应 | ✅ 完成 | -| `RunningHubOutputResponse.java` | 结果查询响应 | ✅ 完成 | - -### 3. Provider实现 ✅ - -| 文件 | 说明 | 状态 | -|------|------|------| -| `OpenAIProviderImpl.java` | OpenAI适配器(同步) | ✅ 完成 | -| `RunningHubProviderImpl.java` | RunningHub适配器(异步) | ✅ 完成 | - -### 4. 核心服务 ✅ - -| 文件 | 说明 | 状态 | -|------|------|------| -| `AIProviderService.java` | Provider路由服务 | ✅ 完成 | -| `RunningHubPollingScheduler.java` | 轮询调度器 | ✅ 完成 | -| `AiTaskServiceImpl.java` | 任务服务(已集成) | ✅ 完成 | - -### 5. 数据库和配置 ✅ - -| 文件 | 说明 | 状态 | -|------|------|------| -| `V5__add_provider_support.sql` | 数据库迁移脚本 | ✅ 完成 | -| `application.yml` | 多厂商配置 | ✅ 完成 | -| `AiTask.java` | 实体类更新 | ✅ 完成 | -| `PointsConfig.java` | 实体类更新 | ✅ 完成 | -| `AiTaskMapper.xml` | SQL映射更新 | ✅ 完成 | - ---- - -## 🎯 系统架构 - -``` -┌─────────────────────────────────────────────────────────────┐ -│ 用户提交任务 │ -│ (JWT or API Key认证) │ -└────────────────────────┬────────────────────────────────────┘ - ↓ -┌─────────────────────────────────────────────────────────────┐ -│ AiTaskController │ -└────────────────────────┬────────────────────────────────────┘ - ↓ -┌─────────────────────────────────────────────────────────────┐ -│ AiTaskServiceImpl │ -│ 1. 扣积分 │ -│ 2. 创建任务 │ -│ 3. 读取 points_config.provider_type │ -│ 4. 路由到不同流程 │ -└────────┬──────────────────────────────┬─────────────────────┘ - │ │ - ▼ ▼ -┌──────────────────┐ ┌──────────────────┐ -│ OpenAI流程 │ │ RunningHub流程 │ -│ (同步) │ │ (异步) │ -└──────┬───────────┘ └─────────┬─────────┘ - │ │ - ↓ ↓ -┌──────────────────┐ ┌──────────────────┐ -│1. 加入队列 │ │1. 直接提交 │ -│2. TaskScheduler │ │2. 返回taskId │ -│ 定时调度 │ │3. 更新DB │ -│3. AsyncExecutor │ │ │ -│ 同步执行 │ │ │ -│4. 立即返回结果 │ │ │ -└──────────────────┘ └─────────┬─────────┘ - │ - ↓ - ┌──────────────────┐ - │RunningHub │ - │PollingScheduler │ - │ │ - │每5秒轮询: │ - │1. 查询状态 │ - │2. SUCCESS→获取 │ - │3. FAILED→退款 │ - │4. 更新DB+通知 │ - └──────────────────┘ -``` - ---- - -## 📋 工作流程对比 - -### OpenAI流程(同步) - -1. 用户提交任务 -2. 系统扣除积分,创建任务 -3. 任务加入队列(status='queued') -4. `TaskScheduler` 调度任务 -5. `AsyncTaskExecutor` 调用OpenAI API -6. 立即返回结果URL -7. 更新status='completed' -8. 发送WebSocket通知 - -**耗时:** ~10-30秒 - -### RunningHub流程(异步) - -1. 用户提交任务 -2. 系统扣除积分,创建任务 -3. 直接调用RunningHub API -4. 获得taskId,更新status='processing' -5. `RunningHubPollingScheduler` 每5秒轮询 -6. 检测到SUCCESS状态 -7. 调用outputs接口获取结果URL -8. 更新status='completed' -9. 发送WebSocket通知 - -**耗时:** ~2-5分钟 - ---- - -## 🔧 配置说明 - -### application.yml - -```yaml -ai: - providers: - openai: - enabled: true - base-url: https://api.apiyi.com/v1/chat/completions - api-key: "sk-xxx" - runninghub: - enabled: true - base-url: https://www.runninghub.cn - submit-url: /task/openapi/ai-app/run - status-url: /task/openapi/status - output-url: /task/openapi/outputs - default-webapp-id: "1973555977595301890" - api-key: "your_runninghub_api_key" - polling-interval: 5000 - max-polling-times: 120 -``` - -### points_config表配置 - -```sql --- RunningHub模型示例 -INSERT INTO `points_config` VALUES -(8, 'rh_sora2_portrait', 160, 'RunningHub Sora2 竖屏视频(10秒)', 1, 'runninghub', - '{"webappId":"1973555977595301890","duration":10,"model":"portrait"}', NOW(), NOW()); -``` - -**providerConfig字段说明:** -- `webappId`: RunningHub应用ID -- `duration`: 视频时长(秒) -- `model`: 模型类型(portrait/landscape/portrait-hd/landscape-hd) - ---- - -## 🚀 部署步骤 - -### 1. 数据库迁移 - -```bash -mysql -u root -p 1818ai < V5__add_provider_support.sql -``` - -### 2. 更新配置 - -编辑 `application.yml`,填入RunningHub API Key: - -```yaml -ai: - providers: - runninghub: - api-key: "YOUR_RUNNINGHUB_API_KEY" -``` - -### 3. 编译部署 - -```bash -# 编译 -mvn clean package -DskipTests - -# 停止服务 -sudo systemctl stop spring_1818_user_server - -# 备份旧版本 -sudo cp /www/wwwroot/1818_user_server/1818_user_server-1.0-SNAPSHOT.jar \ - /www/wwwroot/1818_user_server/1818_user_server-1.0-SNAPSHOT.jar.bak - -# 部署新版本 -sudo cp target/1818_user_server-1.0-SNAPSHOT.jar \ - /www/wwwroot/1818_user_server/ - -# 启动服务 -sudo systemctl start spring_1818_user_server - -# 查看日志 -sudo journalctl -u spring_1818_user_server -f -``` - ---- - -## 🧪 测试指南 - -### 1. 测试OpenAI模型(验证兼容性) - -```bash -curl -X POST "http://localhost:8081/user/ai/tasks/submit" \ - -H "Authorization: Bearer YOUR_JWT_TOKEN" \ - -H "Content-Type: application/json" \ - -d '{ - "modelName": "sora_image", - "prompt": "一只可爱的猫咪" - }' -``` - -**预期结果:** -- 任务立即执行 -- 30秒内返回completed状态 -- resultUrl包含图片地址 - -### 2. 测试RunningHub模型 - -```bash -curl -X POST "http://localhost:8081/user/ai/tasks/submit" \ - -H "Authorization: Bearer YOUR_JWT_TOKEN" \ - -H "Content-Type: application/json" \ - -d '{ - "modelName": "rh_sora2_portrait", - "prompt": "一个人在海边奔跑,镜头从远到近" - }' -``` - -**预期结果:** -- 任务提交成功,status='processing' -- 返回taskNo和providerTaskId -- 2-5分钟后status变为'completed' -- resultUrl包含视频地址 - -### 3. 查看轮询日志 - -```bash -tail -f logs/application.log | grep "RunningHub" -``` - -**正常日志示例:** -``` -2025-10-20 15:30:05 INFO - 提交任务到RunningHub: TASK20251020153005ABC -2025-10-20 15:30:06 INFO - RunningHub任务提交成功: TASK20251020153005ABC, providerTaskId: 1980149306768457730 -2025-10-20 15:30:11 DEBUG - RunningHub轮询 - 发现1个待处理任务 -2025-10-20 15:30:11 DEBUG - 轮询任务: TASK20251020153005ABC, providerTaskId: 1980149306768457730 -2025-10-20 15:30:11 DEBUG - 任务 TASK20251020153005ABC 状态: RUNNING -... -2025-10-20 15:33:21 INFO - 任务成功 - taskNo: TASK20251020153005ABC -2025-10-20 15:33:22 INFO - 任务 TASK20251020153005ABC 处理完成,结果URL: https://rh-images.xiaoyaoyou.com/... -``` - ---- - -## 📊 数据库变更 - -### ai_task表新增字段 - -```sql -ALTER TABLE `ai_task` -ADD COLUMN `provider_type` VARCHAR(50) NULL, -ADD COLUMN `provider_task_id` VARCHAR(100) NULL, -ADD COLUMN `provider_response` TEXT NULL; -``` - -### points_config表新增字段 - -```sql -ALTER TABLE `points_config` -ADD COLUMN `provider_type` VARCHAR(50) NOT NULL DEFAULT 'openai', -ADD COLUMN `provider_config` TEXT NULL; -``` - ---- - -## ⚠️ 注意事项 - -### 1. 兼容性 - -- ✅ 现有OpenAI模型完全不受影响 -- ✅ 现有API接口保持不变 -- ✅ 现有数据可正常使用 - -### 2. 轮询性能 - -- 每5秒轮询一次RunningHub任务 -- 最多同时处理100个任务 -- 建议生产环境增加Redis缓存减少数据库压力 - -### 3. 错误处理 - -- RunningHub任务失败会自动退还积分 -- 超时任务会被标记为failed -- 所有异常都有详细日志记录 - -### 4. 监控建议 - -```bash -# 查看RunningHub任务数量 -SELECT COUNT(*) FROM ai_task -WHERE provider_type='runninghub' AND status='processing'; - -# 查看平均处理时间 -SELECT AVG(TIMESTAMPDIFF(SECOND, start_time, complete_time)) as avg_seconds -FROM ai_task -WHERE provider_type='runninghub' AND status='completed' -AND complete_time > DATE_SUB(NOW(), INTERVAL 1 DAY); -``` - ---- - -## 🎯 功能对比 - -| 特性 | OpenAI格式 | RunningHub | -|------|-----------|------------| -| **认证方式** | Bearer Token | API Key | -| **调用方式** | 同步 | 异步 | -| **返回方式** | 立即返回 | 轮询查询 | -| **处理时间** | 10-30秒 | 2-5分钟 | -| **支持类型** | 图片、视频 | 视频 | -| **横竖屏** | URL参数 | model字段 | -| **队列管理** | Redis队列 | RunningHub内部 | -| **进度追踪** | WebSocket | WebSocket | - ---- - -## 🔮 未来扩展 - -1. **更多服务商**:可以继续添加其他AI服务商(Midjourney、Stable Diffusion等) -2. **智能路由**:根据价格、速度、成功率自动选择最优服务商 -3. **负载均衡**:同一个模型配置多个服务商,实现负载分担 -4. **降级策略**:主服务商故障时自动切换到备用服务商 -5. **成本优化**:根据用户等级选择不同价格的服务商 - ---- - -## 📞 技术支持 - -如遇问题,请检查: - -1. **数据库迁移是否成功** - ```sql - DESC ai_task; -- 检查是否有provider_type字段 - ``` - -2. **配置是否正确** - ```bash - grep "runninghub" src/main/resources/application.yml - ``` - -3. **服务是否启动** - ```bash - ps aux | grep spring_1818_user_server - ``` - -4. **日志是否有报错** - ```bash - tail -100 logs/application.log - ``` - ---- - -**集成完成!** 🎉 - -系统现已支持OpenAI和RunningHub双服务商,用户可以无感切换使用不同的AI生成服务! - diff --git a/RUNNINGHUB_QUEUE_OPTIMIZATION.md b/RUNNINGHUB_QUEUE_OPTIMIZATION.md deleted file mode 100644 index a2a9183..0000000 --- a/RUNNINGHUB_QUEUE_OPTIMIZATION.md +++ /dev/null @@ -1,575 +0,0 @@ -# RunningHub 队列优化方案 - -**版本:** v2.2.0 -**更新时间:** 2025-10-20 -**优化类型:** 并发控制 + 队列管理 - ---- - -## 🎯 优化目标 - -解决RunningHub任务轮询时的并发控制问题: -- ✅ **限制并发轮询数**:最多同时轮询100个任务 -- ✅ **队列化管理**:超出限制的任务进入等待队列 -- ✅ **自动调度**:任务完成后自动提交等待队列中的新任务 -- ✅ **防止过载**:避免系统资源耗尽和RunningHub API限流 - ---- - -## 📊 问题分析 - -### 原有架构的问题 - -**无限制提交:** -```java -// 旧代码:直接提交所有RunningHub任务 -if ("runninghub".equals(providerType)) { - submitToRunningHub(task, pointsConfig); // 没有并发控制 -} -``` - -**潜在风险:** -1. **系统资源耗尽** - - 500个并发任务 × 10秒轮询 → CPU使用率50%+ - - 数据库连接池耗尽 - - 内存占用过高 - -2. **RunningHub API限流** - - 每秒查询数过高可能被限流 - - 账户被封禁的风险 - -3. **用户体验差** - - 高并发时轮询延迟增加 - - 任务状态更新不及时 - ---- - -## ✨ 新架构设计 - -### 1. 队列管理服务 - -``` -┌─────────────────────────────────────────────────────────────┐ -│ RunningHubQueueService │ -├─────────────────────────────────────────────────────────────┤ -│ │ -│ ┌──────────────────┐ ┌───────────────────┐ │ -│ │ Polling Tasks │ │ Waiting Queue │ │ -│ │ (Map) │ │ │ │ -│ │ │ │ │ │ -│ │ 最多100个任务 │◄────────┤ 无限长度队列 │ │ -│ └──────────────────┘ └───────────────────┘ │ -│ ▲ │ │ │ -│ │ │ │ │ -│ │ └──────────┐ ┌──────────┘ │ -│ │ │ │ │ -│ 完成时释放 任务完成 │ 新任务提交 │ -│ │ │ │ │ -└─────────┼─────────────┼────┼─────────────────────────────────┘ - │ ▼ ▼ - ┌────┴────┐ ┌─────────────┐ - │ 轮询调度 │ │ 队列处理器 │ - │Scheduler│ │ Processor │ - └─────────┘ └─────────────┘ -``` - -### 2. 核心组件 - -#### A. `RunningHubQueueService` (队列管理服务) - -**职责:** -- 管理正在轮询的任务集合(最多100个) -- 管理等待提交的任务队列(无限长度) -- 提供入队/出队操作 -- 处理任务完成回调 - -**关键方法:** -```java -public interface RunningHubQueueService { - // 将任务加入队列或立即提交 - boolean enqueueOrSubmit(AiTask task); - - // 获取当前轮询任务数 - int getPollingTaskCount(); - - // 获取等待队列长度 - int getWaitingQueueSize(); - - // 处理等待队列(从队列中提交新任务) - int processWaitingQueue(); - - // 任务完成回调 - void onTaskCompleted(String taskNo); -} -``` - -#### B. `RunningHubQueueProcessor` (队列处理器) - -**职责:** -- 每5秒检查一次等待队列 -- 当有空位时自动提交新任务 -- 记录队列状态日志 - -**调度策略:** -```java -@Scheduled(fixedDelay = 5000) // 每5秒执行一次 -public void processWaitingQueue() { - if (有空位 && 队列不为空) { - 提交等待中的任务(); - } -} -``` - -#### C. `AdminRunningHubQueueController` (管理接口) - -**职责:** -- 提供队列状态查询接口 -- 提供手动处理队列接口 -- 仅管理员可访问 - -**接口:** -- `GET /admin/runninghub/queue/status` - 查看队列状态 -- `GET /admin/runninghub/queue/process` - 手动处理队列 - ---- - -## 🔧 实现细节 - -### 1. 配置参数 - -```yaml -# application.yml -ai: - providers: - runninghub: - max-polling-tasks: 100 # 最大并发轮询任务数 - queue-check-interval: 5000 # 队列检查间隔(毫秒) -``` - -### 2. 任务提交流程 - -``` -用户提交任务 - ↓ -创建任务记录 - ↓ -扣除积分 - ↓ -判断provider类型 - ↓ -if (runninghub) - ↓ -检查轮询任务数 - ├── < 100个? - │ ├── 是 → 立即提交到RunningHub - │ │ ↓ - │ │ 加入pollingTasks集合 - │ │ ↓ - │ │ 返回"processing"状态 - │ │ - │ └── 否 → 加入waitingQueue - │ ↓ - │ 返回"queued"状态 - │ ↓ - │ 等待队列处理器调度 - └── -``` - -### 3. 任务完成流程 - -``` -轮询检测到任务完成 - ↓ -更新任务状态 - ↓ -发送WebSocket通知 - ↓ -调用 onTaskCompleted(taskNo) - ↓ -从 pollingTasks 中移除 - ↓ -调用 processWaitingQueue() - ↓ -if (waitingQueue不为空) - ↓ -取出队列头部任务 - ↓ -提交到RunningHub - ↓ -加入 pollingTasks - ↓ -循环直到队列空或轮询满 -``` - -### 4. 并发安全 - -所有关键方法使用 `synchronized` 保证线程安全: - -```java -public synchronized boolean enqueueOrSubmit(AiTask task) { - // 原子操作:检查 + 提交/入队 -} - -public synchronized int processWaitingQueue() { - // 原子操作:出队 + 提交 -} - -public synchronized void onTaskCompleted(String taskNo) { - // 原子操作:移除 + 处理队列 -} -``` - -**数据结构选择:** -- `ConcurrentHashMap` - 存储正在轮询的任务 -- `LinkedBlockingQueue` - 存储等待队列(FIFO) - ---- - -## 📈 性能对比 - -### 无队列控制(旧) - -| 并发任务数 | 轮询频率 | CPU使用率 | 内存占用 | 风险等级 | -|-----------|---------|----------|---------|---------| -| 100 | 10秒/次 | 10% | 1.5GB | ✅ 安全 | -| 200 | 10秒/次 | 20% | 2.5GB | ⚠️ 注意 | -| 500 | 10秒/次 | 50% | 5GB | ❌ 危险 | -| 1000 | 10秒/次 | 80%+ | 10GB+ | ❌ 崩溃 | - -### 有队列控制(新) - -| 并发任务数 | 轮询任务数 | 等待队列 | CPU使用率 | 内存占用 | 风险等级 | -|-----------|-----------|---------|----------|---------|---------| -| 100 | 100 | 0 | 10% | 1.5GB | ✅ 安全 | -| 200 | 100 | 100 | 10% | 1.6GB | ✅ 安全 | -| 500 | 100 | 400 | 10% | 2GB | ✅ 安全 | -| 1000 | 100 | 900 | 10% | 3GB | ✅ 安全 | - -**关键优势:** -- ✅ **CPU使用率稳定**在10%,不随并发增加而增长 -- ✅ **内存占用可控**,轮询任务固定100个 -- ✅ **无崩溃风险**,队列可以无限增长 -- ✅ **自动调度**,任务完成后立即提交新任务 - ---- - -## 🧪 测试验证 - -### 测试场景1:正常负载(100并发) - -```bash -# 提交100个任务 -for i in {1..100}; do - curl -X POST "http://localhost:8081/user/ai/tasks/submit" \ - -H "Authorization: Bearer $TOKEN" \ - -H "Content-Type: application/json" \ - -d "{\"modelName\":\"rh_sora2_text_portrait\",\"prompt\":\"测试任务$i\"}" -done - -# 查看队列状态 -curl "http://localhost:8081/admin/runninghub/queue/status" \ - -H "Authorization: Bearer $ADMIN_TOKEN" -``` - -**预期结果:** -```json -{ - "maxPollingTasks": 100, - "currentPollingTasks": 100, - "waitingQueueSize": 0, - "availableSlots": 0, - "utilizationRate": "100.0%" -} -``` - -### 测试场景2:超载(200并发) - -```bash -# 提交200个任务 -for i in {1..200}; do - curl -X POST "http://localhost:8081/user/ai/tasks/submit" \ - -H "Authorization: Bearer $TOKEN" \ - -H "Content-Type: application/json" \ - -d "{\"modelName\":\"rh_sora2_text_portrait\",\"prompt\":\"测试任务$i\"}" -done - -# 查看队列状态 -curl "http://localhost:8081/admin/runninghub/queue/status" \ - -H "Authorization: Bearer $ADMIN_TOKEN" -``` - -**预期结果:** -```json -{ - "maxPollingTasks": 100, - "currentPollingTasks": 100, - "waitingQueueSize": 100, - "availableSlots": 0, - "utilizationRate": "100.0%" -} -``` - -### 测试场景3:任务完成后自动调度 - -```bash -# 等待一些任务完成(3-5分钟) - -# 再次查看队列状态 -curl "http://localhost:8081/admin/runninghub/queue/status" \ - -H "Authorization: Bearer $ADMIN_TOKEN" -``` - -**预期结果:** -```json -{ - "maxPollingTasks": 100, - "currentPollingTasks": 100, // 仍然满载 - "waitingQueueSize": 50, // 队列减少了50个(已自动提交) - "availableSlots": 0, - "utilizationRate": "100.0%" -} -``` - ---- - -## 📊 监控指标 - -### 1. 队列状态监控 - -```sql --- 查看RunningHub任务分布 -SELECT - status, - COUNT(*) as count -FROM ai_task -WHERE provider_type = 'runninghub' - AND create_time > DATE_SUB(NOW(), INTERVAL 1 HOUR) -GROUP BY status; - --- 预期结果: --- queued: 等待队列中的任务 --- processing: 正在轮询的任务(应≤100) --- completed: 已完成的任务 --- failed: 失败的任务 -``` - -### 2. 系统负载监控 - -```bash -# 查看CPU使用率 -top -p $(pgrep -f spring_1818_user_server) - -# 查看内存占用 -ps aux | grep spring_1818_user_server | awk '{print $6/1024 " MB"}' - -# 查看网络流量 -iftop -i eth0 -f "port 8081" -``` - -### 3. 日志监控 - -```bash -# 查看队列处理日志 -sudo journalctl -u spring_1818_user_server | grep "RunningHub队列" - -# 预期日志: -# RunningHub队列状态 - 正在轮询: 100/100, 等待队列: 50 -# RunningHub队列处理器启动 - 正在轮询: 95/100, 等待队列: 50 -# 从等待队列提交任务 TASK_001 到RunningHub,当前轮询: 96/100, 剩余队列: 49 -``` - ---- - -## ⚙️ 配置调优 - -### 不同场景的推荐配置 - -#### 场景1:低并发(<50任务) - -```yaml -ai: - providers: - runninghub: - max-polling-tasks: 50 # 降低上限,节省资源 - queue-check-interval: 10000 # 降低检查频率 - polling-interval: 10000 -``` - -**特点:** -- 资源占用最小 -- 适合初期部署 - ---- - -#### 场景2:中等并发(50-200任务)✅ **推荐** - -```yaml -ai: - providers: - runninghub: - max-polling-tasks: 100 # 默认100个 - queue-check-interval: 5000 # 5秒检查一次 - polling-interval: 10000 -``` - -**特点:** -- 性能与成本平衡 -- 适合大多数场景 - ---- - -#### 场景3:高并发(200-500任务) - -```yaml -ai: - providers: - runninghub: - max-polling-tasks: 200 # 提高上限 - queue-check-interval: 3000 # 加快检查频率 - polling-interval: 15000 # 降低轮询频率 -``` - -**注意事项:** -- 需要增加数据库连接池 -- 需要监控RunningHub API响应 -- 可能需要独立部署轮询服务 - ---- - -## 🔧 故障排查 - -### 问题1:队列一直堆积,不减少 - -**可能原因:** -1. RunningHub API故障 -2. 队列处理器未启动 -3. 任务完成后未调用 `onTaskCompleted` - -**排查步骤:** -```bash -# 1. 检查队列处理器日志 -sudo journalctl -u spring_1818_user_server | grep "RunningHubQueueProcessor" - -# 2. 检查是否有任务完成 -mysql -u root -p 1818ai -e "SELECT COUNT(*) FROM ai_task WHERE status='completed' AND provider_type='runninghub' AND complete_time > DATE_SUB(NOW(), INTERVAL 10 MINUTE);" - -# 3. 手动触发队列处理 -curl "http://localhost:8081/admin/runninghub/queue/process" \ - -H "Authorization: Bearer $ADMIN_TOKEN" -``` - ---- - -### 问题2:任务卡在queued状态很久 - -**可能原因:** -1. 轮询任务数已满(100个) -2. 前面有很多任务在排队 - -**排查步骤:** -```bash -# 查看队列状态 -curl "http://localhost:8081/admin/runninghub/queue/status" \ - -H "Authorization: Bearer $ADMIN_TOKEN" - -# 查看该任务在队列中的位置(从数据库查询) -mysql -u root -p 1818ai -e "SELECT task_no, status, queue_time FROM ai_task WHERE status='queued' AND provider_type='runninghub' ORDER BY queue_time;" -``` - ---- - -### 问题3:队列处理器不工作 - -**可能原因:** -1. `@EnableScheduling` 未启用 -2. 调度器配置错误 - -**解决方案:** -```java -// 检查 Application.java -@SpringBootApplication -@EnableScheduling // 确保启用调度 -@EnableAsync -public class Application { - // ... -} -``` - ---- - -## ✅ 部署清单 - -### 1. 配置文件更新 - -- [x] `application.yml` - 添加 `max-polling-tasks` 和 `queue-check-interval` - -### 2. 新增文件(3个) - -- [x] `RunningHubQueueService.java` - 队列管理服务接口 -- [x] `RunningHubQueueServiceImpl.java` - 队列管理服务实现 -- [x] `RunningHubQueueProcessor.java` - 队列处理调度器 -- [x] `AdminRunningHubQueueController.java` - 管理员监控接口 - -### 3. 修改文件(3个) - -- [x] `AiTaskServiceImpl.java` - 使用队列服务 -- [x] `RunningHubPollingScheduler.java` - 任务完成时通知队列服务 - -### 4. 验证步骤 - -```bash -# 1. 编译 -mvn clean compile -DskipTests - -# 2. 启动服务 -sudo systemctl restart spring_1818_user_server - -# 3. 检查日志 -sudo journalctl -u spring_1818_user_server -f | grep -E "(队列|Queue)" - -# 4. 测试队列状态接口 -curl "http://localhost:8081/admin/runninghub/queue/status" \ - -H "Authorization: Bearer $ADMIN_TOKEN" - -# 5. 提交测试任务 -curl -X POST "http://localhost:8081/user/ai/tasks/submit" \ - -H "Authorization: Bearer $USER_TOKEN" \ - -H "Content-Type: application/json" \ - -d '{"modelName":"rh_sora2_text_portrait","prompt":"测试"}' -``` - ---- - -## 📝 总结 - -### 优化成果 - -1. ✅ **并发控制**:轮询任务数限制在100个 -2. ✅ **队列管理**:超出部分自动进入等待队列 -3. ✅ **自动调度**:任务完成后立即提交新任务 -4. ✅ **监控接口**:管理员可实时查看队列状态 -5. ✅ **性能稳定**:CPU、内存占用可控 - -### 关键指标 - -| 指标 | 优化前 | 优化后 | 改善 | -|-----|-------|-------|-----| -| 最大轮询任务数 | 无限制 | 100 | ✅ 可控 | -| 500并发时CPU | 50% | 10% | ↓80% | -| 500并发时内存 | 5GB | 2GB | ↓60% | -| 系统崩溃风险 | 高 | 无 | ✅ 消除 | - -### 下一步优化方向 - -1. **Redis队列**:当并发超过1000时,使用Redis替代内存队列 -2. **优先级队列**:VIP用户任务优先处理 -3. **动态限流**:根据RunningHub API响应时间动态调整并发数 -4. **分布式部署**:多个轮询服务实例共享队列 - ---- - -**RunningHub队列优化完成!** 🎉 - -系统现在可以安全处理任意数量的并发任务,不会因为过载而崩溃! - diff --git a/RUNNINGHUB_USAGE_GUIDE.md b/RUNNINGHUB_USAGE_GUIDE.md deleted file mode 100644 index dfab818..0000000 --- a/RUNNINGHUB_USAGE_GUIDE.md +++ /dev/null @@ -1,435 +0,0 @@ -# RunningHub Sora2 使用指南 - -**版本:** v2.1.0 -**更新时间:** 2025-10-20 - ---- - -## 📋 模型列表 - -系统已预配置以下RunningHub Sora2模型(共12个): - -### 文生视频模型(webappId: 1973555977595301890) - -| 模型名称 | 说明 | 时长 | 分辨率 | 积分消耗 | -|---------|------|------|--------|---------| -| `rh_sora2_text_portrait` | 竖屏视频 | 10秒 | 704x1280 | 160 | -| `rh_sora2_text_landscape` | 横屏视频 | 10秒 | 1280x704 | 160 | -| `rh_sora2_text_portrait_hd` | 高清竖屏 | 10秒 | 1024x1792 | 420 | -| `rh_sora2_text_landscape_hd` | 高清横屏 | 10秒 | 1792x1024 | 420 | -| `rh_sora2_text_portrait_15s` | 竖屏视频(长) | 15秒 | 704x1280 | 260 | -| `rh_sora2_text_landscape_15s` | 横屏视频(长) | 15秒 | 1280x704 | 260 | - -### 图生视频模型(webappId: 1973555366057390081) - -| 模型名称 | 说明 | 时长 | 分辨率 | 积分消耗 | -|---------|------|------|--------|---------| -| `rh_sora2_img_portrait` | 竖屏视频 | 10秒 | 704x1280 | 180 | -| `rh_sora2_img_landscape` | 横屏视频 | 10秒 | 1280x704 | 180 | -| `rh_sora2_img_portrait_hd` | 高清竖屏 | 10秒 | 1024x1792 | 480 | -| `rh_sora2_img_landscape_hd` | 高清横屏 | 10秒 | 1792x1024 | 480 | -| `rh_sora2_img_portrait_15s` | 竖屏视频(长) | 15秒 | 704x1280 | 280 | -| `rh_sora2_img_landscape_15s` | 横屏视频(长) | 15秒 | 1280x704 | 280 | - ---- - -## 🚀 使用示例 - -### 1. 文生视频(Text to Video) - -只需要提供 `prompt`,系统会自动选择横竖屏和时长。 - -```bash -curl -X POST "http://localhost:8081/user/ai/tasks/submit" \ - -H "Authorization: Bearer YOUR_JWT_OR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "modelName": "rh_sora2_text_portrait", - "prompt": "第一镜(0–3秒)静谧晨光\n窗外的城市尚在沉睡,镜头推向一只放在床头的 Apple Watch。屏幕亮起的瞬间,柔和的光映照出主人的脸庞,他睁开眼,呼吸与心率同步闪烁。\n第二镜(3–7秒)节奏苏醒\n主角在晨跑,步伐稳健。手表屏幕显示心率曲线与路线图,汗水顺着手臂滑落。阳光从高楼间洒下,镜头追随腕间的微光与动作的力量。\n第三镜(7–10秒)自我回归\n跑步结束,他停在桥上深吸一口气,城市的天际线在他背后延伸。镜头慢慢拉远,Apple Watch的屏幕定格在闪烁的数字上,文字浮现:掌控每一秒的呼吸。" - }' -``` - -**实际发送到RunningHub的请求:** -```json -{ - "webappId": "1973555977595301890", - "apiKey": "5c44cef12da3470e9f24da70c63787dc", - "nodeInfoList": [ - { - "nodeId": "1", - "fieldName": "prompt", - "fieldValue": "第一镜(0–3秒)静谧晨光...", - "description": "输入文本" - }, - { - "nodeId": "1", - "fieldName": "model", - "fieldValue": "portrait", - "fieldData": "[{\"name\":\"portrait\",...}]", - "description": "横竖模式" - }, - { - "nodeId": "1", - "fieldName": "duration_seconds", - "fieldValue": "10", - "fieldData": "[[10, 15], {\"default\": 10}]", - "description": "时长(秒)" - } - ] -} -``` - ---- - -### 2. 图生视频(Image to Video) - -需要提供 `imageUrl` 或 `imageBase64`,以及可选的 `prompt`。 - -#### 方式1:使用图片URL(推荐) - -```bash -curl -X POST "http://localhost:8081/user/ai/tasks/submit" \ - -H "Authorization: Bearer YOUR_JWT_OR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "modelName": "rh_sora2_img_landscape", - "prompt": "镜头一(0s–3s)从空中俯拍,镜头缓缓向下俯冲穿越云层,紫蓝色霓虹反射在摩天大楼玻璃幕墙上...", - "imageUrl": "https://example.com/my-reference-image.jpg" - }' -``` - -#### 方式2:使用图片Base64 - -```bash -curl -X POST "http://localhost:8081/user/ai/tasks/submit" \ - -H "Authorization: Bearer YOUR_JWT_OR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "modelName": "rh_sora2_img_portrait_hd", - "prompt": "让这个场景动起来,添加生动的细节", - "imageBase64": "data:image/jpeg;base64,/9j/4AAQSkZJRg..." - }' -``` - -**实际发送到RunningHub的请求:** -```json -{ - "webappId": "1973555366057390081", - "apiKey": "5c44cef12da3470e9f24da70c63787dc", - "nodeInfoList": [ - { - "nodeId": "2", - "fieldName": "image", - "fieldValue": "https://example.com/my-reference-image.jpg", - "description": "上传图像(不支持真人做图像的输入)" - }, - { - "nodeId": "1", - "fieldName": "prompt", - "fieldValue": "镜头一(0s–3s)从空中俯拍...", - "description": "输入文本" - }, - { - "nodeId": "1", - "fieldName": "model", - "fieldValue": "landscape", - "fieldData": "[{\"name\":\"portrait\",...}]", - "description": "横竖模式" - }, - { - "nodeId": "1", - "fieldName": "duration_seconds", - "fieldValue": "10", - "fieldData": "[[10, 15], {\"default\": 10}]", - "description": "时长(秒)" - } - ] -} -``` - ---- - -## 🔧 关键实现细节 - -### 1. 自动任务类型识别 - -系统根据 `providerConfig.taskType` 自动识别任务类型: - -```java -// points_config表中的配置示例 -{ - "webappId": "1973555366057390081", - "taskType": "image2video", // 或 "text2video" - "model": "landscape", - "duration": 10 -} -``` - -### 2. 图片参数处理 - -- **优先级**:`imageUrl` > `imageBase64` -- **支持格式**: - - 完整URL:`https://example.com/image.jpg` - - RunningHub文件名:`825b8cb2f5603b068704ef435df77d570f081be814a40f652f080b8d4bc6ba03.png` - - Base64编码:`data:image/jpeg;base64,/9j/4AAQSkZJRg...` - -```java -// RunningHubProviderImpl中的逻辑 -if (isImage2Video) { - String imageValue = request.getImageUrl(); - if (imageValue == null || imageValue.trim().isEmpty()) { - imageValue = request.getImageBase64(); - } - - // 添加到nodeInfoList - nodeInfoList.add(RunningHubNodeInfo.builder() - .nodeId("2") - .fieldName("image") - .fieldValue(imageValue) // 支持完整URL - .description("上传图像(不支持真人做图像的输入)") - .build()); -} -``` - -### 3. 节点顺序 - -系统按照RunningHub要求的顺序构建节点: - -**文生视频:** -1. prompt节点(nodeId="1") -2. model节点(nodeId="1") -3. duration_seconds节点(nodeId="1") - -**图生视频:** -1. image节点(nodeId="2") -2. prompt节点(nodeId="1",可选) -3. model节点(nodeId="1") -4. duration_seconds节点(nodeId="1") - ---- - -## 📊 任务流程 - -### 文生视频流程 - -``` -用户提交 - ↓ -提取prompt - ↓ -读取points_config配置 -taskType="text2video" -webappId="1973555977595301890" - ↓ -构建nodeInfoList: -- prompt节点 -- model节点 -- duration节点 - ↓ -调用RunningHub API - ↓ -获得taskId -status='processing' - ↓ -5秒轮询一次 - ↓ -检测到SUCCESS - ↓ -获取视频URL -status='completed' -``` - -### 图生视频流程 - -``` -用户提交 - ↓ -提取prompt + imageUrl - ↓ -读取points_config配置 -taskType="image2video" -webappId="1973555366057390081" - ↓ -构建nodeInfoList: -- image节点(完整URL) -- prompt节点 -- model节点 -- duration节点 - ↓ -调用RunningHub API - ↓ -获得taskId -status='processing' - ↓ -5秒轮询一次 - ↓ -检测到SUCCESS - ↓ -获取视频URL -status='completed' -``` - ---- - -## ⚠️ 注意事项 - -### 1. 图片要求 - -- **图生视频模型不支持真人图像作为输入** -- 建议使用风景、物体、场景类图片 -- 支持完整的HTTP/HTTPS URL,无需预先上传到RunningHub - -### 2. Prompt建议 - -- **文生视频**:详细描述镜头、场景、动作、时间节点 -- **图生视频**:描述如何让图片"动起来",添加什么动态效果 - -### 3. 处理时间 - -- 文生视频:约2-5分钟 -- 图生视频:约2-5分钟(取决于服务器负载) - -### 4. 积分消耗 - -- 任务提交时立即扣除积分(冻结) -- 任务成功:确认消耗积分 -- 任务失败:自动退还积分 - ---- - -## 🧪 测试步骤 - -### 测试1:文生视频(竖屏10秒) - -```bash -# 1. 提交任务 -TASK_RESPONSE=$(curl -X POST "http://localhost:8081/user/ai/tasks/submit" \ - -H "Authorization: Bearer YOUR_TOKEN" \ - -H "Content-Type: application/json" \ - -d '{ - "modelName": "rh_sora2_text_portrait", - "prompt": "一个人在海边奔跑,镜头从远到近" - }') - -echo $TASK_RESPONSE - -# 2. 提取taskNo -TASK_NO=$(echo $TASK_RESPONSE | jq -r '.data.taskNo') - -# 3. 等待2-5分钟后查询 -curl "http://localhost:8081/user/ai/tasks/$TASK_NO" \ - -H "Authorization: Bearer YOUR_TOKEN" -``` - -### 测试2:图生视频(横屏高清) - -```bash -# 1. 提交任务 -curl -X POST "http://localhost:8081/user/ai/tasks/submit" \ - -H "Authorization: Bearer YOUR_TOKEN" \ - -H "Content-Type: application/json" \ - -d '{ - "modelName": "rh_sora2_img_landscape_hd", - "prompt": "镜头缓缓向下俯冲穿越云层,紫蓝色霓虹反射在摩天大楼玻璃幕墙上", - "imageUrl": "https://example.com/city-skyline.jpg" - }' - -# 2. 查看日志确认图片URL正确传递 -tail -f logs/application.log | grep "RunningHub Provider" -``` - ---- - -## 📝 数据库配置 - -所有模型配置已通过 `V5__add_provider_support.sql` 自动创建: - -```sql --- 查看所有RunningHub模型 -SELECT model_name, description, points_cost, provider_config -FROM points_config -WHERE provider_type = 'runninghub' -ORDER BY points_cost; - --- 查看某个模型的配置 -SELECT provider_config -FROM points_config -WHERE model_name = 'rh_sora2_img_landscape'; - --- 结果示例: -{ - "webappId": "1973555366057390081", - "taskType": "image2video", - "model": "landscape", - "duration": 10 -} -``` - ---- - -## 🔍 故障排查 - -### 问题1:图生视频任务失败 - -**错误信息:** "图生视频任务必须提供imageUrl或imageBase64" - -**解决方案:** -- 确认请求中包含 `imageUrl` 或 `imageBase64` 字段 -- 检查图片URL是否可访问 -- 确认使用的是图生视频模型(包含 `_img_` 的模型名) - -### 问题2:任务一直处于processing状态 - -**可能原因:** -- RunningHub服务器负载高 -- 网络连接问题 -- 任务确实在处理中 - -**解决方案:** -```bash -# 1. 查看轮询日志 -tail -f logs/application.log | grep "RunningHub轮询" - -# 2. 检查数据库中的provider_task_id -SELECT task_no, provider_task_id, status, update_time -FROM ai_task -WHERE task_no = 'YOUR_TASK_NO'; - -# 3. 手动查询RunningHub状态(仅用于调试) -curl -X POST "https://www.runninghub.cn/task/openapi/status" \ - -H "Content-Type: application/json" \ - -d '{ - "apiKey": "YOUR_API_KEY", - "taskId": "PROVIDER_TASK_ID" - }' -``` - ---- - -## 📊 性能监控 - -```sql --- 查看RunningHub任务统计 -SELECT - status, - COUNT(*) as count, - AVG(TIMESTAMPDIFF(SECOND, start_time, complete_time)) as avg_seconds -FROM ai_task -WHERE provider_type = 'runninghub' - AND create_time > DATE_SUB(NOW(), INTERVAL 1 DAY) -GROUP BY status; - --- 查看最近的失败任务 -SELECT task_no, model_name, error_message, create_time -FROM ai_task -WHERE provider_type = 'runninghub' - AND status = 'failed' -ORDER BY create_time DESC -LIMIT 10; -``` - ---- - -**RunningHub Sora2集成完成!** 🎉 - -系统现已支持文生视频和图生视频两种模式,共12个预配置模型可供使用! diff --git a/SMS_VERIFICATION_GUIDE.md b/SMS_VERIFICATION_GUIDE.md deleted file mode 100644 index aa4aa87..0000000 --- a/SMS_VERIFICATION_GUIDE.md +++ /dev/null @@ -1,902 +0,0 @@ -# 短信验证系统使用指南 - -**版本:** v1.0.0 -**更新时间:** 2025-11-03 -**系统名称:** 1818AI 用户服务短信验证模块 - ---- - -## 📋 目录 - -- [系统概述](#系统概述) -- [配置说明](#配置说明) -- [API接口文档](#api接口文档) -- [业务场景](#业务场景) -- [安全机制](#安全机制) -- [错误处理](#错误处理) -- [使用示例](#使用示例) -- [常见问题](#常见问题) -- [维护指南](#维护指南) - ---- - -## 📖 系统概述 - -### 功能说明 - -短信验证系统基于**阿里云短信服务**实现,提供验证码的发送和校验功能。主要用于用户注册、登录、密码重置等关键业务场景。 - -### 技术架构 - -``` -┌─────────────────────────────────────────────────┐ -│ 前端应用 │ -└──────────────────┬──────────────────────────────┘ - │ HTTP/HTTPS - ▼ -┌─────────────────────────────────────────────────┐ -│ Spring Boot 应用 │ -│ ┌──────────────┐ ┌──────────────┐ │ -│ │MsmController │─────▶│ MsmService │ │ -│ └──────────────┘ └──────┬───────┘ │ -│ │ │ │ -│ ▼ ▼ │ -│ ┌──────────────┐ ┌──────────────┐ │ -│ │Redis缓存 │ │阿里云SMS API │ │ -│ │(验证码存储) │ │(短信发送) │ │ -│ └──────────────┘ └──────────────┘ │ -└─────────────────────────────────────────────────┘ -``` - -### 核心特性 - -- ✅ **6位数字验证码** - 简单易输入 -- ✅ **5分钟有效期** - 自动过期保护 -- ✅ **一次性使用** - 验证后立即失效 -- ✅ **防重复发送** - 验证码存在时拒绝重发 -- ✅ **强制发送模式** - 支持覆盖已存在的验证码 -- ✅ **完整日志记录** - 便于追踪和调试 - ---- - -## ⚙️ 配置说明 - -### 配置文件位置 - -``` -src/main/resources/application.yml -``` - -### 配置内容 - -```yaml -# --- 短信配置 --- -ly: - sms: - accessKeyId: LTAI5t68do3qVXx5Rufugt3X # 阿里云AccessKey ID - accessKeySecret: 2vD9ToIff49Vph4JQXsn0Cy8nXQfzA # 阿里云AccessKey Secret - signName: 星洋智慧 # 短信签名 - verifyTemplateCode: SMS_491985030 # 验证码短信模板编号 -``` - -### 配置项说明 - -| 配置项 | 类型 | 必填 | 说明 | -|--------|------|------|------| -| `accessKeyId` | String | 是 | 阿里云访问密钥ID,从阿里云控制台获取 | -| `accessKeySecret` | String | 是 | 阿里云访问密钥Secret,从阿里云控制台获取 | -| `signName` | String | 是 | 短信签名,需在阿里云短信服务中申请 | -| `verifyTemplateCode` | String | 是 | 短信模板编号,需在阿里云短信服务中申请 | - -### 阿里云短信服务配置步骤 - -#### 1. 开通短信服务 - -1. 登录 [阿里云控制台](https://www.aliyun.com/) -2. 开通"短信服务"产品 -3. 完成实名认证 - -#### 2. 创建短信签名 - -1. 进入"短信服务控制台" → "国内消息" → "签名管理" -2. 点击"添加签名" -3. 填写签名信息: - - **签名名称**:星洋智慧(或您的公司/产品名) - - **签名来源**:企事业单位的全称或简称 - - **适用场景**:验证码 -4. 提交审核(通常1-2个工作日) - -#### 3. 创建短信模板 - -1. 进入"模板管理" → "添加模板" -2. 填写模板信息: - - **模板类型**:验证码 - - **模板名称**:验证码通知 - - **模板内容**:`您的验证码为:${code},5分钟内有效,请勿泄露给他人。` -3. 提交审核(通常1-2个工作日) -4. 审核通过后获得**模板CODE**(如:SMS_491985030) - -#### 4. 获取AccessKey - -1. 进入"AccessKey管理" -2. 创建AccessKey(如果没有) -3. 记录 `AccessKey ID` 和 `AccessKey Secret` - -⚠️ **安全提示**: -- AccessKey Secret 请妥善保管,不要泄露 -- 建议使用子账号AccessKey,并授予最小权限 -- 定期轮换AccessKey - ---- - -## 🔌 API接口文档 - -### 1. 发送短信验证码 - -#### 接口信息 - -``` -GET /user/msm/send/{phone} -``` - -#### 请求参数 - -**路径参数**: - -| 参数名 | 类型 | 必填 | 说明 | 示例 | -|--------|------|------|------|------| -| phone | String | 是 | 手机号(11位) | 13800138000 | - -**Query参数**: - -| 参数名 | 类型 | 必填 | 默认值 | 说明 | -|--------|------|------|--------|------| -| force | Boolean | 否 | false | 是否强制发送新验证码 | - -#### 响应示例 - -**成功响应**: - -```json -{ - "code": 200, - "message": "success", - "data": true -} -``` - -**失败响应**: - -```json -{ - "code": 400, - "message": "验证码已存在,请稍后再试", - "data": null -} -``` - -```json -{ - "code": 500, - "message": "短信发送失败,请稍后重试", - "data": null -} -``` - -#### 业务逻辑 - -``` -1. 检查Redis中是否已有验证码 - ├─ 有验证码 且 force=false → 返回错误(400) - └─ 无验证码 或 force=true → 继续 - ↓ -2. 生成6位随机数字验证码(100000-999999) - ↓ -3. 调用阿里云短信API发送验证码 - ↓ -4. 发送成功 - ├─ 是 → 存入Redis(5分钟过期)→ 返回成功(200) - └─ 否 → 返回错误(500) -``` - -#### 使用示例 - -**普通发送**: - -```bash -curl -X GET "http://localhost:8081/user/msm/send/13800138000" -``` - -**强制发送**(覆盖已存在的验证码): - -```bash -curl -X GET "http://localhost:8081/user/msm/send/13800138000?force=true" -``` - -#### 注意事项 - -- ⏱️ 验证码5分钟内有效 -- 🔒 同一手机号在验证码未过期前不能重复发送(除非force=true) -- 💰 每次发送会产生短信费用 -- 📝 所有操作都会记录详细日志 - ---- - -## 💼 业务场景 - -### 1. 短信登录 - -**接口**:`POST /user/auth/sms-login` - -**流程**: - -``` -用户输入手机号 - ↓ -调用发送验证码接口 - ↓ -用户收到短信 - ↓ -用户输入验证码 - ↓ -调用登录接口(验证码校验) - ↓ -校验成功 → 生成JWT Token → 返回登录成功 -``` - -**请求示例**: - -```json -{ - "phone": "13800138000", - "code": "123456" -} -``` - -**响应示例**: - -```json -{ - "code": 200, - "message": "success", - "data": { - "token": "eyJhbGciOiJIUzI1NiJ9...", - "tokenExpiresAt": "2025-11-10T12:00:00", - "userInfo": { - "userId": 123456, - "phone": "13800138000", - "username": "用户昵称" - } - } -} -``` - -### 2. 用户注册 - -**接口**:`POST /user/auth/register` - -**流程**: - -``` -用户输入手机号和密码 - ↓ -调用发送验证码接口 - ↓ -用户输入验证码 - ↓ -调用注册接口(验证码校验) - ↓ -校验成功 → 创建用户 → 自动登录 → 返回Token -``` - -**请求示例**: - -```json -{ - "phone": "13800138000", - "code": "123456", - "password": "Abc123456", - "inviteCode": "ABC123" // 可选 -} -``` - -### 3. 重置密码 - -**接口**:`POST /user/auth/reset-password` - -**流程**: - -``` -用户输入手机号 - ↓ -调用发送验证码接口 - ↓ -用户输入验证码和新密码 - ↓ -调用重置密码接口(验证码校验) - ↓ -校验成功 → 更新密码 → 返回成功 -``` - -**请求示例**: - -```json -{ - "phone": "13800138000", - "code": "123456", - "newPassword": "NewPass123" -} -``` - -### 4. 修改手机号 - -**接口**:`PUT /user/users/info` - -**流程**: - -``` -用户输入新手机号 - ↓ -向新手机号发送验证码 - ↓ -用户输入验证码 - ↓ -调用修改接口(验证码校验) - ↓ -校验成功 → 更新手机号 → 返回成功 -``` - -### 5. 修改密码(需要验证码) - -**接口**:`PUT /user/users/info` - -**流程**: - -``` -用户输入当前手机号 - ↓ -发送验证码 - ↓ -用户输入验证码和新密码 - ↓ -调用修改接口(验证码校验) - ↓ -校验成功 → 更新密码 → 返回成功 -``` - ---- - -## 🔒 安全机制 - -### 1. 验证码有效期控制 - -```java -// 存储到Redis,5分钟后自动过期 -redisTemplate.opsForValue().set(phone, code, 5, TimeUnit.MINUTES); -``` - -**说明**: -- 验证码在Redis中存储5分钟 -- 5分钟后自动删除,无法继续使用 -- 防止验证码长期有效带来的安全风险 - -### 2. 一次性使用机制 - -```java -// 验证成功后立即删除 -redisTemplate.delete(phone); -``` - -**说明**: -- 验证码验证成功后立即从Redis删除 -- 每个验证码只能使用一次 -- 防止验证码被重复使用 - -### 3. 错误清除机制 - -```java -// 验证失败时清除验证码 -if (!cachedCode.equals(code)) { - redisTemplate.delete(phone); - throw new RuntimeException("验证码错误或已过期"); -} -``` - -**说明**: -- 验证码输入错误时立即清除 -- 防止暴力破解攻击 -- 用户需重新获取验证码 - -### 4. 业务失败清除 - -```java -// 业务逻辑失败时也清除验证码 -if (existingUser != null) { - redisTemplate.delete(phone); - throw new RuntimeException("手机号已注册"); -} -``` - -**说明**: -- 即使验证码正确,但业务逻辑失败时也清除验证码 -- 例如:注册时手机号已存在、登录时用户不存在等 -- 确保一个验证码只用于一次完整的业务操作 - -### 5. 重复发送限制 - -```java -// 检查是否已有验证码 -String existingCode = redisTemplate.opsForValue().get(phone); -if (existingCode != null && !force) { - return Result.error(400, "验证码已存在,请稍后再试"); -} -``` - -**说明**: -- 验证码存在时拒绝重复发送 -- 防止短信轰炸和资源浪费 -- 特殊情况可使用`force=true`强制发送 - -### 安全建议 - -#### ⚠️ 当前缺少的安全措施 - -1. **频率限制** - ``` - 建议:同一手机号1分钟内最多发送1次 - 建议:同一IP每小时最多发送10次 - 建议:单个手机号每天最多发送5次 - ``` - -2. **图形验证码** - ``` - 建议:发送短信前先验证图形验证码 - 防止:自动化机器人攻击 - ``` - -3. **手机号归属地验证** - ``` - 建议:检查手机号归属地是否为国内 - 防止:国际短信费用损失 - ``` - -4. **黑名单机制** - ``` - 建议:维护恶意手机号黑名单 - 防止:滥用和攻击 - ``` - ---- - -## ❌ 错误处理 - -### 错误码说明 - -| 错误码 | 错误信息 | 原因 | 解决方法 | -|--------|---------|------|----------| -| 400 | 验证码已存在,请稍后再试 | Redis中已有未过期的验证码 | 等待5分钟或使用force=true | -| 400 | 验证码错误或已过期 | 验证码不存在或不匹配 | 重新获取验证码 | -| 500 | 短信发送失败,请稍后重试 | 阿里云短信服务调用失败 | 检查配置和网络,查看日志 | -| 500 | 发送短信验证码失败 | 系统异常 | 查看服务器日志 | - -### 阿里云短信服务错误码 - -| 阿里云错误码 | 说明 | 处理方法 | -|-------------|------|----------| -| OK | 发送成功 | - | -| isv.MOBILE_NUMBER_ILLEGAL | 手机号格式错误 | 检查手机号格式 | -| isv.BUSINESS_LIMIT_CONTROL | 业务限流 | 降低发送频率 | -| isv.AMOUNT_NOT_ENOUGH | 账户余额不足 | 充值阿里云短信服务 | -| isv.TEMPLATE_MISSING_PARAMETERS | 模板参数缺失 | 检查模板参数 | -| isv.INVALID_PARAMETERS | 参数无效 | 检查所有参数 | - -### 日志查询 - -```bash -# 查看短信发送日志 -sudo journalctl -u spring_1818_user_server | grep "短信" - -# 查看特定手机号的日志 -sudo journalctl -u spring_1818_user_server | grep "13800138000" - -# 查看错误日志 -sudo journalctl -u spring_1818_user_server | grep -E "ERROR|WARN" | grep "短信" -``` - ---- - -## 📘 使用示例 - -### 完整的登录流程示例 - -#### 步骤1:发送验证码 - -```bash -curl -X GET "http://localhost:8081/user/msm/send/13800138000" \ - -H "Accept: application/json" -``` - -**响应**: -```json -{ - "code": 200, - "message": "success", - "data": true -} -``` - -#### 步骤2:用户收到短信 - -``` -【星洋智慧】您的验证码为:123456,5分钟内有效,请勿泄露给他人。 -``` - -#### 步骤3:使用验证码登录 - -```bash -curl -X POST "http://localhost:8081/user/auth/sms-login" \ - -H "Content-Type: application/json" \ - -d '{ - "phone": "13800138000", - "code": "123456" - }' -``` - -**响应**: -```json -{ - "code": 200, - "message": "success", - "data": { - "token": "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTYiLCJwaG9uZSI6IjEzODAwMTM4MDAwIiwiaWF0IjoxNjk5MDA4MDAwLCJleHAiOjE2OTk2MTI4MDB9.xxx", - "tokenExpiresAt": "2025-11-10T12:00:00", - "userInfo": { - "userId": 123456, - "phone": "13800138000", - "username": "测试用户" - } - } -} -``` - -### 强制发送验证码示例 - -**场景**:用户点击"重新发送"时,即使验证码未过期也要发送新的 - -```bash -curl -X GET "http://localhost:8081/user/msm/send/13800138000?force=true" \ - -H "Accept: application/json" -``` - -### JavaScript/TypeScript 示例 - -```typescript -// 发送验证码 -async function sendSmsCode(phone: string, force: boolean = false): Promise { - try { - const response = await fetch( - `http://localhost:8081/user/msm/send/${phone}?force=${force}`, - { - method: 'GET', - headers: { - 'Accept': 'application/json' - } - } - ); - - const result = await response.json(); - - if (result.code === 200) { - console.log('验证码发送成功'); - return true; - } else { - console.error('验证码发送失败:', result.message); - return false; - } - } catch (error) { - console.error('网络错误:', error); - return false; - } -} - -// 短信登录 -async function smsLogin(phone: string, code: string): Promise { - const response = await fetch('http://localhost:8081/user/auth/sms-login', { - method: 'POST', - headers: { - 'Content-Type': 'application/json' - }, - body: JSON.stringify({ phone, code }) - }); - - const result = await response.json(); - - if (result.code === 200) { - // 保存token到localStorage - localStorage.setItem('token', result.data.token); - return result.data; - } else { - throw new Error(result.message); - } -} - -// 使用示例 -async function handleLogin() { - const phone = '13800138000'; - const code = '123456'; - - try { - const loginData = await smsLogin(phone, code); - console.log('登录成功:', loginData); - // 跳转到主页 - window.location.href = '/home'; - } catch (error) { - console.error('登录失败:', error.message); - alert(error.message); - } -} -``` - ---- - -## ❓ 常见问题 - -### Q1: 验证码收不到怎么办? - -**A**: 检查以下几点: -1. 手机号格式是否正确(11位数字) -2. 查看服务器日志,确认是否发送成功 -3. 检查阿里云短信服务余额是否充足 -4. 确认短信签名和模板是否已审核通过 -5. 检查手机是否有信号,是否被拦截为垃圾短信 - -### Q2: 提示"验证码已存在"怎么办? - -**A**: 两种解决方法: -1. 等待5分钟后重试(验证码自动过期) -2. 使用`force=true`参数强制发送新验证码 - -```bash -curl -X GET "http://localhost:8081/user/msm/send/13800138000?force=true" -``` - -### Q3: 验证码输入错误后无法重试? - -**A**: 这是安全机制设计,验证码输入错误后会立即失效。需要重新获取新的验证码。 - -### Q4: 如何查看短信发送记录? - -**A**: 查看服务器日志: - -```bash -# 查看所有短信相关日志 -sudo journalctl -u spring_1818_user_server | grep "短信" - -# 查看特定手机号的发送记录 -sudo journalctl -u spring_1818_user_server | grep "phone: 13800138000" -``` - -### Q5: 短信费用如何计算? - -**A**: -- 国内短信:约0.045元/条 -- 计费由阿里云短信服务收取 -- 可在阿里云控制台查看详细账单 - -### Q6: 如何修改验证码有效期? - -**A**: 修改代码中的过期时间: - -```java -// 当前是5分钟 -redisTemplate.opsForValue().set(phone, code, 5, TimeUnit.MINUTES); - -// 修改为3分钟 -redisTemplate.opsForValue().set(phone, code, 3, TimeUnit.MINUTES); -``` - -### Q7: 如何修改验证码位数? - -**A**: 修改生成验证码的代码: - -```java -// 当前是6位(100000-999999) -String code = String.valueOf((int) ((Math.random() * 9 + 1) * 100000)); - -// 修改为4位(1000-9999) -String code = String.valueOf((int) ((Math.random() * 9 + 1) * 1000)); -``` - -### Q8: 如何添加发送频率限制? - -**A**: 需要在代码中添加额外的Redis计数器: - -```java -// 伪代码示例 -String countKey = "sms:count:" + phone; -Integer count = redisTemplate.opsForValue().get(countKey); - -if (count != null && count >= 5) { - return Result.error(429, "发送次数过多,请明天再试"); -} - -// 发送成功后增加计数 -redisTemplate.opsForValue().increment(countKey); -// 设置24小时过期 -redisTemplate.expire(countKey, 24, TimeUnit.HOURS); -``` - ---- - -## 🛠️ 维护指南 - -### 监控指标 - -#### 1. 短信发送成功率 - -```sql --- 查看今日短信发送情况(需要添加短信发送记录表) -SELECT - DATE(create_time) as date, - COUNT(*) as total, - SUM(CASE WHEN status = 'success' THEN 1 ELSE 0 END) as success, - SUM(CASE WHEN status = 'failed' THEN 1 ELSE 0 END) as failed, - ROUND(SUM(CASE WHEN status = 'success' THEN 1 ELSE 0 END) * 100.0 / COUNT(*), 2) as success_rate -FROM sms_log -WHERE DATE(create_time) = CURDATE() -GROUP BY DATE(create_time); -``` - -#### 2. Redis验证码监控 - -```bash -# 连接Redis -redis-cli - -# 查看所有手机号的验证码(生产环境不建议执行) -KEYS * - -# 查看特定手机号的验证码 -GET 13800138000 - -# 查看验证码剩余过期时间(秒) -TTL 13800138000 -``` - -#### 3. 日志监控 - -```bash -# 统计今日短信发送次数 -sudo journalctl -u spring_1818_user_server --since today | grep "短信验证码发送成功" | wc -l - -# 统计今日短信发送失败次数 -sudo journalctl -u spring_1818_user_server --since today | grep "短信验证码发送失败" | wc -l - -# 查看最近的错误 -sudo journalctl -u spring_1818_user_server -n 100 | grep -E "ERROR.*短信" -``` - -### 定期检查项 - -#### 每日检查 - -- [ ] 查看短信发送成功率 -- [ ] 检查阿里云短信服务余额 -- [ ] 查看错误日志 - -#### 每周检查 - -- [ ] 分析短信发送量趋势 -- [ ] 检查异常手机号(发送失败率高的) -- [ ] 审查Redis使用情况 - -#### 每月检查 - -- [ ] 审查短信费用 -- [ ] 更新AccessKey(建议定期轮换) -- [ ] 检查短信签名和模板有效期 - -### 故障处理 - -#### 故障1:大量短信发送失败 - -**排查步骤**: -1. 检查阿里云短信服务是否正常 -2. 检查网络连接是否正常 -3. 检查AccessKey是否过期 -4. 检查账户余额是否充足 -5. 查看详细错误日志 - -#### 故障2:Redis连接失败 - -**排查步骤**: -1. 检查Redis服务是否运行 -2. 检查Redis连接配置 -3. 检查防火墙设置 -4. 重启Redis服务 - -#### 故障3:验证码无法验证 - -**排查步骤**: -1. 检查Redis中是否存在验证码 -2. 检查验证码是否已过期 -3. 检查代码逻辑是否正确 -4. 查看详细日志 - -### 性能优化建议 - -#### 1. Redis连接池优化 - -```yaml -spring: - redis: - lettuce: - pool: - max-active: 20 # 最大连接数 - max-idle: 10 # 最大空闲连接数 - min-idle: 5 # 最小空闲连接数 -``` - -#### 2. 短信发送异步化 - -```java -// 使用@Async异步发送短信 -@Async -public CompletableFuture sendAsync(Map param, String phone) { - boolean result = send(param, phone); - return CompletableFuture.completedFuture(result); -} -``` - -#### 3. 添加缓存预热 - -```java -// 应用启动时检查Redis连接 -@PostConstruct -public void init() { - try { - redisTemplate.opsForValue().set("health_check", "ok", 10, TimeUnit.SECONDS); - log.info("Redis连接正常"); - } catch (Exception e) { - log.error("Redis连接失败", e); - } -} -``` - ---- - -## 📝 更新日志 - -### v1.0.0 (2025-11-03) - -**初始版本**: -- ✅ 实现基础短信验证码发送功能 -- ✅ 集成阿里云短信服务 -- ✅ 实现Redis验证码存储 -- ✅ 实现5分钟过期机制 -- ✅ 实现一次性使用机制 -- ✅ 添加强制发送模式 -- ✅ 完善日志记录 - ---- - -## 📞 技术支持 - -**遇到问题?** - -1. 查看本文档的[常见问题](#常见问题)章节 -2. 查看服务器日志获取详细错误信息 -3. 检查阿里云短信服务控制台 -4. 联系技术团队 - -**相关文档**: -- [阿里云短信服务文档](https://help.aliyun.com/document_detail/101414.html) -- [Redis官方文档](https://redis.io/documentation) -- [Spring Boot Redis文档](https://docs.spring.io/spring-boot/docs/current/reference/html/data.html#data.nosql.redis) - ---- - -**文档版本**: v1.0.0 -**最后更新**: 2025-11-03 -**维护团队**: 1818AI技术团队 - diff --git a/SYSTEM_UPGRADE_SUMMARY_20251020.md b/SYSTEM_UPGRADE_SUMMARY_20251020.md deleted file mode 100644 index 1bd7e00..0000000 --- a/SYSTEM_UPGRADE_SUMMARY_20251020.md +++ /dev/null @@ -1,391 +0,0 @@ -# 系统升级总结 - API Key认证与图生视频功能 - -**升级日期:** 2025-10-20 -**版本号:** v2.0.0 - ---- - -## 📋 升级概述 - -本次升级实现了以下核心功能: - -1. ✅ **API Key认证系统** - 支持不通过JWT也能调用API -2. ✅ **积分独立使用** - 非会员用户可以单独充值积分使用AI服务 -3. ✅ **图生视频功能** - 支持上传参考图片生成视频 -4. ✅ **会员体系优化** - 会员和积分系统解耦,互不影响 - ---- - -## 🎯 核心改动 - -### 1. API Key认证过滤器 - -**文件:** `src/main/java/com/dora/config/ApiKeyAuthenticationFilter.java` - -**功能:** -- 新增Spring Security过滤器,支持API Key认证 -- 从HTTP Header `Authorization: Bearer {api_key}` 中提取API Key -- 与JWT认证共存,JWT优先级更高 -- 所有用户(会员/非会员)都可以通过API Key认证 - -**关键代码:** -```java -@Component -public class ApiKeyAuthenticationFilter extends OncePerRequestFilter { - // 检查JWT是否已认证 - if (SecurityContextHolder.getContext().getAuthentication() != null) { - filterChain.doFilter(request, response); - return; - } - - // 验证API Key - User user = apiKeyService.validateApiKeyForNonMember(apiKey); - if (user != null) { - UsernamePasswordAuthenticationToken authentication = - UsernamePasswordAuthenticationToken.authenticated(...); - SecurityContextHolder.getContext().setAuthentication(authentication); - } -} -``` - ---- - -### 2. API Key服务优化 - -**文件:** `src/main/java/com/dora/service/ApiKeyService.java` - -**改动:** -- ❌ **旧逻辑**:只有会员(role >= 2)才能生成API Key -- ✅ **新逻辑**:所有用户都可以生成API Key,通过积分使用服务 - -**新增方法:** -```java -public User validateApiKeyForNonMember(String keyValue) { - // 不再检查会员身份,所有用户都可以使用API Key - // 只要有积分就可以调用服务 -} -``` - -**影响的方法:** -- `generateApiKey()` - 移除会员检查 -- `refreshApiKey()` - 移除会员检查 -- `validateApiKeyForNonMember()` - 新增方法 - ---- - -### 3. 图生视频功能 - -#### 3.1 数据库扩展 - -**文件:** `V4__add_image_fields_to_ai_task.sql` - -```sql -ALTER TABLE `ai_task` -ADD COLUMN `image_url` VARCHAR(500) NULL COMMENT '参考图片URL(用于图生视频)', -ADD COLUMN `image_base64` TEXT NULL COMMENT '参考图片Base64编码(用于图生视频)', -ADD COLUMN `aspect_ratio` VARCHAR(10) NULL COMMENT '图片宽高比(如2:3, 3:2, 1:1)'; -``` - -#### 3.2 DTO扩展 - -**文件:** `src/main/java/com/dora/dto/TaskSubmitRequest.java` - -```java -@Data -public class TaskSubmitRequest { - private String modelName; - private String prompt; - private String imageUrl; // 新增:图片URL - private String imageBase64; // 新增:图片Base64 - private String aspectRatio; // 新增:宽高比 - - public boolean isImageToVideo() { - return (imageUrl != null && !imageUrl.trim().isEmpty()) || - (imageBase64 != null && !imageBase64.trim().isEmpty()); - } -} -``` - -#### 3.3 第三方API调用扩展 - -**文件:** `src/main/java/com/dora/service/impl/ThirdPartyApiServiceImpl.java` - -**新增支持:** -- 简单文本消息(文生图/视频) -- 复杂内容消息(文本 + 图片,图生视频) - -```java -if (imageParam != null && !imageParam.trim().isEmpty()) { - // 图生视频:构建复杂内容 - List contentItems = new ArrayList<>(); - contentItems.add(ContentItem.text(prompt)); - contentItems.add(ContentItem.imageUrl(imageParam)); - userMessage = new Message("user", contentItems); -} else { - // 文生图/视频:简单文本 - userMessage = new Message("user", prompt); -} -``` - ---- - -### 4. 安全配置更新 - -**文件:** `src/main/java/com/dora/config/SecurityConfig.java` - -**改动:** -```java -@RequiredArgsConstructor -public class SecurityConfig { - private final JwtAuthenticationFilter jwtAuthenticationFilter; - private final ApiKeyAuthenticationFilter apiKeyAuthenticationFilter; // 新增 - - @Bean - public SecurityFilterChain filterChain(HttpSecurity http) { - http - // API Key认证过滤器(在JWT之后) - .addFilterBefore(apiKeyAuthenticationFilter, UsernamePasswordAuthenticationFilter.class) - // JWT认证过滤器 - .addFilterBefore(jwtAuthenticationFilter, ApiKeyAuthenticationFilter.class); - } -} -``` - -**过滤器链顺序:** -1. ApiKeyAuthenticationFilter -2. JwtAuthenticationFilter -3. UsernamePasswordAuthenticationFilter - ---- - -### 5. 控制器优化 - -**文件:** `src/main/java/com/dora/controller/AiTaskController.java` - -**改动:** -- 移除硬编码的 `currentUserId = 1L` -- 使用 `SecurityUtil.getCurrentUserId()` 动态获取用户ID -- 支持JWT和API Key两种认证方式 -- 添加详细的Swagger文档 - -**示例:** -```java -@PostMapping("/submit") -public Result submitTask(@RequestBody TaskSubmitRequest request) { - try { - // 从Spring Security上下文获取用户ID(支持JWT和API Key) - Long currentUserId = SecurityUtil.getCurrentUserId(); - - // 构建任务DTO,包含图片参数 - CreateTaskDto createTaskDto = CreateTaskDto.builder() - .userId(currentUserId) - .modelName(request.getModelName()) - .prompt(request.getPrompt()) - .imageUrl(request.getImageUrl()) - .imageBase64(request.getImageBase64()) - .aspectRatio(request.getAspectRatio()) - .build(); - - AiTask createdTask = aiTaskService.createTask(createTaskDto); - return Result.success(response, "任务提交成功"); - - } catch (AuthenticationException e) { - return Result.error(401, "未认证,请提供有效的JWT Token或API Key"); - } -} -``` - ---- - -## 📊 文件变更清单 - -### 新增文件 - -| 文件路径 | 说明 | -|---------|------| -| `src/main/java/com/dora/config/ApiKeyAuthenticationFilter.java` | API Key认证过滤器 | -| `src/main/java/com/dora/dto/api/ContentItem.java` | 复杂消息内容项(支持文本+图片) | -| `V4__add_image_fields_to_ai_task.sql` | 数据库迁移脚本 | -| `AI_API_KEY_INTEGRATION_GUIDE.md` | API使用指南 | -| `SYSTEM_UPGRADE_SUMMARY_20251020.md` | 本文档 | - -### 修改文件 - -| 文件路径 | 主要改动 | -|---------|---------| -| `src/main/java/com/dora/config/SecurityConfig.java` | 添加API Key过滤器 | -| `src/main/java/com/dora/service/ApiKeyService.java` | 移除会员限制 | -| `src/main/java/com/dora/dto/TaskSubmitRequest.java` | 添加图片字段 | -| `src/main/java/com/dora/dto/CreateTaskDto.java` | 添加图片字段 | -| `src/main/java/com/dora/entity/AiTask.java` | 添加图片字段 | -| `src/main/java/com/dora/dto/api/Message.java` | 支持复杂内容 | -| `src/main/java/com/dora/service/ThirdPartyApiService.java` | 添加图生视频方法 | -| `src/main/java/com/dora/service/impl/ThirdPartyApiServiceImpl.java` | 实现图生视频 | -| `src/main/java/com/dora/service/AsyncTaskExecutor.java` | 支持图片参数 | -| `src/main/java/com/dora/service/impl/AiTaskServiceImpl.java` | 保存图片参数 | -| `src/main/java/com/dora/controller/AiTaskController.java` | 支持API Key认证 | -| `src/main/resources/mapper/AiTaskMapper.xml` | 添加图片字段SQL | - ---- - -## 🔄 兼容性说明 - -### ✅ 向后兼容 - -1. **现有JWT认证**:完全兼容,不受影响 -2. **原有API接口**:所有接口保持不变,仅新增认证方式 -3. **数据库**:新增字段允许NULL,不影响现有数据 -4. **会员体系**:会员用户的权益不受影响 - -### ⚠️ 注意事项 - -1. **数据库迁移**:需要执行 `V4__add_image_fields_to_ai_task.sql` -2. **依赖注入**:`SecurityConfig` 需要注入 `ApiKeyAuthenticationFilter` -3. **API Key生成**:现在所有用户都可以生成,需要更新前端提示文案 - ---- - -## 🧪 测试建议 - -### 1. API Key认证测试 - -```bash -# 1. 生成API Key(需要JWT登录) -curl -X POST "http://localhost:8081/user/v1/api-key/generate" \ - -H "Authorization: Bearer YOUR_JWT_TOKEN" - -# 2. 使用API Key提交任务 -curl -X POST "http://localhost:8081/user/ai/tasks/submit" \ - -H "Authorization: Bearer ak_your_api_key_here" \ - -H "Content-Type: application/json" \ - -d '{ - "modelName": "sora_image", - "prompt": "测试图片" - }' - -# 3. 使用API Key查询任务 -curl -X GET "http://localhost:8081/user/ai/tasks/TASK_NUMBER" \ - -H "Authorization: Bearer ak_your_api_key_here" -``` - -### 2. 图生视频测试 - -```bash -# 使用图片URL -curl -X POST "http://localhost:8081/user/ai/tasks/submit" \ - -H "Authorization: Bearer ak_your_api_key_here" \ - -H "Content-Type: application/json" \ - -d '{ - "modelName": "sora_video2", - "prompt": "让场景动起来", - "imageUrl": "https://example.com/test.jpg" - }' -``` - -### 3. 非会员用户测试 - -1. 创建一个普通用户(role = 0) -2. 充值积分(例如1000积分) -3. 生成API Key -4. 使用API Key提交任务 -5. 验证积分正常扣除 - ---- - -## 📈 性能影响 - -### 过滤器链 - -- **新增过滤器**:1个(ApiKeyAuthenticationFilter) -- **性能影响**:微小(<5ms per request) -- **原因**: - - 如果已有JWT认证,直接跳过 - - API Key验证仅需1次数据库查询(带索引) - - 查询结果可缓存 - -### 数据库 - -- **新增字段**:3个(image_url, image_base64, aspect_ratio) -- **存储影响**: - - `image_url`: ~200 bytes - - `image_base64`: ~100 KB(Base64编码后) - - `aspect_ratio`: ~10 bytes -- **建议**:优先使用 `image_url`,避免存储大量Base64数据 - ---- - -## 🚀 部署步骤 - -### 1. 数据库迁移 - -```bash -# 执行SQL脚本 -mysql -u root -p your_database < V4__add_image_fields_to_ai_task.sql -``` - -### 2. 代码部署 - -```bash -# 编译项目 -mvn clean package -DskipTests - -# 备份旧版本 -cp target/1818_user_server-1.0-SNAPSHOT.jar target/1818_user_server-1.0-SNAPSHOT.jar.bak - -# 停止服务 -sudo systemctl stop spring_1818_user_server - -# 部署新版本 -sudo cp target/1818_user_server-1.0-SNAPSHOT.jar /www/wwwroot/1818_user_server/ - -# 启动服务 -sudo systemctl start spring_1818_user_server - -# 检查日志 -sudo journalctl -u spring_1818_user_server -f -``` - -### 3. 验证部署 - -```bash -# 检查服务状态 -curl http://localhost:8081/actuator/health - -# 测试API Key认证 -curl -X GET "http://localhost:8081/user/v1/api-key/info" \ - -H "Authorization: Bearer YOUR_JWT_TOKEN" -``` - ---- - -## 📚 相关文档 - -- [API使用指南](./AI_API_KEY_INTEGRATION_GUIDE.md) -- [积分系统设计](./POINTS_SYSTEM_DESIGN.md) -- [管理端API文档](./ADMIN_AI_POINTS_API_GUIDE.md) - ---- - -## 🐛 已知问题 - -无 - ---- - -## 🎉 总结 - -本次升级成功实现了: - -1. ✅ **API Key认证体系** - 支持开发者和第三方集成 -2. ✅ **积分独立使用** - 非会员用户可以单独使用AI服务 -3. ✅ **图生视频功能** - 丰富了AI生成能力 -4. ✅ **向后兼容** - 不影响现有功能和用户 - -系统更加灵活开放,为未来的商业化和生态建设打下了基础!🚀 - ---- - -**升级负责人:** AI Assistant -**审核人:** 待定 -**发布日期:** 2025-10-20 - diff --git a/V10__add_plaza_feature.sql b/V10__add_plaza_feature.sql deleted file mode 100644 index b462815..0000000 --- a/V10__add_plaza_feature.sql +++ /dev/null @@ -1,166 +0,0 @@ --- ============================================================ --- V10: 添加广场功能(用户作品展示与分享) --- 描述: 用户可以将AI生成的作品发布到广场,支持按类型查询、点赞、浏览统计 --- 作者: 1818AI --- 日期: 2025-10-26 --- ============================================================ - -USE `1818ai`; - --- ============================================================ --- 1. 创建广场作品表 --- ============================================================ - -CREATE TABLE IF NOT EXISTS `plaza_work` ( - `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键ID', - `work_no` VARCHAR(50) NOT NULL COMMENT '作品编号(唯一标识)', - `user_id` BIGINT NOT NULL COMMENT '发布者用户ID', - `task_no` VARCHAR(50) NOT NULL COMMENT '关联的任务编号', - `task_type` VARCHAR(50) NOT NULL COMMENT '任务类型:text_to_image/image_to_image/text_to_video/image_to_video等', - `model_name` VARCHAR(100) NOT NULL COMMENT '使用的模型名称', - `prompt` TEXT NOT NULL COMMENT '生成提示词', - `result_url` VARCHAR(500) NOT NULL COMMENT '作品结果URL(图片或视频)', - `image_url` VARCHAR(500) DEFAULT NULL COMMENT '参考图URL(图生图/图生视频任务使用)', - `aspect_ratio` VARCHAR(20) DEFAULT NULL COMMENT '宽高比:1:1/2:3/3:2/9:16/16:9等', - - `title` VARCHAR(200) DEFAULT NULL COMMENT '作品标题(可选)', - `description` TEXT DEFAULT NULL COMMENT '作品描述(可选)', - `tags` VARCHAR(500) DEFAULT NULL COMMENT '标签(JSON数组字符串)', - - `view_count` INT DEFAULT 0 COMMENT '浏览次数', - `like_count` INT DEFAULT 0 COMMENT '点赞数', - `share_count` INT DEFAULT 0 COMMENT '分享数', - `comment_count` INT DEFAULT 0 COMMENT '评论数(预留)', - - `is_public` TINYINT(1) DEFAULT 1 COMMENT '是否公开:0-仅自己可见,1-公开', - `status` VARCHAR(20) DEFAULT 'published' COMMENT '状态:draft-草稿,published-已发布,hidden-已隐藏', - - `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', - `is_deleted` TINYINT(1) DEFAULT 0 COMMENT '是否删除:0-未删除,1-已删除', - - PRIMARY KEY (`id`), - UNIQUE KEY `uk_work_no` (`work_no`), - KEY `idx_user_id` (`user_id`), - KEY `idx_task_no` (`task_no`), - KEY `idx_task_type` (`task_type`), - KEY `idx_create_time` (`create_time`), - KEY `idx_like_count` (`like_count`), - KEY `idx_status_public` (`status`, `is_public`, `is_deleted`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='广场作品表'; - --- ============================================================ --- 2. 创建点赞表 --- ============================================================ - -CREATE TABLE IF NOT EXISTS `plaza_work_like` ( - `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键ID', - `work_id` BIGINT NOT NULL COMMENT '作品ID', - `user_id` BIGINT NOT NULL COMMENT '点赞用户ID', - `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '点赞时间', - - PRIMARY KEY (`id`), - UNIQUE KEY `uk_work_user` (`work_id`, `user_id`), - KEY `idx_user_id` (`user_id`), - KEY `idx_create_time` (`create_time`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='广场作品点赞表'; - --- ============================================================ --- 3. 创建浏览记录表(可选,用于统计) --- ============================================================ - -CREATE TABLE IF NOT EXISTS `plaza_work_view` ( - `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键ID', - `work_id` BIGINT NOT NULL COMMENT '作品ID', - `user_id` BIGINT DEFAULT NULL COMMENT '浏览用户ID(可为空,支持匿名浏览)', - `ip_address` VARCHAR(50) DEFAULT NULL COMMENT 'IP地址', - `user_agent` VARCHAR(500) DEFAULT NULL COMMENT '用户代理', - `view_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '浏览时间', - - PRIMARY KEY (`id`), - KEY `idx_work_id` (`work_id`), - KEY `idx_user_id` (`user_id`), - KEY `idx_view_time` (`view_time`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='广场作品浏览记录表'; - --- ============================================================ --- 4. 插入示例数据(可选) --- ============================================================ - --- 假设用户ID 17563793187762127 发布了几个作品 --- INSERT INTO `plaza_work` (`work_no`, `user_id`, `task_no`, `task_type`, `model_name`, `prompt`, `result_url`, `title`, `tags`, `is_public`) VALUES --- ('WORK-20251026-001', 17563793187762127, 'TASK-20251026183750127-8554', 'image_to_video', 'sc_sora2_img_landscape_15s_small', '根据参考图生成战场短视频', 'https://oss-1818ai-user-img.oss-cn-hangzhou.aliyuncs.com/result.mp4', '战场气氛短视频', '["视频","战争","特效"]', 1), --- ('WORK-20251026-002', 17563793187762127, 'TASK-20251026120000000-0001', 'text_to_image', 'sc_soraimg_text_1x1', '一只可爱的橘猫在窗台晒太阳', 'https://oss-1818ai-user-img.oss-cn-hangzhou.aliyuncs.com/cat.png', '窗台上的橘猫', '["猫咪","温馨","治愈"]', 1); - --- ============================================================ --- 5. 添加索引优化查询性能 --- ============================================================ - --- 复合索引:按任务类型和创建时间查询热门作品 -CREATE INDEX `idx_type_like_time` ON `plaza_work`(`task_type`, `like_count` DESC, `create_time` DESC); - --- 复合索引:按状态和公开性查询 -CREATE INDEX `idx_status_public_time` ON `plaza_work`(`status`, `is_public`, `create_time` DESC); - --- ============================================================ --- 6. 创建视图:热门作品 --- ============================================================ - -CREATE OR REPLACE VIEW `v_plaza_hot_works` AS -SELECT - pw.id, - pw.work_no, - pw.user_id, - pw.task_type, - pw.model_name, - pw.title, - pw.result_url, - pw.like_count, - pw.view_count, - pw.create_time, - u.nickname AS user_nickname, - u.avatar_url AS user_avatar -FROM plaza_work pw -LEFT JOIN user u ON pw.user_id = u.id -WHERE pw.status = 'published' - AND pw.is_public = 1 - AND pw.is_deleted = 0 -ORDER BY pw.like_count DESC, pw.create_time DESC; - --- ============================================================ --- 7. 创建视图:最新作品 --- ============================================================ - -CREATE OR REPLACE VIEW `v_plaza_latest_works` AS -SELECT - pw.id, - pw.work_no, - pw.user_id, - pw.task_type, - pw.model_name, - pw.title, - pw.result_url, - pw.like_count, - pw.view_count, - pw.create_time, - u.nickname AS user_nickname, - u.avatar_url AS user_avatar -FROM plaza_work pw -LEFT JOIN user u ON pw.user_id = u.id -WHERE pw.status = 'published' - AND pw.is_public = 1 - AND pw.is_deleted = 0 -ORDER BY pw.create_time DESC; - --- ============================================================ --- 验证表结构 --- ============================================================ - -SHOW CREATE TABLE plaza_work; -SHOW CREATE TABLE plaza_work_like; -SHOW CREATE TABLE plaza_work_view; - --- ============================================================ --- V10脚本结束 --- ============================================================ - diff --git a/V11__add_sora2pro_models.sql b/V11__add_sora2pro_models.sql deleted file mode 100644 index b1b9a45..0000000 --- a/V11__add_sora2pro_models.sql +++ /dev/null @@ -1,95 +0,0 @@ --- ============================================================ --- V11: 添加速创API(SuChuang)的Sora2Pro模型配置 --- 描述: Sora2Pro 是速创的新视频生成模型,使用 /api/sora2pro/submit 接口 --- 特点: --- - 定价:400积分 --- - 支持15秒和25秒时长 --- - 25秒只能标清,15秒有高清和标清选项 --- - 支持9:16(竖屏)和16:9(横屏) --- - 支持文生视频和图生视频 --- 作者: 1818AI --- 日期: 2025-01-XX --- ============================================================ - -USE `1818ai`; - --- 插入速创Sora2Pro模型配置 --- 文生视频模型(6个) --- 9:16 竖屏 -INSERT INTO `points_config` (`model_name`, `description`, `points_cost`, `provider_type`, `provider_config`, `task_type`, `is_enabled`, `create_time`, `update_time`) -VALUES -('sc_sora2pro_text_portrait_15s_small', '速创Sora2Pro 文生视频-竖屏-15秒-标清', 400, 'suchuang', - '{"aspectRatio":"9:16","duration":"15"}', - 'text_to_video', 1, NOW(), NOW()), - -('sc_sora2pro_text_portrait_15s_large', '速创Sora2Pro 文生视频-竖屏-15秒-高清', 400, 'suchuang', - '{"aspectRatio":"9:16","duration":"15"}', - 'text_to_video', 1, NOW(), NOW()), - -('sc_sora2pro_text_portrait_25s_small', '速创Sora2Pro 文生视频-竖屏-25秒-标清', 400, 'suchuang', - '{"aspectRatio":"9:16","duration":"25"}', - 'text_to_video', 1, NOW(), NOW()); - --- 16:9 横屏 -INSERT INTO `points_config` (`model_name`, `description`, `points_cost`, `provider_type`, `provider_config`, `task_type`, `is_enabled`, `create_time`, `update_time`) -VALUES -('sc_sora2pro_text_landscape_15s_small', '速创Sora2Pro 文生视频-横屏-15秒-标清', 400, 'suchuang', - '{"aspectRatio":"16:9","duration":"15"}', - 'text_to_video', 1, NOW(), NOW()), - -('sc_sora2pro_text_landscape_15s_large', '速创Sora2Pro 文生视频-横屏-15秒-高清', 400, 'suchuang', - '{"aspectRatio":"16:9","duration":"15"}', - 'text_to_video', 1, NOW(), NOW()), - -('sc_sora2pro_text_landscape_25s_small', '速创Sora2Pro 文生视频-横屏-25秒-标清', 400, 'suchuang', - '{"aspectRatio":"16:9","duration":"25"}', - 'text_to_video', 1, NOW(), NOW()); - --- 图生视频模型(6个) --- 9:16 竖屏 -INSERT INTO `points_config` (`model_name`, `description`, `points_cost`, `provider_type`, `provider_config`, `task_type`, `is_enabled`, `create_time`, `update_time`) -VALUES -('sc_sora2pro_img_portrait_15s_small', '速创Sora2Pro 图生视频-竖屏-15秒-标清', 400, 'suchuang', - '{"aspectRatio":"9:16","duration":"15","requireImage":true}', - 'image_to_video', 1, NOW(), NOW()), - -('sc_sora2pro_img_portrait_15s_large', '速创Sora2Pro 图生视频-竖屏-15秒-高清', 400, 'suchuang', - '{"aspectRatio":"9:16","duration":"15","requireImage":true}', - 'image_to_video', 1, NOW(), NOW()), - -('sc_sora2pro_img_portrait_25s_small', '速创Sora2Pro 图生视频-竖屏-25秒-标清', 400, 'suchuang', - '{"aspectRatio":"9:16","duration":"25","requireImage":true}', - 'image_to_video', 1, NOW(), NOW()); - --- 16:9 横屏 -INSERT INTO `points_config` (`model_name`, `description`, `points_cost`, `provider_type`, `provider_config`, `task_type`, `is_enabled`, `create_time`, `update_time`) -VALUES -('sc_sora2pro_img_landscape_15s_small', '速创Sora2Pro 图生视频-横屏-15秒-标清', 400, 'suchuang', - '{"aspectRatio":"16:9","duration":"15","requireImage":true}', - 'image_to_video', 1, NOW(), NOW()), - -('sc_sora2pro_img_landscape_15s_large', '速创Sora2Pro 图生视频-横屏-15秒-高清', 400, 'suchuang', - '{"aspectRatio":"16:9","duration":"15","requireImage":true}', - 'image_to_video', 1, NOW(), NOW()), - -('sc_sora2pro_img_landscape_25s_small', '速创Sora2Pro 图生视频-横屏-25秒-标清', 400, 'suchuang', - '{"aspectRatio":"16:9","duration":"25","requireImage":true}', - 'image_to_video', 1, NOW(), NOW()); - --- 验证插入的模型 -SELECT - model_name, - description, - points_cost, - provider_type, - task_type, - provider_config, - is_enabled -FROM points_config -WHERE model_name LIKE 'sc_sora2pro%' -ORDER BY task_type, model_name; - --- ============================================================ --- V11脚本结束 --- ============================================================ - diff --git a/V2__add_ai_task_and_points_schema.sql b/V2__add_ai_task_and_points_schema.sql deleted file mode 100644 index 1b95fc9..0000000 --- a/V2__add_ai_task_and_points_schema.sql +++ /dev/null @@ -1,117 +0,0 @@ --- ================================================================= --- V2: AI任务与积分消费系统 数据库结构定义 --- 时间: 2025-10-19 --- 描述: 为集成第三方AI模型和积分商业化,新增相关表结构。 --- 此脚本为增量更新,不修改现有表,保证向前兼容。 --- ================================================================= - --- 1. AI生成任务表 (核心) --- 作用: 持久化用户的每一次AI生成请求,追踪其完整的生命周期。 --- ================================================================= -CREATE TABLE IF NOT EXISTS `ai_task` ( - `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键', - `task_no` varchar(64) UNIQUE NOT NULL COMMENT '任务编号 (系统生成的唯一ID)', - `user_id` bigint NOT NULL COMMENT '关联的用户ID', - `model_name` varchar(64) NOT NULL COMMENT '请求的模型名称 (如: sora_image)', - `task_type` varchar(32) NOT NULL COMMENT '任务类型 (image/video)', - `prompt` text NOT NULL COMMENT '用户提交的提示词', - `status` varchar(32) NOT NULL DEFAULT 'created' COMMENT '任务状态 (created, queued, processing, completed, failed, cancelled)', - `progress` int DEFAULT 0 COMMENT '生成进度百分比 (0-100)', - `progress_message` varchar(255) DEFAULT NULL COMMENT '当前进度文本描述', - `points_frozen` int NOT NULL COMMENT '本次任务冻结的积分', - `points_consumed` int DEFAULT 0 COMMENT '任务成功后实际消耗的积分', - `result_url` varchar(512) DEFAULT NULL COMMENT '生成结果的URL', - `error_message` text DEFAULT NULL COMMENT '任务失败时的错误信息', - `queue_time` datetime DEFAULT NULL COMMENT '进入队列的时间', - `start_time` datetime DEFAULT NULL COMMENT '开始处理的时间', - `complete_time` datetime DEFAULT NULL COMMENT '任务完成或失败的时间', - `expire_time` datetime DEFAULT NULL COMMENT '结果URL的过期时间 (根据第三方API策略设定)', - `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '任务创建时间', - `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后更新时间', - `is_deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除标识', - PRIMARY KEY (`id`), - UNIQUE KEY `uk_task_no` (`task_no`), - KEY `idx_user_status` (`user_id`, `status`), - KEY `idx_status_time` (`status`, `create_time`), - FOREIGN KEY (`user_id`) REFERENCES `user`(`id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='AI生成任务表'; - --- ================================================================= --- 2. 积分消费配置表 --- 作用: 管理员可在此配置不同AI模型的积分价格,实现动态调价。 --- ================================================================= -CREATE TABLE IF NOT EXISTS `points_config` ( - `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键', - `model_name` varchar(64) UNIQUE NOT NULL COMMENT '模型名称 (如: sora_image)', - `points_cost` int NOT NULL COMMENT '调用一次消耗的积分', - `description` varchar(255) DEFAULT NULL COMMENT '模型描述', - `is_enabled` tinyint(1) NOT NULL DEFAULT 1 COMMENT '是否启用 (0:禁用, 1:启用)', - `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后更新时间', - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='积分消费配置表'; - --- ================================================================= --- 3. 积分消费记录表 --- 作用: 提供完整的积分变动审计日志,便于追踪和对账。 --- ================================================================= -CREATE TABLE IF NOT EXISTS `points_consumption_log` ( - `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键', - `user_id` bigint NOT NULL COMMENT '关联的用户ID', - `task_no` varchar(64) DEFAULT NULL COMMENT '关联的AI任务编号', - `change_type` varchar(32) NOT NULL COMMENT '变动类型 (consume:消费, refund:退款, admin_adjust:管理员调整)', - `change_amount` int NOT NULL COMMENT '变动积分数量 (正数表示增加,负数表示减少)', - `balance_before` int NOT NULL COMMENT '变动前积分余额', - `balance_after` int NOT NULL COMMENT '变动后积分余额', - `description` varchar(255) DEFAULT NULL COMMENT '变动描述', - `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '记录创建时间', - PRIMARY KEY (`id`), - KEY `idx_user_id_type` (`user_id`, `change_type`), - FOREIGN KEY (`user_id`) REFERENCES `user`(`id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='积分消费记录表'; - --- ================================================================= --- 4. 系统配置表 --- 作用: 存储可由管理员在后台动态调整的系统级参数。 --- ================================================================= -CREATE TABLE IF NOT EXISTS `system_config` ( - `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键', - `config_key` varchar(64) UNIQUE NOT NULL COMMENT '配置键 (如: ai.queue.max_concurrent)', - `config_value` varchar(512) NOT NULL COMMENT '配置值', - `description` varchar(255) DEFAULT NULL COMMENT '配置说明', - `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后更新时间', - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='系统配置表'; - --- ================================================================= --- 初始化默认配置数据 --- 作用: 插入一些基础配置,保证系统首次启动时功能正常。 --- ================================================================= - --- 初始化系统配置 -INSERT INTO `system_config` (`config_key`, `config_value`, `description`) VALUES - ('ai.queue.max_concurrent', '50', '每个AI模型的最大并发处理数'), - ('ai.queue.max_user_concurrent', '3', '单个用户的最大并发任务数'), - ('ai.task.timeout_minutes', '10', '任务处理超时时间(分钟)'), - ('ai.task.max_retry', '2', '任务失败后的最大自动重试次数') -ON DUPLICATE KEY UPDATE `config_value` = VALUES(`config_value`); - --- 初始化图片模型定价 -INSERT INTO `points_config` (`model_name`, `points_cost`, `description`, `is_enabled`) VALUES - ('sora_image', 11, 'Sora高质量图片生成', 1), - ('gpt-4o-image', 11, 'GPT-4o图片生成', 1) -ON DUPLICATE KEY UPDATE `points_cost` = VALUES(`points_cost`); - --- 初始化视频模型定价 -INSERT INTO `points_config` (`model_name`, `points_cost`, `description`, `is_enabled`) VALUES - ('sora_video2', 160, 'Sora视频生成 (竖屏10秒)', 1), - ('sora_video2-landscape', 160, 'Sora视频生成 (横屏10秒)', 1), - ('sora_video2-15s', 260, 'Sora视频生成 (竖屏15秒)', 1), - ('sora_video2-landscape-15s', 260, 'Sora视频生成 (横屏15秒)', 1), - ('sora-2-pro-all', 420, 'Sora Pro高清视频', 1) -ON DUPLICATE KEY UPDATE `points_cost` = VALUES(`points_cost`); - --- ================================================================= --- V2脚本结束 --- ================================================================= diff --git a/V3__add_is_deleted_to_new_tables.sql b/V3__add_is_deleted_to_new_tables.sql deleted file mode 100644 index 6beda56..0000000 --- a/V3__add_is_deleted_to_new_tables.sql +++ /dev/null @@ -1,22 +0,0 @@ --- ================================================================= --- V3: 为AI任务与积分系统的新表添加逻辑删除字段 --- 时间: 2025-10-19 --- 描述: 补充 V2 脚本中遗漏的 is_deleted 字段,保持与项目其他表的一致性。 --- ================================================================= - --- 为 points_config 表添加逻辑删除字段 -ALTER TABLE `points_config` -ADD COLUMN `is_deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除标识' AFTER `update_time`; - --- 为 points_consumption_log 表添加逻辑删除字段 -ALTER TABLE `points_consumption_log` -ADD COLUMN `is_deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除标识' AFTER `create_time`; - --- 为 system_config 表添加逻辑删除字段 -ALTER TABLE `system_config` -ADD COLUMN `is_deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除标识' AFTER `update_time`; - --- ================================================================= --- V3脚本结束 --- ================================================================= - diff --git a/V4__add_image_fields_to_ai_task.sql b/V4__add_image_fields_to_ai_task.sql deleted file mode 100644 index 128a828..0000000 --- a/V4__add_image_fields_to_ai_task.sql +++ /dev/null @@ -1,21 +0,0 @@ --- ============================================================ --- V4: 为AI任务表添加图片参数支持 --- 描述: 支持图生视频功能,允许用户上传参考图片 --- 作者: 1818AI --- 日期: 2025-10-20 --- ============================================================ - --- 添加图片相关字段到ai_task表 -ALTER TABLE `ai_task` -ADD COLUMN `image_url` VARCHAR(500) NULL COMMENT '参考图片URL(用于图生视频)' AFTER `prompt`, -ADD COLUMN `image_base64` TEXT NULL COMMENT '参考图片Base64编码(用于图生视频)' AFTER `image_url`, -ADD COLUMN `aspect_ratio` VARCHAR(10) NULL COMMENT '图片宽高比(如2:3, 3:2, 1:1)' AFTER `image_base64`; - --- 添加索引以优化查询性能 -CREATE INDEX `idx_task_type` ON `ai_task`(`task_type`); - --- 记录迁移日志 -INSERT INTO `migration_log` (`version`, `description`, `executed_at`) -VALUES ('V4', '为AI任务表添加图片参数支持(图生视频功能)', NOW()) -ON DUPLICATE KEY UPDATE `executed_at` = NOW(); - diff --git a/V4__add_image_fields_to_ai_task_FIXED.sql b/V4__add_image_fields_to_ai_task_FIXED.sql deleted file mode 100644 index 0d4080d..0000000 --- a/V4__add_image_fields_to_ai_task_FIXED.sql +++ /dev/null @@ -1,94 +0,0 @@ --- ============================================================ --- V4: 为AI任务表添加图片参数支持(修复版) --- 描述: 支持图生视频功能,允许用户上传参考图片 --- 作者: 1818AI --- 日期: 2025-10-20 --- ============================================================ - --- 指定数据库 -USE `1818ai`; - --- 1. 添加 image_url 字段(如果不存在) -SET @col_exists = ( - SELECT COUNT(*) - FROM INFORMATION_SCHEMA.COLUMNS - WHERE TABLE_SCHEMA = DATABASE() - AND TABLE_NAME = 'ai_task' - AND COLUMN_NAME = 'image_url' -); - -SET @sql = IF(@col_exists = 0, - 'ALTER TABLE `ai_task` ADD COLUMN `image_url` VARCHAR(500) NULL COMMENT ''参考图片URL(用于图生视频)'' AFTER `prompt`', - 'SELECT ''Column image_url already exists'' AS info' -); -PREPARE stmt FROM @sql; -EXECUTE stmt; -DEALLOCATE PREPARE stmt; - --- 2. 添加 image_base64 字段(如果不存在) -SET @col_exists = ( - SELECT COUNT(*) - FROM INFORMATION_SCHEMA.COLUMNS - WHERE TABLE_SCHEMA = DATABASE() - AND TABLE_NAME = 'ai_task' - AND COLUMN_NAME = 'image_base64' -); - -SET @sql = IF(@col_exists = 0, - 'ALTER TABLE `ai_task` ADD COLUMN `image_base64` TEXT NULL COMMENT ''参考图片Base64编码(用于图生视频)'' AFTER `image_url`', - 'SELECT ''Column image_base64 already exists'' AS info' -); -PREPARE stmt FROM @sql; -EXECUTE stmt; -DEALLOCATE PREPARE stmt; - --- 3. 添加 aspect_ratio 字段(如果不存在) -SET @col_exists = ( - SELECT COUNT(*) - FROM INFORMATION_SCHEMA.COLUMNS - WHERE TABLE_SCHEMA = DATABASE() - AND TABLE_NAME = 'ai_task' - AND COLUMN_NAME = 'aspect_ratio' -); - -SET @sql = IF(@col_exists = 0, - 'ALTER TABLE `ai_task` ADD COLUMN `aspect_ratio` VARCHAR(10) NULL COMMENT ''图片宽高比(如2:3, 3:2, 1:1)'' AFTER `image_base64`', - 'SELECT ''Column aspect_ratio already exists'' AS info' -); -PREPARE stmt FROM @sql; -EXECUTE stmt; -DEALLOCATE PREPARE stmt; - --- 4. 添加索引(如果不存在) -SET @index_exists = ( - SELECT COUNT(*) - FROM INFORMATION_SCHEMA.STATISTICS - WHERE TABLE_SCHEMA = DATABASE() - AND TABLE_NAME = 'ai_task' - AND INDEX_NAME = 'idx_task_type' -); - -SET @sql = IF(@index_exists = 0, - 'CREATE INDEX `idx_task_type` ON `ai_task`(`task_type`)', - 'SELECT ''Index idx_task_type already exists'' AS info' -); -PREPARE stmt FROM @sql; -EXECUTE stmt; -DEALLOCATE PREPARE stmt; - --- 5. 验证字段是否添加成功 -SELECT - COLUMN_NAME, - COLUMN_TYPE, - IS_NULLABLE, - COLUMN_COMMENT -FROM INFORMATION_SCHEMA.COLUMNS -WHERE TABLE_SCHEMA = DATABASE() - AND TABLE_NAME = 'ai_task' - AND COLUMN_NAME IN ('image_url', 'image_base64', 'aspect_ratio') -ORDER BY ORDINAL_POSITION; - --- ============================================================ --- V4脚本结束 --- ============================================================ - diff --git a/V5_MIGRATION_FIX_GUIDE.md b/V5_MIGRATION_FIX_GUIDE.md deleted file mode 100644 index 319254d..0000000 --- a/V5_MIGRATION_FIX_GUIDE.md +++ /dev/null @@ -1,367 +0,0 @@ -# V5 数据库迁移修复指南 - -**问题:** 执行V5迁移脚本时出现 `#1060 - Duplicate column name 'provider_type'` 错误 - -**原因:** -1. `provider_type` 列已经存在(之前执行过V5的ALTER TABLE部分) -2. V5中插入的RunningHub模型的 `provider_type` 值为空字符串 `''`,应该是 `'runninghub'` - ---- - -## 📋 解决方案 - -### 方案1:修复现有数据库(推荐) - -如果你已经执行过V5脚本的ALTER TABLE部分,只需要更新数据: - -```bash -# 1. 执行修复脚本 -mysql -u root -p 1818ai < FIX_V5_provider_type.sql -``` - -**修复脚本内容:** -```sql --- 更新所有RunningHub模型的provider_type -UPDATE `points_config` -SET `provider_type` = 'runninghub' -WHERE `model_name` LIKE 'rh_sora2_%' - AND (`provider_type` = '' OR `provider_type` IS NULL); - --- 验证更新结果 -SELECT model_name, provider_type, description -FROM `points_config` -WHERE `model_name` LIKE 'rh_sora2_%'; -``` - -**验证步骤:** -```sql --- 1. 检查列是否存在 -SHOW COLUMNS FROM `points_config` LIKE 'provider_type'; -SHOW COLUMNS FROM `ai_task` LIKE 'provider_type'; - --- 2. 检查RunningHub模型配置 -SELECT model_name, provider_type, points_cost, description -FROM `points_config` -WHERE `model_name` LIKE 'rh_sora2_%'; - --- 预期结果:12个模型,provider_type都是'runninghub' -``` - ---- - -### 方案2:从头执行(全新数据库) - -如果是全新的数据库或需要重新迁移,使用修正版脚本: - -```bash -# 使用修正版脚本 -mysql -u root -p 1818ai < V5__add_provider_support_CORRECTED.sql -``` - -**修正版特点:** -- ✅ 使用 `ADD COLUMN IF NOT EXISTS` 避免重复列错误 -- ✅ 使用 `CREATE INDEX IF NOT EXISTS` 避免重复索引错误 -- ✅ `provider_type` 值正确设置为 `'runninghub'` -- ✅ ON DUPLICATE KEY UPDATE 包含所有必要字段 - ---- - -## 🔍 问题诊断 - -### 检查当前数据库状态 - -```sql --- 1. 检查points_config表结构 -DESC `points_config`; - --- 2. 检查是否有provider_type列 -SELECT COUNT(*) as has_column -FROM INFORMATION_SCHEMA.COLUMNS -WHERE TABLE_SCHEMA = '1818ai' - AND TABLE_NAME = 'points_config' - AND COLUMN_NAME = 'provider_type'; --- 结果为1表示列已存在,0表示不存在 - --- 3. 检查现有RunningHub模型的provider_type值 -SELECT - model_name, - provider_type, - CASE - WHEN provider_type = '' THEN '空字符串(错误)' - WHEN provider_type = 'runninghub' THEN '正确' - WHEN provider_type IS NULL THEN 'NULL(错误)' - ELSE CONCAT('其他值: ', provider_type) - END as status -FROM `points_config` -WHERE `model_name` LIKE 'rh_sora2_%'; - --- 4. 检查是否有RunningHub模型记录 -SELECT COUNT(*) as runninghub_model_count -FROM `points_config` -WHERE `model_name` LIKE 'rh_sora2_%'; --- 应该是12个 -``` - ---- - -## 📝 分步修复流程 - -### 步骤1:备份数据库 - -```bash -# 备份整个数据库 -mysqldump -u root -p 1818ai > backup_before_v5_fix_$(date +%Y%m%d_%H%M%S).sql - -# 只备份points_config表 -mysqldump -u root -p 1818ai points_config > backup_points_config_$(date +%Y%m%d_%H%M%S).sql -``` - -### 步骤2:检查表结构 - -```sql --- 检查points_config是否有provider相关列 -SHOW COLUMNS FROM `points_config` WHERE Field IN ('provider_type', 'provider_config'); - --- 检查ai_task是否有provider相关列 -SHOW COLUMNS FROM `ai_task` WHERE Field IN ('provider_type', 'provider_task_id', 'provider_response'); -``` - -**预期结果:** -``` --- points_config应该有: -provider_type | varchar(50) | NO | | openai -provider_config | text | YES | | NULL - --- ai_task应该有: -provider_type | varchar(50) | YES | | NULL -provider_task_id | varchar(100) | YES | | NULL -provider_response | text | YES | | NULL -``` - -### 步骤3:根据情况执行修复 - -**情况A:列已存在,但RunningHub模型的provider_type值错误** -```sql --- 直接执行修复脚本 -source FIX_V5_provider_type.sql; -``` - -**情况B:列不存在** -```sql --- 执行完整的V5脚本(建议使用修正版) -source V5__add_provider_support_CORRECTED.sql; -``` - -**情况C:部分列存在** -```sql --- 1. 手动添加缺失的列 -ALTER TABLE `points_config` -ADD COLUMN IF NOT EXISTS `provider_type` VARCHAR(50) NOT NULL DEFAULT 'openai' - COMMENT 'AI服务提供商类型' AFTER `is_enabled`, -ADD COLUMN IF NOT EXISTS `provider_config` TEXT NULL - COMMENT '服务商特定配置(JSON格式)' AFTER `provider_type`; - -ALTER TABLE `ai_task` -ADD COLUMN IF NOT EXISTS `provider_type` VARCHAR(50) NULL - COMMENT 'AI服务提供商类型' AFTER `task_type`, -ADD COLUMN IF NOT EXISTS `provider_task_id` VARCHAR(100) NULL - COMMENT '服务商返回的任务ID' AFTER `provider_type`, -ADD COLUMN IF NOT EXISTS `provider_response` TEXT NULL - COMMENT '服务商原始响应(JSON)' AFTER `provider_task_id`; - --- 2. 执行修复脚本 -source FIX_V5_provider_type.sql; -``` - -### 步骤4:验证修复结果 - -```sql --- 1. 检查RunningHub模型数量 -SELECT COUNT(*) as count -FROM `points_config` -WHERE `model_name` LIKE 'rh_sora2_%'; --- 预期:12 - --- 2. 检查provider_type值 -SELECT - COUNT(*) as total, - SUM(CASE WHEN provider_type = 'runninghub' THEN 1 ELSE 0 END) as correct, - SUM(CASE WHEN provider_type != 'runninghub' THEN 1 ELSE 0 END) as incorrect -FROM `points_config` -WHERE `model_name` LIKE 'rh_sora2_%'; --- 预期:total=12, correct=12, incorrect=0 - --- 3. 查看所有RunningHub模型 -SELECT model_name, provider_type, points_cost, description -FROM `points_config` -WHERE `model_name` LIKE 'rh_sora2_%' -ORDER BY points_cost, model_name; - --- 预期输出: -/* -model_name | provider_type | points_cost | description -----------------------------|---------------|-------------|--------------------------- -rh_sora2_text_portrait | runninghub | 160 | RunningHub Sora2 文生视频-竖屏(10秒) -rh_sora2_text_landscape | runninghub | 160 | RunningHub Sora2 文生视频-横屏(10秒) -rh_sora2_img_portrait | runninghub | 180 | RunningHub Sora2 图生视频-竖屏(10秒) -rh_sora2_img_landscape | runninghub | 180 | RunningHub Sora2 图生视频-横屏(10秒) -...(共12条) -*/ - --- 4. 检查provider_config是否为有效JSON -SELECT - model_name, - provider_config, - CASE - WHEN JSON_VALID(provider_config) THEN '有效JSON' - ELSE '无效JSON' - END as json_status -FROM `points_config` -WHERE `model_name` LIKE 'rh_sora2_%'; --- 所有记录的json_status应该是'有效JSON' -``` - ---- - -## ⚠️ 常见错误处理 - -### 错误1:Duplicate column name 'provider_type' - -**错误信息:** -``` -#1060 - Duplicate column name 'provider_type' -``` - -**原因:** 列已经存在 - -**解决:** -```sql --- 跳过ALTER TABLE,直接执行修复脚本 -source FIX_V5_provider_type.sql; -``` - ---- - -### 错误2:Duplicate entry for key 'PRIMARY' - -**错误信息:** -``` -#1062 - Duplicate entry 'rh_sora2_text_portrait' for key 'PRIMARY' -``` - -**原因:** RunningHub模型已经插入过 - -**解决:** -```sql --- 使用UPDATE而非INSERT -UPDATE `points_config` -SET - provider_type = 'runninghub', - provider_config = '{"webappId":"1973555977595301890","taskType":"text2video","model":"portrait","duration":10}', - update_time = NOW() -WHERE model_name = 'rh_sora2_text_portrait'; - --- 或者直接执行修复脚本(批量更新) -source FIX_V5_provider_type.sql; -``` - ---- - -### 错误3:provider_type值为空字符串 - -**症状:** -```sql -SELECT model_name, provider_type -FROM `points_config` -WHERE `model_name` LIKE 'rh_sora2_%'; - --- 结果:provider_type显示为空或'' -``` - -**解决:** -```sql --- 执行修复脚本 -source FIX_V5_provider_type.sql; -``` - ---- - -## ✅ 验证清单 - -修复完成后,确认以下所有项: - -- [ ] `points_config` 表有 `provider_type` 和 `provider_config` 列 -- [ ] `ai_task` 表有 `provider_type`、`provider_task_id`、`provider_response` 列 -- [ ] 有12个RunningHub模型记录 -- [ ] 所有RunningHub模型的 `provider_type` 值为 `'runninghub'` -- [ ] 所有RunningHub模型的 `provider_config` 是有效的JSON -- [ ] 索引 `idx_provider_task_id` 和 `idx_provider_type_status` 存在 - -**验证命令:** -```bash -# 执行完整验证 -mysql -u root -p 1818ai << 'EOF' --- 1. 检查列 -SELECT 'points_config columns' as check_item, COUNT(*) as result -FROM INFORMATION_SCHEMA.COLUMNS -WHERE TABLE_SCHEMA = '1818ai' AND TABLE_NAME = 'points_config' - AND COLUMN_NAME IN ('provider_type', 'provider_config'); --- 预期:2 - -SELECT 'ai_task columns' as check_item, COUNT(*) as result -FROM INFORMATION_SCHEMA.COLUMNS -WHERE TABLE_SCHEMA = '1818ai' AND TABLE_NAME = 'ai_task' - AND COLUMN_NAME IN ('provider_type', 'provider_task_id', 'provider_response'); --- 预期:3 - --- 2. 检查RunningHub模型 -SELECT 'RunningHub models' as check_item, COUNT(*) as result -FROM `points_config` -WHERE `model_name` LIKE 'rh_sora2_%'; --- 预期:12 - --- 3. 检查provider_type正确性 -SELECT 'Correct provider_type' as check_item, COUNT(*) as result -FROM `points_config` -WHERE `model_name` LIKE 'rh_sora2_%' AND `provider_type` = 'runninghub'; --- 预期:12 - --- 4. 检查索引 -SELECT 'Indexes' as check_item, COUNT(*) as result -FROM INFORMATION_SCHEMA.STATISTICS -WHERE TABLE_SCHEMA = '1818ai' AND TABLE_NAME = 'ai_task' - AND INDEX_NAME IN ('idx_provider_task_id', 'idx_provider_type_status'); --- 预期:2(至少) - -EOF -``` - ---- - -## 📞 技术支持 - -如果遇到其他问题,请提供以下信息: - -```sql --- 1. 数据库版本 -SELECT VERSION(); - --- 2. 表结构 -SHOW CREATE TABLE `points_config`; -SHOW CREATE TABLE `ai_task`; - --- 3. 现有数据 -SELECT model_name, provider_type, provider_config -FROM `points_config` -WHERE `model_name` LIKE 'rh_sora2_%' OR model_name LIKE 'sora_%'; - --- 4. 错误信息截图 -``` - ---- - -**修复完成!** ✅ - -执行完修复脚本后,系统应该可以正常使用RunningHub功能了。 - - diff --git a/V5__add_provider_support.sql b/V5__add_provider_support.sql deleted file mode 100644 index e502653..0000000 --- a/V5__add_provider_support.sql +++ /dev/null @@ -1,82 +0,0 @@ --- ============================================================ --- V5: 添加多AI服务提供商支持 --- 描述: 支持接入多个AI服务提供商(OpenAI格式、等) --- 作者: 1818AI --- 日期: 2025-10-20 --- ============================================================ - --- 1. 扩展points_config表,添加服务商配置 -ALTER TABLE `points_config` -ADD COLUMN `provider_type` VARCHAR(50) NOT NULL DEFAULT 'openai' - COMMENT 'AI服务提供商类型:openai, ' AFTER `is_enabled`, -ADD COLUMN `provider_config` TEXT NULL - COMMENT '服务商特定配置(JSON格式)' AFTER `provider_type`; - --- 2. 扩展ai_task表,添加服务商相关字段 -ALTER TABLE `ai_task` -ADD COLUMN `provider_type` VARCHAR(50) NULL - COMMENT 'AI服务提供商类型' AFTER `task_type`, -ADD COLUMN `provider_task_id` VARCHAR(100) NULL - COMMENT '服务商返回的任务ID' AFTER `provider_type`, -ADD COLUMN `provider_response` TEXT NULL - COMMENT '服务商原始响应(JSON)' AFTER `provider_task_id`; - --- 3. 添加索引以优化查询性能 -CREATE INDEX `idx_provider_task_id` ON `ai_task`(`provider_task_id`); -CREATE INDEX `idx_provider_type_status` ON `ai_task`(`provider_type`, `status`); - --- 4. 更新现有数据,设置默认provider_type为openai -UPDATE `ai_task` SET `provider_type` = 'openai' WHERE `provider_type` IS NULL; -UPDATE `points_config` SET `provider_type` = 'openai' WHERE `provider_type` = 'openai'; - --- 5. 插入模型配置(文生视频 + 图生视频) -INSERT INTO `points_config` -(model_name, points_cost, description, is_enabled, provider_type, provider_config, create_time, update_time) -VALUES --- Sora2 文生视频(webappId: 1973555977595301890) -('rh_sora2_text_portrait', 160, ' Sora2 文生视频-竖屏(10秒)', 1, '', - '{"webappId":"1973555977595301890","taskType":"text2video","model":"portrait","duration":10}', NOW(), NOW()), - -('rh_sora2_text_landscape', 160, ' Sora2 文生视频-横屏(10秒)', 1, '', - '{"webappId":"1973555977595301890","taskType":"text2video","model":"landscape","duration":10}', NOW(), NOW()), - -('rh_sora2_text_portrait_hd', 420, ' Sora2 文生视频-高清竖屏(10秒)', 1, '', - '{"webappId":"1973555977595301890","taskType":"text2video","model":"portrait-hd","duration":10}', NOW(), NOW()), - -('rh_sora2_text_landscape_hd', 420, ' Sora2 文生视频-高清横屏(10秒)', 1, '', - '{"webappId":"1973555977595301890","taskType":"text2video","model":"landscape-hd","duration":10}', NOW(), NOW()), - --- Sora2 图生视频(webappId: 1973555366057390081) -('rh_sora2_img_portrait', 180, ' Sora2 图生视频-竖屏(10秒)', 1, '', - '{"webappId":"1973555366057390081","taskType":"image2video","model":"portrait","duration":10}', NOW(), NOW()), - -('rh_sora2_img_landscape', 180, ' Sora2 图生视频-横屏(10秒)', 1, '', - '{"webappId":"1973555366057390081","taskType":"image2video","model":"landscape","duration":10}', NOW(), NOW()), - -('rh_sora2_img_portrait_hd', 480, ' Sora2 图生视频-高清竖屏(10秒)', 1, '', - '{"webappId":"1973555366057390081","taskType":"image2video","model":"portrait-hd","duration":10}', NOW(), NOW()), - -('rh_sora2_img_landscape_hd', 480, ' Sora2 图生视频-高清横屏(10秒)', 1, '', - '{"webappId":"1973555366057390081","taskType":"image2video","model":"landscape-hd","duration":10}', NOW(), NOW()), - --- 15秒版本 -('rh_sora2_text_portrait_15s', 260, ' Sora2 文生视频-竖屏(15秒)', 1, '', - '{"webappId":"1973555977595301890","taskType":"text2video","model":"portrait","duration":15}', NOW(), NOW()), - -('rh_sora2_text_landscape_15s', 260, ' Sora2 文生视频-横屏(15秒)', 1, '', - '{"webappId":"1973555977595301890","taskType":"text2video","model":"landscape","duration":15}', NOW(), NOW()), - -('rh_sora2_img_portrait_15s', 280, ' Sora2 图生视频-竖屏(15秒)', 1, '', - '{"webappId":"1973555366057390081","taskType":"image2video","model":"portrait","duration":15}', NOW(), NOW()), - -('rh_sora2_img_landscape_15s', 280, ' Sora2 图生视频-横屏(15秒)', 1, '', - '{"webappId":"1973555366057390081","taskType":"image2video","model":"landscape","duration":15}', NOW(), NOW()) -ON DUPLICATE KEY UPDATE - description = VALUES(description), - provider_config = VALUES(provider_config); - --- 6. 记录迁移日志 -INSERT INTO `migration_log` (`version`, `description`, `executed_at`) -VALUES ('V5', '添加多AI服务提供商支持(OpenAI、)', NOW()) -ON DUPLICATE KEY UPDATE `executed_at` = NOW(); - diff --git a/V5__add_provider_support_CORRECTED.sql b/V5__add_provider_support_CORRECTED.sql deleted file mode 100644 index f6b7014..0000000 --- a/V5__add_provider_support_CORRECTED.sql +++ /dev/null @@ -1,89 +0,0 @@ --- ============================================================ --- V5: 添加多AI服务提供商支持(修正版) --- 描述: 支持接入多个AI服务提供商(OpenAI、RunningHub等) --- 作者: 1818AI --- 日期: 2025-10-20 --- ============================================================ - --- 1. 扩展points_config表,添加服务商配置 -ALTER TABLE `points_config` -ADD COLUMN IF NOT EXISTS `provider_type` VARCHAR(50) NOT NULL DEFAULT 'openai' - COMMENT 'AI服务提供商类型:openai, runninghub' AFTER `is_enabled`, -ADD COLUMN IF NOT EXISTS `provider_config` TEXT NULL - COMMENT '服务商特定配置(JSON格式)' AFTER `provider_type`; - --- 2. 扩展ai_task表,添加服务商相关字段 -ALTER TABLE `ai_task` -ADD COLUMN IF NOT EXISTS `provider_type` VARCHAR(50) NULL - COMMENT 'AI服务提供商类型' AFTER `task_type`, -ADD COLUMN IF NOT EXISTS `provider_task_id` VARCHAR(100) NULL - COMMENT '服务商返回的任务ID' AFTER `provider_type`, -ADD COLUMN IF NOT EXISTS `provider_response` TEXT NULL - COMMENT '服务商原始响应(JSON)' AFTER `provider_task_id`; - --- 3. 添加索引以优化查询性能(如果不存在) -CREATE INDEX IF NOT EXISTS `idx_provider_task_id` ON `ai_task`(`provider_task_id`); -CREATE INDEX IF NOT EXISTS `idx_provider_type_status` ON `ai_task`(`provider_type`, `status`); - --- 4. 更新现有数据,设置默认provider_type为openai -UPDATE `ai_task` SET `provider_type` = 'openai' WHERE `provider_type` IS NULL; - --- 5. 插入RunningHub模型配置(文生视频 + 图生视频) -INSERT INTO `points_config` -(model_name, points_cost, description, is_enabled, provider_type, provider_config, create_time, update_time) -VALUES --- RunningHub Sora2 文生视频(webappId: 1973555977595301890) -('rh_sora2_text_portrait', 160, 'RunningHub Sora2 文生视频-竖屏(10秒)', 1, 'runninghub', - '{"webappId":"1973555977595301890","taskType":"text2video","model":"portrait","duration":10}', NOW(), NOW()), - -('rh_sora2_text_landscape', 160, 'RunningHub Sora2 文生视频-横屏(10秒)', 1, 'runninghub', - '{"webappId":"1973555977595301890","taskType":"text2video","model":"landscape","duration":10}', NOW(), NOW()), - -('rh_sora2_text_portrait_hd', 420, 'RunningHub Sora2 文生视频-高清竖屏(10秒)', 1, 'runninghub', - '{"webappId":"1973555977595301890","taskType":"text2video","model":"portrait-hd","duration":10}', NOW(), NOW()), - -('rh_sora2_text_landscape_hd', 420, 'RunningHub Sora2 文生视频-高清横屏(10秒)', 1, 'runninghub', - '{"webappId":"1973555977595301890","taskType":"text2video","model":"landscape-hd","duration":10}', NOW(), NOW()), - --- RunningHub Sora2 图生视频(webappId: 1973555366057390081) -('rh_sora2_img_portrait', 180, 'RunningHub Sora2 图生视频-竖屏(10秒)', 1, 'runninghub', - '{"webappId":"1973555366057390081","taskType":"image2video","model":"portrait","duration":10}', NOW(), NOW()), - -('rh_sora2_img_landscape', 180, 'RunningHub Sora2 图生视频-横屏(10秒)', 1, 'runninghub', - '{"webappId":"1973555366057390081","taskType":"image2video","model":"landscape","duration":10}', NOW(), NOW()), - -('rh_sora2_img_portrait_hd', 480, 'RunningHub Sora2 图生视频-高清竖屏(10秒)', 1, 'runninghub', - '{"webappId":"1973555366057390081","taskType":"image2video","model":"portrait-hd","duration":10}', NOW(), NOW()), - -('rh_sora2_img_landscape_hd', 480, 'RunningHub Sora2 图生视频-高清横屏(10秒)', 1, 'runninghub', - '{"webappId":"1973555366057390081","taskType":"image2video","model":"landscape-hd","duration":10}', NOW(), NOW()), - --- 15秒版本 -('rh_sora2_text_portrait_15s', 260, 'RunningHub Sora2 文生视频-竖屏(15秒)', 1, 'runninghub', - '{"webappId":"1973555977595301890","taskType":"text2video","model":"portrait","duration":15}', NOW(), NOW()), - -('rh_sora2_text_landscape_15s', 260, 'RunningHub Sora2 文生视频-横屏(15秒)', 1, 'runninghub', - '{"webappId":"1973555977595301890","taskType":"text2video","model":"landscape","duration":15}', NOW(), NOW()), - -('rh_sora2_img_portrait_15s', 280, 'RunningHub Sora2 图生视频-竖屏(15秒)', 1, 'runninghub', - '{"webappId":"1973555366057390081","taskType":"image2video","model":"portrait","duration":15}', NOW(), NOW()), - -('rh_sora2_img_landscape_15s', 280, 'RunningHub Sora2 图生视频-横屏(15秒)', 1, 'runninghub', - '{"webappId":"1973555366057390081","taskType":"image2video","model":"landscape","duration":15}', NOW(), NOW()) -ON DUPLICATE KEY UPDATE - description = VALUES(description), - points_cost = VALUES(points_cost), - provider_type = VALUES(provider_type), - provider_config = VALUES(provider_config), - update_time = NOW(); - --- 6. 验证插入结果 -SELECT model_name, provider_type, points_cost, description -FROM `points_config` -WHERE `model_name` LIKE 'rh_sora2_%'; - --- 7. 记录迁移日志 -INSERT INTO `migration_log` (`version`, `description`, `executed_at`) -VALUES ('V5', '添加多AI服务提供商支持(OpenAI、RunningHub)', NOW()) -ON DUPLICATE KEY UPDATE `executed_at` = NOW(); - diff --git a/V6__add_points_recharge_system.sql b/V6__add_points_recharge_system.sql deleted file mode 100644 index 176836a..0000000 --- a/V6__add_points_recharge_system.sql +++ /dev/null @@ -1,174 +0,0 @@ --- ============================================================ --- V6: 添加积分充值系统 --- 描述: 支持用户直接购买积分(支付宝/微信支付) --- 作者: 1818AI --- 日期: 2025-10-21 --- ============================================================ - --- 1. 创建积分套餐表 -CREATE TABLE IF NOT EXISTS `points_package` ( - `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键', - `name` varchar(64) NOT NULL COMMENT '套餐名称', - `description` varchar(255) DEFAULT NULL COMMENT '套餐描述', - `points` int NOT NULL COMMENT '基础积分数量', - `bonus_points` int NOT NULL DEFAULT 0 COMMENT '赠送积分数量', - `total_points` int NOT NULL COMMENT '总积分(基础+赠送)', - `price` decimal(10,2) NOT NULL COMMENT '价格(元)', - `original_price` decimal(10,2) DEFAULT NULL COMMENT '原价(用于显示优惠)', - `points_expire_days` int NOT NULL DEFAULT 365 COMMENT '积分有效期(天)', - `discount_label` varchar(32) DEFAULT NULL COMMENT '优惠标签(如:首充特惠、限时优惠)', - `sort_order` int NOT NULL DEFAULT 0 COMMENT '排序(数字越小越靠前)', - `is_hot` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否热门推荐', - `is_active` tinyint(1) NOT NULL DEFAULT 1 COMMENT '是否上架', - `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', - `is_deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除标识', - PRIMARY KEY (`id`), - KEY `idx_points_package_active` (`is_active`), - KEY `idx_points_package_sort` (`sort_order`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='积分套餐表'; - --- 2. 扩展订单表,添加积分订单相关字段(使用IF NOT EXISTS避免重复) --- 检查并添加 order_type 字段 -SET @col_exists = ( - SELECT COUNT(*) - FROM INFORMATION_SCHEMA.COLUMNS - WHERE TABLE_SCHEMA = DATABASE() - AND TABLE_NAME = 'order' - AND COLUMN_NAME = 'order_type' -); - -SET @sql = IF(@col_exists = 0, - 'ALTER TABLE `order` ADD COLUMN `order_type` tinyint NOT NULL DEFAULT 1 COMMENT ''订单类型(1-会员订单/2-积分订单)'' AFTER `order_no`', - 'SELECT ''Column order_type already exists'' AS info' -); -PREPARE stmt FROM @sql; -EXECUTE stmt; -DEALLOCATE PREPARE stmt; - --- 检查并添加 points_package_id 字段 -SET @col_exists = ( - SELECT COUNT(*) - FROM INFORMATION_SCHEMA.COLUMNS - WHERE TABLE_SCHEMA = DATABASE() - AND TABLE_NAME = 'order' - AND COLUMN_NAME = 'points_package_id' -); - -SET @sql = IF(@col_exists = 0, - 'ALTER TABLE `order` ADD COLUMN `points_package_id` bigint DEFAULT NULL COMMENT ''积分套餐ID(积分订单)'' AFTER `plan_id`', - 'SELECT ''Column points_package_id already exists'' AS info' -); -PREPARE stmt FROM @sql; -EXECUTE stmt; -DEALLOCATE PREPARE stmt; - --- 检查并添加 points_amount 字段 -SET @col_exists = ( - SELECT COUNT(*) - FROM INFORMATION_SCHEMA.COLUMNS - WHERE TABLE_SCHEMA = DATABASE() - AND TABLE_NAME = 'order' - AND COLUMN_NAME = 'points_amount' -); - -SET @sql = IF(@col_exists = 0, - 'ALTER TABLE `order` ADD COLUMN `points_amount` int DEFAULT NULL COMMENT ''积分数量(积分订单)'' AFTER `points_package_id`', - 'SELECT ''Column points_amount already exists'' AS info' -); -PREPARE stmt FROM @sql; -EXECUTE stmt; -DEALLOCATE PREPARE stmt; - --- 添加索引(如果不存在) -SET @index_exists = ( - SELECT COUNT(*) - FROM INFORMATION_SCHEMA.STATISTICS - WHERE TABLE_SCHEMA = DATABASE() - AND TABLE_NAME = 'order' - AND INDEX_NAME = 'idx_order_type' -); - -SET @sql = IF(@index_exists = 0, - 'CREATE INDEX `idx_order_type` ON `order`(`order_type`)', - 'SELECT ''Index idx_order_type already exists'' AS info' -); -PREPARE stmt FROM @sql; -EXECUTE stmt; -DEALLOCATE PREPARE stmt; - -SET @index_exists = ( - SELECT COUNT(*) - FROM INFORMATION_SCHEMA.STATISTICS - WHERE TABLE_SCHEMA = DATABASE() - AND TABLE_NAME = 'order' - AND INDEX_NAME = 'idx_order_points_package' -); - -SET @sql = IF(@index_exists = 0, - 'CREATE INDEX `idx_order_points_package` ON `order`(`points_package_id`)', - 'SELECT ''Index idx_order_points_package already exists'' AS info' -); -PREPARE stmt FROM @sql; -EXECUTE stmt; -DEALLOCATE PREPARE stmt; - --- 3. 扩展积分消费记录表,支持充值类型 --- points_consumption_log 表已存在,只需确保支持 change_type='recharge' --- 修改注释以明确支持的类型 -ALTER TABLE `points_consumption_log` -MODIFY COLUMN `change_type` varchar(32) NOT NULL - COMMENT '变动类型 (recharge:充值, consume:消费, refund:退款, expire:过期, admin_adjust:管理员调整)'; - --- 4. 插入默认积分套餐数据 -INSERT INTO `points_package` -(name, description, points, bonus_points, total_points, price, original_price, points_expire_days, discount_label, sort_order, is_hot, is_active) -VALUES --- 基础套餐 -('体验包', '新手体验,小额充值', 100, 0, 100, 10.00, NULL, 365, NULL, 1, 0, 1), -('标准包', '日常使用推荐', 500, 50, 550, 48.00, 50.00, 365, '赠送50积分', 2, 1, 1), -('超值包', '性价比之选', 1000, 150, 1150, 88.00, 100.00, 365, '赠送150积分', 3, 1, 1), -('豪华包', '重度用户首选', 3000, 500, 3500, 258.00, 300.00, 365, '赠送500积分', 4, 0, 1), -('至尊包', '超值优惠', 5000, 1000, 6000, 398.00, 500.00, 365, '赠送1000积分', 5, 1, 1), -('旗舰包', '一次购买全年无忧', 10000, 3000, 13000, 688.00, 1000.00, 365, '赠送3000积分', 6, 0, 1) -ON DUPLICATE KEY UPDATE - description = VALUES(description), - points = VALUES(points), - bonus_points = VALUES(bonus_points), - total_points = VALUES(total_points), - price = VALUES(price), - original_price = VALUES(original_price), - update_time = NOW(); - --- 5. 初始化系统配置(积分充值相关) -INSERT INTO `system_config` (`config_key`, `config_value`, `description`) VALUES - ('points.recharge.min_amount', '10.00', '最低充值金额(元)'), - ('points.recharge.max_amount', '10000.00', '最高充值金额(元)'), - ('points.default_expire_days', '365', '默认积分有效期(天)'), - ('points.first_recharge_bonus', '0.1', '首次充值额外赠送比例(10%)') -ON DUPLICATE KEY UPDATE `config_value` = VALUES(`config_value`); - --- 6. 创建积分充值统计视图(便于管理员查看) -CREATE OR REPLACE VIEW `v_points_recharge_stats` AS -SELECT - DATE(o.create_time) as recharge_date, - COUNT(o.id) as order_count, - SUM(o.amount) as total_amount, - SUM(o.points_amount) as total_points, - AVG(o.amount) as avg_amount -FROM `order` o -WHERE o.order_type = 2 - AND o.status = 1 - AND o.is_deleted = 0 -GROUP BY DATE(o.create_time) -ORDER BY recharge_date DESC; - --- 7. 记录迁移日志 -INSERT INTO `migration_log` (`version`, `description`, `executed_at`) -VALUES ('V6', '添加积分充值系统(积分套餐、支付购买)', NOW()) -ON DUPLICATE KEY UPDATE `executed_at` = NOW(); - --- ============================================================ --- V6脚本结束 --- ============================================================ - diff --git a/V7__add_task_type_to_points_config.sql b/V7__add_task_type_to_points_config.sql deleted file mode 100644 index fe54750..0000000 --- a/V7__add_task_type_to_points_config.sql +++ /dev/null @@ -1,157 +0,0 @@ --- ================================================================= --- V7: 为 points_config 表添加 task_type 字段,支持更细致的任务类型分类 --- 时间: 2025-10-22 --- 描述: 添加任务类型字段,区分文生图、图生图、图生视频、文生视频等 --- ================================================================= - --- 指定数据库(请根据实际情况修改数据库名) -USE `1818_user_server`; - --- 1. 添加 task_type 字段(如果不存在) --- 检查字段是否存在,如果不存在则添加 -SET @col_exists = ( - SELECT COUNT(*) - FROM INFORMATION_SCHEMA.COLUMNS - WHERE TABLE_SCHEMA = DATABASE() - AND TABLE_NAME = 'points_config' - AND COLUMN_NAME = 'task_type' -); - -SET @sql = IF(@col_exists = 0, - 'ALTER TABLE `points_config` ADD COLUMN `task_type` VARCHAR(50) NULL COMMENT ''任务类型:text_to_image(文生图)/image_to_image(图生图)/text_to_video(文生视频)/image_to_video(图生视频)/llm(大语言模型)/text_to_audio(文生音频)/image_to_text(图生文)/other(其他)'' AFTER `provider_config`', - 'SELECT ''Column task_type already exists'' AS info' -); -PREPARE stmt FROM @sql; -EXECUTE stmt; -DEALLOCATE PREPARE stmt; - --- 2. 根据现有模型名称更新 task_type --- OpenAI 模型(文生图) -UPDATE `points_config` -SET `task_type` = 'text_to_image' -WHERE `model_name` IN ('sora_image', 'gpt-4o-image') - AND `task_type` IS NULL; - --- RunningHub Sora2 文生视频模型(竖屏/横屏,10秒/15秒) -UPDATE `points_config` -SET `task_type` = 'text_to_video' -WHERE `model_name` IN ( - 'sora_video2', -- 竖屏10秒 - 'sora_video2-landscape', -- 横屏10秒 - 'sora_video2-15s', -- 竖屏15秒 - 'sora_video2-landscape-15s', -- 横屏15秒 - 'rh_sora2_text_portrait', -- RunningHub 文生视频-竖屏 - 'rh_sora2_text_landscape', -- RunningHub 文生视频-横屏 - 'rh_sora2_text_portrait_hd', -- RunningHub 文生视频-高清竖屏 - 'rh_sora2_text_landscape_hd', -- RunningHub 文生视频-高清横屏 - 'rh_sora2_text_portrait_15s', -- RunningHub 文生视频-竖屏15秒 - 'rh_sora2_text_landscape_15s' -- RunningHub 文生视频-横屏15秒 -) AND `task_type` IS NULL; - --- RunningHub Sora2 图生视频模型 -UPDATE `points_config` -SET `task_type` = 'image_to_video' -WHERE `model_name` IN ( - 'rh_sora2_img_portrait', -- RunningHub 图生视频-竖屏 - 'rh_sora2_img_landscape', -- RunningHub 图生视频-横屏 - 'rh_sora2_img_portrait_hd', -- RunningHub 图生视频-高清竖屏 - 'rh_sora2_img_landscape_hd', -- RunningHub 图生视频-高清横屏 - 'rh_sora2_img_portrait_15s', -- RunningHub 图生视频-竖屏15秒 - 'rh_sora2_img_landscape_15s' -- RunningHub 图生视频-横屏15秒 -) AND `task_type` IS NULL; - --- RunningHub Sora Pro 高清视频 -UPDATE `points_config` -SET `task_type` = 'text_to_video' -WHERE `model_name` = 'sora-2-pro-all' - AND `task_type` IS NULL; - --- 3. 添加新的模型配置示例(可选) --- 如果需要添加更多模型类型,可以在这里插入 - --- 文生图模型示例 -INSERT INTO `points_config` (`model_name`, `points_cost`, `description`, `is_enabled`, `provider_type`, `task_type`) VALUES - ('dall-e-3', 15, 'DALL-E 3 高质量图片生成', 0, 'openai', 'text_to_image'), - ('midjourney-v6', 20, 'Midjourney V6 艺术图片生成', 0, 'midjourney', 'text_to_image'), - ('rh_dalle-3', 12, 'RunningHub DALL-E 3 图片生成', 1, 'runninghub', 'text_to_image'), - ('rh_midjourney', 18, 'RunningHub Midjourney 图片生成', 1, 'runninghub', 'text_to_image') -ON DUPLICATE KEY UPDATE - `task_type` = VALUES(`task_type`), - `description` = VALUES(`description`); - --- 图生图模型示例 -INSERT INTO `points_config` (`model_name`, `points_cost`, `description`, `is_enabled`, `provider_type`, `task_type`) VALUES - ('stable-diffusion-img2img', 12, 'Stable Diffusion 图片转换', 0, 'stability', 'image_to_image') -ON DUPLICATE KEY UPDATE - `task_type` = VALUES(`task_type`), - `description` = VALUES(`description`); - --- LLM大语言模型示例 -INSERT INTO `points_config` (`model_name`, `points_cost`, `description`, `is_enabled`, `provider_type`, `task_type`) VALUES - ('gpt-4-turbo', 5, 'GPT-4 Turbo 对话模型', 0, 'openai', 'llm'), - ('claude-3-opus', 6, 'Claude 3 Opus 对话模型', 0, 'anthropic', 'llm'), - ('gemini-pro', 4, 'Google Gemini Pro 对话模型', 0, 'google', 'llm') -ON DUPLICATE KEY UPDATE - `task_type` = VALUES(`task_type`), - `description` = VALUES(`description`); - --- 文生音频模型示例 -INSERT INTO `points_config` (`model_name`, `points_cost`, `description`, `is_enabled`, `provider_type`, `task_type`) VALUES - ('tts-1', 3, 'OpenAI TTS 语音合成', 0, 'openai', 'text_to_audio'), - ('elevenlabs-tts', 4, 'ElevenLabs 高质量语音合成', 0, 'elevenlabs', 'text_to_audio') -ON DUPLICATE KEY UPDATE - `task_type` = VALUES(`task_type`), - `description` = VALUES(`description`); - --- 图生文模型示例 -INSERT INTO `points_config` (`model_name`, `points_cost`, `description`, `is_enabled`, `provider_type`, `task_type`) VALUES - ('gpt-4-vision', 8, 'GPT-4 Vision 图片理解', 0, 'openai', 'image_to_text'), - ('claude-3-vision', 7, 'Claude 3 图片分析', 0, 'anthropic', 'image_to_text') -ON DUPLICATE KEY UPDATE - `task_type` = VALUES(`task_type`), - `description` = VALUES(`description`); - --- 4. 为未分类的模型设置默认类型 -UPDATE `points_config` -SET `task_type` = 'other' -WHERE `task_type` IS NULL; - --- 5. 添加索引以提升查询性能(如果不存在) --- 检查并添加 task_type 索引 -SET @index_exists = ( - SELECT COUNT(*) - FROM INFORMATION_SCHEMA.STATISTICS - WHERE TABLE_SCHEMA = DATABASE() - AND TABLE_NAME = 'points_config' - AND INDEX_NAME = 'idx_points_config_task_type' -); - -SET @sql = IF(@index_exists = 0, - 'CREATE INDEX `idx_points_config_task_type` ON `points_config`(`task_type`)', - 'SELECT ''Index idx_points_config_task_type already exists'' AS info' -); -PREPARE stmt FROM @sql; -EXECUTE stmt; -DEALLOCATE PREPARE stmt; - --- 检查并添加复合索引 -SET @index_exists = ( - SELECT COUNT(*) - FROM INFORMATION_SCHEMA.STATISTICS - WHERE TABLE_SCHEMA = DATABASE() - AND TABLE_NAME = 'points_config' - AND INDEX_NAME = 'idx_points_config_provider_task' -); - -SET @sql = IF(@index_exists = 0, - 'CREATE INDEX `idx_points_config_provider_task` ON `points_config`(`provider_type`, `task_type`)', - 'SELECT ''Index idx_points_config_provider_task already exists'' AS info' -); -PREPARE stmt FROM @sql; -EXECUTE stmt; -DEALLOCATE PREPARE stmt; - --- ================================================================= --- V7脚本结束 --- ================================================================= - diff --git a/V8__add_suchuang_models.sql b/V8__add_suchuang_models.sql deleted file mode 100644 index a50b8a8..0000000 --- a/V8__add_suchuang_models.sql +++ /dev/null @@ -1,106 +0,0 @@ --- ============================================================ --- V8: 添加速创API(SuChuang)的Sora2模型配置 --- 描述: 速创API只有一个Sora2接口,通过参数区分不同功能 --- 作者: 1818AI --- 日期: 2025-10-23 --- ============================================================ - -USE `1818ai`; - --- 插入速创Sora2模型配置 --- 速创不区分具体模型,通过参数控制:aspectRatio, duration, size, url(图生视频时) - --- 文生视频模型(8个) --- 9:16 竖屏 -INSERT INTO `points_config` (`model_name`, `description`, `points_cost`, `provider_type`, `provider_config`, `task_type`, `is_enabled`, `create_time`, `update_time`) -VALUES -('sc_sora2_text_portrait_10s_small', '速创Sora2 文生视频-竖屏-10秒-标清', 80, 'suchuang', - '{"aspectRatio":"9:16","duration":"10","size":"small"}', - 'text_to_video', 1, NOW(), NOW()), - -('sc_sora2_text_portrait_10s_large', '速创Sora2 文生视频-竖屏-10秒-高清', 200, 'suchuang', - '{"aspectRatio":"9:16","duration":"10","size":"large"}', - 'text_to_video', 1, NOW(), NOW()), - -('sc_sora2_text_portrait_15s_small', '速创Sora2 文生视频-竖屏-15秒-标清', 130, 'suchuang', - '{"aspectRatio":"9:16","duration":"15","size":"small"}', - 'text_to_video', 1, NOW(), NOW()), - -('sc_sora2_text_portrait_15s_large', '速创Sora2 文生视频-竖屏-15秒-高清', 320, 'suchuang', - '{"aspectRatio":"9:16","duration":"15","size":"large"}', - 'text_to_video', 1, NOW(), NOW()); - --- 16:9 横屏 -INSERT INTO `points_config` (`model_name`, `description`, `points_cost`, `provider_type`, `provider_config`, `task_type`, `is_enabled`, `create_time`, `update_time`) -VALUES -('sc_sora2_text_landscape_10s_small', '速创Sora2 文生视频-横屏-10秒-标清', 80, 'suchuang', - '{"aspectRatio":"16:9","duration":"10","size":"small"}', - 'text_to_video', 1, NOW(), NOW()), - -('sc_sora2_text_landscape_10s_large', '速创Sora2 文生视频-横屏-10秒-高清', 200, 'suchuang', - '{"aspectRatio":"16:9","duration":"10","size":"large"}', - 'text_to_video', 1, NOW(), NOW()), - -('sc_sora2_text_landscape_15s_small', '速创Sora2 文生视频-横屏-15秒-标清', 130, 'suchuang', - '{"aspectRatio":"16:9","duration":"15","size":"small"}', - 'text_to_video', 1, NOW(), NOW()), - -('sc_sora2_text_landscape_15s_large', '速创Sora2 文生视频-横屏-15秒-高清', 320, 'suchuang', - '{"aspectRatio":"16:9","duration":"15","size":"large"}', - 'text_to_video', 1, NOW(), NOW()); - --- 图生视频模型(8个) --- 9:16 竖屏 -INSERT INTO `points_config` (`model_name`, `description`, `points_cost`, `provider_type`, `provider_config`, `task_type`, `is_enabled`, `create_time`, `update_time`) -VALUES -('sc_sora2_img_portrait_10s_small', '速创Sora2 图生视频-竖屏-10秒-标清', 90, 'suchuang', - '{"aspectRatio":"9:16","duration":"10","size":"small","requireImage":true}', - 'image_to_video', 1, NOW(), NOW()), - -('sc_sora2_img_portrait_10s_large', '速创Sora2 图生视频-竖屏-10秒-高清', 240, 'suchuang', - '{"aspectRatio":"9:16","duration":"10","size":"large","requireImage":true}', - 'image_to_video', 1, NOW(), NOW()), - -('sc_sora2_img_portrait_15s_small', '速创Sora2 图生视频-竖屏-15秒-标清', 140, 'suchuang', - '{"aspectRatio":"9:16","duration":"15","size":"small","requireImage":true}', - 'image_to_video', 1, NOW(), NOW()), - -('sc_sora2_img_portrait_15s_large', '速创Sora2 图生视频-竖屏-15秒-高清', 360, 'suchuang', - '{"aspectRatio":"9:16","duration":"15","size":"large","requireImage":true}', - 'image_to_video', 1, NOW(), NOW()); - --- 16:9 横屏 -INSERT INTO `points_config` (`model_name`, `description`, `points_cost`, `provider_type`, `provider_config`, `task_type`, `is_enabled`, `create_time`, `update_time`) -VALUES -('sc_sora2_img_landscape_10s_small', '速创Sora2 图生视频-横屏-10秒-标清', 90, 'suchuang', - '{"aspectRatio":"16:9","duration":"10","size":"small","requireImage":true}', - 'image_to_video', 1, NOW(), NOW()), - -('sc_sora2_img_landscape_10s_large', '速创Sora2 图生视频-横屏-10秒-高清', 240, 'suchuang', - '{"aspectRatio":"16:9","duration":"10","size":"large","requireImage":true}', - 'image_to_video', 1, NOW(), NOW()), - -('sc_sora2_img_landscape_15s_small', '速创Sora2 图生视频-横屏-15秒-标清', 140, 'suchuang', - '{"aspectRatio":"16:9","duration":"15","size":"small","requireImage":true}', - 'image_to_video', 1, NOW(), NOW()), - -('sc_sora2_img_landscape_15s_large', '速创Sora2 图生视频-横屏-15秒-高清', 360, 'suchuang', - '{"aspectRatio":"16:9","duration":"15","size":"large","requireImage":true}', - 'image_to_video', 1, NOW(), NOW()); - --- 验证插入的模型 -SELECT - model_name, - description, - points_cost, - provider_type, - task_type, - is_enabled -FROM points_config -WHERE provider_type = 'suchuang' -ORDER BY task_type, model_name; - --- ============================================================ --- V8脚本结束 --- ============================================================ - diff --git a/V9__add_suchuang_image_models.sql b/V9__add_suchuang_image_models.sql deleted file mode 100644 index b03e35c..0000000 --- a/V9__add_suchuang_image_models.sql +++ /dev/null @@ -1,128 +0,0 @@ --- ============================================================ --- V9: 添加速创API(SuChuang)的生图模型配置(img/draw) --- 描述: 速创生图接口,支持文生图和图生图,通过size参数控制输出比例 --- 作者: 1818AI --- 日期: 2025-10-26 --- ============================================================ - -USE `1818ai`; - --- 插入速创生图模型配置 --- 速创生图使用 /api/img/draw 接口,通过参数控制: --- - model: "sora-image" (固定) --- - size: "auto" | "1:1" | "2:3" | "3:2" --- - img_url: 可选,用于图生图 - --- ============================================================ --- 文生图模型(text_to_image)- 4个比例 --- ============================================================ - -INSERT INTO `points_config` (`model_name`, `description`, `points_cost`, `provider_type`, `provider_config`, `task_type`, `is_enabled`, `create_time`, `update_time`) -VALUES --- 自动比例 -('sc_soraimg_text_auto', '速创生图 文生图-自动比例', 30, 'suchuang', - '{"aspectRatio":"auto","imgSize":"auto"}', - 'text_to_image', 1, NOW(), NOW()), - --- 1:1 正方形 -('sc_soraimg_text_1x1', '速创生图 文生图-正方形(1:1)', 30, 'suchuang', - '{"aspectRatio":"1:1","imgSize":"1:1"}', - 'text_to_image', 1, NOW(), NOW()), - --- 2:3 竖图 -('sc_soraimg_text_2x3', '速创生图 文生图-竖图(2:3)', 30, 'suchuang', - '{"aspectRatio":"2:3","imgSize":"2:3"}', - 'text_to_image', 1, NOW(), NOW()), - --- 3:2 横图 -('sc_soraimg_text_3x2', '速创生图 文生图-横图(3:2)', 30, 'suchuang', - '{"aspectRatio":"3:2","imgSize":"3:2"}', - 'text_to_image', 1, NOW(), NOW()); - --- ============================================================ --- 图生图模型(image_to_image)- 4个比例,需要参考图 --- ============================================================ - -INSERT INTO `points_config` (`model_name`, `description`, `points_cost`, `provider_type`, `provider_config`, `task_type`, `is_enabled`, `create_time`, `update_time`) -VALUES --- 自动比例 -('sc_soraimg_img2img_auto', '速创生图 图生图-自动比例', 35, 'suchuang', - '{"aspectRatio":"auto","imgSize":"auto","requireImage":true}', - 'image_to_image', 1, NOW(), NOW()), - --- 1:1 正方形 -('sc_soraimg_img2img_1x1', '速创生图 图生图-正方形(1:1)', 35, 'suchuang', - '{"aspectRatio":"1:1","imgSize":"1:1","requireImage":true}', - 'image_to_image', 1, NOW(), NOW()), - --- 2:3 竖图 -('sc_soraimg_img2img_2x3', '速创生图 图生图-竖图(2:3)', 35, 'suchuang', - '{"aspectRatio":"2:3","imgSize":"2:3","requireImage":true}', - 'image_to_image', 1, NOW(), NOW()), - --- 3:2 横图 -('sc_soraimg_img2img_3x2', '速创生图 图生图-横图(3:2)', 35, 'suchuang', - '{"aspectRatio":"3:2","imgSize":"3:2","requireImage":true}', - 'image_to_image', 1, NOW(), NOW()); - --- ============================================================ --- 兼容旧版本:添加 sora-image 通用模型(自动比例) --- ============================================================ - -INSERT INTO `points_config` (`model_name`, `description`, `points_cost`, `provider_type`, `provider_config`, `task_type`, `is_enabled`, `create_time`, `update_time`) -VALUES -('sora-image', '速创生图 通用模型(兼容)', 30, 'suchuang', - '{"aspectRatio":"auto","imgSize":"auto"}', - 'text_to_image', 1, NOW(), NOW()) -ON DUPLICATE KEY UPDATE - `provider_type` = VALUES(`provider_type`), - `provider_config` = VALUES(`provider_config`), - `task_type` = VALUES(`task_type`), - `description` = VALUES(`description`), - `update_time` = NOW(); - --- ============================================================ --- 验证插入的生图模型 --- ============================================================ - -SELECT - model_name, - description, - points_cost, - provider_type, - task_type, - provider_config, - is_enabled -FROM points_config -WHERE provider_type = 'suchuang' AND task_type IN ('text_to_image', 'image_to_image') -ORDER BY task_type, model_name; - --- ============================================================ --- 使用说明 --- ============================================================ --- --- 文生图示例: --- { --- "modelName": "sc_soraimg_text_1x1", --- "taskType": "text_to_image", --- "prompt": "一个可爱的卡通猫咪", --- "aspectRatio": "1:1" // 可选,会从provider_config读取 --- } --- --- 图生图示例: --- { --- "modelName": "sc_soraimg_img2img_1x1", --- "taskType": "image_to_image", --- "prompt": "把我的图片转化为卡通风格", --- "imageUrl": "https://example.com/image.jpg", --- "aspectRatio": "1:1" // 可选,会从provider_config读取 --- } --- --- img_url 参数支持: --- - 单个字符串: "https://example.com/image.jpg" --- - JSON数组字符串: "[\"https://a.jpg\",\"https://b.jpg\"]" --- --- ============================================================ --- V9脚本结束 --- ============================================================ - diff --git a/WECHAT_PAY_INTEGRATION.md b/WECHAT_PAY_INTEGRATION.md deleted file mode 100644 index 7052ab1..0000000 --- a/WECHAT_PAY_INTEGRATION.md +++ /dev/null @@ -1,480 +0,0 @@ -# 微信支付积分充值集成完成 - -## ✅ 真实微信支付已集成 - -### 实现概览 - -本系统已完整集成真实的微信支付功能,用户可以通过微信支付直接购买积分。 - ---- - -## 🔧 核心实现 - -### 1. 支付下单流程 - -**文件**:`PointsRechargeServiceImpl.java` - -```java -// 真实调用微信支付SDK -PayProduct payProduct = payFactory.init(PayType.WX_V2); - -PayReqVO payReqVO = new PayReqVO(); -payReqVO.setAmounts(order.getAmount()); -payReqVO.setOrderNo(order.getOrderNo()); -payReqVO.setDescription("积分充值 - " + order.getPointsAmount() + "积分"); -payReqVO.setTradeType(request.getTradeType()); // JSAPI/APP -payReqVO.setOpenid(request.getOpenid()); // 用户OpenID -payReqVO.setNotifyUrl(wechatNotifyUrl); // 回调URL - -Map result = payProduct.placeOrder(payReqVO); -``` - -**特点**: -- ✅ 使用现有的微信支付SDK(PayFactory) -- ✅ 支持小程序支付(JSAPI)和APP支付 -- ✅ 自动计算订单金额 -- ✅ 动态生成支付参数 - ---- - -### 2. 支付回调处理 - -**文件**:`PaymentCallbackController.java` - -```java -@RequestMapping("/wechat") -public String wechatCallback(HttpServletRequest request) { - // 1. 验证签名 - boolean signValid = servletAdapter.verifyWxPayCallback(requestMap, mchKey); - - // 2. 查询订单类型 - Order order = orderMapper.selectByOrderNo(orderNo); - - // 3. 根据订单类型处理 - if (order.getOrderType() == 2) { - // 积分订单 - 调用积分充值服务 - pointsRechargeService.handleRechargePaymentSuccess(orderNo); - } else { - // 会员订单 - 调用会员服务 - // ... - } - - return convertMapToXml(createSuccessResponse()); -} -``` - -**特点**: -- ✅ 复用现有的签名验证逻辑 -- ✅ 自动识别订单类型(会员/积分) -- ✅ 金额验证(防篡改) -- ✅ 防重复处理 - ---- - -### 3. 积分到账逻辑 - -**文件**:`PointsRechargeServiceImpl.handleRechargePaymentSuccess()` - -```java -public void handleRechargePaymentSuccess(String orderNo) { - // 1. 查询订单 - Order order = orderMapper.selectByOrderNo(orderNo); - - // 2. 防重复处理 - if (order.getStatus() != 0) { - return; // 已处理过 - } - - // 3. 更新用户积分 - user.setPoints(newPoints); - user.setPointsExpiresAt(newPointsExpiresAt); - userMapper.updateById(user); - - // 4. 记录积分变动日志 - pointsConsumptionLogMapper.insert(log); - - // 5. 更新订单状态 - orderMapper.updateById(order); -} -``` - ---- - -## 📦 API接口 - -### 创建充值订单 - -**接口**:`POST /user/points/recharge` - -**请求示例**: -```json -{ - "packageId": 2, - "paymentMethod": 2, - "openid": "o6_bmjrPTlm6_2sgVt7hMZOPfL2M", - "tradeType": "JSAPI" -} -``` - -**参数说明**: -- `packageId`:套餐ID(必填) -- `paymentMethod`:支付方式,固定为 `2`(微信支付) -- `openid`:微信用户OpenID(必填,JSAPI支付) -- `tradeType`:交易类型 - - `JSAPI`:小程序支付(默认) - - `APP`:APP支付 - -**响应示例**: -```json -{ - "code": 200, - "data": { - "orderNo": "ORD20251021123456", - "amount": 48.00, - "pointsAmount": 605, - "paymentMethod": 2, - "paymentParams": "{\"appId\":\"wx123...\",\"timeStamp\":\"1634567890\",\"nonceStr\":\"abc123\",\"package\":\"prepay_id=wx20211021...\",\"signType\":\"RSA\",\"paySign\":\"...\"}" - } -} -``` - -**前端调起支付**: -```javascript -const params = JSON.parse(response.data.paymentParams); - -wx.requestPayment({ - timeStamp: params.timeStamp, - nonceStr: params.nonceStr, - package: params.package, - signType: params.signType, - paySign: params.paySign, - success: function(res) { - console.log('支付成功'); - }, - fail: function(err) { - console.log('支付失败', err); - } -}); -``` - ---- - -### 支付回调 - -**接口**:`POST /payment/callback/wechat` - -**处理流程**: -1. 接收微信服务器通知 -2. 验证签名 -3. 解析回调参数 -4. 验证订单金额 -5. 识别订单类型 -6. 处理积分充值 -7. 返回成功响应 - -**回调URL配置**: -```yaml -# application.yml -wx2: - notifyUrl: https://yourdomain.com/payment/callback/wechat - mchKey: your_mch_key_here -``` - ---- - -## 🔄 完整业务流程 - -``` -用户选择套餐 - ↓ -【前端】获取用户openid - ↓ -【前端】调用充值接口 /user/points/recharge - ↓ -【后端】创建订单(order_type=2) - ↓ -【后端】调用微信支付下单API - ↓ -【后端】返回支付参数给前端 - ↓ -【前端】调起微信支付 wx.requestPayment() - ↓ -【用户】完成微信支付 - ↓ -【微信】异步回调 /payment/callback/wechat - ↓ -【后端】验证签名 ✓ - ↓ -【后端】验证金额 ✓ - ↓ -【后端】识别订单类型 → 积分订单 - ↓ -【后端】增加用户积分 - ↓ -【后端】更新订单状态 → 已完成 - ↓ -【后端】记录积分变动日志 - ↓ -【后端】返回SUCCESS给微信 - ↓ -【前端】查询充值结果 ✓ -``` - ---- - -## 🧪 测试步骤 - -### 1. 小程序端测试 - -```javascript -// 1. 获取用户openid -wx.login({ - success: (res) => { - // 调用后端接口换取openid - fetch('/user/auth/wechat-login', { - method: 'POST', - body: JSON.stringify({ code: res.code }) - }).then(response => { - const openid = response.data.openid; - // 保存openid用于支付 - }); - } -}); - -// 2. 创建充值订单 -fetch('/user/points/recharge', { - method: 'POST', - headers: { - 'Authorization': 'Bearer ' + token, - 'Content-Type': 'application/json' - }, - body: JSON.stringify({ - packageId: 2, - paymentMethod: 2, - openid: openid, - tradeType: 'JSAPI' - }) -}).then(response => { - if (response.code === 200) { - const params = JSON.parse(response.data.paymentParams); - - // 3. 调起支付 - wx.requestPayment({ - ...params, - success: () => { - wx.showToast({ title: '充值成功' }); - // 刷新积分余额 - }, - fail: (err) => { - console.error('支付失败', err); - } - }); - } -}); -``` - ---- - -### 2. 开发测试(模拟回调) - -```bash -# 使用测试回调接口 -curl -X POST "http://localhost:8080/payment/callback/test?orderNo=ORD20251021123456" - -# 查看用户积分 -curl -X GET "http://localhost:8080/user/info" \ - -H "Authorization: Bearer YOUR_TOKEN" - -# 查看充值记录 -curl -X GET "http://localhost:8080/user/points/recharge/records?page=1&size=10" \ - -H "Authorization: Bearer YOUR_TOKEN" -``` - ---- - -## ⚙️ 配置说明 - -### application.yml 配置 - -```yaml -# 微信支付配置 -wx2: - appid: wx1234567890abcdef # 小程序AppID - mchId: 1234567890 # 商户号 - mchKey: your_mch_key_32_chars # 商户密钥(32位) - notifyUrl: https://yourdomain.com/payment/callback/wechat # 回调URL - certPath: /path/to/apiclient_cert.p12 # 证书路径(退款用) -``` - -**注意事项**: -1. `notifyUrl` 必须是外网可访问的HTTPS地址 -2. 回调URL需要在微信商户平台配置白名单 -3. 本地开发可以使用内网穿透工具(如ngrok) - ---- - -## 🔐 安全机制 - -### 1. 签名验证 -- ✅ 使用 `ServletAdapter.verifyWxPayCallback()` 验证签名 -- ✅ 防止回调参数被篡改 - -### 2. 金额验证 -```java -BigDecimal paidAmount = new BigDecimal(totalFee).divide(new BigDecimal("100")); -if (order.getAmount().compareTo(paidAmount) != 0) { - return createFailResponse("金额不匹配"); -} -``` - -### 3. 防重复处理 -```java -if (order.getStatus() != 0) { - log.warn("订单已处理过"); - return; // 直接返回,不重复充值 -} -``` - -### 4. 事务保证 -```java -@Transactional(rollbackFor = Exception.class) -public void handleRechargePaymentSuccess(String orderNo) { - // 所有数据库操作在同一事务中 - // 要么全部成功,要么全部回滚 -} -``` - ---- - -## 📊 数据库设计 - -### 订单表扩展 - -```sql -ALTER TABLE `order` -ADD COLUMN `order_type` tinyint DEFAULT 1 COMMENT '1-会员/2-积分', -ADD COLUMN `points_package_id` bigint COMMENT '积分套餐ID', -ADD COLUMN `points_amount` int COMMENT '积分数量'; -``` - -**订单类型识别**: -- `order_type = 1`:会员订单 -- `order_type = 2`:积分订单 - ---- - -## ❓ 常见问题 - -### Q1: 如何获取用户的openid? - -**小程序端**: -```javascript -wx.login({ - success: (res) => { - // 将code发送到后端 - fetch('/user/auth/wechat-login', { - method: 'POST', - body: JSON.stringify({ code: res.code }) - }).then(response => { - const openid = response.data.openid; - // 使用openid创建支付订单 - }); - } -}); -``` - -**后端处理**: -```java -// TODO: 需要实现微信登录接口 -@PostMapping("/user/auth/wechat-login") -public Result> wechatLogin(@RequestBody Map params) { - String code = params.get("code"); - // 调用微信API换取openid - String openid = wechatService.getOpenid(code); - return Result.success(Map.of("openid", openid)); -} -``` - ---- - -### Q2: 支付失败如何处理? - -**系统自动处理**: -- 订单状态自动更新为 `3`(支付失败) -- 用户可以重新发起支付 - -**查看失败订单**: -```sql -SELECT * FROM `order` -WHERE user_id = ? - AND order_type = 2 - AND status = 3 -ORDER BY create_time DESC; -``` - ---- - -### Q3: 如何测试回调? - -**方法1:使用测试回调接口** -```bash -curl -X POST "http://localhost:8080/payment/callback/test?orderNo=ORD123" -``` - -**方法2:使用微信支付沙箱环境** -- 申请沙箱密钥 -- 配置沙箱参数 -- 使用沙箱专用AppID测试 - -**方法3:使用内网穿透** -```bash -# 使用ngrok暴露本地服务 -ngrok http 8080 - -# 配置回调URL -wx2.notifyUrl: https://abc123.ngrok.io/payment/callback/wechat -``` - ---- - -### Q4: 生产环境部署checklist - -- [ ] 配置真实的微信商户号和密钥 -- [ ] 配置HTTPS回调URL -- [ ] 在微信商户平台配置回调URL白名单 -- [ ] 上传支付证书(用于退款) -- [ ] 小额测试(¥0.01) -- [ ] 验证积分到账 -- [ ] 验证首充奖励 -- [ ] 监控日志配置 - ---- - -## 🎯 总结 - -### ✅ 已实现 -1. **真实微信支付下单** - 调用PayFactory SDK -2. **支付参数生成** - 返回给前端调起支付 -3. **支付回调处理** - 验证签名、金额、订单类型 -4. **积分自动到账** - 事务保证数据一致性 -5. **首充奖励** - 自动识别并赠送10% -6. **防重复处理** - 订单状态检查 -7. **完整日志** - 所有关键步骤都有日志记录 - -### 🔧 技术栈 -- 微信支付SDK:PayFactory + PayProduct -- 签名验证:ServletAdapter.verifyWxPayCallback() -- 订单管理:OrderMapper -- 积分管理:PointsRechargeService -- 事务管理:Spring @Transactional - -### 📝 关键文件 -1. `PointsRechargeServiceImpl.java` - 支付下单 -2. `PaymentCallbackController.java` - 支付回调 -3. `PointsRechargeDto.java` - API DTO -4. `V6__add_points_recharge_system.sql` - 数据库迁移 - ---- - -**系统已完全对接真实微信支付,可以直接上线使用!** 🎉 - diff --git a/WebSocket任务通知接收示例.md b/WebSocket任务通知接收示例.md deleted file mode 100644 index d9a1b5e..0000000 --- a/WebSocket任务通知接收示例.md +++ /dev/null @@ -1,789 +0,0 @@ -# WebSocket 任务通知接收示例 - -## 一、WebSocket 配置说明 - -### 后端配置 -- **连接端点**: `/user/websocket`(支持 SockJS 备用方案) -- **用户前缀**: `/user` -- **订阅目的地**: `/user/queue/tasks-progress` -- **协议**: STOMP over WebSocket - -### 消息格式(TaskProgressDto) -```typescript -interface TaskProgressDto { - taskNo: string; // 任务编号 - status: string; // 任务状态: created/queued/processing/completed/failed - progress: number; // 进度百分比 0-100 - message: string; // 进度消息 - resultUrl?: string; // 结果URL(完成时) - errorMessage?: string; // 错误信息(失败时) -} -``` - ---- - -## 二、前端依赖安装 - -### 使用 npm -```bash -npm install @stomp/stompjs sockjs-client -``` - -### 使用 yarn -```bash -yarn add @stomp/stompjs sockjs-client -``` - -### CDN 引入(HTML) -```html - - -``` - ---- - -## 三、基础连接示例 - -### 1. 原生 JavaScript + STOMP.js - -```javascript -// 引入依赖(如果使用模块化) -import SockJS from 'sockjs-client'; -import { Client } from '@stomp/stompjs'; - -// WebSocket 配置 -const WEBSOCKET_URL = 'http://localhost:8081/ws'; -const AUTH_TOKEN = 'YOUR_JWT_TOKEN'; - -// 创建 STOMP 客户端 -const stompClient = new Client({ - // 使用 SockJS 作为 WebSocket 实现 - webSocketFactory: () => new SockJS(WEBSOCKET_URL), - - // 连接头(携带认证信息) - connectHeaders: { - Authorization: `Bearer ${AUTH_TOKEN}` - }, - - // 连接成功回调 - onConnect: (frame) => { - console.log('WebSocket 连接成功:', frame); - - // 订阅任务进度更新 - stompClient.subscribe('/user/queue/tasks-progress', (message) => { - const notification = JSON.parse(message.body); - console.log('收到任务通知:', notification); - - // 处理通知 - handleTaskNotification(notification); - }); - }, - - // 连接失败回调 - onStompError: (frame) => { - console.error('STOMP 错误:', frame); - }, - - // WebSocket 错误回调 - onWebSocketError: (error) => { - console.error('WebSocket 错误:', error); - }, - - // WebSocket 关闭回调 - onWebSocketClose: (event) => { - console.log('WebSocket 连接关闭:', event); - }, - - // 自动重连配置 - reconnectDelay: 5000, // 5秒后重连 - heartbeatIncoming: 4000, - heartbeatOutgoing: 4000 -}); - -// 激活连接 -stompClient.activate(); - -// 处理任务通知 -function handleTaskNotification(notification) { - const { taskNo, status, progress, message, resultUrl, errorMessage } = notification; - - switch(status) { - case 'created': - console.log(`[${taskNo}] 任务已创建`); - break; - case 'queued': - console.log(`[${taskNo}] 任务排队中: ${message}`); - break; - case 'processing': - console.log(`[${taskNo}] 处理中 ${progress}%: ${message}`); - updateProgressBar(taskNo, progress); - break; - case 'completed': - console.log(`[${taskNo}] 任务完成: ${resultUrl}`); - showCompletedNotification(taskNo, resultUrl); - break; - case 'failed': - console.error(`[${taskNo}] 任务失败: ${errorMessage || message}`); - showErrorNotification(taskNo, errorMessage || message); - break; - } -} - -// 断开连接 -function disconnect() { - if (stompClient.connected) { - stompClient.deactivate(); - console.log('WebSocket 已断开'); - } -} -``` - ---- - -## 四、完整封装类(推荐) - -### TaskWebSocketClient.js - -```javascript -import SockJS from 'sockjs-client'; -import { Client } from '@stomp/stompjs'; - -class TaskWebSocketClient { - constructor(baseUrl = 'http://localhost:8081', token) { - this.baseUrl = baseUrl; - this.token = token; - this.client = null; - this.listeners = { - onTaskUpdate: [], - onConnect: [], - onDisconnect: [], - onError: [] - }; - } - - /** - * 连接 WebSocket - */ - connect() { - if (this.client && this.client.connected) { - console.warn('WebSocket 已连接'); - return Promise.resolve(); - } - - return new Promise((resolve, reject) => { - this.client = new Client({ - webSocketFactory: () => new SockJS(`${this.baseUrl}/ws`), - - connectHeaders: { - Authorization: `Bearer ${this.token}` - }, - - onConnect: (frame) => { - console.log('✅ WebSocket 连接成功'); - - // 订阅任务进度更新 - this.client.subscribe('/user/queue/tasks-progress', (message) => { - try { - const notification = JSON.parse(message.body); - this._notifyListeners('onTaskUpdate', notification); - } catch (error) { - console.error('解析消息失败:', error); - } - }); - - this._notifyListeners('onConnect', frame); - resolve(frame); - }, - - onStompError: (frame) => { - console.error('❌ STOMP 错误:', frame); - this._notifyListeners('onError', frame); - reject(frame); - }, - - onWebSocketError: (error) => { - console.error('❌ WebSocket 错误:', error); - this._notifyListeners('onError', error); - }, - - onWebSocketClose: (event) => { - console.log('🔌 WebSocket 连接关闭'); - this._notifyListeners('onDisconnect', event); - }, - - reconnectDelay: 5000, - heartbeatIncoming: 4000, - heartbeatOutgoing: 4000 - }); - - this.client.activate(); - }); - } - - /** - * 断开 WebSocket - */ - disconnect() { - if (this.client && this.client.connected) { - this.client.deactivate(); - console.log('WebSocket 已断开'); - } - } - - /** - * 添加任务更新监听器 - */ - onTaskUpdate(callback) { - this.listeners.onTaskUpdate.push(callback); - return () => this._removeListener('onTaskUpdate', callback); - } - - /** - * 添加连接监听器 - */ - onConnect(callback) { - this.listeners.onConnect.push(callback); - return () => this._removeListener('onConnect', callback); - } - - /** - * 添加断开连接监听器 - */ - onDisconnect(callback) { - this.listeners.onDisconnect.push(callback); - return () => this._removeListener('onDisconnect', callback); - } - - /** - * 添加错误监听器 - */ - onError(callback) { - this.listeners.onError.push(callback); - return () => this._removeListener('onError', callback); - } - - /** - * 通知所有监听器 - */ - _notifyListeners(event, data) { - this.listeners[event].forEach(callback => { - try { - callback(data); - } catch (error) { - console.error(`监听器执行错误 (${event}):`, error); - } - }); - } - - /** - * 移除监听器 - */ - _removeListener(event, callback) { - const index = this.listeners[event].indexOf(callback); - if (index > -1) { - this.listeners[event].splice(index, 1); - } - } - - /** - * 检查连接状态 - */ - isConnected() { - return this.client && this.client.connected; - } -} - -export default TaskWebSocketClient; -``` - ---- - -## 五、使用示例 - -### 1. React 组件示例 - -```jsx -import React, { useEffect, useState } from 'react'; -import TaskWebSocketClient from './TaskWebSocketClient'; - -function TaskMonitor() { - const [tasks, setTasks] = useState({}); - const [wsClient, setWsClient] = useState(null); - - useEffect(() => { - // 获取 Token(从 localStorage 或其他地方) - const token = localStorage.getItem('jwt_token'); - - // 创建 WebSocket 客户端 - const client = new TaskWebSocketClient('http://localhost:8081', token); - - // 监听任务更新 - const unsubscribe = client.onTaskUpdate((notification) => { - console.log('任务更新:', notification); - - // 更新任务状态 - setTasks(prev => ({ - ...prev, - [notification.taskNo]: notification - })); - - // 根据状态显示不同提示 - if (notification.status === 'completed') { - showSuccessToast(`任务 ${notification.taskNo} 已完成!`); - } else if (notification.status === 'failed') { - showErrorToast(`任务 ${notification.taskNo} 失败: ${notification.errorMessage}`); - } - }); - - // 连接 WebSocket - client.connect().catch(error => { - console.error('连接失败:', error); - }); - - setWsClient(client); - - // 清理函数 - return () => { - unsubscribe(); - client.disconnect(); - }; - }, []); - - return ( - - 任务监控 - {Object.values(tasks).map(task => ( - - {task.taskNo} - 状态: {task.status} - 进度: {task.progress}% - {task.message} - {task.resultUrl && ( - - 查看结果 - - )} - - ))} - - ); -} - -export default TaskMonitor; -``` - -### 2. Vue 3 组件示例 - -```vue - - - 任务监控 - - {{ task.taskNo }} - 状态: {{ task.status }} - - - {{ task.progress }}% - - {{ task.message }} - - 查看结果 - - - - - - -``` - -### 3. 原生 JavaScript 完整示例 - -```html - - - - 任务监控 - - - - - AI 任务实时监控 - 未连接 - - - - - - - -``` - ---- - -## 六、完整业务流程示例 - -```javascript -import TaskWebSocketClient from './TaskWebSocketClient'; -import SuChuangImageGenerator from './SuChuangImageGenerator'; - -class AITaskManager { - constructor(token, baseUrl = 'http://localhost:8081') { - this.wsClient = new TaskWebSocketClient(baseUrl, token); - this.generator = new SuChuangImageGenerator(token, baseUrl); - this.pendingTasks = new Map(); - } - - /** - * 初始化(连接 WebSocket 并设置监听器) - */ - async init() { - // 监听任务更新 - this.wsClient.onTaskUpdate((notification) => { - this.handleTaskUpdate(notification); - }); - - // 连接 WebSocket - await this.wsClient.connect(); - console.log('AI 任务管理器已初始化'); - } - - /** - * 提交文生图任务 - */ - async submitTextToImage(prompt, aspectRatio = '1:1', onProgress, onComplete, onError) { - try { - // 提交任务 - const taskNo = await this.generator.generateImage(prompt, aspectRatio); - - // 注册回调 - this.pendingTasks.set(taskNo, { onProgress, onComplete, onError }); - - return taskNo; - } catch (error) { - if (onError) onError(error); - throw error; - } - } - - /** - * 提交图生图任务 - */ - async submitImageToImage(prompt, imageUrl, aspectRatio = '1:1', onProgress, onComplete, onError) { - try { - const taskNo = await this.generator.transformImage(prompt, imageUrl, aspectRatio); - this.pendingTasks.set(taskNo, { onProgress, onComplete, onError }); - return taskNo; - } catch (error) { - if (onError) onError(error); - throw error; - } - } - - /** - * 处理任务更新 - */ - handleTaskUpdate(notification) { - const { taskNo, status, progress, message, resultUrl, errorMessage } = notification; - const callbacks = this.pendingTasks.get(taskNo); - - if (!callbacks) return; - - const { onProgress, onComplete, onError } = callbacks; - - switch(status) { - case 'processing': - if (onProgress) onProgress(progress, message); - break; - - case 'completed': - if (onComplete) onComplete(resultUrl); - this.pendingTasks.delete(taskNo); - break; - - case 'failed': - if (onError) onError(new Error(errorMessage || message)); - this.pendingTasks.delete(taskNo); - break; - } - } - - /** - * 清理资源 - */ - destroy() { - this.wsClient.disconnect(); - this.pendingTasks.clear(); - } -} - -// 使用示例 -const taskManager = new AITaskManager(YOUR_JWT_TOKEN); - -// 初始化 -await taskManager.init(); - -// 提交任务并监听进度 -const taskNo = await taskManager.submitTextToImage( - '一只可爱的柴犬', - '1:1', - (progress, message) => { - console.log(`进度: ${progress}% - ${message}`); - updateProgressBar(progress); - }, - (resultUrl) => { - console.log('生成完成:', resultUrl); - displayImage(resultUrl); - }, - (error) => { - console.error('生成失败:', error); - showErrorMessage(error.message); - } -); - -console.log('任务已提交:', taskNo); -``` - ---- - -## 七、常见问题 - -### 1. 跨域问题 -如果前端和后端不在同一域名,确保后端已配置 CORS: - -```java -// WebSocketConfig.java 中已配置 -registry.addEndpoint("/ws").setAllowedOriginPatterns("*").withSockJS(); -``` - -### 2. 认证失败 -确保在连接时传递了正确的 JWT Token: - -```javascript -connectHeaders: { - Authorization: `Bearer ${YOUR_JWT_TOKEN}` -} -``` - -### 3. 连接断开自动重连 -STOMP 客户端已配置自动重连: - -```javascript -reconnectDelay: 5000 // 5秒后自动重连 -``` - -### 4. 心跳检测 -防止连接超时: - -```javascript -heartbeatIncoming: 4000, // 接收心跳间隔 -heartbeatOutgoing: 4000 // 发送心跳间隔 -``` - ---- - -## 八、调试技巧 - -### 1. 开启详细日志 -```javascript -const client = new Client({ - // ... 其他配置 - debug: (str) => { - console.log('STOMP Debug:', str); - } -}); -``` - -### 2. 监控连接状态 -```javascript -client.onConnect = () => console.log('✅ 已连接'); -client.onDisconnect = () => console.log('🔌 已断开'); -client.onWebSocketError = (error) => console.error('❌ 错误:', error); -``` - -### 3. 测试消息接收 -```javascript -client.subscribe('/user/queue/tasks-progress', (message) => { - console.log('收到原始消息:', message.body); - const data = JSON.parse(message.body); - console.log('解析后的数据:', data); -}); -``` - ---- - -## 九、安全建议 - -1. **不要在前端暴露敏感信息** - - Token 应通过 localStorage 或 sessionStorage 安全存储 - - 避免在 URL 中传递 Token - -2. **设置合理的超时时间** - - 避免长时间保持空闲连接 - -3. **处理连接断开** - - 实现重连逻辑 - - 提示用户连接状态 - -4. **验证消息来源** - - 确认 taskNo 是否为当前用户的任务 - ---- - -## 十、完整目录结构 - -``` -src/ -├── websocket/ -│ ├── TaskWebSocketClient.js # WebSocket 封装类 -│ └── AITaskManager.js # 任务管理器 -├── api/ -│ └── SuChuangImageGenerator.js # 任务提交API -├── components/ -│ ├── TaskMonitor.jsx # React 任务监控组件 -│ └── TaskMonitor.vue # Vue 任务监控组件 -└── utils/ - └── notification.js # 浏览器通知工具 -``` - ---- - -## 总结 - -前端通过以下步骤接收 WebSocket 通知: - -1. **连接**: `new SockJS('http://localhost:8081/ws')` -2. **认证**: 在 `connectHeaders` 中传递 JWT Token -3. **订阅**: `client.subscribe('/user/queue/tasks-progress', callback)` -4. **处理**: 根据 `status` 字段处理不同状态的通知 - -**关键点**: -- ✅ 端点以 `/ws` 开头(不是 `/user/ws`) -- ✅ 订阅地址为 `/user/queue/tasks-progress` -- ✅ Spring 会自动将消息路由到当前用户 -- ✅ 支持自动重连和心跳检测 - diff --git a/debug_points_config.sql b/debug_points_config.sql deleted file mode 100644 index a4ddc8c..0000000 --- a/debug_points_config.sql +++ /dev/null @@ -1,38 +0,0 @@ --- 检查 points_config 表中的数据 --- 执行以下SQL来排查问题 - --- 1. 查看所有数据 -SELECT id, model_name, points_cost, description, is_enabled, provider_type, task_type -FROM points_config -WHERE is_deleted = 0 -ORDER BY id; - --- 2. 查看 RunningHub 的模型 -SELECT id, model_name, points_cost, description, is_enabled, provider_type, task_type -FROM points_config -WHERE provider_type = 'runninghub' - AND is_deleted = 0 -ORDER BY id; - --- 3. 查看文生图类型的模型 -SELECT id, model_name, points_cost, description, is_enabled, provider_type, task_type -FROM points_config -WHERE task_type = 'text_to_image' - AND is_deleted = 0 -ORDER BY id; - --- 4. 查看 RunningHub + 文生图的组合 -SELECT id, model_name, points_cost, description, is_enabled, provider_type, task_type -FROM points_config -WHERE provider_type = 'runninghub' - AND task_type = 'text_to_image' - AND is_deleted = 0 -ORDER BY id; - --- 5. 查看已启用的 RunningHub 模型 -SELECT id, model_name, points_cost, description, is_enabled, provider_type, task_type -FROM points_config -WHERE provider_type = 'runninghub' - AND is_enabled = 1 - AND is_deleted = 0 -ORDER BY id; diff --git a/docs/admin-tool-config-api.md b/docs/admin-tool-config-api.md new file mode 100644 index 0000000..b5391f3 --- /dev/null +++ b/docs/admin-tool-config-api.md @@ -0,0 +1,501 @@ +# 工具配置管理(管理端)API 文档 + +## 概述 + +管理端工具配置API,用于管理工具配置和查看使用统计。 + +- **Base URL**: `/admin/tools` +- **认证方式**: 需要管理员权限(`ROLE_ADMIN`) +- **请求头**: `Authorization: Bearer {admin_jwt_token}` + +--- + +## 一、工具配置管理 + +### 1.1 获取所有工具配置 + +获取所有工具配置列表。 + +**请求** +``` +GET /admin/tools/configs +``` + +**响应** +```json +{ + "code": 200, + "message": "success", + "data": [ + { + "id": 1, + "toolCode": "douyin_user_videos", + "toolName": "获取用户主页视频", + "category": "douyin", + "description": "根据sec_user_id获取用户发布的视频列表", + "apiEndpoint": "/api/v1/douyin/app/v3/fetch_user_post_videos", + "requestMethod": "GET", + "pointsCost": 5, + "isEnabled": 1, + "sortOrder": 1, + "createTime": "2026-01-02T10:00:00", + "updateTime": "2026-01-02T10:00:00" + } + ] +} +``` + +--- + +### 1.2 获取工具配置详情 + +根据ID获取工具配置详情。 + +**请求** +``` +GET /admin/tools/configs/{id} +``` + +**路径参数** +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| id | Long | 是 | 工具ID | + +**响应** +```json +{ + "code": 200, + "message": "success", + "data": { + "id": 1, + "toolCode": "douyin_user_videos", + "toolName": "获取用户主页视频", + "category": "douyin", + "description": "根据sec_user_id获取用户发布的视频列表", + "apiEndpoint": "/api/v1/douyin/app/v3/fetch_user_post_videos", + "requestMethod": "GET", + "pointsCost": 5, + "isEnabled": 1, + "sortOrder": 1, + "createTime": "2026-01-02T10:00:00", + "updateTime": "2026-01-02T10:00:00" + } +} +``` + +--- + +### 1.3 创建工具配置 + +创建新的工具配置。 + +**请求** +``` +POST /admin/tools/configs +Content-Type: application/json +``` + +**请求体** +```json +{ + "toolCode": "douyin_user_videos", + "toolName": "获取用户主页视频", + "category": "douyin", + "description": "根据sec_user_id获取用户发布的视频列表", + "apiEndpoint": "/api/v1/douyin/app/v3/fetch_user_post_videos", + "requestMethod": "GET", + "pointsCost": 5, + "isEnabled": 1, + "sortOrder": 1 +} +``` + +**请求体参数说明** +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| toolCode | String | 是 | 工具编码(唯一标识) | +| toolName | String | 是 | 工具名称 | +| category | String | 是 | 工具分类(douyin/xiaohongshu/wechat_mp) | +| description | String | 否 | 工具描述 | +| apiEndpoint | String | 是 | API端点路径 | +| requestMethod | String | 否 | 请求方法(GET/POST),默认GET | +| pointsCost | Integer | 否 | 积分消耗,默认1 | +| isEnabled | Integer | 否 | 是否启用(0禁用/1启用),默认1 | +| sortOrder | Integer | 否 | 排序顺序,默认0 | + +**响应** +```json +{ + "code": 200, + "message": "创建成功", + "data": { + "id": 1, + "toolCode": "douyin_user_videos", + "toolName": "获取用户主页视频", + "category": "douyin", + "description": "根据sec_user_id获取用户发布的视频列表", + "apiEndpoint": "/api/v1/douyin/app/v3/fetch_user_post_videos", + "requestMethod": "GET", + "pointsCost": 5, + "isEnabled": 1, + "sortOrder": 1, + "createTime": "2026-01-02T10:00:00", + "updateTime": "2026-01-02T10:00:00" + } +} +``` + +--- + +### 1.4 更新工具配置 + +更新指定工具配置。 + +**请求** +``` +PUT /admin/tools/configs/{id} +Content-Type: application/json +``` + +**路径参数** +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| id | Long | 是 | 工具ID | + +**请求体** +```json +{ + "toolCode": "douyin_user_videos", + "toolName": "获取用户主页视频", + "category": "douyin", + "description": "根据sec_user_id获取用户发布的视频列表", + "apiEndpoint": "/api/v1/douyin/app/v3/fetch_user_post_videos", + "requestMethod": "GET", + "pointsCost": 10, + "isEnabled": 1, + "sortOrder": 1 +} +``` + +**响应** +```json +{ + "code": 200, + "message": "更新成功", + "data": { + "id": 1, + "toolCode": "douyin_user_videos", + "toolName": "获取用户主页视频", + "category": "douyin", + "description": "根据sec_user_id获取用户发布的视频列表", + "apiEndpoint": "/api/v1/douyin/app/v3/fetch_user_post_videos", + "requestMethod": "GET", + "pointsCost": 10, + "isEnabled": 1, + "sortOrder": 1, + "createTime": "2026-01-02T10:00:00", + "updateTime": "2026-01-02T11:00:00" + } +} +``` + +--- + +### 1.5 更新积分消耗 + +单独更新工具的积分消耗配置。 + +**请求** +``` +PATCH /admin/tools/configs/{id}/points-cost?pointsCost={pointsCost} +``` + +**参数** +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| id | Long | 是 | 工具ID(路径参数) | +| pointsCost | Integer | 是 | 积分消耗(查询参数) | + +**响应** +```json +{ + "code": 200, + "message": "更新成功", + "data": null +} +``` + +--- + +### 1.6 更新工具状态 + +启用或禁用工具。 + +**请求** +``` +PATCH /admin/tools/configs/{id}/status?isEnabled={isEnabled} +``` + +**参数** +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| id | Long | 是 | 工具ID(路径参数) | +| isEnabled | Integer | 是 | 是否启用(0禁用/1启用)(查询参数) | + +**响应** +```json +{ + "code": 200, + "message": "更新成功", + "data": null +} +``` + +--- + +### 1.7 删除工具配置 + +删除指定工具配置(逻辑删除)。 + +**请求** +``` +DELETE /admin/tools/configs/{id} +``` + +**路径参数** +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| id | Long | 是 | 工具ID | + +**响应** +```json +{ + "code": 200, + "message": "删除成功", + "data": null +} +``` + +--- + +## 二、使用统计 + +### 2.1 获取统计概览 + +获取工具数量和今日调用统计。 + +**请求** +``` +GET /admin/tools/stats/info +``` + +**响应** +```json +{ + "code": 200, + "message": "success", + "data": { + "totalTools": 8, + "enabledTools": 8, + "todayCalls": 156, + "todayPointsCost": 780 + } +} +``` + +**响应字段说明** +| 字段 | 类型 | 说明 | +|------|------|------| +| totalTools | Long | 工具总数 | +| enabledTools | Long | 已启用工具数 | +| todayCalls | Long | 今日调用次数 | +| todayPointsCost | Long | 今日消耗积分 | + +--- + +### 2.2 获取统计汇总 + +获取指定日期范围内的统计汇总。 + +**请求** +``` +GET /admin/tools/stats/summary?startDate={startDate}&endDate={endDate} +``` + +**查询参数** +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| startDate | String | 否 | 开始日期(yyyy-MM-dd),默认30天前 | +| endDate | String | 否 | 结束日期(yyyy-MM-dd),默认今天 | + +**响应** +```json +{ + "code": 200, + "message": "success", + "data": { + "totalCalls": 1560, + "successCalls": 1500, + "failedCalls": 60, + "totalPointsCost": 7800, + "uniqueUsers": null, + "toolStats": [ + { + "toolCode": "douyin_user_videos", + "toolName": "获取用户主页视频", + "category": null, + "totalCalls": 500, + "successCalls": 480, + "totalPointsCost": 2500 + }, + { + "toolCode": "xiaohongshu_search_notes", + "toolName": "搜索笔记", + "category": null, + "totalCalls": 300, + "successCalls": 290, + "totalPointsCost": 1500 + } + ] + } +} +``` + +**响应字段说明** +| 字段 | 类型 | 说明 | +|------|------|------| +| totalCalls | Long | 总调用次数 | +| successCalls | Long | 成功次数 | +| failedCalls | Long | 失败次数 | +| totalPointsCost | Long | 总消耗积分 | +| uniqueUsers | Long | 独立用户数 | +| toolStats | Array | 按工具分类统计 | + +--- + +### 2.3 获取每日统计 + +获取每日统计数据列表。 + +**请求** +``` +GET /admin/tools/stats/daily?startDate={startDate}&endDate={endDate}&toolCode={toolCode} +``` + +**查询参数** +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| startDate | String | 否 | 开始日期(yyyy-MM-dd),默认7天前 | +| endDate | String | 否 | 结束日期(yyyy-MM-dd),默认今天 | +| toolCode | String | 否 | 工具编码,用于筛选特定工具 | + +**响应** +```json +{ + "code": 200, + "message": "success", + "data": [ + { + "statsDate": "2026-01-02", + "toolCode": "douyin_user_videos", + "toolName": "获取用户主页视频", + "totalCalls": 100, + "successCalls": 95, + "failedCalls": 5, + "totalPointsCost": 500, + "uniqueUsers": 20 + }, + { + "statsDate": "2026-01-01", + "toolCode": "douyin_user_videos", + "toolName": "获取用户主页视频", + "totalCalls": 80, + "successCalls": 78, + "failedCalls": 2, + "totalPointsCost": 400, + "uniqueUsers": 15 + } + ] +} +``` + +**响应字段说明** +| 字段 | 类型 | 说明 | +|------|------|------| +| statsDate | String | 统计日期 | +| toolCode | String | 工具编码 | +| toolName | String | 工具名称 | +| totalCalls | Integer | 调用总次数 | +| successCalls | Integer | 成功次数 | +| failedCalls | Integer | 失败次数 | +| totalPointsCost | Integer | 消耗总积分 | +| uniqueUsers | Integer | 独立用户数 | + +--- + +### 2.4 刷新每日统计 + +手动刷新指定日期的统计数据。 + +**请求** +``` +POST /admin/tools/stats/refresh?date={date} +``` + +**查询参数** +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| date | String | 否 | 日期(yyyy-MM-dd),默认今天 | + +**响应** +```json +{ + "code": 200, + "message": "刷新成功", + "data": null +} +``` + +--- + +## 三、错误响应 + +所有接口在发生错误时返回统一格式: + +```json +{ + "code": 500, + "message": "错误描述信息", + "data": null +} +``` + +**常见错误码** +| 错误码 | 说明 | +|--------|------| +| 401 | 未认证或Token过期 | +| 403 | 无权限(非管理员) | +| 500 | 服务器内部错误 | + +--- + +## 四、数据字典 + +### 工具分类(category) +| 值 | 说明 | +|------|------| +| douyin | 抖音 | +| xiaohongshu | 小红书 | +| wechat_mp | 微信公众号 | + +### 请求方法(requestMethod) +| 值 | 说明 | +|------|------| +| GET | GET请求 | +| POST | POST请求 | + +### 启用状态(isEnabled) +| 值 | 说明 | +|------|------| +| 0 | 禁用 | +| 1 | 启用 | diff --git a/docs/plaza-work-report-feature-summary.md b/docs/plaza-work-report-feature-summary.md new file mode 100644 index 0000000..9999753 --- /dev/null +++ b/docs/plaza-work-report-feature-summary.md @@ -0,0 +1,195 @@ +# 广场作品投诉功能实施总结 + +## 概述 +成功实现广场作品投诉功能,用户可以对违规作品进行投诉,管理员审核投诉并处理。 + +## 功能特性 + +### 1. 投诉类型 +支持6种投诉类型: +- `political` - 政治敏感 +- `pornographic` - 色情低俗 +- `violent` - 暴力血腥 +- `dangerous` - 危险行为 +- `uncomfortable` - 引人不适 +- `other` - 其他 + +### 2. 投诉限制机制 +- **每日投诉限制**:每个用户每天最多投诉10次 +- **防重复投诉**:同一用户不能重复投诉同一作品 +- **防自投诉**:不能投诉自己发布的作品 +- **自动重置**:每日0点自动重置投诉计数 + +### 3. 投诉状态 +- `pending` - 待审核 +- `approved` - 投诉成立 +- `rejected` - 投诉不成立 + +### 4. 管理员审核 +- **投诉成立**:下架作品(修改审核状态为 `rejected`,状态改为 `hidden`) +- **投诉不成立**:驳回投诉 +- **处理备注**:必须填写审核备注说明处理原因 + +## 数据库设计 + +### 1. plaza_work_report(投诉表) +```sql +CREATE TABLE `plaza_work_report` ( + `id` BIGINT NOT NULL AUTO_INCREMENT, + `report_no` VARCHAR(50) NOT NULL COMMENT '投诉编号', + `work_id` BIGINT NOT NULL COMMENT '被投诉的作品ID', + `work_no` VARCHAR(50) NOT NULL COMMENT '被投诉的作品编号', + `reporter_id` BIGINT NOT NULL COMMENT '投诉人用户ID', + `report_type` VARCHAR(20) NOT NULL COMMENT '投诉类型', + `report_reason` TEXT COMMENT '投诉原因描述', + `report_status` VARCHAR(20) DEFAULT 'pending' COMMENT '投诉状态', + `audit_admin_id` BIGINT COMMENT '审核管理员ID', + `audit_admin_name` VARCHAR(100) COMMENT '审核管理员名称', + `audit_remark` TEXT COMMENT '审核备注', + `audit_time` DATETIME COMMENT '审核时间', + `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP, + `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `is_deleted` TINYINT(1) DEFAULT 0, + PRIMARY KEY (`id`), + UNIQUE KEY `uk_report_no` (`report_no`), + KEY `idx_work_id` (`work_id`), + KEY `idx_reporter_id` (`reporter_id`), + KEY `idx_report_status` (`report_status`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; +``` + +### 2. plaza_work_report_limit(投诉限制表) +```sql +CREATE TABLE `plaza_work_report_limit` ( + `id` BIGINT NOT NULL AUTO_INCREMENT, + `user_id` BIGINT NOT NULL, + `report_count` INT DEFAULT 0 COMMENT '今日投诉次数', + `last_report_time` DATETIME COMMENT '最后投诉时间', + `reset_date` DATE NOT NULL COMMENT '重置日期', + `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP, + `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`id`), + UNIQUE KEY `uk_user_id` (`user_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; +``` + +## API 接口 + +### 用户端接口 + +#### 1. 提交投诉 +``` +POST /user/plaza/reports/submit +``` +**请求体:** +```json +{ + "workNo": "WORK-20251026-001", + "reportType": "pornographic", + "reportReason": "该作品包含不当内容" +} +``` + +#### 2. 查询我的投诉列表 +``` +GET /user/plaza/reports/my?page=1&size=10 +``` + +### 管理员端接口 + +#### 1. 查询投诉列表 +``` +GET /admin/plaza/reports/list?page=1&size=20&reportStatus=pending&reportType=pornographic&workNo=WORK-xxx&reporterId=123 +``` + +#### 2. 审核投诉 +``` +POST /admin/plaza/reports/audit +``` +**请求体:** +```json +{ + "reportNo": "REPORT-20251114-001", + "auditResult": "approved", + "auditRemark": "经审核,该作品确实存在违规内容,已下架处理" +} +``` + +#### 3. 获取待审核投诉数量 +``` +GET /admin/plaza/reports/pending/count +``` + +## 代码文件清单 + +### 数据库 +- ✅ `V12__add_plaza_work_report.sql` - 创建投诉表和限制表 + +### 实体类 +- ✅ `PlazaWorkReport.java` - 投诉实体类 +- ✅ `PlazaWorkReportLimit.java` - 投诉限制实体类 + +### DTO +- ✅ `PlazaWorkReportDto.java` - 投诉相关DTO + +### Mapper +- ✅ `PlazaWorkReportMapper.java` - 投诉Mapper接口 +- ✅ `PlazaWorkReportLimitMapper.java` - 投诉限制Mapper接口 + +### Service +- ✅ `PlazaWorkReportService.java` - 投诉服务接口 +- ✅ `PlazaWorkReportServiceImpl.java` - 投诉服务实现 + +### Controller +- ✅ `PlazaWorkReportController.java` - 用户端投诉控制器 +- ✅ `AdminPlazaWorkReportController.java` - 管理员端投诉控制器 + +### 修改文件 +- ✅ `PlazaWorkMapper.java` - 更新update方法支持审核状态修改 + +## 业务流程 + +### 用户投诉流程 +1. 用户选择作品并填写投诉信息 +2. 系统检查投诉限制(每日10次) +3. 系统检查是否重复投诉 +4. 系统检查是否投诉自己的作品 +5. 创建投诉记录,状态为 `pending` +6. 更新用户投诉计数 + +### 管理员审核流程 +1. 管理员查看待审核投诉列表 +2. 管理员查看投诉详情(包含作品信息) +3. 管理员审核投诉: + - **投诉成立**:更新投诉状态为 `approved`,下架作品(修改作品审核状态为 `rejected`,状态改为 `hidden`) + - **投诉不成立**:更新投诉状态为 `rejected` +4. 记录审核管理员信息和备注 + +## 部署步骤 + +1. **执行数据库脚本** + ```sql + source V12__add_plaza_work_report.sql; + ``` + +2. **部署代码** + - 部署所有新增和修改的文件 + - 重启应用服务 + +3. **验证功能** + - 测试用户提交投诉 + - 测试投诉限制机制 + - 测试管理员审核投诉 + - 测试投诉成立后作品下架 + +## 注意事项 + +1. **投诉限制**:每日最多10次,跨天自动重置 +2. **防重复投诉**:同一用户对同一作品只能投诉一次 +3. **防自投诉**:不能投诉自己发布的作品 +4. **作品下架**:投诉成立时,作品审核状态改为 `rejected`,状态改为 `hidden` +5. **审核备注**:管理员审核时必须填写处理备注 + +## 完成时间 +2025-11-14 + diff --git a/docs/sora2pro-integration-summary.md b/docs/sora2pro-integration-summary.md index 2c39838..e73a093 100644 --- a/docs/sora2pro-integration-summary.md +++ b/docs/sora2pro-integration-summary.md @@ -70,7 +70,7 @@ boolean isSora2Pro = isSora2ProModel(request.getModelName()); // 使用不同的接口 -String requestUrl = isSora2Pro ? apiUrl + "/api/sora2pro/submit" : apiUrl + "/api/sora2/submit"; +String requestUrl = isSora2Pro ? apiUrl + "/api/sora2pro/submit" : apiUrl + "/api/sora2-new/submit"; // sora2pro 不需要 size 参数 if (!isSora2Pro) { @@ -128,7 +128,7 @@ if (!isSora2Pro) { ## 注意事项 -1. **接口差异**: sora2pro 使用 `/api/sora2pro/submit`,而 sora2 使用 `/api/sora2/submit` +1. **接口差异**: sora2pro 使用 `/api/sora2pro/submit`,而 sora2 使用 `/api/sora2-new/submit` 2. **参数差异**: sora2pro 不需要 `size` 参数 3. **时长限制**: 25秒只能生成标清,15秒支持高清和标清 4. **查询接口**: sora2pro 和 sora2 共用 `/api/sora2/detail` 查询接口 diff --git a/docs/tool-service-api.md b/docs/tool-service-api.md new file mode 100644 index 0000000..7f300e0 --- /dev/null +++ b/docs/tool-service-api.md @@ -0,0 +1,234 @@ +# 工具服务模块 API 文档 + +## 概述 + +工具服务模块提供第三方数据采集工具的调用功能,支持抖音、小红书、微信公众号等平台的数据获取。 + +## 认证方式 + +工具接口支持两种认证方式: + +### 1. JWT Token(Web端) +登录后自动使用,适合Web前端调用。 + +### 2. API Key(开发者) +在请求头添加 `Authorization: Bearer {your_api_key}`,适合后端服务或脚本调用。 + +**获取API Key**: +1. 登录系统 +2. 进入个人中心 -> API密钥管理 +3. 生成API密钥 + +**调用示例**: +```bash +curl -X POST "https://api.1818ai.com/user/tools/call/douyin_user_videos" \ + -H "Authorization: Bearer ak_1234567890abcdef1234567890abcdef" \ + -H "Content-Type: application/json" \ + -d '{"sec_user_id": "MS4wLjABAAAA...", "max_cursor": 0, "count": 20}' +``` + +## 功能特性 + +1. **工具配置管理**:管理员可配置每个工具的积分消耗 +2. **积分扣除**:用户调用工具时自动扣除积分 +3. **调用记录**:完整记录每次工具调用 +4. **使用统计**:按天统计每个工具的使用次数 + +## 数据库表 + +### tool_config(工具配置表) +| 字段 | 类型 | 说明 | +|------|------|------| +| id | bigint | 主键 | +| tool_code | varchar(64) | 工具编码(唯一) | +| tool_name | varchar(128) | 工具名称 | +| category | varchar(32) | 分类(douyin/xiaohongshu/wechat_mp) | +| api_endpoint | varchar(256) | API端点路径 | +| points_cost | int | 调用消耗积分 | +| is_enabled | tinyint | 是否启用 | + +### tool_usage_log(调用记录表) +| 字段 | 类型 | 说明 | +|------|------|------| +| id | bigint | 主键 | +| usage_no | varchar(64) | 调用流水号 | +| user_id | bigint | 用户ID | +| tool_code | varchar(64) | 工具编码 | +| points_cost | int | 消耗积分 | +| status | varchar(20) | 状态(success/failed) | +| create_time | datetime | 调用时间 | + +### tool_usage_daily_stats(每日统计表) +| 字段 | 类型 | 说明 | +|------|------|------| +| stats_date | date | 统计日期 | +| tool_code | varchar(64) | 工具编码 | +| total_calls | int | 调用总次数 | +| success_calls | int | 成功次数 | +| total_points_cost | int | 消耗总积分 | + +--- + +## 用户端 API + +### 1. 获取工具列表 +``` +GET /user/tools/list +``` + +**响应示例:** +```json +{ + "code": 200, + "message": "success", + "data": [ + { + "toolCode": "douyin_user_videos", + "toolName": "获取用户主页视频", + "category": "douyin", + "description": "根据sec_user_id获取用户发布的视频列表", + "pointsCost": 5 + } + ] +} +``` + +### 2. 按分类获取工具 +``` +GET /user/tools/list/{category} +``` +- category: douyin / xiaohongshu / wechat_mp + +### 3. 调用工具 +``` +POST /user/tools/call/{toolCode} +``` + +**请求示例(抖音获取用户视频):** +```json +{ + "sec_user_id": "MS4wLjABAAAAnxkX6qJBxkyBnNhE__dpuYxdNFzihx1UoxfoKKkAlO8", + "max_cursor": 0, + "count": 20 +} +``` + +**响应示例:** +```json +{ + "code": 200, + "message": "success", + "data": { + "usageNo": "TU1735789012345ABCD1234", + "pointsCost": 5, + "remainingPoints": 95, + "data": { + "aweme_list": [...], + "max_cursor": 1528366024000, + "has_more": 1 + } + } +} +``` + +### 4. 获取调用记录 +``` +GET /user/tools/usage/logs?page=1&size=10&toolCode=douyin_user_videos +``` + +--- + +## 管理端 API + +### 1. 获取所有工具配置 +``` +GET /admin/tools/configs +``` + +### 2. 创建工具配置 +``` +POST /admin/tools/configs +``` + +**请求示例:** +```json +{ + "toolCode": "douyin_user_videos", + "toolName": "获取用户主页视频", + "category": "douyin", + "description": "根据sec_user_id获取用户发布的视频列表", + "apiEndpoint": "/api/v1/douyin/app/v3/fetch_user_post_videos", + "requestMethod": "GET", + "pointsCost": 5, + "isEnabled": 1, + "sortOrder": 1 +} +``` + +### 3. 更新积分消耗 +``` +PATCH /admin/tools/configs/{id}/points-cost?pointsCost=10 +``` + +### 4. 启用/禁用工具 +``` +PATCH /admin/tools/configs/{id}/status?isEnabled=0 +``` + +### 5. 获取统计概览 +``` +GET /admin/tools/stats/info +``` + +**响应示例:** +```json +{ + "code": 200, + "data": { + "totalTools": 8, + "enabledTools": 8, + "todayCalls": 156, + "todayPointsCost": 780 + } +} +``` + +### 6. 获取统计汇总 +``` +GET /admin/tools/stats/summary?startDate=2026-01-01&endDate=2026-01-02 +``` + +### 7. 获取每日统计 +``` +GET /admin/tools/stats/daily?startDate=2026-01-01&endDate=2026-01-07&toolCode=douyin_user_videos +``` + +--- + +## 配置说明 + +### application.yml 配置 +```yaml +tikhub: + api: + base-url: https://api.tikhub.io + key: YOUR_TIKHUB_API_KEY +``` + +### 初始化数据库 +执行 `src/main/resources/sql/tool_tables.sql` 创建表和初始数据。 + +--- + +## 预置工具列表 + +| 工具编码 | 名称 | 分类 | 积分 | +|---------|------|------|------| +| douyin_user_videos | 获取用户主页视频 | douyin | 5 | +| douyin_video_by_share | 根据分享链接获取视频 | douyin | 3 | +| xiaohongshu_user_notes | 获取用户笔记列表 | xiaohongshu | 5 | +| xiaohongshu_search_notes | 搜索笔记 | xiaohongshu | 5 | +| xiaohongshu_note_detail | 获取笔记详情 | xiaohongshu | 3 | +| wechat_mp_article_list | 获取文章列表 | wechat_mp | 5 | +| wechat_mp_article_json | 获取文章详情(JSON) | wechat_mp | 10 | +| wechat_mp_article_html | 获取文章详情(HTML) | wechat_mp | 100 | diff --git a/fix_wechat_menu_data.sql b/fix_wechat_menu_data.sql deleted file mode 100644 index fe5bffd..0000000 --- a/fix_wechat_menu_data.sql +++ /dev/null @@ -1,142 +0,0 @@ --- ================================================ --- 微信菜单数据修复脚本 --- ================================================ --- 此脚本用于检查和修复数据库中的无效微信菜单数据 - --- ------------------------------------------------ --- 1. 检查所有可能有问题的菜单数据 --- ------------------------------------------------ - --- 检查 view 类型但 URL 为空的菜单 -SELECT - id, - menu_name AS '菜单名称', - menu_type AS '类型', - menu_url AS 'URL', - menu_key AS 'Key', - parent_id AS '父菜单ID', - '问题:view类型缺少URL' AS '问题描述' -FROM wechat_menu -WHERE menu_type = 'view' - AND (menu_url IS NULL OR menu_url = '') - AND is_enabled = 1; - --- 检查 click 类型但 Key 为空的菜单 -SELECT - id, - menu_name AS '菜单名称', - menu_type AS '类型', - menu_key AS 'Key', - parent_id AS '父菜单ID', - '问题:click类型缺少Key' AS '问题描述' -FROM wechat_menu -WHERE menu_type = 'click' - AND (menu_key IS NULL OR menu_key = '') - AND is_enabled = 1; - --- 检查 miniprogram 类型但缺少必要字段的菜单 -SELECT - id, - menu_name AS '菜单名称', - menu_type AS '类型', - menu_url AS 'URL', - appid AS 'AppID', - pagepath AS 'PagePath', - parent_id AS '父菜单ID', - '问题:miniprogram类型缺少必要字段' AS '问题描述' -FROM wechat_menu -WHERE menu_type = 'miniprogram' - AND (menu_url IS NULL OR menu_url = '' - OR appid IS NULL OR appid = '' - OR pagepath IS NULL OR pagepath = '') - AND is_enabled = 1; - --- ------------------------------------------------ --- 2. 修复方案(请根据实际情况选择执行) --- ------------------------------------------------ - --- 方案A:禁用所有无效的菜单(推荐,不会删除数据) --- 禁用 view 类型但 URL 为空的菜单 -UPDATE wechat_menu -SET is_enabled = 0, - description = CONCAT(IFNULL(description, ''), ' [自动禁用:缺少URL]') -WHERE menu_type = 'view' - AND (menu_url IS NULL OR menu_url = '') - AND is_enabled = 1; - --- 禁用 click 类型但 Key 为空的菜单 -UPDATE wechat_menu -SET is_enabled = 0, - description = CONCAT(IFNULL(description, ''), ' [自动禁用:缺少Key]') -WHERE menu_type = 'click' - AND (menu_key IS NULL OR menu_key = '') - AND is_enabled = 1; - --- 禁用 miniprogram 类型但缺少必要字段的菜单 -UPDATE wechat_menu -SET is_enabled = 0, - description = CONCAT(IFNULL(description, ''), ' [自动禁用:缺少必要字段]') -WHERE menu_type = 'miniprogram' - AND (menu_url IS NULL OR menu_url = '' - OR appid IS NULL OR appid = '' - OR pagepath IS NULL OR pagepath = '') - AND is_enabled = 1; - --- ------------------------------------------------ --- 方案B:手动修复特定菜单(示例) --- ------------------------------------------------ - --- 如果您想保留 "首页" 菜单,可以为其添加URL --- UPDATE wechat_menu --- SET menu_url = 'https://your-website.com' --- WHERE menu_name = '首页' AND menu_type = 'view'; - --- 如果您想保留 "帮助中心" 菜单,可以为其添加URL --- UPDATE wechat_menu --- SET menu_url = 'https://your-website.com/help' --- WHERE menu_name = '帮助中心' AND menu_type = 'view'; - --- 或者,如果您想将这些菜单改为 click 类型: --- UPDATE wechat_menu --- SET menu_type = 'click', menu_key = 'MENU_HOME', menu_url = NULL --- WHERE menu_name = '首页'; - --- ------------------------------------------------ --- 方案C:删除无效菜单(慎用!) --- ------------------------------------------------ - --- 如果您确定要删除这些无效菜单,取消下面的注释 --- DELETE FROM wechat_menu --- WHERE menu_type = 'view' --- AND (menu_url IS NULL OR menu_url = '') --- AND is_enabled = 1; - --- ------------------------------------------------ --- 3. 修复后验证 --- ------------------------------------------------ - --- 查看所有启用的菜单 -SELECT - id, - parent_id, - menu_name, - menu_type, - menu_key, - menu_url, - is_enabled, - sort_order -FROM wechat_menu -WHERE is_enabled = 1 -ORDER BY parent_id ASC, sort_order ASC; - --- 统计菜单数量 -SELECT - is_enabled, - COUNT(*) as count, - CASE - WHEN is_enabled = 1 THEN '启用' - ELSE '禁用' - END as status -FROM wechat_menu -GROUP BY is_enabled; - diff --git a/logs/1818-user-server-error.2026-01-08.log b/logs/1818-user-server-error.2026-01-08.log new file mode 100644 index 0000000..3f5bfba --- /dev/null +++ b/logs/1818-user-server-error.2026-01-08.log @@ -0,0 +1,958 @@ +2026-01-08 12:49:59.170 [MessageBroker-1] ERROR com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Exception during pool initialization. +java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy158.findStuckTasks(Unknown Source) + at com.dora.scheduler.TaskScheduler.checkTasksTimeout(TaskScheduler.java:60) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +2026-01-08 12:49:59.175 [MessageBroker-1] ERROR o.s.s.support.TaskUtils$LoggingErrorHandler - Unexpected error occurred in scheduled task +org.mybatis.spring.MyBatisSystemException: null + at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:97) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:439) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy158.findStuckTasks(Unknown Source) + at com.dora.scheduler.TaskScheduler.checkTasksTimeout(TaskScheduler.java:60) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +Caused by: org.apache.ibatis.exceptions.PersistenceException: +### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection +### The error may exist in file [C:\Users\admin\Desktop\1818AI_admin\1818_user_server - 副本\target\classes\mapper\AiTaskMapper.xml] +### The error may involve com.dora.mapper.AiTaskMapper.findStuckTasks +### The error occurred while executing a query +### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:156) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + ... 23 common frames omitted +Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:84) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + ... 30 common frames omitted +Caused by: java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + ... 42 common frames omitted +2026-01-08 12:50:00.231 [MessageBroker-10] ERROR com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Exception during pool initialization. +java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy158.findProcessingTasksByProvider(Unknown Source) + at com.dora.scheduler.SuChuangPollingScheduler.pollSuChuangTasks(SuChuangPollingScheduler.java:49) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +2026-01-08 12:50:00.232 [MessageBroker-10] ERROR com.dora.scheduler.SuChuangPollingScheduler - 速创轮询调度器执行失败 +org.mybatis.spring.MyBatisSystemException: null + at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:97) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:439) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy158.findProcessingTasksByProvider(Unknown Source) + at com.dora.scheduler.SuChuangPollingScheduler.pollSuChuangTasks(SuChuangPollingScheduler.java:49) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +Caused by: org.apache.ibatis.exceptions.PersistenceException: +### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection +### The error may exist in file [C:\Users\admin\Desktop\1818AI_admin\1818_user_server - 副本\target\classes\mapper\AiTaskMapper.xml] +### The error may involve com.dora.mapper.AiTaskMapper.findProcessingTasksByProvider +### The error occurred while executing a query +### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:156) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + ... 23 common frames omitted +Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:84) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + ... 30 common frames omitted +Caused by: java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + ... 42 common frames omitted +2026-01-08 12:50:01.289 [MessageBroker-5] ERROR com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Exception during pool initialization. +java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy158.findQueuedTasksBeforeTime(Unknown Source) + at com.dora.scheduler.QueuedTaskTimeoutChecker.checkQueuedTasksTimeout(QueuedTaskTimeoutChecker.java:55) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +2026-01-08 12:50:01.289 [MessageBroker-5] ERROR com.dora.scheduler.QueuedTaskTimeoutChecker - 队列超时检查器执行失败 +org.mybatis.spring.MyBatisSystemException: null + at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:97) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:439) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy158.findQueuedTasksBeforeTime(Unknown Source) + at com.dora.scheduler.QueuedTaskTimeoutChecker.checkQueuedTasksTimeout(QueuedTaskTimeoutChecker.java:55) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +Caused by: org.apache.ibatis.exceptions.PersistenceException: +### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection +### The error may exist in file [C:\Users\admin\Desktop\1818AI_admin\1818_user_server - 副本\target\classes\mapper\AiTaskMapper.xml] +### The error may involve com.dora.mapper.AiTaskMapper.findQueuedTasksBeforeTime +### The error occurred while executing a query +### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:156) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + ... 23 common frames omitted +Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:84) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + ... 30 common frames omitted +Caused by: java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + ... 42 common frames omitted +2026-01-08 12:50:02.344 [MessageBroker-3] ERROR com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Exception during pool initialization. +java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy140.findAll(Unknown Source) + at com.dora.scheduler.TaskScheduler.getActiveModels(TaskScheduler.java:119) + at com.dora.scheduler.TaskScheduler.dispatchTasks(TaskScheduler.java:40) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +2026-01-08 12:50:02.345 [MessageBroker-3] ERROR o.s.s.support.TaskUtils$LoggingErrorHandler - Unexpected error occurred in scheduled task +org.mybatis.spring.MyBatisSystemException: null + at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:97) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:439) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy140.findAll(Unknown Source) + at com.dora.scheduler.TaskScheduler.getActiveModels(TaskScheduler.java:119) + at com.dora.scheduler.TaskScheduler.dispatchTasks(TaskScheduler.java:40) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +Caused by: org.apache.ibatis.exceptions.PersistenceException: +### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection +### The error may exist in file [C:\Users\admin\Desktop\1818AI_admin\1818_user_server - 副本\target\classes\mapper\PointsConfigMapper.xml] +### The error may involve com.dora.mapper.PointsConfigMapper.findAll +### The error occurred while executing a query +### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:156) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + ... 24 common frames omitted +Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:84) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + ... 31 common frames omitted +Caused by: java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + ... 43 common frames omitted +2026-01-08 12:50:03.397 [MessageBroker-2] ERROR com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Exception during pool initialization. +java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy158.findProcessingTasksByProvider(Unknown Source) + at com.dora.scheduler.RunningHubPollingScheduler.pollRunningHubTasks(RunningHubPollingScheduler.java:57) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +2026-01-08 12:50:03.398 [MessageBroker-2] ERROR com.dora.scheduler.RunningHubPollingScheduler - RunningHub轮询调度器执行失败 +org.mybatis.spring.MyBatisSystemException: null + at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:97) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:439) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy158.findProcessingTasksByProvider(Unknown Source) + at com.dora.scheduler.RunningHubPollingScheduler.pollRunningHubTasks(RunningHubPollingScheduler.java:57) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +Caused by: org.apache.ibatis.exceptions.PersistenceException: +### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection +### The error may exist in file [C:\Users\admin\Desktop\1818AI_admin\1818_user_server - 副本\target\classes\mapper\AiTaskMapper.xml] +### The error may involve com.dora.mapper.AiTaskMapper.findProcessingTasksByProvider +### The error occurred while executing a query +### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:156) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + ... 23 common frames omitted +Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:84) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + ... 30 common frames omitted +Caused by: java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + ... 42 common frames omitted +2026-01-08 12:50:04.451 [MessageBroker-11] ERROR com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Exception during pool initialization. +java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy140.findAll(Unknown Source) + at com.dora.scheduler.TaskScheduler.getActiveModels(TaskScheduler.java:119) + at com.dora.scheduler.TaskScheduler.dispatchTasks(TaskScheduler.java:40) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +2026-01-08 12:50:04.451 [MessageBroker-11] ERROR o.s.s.support.TaskUtils$LoggingErrorHandler - Unexpected error occurred in scheduled task +org.mybatis.spring.MyBatisSystemException: null + at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:97) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:439) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy140.findAll(Unknown Source) + at com.dora.scheduler.TaskScheduler.getActiveModels(TaskScheduler.java:119) + at com.dora.scheduler.TaskScheduler.dispatchTasks(TaskScheduler.java:40) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +Caused by: org.apache.ibatis.exceptions.PersistenceException: +### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection +### The error may exist in file [C:\Users\admin\Desktop\1818AI_admin\1818_user_server - 副本\target\classes\mapper\PointsConfigMapper.xml] +### The error may involve com.dora.mapper.PointsConfigMapper.findAll +### The error occurred while executing a query +### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:156) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + ... 24 common frames omitted +Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:84) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + ... 31 common frames omitted +Caused by: java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + ... 43 common frames omitted +2026-01-08 12:50:08.882 [MessageBroker-11] ERROR com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Exception during pool initialization. +java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy140.findAll(Unknown Source) + at com.dora.scheduler.TaskScheduler.getActiveModels(TaskScheduler.java:119) + at com.dora.scheduler.TaskScheduler.dispatchTasks(TaskScheduler.java:40) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +2026-01-08 12:50:08.882 [MessageBroker-11] ERROR o.s.s.support.TaskUtils$LoggingErrorHandler - Unexpected error occurred in scheduled task +org.mybatis.spring.MyBatisSystemException: null + at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:97) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:439) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy140.findAll(Unknown Source) + at com.dora.scheduler.TaskScheduler.getActiveModels(TaskScheduler.java:119) + at com.dora.scheduler.TaskScheduler.dispatchTasks(TaskScheduler.java:40) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +Caused by: org.apache.ibatis.exceptions.PersistenceException: +### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection +### The error may exist in file [C:\Users\admin\Desktop\1818AI_admin\1818_user_server - 副本\target\classes\mapper\PointsConfigMapper.xml] +### The error may involve com.dora.mapper.PointsConfigMapper.findAll +### The error occurred while executing a query +### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:156) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + ... 24 common frames omitted +Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:84) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + ... 31 common frames omitted +Caused by: java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + ... 43 common frames omitted diff --git a/logs/1818-user-server-error.2026-01-13.log b/logs/1818-user-server-error.2026-01-13.log new file mode 100644 index 0000000..23fea9d --- /dev/null +++ b/logs/1818-user-server-error.2026-01-13.log @@ -0,0 +1,11281 @@ +2026-01-13 14:05:15.839 [MessageBroker-5] ERROR com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Exception during pool initialization. +java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy158.findQueuedTasksBeforeTime(Unknown Source) + at com.dora.scheduler.QueuedTaskTimeoutChecker.checkQueuedTasksTimeout(QueuedTaskTimeoutChecker.java:55) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +2026-01-13 14:05:15.845 [MessageBroker-5] ERROR com.dora.scheduler.QueuedTaskTimeoutChecker - 队列超时检查器执行失败 +org.mybatis.spring.MyBatisSystemException: null + at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:97) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:439) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy158.findQueuedTasksBeforeTime(Unknown Source) + at com.dora.scheduler.QueuedTaskTimeoutChecker.checkQueuedTasksTimeout(QueuedTaskTimeoutChecker.java:55) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +Caused by: org.apache.ibatis.exceptions.PersistenceException: +### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection +### The error may exist in file [C:\Users\admin\Desktop\new_1818ai\1818_user_server - 副本\target\classes\mapper\AiTaskMapper.xml] +### The error may involve com.dora.mapper.AiTaskMapper.findQueuedTasksBeforeTime +### The error occurred while executing a query +### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:156) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + ... 23 common frames omitted +Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:84) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + ... 30 common frames omitted +Caused by: java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + ... 42 common frames omitted +2026-01-13 14:05:16.910 [MessageBroker-2] ERROR com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Exception during pool initialization. +java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy158.findProcessingTasksByProvider(Unknown Source) + at com.dora.scheduler.RunningHubPollingScheduler.pollRunningHubTasks(RunningHubPollingScheduler.java:57) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +2026-01-13 14:05:16.911 [MessageBroker-2] ERROR com.dora.scheduler.RunningHubPollingScheduler - RunningHub轮询调度器执行失败 +org.mybatis.spring.MyBatisSystemException: null + at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:97) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:439) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy158.findProcessingTasksByProvider(Unknown Source) + at com.dora.scheduler.RunningHubPollingScheduler.pollRunningHubTasks(RunningHubPollingScheduler.java:57) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +Caused by: org.apache.ibatis.exceptions.PersistenceException: +### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection +### The error may exist in file [C:\Users\admin\Desktop\new_1818ai\1818_user_server - 副本\target\classes\mapper\AiTaskMapper.xml] +### The error may involve com.dora.mapper.AiTaskMapper.findProcessingTasksByProvider +### The error occurred while executing a query +### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:156) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + ... 23 common frames omitted +Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:84) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + ... 30 common frames omitted +Caused by: java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + ... 42 common frames omitted +2026-01-13 14:05:17.970 [MessageBroker-1] ERROR com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Exception during pool initialization. +java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy158.findStuckTasks(Unknown Source) + at com.dora.scheduler.TaskScheduler.checkTasksTimeout(TaskScheduler.java:60) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +2026-01-13 14:05:17.971 [MessageBroker-1] ERROR o.s.s.support.TaskUtils$LoggingErrorHandler - Unexpected error occurred in scheduled task +org.mybatis.spring.MyBatisSystemException: null + at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:97) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:439) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy158.findStuckTasks(Unknown Source) + at com.dora.scheduler.TaskScheduler.checkTasksTimeout(TaskScheduler.java:60) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +Caused by: org.apache.ibatis.exceptions.PersistenceException: +### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection +### The error may exist in file [C:\Users\admin\Desktop\new_1818ai\1818_user_server - 副本\target\classes\mapper\AiTaskMapper.xml] +### The error may involve com.dora.mapper.AiTaskMapper.findStuckTasks +### The error occurred while executing a query +### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:156) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + ... 23 common frames omitted +Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:84) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + ... 30 common frames omitted +Caused by: java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + ... 42 common frames omitted +2026-01-13 14:05:19.037 [MessageBroker-3] ERROR com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Exception during pool initialization. +java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy140.findAll(Unknown Source) + at com.dora.scheduler.TaskScheduler.getActiveModels(TaskScheduler.java:119) + at com.dora.scheduler.TaskScheduler.dispatchTasks(TaskScheduler.java:40) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +2026-01-13 14:05:19.038 [MessageBroker-3] ERROR o.s.s.support.TaskUtils$LoggingErrorHandler - Unexpected error occurred in scheduled task +org.mybatis.spring.MyBatisSystemException: null + at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:97) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:439) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy140.findAll(Unknown Source) + at com.dora.scheduler.TaskScheduler.getActiveModels(TaskScheduler.java:119) + at com.dora.scheduler.TaskScheduler.dispatchTasks(TaskScheduler.java:40) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +Caused by: org.apache.ibatis.exceptions.PersistenceException: +### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection +### The error may exist in file [C:\Users\admin\Desktop\new_1818ai\1818_user_server - 副本\target\classes\mapper\PointsConfigMapper.xml] +### The error may involve com.dora.mapper.PointsConfigMapper.findAll +### The error occurred while executing a query +### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:156) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + ... 24 common frames omitted +Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:84) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + ... 31 common frames omitted +Caused by: java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + ... 43 common frames omitted +2026-01-13 14:05:20.099 [MessageBroker-12] ERROR com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Exception during pool initialization. +java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy158.findProcessingTasksByProvider(Unknown Source) + at com.dora.scheduler.SuChuangPollingScheduler.pollSuChuangTasks(SuChuangPollingScheduler.java:49) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +2026-01-13 14:05:20.100 [MessageBroker-12] ERROR com.dora.scheduler.SuChuangPollingScheduler - 速创轮询调度器执行失败 +org.mybatis.spring.MyBatisSystemException: null + at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:97) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:439) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy158.findProcessingTasksByProvider(Unknown Source) + at com.dora.scheduler.SuChuangPollingScheduler.pollSuChuangTasks(SuChuangPollingScheduler.java:49) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +Caused by: org.apache.ibatis.exceptions.PersistenceException: +### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection +### The error may exist in file [C:\Users\admin\Desktop\new_1818ai\1818_user_server - 副本\target\classes\mapper\AiTaskMapper.xml] +### The error may involve com.dora.mapper.AiTaskMapper.findProcessingTasksByProvider +### The error occurred while executing a query +### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:156) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + ... 23 common frames omitted +Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:84) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + ... 30 common frames omitted +Caused by: java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + ... 42 common frames omitted +2026-01-13 14:05:21.157 [MessageBroker-3] ERROR com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Exception during pool initialization. +java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy140.findAll(Unknown Source) + at com.dora.scheduler.TaskScheduler.getActiveModels(TaskScheduler.java:119) + at com.dora.scheduler.TaskScheduler.dispatchTasks(TaskScheduler.java:40) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +2026-01-13 14:05:21.157 [MessageBroker-3] ERROR o.s.s.support.TaskUtils$LoggingErrorHandler - Unexpected error occurred in scheduled task +org.mybatis.spring.MyBatisSystemException: null + at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:97) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:439) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy140.findAll(Unknown Source) + at com.dora.scheduler.TaskScheduler.getActiveModels(TaskScheduler.java:119) + at com.dora.scheduler.TaskScheduler.dispatchTasks(TaskScheduler.java:40) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +Caused by: org.apache.ibatis.exceptions.PersistenceException: +### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection +### The error may exist in file [C:\Users\admin\Desktop\new_1818ai\1818_user_server - 副本\target\classes\mapper\PointsConfigMapper.xml] +### The error may involve com.dora.mapper.PointsConfigMapper.findAll +### The error occurred while executing a query +### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:156) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + ... 24 common frames omitted +Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:84) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + ... 31 common frames omitted +Caused by: java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + ... 43 common frames omitted +2026-01-13 14:05:25.534 [MessageBroker-3] ERROR com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Exception during pool initialization. +java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy140.findAll(Unknown Source) + at com.dora.scheduler.TaskScheduler.getActiveModels(TaskScheduler.java:119) + at com.dora.scheduler.TaskScheduler.dispatchTasks(TaskScheduler.java:40) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +2026-01-13 14:05:25.534 [MessageBroker-3] ERROR o.s.s.support.TaskUtils$LoggingErrorHandler - Unexpected error occurred in scheduled task +org.mybatis.spring.MyBatisSystemException: null + at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:97) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:439) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy140.findAll(Unknown Source) + at com.dora.scheduler.TaskScheduler.getActiveModels(TaskScheduler.java:119) + at com.dora.scheduler.TaskScheduler.dispatchTasks(TaskScheduler.java:40) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +Caused by: org.apache.ibatis.exceptions.PersistenceException: +### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection +### The error may exist in file [C:\Users\admin\Desktop\new_1818ai\1818_user_server - 副本\target\classes\mapper\PointsConfigMapper.xml] +### The error may involve com.dora.mapper.PointsConfigMapper.findAll +### The error occurred while executing a query +### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:156) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + ... 24 common frames omitted +Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:84) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + ... 31 common frames omitted +Caused by: java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + ... 43 common frames omitted +2026-01-13 14:05:30.535 [MessageBroker-3] ERROR com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Exception during pool initialization. +java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy140.findAll(Unknown Source) + at com.dora.scheduler.TaskScheduler.getActiveModels(TaskScheduler.java:119) + at com.dora.scheduler.TaskScheduler.dispatchTasks(TaskScheduler.java:40) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +2026-01-13 14:05:30.535 [MessageBroker-3] ERROR o.s.s.support.TaskUtils$LoggingErrorHandler - Unexpected error occurred in scheduled task +org.mybatis.spring.MyBatisSystemException: null + at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:97) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:439) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy140.findAll(Unknown Source) + at com.dora.scheduler.TaskScheduler.getActiveModels(TaskScheduler.java:119) + at com.dora.scheduler.TaskScheduler.dispatchTasks(TaskScheduler.java:40) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +Caused by: org.apache.ibatis.exceptions.PersistenceException: +### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection +### The error may exist in file [C:\Users\admin\Desktop\new_1818ai\1818_user_server - 副本\target\classes\mapper\PointsConfigMapper.xml] +### The error may involve com.dora.mapper.PointsConfigMapper.findAll +### The error occurred while executing a query +### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:156) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + ... 24 common frames omitted +Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:84) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + ... 31 common frames omitted +Caused by: java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + ... 43 common frames omitted +2026-01-13 14:05:35.536 [MessageBroker-3] ERROR com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Exception during pool initialization. +java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy140.findAll(Unknown Source) + at com.dora.scheduler.TaskScheduler.getActiveModels(TaskScheduler.java:119) + at com.dora.scheduler.TaskScheduler.dispatchTasks(TaskScheduler.java:40) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +2026-01-13 14:05:35.537 [MessageBroker-3] ERROR o.s.s.support.TaskUtils$LoggingErrorHandler - Unexpected error occurred in scheduled task +org.mybatis.spring.MyBatisSystemException: null + at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:97) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:439) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy140.findAll(Unknown Source) + at com.dora.scheduler.TaskScheduler.getActiveModels(TaskScheduler.java:119) + at com.dora.scheduler.TaskScheduler.dispatchTasks(TaskScheduler.java:40) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +Caused by: org.apache.ibatis.exceptions.PersistenceException: +### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection +### The error may exist in file [C:\Users\admin\Desktop\new_1818ai\1818_user_server - 副本\target\classes\mapper\PointsConfigMapper.xml] +### The error may involve com.dora.mapper.PointsConfigMapper.findAll +### The error occurred while executing a query +### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:156) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + ... 24 common frames omitted +Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:84) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + ... 31 common frames omitted +Caused by: java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + ... 43 common frames omitted +2026-01-13 14:05:37.978 [MessageBroker-7] ERROR com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Exception during pool initialization. +java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy158.findProcessingTasksByProvider(Unknown Source) + at com.dora.scheduler.RunningHubPollingScheduler.pollRunningHubTasks(RunningHubPollingScheduler.java:57) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +2026-01-13 14:05:37.978 [MessageBroker-7] ERROR com.dora.scheduler.RunningHubPollingScheduler - RunningHub轮询调度器执行失败 +org.mybatis.spring.MyBatisSystemException: null + at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:97) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:439) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy158.findProcessingTasksByProvider(Unknown Source) + at com.dora.scheduler.RunningHubPollingScheduler.pollRunningHubTasks(RunningHubPollingScheduler.java:57) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +Caused by: org.apache.ibatis.exceptions.PersistenceException: +### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection +### The error may exist in file [C:\Users\admin\Desktop\new_1818ai\1818_user_server - 副本\target\classes\mapper\AiTaskMapper.xml] +### The error may involve com.dora.mapper.AiTaskMapper.findProcessingTasksByProvider +### The error occurred while executing a query +### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:156) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + ... 23 common frames omitted +Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:84) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + ... 30 common frames omitted +Caused by: java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + ... 42 common frames omitted +2026-01-13 14:05:40.535 [MessageBroker-15] ERROR com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Exception during pool initialization. +java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy140.findAll(Unknown Source) + at com.dora.scheduler.TaskScheduler.getActiveModels(TaskScheduler.java:119) + at com.dora.scheduler.TaskScheduler.dispatchTasks(TaskScheduler.java:40) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +2026-01-13 14:05:40.535 [MessageBroker-15] ERROR o.s.s.support.TaskUtils$LoggingErrorHandler - Unexpected error occurred in scheduled task +org.mybatis.spring.MyBatisSystemException: null + at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:97) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:439) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy140.findAll(Unknown Source) + at com.dora.scheduler.TaskScheduler.getActiveModels(TaskScheduler.java:119) + at com.dora.scheduler.TaskScheduler.dispatchTasks(TaskScheduler.java:40) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +Caused by: org.apache.ibatis.exceptions.PersistenceException: +### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection +### The error may exist in file [C:\Users\admin\Desktop\new_1818ai\1818_user_server - 副本\target\classes\mapper\PointsConfigMapper.xml] +### The error may involve com.dora.mapper.PointsConfigMapper.findAll +### The error occurred while executing a query +### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:156) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + ... 24 common frames omitted +Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:84) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + ... 31 common frames omitted +Caused by: java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + ... 43 common frames omitted +2026-01-13 14:05:45.541 [MessageBroker-15] ERROR com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Exception during pool initialization. +java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy140.findAll(Unknown Source) + at com.dora.scheduler.TaskScheduler.getActiveModels(TaskScheduler.java:119) + at com.dora.scheduler.TaskScheduler.dispatchTasks(TaskScheduler.java:40) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +2026-01-13 14:05:45.541 [MessageBroker-15] ERROR o.s.s.support.TaskUtils$LoggingErrorHandler - Unexpected error occurred in scheduled task +org.mybatis.spring.MyBatisSystemException: null + at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:97) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:439) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy140.findAll(Unknown Source) + at com.dora.scheduler.TaskScheduler.getActiveModels(TaskScheduler.java:119) + at com.dora.scheduler.TaskScheduler.dispatchTasks(TaskScheduler.java:40) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +Caused by: org.apache.ibatis.exceptions.PersistenceException: +### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection +### The error may exist in file [C:\Users\admin\Desktop\new_1818ai\1818_user_server - 副本\target\classes\mapper\PointsConfigMapper.xml] +### The error may involve com.dora.mapper.PointsConfigMapper.findAll +### The error occurred while executing a query +### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:156) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + ... 24 common frames omitted +Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:84) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + ... 31 common frames omitted +Caused by: java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + ... 43 common frames omitted +2026-01-13 14:05:50.527 [MessageBroker-15] ERROR com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Exception during pool initialization. +java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy140.findAll(Unknown Source) + at com.dora.scheduler.TaskScheduler.getActiveModels(TaskScheduler.java:119) + at com.dora.scheduler.TaskScheduler.dispatchTasks(TaskScheduler.java:40) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +2026-01-13 14:05:50.527 [MessageBroker-15] ERROR o.s.s.support.TaskUtils$LoggingErrorHandler - Unexpected error occurred in scheduled task +org.mybatis.spring.MyBatisSystemException: null + at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:97) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:439) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy140.findAll(Unknown Source) + at com.dora.scheduler.TaskScheduler.getActiveModels(TaskScheduler.java:119) + at com.dora.scheduler.TaskScheduler.dispatchTasks(TaskScheduler.java:40) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +Caused by: org.apache.ibatis.exceptions.PersistenceException: +### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection +### The error may exist in file [C:\Users\admin\Desktop\new_1818ai\1818_user_server - 副本\target\classes\mapper\PointsConfigMapper.xml] +### The error may involve com.dora.mapper.PointsConfigMapper.findAll +### The error occurred while executing a query +### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:156) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + ... 24 common frames omitted +Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:84) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + ... 31 common frames omitted +Caused by: java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + ... 43 common frames omitted +2026-01-13 14:05:51.593 [MessageBroker-2] ERROR com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Exception during pool initialization. +java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy158.findProcessingTasksByProvider(Unknown Source) + at com.dora.scheduler.SuChuangPollingScheduler.pollSuChuangTasks(SuChuangPollingScheduler.java:49) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +2026-01-13 14:05:51.593 [MessageBroker-2] ERROR com.dora.scheduler.SuChuangPollingScheduler - 速创轮询调度器执行失败 +org.mybatis.spring.MyBatisSystemException: null + at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:97) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:439) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy158.findProcessingTasksByProvider(Unknown Source) + at com.dora.scheduler.SuChuangPollingScheduler.pollSuChuangTasks(SuChuangPollingScheduler.java:49) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +Caused by: org.apache.ibatis.exceptions.PersistenceException: +### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection +### The error may exist in file [C:\Users\admin\Desktop\new_1818ai\1818_user_server - 副本\target\classes\mapper\AiTaskMapper.xml] +### The error may involve com.dora.mapper.AiTaskMapper.findProcessingTasksByProvider +### The error occurred while executing a query +### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:156) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + ... 23 common frames omitted +Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:84) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + ... 30 common frames omitted +Caused by: java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + ... 42 common frames omitted +2026-01-13 14:05:55.541 [MessageBroker-15] ERROR com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Exception during pool initialization. +java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy140.findAll(Unknown Source) + at com.dora.scheduler.TaskScheduler.getActiveModels(TaskScheduler.java:119) + at com.dora.scheduler.TaskScheduler.dispatchTasks(TaskScheduler.java:40) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +2026-01-13 14:05:55.541 [MessageBroker-15] ERROR o.s.s.support.TaskUtils$LoggingErrorHandler - Unexpected error occurred in scheduled task +org.mybatis.spring.MyBatisSystemException: null + at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:97) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:439) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy140.findAll(Unknown Source) + at com.dora.scheduler.TaskScheduler.getActiveModels(TaskScheduler.java:119) + at com.dora.scheduler.TaskScheduler.dispatchTasks(TaskScheduler.java:40) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +Caused by: org.apache.ibatis.exceptions.PersistenceException: +### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection +### The error may exist in file [C:\Users\admin\Desktop\new_1818ai\1818_user_server - 副本\target\classes\mapper\PointsConfigMapper.xml] +### The error may involve com.dora.mapper.PointsConfigMapper.findAll +### The error occurred while executing a query +### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:156) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + ... 24 common frames omitted +Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:84) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + ... 31 common frames omitted +Caused by: java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + ... 43 common frames omitted +2026-01-13 14:05:59.056 [MessageBroker-13] ERROR com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Exception during pool initialization. +java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy158.findProcessingTasksByProvider(Unknown Source) + at com.dora.scheduler.RunningHubPollingScheduler.pollRunningHubTasks(RunningHubPollingScheduler.java:57) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +2026-01-13 14:05:59.057 [MessageBroker-13] ERROR com.dora.scheduler.RunningHubPollingScheduler - RunningHub轮询调度器执行失败 +org.mybatis.spring.MyBatisSystemException: null + at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:97) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:439) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy158.findProcessingTasksByProvider(Unknown Source) + at com.dora.scheduler.RunningHubPollingScheduler.pollRunningHubTasks(RunningHubPollingScheduler.java:57) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +Caused by: org.apache.ibatis.exceptions.PersistenceException: +### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection +### The error may exist in file [C:\Users\admin\Desktop\new_1818ai\1818_user_server - 副本\target\classes\mapper\AiTaskMapper.xml] +### The error may involve com.dora.mapper.AiTaskMapper.findProcessingTasksByProvider +### The error occurred while executing a query +### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:156) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + ... 23 common frames omitted +Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:84) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + ... 30 common frames omitted +Caused by: java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + ... 42 common frames omitted +2026-01-13 14:06:00.524 [MessageBroker-8] ERROR com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Exception during pool initialization. +java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at jdk.internal.reflect.GeneratedMethodAccessor28.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy140.findAll(Unknown Source) + at com.dora.scheduler.TaskScheduler.getActiveModels(TaskScheduler.java:119) + at com.dora.scheduler.TaskScheduler.dispatchTasks(TaskScheduler.java:40) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +2026-01-13 14:06:00.524 [MessageBroker-8] ERROR o.s.s.support.TaskUtils$LoggingErrorHandler - Unexpected error occurred in scheduled task +org.mybatis.spring.MyBatisSystemException: null + at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:97) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:439) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy140.findAll(Unknown Source) + at com.dora.scheduler.TaskScheduler.getActiveModels(TaskScheduler.java:119) + at com.dora.scheduler.TaskScheduler.dispatchTasks(TaskScheduler.java:40) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +Caused by: org.apache.ibatis.exceptions.PersistenceException: +### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection +### The error may exist in file [C:\Users\admin\Desktop\new_1818ai\1818_user_server - 副本\target\classes\mapper\PointsConfigMapper.xml] +### The error may involve com.dora.mapper.PointsConfigMapper.findAll +### The error occurred while executing a query +### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:156) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at jdk.internal.reflect.GeneratedMethodAccessor28.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + ... 24 common frames omitted +Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:84) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + ... 30 common frames omitted +Caused by: java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + ... 42 common frames omitted +2026-01-13 14:06:05.552 [MessageBroker-8] ERROR com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Exception during pool initialization. +java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at jdk.internal.reflect.GeneratedMethodAccessor28.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy140.findAll(Unknown Source) + at com.dora.scheduler.TaskScheduler.getActiveModels(TaskScheduler.java:119) + at com.dora.scheduler.TaskScheduler.dispatchTasks(TaskScheduler.java:40) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +2026-01-13 14:06:05.552 [MessageBroker-8] ERROR o.s.s.support.TaskUtils$LoggingErrorHandler - Unexpected error occurred in scheduled task +org.mybatis.spring.MyBatisSystemException: null + at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:97) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:439) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy140.findAll(Unknown Source) + at com.dora.scheduler.TaskScheduler.getActiveModels(TaskScheduler.java:119) + at com.dora.scheduler.TaskScheduler.dispatchTasks(TaskScheduler.java:40) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +Caused by: org.apache.ibatis.exceptions.PersistenceException: +### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection +### The error may exist in file [C:\Users\admin\Desktop\new_1818ai\1818_user_server - 副本\target\classes\mapper\PointsConfigMapper.xml] +### The error may involve com.dora.mapper.PointsConfigMapper.findAll +### The error occurred while executing a query +### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:156) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at jdk.internal.reflect.GeneratedMethodAccessor28.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + ... 24 common frames omitted +Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:84) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + ... 30 common frames omitted +Caused by: java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + ... 42 common frames omitted +2026-01-13 14:06:10.530 [MessageBroker-8] ERROR com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Exception during pool initialization. +java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at jdk.internal.reflect.GeneratedMethodAccessor28.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy140.findAll(Unknown Source) + at com.dora.scheduler.TaskScheduler.getActiveModels(TaskScheduler.java:119) + at com.dora.scheduler.TaskScheduler.dispatchTasks(TaskScheduler.java:40) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +2026-01-13 14:06:10.531 [MessageBroker-8] ERROR o.s.s.support.TaskUtils$LoggingErrorHandler - Unexpected error occurred in scheduled task +org.mybatis.spring.MyBatisSystemException: null + at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:97) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:439) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy140.findAll(Unknown Source) + at com.dora.scheduler.TaskScheduler.getActiveModels(TaskScheduler.java:119) + at com.dora.scheduler.TaskScheduler.dispatchTasks(TaskScheduler.java:40) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +Caused by: org.apache.ibatis.exceptions.PersistenceException: +### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection +### The error may exist in file [C:\Users\admin\Desktop\new_1818ai\1818_user_server - 副本\target\classes\mapper\PointsConfigMapper.xml] +### The error may involve com.dora.mapper.PointsConfigMapper.findAll +### The error occurred while executing a query +### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:156) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at jdk.internal.reflect.GeneratedMethodAccessor28.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + ... 24 common frames omitted +Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:84) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + ... 30 common frames omitted +Caused by: java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + ... 42 common frames omitted +2026-01-13 14:06:15.548 [MessageBroker-12] ERROR com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Exception during pool initialization. +java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at jdk.internal.reflect.GeneratedMethodAccessor28.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy140.findAll(Unknown Source) + at com.dora.scheduler.TaskScheduler.getActiveModels(TaskScheduler.java:119) + at com.dora.scheduler.TaskScheduler.dispatchTasks(TaskScheduler.java:40) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +2026-01-13 14:06:15.548 [MessageBroker-12] ERROR o.s.s.support.TaskUtils$LoggingErrorHandler - Unexpected error occurred in scheduled task +org.mybatis.spring.MyBatisSystemException: null + at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:97) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:439) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy140.findAll(Unknown Source) + at com.dora.scheduler.TaskScheduler.getActiveModels(TaskScheduler.java:119) + at com.dora.scheduler.TaskScheduler.dispatchTasks(TaskScheduler.java:40) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +Caused by: org.apache.ibatis.exceptions.PersistenceException: +### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection +### The error may exist in file [C:\Users\admin\Desktop\new_1818ai\1818_user_server - 副本\target\classes\mapper\PointsConfigMapper.xml] +### The error may involve com.dora.mapper.PointsConfigMapper.findAll +### The error occurred while executing a query +### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:156) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at jdk.internal.reflect.GeneratedMethodAccessor28.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + ... 24 common frames omitted +Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:84) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + ... 30 common frames omitted +Caused by: java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + ... 42 common frames omitted +2026-01-13 14:06:16.604 [MessageBroker-2] ERROR com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Exception during pool initialization. +java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at jdk.internal.reflect.GeneratedMethodAccessor28.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy158.findStuckTasks(Unknown Source) + at com.dora.scheduler.TaskScheduler.checkTasksTimeout(TaskScheduler.java:60) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +2026-01-13 14:06:16.605 [MessageBroker-2] ERROR o.s.s.support.TaskUtils$LoggingErrorHandler - Unexpected error occurred in scheduled task +org.mybatis.spring.MyBatisSystemException: null + at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:97) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:439) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy158.findStuckTasks(Unknown Source) + at com.dora.scheduler.TaskScheduler.checkTasksTimeout(TaskScheduler.java:60) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +Caused by: org.apache.ibatis.exceptions.PersistenceException: +### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection +### The error may exist in file [C:\Users\admin\Desktop\new_1818ai\1818_user_server - 副本\target\classes\mapper\AiTaskMapper.xml] +### The error may involve com.dora.mapper.AiTaskMapper.findStuckTasks +### The error occurred while executing a query +### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:156) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at jdk.internal.reflect.GeneratedMethodAccessor28.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + ... 23 common frames omitted +Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:84) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + ... 29 common frames omitted +Caused by: java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + ... 41 common frames omitted +2026-01-13 14:06:20.133 [MessageBroker-15] ERROR com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Exception during pool initialization. +java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at jdk.internal.reflect.GeneratedMethodAccessor28.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy158.findProcessingTasksByProvider(Unknown Source) + at com.dora.scheduler.RunningHubPollingScheduler.pollRunningHubTasks(RunningHubPollingScheduler.java:57) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +2026-01-13 14:06:20.133 [MessageBroker-15] ERROR com.dora.scheduler.RunningHubPollingScheduler - RunningHub轮询调度器执行失败 +org.mybatis.spring.MyBatisSystemException: null + at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:97) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:439) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy158.findProcessingTasksByProvider(Unknown Source) + at com.dora.scheduler.RunningHubPollingScheduler.pollRunningHubTasks(RunningHubPollingScheduler.java:57) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +Caused by: org.apache.ibatis.exceptions.PersistenceException: +### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection +### The error may exist in file [C:\Users\admin\Desktop\new_1818ai\1818_user_server - 副本\target\classes\mapper\AiTaskMapper.xml] +### The error may involve com.dora.mapper.AiTaskMapper.findProcessingTasksByProvider +### The error occurred while executing a query +### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:156) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at jdk.internal.reflect.GeneratedMethodAccessor28.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + ... 23 common frames omitted +Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:84) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + ... 29 common frames omitted +Caused by: java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + ... 41 common frames omitted +2026-01-13 14:06:21.190 [MessageBroker-13] ERROR com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Exception during pool initialization. +java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at jdk.internal.reflect.GeneratedMethodAccessor28.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy140.findAll(Unknown Source) + at com.dora.scheduler.TaskScheduler.getActiveModels(TaskScheduler.java:119) + at com.dora.scheduler.TaskScheduler.dispatchTasks(TaskScheduler.java:40) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +2026-01-13 14:06:21.191 [MessageBroker-13] ERROR o.s.s.support.TaskUtils$LoggingErrorHandler - Unexpected error occurred in scheduled task +org.mybatis.spring.MyBatisSystemException: null + at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:97) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:439) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy140.findAll(Unknown Source) + at com.dora.scheduler.TaskScheduler.getActiveModels(TaskScheduler.java:119) + at com.dora.scheduler.TaskScheduler.dispatchTasks(TaskScheduler.java:40) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +Caused by: org.apache.ibatis.exceptions.PersistenceException: +### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection +### The error may exist in file [C:\Users\admin\Desktop\new_1818ai\1818_user_server - 副本\target\classes\mapper\PointsConfigMapper.xml] +### The error may involve com.dora.mapper.PointsConfigMapper.findAll +### The error occurred while executing a query +### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:156) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at jdk.internal.reflect.GeneratedMethodAccessor28.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + ... 24 common frames omitted +Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:84) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + ... 30 common frames omitted +Caused by: java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + ... 42 common frames omitted +2026-01-13 14:06:22.654 [MessageBroker-16] ERROR com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Exception during pool initialization. +java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at jdk.internal.reflect.GeneratedMethodAccessor28.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy158.findProcessingTasksByProvider(Unknown Source) + at com.dora.scheduler.SuChuangPollingScheduler.pollSuChuangTasks(SuChuangPollingScheduler.java:49) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +2026-01-13 14:06:22.654 [MessageBroker-16] ERROR com.dora.scheduler.SuChuangPollingScheduler - 速创轮询调度器执行失败 +org.mybatis.spring.MyBatisSystemException: null + at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:97) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:439) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy158.findProcessingTasksByProvider(Unknown Source) + at com.dora.scheduler.SuChuangPollingScheduler.pollSuChuangTasks(SuChuangPollingScheduler.java:49) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +Caused by: org.apache.ibatis.exceptions.PersistenceException: +### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection +### The error may exist in file [C:\Users\admin\Desktop\new_1818ai\1818_user_server - 副本\target\classes\mapper\AiTaskMapper.xml] +### The error may involve com.dora.mapper.AiTaskMapper.findProcessingTasksByProvider +### The error occurred while executing a query +### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:156) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at jdk.internal.reflect.GeneratedMethodAccessor28.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + ... 23 common frames omitted +Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:84) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + ... 29 common frames omitted +Caused by: java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + ... 41 common frames omitted +2026-01-13 14:06:25.519 [MessageBroker-5] ERROR com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Exception during pool initialization. +java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at jdk.internal.reflect.GeneratedMethodAccessor28.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy140.findAll(Unknown Source) + at com.dora.scheduler.TaskScheduler.getActiveModels(TaskScheduler.java:119) + at com.dora.scheduler.TaskScheduler.dispatchTasks(TaskScheduler.java:40) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +2026-01-13 14:06:25.520 [MessageBroker-5] ERROR o.s.s.support.TaskUtils$LoggingErrorHandler - Unexpected error occurred in scheduled task +org.mybatis.spring.MyBatisSystemException: null + at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:97) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:439) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy140.findAll(Unknown Source) + at com.dora.scheduler.TaskScheduler.getActiveModels(TaskScheduler.java:119) + at com.dora.scheduler.TaskScheduler.dispatchTasks(TaskScheduler.java:40) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +Caused by: org.apache.ibatis.exceptions.PersistenceException: +### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection +### The error may exist in file [C:\Users\admin\Desktop\new_1818ai\1818_user_server - 副本\target\classes\mapper\PointsConfigMapper.xml] +### The error may involve com.dora.mapper.PointsConfigMapper.findAll +### The error occurred while executing a query +### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:156) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at jdk.internal.reflect.GeneratedMethodAccessor28.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + ... 24 common frames omitted +Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:84) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + ... 30 common frames omitted +Caused by: java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + ... 42 common frames omitted +2026-01-13 14:06:30.537 [MessageBroker-5] ERROR com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Exception during pool initialization. +java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at jdk.internal.reflect.GeneratedMethodAccessor28.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy140.findAll(Unknown Source) + at com.dora.scheduler.TaskScheduler.getActiveModels(TaskScheduler.java:119) + at com.dora.scheduler.TaskScheduler.dispatchTasks(TaskScheduler.java:40) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +2026-01-13 14:06:30.537 [MessageBroker-5] ERROR o.s.s.support.TaskUtils$LoggingErrorHandler - Unexpected error occurred in scheduled task +org.mybatis.spring.MyBatisSystemException: null + at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:97) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:439) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy140.findAll(Unknown Source) + at com.dora.scheduler.TaskScheduler.getActiveModels(TaskScheduler.java:119) + at com.dora.scheduler.TaskScheduler.dispatchTasks(TaskScheduler.java:40) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +Caused by: org.apache.ibatis.exceptions.PersistenceException: +### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection +### The error may exist in file [C:\Users\admin\Desktop\new_1818ai\1818_user_server - 副本\target\classes\mapper\PointsConfigMapper.xml] +### The error may involve com.dora.mapper.PointsConfigMapper.findAll +### The error occurred while executing a query +### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:156) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at jdk.internal.reflect.GeneratedMethodAccessor28.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + ... 24 common frames omitted +Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:84) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + ... 30 common frames omitted +Caused by: java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + ... 42 common frames omitted +2026-01-13 14:06:35.524 [MessageBroker-5] ERROR com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Exception during pool initialization. +java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at jdk.internal.reflect.GeneratedMethodAccessor28.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy140.findAll(Unknown Source) + at com.dora.scheduler.TaskScheduler.getActiveModels(TaskScheduler.java:119) + at com.dora.scheduler.TaskScheduler.dispatchTasks(TaskScheduler.java:40) + at jdk.internal.reflect.GeneratedMethodAccessor30.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +2026-01-13 14:06:35.524 [MessageBroker-5] ERROR o.s.s.support.TaskUtils$LoggingErrorHandler - Unexpected error occurred in scheduled task +org.mybatis.spring.MyBatisSystemException: null + at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:97) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:439) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy140.findAll(Unknown Source) + at com.dora.scheduler.TaskScheduler.getActiveModels(TaskScheduler.java:119) + at com.dora.scheduler.TaskScheduler.dispatchTasks(TaskScheduler.java:40) + at jdk.internal.reflect.GeneratedMethodAccessor30.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +Caused by: org.apache.ibatis.exceptions.PersistenceException: +### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection +### The error may exist in file [C:\Users\admin\Desktop\new_1818ai\1818_user_server - 副本\target\classes\mapper\PointsConfigMapper.xml] +### The error may involve com.dora.mapper.PointsConfigMapper.findAll +### The error occurred while executing a query +### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:156) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at jdk.internal.reflect.GeneratedMethodAccessor28.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + ... 23 common frames omitted +Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:84) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + ... 29 common frames omitted +Caused by: java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + ... 41 common frames omitted +2026-01-13 14:06:40.529 [MessageBroker-5] ERROR com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Exception during pool initialization. +java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at jdk.internal.reflect.GeneratedMethodAccessor28.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy140.findAll(Unknown Source) + at com.dora.scheduler.TaskScheduler.getActiveModels(TaskScheduler.java:119) + at com.dora.scheduler.TaskScheduler.dispatchTasks(TaskScheduler.java:40) + at jdk.internal.reflect.GeneratedMethodAccessor30.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +2026-01-13 14:06:40.530 [MessageBroker-5] ERROR o.s.s.support.TaskUtils$LoggingErrorHandler - Unexpected error occurred in scheduled task +org.mybatis.spring.MyBatisSystemException: null + at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:97) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:439) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy140.findAll(Unknown Source) + at com.dora.scheduler.TaskScheduler.getActiveModels(TaskScheduler.java:119) + at com.dora.scheduler.TaskScheduler.dispatchTasks(TaskScheduler.java:40) + at jdk.internal.reflect.GeneratedMethodAccessor30.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +Caused by: org.apache.ibatis.exceptions.PersistenceException: +### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection +### The error may exist in file [C:\Users\admin\Desktop\new_1818ai\1818_user_server - 副本\target\classes\mapper\PointsConfigMapper.xml] +### The error may involve com.dora.mapper.PointsConfigMapper.findAll +### The error occurred while executing a query +### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:156) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at jdk.internal.reflect.GeneratedMethodAccessor28.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + ... 23 common frames omitted +Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:84) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + ... 29 common frames omitted +Caused by: java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + ... 41 common frames omitted +2026-01-13 14:06:41.590 [MessageBroker-14] ERROR com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Exception during pool initialization. +java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at jdk.internal.reflect.GeneratedMethodAccessor28.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy158.findProcessingTasksByProvider(Unknown Source) + at com.dora.scheduler.RunningHubPollingScheduler.pollRunningHubTasks(RunningHubPollingScheduler.java:57) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +2026-01-13 14:06:41.591 [MessageBroker-14] ERROR com.dora.scheduler.RunningHubPollingScheduler - RunningHub轮询调度器执行失败 +org.mybatis.spring.MyBatisSystemException: null + at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:97) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:439) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy158.findProcessingTasksByProvider(Unknown Source) + at com.dora.scheduler.RunningHubPollingScheduler.pollRunningHubTasks(RunningHubPollingScheduler.java:57) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +Caused by: org.apache.ibatis.exceptions.PersistenceException: +### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection +### The error may exist in file [C:\Users\admin\Desktop\new_1818ai\1818_user_server - 副本\target\classes\mapper\AiTaskMapper.xml] +### The error may involve com.dora.mapper.AiTaskMapper.findProcessingTasksByProvider +### The error occurred while executing a query +### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:156) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at jdk.internal.reflect.GeneratedMethodAccessor28.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + ... 23 common frames omitted +Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:84) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + ... 29 common frames omitted +Caused by: java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + ... 41 common frames omitted +2026-01-13 14:06:45.537 [MessageBroker-5] ERROR com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Exception during pool initialization. +java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at jdk.internal.reflect.GeneratedMethodAccessor28.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy140.findAll(Unknown Source) + at com.dora.scheduler.TaskScheduler.getActiveModels(TaskScheduler.java:119) + at com.dora.scheduler.TaskScheduler.dispatchTasks(TaskScheduler.java:40) + at jdk.internal.reflect.GeneratedMethodAccessor30.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +2026-01-13 14:06:45.537 [MessageBroker-5] ERROR o.s.s.support.TaskUtils$LoggingErrorHandler - Unexpected error occurred in scheduled task +org.mybatis.spring.MyBatisSystemException: null + at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:97) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:439) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy140.findAll(Unknown Source) + at com.dora.scheduler.TaskScheduler.getActiveModels(TaskScheduler.java:119) + at com.dora.scheduler.TaskScheduler.dispatchTasks(TaskScheduler.java:40) + at jdk.internal.reflect.GeneratedMethodAccessor30.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +Caused by: org.apache.ibatis.exceptions.PersistenceException: +### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection +### The error may exist in file [C:\Users\admin\Desktop\new_1818ai\1818_user_server - 副本\target\classes\mapper\PointsConfigMapper.xml] +### The error may involve com.dora.mapper.PointsConfigMapper.findAll +### The error occurred while executing a query +### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:156) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at jdk.internal.reflect.GeneratedMethodAccessor28.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + ... 23 common frames omitted +Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:84) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + ... 29 common frames omitted +Caused by: java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + ... 41 common frames omitted +2026-01-13 14:06:50.530 [MessageBroker-5] ERROR com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Exception during pool initialization. +java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at jdk.internal.reflect.GeneratedMethodAccessor28.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy140.findAll(Unknown Source) + at com.dora.scheduler.TaskScheduler.getActiveModels(TaskScheduler.java:119) + at com.dora.scheduler.TaskScheduler.dispatchTasks(TaskScheduler.java:40) + at jdk.internal.reflect.GeneratedMethodAccessor30.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +2026-01-13 14:06:50.531 [MessageBroker-5] ERROR o.s.s.support.TaskUtils$LoggingErrorHandler - Unexpected error occurred in scheduled task +org.mybatis.spring.MyBatisSystemException: null + at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:97) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:439) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy140.findAll(Unknown Source) + at com.dora.scheduler.TaskScheduler.getActiveModels(TaskScheduler.java:119) + at com.dora.scheduler.TaskScheduler.dispatchTasks(TaskScheduler.java:40) + at jdk.internal.reflect.GeneratedMethodAccessor30.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +Caused by: org.apache.ibatis.exceptions.PersistenceException: +### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection +### The error may exist in file [C:\Users\admin\Desktop\new_1818ai\1818_user_server - 副本\target\classes\mapper\PointsConfigMapper.xml] +### The error may involve com.dora.mapper.PointsConfigMapper.findAll +### The error occurred while executing a query +### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:156) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at jdk.internal.reflect.GeneratedMethodAccessor28.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + ... 23 common frames omitted +Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:84) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + ... 29 common frames omitted +Caused by: java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + ... 41 common frames omitted +2026-01-13 14:06:53.718 [MessageBroker-4] ERROR com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Exception during pool initialization. +java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at jdk.internal.reflect.GeneratedMethodAccessor28.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy158.findProcessingTasksByProvider(Unknown Source) + at com.dora.scheduler.SuChuangPollingScheduler.pollSuChuangTasks(SuChuangPollingScheduler.java:49) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +2026-01-13 14:06:53.718 [MessageBroker-4] ERROR com.dora.scheduler.SuChuangPollingScheduler - 速创轮询调度器执行失败 +org.mybatis.spring.MyBatisSystemException: null + at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:97) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:439) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy158.findProcessingTasksByProvider(Unknown Source) + at com.dora.scheduler.SuChuangPollingScheduler.pollSuChuangTasks(SuChuangPollingScheduler.java:49) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +Caused by: org.apache.ibatis.exceptions.PersistenceException: +### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection +### The error may exist in file [C:\Users\admin\Desktop\new_1818ai\1818_user_server - 副本\target\classes\mapper\AiTaskMapper.xml] +### The error may involve com.dora.mapper.AiTaskMapper.findProcessingTasksByProvider +### The error occurred while executing a query +### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:156) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at jdk.internal.reflect.GeneratedMethodAccessor28.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + ... 23 common frames omitted +Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:84) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + ... 29 common frames omitted +Caused by: java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + ... 41 common frames omitted +2026-01-13 14:06:55.532 [MessageBroker-16] ERROR com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Exception during pool initialization. +java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at jdk.internal.reflect.GeneratedMethodAccessor28.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy140.findAll(Unknown Source) + at com.dora.scheduler.TaskScheduler.getActiveModels(TaskScheduler.java:119) + at com.dora.scheduler.TaskScheduler.dispatchTasks(TaskScheduler.java:40) + at jdk.internal.reflect.GeneratedMethodAccessor30.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +2026-01-13 14:06:55.532 [MessageBroker-16] ERROR o.s.s.support.TaskUtils$LoggingErrorHandler - Unexpected error occurred in scheduled task +org.mybatis.spring.MyBatisSystemException: null + at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:97) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:439) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy140.findAll(Unknown Source) + at com.dora.scheduler.TaskScheduler.getActiveModels(TaskScheduler.java:119) + at com.dora.scheduler.TaskScheduler.dispatchTasks(TaskScheduler.java:40) + at jdk.internal.reflect.GeneratedMethodAccessor30.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +Caused by: org.apache.ibatis.exceptions.PersistenceException: +### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection +### The error may exist in file [C:\Users\admin\Desktop\new_1818ai\1818_user_server - 副本\target\classes\mapper\PointsConfigMapper.xml] +### The error may involve com.dora.mapper.PointsConfigMapper.findAll +### The error occurred while executing a query +### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:156) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at jdk.internal.reflect.GeneratedMethodAccessor28.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + ... 23 common frames omitted +Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:84) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + ... 29 common frames omitted +Caused by: java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + ... 41 common frames omitted +2026-01-13 14:07:00.574 [MessageBroker-16] ERROR com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Exception during pool initialization. +java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at jdk.internal.reflect.GeneratedMethodAccessor28.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy140.findAll(Unknown Source) + at com.dora.scheduler.TaskScheduler.getActiveModels(TaskScheduler.java:119) + at com.dora.scheduler.TaskScheduler.dispatchTasks(TaskScheduler.java:40) + at jdk.internal.reflect.GeneratedMethodAccessor30.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +2026-01-13 14:07:00.576 [MessageBroker-16] ERROR o.s.s.support.TaskUtils$LoggingErrorHandler - Unexpected error occurred in scheduled task +org.mybatis.spring.MyBatisSystemException: null + at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:97) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:439) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy140.findAll(Unknown Source) + at com.dora.scheduler.TaskScheduler.getActiveModels(TaskScheduler.java:119) + at com.dora.scheduler.TaskScheduler.dispatchTasks(TaskScheduler.java:40) + at jdk.internal.reflect.GeneratedMethodAccessor30.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +Caused by: org.apache.ibatis.exceptions.PersistenceException: +### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection +### The error may exist in file [C:\Users\admin\Desktop\new_1818ai\1818_user_server - 副本\target\classes\mapper\PointsConfigMapper.xml] +### The error may involve com.dora.mapper.PointsConfigMapper.findAll +### The error occurred while executing a query +### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:156) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at jdk.internal.reflect.GeneratedMethodAccessor28.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + ... 23 common frames omitted +Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:84) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + ... 29 common frames omitted +Caused by: java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + ... 41 common frames omitted +2026-01-13 14:07:02.746 [MessageBroker-15] ERROR com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Exception during pool initialization. +java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at jdk.internal.reflect.GeneratedMethodAccessor28.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy158.findProcessingTasksByProvider(Unknown Source) + at com.dora.scheduler.RunningHubPollingScheduler.pollRunningHubTasks(RunningHubPollingScheduler.java:57) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +2026-01-13 14:07:02.747 [MessageBroker-15] ERROR com.dora.scheduler.RunningHubPollingScheduler - RunningHub轮询调度器执行失败 +org.mybatis.spring.MyBatisSystemException: null + at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:97) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:439) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy158.findProcessingTasksByProvider(Unknown Source) + at com.dora.scheduler.RunningHubPollingScheduler.pollRunningHubTasks(RunningHubPollingScheduler.java:57) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +Caused by: org.apache.ibatis.exceptions.PersistenceException: +### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection +### The error may exist in file [C:\Users\admin\Desktop\new_1818ai\1818_user_server - 副本\target\classes\mapper\AiTaskMapper.xml] +### The error may involve com.dora.mapper.AiTaskMapper.findProcessingTasksByProvider +### The error occurred while executing a query +### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:156) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at jdk.internal.reflect.GeneratedMethodAccessor28.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + ... 23 common frames omitted +Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:84) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + ... 29 common frames omitted +Caused by: java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + ... 41 common frames omitted +2026-01-13 14:07:05.528 [MessageBroker-13] ERROR com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Exception during pool initialization. +java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at jdk.internal.reflect.GeneratedMethodAccessor28.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy140.findAll(Unknown Source) + at com.dora.scheduler.TaskScheduler.getActiveModels(TaskScheduler.java:119) + at com.dora.scheduler.TaskScheduler.dispatchTasks(TaskScheduler.java:40) + at jdk.internal.reflect.GeneratedMethodAccessor30.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +2026-01-13 14:07:05.529 [MessageBroker-13] ERROR o.s.s.support.TaskUtils$LoggingErrorHandler - Unexpected error occurred in scheduled task +org.mybatis.spring.MyBatisSystemException: null + at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:97) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:439) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy140.findAll(Unknown Source) + at com.dora.scheduler.TaskScheduler.getActiveModels(TaskScheduler.java:119) + at com.dora.scheduler.TaskScheduler.dispatchTasks(TaskScheduler.java:40) + at jdk.internal.reflect.GeneratedMethodAccessor30.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +Caused by: org.apache.ibatis.exceptions.PersistenceException: +### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection +### The error may exist in file [C:\Users\admin\Desktop\new_1818ai\1818_user_server - 副本\target\classes\mapper\PointsConfigMapper.xml] +### The error may involve com.dora.mapper.PointsConfigMapper.findAll +### The error occurred while executing a query +### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:156) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at jdk.internal.reflect.GeneratedMethodAccessor28.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + ... 23 common frames omitted +Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:84) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + ... 29 common frames omitted +Caused by: java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + ... 41 common frames omitted +2026-01-13 14:07:10.533 [MessageBroker-13] ERROR com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Exception during pool initialization. +java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at jdk.internal.reflect.GeneratedMethodAccessor28.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy140.findAll(Unknown Source) + at com.dora.scheduler.TaskScheduler.getActiveModels(TaskScheduler.java:119) + at com.dora.scheduler.TaskScheduler.dispatchTasks(TaskScheduler.java:40) + at jdk.internal.reflect.GeneratedMethodAccessor30.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +2026-01-13 14:07:10.533 [MessageBroker-13] ERROR o.s.s.support.TaskUtils$LoggingErrorHandler - Unexpected error occurred in scheduled task +org.mybatis.spring.MyBatisSystemException: null + at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:97) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:439) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy140.findAll(Unknown Source) + at com.dora.scheduler.TaskScheduler.getActiveModels(TaskScheduler.java:119) + at com.dora.scheduler.TaskScheduler.dispatchTasks(TaskScheduler.java:40) + at jdk.internal.reflect.GeneratedMethodAccessor30.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +Caused by: org.apache.ibatis.exceptions.PersistenceException: +### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection +### The error may exist in file [C:\Users\admin\Desktop\new_1818ai\1818_user_server - 副本\target\classes\mapper\PointsConfigMapper.xml] +### The error may involve com.dora.mapper.PointsConfigMapper.findAll +### The error occurred while executing a query +### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:156) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at jdk.internal.reflect.GeneratedMethodAccessor28.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + ... 23 common frames omitted +Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:84) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + ... 29 common frames omitted +Caused by: java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + ... 41 common frames omitted +2026-01-13 14:07:15.540 [MessageBroker-13] ERROR com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Exception during pool initialization. +java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at jdk.internal.reflect.GeneratedMethodAccessor28.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy140.findAll(Unknown Source) + at com.dora.scheduler.TaskScheduler.getActiveModels(TaskScheduler.java:119) + at com.dora.scheduler.TaskScheduler.dispatchTasks(TaskScheduler.java:40) + at jdk.internal.reflect.GeneratedMethodAccessor30.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +2026-01-13 14:07:15.541 [MessageBroker-13] ERROR o.s.s.support.TaskUtils$LoggingErrorHandler - Unexpected error occurred in scheduled task +org.mybatis.spring.MyBatisSystemException: null + at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:97) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:439) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy140.findAll(Unknown Source) + at com.dora.scheduler.TaskScheduler.getActiveModels(TaskScheduler.java:119) + at com.dora.scheduler.TaskScheduler.dispatchTasks(TaskScheduler.java:40) + at jdk.internal.reflect.GeneratedMethodAccessor30.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +Caused by: org.apache.ibatis.exceptions.PersistenceException: +### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection +### The error may exist in file [C:\Users\admin\Desktop\new_1818ai\1818_user_server - 副本\target\classes\mapper\PointsConfigMapper.xml] +### The error may involve com.dora.mapper.PointsConfigMapper.findAll +### The error occurred while executing a query +### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:156) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at jdk.internal.reflect.GeneratedMethodAccessor28.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + ... 23 common frames omitted +Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:84) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + ... 29 common frames omitted +Caused by: java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + ... 41 common frames omitted +2026-01-13 14:07:16.611 [MessageBroker-3] ERROR com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Exception during pool initialization. +java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at jdk.internal.reflect.GeneratedMethodAccessor28.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy158.findStuckTasks(Unknown Source) + at com.dora.scheduler.TaskScheduler.checkTasksTimeout(TaskScheduler.java:60) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +2026-01-13 14:07:16.612 [MessageBroker-3] ERROR o.s.s.support.TaskUtils$LoggingErrorHandler - Unexpected error occurred in scheduled task +org.mybatis.spring.MyBatisSystemException: null + at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:97) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:439) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy158.findStuckTasks(Unknown Source) + at com.dora.scheduler.TaskScheduler.checkTasksTimeout(TaskScheduler.java:60) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +Caused by: org.apache.ibatis.exceptions.PersistenceException: +### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection +### The error may exist in file [C:\Users\admin\Desktop\new_1818ai\1818_user_server - 副本\target\classes\mapper\AiTaskMapper.xml] +### The error may involve com.dora.mapper.AiTaskMapper.findStuckTasks +### The error occurred while executing a query +### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:156) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at jdk.internal.reflect.GeneratedMethodAccessor28.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + ... 23 common frames omitted +Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:84) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + ... 29 common frames omitted +Caused by: java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + ... 41 common frames omitted +2026-01-13 14:07:17.693 [http-nio-8082-exec-1] ERROR com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Exception during pool initialization. +java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:75) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectOne(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectOne(SqlSessionTemplate.java:160) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:87) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy107.selectByKeyValue(Unknown Source) + at com.dora.service.ApiKeyService.validateApiKeyForNonMember(ApiKeyService.java:186) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:354) + at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:716) + at com.dora.service.ApiKeyService$$SpringCGLIB$$0.validateApiKeyForNonMember() + at com.dora.config.ApiKeyAuthenticationFilter.doFilterInternal(ApiKeyAuthenticationFilter.java:92) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at com.dora.config.JwtAuthenticationFilter.doFilterInternal(JwtAuthenticationFilter.java:111) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:107) + at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:93) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:91) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90) + at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.context.SecurityContextHolderFilter.doFilter(SecurityContextHolderFilter.java:82) + at org.springframework.security.web.context.SecurityContextHolderFilter.doFilter(SecurityContextHolderFilter.java:69) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:62) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.session.DisableEncodeUrlFilter.doFilterInternal(DisableEncodeUrlFilter.java:42) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:233) + at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:191) + at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:113) + at org.springframework.web.servlet.handler.HandlerMappingIntrospector.lambda$createCacheFilter$3(HandlerMappingIntrospector.java:195) + at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:113) + at org.springframework.web.filter.CompositeFilter.doFilter(CompositeFilter.java:74) + at org.springframework.security.config.annotation.web.configuration.WebMvcSecurityConfiguration$CompositeFilterChainProxy.doFilter(WebMvcSecurityConfiguration.java:230) + at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:352) + at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:268) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167) + at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) + at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482) + at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115) + at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) + at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) + at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344) + at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:391) + at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) + at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:896) + at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1736) + at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) + at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) + at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) + at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63) + at java.base/java.lang.Thread.run(Thread.java:842) +2026-01-13 14:07:17.693 [http-nio-8082-exec-1] ERROR com.dora.config.ApiKeyAuthenticationFilter - API Key认证过程中发生错误: null +2026-01-13 14:07:18.746 [http-nio-8082-exec-3] ERROR com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Exception during pool initialization. +java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:75) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectOne(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectOne(SqlSessionTemplate.java:160) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:87) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy122.countAllWorkflows(Unknown Source) + at com.dora.service.impl.WorkflowServiceImpl.getCategories(WorkflowServiceImpl.java:60) + at com.dora.controller.WorkflowController.getCategories(WorkflowController.java:50) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:354) + at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196) + at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) + at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:768) + at org.springframework.validation.beanvalidation.MethodValidationInterceptor.invoke(MethodValidationInterceptor.java:174) + at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) + at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:768) + at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:720) + at com.dora.controller.WorkflowController$$SpringCGLIB$$0.getCategories() + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:255) + at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:188) + at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118) + at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:926) + at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:831) + at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) + at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1089) + at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979) + at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014) + at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903) + at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564) + at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885) + at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:206) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:110) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:110) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:108) + at org.springframework.security.web.FilterChainProxy.lambda$doFilterInternal$3(FilterChainProxy.java:231) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:365) + at org.springframework.security.web.access.intercept.AuthorizationFilter.doFilter(AuthorizationFilter.java:100) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:126) + at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:120) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:131) + at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:85) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:100) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:179) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at com.dora.config.ApiKeyAuthenticationFilter.doFilterInternal(ApiKeyAuthenticationFilter.java:63) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at com.dora.config.JwtAuthenticationFilter.doFilterInternal(JwtAuthenticationFilter.java:111) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:107) + at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:93) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:91) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90) + at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.context.SecurityContextHolderFilter.doFilter(SecurityContextHolderFilter.java:82) + at org.springframework.security.web.context.SecurityContextHolderFilter.doFilter(SecurityContextHolderFilter.java:69) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:62) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.session.DisableEncodeUrlFilter.doFilterInternal(DisableEncodeUrlFilter.java:42) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:233) + at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:191) + at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:113) + at org.springframework.web.servlet.handler.HandlerMappingIntrospector.lambda$createCacheFilter$3(HandlerMappingIntrospector.java:195) + at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:113) + at org.springframework.web.filter.CompositeFilter.doFilter(CompositeFilter.java:74) + at org.springframework.security.config.annotation.web.configuration.WebMvcSecurityConfiguration$CompositeFilterChainProxy.doFilter(WebMvcSecurityConfiguration.java:230) + at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:352) + at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:268) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167) + at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) + at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482) + at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115) + at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) + at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) + at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344) + at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:391) + at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) + at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:896) + at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1736) + at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) + at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) + at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) + at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63) + at java.base/java.lang.Thread.run(Thread.java:842) +2026-01-13 14:07:18.747 [http-nio-8082-exec-3] ERROR com.dora.service.impl.WorkflowServiceImpl - 获取工作流分类列表失败 +org.mybatis.spring.MyBatisSystemException: null + at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:97) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:439) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectOne(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectOne(SqlSessionTemplate.java:160) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:87) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy122.countAllWorkflows(Unknown Source) + at com.dora.service.impl.WorkflowServiceImpl.getCategories(WorkflowServiceImpl.java:60) + at com.dora.controller.WorkflowController.getCategories(WorkflowController.java:50) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:354) + at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196) + at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) + at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:768) + at org.springframework.validation.beanvalidation.MethodValidationInterceptor.invoke(MethodValidationInterceptor.java:174) + at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) + at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:768) + at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:720) + at com.dora.controller.WorkflowController$$SpringCGLIB$$0.getCategories() + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:255) + at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:188) + at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118) + at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:926) + at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:831) + at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) + at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1089) + at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979) + at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014) + at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903) + at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564) + at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885) + at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:206) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:110) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:110) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:108) + at org.springframework.security.web.FilterChainProxy.lambda$doFilterInternal$3(FilterChainProxy.java:231) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:365) + at org.springframework.security.web.access.intercept.AuthorizationFilter.doFilter(AuthorizationFilter.java:100) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:126) + at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:120) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:131) + at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:85) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:100) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:179) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at com.dora.config.ApiKeyAuthenticationFilter.doFilterInternal(ApiKeyAuthenticationFilter.java:63) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at com.dora.config.JwtAuthenticationFilter.doFilterInternal(JwtAuthenticationFilter.java:111) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:107) + at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:93) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:91) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90) + at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.context.SecurityContextHolderFilter.doFilter(SecurityContextHolderFilter.java:82) + at org.springframework.security.web.context.SecurityContextHolderFilter.doFilter(SecurityContextHolderFilter.java:69) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:62) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.session.DisableEncodeUrlFilter.doFilterInternal(DisableEncodeUrlFilter.java:42) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:233) + at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:191) + at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:113) + at org.springframework.web.servlet.handler.HandlerMappingIntrospector.lambda$createCacheFilter$3(HandlerMappingIntrospector.java:195) + at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:113) + at org.springframework.web.filter.CompositeFilter.doFilter(CompositeFilter.java:74) + at org.springframework.security.config.annotation.web.configuration.WebMvcSecurityConfiguration$CompositeFilterChainProxy.doFilter(WebMvcSecurityConfiguration.java:230) + at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:352) + at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:268) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167) + at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) + at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482) + at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115) + at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) + at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) + at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344) + at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:391) + at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) + at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:896) + at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1736) + at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) + at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) + at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) + at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63) + at java.base/java.lang.Thread.run(Thread.java:842) +Caused by: org.apache.ibatis.exceptions.PersistenceException: +### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection +### The error may exist in file [C:\Users\admin\Desktop\new_1818ai\1818_user_server - 副本\target\classes\mapper\WorkflowMapper.xml] +### The error may involve com.dora.mapper.WorkflowMapper.countAllWorkflows +### The error occurred while executing a query +### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:156) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:75) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + ... 130 common frames omitted +Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:84) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + ... 138 common frames omitted +Caused by: java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + ... 150 common frames omitted +2026-01-13 14:07:18.748 [http-nio-8082-exec-3] ERROR com.dora.controller.WorkflowController - 获取工作流分类列表失败 +com.dora.exception.BusinessException: 获取工作流分类列表失败 + at com.dora.service.impl.WorkflowServiceImpl.getCategories(WorkflowServiceImpl.java:101) + at com.dora.controller.WorkflowController.getCategories(WorkflowController.java:50) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:354) + at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196) + at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) + at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:768) + at org.springframework.validation.beanvalidation.MethodValidationInterceptor.invoke(MethodValidationInterceptor.java:174) + at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) + at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:768) + at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:720) + at com.dora.controller.WorkflowController$$SpringCGLIB$$0.getCategories() + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:255) + at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:188) + at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118) + at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:926) + at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:831) + at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) + at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1089) + at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979) + at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014) + at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903) + at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564) + at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885) + at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:206) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:110) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:110) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:108) + at org.springframework.security.web.FilterChainProxy.lambda$doFilterInternal$3(FilterChainProxy.java:231) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:365) + at org.springframework.security.web.access.intercept.AuthorizationFilter.doFilter(AuthorizationFilter.java:100) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:126) + at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:120) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:131) + at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:85) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:100) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:179) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at com.dora.config.ApiKeyAuthenticationFilter.doFilterInternal(ApiKeyAuthenticationFilter.java:63) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at com.dora.config.JwtAuthenticationFilter.doFilterInternal(JwtAuthenticationFilter.java:111) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:107) + at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:93) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:91) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90) + at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.context.SecurityContextHolderFilter.doFilter(SecurityContextHolderFilter.java:82) + at org.springframework.security.web.context.SecurityContextHolderFilter.doFilter(SecurityContextHolderFilter.java:69) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:62) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.session.DisableEncodeUrlFilter.doFilterInternal(DisableEncodeUrlFilter.java:42) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:233) + at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:191) + at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:113) + at org.springframework.web.servlet.handler.HandlerMappingIntrospector.lambda$createCacheFilter$3(HandlerMappingIntrospector.java:195) + at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:113) + at org.springframework.web.filter.CompositeFilter.doFilter(CompositeFilter.java:74) + at org.springframework.security.config.annotation.web.configuration.WebMvcSecurityConfiguration$CompositeFilterChainProxy.doFilter(WebMvcSecurityConfiguration.java:230) + at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:352) + at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:268) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167) + at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) + at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482) + at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115) + at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) + at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) + at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344) + at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:391) + at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) + at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:896) + at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1736) + at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) + at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) + at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) + at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63) + at java.base/java.lang.Thread.run(Thread.java:842) +2026-01-13 14:07:19.804 [http-nio-8082-exec-2] ERROR com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Exception during pool initialization. +java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at jdk.internal.reflect.GeneratedMethodAccessor28.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy135.selectAllEnabled(Unknown Source) + at com.dora.service.impl.BannerServiceImpl.getAllEnabledBanners(BannerServiceImpl.java:30) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:354) + at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:716) + at com.dora.service.impl.BannerServiceImpl$$SpringCGLIB$$0.getAllEnabledBanners() + at com.dora.controller.BannerController.getBannerList(BannerController.java:31) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:255) + at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:188) + at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118) + at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:926) + at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:831) + at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) + at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1089) + at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979) + at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014) + at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903) + at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564) + at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885) + at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:206) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:110) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:110) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:108) + at org.springframework.security.web.FilterChainProxy.lambda$doFilterInternal$3(FilterChainProxy.java:231) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:365) + at org.springframework.security.web.access.intercept.AuthorizationFilter.doFilter(AuthorizationFilter.java:100) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:126) + at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:120) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:131) + at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:85) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:100) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:179) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at com.dora.config.ApiKeyAuthenticationFilter.doFilterInternal(ApiKeyAuthenticationFilter.java:63) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at com.dora.config.JwtAuthenticationFilter.doFilterInternal(JwtAuthenticationFilter.java:111) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:107) + at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:93) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:91) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90) + at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.context.SecurityContextHolderFilter.doFilter(SecurityContextHolderFilter.java:82) + at org.springframework.security.web.context.SecurityContextHolderFilter.doFilter(SecurityContextHolderFilter.java:69) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:62) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.session.DisableEncodeUrlFilter.doFilterInternal(DisableEncodeUrlFilter.java:42) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:233) + at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:191) + at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:113) + at org.springframework.web.servlet.handler.HandlerMappingIntrospector.lambda$createCacheFilter$3(HandlerMappingIntrospector.java:195) + at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:113) + at org.springframework.web.filter.CompositeFilter.doFilter(CompositeFilter.java:74) + at org.springframework.security.config.annotation.web.configuration.WebMvcSecurityConfiguration$CompositeFilterChainProxy.doFilter(WebMvcSecurityConfiguration.java:230) + at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:352) + at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:268) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167) + at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) + at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482) + at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115) + at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) + at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) + at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344) + at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:391) + at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) + at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:896) + at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1736) + at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) + at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) + at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) + at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63) + at java.base/java.lang.Thread.run(Thread.java:842) +2026-01-13 14:07:19.806 [http-nio-8082-exec-2] ERROR com.dora.controller.BannerController - 获取Banner列表失败 +org.mybatis.spring.MyBatisSystemException: null + at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:97) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:439) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy135.selectAllEnabled(Unknown Source) + at com.dora.service.impl.BannerServiceImpl.getAllEnabledBanners(BannerServiceImpl.java:30) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:354) + at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:716) + at com.dora.service.impl.BannerServiceImpl$$SpringCGLIB$$0.getAllEnabledBanners() + at com.dora.controller.BannerController.getBannerList(BannerController.java:31) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:255) + at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:188) + at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118) + at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:926) + at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:831) + at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) + at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1089) + at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979) + at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014) + at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903) + at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564) + at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885) + at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:206) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:110) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:110) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:108) + at org.springframework.security.web.FilterChainProxy.lambda$doFilterInternal$3(FilterChainProxy.java:231) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:365) + at org.springframework.security.web.access.intercept.AuthorizationFilter.doFilter(AuthorizationFilter.java:100) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:126) + at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:120) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:131) + at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:85) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:100) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:179) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at com.dora.config.ApiKeyAuthenticationFilter.doFilterInternal(ApiKeyAuthenticationFilter.java:63) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at com.dora.config.JwtAuthenticationFilter.doFilterInternal(JwtAuthenticationFilter.java:111) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:107) + at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:93) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:91) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90) + at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.context.SecurityContextHolderFilter.doFilter(SecurityContextHolderFilter.java:82) + at org.springframework.security.web.context.SecurityContextHolderFilter.doFilter(SecurityContextHolderFilter.java:69) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:62) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.session.DisableEncodeUrlFilter.doFilterInternal(DisableEncodeUrlFilter.java:42) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:233) + at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:191) + at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:113) + at org.springframework.web.servlet.handler.HandlerMappingIntrospector.lambda$createCacheFilter$3(HandlerMappingIntrospector.java:195) + at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:113) + at org.springframework.web.filter.CompositeFilter.doFilter(CompositeFilter.java:74) + at org.springframework.security.config.annotation.web.configuration.WebMvcSecurityConfiguration$CompositeFilterChainProxy.doFilter(WebMvcSecurityConfiguration.java:230) + at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:352) + at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:268) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167) + at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) + at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482) + at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115) + at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) + at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) + at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344) + at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:391) + at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) + at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:896) + at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1736) + at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) + at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) + at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) + at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63) + at java.base/java.lang.Thread.run(Thread.java:842) +Caused by: org.apache.ibatis.exceptions.PersistenceException: +### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection +### The error may exist in file [C:\Users\admin\Desktop\new_1818ai\1818_user_server - 副本\target\classes\mapper\BannerMapper.xml] +### The error may involve com.dora.mapper.BannerMapper.selectAllEnabled +### The error occurred while executing a query +### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:156) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at jdk.internal.reflect.GeneratedMethodAccessor28.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + ... 125 common frames omitted +Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:84) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + ... 131 common frames omitted +Caused by: java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + ... 143 common frames omitted +2026-01-13 14:07:20.872 [http-nio-8082-exec-4] ERROR com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Exception during pool initialization. +java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:75) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectOne(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectOne(SqlSessionTemplate.java:160) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:87) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy137.countAllCourses(Unknown Source) + at com.dora.service.impl.CourseServiceImpl.getCategories(CourseServiceImpl.java:66) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:354) + at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:716) + at com.dora.service.impl.CourseServiceImpl$$SpringCGLIB$$0.getCategories() + at com.dora.controller.CourseController.getCategories(CourseController.java:45) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:255) + at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:188) + at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118) + at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:926) + at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:831) + at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) + at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1089) + at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979) + at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014) + at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903) + at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564) + at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885) + at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:206) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:110) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:110) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:108) + at org.springframework.security.web.FilterChainProxy.lambda$doFilterInternal$3(FilterChainProxy.java:231) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:365) + at org.springframework.security.web.access.intercept.AuthorizationFilter.doFilter(AuthorizationFilter.java:100) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:126) + at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:120) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:131) + at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:85) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:100) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:179) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at com.dora.config.ApiKeyAuthenticationFilter.doFilterInternal(ApiKeyAuthenticationFilter.java:63) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at com.dora.config.JwtAuthenticationFilter.doFilterInternal(JwtAuthenticationFilter.java:111) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:107) + at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:93) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:91) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90) + at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.context.SecurityContextHolderFilter.doFilter(SecurityContextHolderFilter.java:82) + at org.springframework.security.web.context.SecurityContextHolderFilter.doFilter(SecurityContextHolderFilter.java:69) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:62) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.session.DisableEncodeUrlFilter.doFilterInternal(DisableEncodeUrlFilter.java:42) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:233) + at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:191) + at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:113) + at org.springframework.web.servlet.handler.HandlerMappingIntrospector.lambda$createCacheFilter$3(HandlerMappingIntrospector.java:195) + at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:113) + at org.springframework.web.filter.CompositeFilter.doFilter(CompositeFilter.java:74) + at org.springframework.security.config.annotation.web.configuration.WebMvcSecurityConfiguration$CompositeFilterChainProxy.doFilter(WebMvcSecurityConfiguration.java:230) + at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:352) + at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:268) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167) + at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) + at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482) + at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115) + at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) + at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) + at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344) + at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:391) + at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) + at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:896) + at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1736) + at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) + at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) + at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) + at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63) + at java.base/java.lang.Thread.run(Thread.java:842) +2026-01-13 14:07:20.873 [http-nio-8082-exec-4] ERROR com.dora.service.impl.CourseServiceImpl - 获取课程分类列表失败 +org.mybatis.spring.MyBatisSystemException: null + at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:97) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:439) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectOne(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectOne(SqlSessionTemplate.java:160) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:87) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy137.countAllCourses(Unknown Source) + at com.dora.service.impl.CourseServiceImpl.getCategories(CourseServiceImpl.java:66) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:354) + at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:716) + at com.dora.service.impl.CourseServiceImpl$$SpringCGLIB$$0.getCategories() + at com.dora.controller.CourseController.getCategories(CourseController.java:45) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:255) + at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:188) + at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118) + at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:926) + at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:831) + at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) + at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1089) + at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979) + at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014) + at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903) + at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564) + at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885) + at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:206) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:110) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:110) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:108) + at org.springframework.security.web.FilterChainProxy.lambda$doFilterInternal$3(FilterChainProxy.java:231) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:365) + at org.springframework.security.web.access.intercept.AuthorizationFilter.doFilter(AuthorizationFilter.java:100) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:126) + at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:120) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:131) + at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:85) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:100) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:179) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at com.dora.config.ApiKeyAuthenticationFilter.doFilterInternal(ApiKeyAuthenticationFilter.java:63) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at com.dora.config.JwtAuthenticationFilter.doFilterInternal(JwtAuthenticationFilter.java:111) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:107) + at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:93) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:91) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90) + at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.context.SecurityContextHolderFilter.doFilter(SecurityContextHolderFilter.java:82) + at org.springframework.security.web.context.SecurityContextHolderFilter.doFilter(SecurityContextHolderFilter.java:69) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:62) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.session.DisableEncodeUrlFilter.doFilterInternal(DisableEncodeUrlFilter.java:42) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:233) + at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:191) + at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:113) + at org.springframework.web.servlet.handler.HandlerMappingIntrospector.lambda$createCacheFilter$3(HandlerMappingIntrospector.java:195) + at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:113) + at org.springframework.web.filter.CompositeFilter.doFilter(CompositeFilter.java:74) + at org.springframework.security.config.annotation.web.configuration.WebMvcSecurityConfiguration$CompositeFilterChainProxy.doFilter(WebMvcSecurityConfiguration.java:230) + at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:352) + at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:268) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167) + at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) + at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482) + at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115) + at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) + at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) + at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344) + at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:391) + at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) + at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:896) + at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1736) + at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) + at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) + at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) + at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63) + at java.base/java.lang.Thread.run(Thread.java:842) +Caused by: org.apache.ibatis.exceptions.PersistenceException: +### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection +### The error may exist in file [C:\Users\admin\Desktop\new_1818ai\1818_user_server - 副本\target\classes\mapper\CourseMapper.xml] +### The error may involve com.dora.mapper.CourseMapper.countAllCourses +### The error occurred while executing a query +### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:156) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:75) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + ... 124 common frames omitted +Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:84) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + ... 132 common frames omitted +Caused by: java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + ... 144 common frames omitted +2026-01-13 14:07:20.874 [http-nio-8082-exec-4] ERROR com.dora.controller.CourseController - 获取课程分类列表失败 +com.dora.exception.BusinessException: 获取课程分类列表失败 + at com.dora.service.impl.CourseServiceImpl.getCategories(CourseServiceImpl.java:107) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:354) + at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:716) + at com.dora.service.impl.CourseServiceImpl$$SpringCGLIB$$0.getCategories() + at com.dora.controller.CourseController.getCategories(CourseController.java:45) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:255) + at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:188) + at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118) + at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:926) + at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:831) + at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) + at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1089) + at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979) + at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014) + at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903) + at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564) + at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885) + at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:206) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:110) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:110) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:108) + at org.springframework.security.web.FilterChainProxy.lambda$doFilterInternal$3(FilterChainProxy.java:231) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:365) + at org.springframework.security.web.access.intercept.AuthorizationFilter.doFilter(AuthorizationFilter.java:100) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:126) + at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:120) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:131) + at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:85) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:100) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:179) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at com.dora.config.ApiKeyAuthenticationFilter.doFilterInternal(ApiKeyAuthenticationFilter.java:63) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at com.dora.config.JwtAuthenticationFilter.doFilterInternal(JwtAuthenticationFilter.java:111) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:107) + at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:93) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:91) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90) + at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.context.SecurityContextHolderFilter.doFilter(SecurityContextHolderFilter.java:82) + at org.springframework.security.web.context.SecurityContextHolderFilter.doFilter(SecurityContextHolderFilter.java:69) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:62) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.session.DisableEncodeUrlFilter.doFilterInternal(DisableEncodeUrlFilter.java:42) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) + at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:233) + at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:191) + at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:113) + at org.springframework.web.servlet.handler.HandlerMappingIntrospector.lambda$createCacheFilter$3(HandlerMappingIntrospector.java:195) + at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:113) + at org.springframework.web.filter.CompositeFilter.doFilter(CompositeFilter.java:74) + at org.springframework.security.config.annotation.web.configuration.WebMvcSecurityConfiguration$CompositeFilterChainProxy.doFilter(WebMvcSecurityConfiguration.java:230) + at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:352) + at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:268) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) + at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167) + at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) + at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482) + at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115) + at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) + at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) + at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344) + at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:391) + at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) + at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:896) + at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1736) + at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) + at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) + at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) + at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63) + at java.base/java.lang.Thread.run(Thread.java:842) +2026-01-13 14:07:21.924 [MessageBroker-13] ERROR com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Exception during pool initialization. +java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at jdk.internal.reflect.GeneratedMethodAccessor28.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy140.findAll(Unknown Source) + at com.dora.scheduler.TaskScheduler.getActiveModels(TaskScheduler.java:119) + at com.dora.scheduler.TaskScheduler.dispatchTasks(TaskScheduler.java:40) + at jdk.internal.reflect.GeneratedMethodAccessor30.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +2026-01-13 14:07:21.925 [MessageBroker-13] ERROR o.s.s.support.TaskUtils$LoggingErrorHandler - Unexpected error occurred in scheduled task +org.mybatis.spring.MyBatisSystemException: null + at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:97) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:439) + at jdk.proxy2/jdk.proxy2.$Proxy106.selectList(Unknown Source) + at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) + at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) + at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) + at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) + at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) + at jdk.proxy2/jdk.proxy2.$Proxy140.findAll(Unknown Source) + at com.dora.scheduler.TaskScheduler.getActiveModels(TaskScheduler.java:119) + at com.dora.scheduler.TaskScheduler.dispatchTasks(TaskScheduler.java:40) + at jdk.internal.reflect.GeneratedMethodAccessor30.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) + at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) + at io.micrometer.observation.Observation.observe(Observation.java:499) + at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124) + at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) + at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) + at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) + at java.base/java.lang.Thread.run(Thread.java:842) +Caused by: org.apache.ibatis.exceptions.PersistenceException: +### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection +### The error may exist in file [C:\Users\admin\Desktop\new_1818ai\1818_user_server - 副本\target\classes\mapper\PointsConfigMapper.xml] +### The error may involve com.dora.mapper.PointsConfigMapper.findAll +### The error occurred while executing a query +### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:156) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) + at jdk.internal.reflect.GeneratedMethodAccessor28.invoke(Unknown Source) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) + ... 23 common frames omitted +Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:84) + at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80) + at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67) + at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:348) + at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:89) + at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:64) + at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) + at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) + at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) + at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151) + at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59) + at jdk.proxy2/jdk.proxy2.$Proxy207.query(Unknown Source) + at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) + ... 29 common frames omitted +Caused by: java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:438) + at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) + at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:189) + at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) + at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359) + at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201) + at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470) + at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) + at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:100) + at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) + at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) + at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) + at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) + ... 41 common frames omitted +2026-01-13 14:07:22.979 [http-nio-8082-exec-5] ERROR com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Exception during pool initialization. +java.sql.SQLException: Access denied for user '1818ai'@'localhost' (using password: YES) + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815) + at com.mysql.cj.jdbc.ConnectionImpl.
{{ model.description }}
SignatureDoesNotMatch
InvalidPolicyDocument
{{ balance?.currentPoints || 0 }}
- {{ balance.willExpireSoon ? '即将过期' : '有效期至' }}: - {{ formatDate(balance.pointsExpiresAt) }} -
状态: {task.status}
进度: {task.progress}%
{task.message}
状态: {{ task.status }}
{{ task.message }}