diff --git a/docs/script/sql/ruoyi-ai-v3_mysql8.sql b/docs/script/sql/ruoyi-ai-v3_mysql8.sql index 58d14837..805c932d 100644 --- a/docs/script/sql/ruoyi-ai-v3_mysql8.sql +++ b/docs/script/sql/ruoyi-ai-v3_mysql8.sql @@ -1,58 +1,22 @@ +/* + Navicat MySQL Dump SQL + + Source Server : 本地 + Source Server Type : MySQL + Source Server Version : 80045 (8.0.45) + Source Host : localhost:3306 + Source Schema : ruoyi-ai + + Target Server Type : MySQL + Target Server Version : 80045 (8.0.45) + File Encoding : 65001 + + Date: 27/02/2026 13:59:20 +*/ SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; --- ---------------------------- --- Table structure for aihuman_config --- ---------------------------- -DROP TABLE IF EXISTS `aihuman_config`; -CREATE TABLE `aihuman_config` ( - `id` int NOT NULL AUTO_INCREMENT, - `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL, - `model_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL, - `model_path` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL, - `model_params` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL, - `agent_params` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL, - `create_time` datetime NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP, - `update_time` datetime NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP, - `status` int NULL DEFAULT NULL, - `publish` int NULL DEFAULT NULL, - `create_dept` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL, - `create_by` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL, - `update_by` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL, - `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户Id', - PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 14 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '数字人配置信息' ROW_FORMAT = DYNAMIC; - --- ---------------------------- --- Records of aihuman_config --- ---------------------------- -INSERT INTO `aihuman_config` VALUES (9, '关爱老婆数字人(梅朵)', '梅朵吉祥物', '/Live2D/models/梅朵吉祥物/梅朵吉祥物.model3.json', '{\n \"Version\": 3,\n \"FileReferences\": {\n \"Moc\": \"梅朵吉祥物.moc3\",\n \"Textures\": [\n \"梅朵吉祥物.4096/texture_00.png\",\n \"梅朵吉祥物.4096/texture_01.png\"\n ],\n \"Physics\": \"梅朵吉祥物.physics3.json\",\n \"DisplayInfo\": \"梅朵吉祥物.cdi3.json\",\n \"MotionSync\": \"梅朵吉祥物.motionsync3.json\",\n \"Expressions\": [\n {\n \"Name\": \"kaixin\",\n \"File\": \"kaixin.exp3.json\"\n },\n {\n \"Name\": \"maozi\",\n \"File\": \"maozi.exp3.json\"\n },\n {\n \"Name\": \"mouth open\",\n \"File\": \"mouth open.exp3.json\"\n },\n {\n \"Name\": \"shibai\",\n \"File\": \"shibai.exp3.json\"\n },\n {\n \"Name\": \"yinchen\",\n \"File\": \"yinchen.exp3.json\"\n }\n ],\n \"Motions\": {\n \"\": [\n {\n \"File\": \"mouth.motion3.json\"\n }\n ]\n }\n },\n \"Groups\": [\n {\n \"Target\": \"Parameter\",\n \"Name\": \"LipSync\",\n \"Ids\": [\n \"ParamMouthForm\",\n \"ParamMouthOpenY\"\n ]\n },\n {\n \"Target\": \"Parameter\",\n \"Name\": \"EyeBlink\",\n \"Ids\": [\n \"ParamEyeLOpen\",\n \"ParamEyeROpen\"\n ]\n }\n ],\n \"HitAreas\": []\n}', '{\n \"bot_id\": \"7504596188201746470\",\n \"user_id\": \"7376476310010937396\",\n \"stream\": true,\n \"auto_save_history\": true\n}', '2025-09-29 16:36:46', '2025-09-29 16:36:46', 0, 1, NULL, NULL, '1', 0); -INSERT INTO `aihuman_config` VALUES (10, '关爱老婆数字人(K)', 'kei_vowels_pro', '/Live2D/models/kei_vowels_pro/kei_vowels_pro.model3.json', '{\n \"Version\": 3,\n \"FileReferences\": {\n \"Moc\": \"kei_vowels_pro.moc3\",\n \"Textures\": [\n \"kei_vowels_pro.2048/texture_00.png\"\n ],\n \"Physics\": \"kei_vowels_pro.physics3.json\",\n \"DisplayInfo\": \"kei_vowels_pro.cdi3.json\",\n \"MotionSync\": \"kei_vowels_pro.motionsync3.json\",\n \"Motions\": {\n \"\": [\n {\n \"File\": \"motions/01_kei_en.motion3.json\",\n \"Sound\": \"sounds/01_kei_en.wav\",\n \"MotionSync\": \"Vowels_CRI\"\n },\n {\n \"File\": \"motions/01_kei_jp.motion3.json\",\n \"Sound\": \"sounds/01_kei_jp.wav\",\n \"MotionSync\": \"Vowels_CRI\"\n },\n {\n \"File\": \"motions/01_kei_ko.motion3.json\",\n \"Sound\": \"sounds/01_kei_ko.wav\",\n \"MotionSync\": \"Vowels_CRI\"\n },\n {\n \"File\": \"motions/01_kei_zh.motion3.json\",\n \"Sound\": \"sounds/01_kei_zh.wav\",\n \"MotionSync\": \"Vowels_CRI\"\n }\n ]\n }\n },\n \"Groups\": [\n {\n \"Target\": \"Parameter\",\n \"Name\": \"LipSync\",\n \"Ids\": []\n },\n {\n \"Target\": \"Parameter\",\n \"Name\": \"EyeBlink\",\n \"Ids\": [\n \"ParamEyeLOpen\",\n \"ParamEyeROpen\"\n ]\n }\n ],\n \"HitAreas\": [\n {\n \"Id\": \"HitAreaHead\",\n \"Name\": \"Head\"\n }\n ]\n}', '3', '2025-09-29 16:35:27', '2025-09-29 16:35:27', 0, 1, NULL, NULL, '1', 0); -INSERT INTO `aihuman_config` VALUES (11, '关爱老婆数字人(March 7th)', 'March 7th', '/Live2D/models/March 7th/March 7th.model3.json', '{\n \"Version\": 3,\n \"FileReferences\": {\n \"Moc\": \"March 7th.moc3\",\n \"Textures\": [\n \"March 7th.4096/texture_00.png\",\n \"March 7th.4096/texture_01.png\"\n ],\n \"Physics\": \"March 7th.physics3.json\",\n \"DisplayInfo\": \"March 7th.cdi3.json\",\n \"Expressions\": [\n {\n \"Name\": \"捂脸\",\n \"File\": \"1.exp3.json\"\n },\n {\n \"Name\": \"比耶\",\n \"File\": \"2.exp3.json\"\n },\n {\n \"Name\": \"照相\",\n \"File\": \"3.exp3.json\"\n },\n {\n \"Name\": \"脸红\",\n \"File\": \"4.exp3.json\"\n },\n {\n \"Name\": \"黑脸\",\n \"File\": \"5.exp3.json\"\n },\n {\n \"Name\": \"哭\",\n \"File\": \"6.exp3.json\"\n },\n {\n \"Name\": \"流汗\",\n \"File\": \"7.exp3.json\"\n },\n {\n \"Name\": \"星星\",\n \"File\": \"8.exp3.json\"\n }\n ]\n },\n \"Groups\": [\n {\n \"Target\": \"Parameter\",\n \"Name\": \"EyeBlink\",\n \"Ids\": [\n \"ParamEyeLOpen\",\n \"ParamEyeROpen\"\n ]\n },\n {\n \"Target\": \"Parameter\",\n \"Name\": \"LipSync\",\n \"Ids\": [\n \"ParamMouthOpenY\"\n ]\n }\n ],\n \"HitAreas\": []\n}', '3', '2025-09-29 21:09:26', '2025-09-29 21:09:28', 0, 1, NULL, NULL, NULL, 0); -INSERT INTO `aihuman_config` VALUES (12, '关爱老婆数字人(pachan)', 'pachan', '/Live2D/models/pachan/pachan.model3.json', '{\n \"Version\": 3,\n \"FileReferences\": {\n \"Moc\": \"pachirisu anime girl - top half.moc3\",\n \"Textures\": [\n \"pachirisu anime girl - top half.4096/texture_00.png\"\n ],\n \"Physics\": \"pachirisu anime girl - top half.physics3.json\",\n \"DisplayInfo\": \"pachirisu anime girl - top half.cdi3.json\"\n },\n \"Groups\": [\n {\n \"Target\": \"Parameter\",\n \"Name\": \"EyeBlink\",\n \"Ids\": []\n },\n {\n \"Target\": \"Parameter\",\n \"Name\": \"LipSync\",\n \"Ids\": []\n }\n ]\n}', NULL, '2025-10-05 19:49:56', '2025-10-05 19:49:56', 0, 1, NULL, NULL, NULL, 0); -INSERT INTO `aihuman_config` VALUES (13, '关爱老婆数字人(230108)', '230108', '/Live2D/models/230108/230108.model3.json', '{\n \"Version\": 3,\n \"FileReferences\": {\n \"Moc\": \"230108.moc3\",\n \"Textures\": [\n \"230108.4096/texture_00.png\"\n ],\n \"Physics\": \"230108.physics3.json\",\n \"DisplayInfo\": \"230108.cdi3.json\"\n },\n \"Groups\": [\n {\n \"Target\": \"Parameter\",\n \"Name\": \"LipSync\",\n \"Ids\": [\n \"ParamMouthOpenY\"\n ]\n },\n {\n \"Target\": \"Parameter\",\n \"Name\": \"EyeBlink\",\n \"Ids\": [\n \"ParamEyeLOpen\",\n \"ParamEyeROpen\"\n ]\n }\n ]\n}', NULL, '2025-10-06 19:28:20', '2025-10-06 19:28:23', 0, 1, NULL, NULL, NULL, 0); - --- ---------------------------- --- Table structure for aihuman_info --- ---------------------------- -DROP TABLE IF EXISTS `aihuman_info`; -CREATE TABLE `aihuman_info` ( - `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID', - `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '交互名称', - `content` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '交互内容', - `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间', - `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间', - `del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '删除标志(0代表存在 2代表删除)', - `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户Id', - PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = 'AI人类交互信息表' ROW_FORMAT = DYNAMIC; - --- ---------------------------- --- Records of aihuman_info --- ---------------------------- -INSERT INTO `aihuman_info` VALUES (1, '1', '1', '2025-09-26 18:02:00', '2025-09-26 18:02:02', '0', 0); - -- ---------------------------- -- Table structure for chat_config -- ---------------------------- @@ -139,8 +103,8 @@ CREATE TABLE `chat_model` ( -- ---------------------------- -- Records of chat_model -- ---------------------------- -INSERT INTO `chat_model` VALUES (2000585866022060033, 'chat', 'deepseek/deepseek-v3.2', 'openai', 'deepseek', 1, '1', 'Y', 'Y', 1, 'https://api.ppinfra.com/openai', 'sk_xx', 103, 1, '2025-12-15 23:16:54', 1, '2026-02-06 01:02:31', 'DeepSeek-V3.2 是一款在高效推理、复杂推理能力与智能体场景中表现突出的领先模型。其基于 DeepSeek Sparse Attention(DSA)稀疏注意力机制,在显著降低计算开销的同时优化长上下文性能;通过可扩展强化学习框架,整体能力达到 GPT-5 同级,高算力版本 V3.2-Speciale 更在推理表现上接近 Gemini-3.0-Pro;同时,模型依托大型智能体任务合成管线,具备更强的工具调用与多步骤决策能力,并在 2025 年 IMO 与 IOI 中取得金牌级表现。作为 MaaS 平台,我们已对 DeepSeek-V3.2 完成深度适配,通过动态调度、批处理加速、低延迟推理与企业级 SLA 保障,进一步增强其在企业生产环境中的稳定性、性价比与可控性,适用于搜索、问答、智能体、代码、数据处理等多类高价值场景。', 0); -INSERT INTO `chat_model` VALUES (2007528268536287233, 'vector', 'baai/bge-m3', 'openai', 'bge-m3', 0, '1', 'N', 'Y', 1, 'https://api.ppinfra.com/openai', 'sk_xx', 103, 1, '2026-01-04 03:03:32', 1, '2026-02-06 01:02:35', 'bge-large-zh-v1.5', 0); +INSERT INTO `chat_model` VALUES (2000585866022060033, 'chat', 'deepseek/deepseek-v3.2', 'ppio', 'deepseek', 1, '1', 'Y', 'Y', 1, 'https://api.ppinfra.com/openai', 'sk_xx', 103, 1, '2025-12-15 23:16:54', 1, '2026-02-25 21:46:08', 'DeepSeek-V3.2 是一款在高效推理、复杂推理能力与智能体场景中表现突出的领先模型。其基于 DeepSeek Sparse Attention(DSA)稀疏注意力机制,在显著降低计算开销的同时优化长上下文性能;通过可扩展强化学习框架,整体能力达到 GPT-5 同级,高算力版本 V3.2-Speciale 更在推理表现上接近 Gemini-3.0-Pro;同时,模型依托大型智能体任务合成管线,具备更强的工具调用与多步骤决策能力,并在 2025 年 IMO 与 IOI 中取得金牌级表现。作为 MaaS 平台,我们已对 DeepSeek-V3.2 完成深度适配,通过动态调度、批处理加速、低延迟推理与企业级 SLA 保障,进一步增强其在企业生产环境中的稳定性、性价比与可控性,适用于搜索、问答、智能体、代码、数据处理等多类高价值场景。', 0); +INSERT INTO `chat_model` VALUES (2007528268536287233, 'vector', 'baai/bge-m3', 'ppio', 'bge-m3', 0, '1', 'N', 'Y', 1, 'https://api.ppinfra.com/openai', 'sk_xx', 103, 1, '2026-01-04 03:03:32', 1, '2026-02-25 21:15:14', 'bge-large-zh-v1.5', 0); -- ---------------------------- -- Table structure for chat_provider @@ -173,11 +137,11 @@ CREATE TABLE `chat_provider` ( -- ---------------------------- -- Records of chat_provider -- ---------------------------- -INSERT INTO `chat_provider` VALUES (1, 'OpenAI', 'openai', 'https://ruoyi-ai-1254149996.cos.ap-guangzhou.myqcloud.com/2025/12/15/9d944a6abfcd46e2bd6e364f07202589.png', 'OpenAI官方API服务商', 'https://api.openai.com', '0', 1, NULL, '2025-12-14 21:48:11', '1', '1', '2026-01-22 15:05:55', 'OpenAI厂商', NULL, '0', NULL, 0); -INSERT INTO `chat_provider` VALUES (2, '阿里云百炼', 'qianwen', 'https://ruoyi-ai-1254149996.cos.ap-guangzhou.myqcloud.com/2025/12/15/039ad13f690649f0ade139f8c803727b.png', '阿里云百炼大模型服务', 'https://dashscope.aliyuncs.com', '0', 2, NULL, '2025-12-14 21:48:11', '1', '1', '2026-02-06 00:58:22', '阿里云厂商', NULL, '0', NULL, 0); +INSERT INTO `chat_provider` VALUES (1, 'OpenAI', 'openai', 'https://ruoyiai-1254149996.cos.ap-guangzhou.myqcloud.com/2026/02/25/01091be272334383a1efd9bc22b73ee6.png', 'OpenAI官方API服务商', 'https://api.openai.com', '0', 1, NULL, '2025-12-14 21:48:11', '1', '1', '2026-02-25 20:46:59', 'OpenAI厂商', NULL, '0', NULL, 0); +INSERT INTO `chat_provider` VALUES (2, '阿里云百炼', 'qianwen', 'https://ruoyiai-1254149996.cos.ap-guangzhou.myqcloud.com/2026/02/25/de2aa7e649de44f3ba5c6380ac6acd04.png', '阿里云百炼大模型服务', 'https://dashscope.aliyuncs.com', '0', 2, NULL, '2025-12-14 21:48:11', '1', '1', '2026-02-25 20:49:13', '阿里云厂商', NULL, '0', NULL, 0); INSERT INTO `chat_provider` VALUES (3, '智谱AI', 'zhipu', 'https://ruoyi-ai-1254149996.cos.ap-guangzhou.myqcloud.com/2025/12/15/a43e98fb7b3b4861b8caa6184e6fa40a.png', '智谱AI大模型服务', 'https://open.bigmodel.cn', '0', 3, NULL, '2025-12-14 21:48:11', '1', '1', '2026-02-06 00:49:14', '智谱AI厂商', NULL, '1', NULL, 0); -INSERT INTO `chat_provider` VALUES (5, 'ollama', 'ollama', 'https://ruoyi-ai-1254149996.cos.ap-guangzhou.myqcloud.com/2025/12/15/2ff984bc9e4249df992733b31959056b.png', 'ollama大模型', 'http://127.0.0.1:11434', '0', 5, NULL, '2025-12-14 21:48:11', '1', '1', '2025-12-15 00:49:05', 'ollama厂商', NULL, '0', NULL, 0); -INSERT INTO `chat_provider` VALUES (2000585060904435714, 'PPIO', 'ppio', 'https://ruoyi-ai-1254149996.cos.ap-guangzhou.myqcloud.com/2025/12/15/c4f8e304ce7740029b0024934d4625bc.png', 'api聚合厂商', 'https://api.ppinfra.com/openai', '0', 5, 103, '2025-12-15 23:13:42', '1', '1', '2026-01-02 00:54:45', 'api聚合厂商', NULL, '0', NULL, 0); +INSERT INTO `chat_provider` VALUES (5, 'ollama', 'ollama', 'https://ruoyiai-1254149996.cos.ap-guangzhou.myqcloud.com/2026/02/25/afecabebc8014d80b0f06b4796a74c5d.png', 'ollama大模型', 'http://127.0.0.1:11434', '0', 5, NULL, '2025-12-14 21:48:11', '1', '1', '2026-02-25 20:48:48', 'ollama厂商', NULL, '0', NULL, 0); +INSERT INTO `chat_provider` VALUES (2000585060904435714, 'PPIO', 'ppio', 'https://ruoyiai-1254149996.cos.ap-guangzhou.myqcloud.com/2026/02/25/049bb6a507174f73bba4b8d8b9e55b8a.png', 'api聚合厂商', 'https://api.ppinfra.com/openai', '0', 5, 103, '2025-12-15 23:13:42', '1', '1', '2026-02-25 20:49:01', 'api聚合厂商', NULL, '0', NULL, 0); -- ---------------------------- -- Table structure for chat_session @@ -1448,6 +1412,90 @@ CREATE TABLE `knowledge_info` ( -- Records of knowledge_info -- ---------------------------- +-- ---------------------------- +-- Table structure for mcp_market_info +-- ---------------------------- +DROP TABLE IF EXISTS `mcp_market_info`; +CREATE TABLE `mcp_market_info` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '市场ID', + `name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '市场名称', + `url` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '市场URL', + `description` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL COMMENT '市场描述', + `auth_config` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL COMMENT '认证配置(JSON格式)', + `status` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT 'ENABLED' COMMENT '状态:ENABLED-启用, DISABLED-禁用', + `tenant_id` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '000000' COMMENT '租户编号', + `create_dept` bigint NULL DEFAULT NULL COMMENT '创建部门', + `create_by` bigint NULL DEFAULT NULL COMMENT '创建者', + `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间', + `update_by` bigint NULL DEFAULT NULL COMMENT '更新者', + `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间', + `del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '0' COMMENT '删除标志(0代表存在 2代表删除)', + PRIMARY KEY (`id`) USING BTREE, + INDEX `idx_name`(`name` ASC) USING BTREE, + INDEX `idx_status`(`status` ASC) USING BTREE, + INDEX `idx_tenant_id`(`tenant_id` ASC) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'MCP市场表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of mcp_market_info +-- ---------------------------- + +-- ---------------------------- +-- Table structure for mcp_market_tool +-- ---------------------------- +DROP TABLE IF EXISTS `mcp_market_tool`; +CREATE TABLE `mcp_market_tool` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'ID', + `market_id` bigint NOT NULL COMMENT '市场ID', + `tool_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '工具名称', + `tool_description` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL COMMENT '工具描述', + `tool_version` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '工具版本', + `tool_metadata` json NULL COMMENT '工具元数据(JSON格式)', + `is_loaded` tinyint(1) NULL DEFAULT 0 COMMENT '是否已加载到本地', + `local_tool_id` bigint NULL DEFAULT NULL COMMENT '关联的本地工具ID', + `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间', + PRIMARY KEY (`id`) USING BTREE, + INDEX `idx_market_id`(`market_id` ASC) USING BTREE, + INDEX `idx_tool_name`(`tool_name` ASC) USING BTREE, + INDEX `idx_is_loaded`(`is_loaded` ASC) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'MCP市场工具关联表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of mcp_market_tool +-- ---------------------------- + +-- ---------------------------- +-- Table structure for mcp_tool_info +-- ---------------------------- +DROP TABLE IF EXISTS `mcp_tool_info`; +CREATE TABLE `mcp_tool_info` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '工具ID', + `name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '工具名称', + `description` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL COMMENT '工具描述', + `type` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT 'LOCAL' COMMENT '工具类型:LOCAL-本地, REMOTE-远程, BUILTIN-内置', + `status` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT 'ENABLED' COMMENT '状态:ENABLED-启用, DISABLED-禁用', + `config_json` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL COMMENT '配置信息(JSON格式)', + `tenant_id` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '000000' COMMENT '租户编号', + `create_dept` bigint NULL DEFAULT NULL COMMENT '创建部门', + `create_by` bigint NULL DEFAULT NULL COMMENT '创建者', + `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间', + `update_by` bigint NULL DEFAULT NULL COMMENT '更新者', + `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间', + `del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '0' COMMENT '删除标志(0代表存在 2代表删除)', + PRIMARY KEY (`id`) USING BTREE, + INDEX `idx_name`(`name` ASC) USING BTREE, + INDEX `idx_type`(`type` ASC) USING BTREE, + INDEX `idx_status`(`status` ASC) USING BTREE, + INDEX `idx_tenant_id`(`tenant_id` ASC) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'MCP工具表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of mcp_tool_info +-- ---------------------------- +INSERT INTO `mcp_tool_info` VALUES (1, 'edit_file', 'Edits a file by applying a diff. Use this tool when you need to make specific changes to a file. The tool will show the diff before applying changes. Use absolute paths within the workspace directory.', 'BUILTIN', 'ENABLED', NULL, '000000', -1, -1, '2026-02-24 20:19:41', -1, '2026-02-24 20:19:41', '0'); +INSERT INTO `mcp_tool_info` VALUES (2, 'list_directory', 'Lists files and directories in the specified path. Supports recursive listing and filtering. Shows file sizes, modification times, and types. Use absolute paths within the workspace directory.', 'BUILTIN', 'ENABLED', NULL, '000000', -1, -1, '2026-02-24 20:19:41', -1, '2026-02-24 20:19:41', '0'); +INSERT INTO `mcp_tool_info` VALUES (3, 'read_file', 'Reads the contents of a file. Use absolute paths within the workspace directory. Returns the complete file content as a string.', 'BUILTIN', 'ENABLED', NULL, '000000', -1, -1, '2026-02-24 20:19:41', -1, '2026-02-24 20:19:41', '0'); + -- ---------------------------- -- Table structure for sj_distributed_lock -- ---------------------------- @@ -1460,7 +1508,7 @@ CREATE TABLE `sj_distributed_lock` ( `create_dt` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `update_dt` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间', PRIMARY KEY (`name`) USING BTREE -) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '锁定表' ROW_FORMAT = Dynamic; +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '锁定表' ROW_FORMAT = DYNAMIC; -- ---------------------------- -- Records of sj_distributed_lock @@ -1485,7 +1533,7 @@ CREATE TABLE `sj_group_config` ( `update_dt` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间', PRIMARY KEY (`id`) USING BTREE, UNIQUE INDEX `uk_namespace_id_group_name`(`namespace_id` ASC, `group_name` ASC) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '组配置' ROW_FORMAT = Dynamic; +) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '组配置' ROW_FORMAT = DYNAMIC; -- ---------------------------- -- Records of sj_group_config @@ -1531,7 +1579,7 @@ CREATE TABLE `sj_job` ( INDEX `idx_namespace_id_group_name`(`namespace_id` ASC, `group_name` ASC) USING BTREE, INDEX `idx_job_status_bucket_index`(`job_status` ASC, `bucket_index` ASC) USING BTREE, INDEX `idx_create_dt`(`create_dt` ASC) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '任务信息' ROW_FORMAT = Dynamic; +) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '任务信息' ROW_FORMAT = DYNAMIC; -- ---------------------------- -- Records of sj_job @@ -1553,7 +1601,7 @@ CREATE TABLE `sj_job_executor` ( PRIMARY KEY (`id`) USING BTREE, INDEX `idx_namespace_id_group_name`(`namespace_id` ASC, `group_name` ASC) USING BTREE, INDEX `idx_create_dt`(`create_dt` ASC) USING BTREE -) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '任务执行器信息' ROW_FORMAT = Dynamic; +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '任务执行器信息' ROW_FORMAT = DYNAMIC; -- ---------------------------- -- Records of sj_job_executor @@ -1579,7 +1627,7 @@ CREATE TABLE `sj_job_log_message` ( INDEX `idx_task_batch_id_task_id`(`task_batch_id` ASC, `task_id` ASC) USING BTREE, INDEX `idx_create_dt`(`create_dt` ASC) USING BTREE, INDEX `idx_namespace_id_group_name`(`namespace_id` ASC, `group_name` ASC) USING BTREE -) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '调度日志' ROW_FORMAT = Dynamic; +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '调度日志' ROW_FORMAT = DYNAMIC; -- ---------------------------- -- Records of sj_job_log_message @@ -1608,7 +1656,7 @@ CREATE TABLE `sj_job_summary` ( PRIMARY KEY (`id`) USING BTREE, UNIQUE INDEX `uk_trigger_at_system_task_type_business_id`(`trigger_at` ASC, `system_task_type` ASC, `business_id` ASC) USING BTREE, INDEX `idx_namespace_id_group_name_business_id`(`namespace_id` ASC, `group_name` ASC, `business_id` ASC) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = 'DashBoard_Job' ROW_FORMAT = Dynamic; +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = 'DashBoard_Job' ROW_FORMAT = DYNAMIC; -- ---------------------------- -- Records of sj_job_summary @@ -1642,7 +1690,7 @@ CREATE TABLE `sj_job_task` ( INDEX `idx_task_batch_id_task_status`(`task_batch_id` ASC, `task_status` ASC) USING BTREE, INDEX `idx_create_dt`(`create_dt` ASC) USING BTREE, INDEX `idx_namespace_id_group_name`(`namespace_id` ASC, `group_name` ASC) USING BTREE -) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '任务实例' ROW_FORMAT = Dynamic; +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '任务实例' ROW_FORMAT = DYNAMIC; -- ---------------------------- -- Records of sj_job_task @@ -1674,7 +1722,7 @@ CREATE TABLE `sj_job_task_batch` ( INDEX `idx_create_dt`(`create_dt` ASC) USING BTREE, INDEX `idx_namespace_id_group_name`(`namespace_id` ASC, `group_name` ASC) USING BTREE, INDEX `idx_workflow_task_batch_id_workflow_node_id`(`workflow_task_batch_id` ASC, `workflow_node_id` ASC) USING BTREE -) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '任务批次' ROW_FORMAT = Dynamic; +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '任务批次' ROW_FORMAT = DYNAMIC; -- ---------------------------- -- Records of sj_job_task_batch @@ -1695,7 +1743,7 @@ CREATE TABLE `sj_namespace` ( PRIMARY KEY (`id`) USING BTREE, UNIQUE INDEX `uk_unique_id`(`unique_id` ASC) USING BTREE, INDEX `idx_name`(`name` ASC) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '命名空间' ROW_FORMAT = Dynamic; +) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '命名空间' ROW_FORMAT = DYNAMIC; -- ---------------------------- -- Records of sj_namespace @@ -1724,7 +1772,7 @@ CREATE TABLE `sj_notify_config` ( `update_dt` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间', PRIMARY KEY (`id`) USING BTREE, INDEX `idx_namespace_id_group_name_scene_name`(`namespace_id` ASC, `group_name` ASC) USING BTREE -) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '通知配置' ROW_FORMAT = Dynamic; +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '通知配置' ROW_FORMAT = DYNAMIC; -- ---------------------------- -- Records of sj_notify_config @@ -1745,7 +1793,7 @@ CREATE TABLE `sj_notify_recipient` ( `update_dt` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间', PRIMARY KEY (`id`) USING BTREE, INDEX `idx_namespace_id`(`namespace_id` ASC) USING BTREE -) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '告警通知接收人' ROW_FORMAT = Dynamic; +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '告警通知接收人' ROW_FORMAT = DYNAMIC; -- ---------------------------- -- Records of sj_notify_recipient @@ -1784,7 +1832,7 @@ CREATE TABLE `sj_retry` ( INDEX `idx_retry_status_bucket_index`(`retry_status` ASC, `bucket_index` ASC) USING BTREE, INDEX `idx_parent_id`(`parent_id` ASC) USING BTREE, INDEX `idx_create_dt`(`create_dt` ASC) USING BTREE -) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '重试信息表' ROW_FORMAT = Dynamic; +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '重试信息表' ROW_FORMAT = DYNAMIC; -- ---------------------------- -- Records of sj_retry @@ -1813,7 +1861,7 @@ CREATE TABLE `sj_retry_dead_letter` ( INDEX `idx_idempotent_id`(`idempotent_id` ASC) USING BTREE, INDEX `idx_biz_no`(`biz_no` ASC) USING BTREE, INDEX `idx_create_dt`(`create_dt` ASC) USING BTREE -) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '死信队列表' ROW_FORMAT = Dynamic; +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '死信队列表' ROW_FORMAT = DYNAMIC; -- ---------------------------- -- Records of sj_retry_dead_letter @@ -1848,7 +1896,7 @@ CREATE TABLE `sj_retry_scene_config` ( `update_dt` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间', PRIMARY KEY (`id`) USING BTREE, UNIQUE INDEX `uk_namespace_id_group_name_scene_name`(`namespace_id` ASC, `group_name` ASC, `scene_name` ASC) USING BTREE -) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '场景配置' ROW_FORMAT = Dynamic; +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '场景配置' ROW_FORMAT = DYNAMIC; -- ---------------------------- -- Records of sj_retry_scene_config @@ -1873,7 +1921,7 @@ CREATE TABLE `sj_retry_summary` ( PRIMARY KEY (`id`) USING BTREE, UNIQUE INDEX `uk_scene_name_trigger_at`(`namespace_id` ASC, `group_name` ASC, `scene_name` ASC, `trigger_at` ASC) USING BTREE, INDEX `idx_trigger_at`(`trigger_at` ASC) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = 'DashBoard_Retry' ROW_FORMAT = Dynamic; +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = 'DashBoard_Retry' ROW_FORMAT = DYNAMIC; -- ---------------------------- -- Records of sj_retry_summary @@ -1901,7 +1949,7 @@ CREATE TABLE `sj_retry_task` ( INDEX `task_status`(`task_status` ASC) USING BTREE, INDEX `idx_create_dt`(`create_dt` ASC) USING BTREE, INDEX `idx_retry_id`(`retry_id` ASC) USING BTREE -) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '重试任务表' ROW_FORMAT = Dynamic; +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '重试任务表' ROW_FORMAT = DYNAMIC; -- ---------------------------- -- Records of sj_retry_task @@ -1924,7 +1972,7 @@ CREATE TABLE `sj_retry_task_log_message` ( PRIMARY KEY (`id`) USING BTREE, INDEX `idx_namespace_id_group_name_retry_task_id`(`namespace_id` ASC, `group_name` ASC, `retry_task_id` ASC) USING BTREE, INDEX `idx_create_dt`(`create_dt` ASC) USING BTREE -) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '任务调度日志信息记录表' ROW_FORMAT = Dynamic; +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '任务调度日志信息记录表' ROW_FORMAT = DYNAMIC; -- ---------------------------- -- Records of sj_retry_task_log_message @@ -1951,7 +1999,7 @@ CREATE TABLE `sj_server_node` ( UNIQUE INDEX `uk_host_id_host_ip`(`host_id` ASC, `host_ip` ASC) USING BTREE, INDEX `idx_namespace_id_group_name`(`namespace_id` ASC, `group_name` ASC) USING BTREE, INDEX `idx_expire_at_node_type`(`expire_at` ASC, `node_type` ASC) USING BTREE -) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '服务器节点' ROW_FORMAT = Dynamic; +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '服务器节点' ROW_FORMAT = DYNAMIC; -- ---------------------------- -- Records of sj_server_node @@ -1970,7 +2018,7 @@ CREATE TABLE `sj_system_user` ( `update_dt` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间', PRIMARY KEY (`id`) USING BTREE, UNIQUE INDEX `uk_username`(`username` ASC) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '系统用户表' ROW_FORMAT = Dynamic; +) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '系统用户表' ROW_FORMAT = DYNAMIC; -- ---------------------------- -- Records of sj_system_user @@ -1990,7 +2038,7 @@ CREATE TABLE `sj_system_user_permission` ( `update_dt` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间', PRIMARY KEY (`id`) USING BTREE, UNIQUE INDEX `uk_namespace_id_group_name_system_user_id`(`namespace_id` ASC, `group_name` ASC, `system_user_id` ASC) USING BTREE -) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '系统用户权限表' ROW_FORMAT = Dynamic; +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '系统用户权限表' ROW_FORMAT = DYNAMIC; -- ---------------------------- -- Records of sj_system_user_permission @@ -2025,7 +2073,7 @@ CREATE TABLE `sj_workflow` ( PRIMARY KEY (`id`) USING BTREE, INDEX `idx_create_dt`(`create_dt` ASC) USING BTREE, INDEX `idx_namespace_id_group_name`(`namespace_id` ASC, `group_name` ASC) USING BTREE -) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '工作流' ROW_FORMAT = Dynamic; +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '工作流' ROW_FORMAT = DYNAMIC; -- ---------------------------- -- Records of sj_workflow @@ -2056,7 +2104,7 @@ CREATE TABLE `sj_workflow_node` ( PRIMARY KEY (`id`) USING BTREE, INDEX `idx_create_dt`(`create_dt` ASC) USING BTREE, INDEX `idx_namespace_id_group_name`(`namespace_id` ASC, `group_name` ASC) USING BTREE -) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '工作流节点' ROW_FORMAT = Dynamic; +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '工作流节点' ROW_FORMAT = DYNAMIC; -- ---------------------------- -- Records of sj_workflow_node @@ -2085,7 +2133,7 @@ CREATE TABLE `sj_workflow_task_batch` ( INDEX `idx_job_id_task_batch_status`(`workflow_id` ASC, `task_batch_status` ASC) USING BTREE, INDEX `idx_create_dt`(`create_dt` ASC) USING BTREE, INDEX `idx_namespace_id_group_name`(`namespace_id` ASC, `group_name` ASC) USING BTREE -) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '工作流批次' ROW_FORMAT = Dynamic; +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '工作流批次' ROW_FORMAT = DYNAMIC; -- ---------------------------- -- Records of sj_workflow_task_batch @@ -2288,6 +2336,11 @@ INSERT INTO `sys_dict_data` VALUES (2018858143757504522, '154726', 0, 'PC', 'pc' INSERT INTO `sys_dict_data` VALUES (2018858143761698817, '154726', 0, '安卓', 'android', 'sys_device_type', '', 'default', 'N', 103, 1, '2026-02-04 09:24:25', 1, '2026-02-04 09:24:25', '安卓'); INSERT INTO `sys_dict_data` VALUES (2018858143761698818, '154726', 0, 'iOS', 'ios', 'sys_device_type', '', 'default', 'N', 103, 1, '2026-02-04 09:24:25', 1, '2026-02-04 09:24:25', 'iOS'); INSERT INTO `sys_dict_data` VALUES (2018858143761698819, '154726', 0, '小程序', 'xcx', 'sys_device_type', '', 'default', 'N', 103, 1, '2026-02-04 09:24:25', 1, '2026-02-04 09:24:25', '小程序'); +INSERT INTO `sys_dict_data` VALUES (2026642472673288194, '000000', 0, '对话', 'chat', 'chat_model_category', NULL, 'cyan', 'N', 103, 1, '2026-02-25 20:56:33', 1, '2026-02-25 21:01:42', NULL); +INSERT INTO `sys_dict_data` VALUES (2026642525081116674, '000000', 1, '图像', 'image', 'chat_model_category', NULL, 'success', 'N', 103, 1, '2026-02-25 20:56:46', 1, '2026-02-25 21:01:37', NULL); +INSERT INTO `sys_dict_data` VALUES (2026643983713247233, '000000', 1, '次数计费', '1', 'sys_model_billing', NULL, 'green', 'N', 103, 1, '2026-02-25 21:02:34', 1, '2026-02-25 21:02:56', NULL); +INSERT INTO `sys_dict_data` VALUES (2026644058522853378, '000000', 2, 'token计费', '2', 'sys_model_billing', NULL, 'primary', 'N', 103, 1, '2026-02-25 21:02:51', 1, '2026-02-25 21:02:51', NULL); +INSERT INTO `sys_dict_data` VALUES (2027261114955931650, '000000', 2, '向量', 'vector', 'chat_model_category', NULL, 'default', 'N', 103, 1, '2026-02-27 13:54:49', 1, '2026-02-27 13:54:54', NULL); -- ---------------------------- -- Table structure for sys_dict_type @@ -2331,6 +2384,8 @@ INSERT INTO `sys_dict_type` VALUES (2018858143723950085, '154726', '操作类型 INSERT INTO `sys_dict_type` VALUES (2018858143723950086, '154726', '系统状态', 'sys_common_status', 103, 1, '2026-02-04 09:24:25', 1, '2026-02-04 09:24:25', '登录状态列表'); INSERT INTO `sys_dict_type` VALUES (2018858143723950087, '154726', '授权类型', 'sys_grant_type', 103, 1, '2026-02-04 09:24:25', 1, '2026-02-04 09:24:25', '认证授权类型'); INSERT INTO `sys_dict_type` VALUES (2018858143723950088, '154726', '设备类型', 'sys_device_type', 103, 1, '2026-02-04 09:24:25', 1, '2026-02-04 09:24:25', '客户端设备类型'); +INSERT INTO `sys_dict_type` VALUES (2026642112982360066, '000000', '模型分类', 'chat_model_category', 103, 1, '2026-02-25 20:55:08', 1, '2026-02-25 20:55:08', '模型分类'); +INSERT INTO `sys_dict_type` VALUES (2026642183606050817, '000000', '计费方式', 'sys_model_billing', 103, 1, '2026-02-25 20:55:24', 1, '2026-02-25 20:55:24', '计费方式'); -- ---------------------------- -- Table structure for sys_logininfor @@ -2569,6 +2624,15 @@ INSERT INTO `sys_logininfor` VALUES (2019224998575153153, '000000', 'admin', 'pc INSERT INTO `sys_logininfor` VALUES (2019225059417726977, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-05 09:42:24'); INSERT INTO `sys_logininfor` VALUES (2019240817392693249, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-05 10:45:01'); INSERT INTO `sys_logininfor` VALUES (2019447979716972545, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-06 00:28:13'); +INSERT INTO `sys_logininfor` VALUES (2026536636865163265, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-25 13:56:00'); +INSERT INTO `sys_logininfor` VALUES (2026556949535502337, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-25 15:16:43'); +INSERT INTO `sys_logininfor` VALUES (2026578433112911874, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-25 16:42:05'); +INSERT INTO `sys_logininfor` VALUES (2026638437400518657, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-25 20:40:31'); +INSERT INTO `sys_logininfor` VALUES (2026647463072952321, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-25 21:16:23'); +INSERT INTO `sys_logininfor` VALUES (2026653919016968194, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '退出成功', '2026-02-25 21:42:02'); +INSERT INTO `sys_logininfor` VALUES (2026654082020204546, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-25 21:42:41'); +INSERT INTO `sys_logininfor` VALUES (2026654455514587138, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-25 21:44:10'); +INSERT INTO `sys_logininfor` VALUES (2027260957187186689, '000000', 'admin', 'pc', 'pc', '127.0.0.1', '内网IP', 'MSEdge', 'Windows 10 or Windows Server 2016', '0', '登录成功', '2026-02-27 13:54:12'); -- ---------------------------- -- Table structure for sys_menu @@ -2604,7 +2668,7 @@ CREATE TABLE `sys_menu` ( INSERT INTO `sys_menu` VALUES (1, '系统管理', 0, 3, 'system', '', '', 1, 0, 'M', '0', '0', '', 'eos-icons:system-group', 103, 1, '2025-12-14 16:11:49', 1, '2026-01-01 19:06:19', '系统管理目录'); INSERT INTO `sys_menu` VALUES (2, '系统监控', 0, 3, 'monitor', '', '', 1, 0, 'M', '0', '0', '', 'solar:monitor-camera-outline', 103, 1, '2025-12-14 16:11:49', 1, '2025-12-14 17:56:44', '系统监控目录'); INSERT INTO `sys_menu` VALUES (3, '系统工具', 0, 4, 'tool', NULL, '', 1, 0, 'M', '0', '0', '', 'ant-design:tool-outlined', 103, 1, '2025-12-14 16:11:49', NULL, NULL, '系统工具目录'); -INSERT INTO `sys_menu` VALUES (6, '租户管理', 0, 2, 'tenant', NULL, '', 1, 0, 'M', '0', '0', '', 'ph:users-light', 103, 1, '2025-12-14 16:11:49', NULL, NULL, '租户管理目录'); +INSERT INTO `sys_menu` VALUES (6, '租户管理', 0, 8, 'tenant', '', '', 1, 0, 'M', '0', '0', '', 'ph:users-light', 103, 1, '2025-12-14 16:11:49', 1, '2026-02-25 20:42:14', '租户管理目录'); INSERT INTO `sys_menu` VALUES (100, '用户管理', 1, 1, 'user', 'system/user/index', '', 1, 0, 'C', '0', '0', 'system:user:list', 'ant-design:user-outlined', 103, 1, '2025-12-14 16:11:49', NULL, NULL, '用户管理菜单'); INSERT INTO `sys_menu` VALUES (101, '角色管理', 1, 2, 'role', 'system/role/index', '', 1, 0, 'C', '0', '0', 'system:role:list', 'eos-icons:role-binding-outlined', 103, 1, '2025-12-14 16:11:49', NULL, NULL, '角色管理菜单'); INSERT INTO `sys_menu` VALUES (102, '菜单管理', 1, 3, 'menu', 'system/menu/index', '', 1, 0, 'C', '0', '0', 'system:menu:list', 'ic:sharp-menu', 103, 1, '2025-12-14 16:11:49', NULL, NULL, '菜单管理菜单'); @@ -2708,6 +2772,22 @@ INSERT INTO `sys_menu` VALUES (1620, '配置列表', 118, 5, '#', '', '', 1, 0, INSERT INTO `sys_menu` VALUES (1621, '配置添加', 118, 6, '#', '', '', 1, 0, 'F', '0', '0', 'system:ossConfig:add', '#', 103, 1, '2025-12-14 16:11:49', NULL, NULL, ''); INSERT INTO `sys_menu` VALUES (1622, '配置编辑', 118, 6, '#', '', '', 1, 0, 'F', '0', '0', 'system:ossConfig:edit', '#', 103, 1, '2025-12-14 16:11:49', NULL, NULL, ''); INSERT INTO `sys_menu` VALUES (1623, '配置删除', 118, 6, '#', '', '', 1, 0, 'F', '0', '0', 'system:ossConfig:remove', '#', 103, 1, '2025-12-14 16:11:49', NULL, NULL, ''); +INSERT INTO `sys_menu` VALUES (2000, 'MCP管理', 0, 2, 'mcp', '', '', 1, 0, 'M', '0', '0', '', 'mdi:robot-industrial', 103, 1, '2026-02-24 20:02:47', 1, '2026-02-25 20:41:54', 'MCP模块管理菜单'); +INSERT INTO `sys_menu` VALUES (2001, 'MCP工具管理', 2000, 1, 'tool', 'mcp/tool/index', '', 1, 0, 'C', '0', '0', 'mcp:tool:list', 'octicon:tools-24', 103, 1, '2026-02-24 20:02:47', 1, '2026-02-25 20:41:27', 'MCP工具管理菜单'); +INSERT INTO `sys_menu` VALUES (2002, 'MCP工具查询', 2001, 1, '#', '', '', 1, 0, 'F', '0', '0', 'mcp:tool:query', '#', 103, 1, '2026-02-24 20:02:47', NULL, NULL, ''); +INSERT INTO `sys_menu` VALUES (2003, 'MCP工具新增', 2001, 2, '#', '', '', 1, 0, 'F', '0', '0', 'mcp:tool:add', '#', 103, 1, '2026-02-24 20:02:47', NULL, NULL, ''); +INSERT INTO `sys_menu` VALUES (2004, 'MCP工具修改', 2001, 3, '#', '', '', 1, 0, 'F', '0', '0', 'mcp:tool:edit', '#', 103, 1, '2026-02-24 20:02:47', NULL, NULL, ''); +INSERT INTO `sys_menu` VALUES (2005, 'MCP工具删除', 2001, 4, '#', '', '', 1, 0, 'F', '0', '0', 'mcp:tool:remove', '#', 103, 1, '2026-02-24 20:02:47', NULL, NULL, ''); +INSERT INTO `sys_menu` VALUES (2006, 'MCP工具测试', 2001, 5, '#', '', '', 1, 0, 'F', '0', '0', 'mcp:tool:test', '#', 103, 1, '2026-02-24 20:02:47', NULL, NULL, ''); +INSERT INTO `sys_menu` VALUES (2007, 'MCP工具导出', 2001, 6, '#', '', '', 1, 0, 'F', '0', '0', 'mcp:tool:export', '#', 103, 1, '2026-02-24 20:02:47', NULL, NULL, ''); +INSERT INTO `sys_menu` VALUES (2010, 'MCP市场管理', 2000, 2, 'market', 'mcp/market/index', '', 1, 0, 'C', '0', '0', 'mcp:market:list', 'mdi:storefront-outline', 103, 1, '2026-02-24 20:02:47', NULL, NULL, 'MCP市场管理菜单'); +INSERT INTO `sys_menu` VALUES (2011, 'MCP市场查询', 2010, 1, '#', '', '', 1, 0, 'F', '0', '0', 'mcp:market:query', '#', 103, 1, '2026-02-24 20:02:47', NULL, NULL, ''); +INSERT INTO `sys_menu` VALUES (2012, 'MCP市场新增', 2010, 2, '#', '', '', 1, 0, 'F', '0', '0', 'mcp:market:add', '#', 103, 1, '2026-02-24 20:02:47', NULL, NULL, ''); +INSERT INTO `sys_menu` VALUES (2013, 'MCP市场修改', 2010, 3, '#', '', '', 1, 0, 'F', '0', '0', 'mcp:market:edit', '#', 103, 1, '2026-02-24 20:02:47', NULL, NULL, ''); +INSERT INTO `sys_menu` VALUES (2014, 'MCP市场删除', 2010, 4, '#', '', '', 1, 0, 'F', '0', '0', 'mcp:market:remove', '#', 103, 1, '2026-02-24 20:02:47', NULL, NULL, ''); +INSERT INTO `sys_menu` VALUES (2015, 'MCP市场刷新', 2010, 5, '#', '', '', 1, 0, 'F', '0', '0', 'mcp:market:refresh', '#', 103, 1, '2026-02-24 20:02:47', NULL, NULL, ''); +INSERT INTO `sys_menu` VALUES (2016, 'MCP工具加载', 2010, 6, '#', '', '', 1, 0, 'F', '0', '0', 'mcp:market:load', '#', 103, 1, '2026-02-24 20:02:47', NULL, NULL, ''); +INSERT INTO `sys_menu` VALUES (2017, 'MCP市场导出', 2010, 7, '#', '', '', 1, 0, 'F', '0', '0', 'mcp:market:export', '#', 103, 1, '2026-02-24 20:02:47', NULL, NULL, ''); INSERT INTO `sys_menu` VALUES (11616, '工作流', 0, 6, 'workflow', '', '', 1, 0, 'M', '0', '0', '', 'mdi:workflow-outline', 103, 1, '2026-01-05 14:39:33', 1, '2026-01-05 14:56:07', ''); INSERT INTO `sys_menu` VALUES (11618, '我的任务', 0, 7, 'task', '', '', 1, 0, 'M', '0', '0', '', 'carbon:task-approved', 103, 1, '2026-01-05 14:39:33', NULL, NULL, ''); INSERT INTO `sys_menu` VALUES (11619, '我的待办', 11618, 2, 'taskWaiting', 'workflow/task/taskWaiting', '', 1, 1, 'C', '0', '0', '', 'ri:todo-line', 103, 1, '2026-01-05 14:39:33', NULL, NULL, ''); @@ -2732,13 +2812,6 @@ INSERT INTO `sys_menu` VALUES (11803, '流程达式定义新增', 11801, 2, '#', INSERT INTO `sys_menu` VALUES (11804, '流程达式定义修改', 11801, 3, '#', '', NULL, 1, 0, 'F', '0', '0', 'workflow:spel:edit', '#', 103, 1, '2026-01-05 14:39:33', NULL, NULL, ''); INSERT INTO `sys_menu` VALUES (11805, '流程达式定义删除', 11801, 4, '#', '', NULL, 1, 0, 'F', '0', '0', 'workflow:spel:remove', '#', 103, 1, '2026-01-05 14:39:33', NULL, NULL, ''); INSERT INTO `sys_menu` VALUES (11806, '流程达式定义导出', 11801, 5, '#', '', NULL, 1, 0, 'F', '0', '0', 'workflow:spel:export', '#', 103, 1, '2026-01-05 14:39:33', NULL, NULL, ''); -INSERT INTO `sys_menu` VALUES (1971546066781597696, '数字人体验', 2019459914910994434, 10, 'aihumanPublish', 'aihuman/aihumanPublish/index', NULL, 1, 0, 'C', '0', '0', '', 'mdi:human-child', 103, 1, '2026-02-06 01:13:22', 1, '2026-02-06 01:29:34', '数字人信息管理菜单'); -INSERT INTO `sys_menu` VALUES (1971546066781597697, '数字人信息管理查询', 1971546066781597696, 1, '#', '', NULL, 1, 0, 'F', '0', '0', 'aihuman:aihumanInfo:query', '#', 103, 1, '2026-02-06 01:13:22', NULL, NULL, ''); -INSERT INTO `sys_menu` VALUES (1971546066781597698, '数字人信息管理新增', 1971546066781597696, 2, '#', '', NULL, 1, 0, 'F', '0', '0', 'aihuman:aihumanInfo:add', '#', 103, 1, '2026-02-06 01:13:22', NULL, NULL, ''); -INSERT INTO `sys_menu` VALUES (1971546066781597699, '数字人信息管理修改', 1971546066781597696, 3, '#', '', NULL, 1, 0, 'F', '0', '0', 'aihuman:aihumanInfo:edit', '#', 103, 1, '2026-02-06 01:13:22', NULL, NULL, ''); -INSERT INTO `sys_menu` VALUES (1971546066781597700, '数字人信息管理删除', 1971546066781597696, 4, '#', '', NULL, 1, 0, 'F', '0', '0', 'aihuman:aihumanInfo:remove', '#', 103, 1, '2026-02-06 01:13:22', NULL, NULL, ''); -INSERT INTO `sys_menu` VALUES (1971546066781597701, '数字人信息管理导出', 1971546066781597696, 5, '#', '', NULL, 1, 0, 'F', '0', '0', 'aihuman:aihumanInfo:export', '#', 103, 1, '2026-02-06 01:13:22', NULL, NULL, ''); -INSERT INTO `sys_menu` VALUES (1980480880138051584, '数字人配置', 2019459914910994434, 1, 'aihumanConfig', 'aihuman/aihumanConfig/index', NULL, 1, 0, 'C', '0', '0', 'aihuman:aihumanConfig:list', 'mdi:human-child', 103, 1, '2026-02-06 01:13:35', 1, '2026-02-06 01:28:12', ''); INSERT INTO `sys_menu` VALUES (2000209300188356609, '对话管理', 0, 0, 'chat', '', NULL, 1, 0, 'M', '0', '0', NULL, 'material-symbols:chat-outline', 103, 1, '2025-12-14 22:20:34', 1, '2025-12-14 22:21:24', ''); INSERT INTO `sys_menu` VALUES (2000210913451892738, '厂商管理', 2000209300188356609, 1, 'provider', 'chat/provider/index', NULL, 1, 0, 'C', '0', '0', 'system:provider:list', 'tabler:cube-spark', 103, 1, '2025-12-14 22:28:05', 1, '2025-12-14 23:42:55', '厂商管理菜单'); INSERT INTO `sys_menu` VALUES (2000210913451892739, '厂商管理查询', 2000210913451892738, 1, '#', '', NULL, 1, 0, 'F', '0', '0', 'system:provider:query', '#', 103, 1, '2025-12-14 22:28:05', NULL, NULL, ''); @@ -2771,7 +2844,6 @@ INSERT INTO `sys_menu` VALUES (2006681261898813444, '知识库修改', 200668126 INSERT INTO `sys_menu` VALUES (2006681261898813445, '知识库删除', 2006681261898813441, 4, '#', '', NULL, 1, 0, 'F', '0', '0', 'system:info:remove', '#', 103, 1, '2026-01-01 18:59:06', NULL, NULL, ''); INSERT INTO `sys_menu` VALUES (2006681261898813446, '知识库导出', 2006681261898813441, 5, '#', '', NULL, 1, 0, 'F', '0', '0', 'system:info:export', '#', 103, 1, '2026-01-01 18:59:06', NULL, NULL, ''); INSERT INTO `sys_menu` VALUES (2006683336984580098, '知识管理', 0, 2, 'knowledge', '', NULL, 1, 0, 'M', '0', '0', NULL, 'bx:book', 103, 1, '2026-01-01 19:06:05', 1, '2026-01-01 19:06:05', ''); -INSERT INTO `sys_menu` VALUES (2019459914910994434, '数字人管理', 0, 2, 'human', '', NULL, 1, 0, 'M', '0', '0', NULL, 'tdesign:user', 103, 1, '2026-02-06 01:15:38', 1, '2026-02-06 01:16:58', ''); INSERT INTO `sys_menu` VALUES (2019464280262905857, '图谱实例', 2019464531388469250, 1, 'graphInstance', 'graph/graphInstance/index', NULL, 1, 0, 'C', '0', '0', 'operator:graph:list', 'ant-design:node-index-outlined', 103, 1, '2026-02-06 01:32:59', 1, '2026-02-06 01:40:06', ''); INSERT INTO `sys_menu` VALUES (2019464531388469250, '知识图谱', 2006683336984580098, 15, 'graph', '', NULL, 1, 0, 'M', '0', '0', NULL, 'carbon:chart-relationship', 103, 1, '2026-02-06 01:33:59', 1, '2026-02-06 01:33:59', ''); INSERT INTO `sys_menu` VALUES (2019464779217309697, '图谱可视化', 2019464531388469250, 2, 'graphVisualization', 'graph/graphVisualization/index', NULL, 1, 0, 'C', '0', '0', 'operator:graph:view', 'carbon:chart-network', 103, 1, '2026-02-06 01:34:58', 1, '2026-02-06 01:40:14', ''); @@ -2860,6 +2932,12 @@ CREATE TABLE `sys_oss` ( -- ---------------------------- -- Records of sys_oss -- ---------------------------- +INSERT INTO `sys_oss` VALUES (2026580908423340033, '000000', '2026/02/25/9219d6d71a6d45e19192014609d92dc9.png', 'logo.png', '.png', 'https://ruoyiai-1254149996.cos.ap-guangzhou.myqcloud.com/2026/02/25/9219d6d71a6d45e19192014609d92dc9.png', '{\"fileSize\":\"183613\",\"contentType\":\"image/png\"}', 103, '2026-02-25 16:51:55', 1, '2026-02-25 16:51:55', 1, 'qcloud'); +INSERT INTO `sys_oss` VALUES (2026640059920883713, '000000', '2026/02/25/01091be272334383a1efd9bc22b73ee6.png', 'openai.png', '.png', 'https://ruoyiai-1254149996.cos.ap-guangzhou.myqcloud.com/2026/02/25/01091be272334383a1efd9bc22b73ee6.png', '{\"fileSize\":\"11297\",\"contentType\":\"image/png\"}', 103, '2026-02-25 20:46:58', 1, '2026-02-25 20:46:58', 1, 'qcloud'); +INSERT INTO `sys_oss` VALUES (2026640515967557633, '000000', '2026/02/25/afecabebc8014d80b0f06b4796a74c5d.png', 'ollama.png', '.png', 'https://ruoyiai-1254149996.cos.ap-guangzhou.myqcloud.com/2026/02/25/afecabebc8014d80b0f06b4796a74c5d.png', '{\"fileSize\":\"8746\",\"contentType\":\"image/png\"}', 103, '2026-02-25 20:48:47', 1, '2026-02-25 20:48:47', 1, 'qcloud'); +INSERT INTO `sys_oss` VALUES (2026640548213366785, '000000', '2026/02/25/e16429a462e54e14a1d36673146b9e3c.png', 'ppio-color.png', '.png', 'https://ruoyiai-1254149996.cos.ap-guangzhou.myqcloud.com/2026/02/25/e16429a462e54e14a1d36673146b9e3c.png', '{\"fileSize\":\"7382\",\"contentType\":\"image/png\"}', 103, '2026-02-25 20:48:55', 1, '2026-02-25 20:48:55', 1, 'qcloud'); +INSERT INTO `sys_oss` VALUES (2026640572443860993, '000000', '2026/02/25/049bb6a507174f73bba4b8d8b9e55b8a.png', 'ppio-color.png', '.png', 'https://ruoyiai-1254149996.cos.ap-guangzhou.myqcloud.com/2026/02/25/049bb6a507174f73bba4b8d8b9e55b8a.png', '{\"fileSize\":\"7382\",\"contentType\":\"image/png\"}', 103, '2026-02-25 20:49:00', 1, '2026-02-25 20:49:00', 1, 'qcloud'); +INSERT INTO `sys_oss` VALUES (2026640621945036802, '000000', '2026/02/25/de2aa7e649de44f3ba5c6380ac6acd04.png', 'bailian-color.png', '.png', 'https://ruoyiai-1254149996.cos.ap-guangzhou.myqcloud.com/2026/02/25/de2aa7e649de44f3ba5c6380ac6acd04.png', '{\"fileSize\":\"5901\",\"contentType\":\"image/png\"}', 103, '2026-02-25 20:49:12', 1, '2026-02-25 20:49:12', 1, 'qcloud'); -- ---------------------------- -- Table structure for sys_oss_config @@ -2892,10 +2970,10 @@ CREATE TABLE `sys_oss_config` ( -- ---------------------------- -- Records of sys_oss_config -- ---------------------------- -INSERT INTO `sys_oss_config` VALUES (1, '000000', 'minio', 'ruoyi', 'ruoyi123', 'ruoyi', '', '127.0.0.1:9000', '', 'N', '', '1', '0', '', 103, 1, '2026-02-03 05:14:52', 1, '2026-02-03 05:14:52', NULL); +INSERT INTO `sys_oss_config` VALUES (1, '000000', 'minio', 'ruoyi', 'ruoyi123', 'ruoyi', '', '127.0.0.1:9000', '', 'N', '', '1', '1', '', 103, 1, '2026-02-03 05:14:52', 1, '2026-02-25 15:44:13', NULL); INSERT INTO `sys_oss_config` VALUES (2, '000000', 'qiniu', 'XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX', 'ruoyi', '', 's3-cn-north-1.qiniucs.com', '', 'N', '', '1', '1', '', 103, 1, '2026-02-03 05:14:52', 1, '2026-02-03 05:14:52', NULL); INSERT INTO `sys_oss_config` VALUES (3, '000000', 'aliyun', 'XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX', 'ruoyi', '', 'oss-cn-beijing.aliyuncs.com', '', 'N', '', '1', '1', '', 103, 1, '2026-02-03 05:14:52', 1, '2026-02-03 05:14:52', NULL); -INSERT INTO `sys_oss_config` VALUES (4, '000000', 'qcloud', 'XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX', 'ruoyi-1240000000', '', 'cos.ap-beijing.myqcloud.com', '', 'N', 'ap-beijing', '1', '1', '', 103, 1, '2026-02-03 05:14:52', 1, '2026-02-03 05:14:52', NULL); +INSERT INTO `sys_oss_config` VALUES (4, '000000', 'qcloud', 'xx', 'xx', 'ruoyiai-1254149996', '', 'cos.ap-guangzhou.myqcloud.com', '', 'Y', 'ap-guangzhou', '1', '0', '', 103, 1, '2026-02-03 05:14:52', 1, '2026-02-25 16:51:41', ''); INSERT INTO `sys_oss_config` VALUES (5, '000000', 'image', 'ruoyi', 'ruoyi123', 'ruoyi', 'image', '127.0.0.1:9000', '', 'N', '', '1', '1', '', 103, 1, '2026-02-03 05:14:53', 1, '2026-02-03 05:14:53', NULL); -- ---------------------------- @@ -3342,7 +3420,7 @@ CREATE TABLE `sys_user` ( -- ---------------------------- -- Records of sys_user -- ---------------------------- -INSERT INTO `sys_user` VALUES (1, '000000', 103, 'admin', 'admin', 'sys_user', 'ageerle@163.com', '15888888888', '1', NULL, '$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2', '0', '0', '127.0.0.1', '2026-02-06 00:28:13', 103, 1, '2026-02-05 09:22:12', -1, '2026-02-06 00:28:13', '管理员', NULL, 0.00); +INSERT INTO `sys_user` VALUES (1, '000000', 103, 'admin', 'admin', 'sys_user', 'ageerle@163.com', '15888888888', '1', NULL, '$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2', '0', '0', '127.0.0.1', '2026-02-27 13:54:12', 103, 1, '2026-02-05 09:22:12', -1, '2026-02-27 13:54:12', '管理员', NULL, 0.00); INSERT INTO `sys_user` VALUES (3, '000000', 108, 'test', '本部门及以下 密码666666', 'sys_user', '', '', '0', NULL, '$2a$10$b8yUzN0C71sbz.PhNOCgJe.Tu1yWC3RNrTyjSQ8p1W0.aaUXUJ.Ne', '0', '0', '127.0.0.1', '2026-02-05 09:22:12', 103, 1, '2026-02-05 09:22:12', 3, '2026-02-05 09:22:12', NULL, NULL, 0.00); INSERT INTO `sys_user` VALUES (4, '000000', 102, 'test1', '仅本人 密码666666', 'sys_user', '', '', '0', NULL, '$2a$10$b8yUzN0C71sbz.PhNOCgJe.Tu1yWC3RNrTyjSQ8p1W0.aaUXUJ.Ne', '0', '0', '127.0.0.1', '2026-02-05 09:22:12', 103, 1, '2026-02-05 09:22:12', 4, '2026-02-05 09:22:12', NULL, NULL, 0.00); @@ -3421,7 +3499,7 @@ CREATE TABLE `t_workflow_component` ( `tenant_id` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '000000' COMMENT '租户编号', PRIMARY KEY (`id`) USING BTREE, INDEX `idx_display_order`(`display_order` ASC) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 20 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '工作流组件库 | Workflow Component' ROW_FORMAT = DYNAMIC; +) ENGINE = InnoDB AUTO_INCREMENT = 37 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '工作流组件库 | Workflow Component' ROW_FORMAT = DYNAMIC; -- ---------------------------- -- Records of t_workflow_component @@ -3429,6 +3507,9 @@ CREATE TABLE `t_workflow_component` ( INSERT INTO `t_workflow_component` VALUES (17, '5cd68dccbbb411f0bb7840c2ba9a7fbc', 'Start', '开始', '流程由此开始', 0, 1, '2025-11-07 16:32:49', '2025-11-07 16:32:49', 0, '000000'); INSERT INTO `t_workflow_component` VALUES (18, '5cd6ac69bbb411f0bb7840c2ba9a7fbc', 'End', '结束', '流程由此结束', 0, 1, '2025-11-07 16:32:49', '2025-11-07 16:32:49', 0, '000000'); INSERT INTO `t_workflow_component` VALUES (19, '5cd6c8eabbb411f0bb7840c2ba9a7fbc', 'Answer', '生成回答', '调用大语言模型回答问题', 0, 1, '2025-11-07 16:32:49', '2025-11-07 16:32:49', 0, '000000'); +INSERT INTO `t_workflow_component` VALUES (25, '0b4369bb60dc46d6bd84ceb4e36184dc', 'KeywordExtractor', '关键词提取', '从文本中提取关键词', 0, 1, '2025-12-26 16:30:05', '2025-12-26 16:30:05', 0, '000000'); +INSERT INTO `t_workflow_component` VALUES (26, 'bb00fc2f52c74fec82ee3f99725b56bb', 'Switcher', '条件分支', '根据条件执行不同分支', 0, 1, '2025-12-26 16:30:46', '2025-12-26 16:30:46', 0, '000000'); +INSERT INTO `t_workflow_component` VALUES (36, 'f37dbcb8f0d5464d90fbb22774490a56', 'HumanFeedback', '人类', '人机沟通', 0, 1, '2025-12-30 17:37:14', '2025-12-30 17:37:14', 0, '000000'); -- ---------------------------- -- Table structure for t_workflow_edge diff --git a/pom.xml b/pom.xml index 4fda3ba8..372c2770 100644 --- a/pom.xml +++ b/pom.xml @@ -389,13 +389,6 @@ ${revision} - - - org.ruoyi - ruoyi-aihuman - ${revision} - - org.ruoyi diff --git a/ruoyi-admin/pom.xml b/ruoyi-admin/pom.xml index 28ce987a..4675462c 100644 --- a/ruoyi-admin/pom.xml +++ b/ruoyi-admin/pom.xml @@ -104,12 +104,6 @@ ruoyi-wechat - - - org.ruoyi - ruoyi-aihuman - - org.ruoyi diff --git a/ruoyi-modules/pom.xml b/ruoyi-modules/pom.xml index 17b9a97e..5db99df1 100644 --- a/ruoyi-modules/pom.xml +++ b/ruoyi-modules/pom.xml @@ -10,7 +10,6 @@ 4.0.0 - ruoyi-aihuman ruoyi-aiflow ruoyi-chat ruoyi-demo diff --git a/ruoyi-modules/ruoyi-aihuman/pom.xml b/ruoyi-modules/ruoyi-aihuman/pom.xml deleted file mode 100644 index baaf8619..00000000 --- a/ruoyi-modules/ruoyi-aihuman/pom.xml +++ /dev/null @@ -1,101 +0,0 @@ - - - 4.0.0 - - org.ruoyi - ruoyi-modules - ${revision} - ../pom.xml - - - ruoyi-aihuman - - - aihuman模块 - - - - 3.2.1 - 5.13.0 - 1.5.5 - - - - - - - org.ruoyi - ruoyi-common-core - - - - org.ruoyi - ruoyi-common-doc - - - - org.ruoyi - ruoyi-common-mybatis - - - - org.ruoyi - ruoyi-common-web - - - - org.ruoyi - ruoyi-common-log - - - - org.ruoyi - ruoyi-common-idempotent - - - - - org.apache.velocity - velocity-engine-core - - - - - - - - - - - - - - - - org.ruoyi - ruoyi-common-excel - - - - net.java.dev.jna - jna - ${jna.version} - - - - net.java.dev.jna - jna-platform - ${jna.version} - - - - org.java-websocket - Java-WebSocket - ${java-websocket.version} - - - - - diff --git a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/config/WebConfig.java b/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/config/WebConfig.java deleted file mode 100644 index 5ccaf134..00000000 --- a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/config/WebConfig.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.ruoyi.aihuman.config; - -import org.springframework.context.annotation.Configuration; -import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; - -@Configuration -public class WebConfig implements WebMvcConfigurer { - @Override - public void addResourceHandlers(ResourceHandlerRegistry registry) { - // 映射/voice/**路径到classpath:/voice/目录 - registry.addResourceHandler("/voice/**") - .addResourceLocations("classpath:/voice/") - .setCachePeriod(3600); - } -} \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/controller/AihumanConfigController.java b/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/controller/AihumanConfigController.java deleted file mode 100644 index c4397df8..00000000 --- a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/controller/AihumanConfigController.java +++ /dev/null @@ -1,126 +0,0 @@ -package org.ruoyi.aihuman.controller; - -import cn.dev33.satoken.annotation.SaCheckPermission; -import cn.dev33.satoken.annotation.SaIgnore; -import jakarta.servlet.http.HttpServletResponse; -import jakarta.validation.constraints.NotEmpty; -import jakarta.validation.constraints.NotNull; -import lombok.RequiredArgsConstructor; -import org.ruoyi.aihuman.domain.bo.AihumanConfigBo; -import org.ruoyi.aihuman.domain.vo.AihumanConfigVo; -import org.ruoyi.aihuman.service.AihumanConfigService; -import org.ruoyi.common.core.domain.R; -import org.ruoyi.common.core.validate.AddGroup; -import org.ruoyi.common.core.validate.EditGroup; -import org.ruoyi.common.excel.utils.ExcelUtil; -import org.ruoyi.common.idempotent.annotation.RepeatSubmit; -import org.ruoyi.common.log.annotation.Log; -import org.ruoyi.common.log.enums.BusinessType; -import org.ruoyi.common.mybatis.core.page.PageQuery; -import org.ruoyi.common.mybatis.core.page.TableDataInfo; -import org.ruoyi.common.web.core.BaseController; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -import java.util.List; - -/** - * 交互数字人配置 - * - * @author ageerle - * @date Fri Sep 26 22:27:00 GMT+08:00 2025 - */ - -//临时免登录 -@SaIgnore - -@Validated -@RequiredArgsConstructor -@RestController -@RequestMapping("/aihuman/aihumanConfig") -public class AihumanConfigController extends BaseController { - - private final AihumanConfigService aihumanConfigService; - - /** - * 查询交互数字人配置列表 - */ - @SaCheckPermission("aihuman:aihumanConfig:list") - @GetMapping("/list") - public TableDataInfo list(AihumanConfigBo bo, PageQuery pageQuery) { - return aihumanConfigService.queryPageList(bo, pageQuery); - } - - /** - * 导出交互数字人配置列表 - */ - @SaCheckPermission("aihuman:aihumanConfig:export") - @Log(title = "交互数字人配置", businessType = BusinessType.EXPORT) - @PostMapping("/export") - public void export(AihumanConfigBo bo, HttpServletResponse response) { - List list = aihumanConfigService.queryList(bo); - ExcelUtil.exportExcel(list, "交互数字人配置", AihumanConfigVo.class, response); - } - - /** - * 获取交互数字人配置详细信息 - * - * @param id 主键 - */ - @SaCheckPermission("aihuman:aihumanConfig:query") - @GetMapping("/{id}") - public R getInfo(@NotNull(message = "主键不能为空") - @PathVariable Integer id) { - return R.ok(aihumanConfigService.queryById(id)); - } - - /** - * 新增交互数字人配置 - */ - @SaCheckPermission("aihuman:aihumanConfig:add") - @Log(title = "交互数字人配置", businessType = BusinessType.INSERT) - @RepeatSubmit() - @PostMapping() - public R add(@Validated(AddGroup.class) @RequestBody AihumanConfigBo bo) { - return toAjax(aihumanConfigService.insertByBo(bo)); - } - - /** - * 修改交互数字人配置 - */ - @SaCheckPermission("aihuman:aihumanConfig:edit") - @Log(title = "交互数字人配置", businessType = BusinessType.UPDATE) - @RepeatSubmit() - @PutMapping() - public R edit(@Validated(EditGroup.class) @RequestBody AihumanConfigBo bo) { - return toAjax(aihumanConfigService.updateByBo(bo)); - } - - /** - * 删除交互数字人配置 - * - * @param ids 主键串 - */ - @SaCheckPermission("aihuman:aihumanConfig:remove") - @Log(title = "交互数字人配置", businessType = BusinessType.DELETE) - @DeleteMapping("/{ids}") - public R remove(@NotEmpty(message = "主键不能为空") - @PathVariable Integer[] ids) { - return toAjax(aihumanConfigService.deleteWithValidByIds(List.of(ids), true)); - } - - /** - * 查询已发布的交互数字人配置列表 - * 只返回 publish = 1 的数据 - */ - @GetMapping("/publishedList") - public TableDataInfo publishedList(PageQuery pageQuery) { - // 创建查询条件对象并设置publish=1 - AihumanConfigBo bo = new AihumanConfigBo(); - bo.setPublish(1); - // 调用现有的查询方法,传入预设了publish=1条件的bo对象 - return aihumanConfigService.queryPageList(bo, pageQuery); - } - - -} diff --git a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/controller/AihumanInfoController.java b/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/controller/AihumanInfoController.java deleted file mode 100644 index 2f0e9628..00000000 --- a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/controller/AihumanInfoController.java +++ /dev/null @@ -1,80 +0,0 @@ -package org.ruoyi.aihuman.controller; - -import cn.dev33.satoken.annotation.SaIgnore; -import lombok.RequiredArgsConstructor; -import org.ruoyi.aihuman.domain.AihumanInfo; -import org.ruoyi.aihuman.domain.vo.AihumanInfoVo; -import org.ruoyi.aihuman.service.IAihumanInfoService; -import org.ruoyi.common.core.domain.R; -import org.ruoyi.common.mybatis.core.page.PageQuery; -import org.ruoyi.common.mybatis.core.page.TableDataInfo; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -import java.util.Arrays; - -/** - * AI人类交互信息Controller - * 免登录接口,方便验证 - * - * @author QingYunAI - */ -@SaIgnore -@Validated -@RequiredArgsConstructor -@RestController -@RequestMapping("/aihuman/info") -public class AihumanInfoController { - - private final IAihumanInfoService aihumanInfoService; - - /** - * 获取AI人类交互信息详情 - */ - @GetMapping("/{id}") - public R getInfo(@PathVariable Long id) { - return R.ok(aihumanInfoService.queryById(id)); - } - - /** - * 查询AI人类交互信息列表 - */ - @GetMapping("/list") - public R> list(AihumanInfo aihumanInfo, PageQuery pageQuery) { - TableDataInfo tableDataInfo = aihumanInfoService.queryPageList(aihumanInfo, pageQuery); - return R.ok(tableDataInfo); - } - - /** - * 新增AI人类交互信息 - */ - @PostMapping - public R add(@Validated @RequestBody AihumanInfo aihumanInfo) { - return R.ok(aihumanInfoService.insert(aihumanInfo)); - } - - /** - * 修改AI人类交互信息 - */ - @PutMapping - public R edit(@Validated @RequestBody AihumanInfo aihumanInfo) { - return R.ok(aihumanInfoService.update(aihumanInfo)); - } - - /** - * 删除AI人类交互信息 - */ - @DeleteMapping("/{ids}") - public R remove(@PathVariable Long[] ids) { - return R.ok(aihumanInfoService.deleteWithValidByIds(Arrays.asList(ids), true)); - } - - /** - * 测试接口 - * 提供一个简单的GET接口用于快速验证控制器是否正常工作 - */ - @GetMapping("/test") - public R test() { - return R.ok("AI Human Controller is working!"); - } -} diff --git a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/controller/AihumanRealConfigController.java b/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/controller/AihumanRealConfigController.java deleted file mode 100644 index 46e47198..00000000 --- a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/controller/AihumanRealConfigController.java +++ /dev/null @@ -1,157 +0,0 @@ -package org.ruoyi.aihuman.controller; - -import cn.dev33.satoken.annotation.SaCheckPermission; -import cn.dev33.satoken.annotation.SaIgnore; -import jakarta.servlet.http.HttpServletResponse; -import jakarta.validation.constraints.NotEmpty; -import jakarta.validation.constraints.NotNull; -import lombok.RequiredArgsConstructor; -import org.ruoyi.aihuman.domain.bo.AihumanRealConfigBo; -import org.ruoyi.aihuman.domain.vo.AihumanRealConfigVo; -import org.ruoyi.aihuman.service.AihumanRealConfigService; -import org.ruoyi.common.core.domain.R; -import org.ruoyi.common.core.validate.AddGroup; -import org.ruoyi.common.core.validate.EditGroup; -import org.ruoyi.common.excel.utils.ExcelUtil; -import org.ruoyi.common.idempotent.annotation.RepeatSubmit; -import org.ruoyi.common.log.annotation.Log; -import org.ruoyi.common.log.enums.BusinessType; -import org.ruoyi.common.mybatis.core.page.PageQuery; -import org.ruoyi.common.mybatis.core.page.TableDataInfo; -import org.ruoyi.common.web.core.BaseController; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -import java.util.List; - -/** - * 真人交互数字人配置 - * - * @author ageerle - * @date Tue Oct 21 11:46:52 GMT+08:00 2025 - */ -//临时免登录 -@SaIgnore - -@Validated -@RequiredArgsConstructor -@RestController -@RequestMapping("/aihuman/aihumanRealConfig") -public class AihumanRealConfigController extends BaseController { - - private final AihumanRealConfigService aihumanRealConfigService; - - /** - * 查询真人交互数字人配置列表 - */ - @SaCheckPermission("aihuman:aihumanRealConfig:list") - @GetMapping("/list") - public TableDataInfo list(AihumanRealConfigBo bo, PageQuery pageQuery) { - return aihumanRealConfigService.queryPageList(bo, pageQuery); - } - - /** - * 导出真人交互数字人配置列表 - */ - @SaCheckPermission("aihuman:aihumanRealConfig:export") - @Log(title = "真人交互数字人配置", businessType = BusinessType.EXPORT) - @PostMapping("/export") - public void export(AihumanRealConfigBo bo, HttpServletResponse response) { - List list = aihumanRealConfigService.queryList(bo); - ExcelUtil.exportExcel(list, "真人交互数字人配置", AihumanRealConfigVo.class, response); - } - - /** - * 获取真人交互数字人配置详细信息 - * - * @param id 主键 - */ - @SaCheckPermission("aihuman:aihumanRealConfig:query") - @GetMapping("/{id}") - public R getInfo(@NotNull(message = "主键不能为空") - @PathVariable Integer id) { - return R.ok(aihumanRealConfigService.queryById(id)); - } - - /** - * 新增真人交互数字人配置 - */ - @SaCheckPermission("aihuman:aihumanRealConfig:add") - @Log(title = "真人交互数字人配置", businessType = BusinessType.INSERT) - @RepeatSubmit() - @PostMapping() - public R add(@Validated(AddGroup.class) @RequestBody AihumanRealConfigBo bo) { - return toAjax(aihumanRealConfigService.insertByBo(bo)); - } - - /** - * 修改真人交互数字人配置 - */ - @SaCheckPermission("aihuman:aihumanRealConfig:edit") - @Log(title = "真人交互数字人配置", businessType = BusinessType.UPDATE) - @RepeatSubmit() - @PutMapping() - public R edit(@Validated(EditGroup.class) @RequestBody AihumanRealConfigBo bo) { - return toAjax(aihumanRealConfigService.updateByBo(bo)); - } - - /** - * 删除真人交互数字人配置 - * - * @param ids 主键串 - */ - @SaCheckPermission("aihuman:aihumanRealConfig:remove") - @Log(title = "真人交互数字人配置", businessType = BusinessType.DELETE) - @DeleteMapping("/{ids}") - public R remove(@NotEmpty(message = "主键不能为空") - @PathVariable Integer[] ids) { - return toAjax(aihumanRealConfigService.deleteWithValidByIds(List.of(ids), true)); - } - - /** - * 1.执行以下命令: - * cd F:\Projects\AI-Human\LiveTalking - * conda activate D:\zg117\C\Users\zg117\.conda\envs\livetalking_new - * python app.py --transport webrtc --model wav2lip --avatar_id wav2lip256_avatar1 - *

- * 2.监听 python app.py --transport webrtc --model wav2lip --avatar_id wav2lip256_avatar1 执行情况 - *

- * 3.返回执行结果并打开页面 - * http://127.0.0.1:8010/webrtcapi-diy.html - */ - @SaCheckPermission("aihuman:aihumanRealConfig:run") - //@Log(title = "真人交互数字人配置", businessType = BusinessType.UPDATE, operatorType = OperatorType.OTHER) - @RepeatSubmit() - @PutMapping("/run") - public R run(@Validated(EditGroup.class) @RequestBody AihumanRealConfigBo bo) { - boolean result = aihumanRealConfigService.runByBo(bo); - if (result) { - // 返回前端页面URL,前端可以根据这个URL跳转或打开新页面 - // http://127.0.0.1:8010/webrtcapi-diy.html 其中的 http://127.0.0.1 获取当前java服务的IP地址 - // return R.ok("http://127.0.0.1:8010/webrtcapi-diy.html"); - // 运行状态 - bo.setRunStatus("1"); - return R.ok("http://127.0.0.1:8010/webrtcapi-diy.html"); - } else { - return R.fail("启动真人交互数字人失败"); - } - } - - /** - * 停止真人交互数字人配置任务 - */ - @SaCheckPermission("aihuman:aihumanRealConfig:stop") - //@Log(title = "真人交互数字人配置", businessType = BusinessType.UPDATE, operatorType = OperatorType.OTHER) - @RepeatSubmit() - @PutMapping("/stop") - public R stop(@Validated(EditGroup.class) @RequestBody AihumanRealConfigBo bo) { - boolean result = aihumanRealConfigService.stopByBo(bo); - if (result) { - // 运行状态 - bo.setRunStatus("0"); - return R.ok("真人交互数字人任务已停止"); - } else { - return R.fail("停止真人交互数字人任务失败或没有正在运行的任务"); - } - } -} diff --git a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/controller/AihumanVolcengineController.java b/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/controller/AihumanVolcengineController.java deleted file mode 100644 index e9b3e99a..00000000 --- a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/controller/AihumanVolcengineController.java +++ /dev/null @@ -1,502 +0,0 @@ -package org.ruoyi.aihuman.controller; - -import cn.dev33.satoken.annotation.SaIgnore; -import com.fasterxml.jackson.databind.ObjectMapper; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.ruoyi.aihuman.domain.VoiceRequest; -import org.ruoyi.aihuman.protocol.EventType; -import org.ruoyi.aihuman.protocol.Message; -import org.ruoyi.aihuman.protocol.MsgType; -import org.ruoyi.aihuman.protocol.SpeechWebSocketClient; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.core.io.ResourceLoader; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.net.URI; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.nio.file.StandardOpenOption; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; - -/** - * 火山引擎相关接口 - * - * @author ruoyi - */ -// 临时免登录 -@SaIgnore - -@Validated -@RequiredArgsConstructor -@Slf4j -@RestController -@RequestMapping("/aihuman/volcengine") -public class AihumanVolcengineController { - - private static final ObjectMapper objectMapper = new ObjectMapper(); - private static final Logger logger = LoggerFactory.getLogger(AihumanVolcengineController.class); - @Autowired - private ResourceLoader resourceLoader; - - @PostMapping("/generate-voice-direct") - public ResponseEntity generateVoiceDirect(@RequestBody VoiceRequest request) { - try { - // 生成唯一的语音ID - String voiceId = UUID.randomUUID().toString().replace("-", ""); - - log.info("开始生成语音,voiceId: {}", voiceId); - - // 调用火山引擎TTS API获取音频数据 - byte[] audioData = generateVoiceData(request, voiceId); - - // 设置响应头,返回音频数据 - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.parseMediaType("audio/wav")); - headers.setContentDispositionFormData("attachment", "voice_" + System.currentTimeMillis() + ".wav"); - headers.setContentLength(audioData.length); - - log.info("语音生成成功并返回,长度: {} bytes", audioData.length); - return new ResponseEntity<>(audioData, headers, HttpStatus.OK); - } catch (Exception e) { - log.error("生成语音失败", e); - return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); - } - } - - private byte[] generateVoiceData(VoiceRequest request, String voiceId) { - try { - // 这里是调用火山引擎TTS API的核心逻辑 - // 您需要根据火山引擎的API文档实现具体的调用逻辑 - // 注意:这只是一个示例框架,您需要根据实际情况进行实现 - - // 调用火山引擎API并获取音频数据 - // 假设您已经有现有的调用逻辑,这里保留原有的实现 - String endpoint = request.getEndpoint(); - String appId = request.getAppId(); - String accessToken = request.getAccessToken(); - String resourceId = request.getResourceId(); - String voice = request.getVoice(); - String text = request.getText(); - String encoding = request.getEncoding(); - - // 调用原有的火山引擎API调用方法(如果有) - // 或者直接在这里实现API调用逻辑 - byte[] audioData = callVolcengineTtsApiByte(endpoint, appId, accessToken, - resourceId, voice, text, encoding); - - log.info("成功生成语音数据,大小: {} bytes", audioData.length); - return audioData; - } catch (Exception e) { - log.error("生成语音数据失败", e); - throw new RuntimeException("生成语音数据失败", e); - } - - } - - private byte[] callVolcengineTtsApiByte(String endpoint, String appId, String accessToken, - String resourceId, String voice, String text, String encoding) { - try { - // 确保resourceId不为空,如果为空则根据voice类型获取默认值 - if (resourceId == null || resourceId.isEmpty()) { - resourceId = voiceToResourceId(voice); - } - - // 设置请求头 - Map headers = new HashMap<>(); - headers.put("X-Api-App-Key", appId); - headers.put("X-Api-Access-Key", accessToken); - headers.put("X-Api-Resource-Id", resourceId); - headers.put("X-Api-Connect-Id", UUID.randomUUID().toString()); - - // 创建WebSocket客户端 - SpeechWebSocketClient client = new SpeechWebSocketClient(new URI(endpoint), headers); - ByteArrayOutputStream totalAudioStream = new ByteArrayOutputStream(); - boolean audioReceived = false; - - try { - // 连接WebSocket - client.connectBlocking(); - - // 构建请求参数 - Map request = new HashMap<>(); - request.put("user", Map.of("uid", UUID.randomUUID().toString())); - request.put("namespace", "BidirectionalTTS"); - - Map reqParams = new HashMap<>(); - reqParams.put("speaker", voice); - - Map audioParams = new HashMap<>(); - audioParams.put("format", encoding); - audioParams.put("sample_rate", 24000); - audioParams.put("enable_timestamp", true); - - reqParams.put("audio_params", audioParams); - reqParams.put("additions", objectMapper.writeValueAsString(Map.of("disable_markdown_filter", false))); - - request.put("req_params", reqParams); - - // 开始连接 - client.sendStartConnection(); - // 等待连接成功 - client.waitForMessage(MsgType.FULL_SERVER_RESPONSE, EventType.CONNECTION_STARTED); - - // 处理每个句子 - String[] sentences = text.split("。"); - for (int i = 0; i < sentences.length; i++) { - if (sentences[i].trim().isEmpty()) { - continue; - } - - String sessionId = UUID.randomUUID().toString(); - ByteArrayOutputStream sentenceAudioStream = new ByteArrayOutputStream(); - - // 开始会话 - Map startReq = new HashMap<>(); - startReq.put("user", request.get("user")); - startReq.put("namespace", request.get("namespace")); - startReq.put("req_params", request.get("req_params")); - startReq.put("event", EventType.START_SESSION.getValue()); - client.sendStartSession(objectMapper.writeValueAsBytes(startReq), sessionId); - // 等待会话开始 - client.waitForMessage(MsgType.FULL_SERVER_RESPONSE, EventType.SESSION_STARTED); - - // 发送文本内容 - for (char c : sentences[i].toCharArray()) { - @SuppressWarnings("unchecked") - Map currentReqParams = new HashMap<>((Map) request.get("req_params")); - currentReqParams.put("text", String.valueOf(c)); - - Map currentRequest = new HashMap<>(); - currentRequest.put("user", request.get("user")); - currentRequest.put("namespace", request.get("namespace")); - currentRequest.put("req_params", currentReqParams); - currentRequest.put("event", EventType.TASK_REQUEST.getValue()); - - client.sendTaskRequest(objectMapper.writeValueAsBytes(currentRequest), sessionId); - } - - // 结束会话 - client.sendFinishSession(sessionId); - - // 接收响应 - while (true) { - Message msg = client.receiveMessage(); - switch (msg.getType()) { - case FULL_SERVER_RESPONSE: - break; - case AUDIO_ONLY_SERVER: - if (!audioReceived && sentenceAudioStream.size() > 0) { - audioReceived = true; - } - if (msg.getPayload() != null) { - sentenceAudioStream.write(msg.getPayload()); - } - break; - default: - // 不抛出异常,记录日志并继续处理 - log.warn("Unexpected message type: {}", msg.getType()); - } - if (msg.getEvent() == EventType.SESSION_FINISHED) { - break; - } - } - - // 将当前句子的音频追加到总音频流 - if (sentenceAudioStream.size() > 0) { - totalAudioStream.write(sentenceAudioStream.toByteArray()); - } - } - - // 验证是否收到音频数据 - if (totalAudioStream.size() > 0) { - log.info("Audio data generated successfully, size: {} bytes", totalAudioStream.size()); - return totalAudioStream.toByteArray(); - } else { - throw new RuntimeException("No audio data received"); - } - } finally { - // 结束连接 - client.sendFinishConnection(); - client.closeBlocking(); - } - } catch (Exception e) { - log.error("Error calling Volcengine TTS API: {}", e.getMessage(), e); - throw new RuntimeException("Failed to generate voice", e); - } - } - - - /** - * 生成语音文件接口 - * 用户传入JSON参数,返回音频文件的播放地址 - */ - @PostMapping("/generate-voice") - public ResponseEntity generateVoice(@RequestBody VoiceRequest request) { - try { - // 1. 解析请求参数 - String endpoint = request.getEndpoint(); - String appId = request.getAppId(); - String accessToken = request.getAccessToken(); - String resourceId = request.getResourceId(); - String voice = request.getVoice(); - String text = request.getText(); - String encoding = request.getEncoding(); - - // 1.1 验证必要参数 - if (endpoint == null || endpoint.isEmpty()) { - return ResponseEntity.badRequest().body(Map.of("error", "endpoint cannot be null or empty")); - } - if (appId == null || appId.isEmpty()) { - return ResponseEntity.badRequest().body(Map.of("error", "appId cannot be null or empty")); - } - if (accessToken == null || accessToken.isEmpty()) { - return ResponseEntity.badRequest().body(Map.of("error", "accessToken cannot be null or empty")); - } - if (text == null || text.isEmpty()) { - return ResponseEntity.badRequest().body(Map.of("error", "text cannot be null or empty")); - } - - // 1.2 设置默认值 - if (encoding == null || encoding.isEmpty()) { - encoding = "mp3"; - } - - // 2. 调用火山引擎API生成音频文件 - String audioUrl = callVolcengineTtsApi(endpoint, appId, accessToken, resourceId, voice, text, encoding); - - // 3. 构造并返回响应 - Map response = new HashMap<>(); - response.put("audioUrl", audioUrl); - - return ResponseEntity.ok(response); - } catch (Exception e) { - // 处理异常情况 - Map errorResponse = new HashMap<>(); - errorResponse.put("error", "生成音频文件失败: " + e.getMessage()); - return ResponseEntity.status(500).body(errorResponse); - } - } - - /** - * 调用火山引擎TTS API生成音频文件 - */ - private String callVolcengineTtsApi(String endpoint, String appId, String accessToken, - String resourceId, String voice, String text, String encoding) { - try { - // 确保resourceId不为空,如果为空则根据voice类型获取默认值 - if (resourceId == null || resourceId.isEmpty()) { - resourceId = voiceToResourceId(voice); - } - - // 生成唯一的文件名 - String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")); - String randomId = UUID.randomUUID().toString().substring(0, 8); - String fileName = "voice_" + timestamp + "_" + randomId + "." + encoding; - - // 获取resources/voice目录路径 - String voiceDirPath = getVoiceDirectoryPath(); - File voiceDir = new File(voiceDirPath); - if (!voiceDir.exists()) { - voiceDir.mkdirs(); - } - - String filePath = voiceDirPath + File.separator + fileName; - - // 设置请求头 - Map headers = new HashMap<>(); - headers.put("X-Api-App-Key", appId); - headers.put("X-Api-Access-Key", accessToken); - headers.put("X-Api-Resource-Id", resourceId); - headers.put("X-Api-Connect-Id", UUID.randomUUID().toString()); - - // 创建WebSocket客户端 - SpeechWebSocketClient client = new SpeechWebSocketClient(new URI(endpoint), headers); - ByteArrayOutputStream totalAudioStream = new ByteArrayOutputStream(); - boolean audioReceived = false; - - try { - // 连接WebSocket - client.connectBlocking(); - - // 构建请求参数 - Map request = new HashMap<>(); - request.put("user", Map.of("uid", UUID.randomUUID().toString())); - request.put("namespace", "BidirectionalTTS"); - - Map reqParams = new HashMap<>(); - reqParams.put("speaker", voice); - - Map audioParams = new HashMap<>(); - audioParams.put("format", encoding); - audioParams.put("sample_rate", 24000); - audioParams.put("enable_timestamp", true); - - reqParams.put("audio_params", audioParams); - reqParams.put("additions", objectMapper.writeValueAsString(Map.of("disable_markdown_filter", false))); - - request.put("req_params", reqParams); - - // 开始连接 - client.sendStartConnection(); - // 等待连接成功 - client.waitForMessage(MsgType.FULL_SERVER_RESPONSE, EventType.CONNECTION_STARTED); - - // 处理每个句子 - String[] sentences = text.split("。"); - for (int i = 0; i < sentences.length; i++) { - if (sentences[i].trim().isEmpty()) { - continue; - } - - String sessionId = UUID.randomUUID().toString(); - ByteArrayOutputStream sentenceAudioStream = new ByteArrayOutputStream(); - - // 开始会话 - Map startReq = new HashMap<>(); - startReq.put("user", request.get("user")); - startReq.put("namespace", request.get("namespace")); - startReq.put("req_params", request.get("req_params")); - startReq.put("event", EventType.START_SESSION.getValue()); - client.sendStartSession(objectMapper.writeValueAsBytes(startReq), sessionId); - // 等待会话开始 - client.waitForMessage(MsgType.FULL_SERVER_RESPONSE, EventType.SESSION_STARTED); - - // 发送文本内容 - for (char c : sentences[i].toCharArray()) { - @SuppressWarnings("unchecked") - Map currentReqParams = new HashMap<>((Map) request.get("req_params")); - currentReqParams.put("text", String.valueOf(c)); - - Map currentRequest = new HashMap<>(); - currentRequest.put("user", request.get("user")); - currentRequest.put("namespace", request.get("namespace")); - currentRequest.put("req_params", currentReqParams); - currentRequest.put("event", EventType.TASK_REQUEST.getValue()); - - client.sendTaskRequest(objectMapper.writeValueAsBytes(currentRequest), sessionId); - } - - // 结束会话 - client.sendFinishSession(sessionId); - - // 接收响应 - while (true) { - Message msg = client.receiveMessage(); - switch (msg.getType()) { - case FULL_SERVER_RESPONSE: - break; - case AUDIO_ONLY_SERVER: - if (!audioReceived && sentenceAudioStream.size() > 0) { - audioReceived = true; - } - if (msg.getPayload() != null) { - sentenceAudioStream.write(msg.getPayload()); - } - break; - default: - // 不抛出异常,记录日志并继续处理 - log.warn("Unexpected message type: {}", msg.getType()); - } - if (msg.getEvent() == EventType.SESSION_FINISHED) { - break; - } - } - - // 将当前句子的音频追加到总音频流 - if (sentenceAudioStream.size() > 0) { - totalAudioStream.write(sentenceAudioStream.toByteArray()); - } - } - - // 保存音频文件 - if (totalAudioStream.size() > 0) { - Files.write(Paths.get(filePath), totalAudioStream.toByteArray(), StandardOpenOption.CREATE); - log.info("Audio saved to file: {}", filePath); - } else { - throw new RuntimeException("No audio data received"); - } - - // 结束连接 - client.sendFinishConnection(); - } finally { - client.closeBlocking(); - } - - // 返回音频文件的访问路径 - return "/voice/" + fileName; - } catch (Exception e) { - log.error("Error calling Volcengine TTS API: {}", e.getMessage(), e); - throw new RuntimeException("Failed to generate voice", e); - } - } - - /** - * 根据voice类型获取resourceId - */ - private String voiceToResourceId(String voice) { - if (voice != null && voice.startsWith("S_")) { - return "volc.megatts.default"; - } - return "volc.service_type.10029"; - } - - /** - * 获取voice目录路径 - */ - private String getVoiceDirectoryPath() { - try { - // 获取当前项目根目录 - String projectRoot = System.getProperty("user.dir"); - - // 构建目标目录路径:ruoyi-ai/ruoyi-modules/ruoyi-aihuman/src/main/resources/voice - File targetDir = new File(projectRoot, "ruoyi-modules/ruoyi-aihuman/src/main/resources/voice"); - - // 确保目录存在 - if (!targetDir.exists()) { - boolean created = targetDir.mkdirs(); - if (created) { - logger.info("成功创建目录: {}", targetDir.getAbsolutePath()); - } else { - logger.warn("无法创建目录: {}", targetDir.getAbsolutePath()); - - // 降级方案:直接使用项目根目录下的voice文件夹 - File fallbackDir = new File(projectRoot, "voice"); - if (!fallbackDir.exists()) { - fallbackDir.mkdirs(); - } - return fallbackDir.getAbsolutePath(); - } - } - - return targetDir.getAbsolutePath(); - } catch (Exception e) { - logger.error("获取音频目录路径失败", e); - - // 异常情况下的安全降级 - File safeDir = new File("voice"); - if (!safeDir.exists()) { - safeDir.mkdirs(); - } - return safeDir.getAbsolutePath(); - } - } -} - - diff --git a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/domain/AihumanConfig.java b/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/domain/AihumanConfig.java deleted file mode 100644 index 5e9fadbb..00000000 --- a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/domain/AihumanConfig.java +++ /dev/null @@ -1,74 +0,0 @@ -package org.ruoyi.aihuman.domain; - -import com.baomidou.mybatisplus.annotation.IdType; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableName; -import lombok.Data; - -import java.io.Serializable; -import java.time.LocalDateTime; - -/** - * 交互数字人配置对象 aihuman_config - * - * @author ageerle - * @date Fri Sep 26 22:27:00 GMT+08:00 2025 - */ -@Data -@TableName("aihuman_config") -public class AihumanConfig implements Serializable { - - - /** - * id - */ - @TableId(value = "id", type = IdType.AUTO) - private Integer id; - - /** - * name - */ - private String name; - - /** - * modelName - */ - private String modelName; - - /** - * modelPath - */ - private String modelPath; - - /** - * modelParams - */ - private String modelParams; - - /** - * agentParams - */ - private String agentParams; - - /** - * createTime - */ - private LocalDateTime createTime; - - /** - * updateTime - */ - private LocalDateTime updateTime; - - /** - * status - */ - private Integer status; - - /** - * publish - */ - private Integer publish; - - -} diff --git a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/domain/AihumanInfo.java b/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/domain/AihumanInfo.java deleted file mode 100644 index 9be681f2..00000000 --- a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/domain/AihumanInfo.java +++ /dev/null @@ -1,52 +0,0 @@ -package org.ruoyi.aihuman.domain; - -import com.baomidou.mybatisplus.annotation.*; -import lombok.Data; - -import java.io.Serializable; -import java.util.Date; - -/** - * AI人类交互信息实体类 - * - * @author QingYunAI - */ -@Data -@TableName("aihuman_info") -public class AihumanInfo implements Serializable { - private static final long serialVersionUID = 1L; - - /** - * 主键ID - */ - @TableId(value = "id", type = IdType.AUTO) - private Long id; - - /** - * 交互名称 - */ - private String name; - - /** - * 交互内容 - */ - private String content; - - /** - * 创建时间 - */ - @TableField(fill = FieldFill.INSERT) - private Date createTime; - - /** - * 更新时间 - */ - @TableField(fill = FieldFill.INSERT_UPDATE) - private Date updateTime; - - /** - * 删除标志(0代表存在 2代表删除) - */ - @TableLogic - private String delFlag; -} \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/domain/AihumanRealConfig.java b/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/domain/AihumanRealConfig.java deleted file mode 100644 index c87f9bcd..00000000 --- a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/domain/AihumanRealConfig.java +++ /dev/null @@ -1,104 +0,0 @@ -package org.ruoyi.aihuman.domain; - -import com.baomidou.mybatisplus.annotation.IdType; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableName; -import lombok.Data; - -import java.io.Serializable; -import java.time.LocalDateTime; - -/** - * 真人交互数字人配置对象 aihuman_real_config - * - * @author ageerle - * @date Tue Oct 21 11:46:52 GMT+08:00 2025 - */ -@Data -@TableName("aihuman_real_config") -public class AihumanRealConfig implements Serializable { - - - /** - * 主键id - */ - @TableId(value = "id", type = IdType.AUTO) - private Integer id; - - /** - * 场景名称 - */ - private String name; - - /** - * 真人形象名称 - */ - private String avatars; - - /** - * 模型名称 - */ - private String models; - - /** - * 形象参数(预留) - */ - private String avatarsParams; - - /** - * 模型参数(预留) - */ - private String modelsParams; - - /** - * 智能体参数(扣子) - */ - private String agentParams; - - /** - * 创建时间 - */ - private LocalDateTime createTime; - - /** - * 更新时间 - */ - private LocalDateTime updateTime; - - /** - * 状态 - */ - private Integer status; - - /** - * 发布状态 - */ - private Integer publish; - - /** - * 运行参数 - */ - private String runParams; - - /** - * 运行状态 - */ - private String runStatus; - - /** - * 创建部门 - */ - private String createDept; - - /** - * 创建用户 - */ - private String createBy; - - /** - * 更新用户 - */ - private String updateBy; - - -} \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/domain/VoiceRequest.java b/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/domain/VoiceRequest.java deleted file mode 100644 index 4ed0d017..00000000 --- a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/domain/VoiceRequest.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.ruoyi.aihuman.domain; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.Data; - - -/** - * 语音请求参数实体类 - */ -@Data -public class VoiceRequest { - - @JsonProperty("ENDPOINT") - private String endpoint; - private String appId; - private String accessToken; - private String resourceId; - private String voice; - private String text; - private String encoding; - -} \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/domain/bo/AihumanConfigBo.java b/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/domain/bo/AihumanConfigBo.java deleted file mode 100644 index ac9ffad0..00000000 --- a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/domain/bo/AihumanConfigBo.java +++ /dev/null @@ -1,65 +0,0 @@ -package org.ruoyi.aihuman.domain.bo; - -import io.github.linpeilie.annotations.AutoMapper; -import jakarta.validation.constraints.NotNull; -import lombok.Data; -import org.ruoyi.aihuman.domain.AihumanConfig; -import org.ruoyi.common.core.validate.AddGroup; -import org.ruoyi.common.core.validate.EditGroup; - -import java.io.Serializable; -import java.time.LocalDateTime; - -/** - * 交互数字人配置业务对象 aihuman_config - * - * @author ageerle - * @date Fri Sep 26 22:27:00 GMT+08:00 2025 - */ -@Data - -@AutoMapper(target = AihumanConfig.class, reverseConvertGenerate = false) -public class AihumanConfigBo implements Serializable { - - private Integer id; - - /** - * name - */ - private String name; - /** - * modelName - */ - private String modelName; - /** - * modelPath - */ - private String modelPath; - /** - * modelParams - */ - private String modelParams; - /** - * agentParams - */ - private String agentParams; - /** - * createTime - */ - private LocalDateTime createTime; - /** - * updateTime - */ - private LocalDateTime updateTime; - /** - * status - */ - @NotNull(message = "status不能为空", groups = {AddGroup.class, EditGroup.class}) - private Integer status; - /** - * publish - */ - @NotNull(message = "publish不能为空", groups = {AddGroup.class, EditGroup.class}) - private Integer publish; - -} diff --git a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/domain/bo/AihumanInfoBo.java b/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/domain/bo/AihumanInfoBo.java deleted file mode 100644 index c6e49989..00000000 --- a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/domain/bo/AihumanInfoBo.java +++ /dev/null @@ -1,44 +0,0 @@ -package org.ruoyi.aihuman.domain.bo; - -import io.github.linpeilie.annotations.AutoMapper; -import lombok.Data; -import org.ruoyi.aihuman.domain.AihumanInfo; - -import java.io.Serializable; -import java.time.LocalDateTime; - -/** - * 数字人信息管理业务对象 aihuman_info - * - * @author ageerle - * @date Fri Sep 26 20:03:06 GMT+08:00 2025 - */ -@Data - -@AutoMapper(target = AihumanInfo.class, reverseConvertGenerate = false) -public class AihumanInfoBo implements Serializable { - - private Long id; - - /** - * 交互名称 - */ - private String name; - /** - * 交互内容 - */ - private String content; - /** - * 创建时间 - */ - private LocalDateTime createTime; - /** - * 更新时间 - */ - private LocalDateTime updateTime; - /** - * 删除标志(0代表存在 2代表删除) - */ - private String delFlag; - -} diff --git a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/domain/bo/AihumanRealConfigBo.java b/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/domain/bo/AihumanRealConfigBo.java deleted file mode 100644 index 2008c97c..00000000 --- a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/domain/bo/AihumanRealConfigBo.java +++ /dev/null @@ -1,87 +0,0 @@ -package org.ruoyi.aihuman.domain.bo; - -import io.github.linpeilie.annotations.AutoMapper; -import lombok.Data; -import org.ruoyi.aihuman.domain.AihumanRealConfig; - -import java.io.Serializable; -import java.time.LocalDateTime; - -/** - * 真人交互数字人配置业务对象 aihuman_real_config - * - * @author ageerle - * @date Tue Oct 21 11:46:52 GMT+08:00 2025 - */ -@Data - -@AutoMapper(target = AihumanRealConfig.class, reverseConvertGenerate = false) -public class AihumanRealConfigBo implements Serializable { - - private Integer id; - - /** - * 场景名称 - */ - private String name; - /** - * 真人形象名称 - */ - private String avatars; - /** - * 模型名称 - */ - private String models; - /** - * 形象参数(预留) - */ - private String avatarsParams; - /** - * 模型参数(预留) - */ - private String modelsParams; - /** - * 智能体参数(扣子) - */ - private String agentParams; - /** - * 创建时间 - */ - private LocalDateTime createTime; - /** - * 更新时间 - */ - private LocalDateTime updateTime; - /** - * 状态 - */ - private Integer status; - /** - * 发布状态 - */ - private Integer publish; - - /** - * 运行参数 - */ - private String runParams; - - /** - * 运行状态 - */ - private String runStatus; - - /** - * 创建部门 - */ - private String createDept; - /** - * 创建用户 - */ - private String createBy; - /** - * 更新用户 - */ - private String updateBy; - -} \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/domain/vo/AihumanConfigVo.java b/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/domain/vo/AihumanConfigVo.java deleted file mode 100644 index 93fffa76..00000000 --- a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/domain/vo/AihumanConfigVo.java +++ /dev/null @@ -1,75 +0,0 @@ -package org.ruoyi.aihuman.domain.vo; - -import cn.idev.excel.annotation.ExcelIgnoreUnannotated; -import cn.idev.excel.annotation.ExcelProperty; -import io.github.linpeilie.annotations.AutoMapper; -import lombok.Data; -import org.ruoyi.aihuman.domain.AihumanConfig; -import org.ruoyi.common.excel.annotation.ExcelDictFormat; -import org.ruoyi.common.excel.convert.ExcelDictConvert; - -import java.io.Serializable; -import java.time.LocalDateTime; - - -/** - * 交互数字人配置视图对象 aihuman_config - * - * @author ageerle - * @date Fri Sep 26 22:27:00 GMT+08:00 2025 - */ -@Data -@ExcelIgnoreUnannotated -@AutoMapper(target = AihumanConfig.class) -public class AihumanConfigVo implements Serializable { - - private Integer id; - /** - * name - */ - @ExcelProperty(value = "name") - private String name; - /** - * modelName - */ - @ExcelProperty(value = "modelName") - private String modelName; - /** - * modelPath - */ - @ExcelProperty(value = "modelPath") - private String modelPath; - /** - * modelParams - */ - @ExcelProperty(value = "modelParams") - private String modelParams; - /** - * agentParams - */ - @ExcelProperty(value = "agentParams") - private String agentParams; - /** - * createTime - */ - @ExcelProperty(value = "createTime") - private LocalDateTime createTime; - /** - * updateTime - */ - @ExcelProperty(value = "updateTime") - private LocalDateTime updateTime; - /** - * status - */ - @ExcelProperty(value = "status", converter = ExcelDictConvert.class) - @ExcelDictFormat(dictType = "sys_common_status") - private Integer status; - /** - * publish - */ - @ExcelProperty(value = "publish", converter = ExcelDictConvert.class) - @ExcelDictFormat(dictType = "sys_common_status") - private Integer publish; - -} diff --git a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/domain/vo/AihumanInfoVo.java b/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/domain/vo/AihumanInfoVo.java deleted file mode 100644 index a36d7fbd..00000000 --- a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/domain/vo/AihumanInfoVo.java +++ /dev/null @@ -1,44 +0,0 @@ -package org.ruoyi.aihuman.domain.vo; - -import io.github.linpeilie.annotations.AutoMapper; -import lombok.Data; -import org.ruoyi.aihuman.domain.AihumanInfo; - -import java.io.Serializable; -import java.util.Date; - -/** - * AI人类交互信息视图对象 - * - * @author QingYunAI - */ -@Data -@AutoMapper(target = AihumanInfo.class) -public class AihumanInfoVo implements Serializable { - private static final long serialVersionUID = 1L; - - /** - * 主键ID - */ - private Long id; - - /** - * 交互名称 - */ - private String name; - - /** - * 交互内容 - */ - private String content; - - /** - * 创建时间 - */ - private Date createTime; - - /** - * 更新时间 - */ - private Date updateTime; -} \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/domain/vo/AihumanRealConfigVo.java b/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/domain/vo/AihumanRealConfigVo.java deleted file mode 100644 index f6fe020e..00000000 --- a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/domain/vo/AihumanRealConfigVo.java +++ /dev/null @@ -1,109 +0,0 @@ -package org.ruoyi.aihuman.domain.vo; - -import cn.idev.excel.annotation.ExcelIgnoreUnannotated; -import cn.idev.excel.annotation.ExcelProperty; -import io.github.linpeilie.annotations.AutoMapper; -import lombok.Data; -import org.ruoyi.aihuman.domain.AihumanRealConfig; -import org.ruoyi.common.excel.annotation.ExcelDictFormat; -import org.ruoyi.common.excel.convert.ExcelDictConvert; - -import java.io.Serializable; -import java.time.LocalDateTime; - - -/** - * 真人交互数字人配置视图对象 aihuman_real_config - * - * @author ageerle - * @date Tue Oct 21 11:46:52 GMT+08:00 2025 - */ -@Data -@ExcelIgnoreUnannotated -@AutoMapper(target = AihumanRealConfig.class) -public class AihumanRealConfigVo implements Serializable { - - private Integer id; - /** - * 场景名称 - */ - @ExcelProperty(value = "场景名称") - private String name; - /** - * 真人形象名称 - */ - @ExcelProperty(value = "真人形象名称") - private String avatars; - /** - * 模型名称 - */ - @ExcelProperty(value = "模型名称") - private String models; - /** - * 形象参数(预留) - */ - @ExcelProperty(value = "形象参数", converter = ExcelDictConvert.class) - @ExcelDictFormat(readConverterExp = "$column.readConverterExp()") - private String avatarsParams; - /** - * 模型参数(预留) - */ - @ExcelProperty(value = "模型参数", converter = ExcelDictConvert.class) - @ExcelDictFormat(readConverterExp = "$column.readConverterExp()") - private String modelsParams; - /** - * 智能体参数(扣子) - */ - @ExcelProperty(value = "智能体参数", converter = ExcelDictConvert.class) - @ExcelDictFormat(readConverterExp = "$column.readConverterExp()") - private String agentParams; - /** - * 创建时间 - */ - @ExcelProperty(value = "创建时间") - private LocalDateTime createTime; - /** - * 更新时间 - */ - @ExcelProperty(value = "更新时间") - private LocalDateTime updateTime; - /** - * 状态 - */ - @ExcelProperty(value = "状态") - private Integer status; - /** - * 发布状态 - */ - @ExcelProperty(value = "发布状态") - private Integer publish; - - /** - * 运行参数 - */ - @ExcelProperty(value = "运行参数") - private String runParams; - - /** - * 运行状态 - */ - @ExcelProperty(value = "运行状态") - private String runStatus; - - /** - * 创建部门 - */ - @ExcelProperty(value = "创建部门") - private String createDept; - /** - * 创建用户 - */ - @ExcelProperty(value = "创建用户") - private String createBy; - /** - * 更新用户 - */ - @ExcelProperty(value = "更新用户") - private String updateBy; - -} diff --git a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/mapper/AihumanConfigMapper.java b/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/mapper/AihumanConfigMapper.java deleted file mode 100644 index 3a26ef0b..00000000 --- a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/mapper/AihumanConfigMapper.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.ruoyi.aihuman.mapper; - -import org.apache.ibatis.annotations.Mapper; -import org.ruoyi.aihuman.domain.AihumanConfig; -import org.ruoyi.aihuman.domain.vo.AihumanConfigVo; -import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus; - -/** - * 交互数字人配置Mapper接口 - * - * @author ageerle - * @date Fri Sep 26 22:27:00 GMT+08:00 2025 - */ -@Mapper -public interface AihumanConfigMapper extends BaseMapperPlus { - -} diff --git a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/mapper/AihumanInfoMapper.java b/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/mapper/AihumanInfoMapper.java deleted file mode 100644 index a64d0b13..00000000 --- a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/mapper/AihumanInfoMapper.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.ruoyi.aihuman.mapper; - -import org.apache.ibatis.annotations.Mapper; -import org.ruoyi.aihuman.domain.AihumanInfo; -import org.ruoyi.aihuman.domain.vo.AihumanInfoVo; -import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus; - -/** - * AI人类交互信息Mapper接口 - * - * @author QingYunAI - */ -@Mapper -public interface AihumanInfoMapper extends BaseMapperPlus { - -} diff --git a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/mapper/AihumanRealConfigMapper.java b/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/mapper/AihumanRealConfigMapper.java deleted file mode 100644 index 9ae4768e..00000000 --- a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/mapper/AihumanRealConfigMapper.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.ruoyi.aihuman.mapper; - -import org.apache.ibatis.annotations.Mapper; -import org.ruoyi.aihuman.domain.AihumanRealConfig; -import org.ruoyi.aihuman.domain.vo.AihumanRealConfigVo; -import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus; - -/** - * 真人交互数字人配置Mapper接口 - * - * @author ageerle - * @date Tue Oct 21 11:46:52 GMT+08:00 2025 - */ -@Mapper -public interface AihumanRealConfigMapper extends BaseMapperPlus { - -} diff --git a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/protocol/CompressionBits.java b/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/protocol/CompressionBits.java deleted file mode 100644 index 78794aa4..00000000 --- a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/protocol/CompressionBits.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.ruoyi.aihuman.protocol; - -import lombok.Getter; - -@Getter -public enum CompressionBits { - None_((byte) 0), - Gzip((byte) 0b1), - Custom((byte) 0b11), - ; - - private final byte value; - - CompressionBits(byte b) { - this.value = b; - } - - public static CompressionBits fromValue(int value) { - for (CompressionBits type : CompressionBits.values()) { - if (type.value == value) { - return type; - } - } - throw new IllegalArgumentException("Unknown CompressionBits value: " + value); - } -} diff --git a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/protocol/EventType.java b/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/protocol/EventType.java deleted file mode 100644 index ece69af3..00000000 --- a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/protocol/EventType.java +++ /dev/null @@ -1,90 +0,0 @@ -package org.ruoyi.aihuman.protocol; - -import lombok.Getter; - -@Getter -public enum EventType { - // Default event - NONE(0), - - // Upstream Connection events (1-49) - START_CONNECTION(1), - START_TASK(1), - FINISH_CONNECTION(2), - FINISH_TASK(2), - - // Downstream Connection events (50-99) - CONNECTION_STARTED(50), - TASK_STARTED(50), - CONNECTION_FAILED(51), - TASK_FAILED(51), - CONNECTION_FINISHED(52), - TASK_FINISHED(52), - - // Upstream Session events (100-149) - START_SESSION(100), - CANCEL_SESSION(101), - FINISH_SESSION(102), - - // Downstream Session events (150-199) - SESSION_STARTED(150), - SESSION_CANCELED(151), - SESSION_FINISHED(152), - SESSION_FAILED(153), - USAGE_RESPONSE(154), - CHARGE_DATA(154), - - // Upstream General events (200-249) - TASK_REQUEST(200), - UPDATE_CONFIG(201), - - // Downstream General events (250-299) - AUDIO_MUTED(250), - - // Upstream TTS events (300-349) - SAY_HELLO(300), - - // Downstream TTS events (350-399) - TTS_SENTENCE_START(350), - TTS_SENTENCE_END(351), - TTS_RESPONSE(352), - TTS_ENDED(359), - PODCAST_ROUND_START(360), - PODCAST_ROUND_RESPONSE(361), - PODCAST_ROUND_END(362), - - // Downstream ASR events (450-499) - ASR_INFO(450), - ASR_RESPONSE(451), - ASR_ENDED(459), - - // Upstream Chat events (500-549) - CHAT_TTS_TEXT(500), - - // Downstream Chat events (550-599) - CHAT_RESPONSE(550), - CHAT_ENDED(559), - - // Subtitle events (650-699) - SOURCE_SUBTITLE_START(650), - SOURCE_SUBTITLE_RESPONSE(651), - SOURCE_SUBTITLE_END(652), - TRANSLATION_SUBTITLE_START(653), - TRANSLATION_SUBTITLE_RESPONSE(654), - TRANSLATION_SUBTITLE_END(655); - - private final int value; - - EventType(int value) { - this.value = value; - } - - public static EventType fromValue(int value) { - for (EventType type : EventType.values()) { - if (type.value == value) { - return type; - } - } - throw new IllegalArgumentException("Unknown EventType value: " + value); - } -} \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/protocol/HeaderSizeBits.java b/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/protocol/HeaderSizeBits.java deleted file mode 100644 index 6c09a20d..00000000 --- a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/protocol/HeaderSizeBits.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.ruoyi.aihuman.protocol; - -import lombok.Getter; - -@Getter -public enum HeaderSizeBits { - HeaderSize4((byte) 1), - HeaderSize8((byte) 2), - HeaderSize12((byte) 3), - HeaderSize16((byte) 4), - ; - - private final byte value; - - HeaderSizeBits(byte b) { - this.value = b; - } - - public static HeaderSizeBits fromValue(int value) { - for (HeaderSizeBits type : HeaderSizeBits.values()) { - if (type.value == value) { - return type; - } - } - throw new IllegalArgumentException("Unknown HeaderSizeBits value: " + value); - } -} diff --git a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/protocol/Message.java b/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/protocol/Message.java deleted file mode 100644 index d3605edc..00000000 --- a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/protocol/Message.java +++ /dev/null @@ -1,220 +0,0 @@ -package org.ruoyi.aihuman.protocol; - -import lombok.Data; -import lombok.extern.slf4j.Slf4j; - -import java.io.ByteArrayOutputStream; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.charset.StandardCharsets; - -@Slf4j -@Data -public class Message { - private byte version = VersionBits.Version1.getValue(); - private byte headerSize = HeaderSizeBits.HeaderSize4.getValue(); - private MsgType type; - private MsgTypeFlagBits flag; - private byte serialization = SerializationBits.JSON.getValue(); - private byte compression = 0; - - private EventType event; - private String sessionId; - private String connectId; - private int sequence; - private int errorCode; - - private byte[] payload; - - public Message(MsgType type, MsgTypeFlagBits flag) { - this.type = type; - this.flag = flag; - } - - public static Message unmarshal(byte[] data) throws Exception { - ByteBuffer buffer = ByteBuffer.wrap(data); - - byte type_and_flag = data[1]; - MsgType type = MsgType.fromValue((type_and_flag >> 4) & 0x0F); - MsgTypeFlagBits flag = MsgTypeFlagBits.fromValue(type_and_flag & 0x0F); - - // Read version and header size - int versionAndHeaderSize = buffer.get(); - VersionBits version = VersionBits.fromValue((versionAndHeaderSize >> 4) & 0x0F); - HeaderSizeBits headerSize = HeaderSizeBits.fromValue(versionAndHeaderSize & 0x0F); - - // Skip second byte - buffer.get(); - - // Read serialization and compression method - int serializationCompression = buffer.get(); - SerializationBits serialization = SerializationBits.fromValue((serializationCompression >> 4) & 0x0F); - CompressionBits compression = CompressionBits.fromValue(serializationCompression & 0x0F); - - // Skip padding bytes - int headerSizeInt = 4 * (int) headerSize.getValue(); - int paddingSize = headerSizeInt - 3; - while (paddingSize > 0) { - buffer.get(); - paddingSize -= 1; - } - - Message message = new Message(type, flag); - message.setVersion(version.getValue()); - message.setHeaderSize(headerSize.getValue()); - message.setSerialization(serialization.getValue()); - message.setCompression(compression.getValue()); - - // Read sequence if present - if (flag == MsgTypeFlagBits.POSITIVE_SEQ || flag == MsgTypeFlagBits.NEGATIVE_SEQ) { - // Read 4 bytes from ByteBuffer and parse as int (big-endian) - byte[] sequeueBytes = new byte[4]; - if (buffer.remaining() >= 4) { - buffer.get(sequeueBytes); // Read 4 bytes into array - ByteBuffer wrapper = ByteBuffer.wrap(sequeueBytes); - wrapper.order(ByteOrder.BIG_ENDIAN); // Set big-endian order - message.setSequence(wrapper.getInt()); - } - } - - // Read event if present - if (flag == MsgTypeFlagBits.WITH_EVENT) { - // Read 4 bytes from ByteBuffer and parse as int (big-endian) - byte[] eventBytes = new byte[4]; - if (buffer.remaining() >= 4) { - buffer.get(eventBytes); // Read 4 bytes into array - ByteBuffer wrapper = ByteBuffer.wrap(eventBytes); - wrapper.order(ByteOrder.BIG_ENDIAN); // Set big-endian order - message.setEvent(EventType.fromValue(wrapper.getInt())); - } - - if (type != MsgType.ERROR && !(message.event == EventType.START_CONNECTION - || message.event == EventType.FINISH_CONNECTION || - message.event == EventType.CONNECTION_STARTED - || message.event == EventType.CONNECTION_FAILED || - message.event == EventType.CONNECTION_FINISHED)) { - // Read sessionId if present - int sessionIdLength = buffer.getInt(); - if (sessionIdLength > 0) { - byte[] sessionIdBytes = new byte[sessionIdLength]; - buffer.get(sessionIdBytes); - message.setSessionId(new String(sessionIdBytes, StandardCharsets.UTF_8)); - } - } - - if (message.event == EventType.CONNECTION_STARTED || message.event == EventType.CONNECTION_FAILED - || message.event == EventType.CONNECTION_FINISHED) { - // Read connectId if present - int connectIdLength = buffer.getInt(); - if (connectIdLength > 0) { - byte[] connectIdBytes = new byte[connectIdLength]; - buffer.get(connectIdBytes); - message.setConnectId(new String(connectIdBytes, StandardCharsets.UTF_8)); - } - } - } - - // Read errorCode if present - if (type == MsgType.ERROR) { - // Read 4 bytes from ByteBuffer and parse as int (big-endian) - byte[] errorCodeBytes = new byte[4]; - if (buffer.remaining() >= 4) { - buffer.get(errorCodeBytes); // Read 4 bytes into array - ByteBuffer wrapper = ByteBuffer.wrap(errorCodeBytes); - wrapper.order(ByteOrder.BIG_ENDIAN); // Set big-endian order - message.setErrorCode(wrapper.getInt()); - } - } - - // Read remaining bytes as payload - if (buffer.remaining() > 0) { - // 4 bytes length - int payloadLength = buffer.getInt(); - if (payloadLength > 0) { - byte[] payloadBytes = new byte[payloadLength]; - buffer.get(payloadBytes); - message.setPayload(payloadBytes); - } - } - - return message; - } - - public byte[] marshal() throws Exception { - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - - // Write header - buffer.write((version & 0x0F) << 4 | (headerSize & 0x0F)); - buffer.write((type.getValue() & 0x0F) << 4 | (flag.getValue() & 0x0F)); - buffer.write((serialization & 0x0F) << 4 | (compression & 0x0F)); - - int headerSizeInt = 4 * (int) headerSize; - int padding = headerSizeInt - buffer.size(); - while (padding > 0) { - buffer.write(0); - padding -= 1; - } - - // Write event if present - if (event != null) { - byte[] eventBytes = ByteBuffer.allocate(4).putInt(event.getValue()).array(); - buffer.write(eventBytes); - } - - // Write sessionId if present - if (sessionId != null) { - byte[] sessionIdBytes = sessionId.getBytes(StandardCharsets.UTF_8); - buffer.write(ByteBuffer.allocate(4).putInt(sessionIdBytes.length).array()); - buffer.write(sessionIdBytes); - } - - // Write connectId if present - if (connectId != null) { - byte[] connectIdBytes = connectId.getBytes(StandardCharsets.UTF_8); - buffer.write(ByteBuffer.allocate(4).putInt(connectIdBytes.length).array()); - buffer.write(connectIdBytes); - } - - // Write sequence if present - if (sequence != 0) { - buffer.write(ByteBuffer.allocate(4).putInt(sequence).array()); - } - - // Write errorCode if present - if (errorCode != 0) { - buffer.write(ByteBuffer.allocate(4).putInt(errorCode).array()); - } - - // Write payload if present - if (payload != null && payload.length > 0) { - buffer.write(ByteBuffer.allocate(4).putInt(payload.length).array()); - buffer.write(payload); - } - return buffer.toByteArray(); - } - - @Override - public String toString() { - switch (this.type) { - case AUDIO_ONLY_SERVER: - case AUDIO_ONLY_CLIENT: - if (this.flag == MsgTypeFlagBits.POSITIVE_SEQ || this.flag == MsgTypeFlagBits.NEGATIVE_SEQ) { - return String.format("MsgType: %s, EventType: %s, Sequence: %d, PayloadSize: %d", this.type, this.event, this.sequence, - this.payload != null ? this.payload.length : 0); - } - return String.format("MsgType: %s, EventType: %s, PayloadSize: %d", this.type, this.event, - this.payload != null ? this.payload.length : 0); - case ERROR: - return String.format("MsgType: %s, EventType: %s, ErrorCode: %d, Payload: %s", this.type, this.event, this.errorCode, - this.payload != null ? new String(this.payload) : "null"); - default: - if (this.flag == MsgTypeFlagBits.POSITIVE_SEQ || this.flag == MsgTypeFlagBits.NEGATIVE_SEQ) { - return String.format("MsgType: %s, EventType: %s, Sequence: %d, Payload: %s", - this.type, this.event, this.sequence, - this.payload != null ? new String(this.payload) : "null"); - } - return String.format("MsgType: %s, EventType: %s, Payload: %s", this.type, this.event, - this.payload != null ? new String(this.payload) : "null"); - } - } -} \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/protocol/MsgType.java b/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/protocol/MsgType.java deleted file mode 100644 index 965f40e8..00000000 --- a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/protocol/MsgType.java +++ /dev/null @@ -1,29 +0,0 @@ -package org.ruoyi.aihuman.protocol; - -import lombok.Getter; - -@Getter -public enum MsgType { - INVALID((byte) 0), - FULL_CLIENT_REQUEST((byte) 0b1), - AUDIO_ONLY_CLIENT((byte) 0b10), - FULL_SERVER_RESPONSE((byte) 0b1001), - AUDIO_ONLY_SERVER((byte) 0b1011), - FRONT_END_RESULT_SERVER((byte) 0b1100), - ERROR((byte) 0b1111); - - private final byte value; - - MsgType(byte value) { - this.value = value; - } - - public static MsgType fromValue(int value) { - for (MsgType type : MsgType.values()) { - if (type.value == value) { - return type; - } - } - throw new IllegalArgumentException("Unknown MsgType value: " + value); - } -} \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/protocol/MsgTypeFlagBits.java b/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/protocol/MsgTypeFlagBits.java deleted file mode 100644 index 393a24dc..00000000 --- a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/protocol/MsgTypeFlagBits.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.ruoyi.aihuman.protocol; - -import lombok.Getter; - -@Getter -public enum MsgTypeFlagBits { - NO_SEQ((byte) 0), // Non-terminating packet without sequence number - POSITIVE_SEQ((byte) 0b1), // Non-terminating packet with positive sequence number - LAST_NO_SEQ((byte) 0b10), // Terminating packet without sequence number - NEGATIVE_SEQ((byte) 0b11), // Terminating packet with negative sequence number - WITH_EVENT((byte) 0b100); // Packet containing event number - - private final byte value; - - MsgTypeFlagBits(byte value) { - this.value = value; - } - - public static MsgTypeFlagBits fromValue(int value) { - for (MsgTypeFlagBits flag : MsgTypeFlagBits.values()) { - if (flag.value == value) { - return flag; - } - } - throw new IllegalArgumentException("Unknown MsgTypeFlagBits value: " + value); - } -} \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/protocol/SerializationBits.java b/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/protocol/SerializationBits.java deleted file mode 100644 index 01e8f102..00000000 --- a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/protocol/SerializationBits.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.ruoyi.aihuman.protocol; - -import lombok.Getter; - -@Getter -public enum SerializationBits { - Raw((byte) 0), - JSON((byte) 0b1), - Thrift((byte) 0b11), - Custom((byte) 0b1111), - ; - - private final byte value; - - SerializationBits(byte b) { - this.value = b; - } - - public static SerializationBits fromValue(int value) { - for (SerializationBits type : SerializationBits.values()) { - if (type.value == value) { - return type; - } - } - throw new IllegalArgumentException("Unknown SerializationBits value: " + value); - } -} diff --git a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/protocol/SpeechWebSocketClient.java b/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/protocol/SpeechWebSocketClient.java deleted file mode 100644 index c41e57b3..00000000 --- a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/protocol/SpeechWebSocketClient.java +++ /dev/null @@ -1,115 +0,0 @@ -package org.ruoyi.aihuman.protocol; - -import lombok.extern.slf4j.Slf4j; -import org.java_websocket.client.WebSocketClient; -import org.java_websocket.handshake.ServerHandshake; - -import java.net.URI; -import java.nio.ByteBuffer; -import java.util.Map; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.LinkedBlockingQueue; - -@Slf4j -public class SpeechWebSocketClient extends WebSocketClient { - private final BlockingQueue messageQueue = new LinkedBlockingQueue<>(); - - public SpeechWebSocketClient(URI serverUri, Map headers) { - super(serverUri, headers); - } - - @Override - public void onOpen(ServerHandshake handshakedata) { - log.info("WebSocket connection established, Logid: {}", handshakedata.getFieldValue("x-tt-logid")); - } - - @Override - public void onMessage(String message) { - log.warn("Received unexpected text message: {}", message); - } - - @Override - public void onMessage(ByteBuffer bytes) { - try { - Message message = Message.unmarshal(bytes.array()); - messageQueue.put(message); - } catch (Exception e) { - log.error("Failed to parse message", e); - } - } - - @Override - public void onClose(int code, String reason, boolean remote) { - log.info("WebSocket connection closed: code={}, reason={}, remote={}", code, reason, remote); - } - - @Override - public void onError(Exception ex) { - log.error("WebSocket error", ex); - } - - public void sendStartConnection() throws Exception { - Message message = new Message(MsgType.FULL_CLIENT_REQUEST, MsgTypeFlagBits.WITH_EVENT); - message.setEvent(EventType.START_CONNECTION); - message.setPayload("{}".getBytes()); - sendMessage(message); - } - - public void sendFinishConnection() throws Exception { - Message message = new Message(MsgType.FULL_CLIENT_REQUEST, MsgTypeFlagBits.WITH_EVENT); - message.setEvent(EventType.FINISH_CONNECTION); - sendMessage(message); - } - - public void sendStartSession(byte[] payload, String sessionId) throws Exception { - Message message = new Message(MsgType.FULL_CLIENT_REQUEST, MsgTypeFlagBits.WITH_EVENT); - message.setEvent(EventType.START_SESSION); - message.setSessionId(sessionId); - message.setPayload(payload); - sendMessage(message); - } - - public void sendFinishSession(String sessionId) throws Exception { - Message message = new Message(MsgType.FULL_CLIENT_REQUEST, MsgTypeFlagBits.WITH_EVENT); - message.setEvent(EventType.FINISH_SESSION); - message.setSessionId(sessionId); - message.setPayload("{}".getBytes()); - sendMessage(message); - } - - public void sendTaskRequest(byte[] payload, String sessionId) throws Exception { - Message message = new Message(MsgType.FULL_CLIENT_REQUEST, MsgTypeFlagBits.WITH_EVENT); - message.setEvent(EventType.TASK_REQUEST); - message.setSessionId(sessionId); - message.setPayload(payload); - sendMessage(message); - } - - public void sendFullClientMessage(byte[] payload) throws Exception { - Message message = new Message(MsgType.FULL_CLIENT_REQUEST, MsgTypeFlagBits.NO_SEQ); - message.setPayload(payload); - sendMessage(message); - } - - public void sendMessage(Message message) throws Exception { - log.info("Send: {}", message); - send(message.marshal()); - } - - public Message receiveMessage() throws InterruptedException { - Message message = messageQueue.take(); - log.info("Receive: {}", message); - return message; - } - - public Message waitForMessage(MsgType type, EventType event) throws InterruptedException { - while (true) { - Message message = receiveMessage(); - if (message.getType() == type && message.getEvent() == event) { - return message; - } else { - throw new RuntimeException("Unexpected message: " + message); - } - } - } -} \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/protocol/VersionBits.java b/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/protocol/VersionBits.java deleted file mode 100644 index 6f4a8174..00000000 --- a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/protocol/VersionBits.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.ruoyi.aihuman.protocol; - -import lombok.Getter; - -@Getter -public enum VersionBits { - Version1((byte) 1), - Version2((byte) 2), - Version3((byte) 3), - Version4((byte) 4), - ; - - private final byte value; - - VersionBits(byte b) { - this.value = b; - } - - public static VersionBits fromValue(int value) { - for (VersionBits type : VersionBits.values()) { - if (type.value == value) { - return type; - } - } - throw new IllegalArgumentException("Unknown VersionBits value: " + value); - } -} diff --git a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/service/AihumanConfigService.java b/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/service/AihumanConfigService.java deleted file mode 100644 index b70367cb..00000000 --- a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/service/AihumanConfigService.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.ruoyi.aihuman.service; - -import org.ruoyi.aihuman.domain.bo.AihumanConfigBo; -import org.ruoyi.aihuman.domain.vo.AihumanConfigVo; -import org.ruoyi.common.mybatis.core.page.PageQuery; -import org.ruoyi.common.mybatis.core.page.TableDataInfo; - -import java.util.Collection; -import java.util.List; - -/** - * 交互数字人配置Service接口 - * - * @author ageerle - * @date Fri Sep 26 22:27:00 GMT+08:00 2025 - */ -public interface AihumanConfigService { - - /** - * 查询交互数字人配置 - */ - AihumanConfigVo queryById(Integer id); - - /** - * 查询交互数字人配置列表 - */ - TableDataInfo queryPageList(AihumanConfigBo bo, PageQuery pageQuery); - - /** - * 查询交互数字人配置列表 - */ - List queryList(AihumanConfigBo bo); - - /** - * 新增交互数字人配置 - */ - Boolean insertByBo(AihumanConfigBo bo); - - /** - * 修改交互数字人配置 - */ - Boolean updateByBo(AihumanConfigBo bo); - - /** - * 校验并批量删除交互数字人配置信息 - */ - Boolean deleteWithValidByIds(Collection ids, Boolean isValid); -} diff --git a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/service/AihumanRealConfigService.java b/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/service/AihumanRealConfigService.java deleted file mode 100644 index 56398190..00000000 --- a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/service/AihumanRealConfigService.java +++ /dev/null @@ -1,56 +0,0 @@ -package org.ruoyi.aihuman.service; - -import org.ruoyi.aihuman.domain.bo.AihumanRealConfigBo; -import org.ruoyi.aihuman.domain.vo.AihumanRealConfigVo; -import org.ruoyi.common.mybatis.core.page.PageQuery; -import org.ruoyi.common.mybatis.core.page.TableDataInfo; - -import java.util.Collection; -import java.util.List; - -/** - * 真人交互数字人配置Service接口 - * - * @author ageerle - * @date Tue Oct 21 11:46:52 GMT+08:00 2025 - */ -public interface AihumanRealConfigService { - - /** - * 查询真人交互数字人配置 - */ - AihumanRealConfigVo queryById(Integer id); - - /** - * 查询真人交互数字人配置列表 - */ - TableDataInfo queryPageList(AihumanRealConfigBo bo, PageQuery pageQuery); - - /** - * 查询真人交互数字人配置列表 - */ - List queryList(AihumanRealConfigBo bo); - - /** - * 新增真人交互数字人配置 - */ - Boolean insertByBo(AihumanRealConfigBo bo); - - /** - * 修改真人交互数字人配置 - */ - Boolean updateByBo(AihumanRealConfigBo bo); - - /** - * 执行真人交互数字人配置 - */ - Boolean runByBo(AihumanRealConfigBo bo); - - /** - * 校验并批量删除真人交互数字人配置信息 - */ - Boolean deleteWithValidByIds(Collection ids, Boolean isValid); - - // 在AihumanRealConfigService接口中添加 - Boolean stopByBo(AihumanRealConfigBo bo); -} diff --git a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/service/AihumanVolcengineService.java b/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/service/AihumanVolcengineService.java deleted file mode 100644 index 6c99f013..00000000 --- a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/service/AihumanVolcengineService.java +++ /dev/null @@ -1,4 +0,0 @@ -package org.ruoyi.aihuman.service; - -public interface AihumanVolcengineService { -} diff --git a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/service/IAihumanInfoService.java b/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/service/IAihumanInfoService.java deleted file mode 100644 index a07001d6..00000000 --- a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/service/IAihumanInfoService.java +++ /dev/null @@ -1,47 +0,0 @@ -package org.ruoyi.aihuman.service; - -import org.ruoyi.aihuman.domain.AihumanInfo; -import org.ruoyi.aihuman.domain.vo.AihumanInfoVo; -import org.ruoyi.common.mybatis.core.page.PageQuery; -import org.ruoyi.common.mybatis.core.page.TableDataInfo; - -import java.util.Collection; -import java.util.List; - -/** - * AI人类交互信息Service接口 - * - * @author QingYunAI - */ -public interface IAihumanInfoService { - - /** - * 查询AI人类交互信息 - */ - AihumanInfoVo queryById(Long id); - - /** - * 查询AI人类交互信息列表 - */ - TableDataInfo queryPageList(AihumanInfo record, PageQuery pageQuery); - - /** - * 查询AI人类交互信息列表 - */ - List queryList(AihumanInfo record); - - /** - * 新增AI人类交互信息 - */ - int insert(AihumanInfo record); - - /** - * 修改AI人类交互信息 - */ - int update(AihumanInfo record); - - /** - * 批量删除AI人类交互信息 - */ - int deleteWithValidByIds(Collection ids, Boolean isValid); -} diff --git a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/service/impl/AihumanConfigServiceImpl.java b/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/service/impl/AihumanConfigServiceImpl.java deleted file mode 100644 index 6031d692..00000000 --- a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/service/impl/AihumanConfigServiceImpl.java +++ /dev/null @@ -1,115 +0,0 @@ -package org.ruoyi.aihuman.service.impl; - -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.baomidou.mybatisplus.core.toolkit.Wrappers; -import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import lombok.RequiredArgsConstructor; -import org.ruoyi.aihuman.domain.AihumanConfig; -import org.ruoyi.aihuman.domain.bo.AihumanConfigBo; -import org.ruoyi.aihuman.domain.vo.AihumanConfigVo; -import org.ruoyi.aihuman.mapper.AihumanConfigMapper; -import org.ruoyi.aihuman.service.AihumanConfigService; -import org.ruoyi.common.core.utils.MapstructUtils; -import org.ruoyi.common.core.utils.StringUtils; -import org.ruoyi.common.mybatis.core.page.PageQuery; -import org.ruoyi.common.mybatis.core.page.TableDataInfo; -import org.springframework.stereotype.Service; - -import java.util.Collection; -import java.util.List; - -/** - * 交互数字人配置Service业务层处理 - * - * @author ageerle - * @date Fri Sep 26 22:27:00 GMT+08:00 2025 - */ -@RequiredArgsConstructor -@Service -public class AihumanConfigServiceImpl implements AihumanConfigService { - - private final AihumanConfigMapper baseMapper; - - /** - * 查询交互数字人配置 - */ - @Override - public AihumanConfigVo queryById(Integer id) { - return baseMapper.selectVoById(id); - } - - /** - * 查询交互数字人配置列表 - */ - @Override - public TableDataInfo queryPageList(AihumanConfigBo bo, PageQuery pageQuery) { - LambdaQueryWrapper lqw = buildQueryWrapper(bo); - Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); - return TableDataInfo.build(result); - } - - /** - * 查询交互数字人配置列表 - */ - @Override - public List queryList(AihumanConfigBo bo) { - LambdaQueryWrapper lqw = buildQueryWrapper(bo); - return baseMapper.selectVoList(lqw); - } - - private LambdaQueryWrapper buildQueryWrapper(AihumanConfigBo bo) { - LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); - lqw.eq(StringUtils.isNotBlank(bo.getName()), AihumanConfig::getName, bo.getName()); - lqw.eq(StringUtils.isNotBlank(bo.getModelName()), AihumanConfig::getModelName, bo.getModelName()); - lqw.eq(StringUtils.isNotBlank(bo.getModelPath()), AihumanConfig::getModelPath, bo.getModelPath()); - lqw.eq(StringUtils.isNotBlank(bo.getModelParams()), AihumanConfig::getModelParams, bo.getModelParams()); - lqw.eq(StringUtils.isNotBlank(bo.getAgentParams()), AihumanConfig::getAgentParams, bo.getAgentParams()); - lqw.eq(bo.getCreateTime() != null, AihumanConfig::getCreateTime, bo.getCreateTime()); - lqw.eq(bo.getUpdateTime() != null, AihumanConfig::getUpdateTime, bo.getUpdateTime()); - lqw.eq(bo.getStatus() != null, AihumanConfig::getStatus, bo.getStatus()); - lqw.eq(bo.getPublish() != null, AihumanConfig::getPublish, bo.getPublish()); - return lqw; - } - - /** - * 新增交互数字人配置 - */ - @Override - public Boolean insertByBo(AihumanConfigBo bo) { - AihumanConfig add = MapstructUtils.convert(bo, AihumanConfig.class); - validEntityBeforeSave(add); - boolean flag = baseMapper.insert(add) > 0; - if (flag) { - bo.setId(add.getId()); - } - return flag; - } - - /** - * 修改交互数字人配置 - */ - @Override - public Boolean updateByBo(AihumanConfigBo bo) { - AihumanConfig update = MapstructUtils.convert(bo, AihumanConfig.class); - validEntityBeforeSave(update); - return baseMapper.updateById(update) > 0; - } - - /** - * 保存前的数据校验 - */ - private void validEntityBeforeSave(AihumanConfig entity) { - //TODO 做一些数据校验,如唯一约束 - } - - /** - * 批量删除交互数字人配置 - */ - @Override - public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { - if (isValid) { - //TODO 做一些业务上的校验,判断是否需要校验 - } - return baseMapper.deleteBatchIds(ids) > 0; - } -} diff --git a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/service/impl/AihumanInfoServiceImpl.java b/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/service/impl/AihumanInfoServiceImpl.java deleted file mode 100644 index dd5e8a9c..00000000 --- a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/service/impl/AihumanInfoServiceImpl.java +++ /dev/null @@ -1,96 +0,0 @@ -package org.ruoyi.aihuman.service.impl; - -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.baomidou.mybatisplus.core.toolkit.Wrappers; -import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import lombok.RequiredArgsConstructor; -import org.ruoyi.aihuman.domain.AihumanInfo; -import org.ruoyi.aihuman.domain.vo.AihumanInfoVo; -import org.ruoyi.aihuman.mapper.AihumanInfoMapper; -import org.ruoyi.aihuman.service.IAihumanInfoService; -import org.ruoyi.common.core.utils.StringUtils; -import org.ruoyi.common.mybatis.core.page.PageQuery; -import org.ruoyi.common.mybatis.core.page.TableDataInfo; -import org.springframework.stereotype.Service; - -import java.util.Collection; -import java.util.List; - -/** - * AI人类交互信息Service业务层处理 - * - * @author QingYunAI - */ -@RequiredArgsConstructor -@Service -public class AihumanInfoServiceImpl implements IAihumanInfoService { - - private final AihumanInfoMapper baseMapper; - - /** - * 查询AI人类交互信息 - */ - @Override - public AihumanInfoVo queryById(Long id) { - return baseMapper.selectVoById(id); - } - - /** - * 查询AI人类交互信息列表 - */ - @Override - public TableDataInfo queryPageList(AihumanInfo record, PageQuery pageQuery) { - LambdaQueryWrapper lqw = buildQueryWrapper(record); - Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); - return TableDataInfo.build(result); - } - - /** - * 查询AI人类交互信息列表 - */ - @Override - public List queryList(AihumanInfo record) { - LambdaQueryWrapper lqw = buildQueryWrapper(record); - return baseMapper.selectVoList(lqw); - } - - /** - * 构建查询条件 - */ - private LambdaQueryWrapper buildQueryWrapper(AihumanInfo record) { - LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); - lqw.eq(record.getId() != null, AihumanInfo::getId, record.getId()); - lqw.like(StringUtils.isNotBlank(record.getName()), AihumanInfo::getName, record.getName()); - lqw.like(StringUtils.isNotBlank(record.getContent()), AihumanInfo::getContent, record.getContent()); - lqw.orderByDesc(AihumanInfo::getCreateTime); - return lqw; - } - - /** - * 新增AI人类交互信息 - */ - @Override - public int insert(AihumanInfo record) { - return baseMapper.insert(record); - } - - /** - * 修改AI人类交互信息 - */ - @Override - public int update(AihumanInfo record) { - return baseMapper.updateById(record); - } - - /** - * 批量删除AI人类交互信息 - */ - @Override - public int deleteWithValidByIds(Collection ids, Boolean isValid) { - if (isValid) { - // 如果需要逻辑删除,MyBatis-Plus会自动处理 - // 这里的@TableLogic注解已经在实体类中配置 - } - return baseMapper.deleteBatchIds(ids); - } -} diff --git a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/service/impl/AihumanRealConfigServiceImpl.java b/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/service/impl/AihumanRealConfigServiceImpl.java deleted file mode 100644 index 2b162e1c..00000000 --- a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/service/impl/AihumanRealConfigServiceImpl.java +++ /dev/null @@ -1,534 +0,0 @@ -package org.ruoyi.aihuman.service.impl; - -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.baomidou.mybatisplus.core.toolkit.Wrappers; -import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import com.sun.jna.Library; -import com.sun.jna.Native; -import com.sun.jna.Pointer; -import com.sun.jna.platform.win32.WinNT; -import jakarta.annotation.PreDestroy; -import lombok.RequiredArgsConstructor; -import org.ruoyi.aihuman.domain.AihumanRealConfig; -import org.ruoyi.aihuman.domain.bo.AihumanRealConfigBo; -import org.ruoyi.aihuman.domain.vo.AihumanRealConfigVo; -import org.ruoyi.aihuman.mapper.AihumanRealConfigMapper; -import org.ruoyi.aihuman.service.AihumanRealConfigService; -import org.ruoyi.common.core.utils.MapstructUtils; -import org.ruoyi.common.core.utils.StringUtils; -import org.ruoyi.common.mybatis.core.page.PageQuery; -import org.ruoyi.common.mybatis.core.page.TableDataInfo; -import org.ruoyi.common.redis.utils.RedisUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Service; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.lang.reflect.Field; -import java.util.Collection; -import java.util.List; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; - -/** - * 真人交互数字人配置Service业务层处理 - * - * @author ageerle - * @date Tue Oct 21 11:46:52 GMT+08:00 2025 - */ -@RequiredArgsConstructor -@Service -public class AihumanRealConfigServiceImpl implements AihumanRealConfigService { - - private static final Logger log = LoggerFactory.getLogger(AihumanRealConfigServiceImpl.class); - private final AihumanRealConfigMapper baseMapper; - // 存储当前运行的进程,用于停止操作 - private volatile Process runningProcess = null; - - /** - * 查询真人交互数字人配置 - */ - @Override - public AihumanRealConfigVo queryById(Integer id) { - return baseMapper.selectVoById(id); - } - - /** - * 查询真人交互数字人配置列表 - */ - @Override - public TableDataInfo queryPageList(AihumanRealConfigBo bo, PageQuery pageQuery) { - LambdaQueryWrapper lqw = buildQueryWrapper(bo); - Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); - return TableDataInfo.build(result); - } - - /** - * 查询真人交互数字人配置列表 - */ - @Override - public List queryList(AihumanRealConfigBo bo) { - LambdaQueryWrapper lqw = buildQueryWrapper(bo); - return baseMapper.selectVoList(lqw); - } - - private LambdaQueryWrapper buildQueryWrapper(AihumanRealConfigBo bo) { - LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); - lqw.like(StringUtils.isNotBlank(bo.getName()), AihumanRealConfig::getName, bo.getName()); - lqw.like(StringUtils.isNotBlank(bo.getAvatars()), AihumanRealConfig::getAvatars, bo.getAvatars()); - lqw.like(StringUtils.isNotBlank(bo.getModels()), AihumanRealConfig::getModels, bo.getModels()); - lqw.eq(StringUtils.isNotBlank(bo.getAvatarsParams()), AihumanRealConfig::getAvatarsParams, bo.getAvatarsParams()); - lqw.eq(StringUtils.isNotBlank(bo.getModelsParams()), AihumanRealConfig::getModelsParams, bo.getModelsParams()); - lqw.eq(StringUtils.isNotBlank(bo.getAgentParams()), AihumanRealConfig::getAgentParams, bo.getAgentParams()); - lqw.eq(bo.getCreateTime() != null, AihumanRealConfig::getCreateTime, bo.getCreateTime()); - lqw.eq(bo.getUpdateTime() != null, AihumanRealConfig::getUpdateTime, bo.getUpdateTime()); - lqw.eq(bo.getStatus() != null, AihumanRealConfig::getStatus, bo.getStatus()); - lqw.eq(bo.getPublish() != null, AihumanRealConfig::getPublish, bo.getPublish()); - lqw.eq(StringUtils.isNotBlank(bo.getRunParams()), AihumanRealConfig::getRunParams, bo.getRunParams()); - // 添加runStatus字段的查询条件 - lqw.eq(StringUtils.isNotBlank(bo.getRunStatus()), AihumanRealConfig::getRunStatus, bo.getRunStatus()); - lqw.eq(StringUtils.isNotBlank(bo.getCreateDept()), AihumanRealConfig::getCreateDept, bo.getCreateDept()); - lqw.eq(StringUtils.isNotBlank(bo.getCreateBy()), AihumanRealConfig::getCreateBy, bo.getCreateBy()); - lqw.eq(StringUtils.isNotBlank(bo.getUpdateBy()), AihumanRealConfig::getUpdateBy, bo.getUpdateBy()); - return lqw; - } - - /** - * 新增真人交互数字人配置 - */ - @Override - public Boolean insertByBo(AihumanRealConfigBo bo) { - AihumanRealConfig add = MapstructUtils.convert(bo, AihumanRealConfig.class); - validEntityBeforeSave(add); - boolean flag = baseMapper.insert(add) > 0; - if (flag) { - bo.setId(add.getId()); - } - return flag; - } - - /** - * 修改真人交互数字人配置 - */ - @Override - public Boolean updateByBo(AihumanRealConfigBo bo) { - AihumanRealConfig update = MapstructUtils.convert(bo, AihumanRealConfig.class); - validEntityBeforeSave(update); - return baseMapper.updateById(update) > 0; - } - - /** - * 保存前的数据校验 - */ - private void validEntityBeforeSave(AihumanRealConfig entity) { - //TODO 做一些数据校验,如唯一约束 - } - - /** - * 批量删除真人交互数字人配置 - */ - @Override - public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { - if (isValid) { - //TODO 做一些业务上的校验,判断是否需要校验 - } - return baseMapper.deleteBatchIds(ids) > 0; - } - - /** - * 执行真人交互数字人配置 - * 通过主键获取数据库记录,然后从run_params字段读取命令并执行 - */ - @Override - public Boolean runByBo(AihumanRealConfigBo bo) { - try { - // 1. 通过主键获取数据库记录 - Integer id = bo.getId(); - if (id == null) { - log.error("执行命令失败:主键ID为空"); - throw new RuntimeException("执行命令失败:主键ID为空"); - } - - // 检查是否已经有对应的进程在运行 - String redisKey = "aihuman:process:" + id; - String existingPid = RedisUtils.getCacheObject(redisKey); - if (StringUtils.isNotEmpty(existingPid) && isProcessRunning(existingPid)) { - log.warn("ID为{}的配置已有进程在运行,进程ID: {}", id, existingPid); - // 刷新run_status状态为运行中 - AihumanRealConfig updateStatus = new AihumanRealConfig(); - updateStatus.setId(id); - updateStatus.setRunStatus("1"); // 1表示运行中 - baseMapper.updateById(updateStatus); - return true; - } - - // 查询数据库记录 - AihumanRealConfig config = baseMapper.selectById(id); - if (config == null) { - log.error("执行命令失败:未找到ID为{}的配置记录", id); - throw new RuntimeException("执行命令失败:未找到对应的配置记录"); - } - - // 2. 从记录中获取run_params字段 - String runParams = config.getRunParams(); - if (StringUtils.isBlank(runParams)) { - log.error("执行命令失败:ID为{}的记录中run_params字段为空", id); - throw new RuntimeException("执行命令失败:run_params字段为空"); - } - - // 3. 解析并执行命令 - // 将多行命令合并为一个命令字符串 - String[] commands = runParams.split("\\r?\\n"); - if (commands.length == 0) { - log.error("执行命令失败:runParams中没有有效的命令"); - throw new RuntimeException("执行命令失败:runParams中没有有效的命令"); - } - - // 将所有命令合并到一个命令字符串中,使用&&连接,确保在同一个进程中执行 - StringBuilder mergedCmd = new StringBuilder(); - for (int i = 0; i < commands.length; i++) { - String command = commands[i].trim(); - if (command.isEmpty()) { - continue; - } - - if (mergedCmd.length() > 0) { - mergedCmd.append(" && "); - } - - mergedCmd.append(command); - } - - String cmd = "cmd.exe /c " + mergedCmd.toString(); - log.info("准备执行合并命令:{}", cmd); - - // 更新数据库中的运行状态为运行中 - AihumanRealConfig updateStatus = new AihumanRealConfig(); - updateStatus.setId(id); - updateStatus.setRunStatus("1"); // 1表示运行中 - baseMapper.updateById(updateStatus); - - // 使用线程池执行命令并监听输出 - ExecutorService executor = Executors.newSingleThreadExecutor(); - executor.submit(() -> { - try { - Process process = Runtime.getRuntime().exec(cmd); - // 保存进程引用,用于后续停止操作 - runningProcess = process; - - // 获取进程ID并保存到Redis - String pid = getProcessId(process); - if (!"unknown".equals(pid)) { - RedisUtils.setCacheObject(redisKey, pid); - log.info("保存进程ID到Redis:key={}, pid={}", redisKey, pid); - } - - // 读取标准输出 - new Thread(() -> { - try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) { - String line; - while ((line = reader.readLine()) != null) { - log.info("[LiveTalking] {}", line); - } - } catch (IOException e) { - log.error("读取命令输出失败", e); - } - }).start(); - - // 读取debug输出 - new Thread(() -> { - try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getErrorStream()))) { - String line; - while ((line = reader.readLine()) != null) { - log.debug("[LiveTalking DEBUG] {}", line); - } - } catch (IOException e) { - log.error("读取命令debug输出失败", e); - } - }).start(); - - // 等待进程结束 - int exitCode = process.waitFor(); - log.info("LiveTalking进程结束,退出码: {}", exitCode); - - // 进程结束后更新数据库状态为已停止 - AihumanRealConfig endStatus = new AihumanRealConfig(); - endStatus.setId(id); - endStatus.setRunStatus("0"); // 0表示已停止 - baseMapper.updateById(endStatus); - - // 进程结束后从Redis中删除进程ID - RedisUtils.deleteObject(redisKey); - log.info("从Redis中删除进程ID:key={}", redisKey); - - // 进程结束后清空引用 - runningProcess = null; - } catch (Exception e) { - log.error("执行命令失败", e); - // 发生异常时更新数据库状态为失败 - try { - AihumanRealConfig errorStatus = new AihumanRealConfig(); - errorStatus.setId(id); - errorStatus.setRunStatus("2"); // 2表示启动失败 - baseMapper.updateById(errorStatus); - } catch (Exception ex) { - log.error("更新状态失败", ex); - } - // 发生异常时从Redis中删除进程ID - RedisUtils.deleteObject(redisKey); - // 发生异常时清空引用 - runningProcess = null; - } - }); - - executor.shutdown(); - return true; - } catch (Exception e) { - log.error("执行命令过程中发生异常", e); - return false; - } - } - - /** - * 检查进程是否正在运行 - * - * @param pid 进程ID - * @return 是否正在运行 - */ - private boolean isProcessRunning(String pid) { - if (StringUtils.isEmpty(pid) || "unknown".equals(pid)) { - return false; - } - - try { - boolean isWindows = System.getProperty("os.name").toLowerCase().contains("win"); - ProcessBuilder processBuilder; - - if (isWindows) { - processBuilder = new ProcessBuilder("tasklist", "/FI", "PID eq " + pid); - } else { - processBuilder = new ProcessBuilder("ps", "-p", pid); - } - - Process process = processBuilder.start(); - int exitCode = process.waitFor(); - - // 在Windows上,tasklist命令如果找不到进程,退出码也是0,但输出中不会包含PID - if (isWindows) { - try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) { - String line; - while ((line = reader.readLine()) != null) { - if (line.contains(pid)) { - return true; - } - } - } - return false; - } else { - // 在Linux/Mac上,ps命令如果找不到进程,退出码不为0 - return exitCode == 0; - } - } catch (Exception e) { - log.error("检查进程是否运行失败, pid={}", pid, e); - return false; - } - } - - /** - * 停止正在运行的真人交互数字人配置任务 - */ - @Override - public Boolean stopByBo(AihumanRealConfigBo bo) { - try { - Integer id = bo.getId(); - String redisKey = "aihuman:process:" + id; - - // 首先检查Redis中是否有对应的进程ID - String pid = RedisUtils.getCacheObject(redisKey); - if (StringUtils.isNotEmpty(pid)) { - // 如果Redis中有进程ID,先尝试通过进程ID停止进程 - try { - // 根据操作系统类型,使用不同的命令终止进程树 - if (System.getProperty("os.name").toLowerCase().contains("win")) { - // Windows系统使用taskkill命令终止进程树 - log.info("通过Redis中的PID停止进程: taskkill /F /T /PID {}", pid); - Process killProcess = Runtime.getRuntime().exec("taskkill /F /T /PID " + pid); - // 等待kill命令执行完成 - killProcess.waitFor(5, TimeUnit.SECONDS); - } else { - // Linux/Mac系统使用pkill命令终止进程树 - Runtime.getRuntime().exec("pkill -P " + pid); - } - } catch (Exception e) { - log.error("通过Redis中的PID停止进程失败", e); - } - } - - // 然后检查本地runningProcess引用 - if (runningProcess != null && runningProcess.isAlive()) { - log.info("正在停止LiveTalking进程..."); - // 强制销毁进程树,确保完全停止 - destroyProcessTree(runningProcess); - - // 更新数据库中的运行状态为已停止 - AihumanRealConfig updateStatus = new AihumanRealConfig(); - updateStatus.setId(id); - updateStatus.setRunStatus("0"); // 0表示已停止 - baseMapper.updateById(updateStatus); - - runningProcess = null; - log.info("LiveTalking进程已停止"); - } else { - log.warn("没有正在运行的LiveTalking进程"); - // 确保数据库中的状态也是已停止 - AihumanRealConfig updateStatus = new AihumanRealConfig(); - updateStatus.setId(id); - updateStatus.setRunStatus("0"); // 0表示已停止 - baseMapper.updateById(updateStatus); - } - - // 无论如何都从Redis中删除进程ID - RedisUtils.deleteObject(redisKey); - log.info("从Redis中删除进程ID:key={}", redisKey); - - return true; - } catch (Exception e) { - log.error("停止进程时发生异常", e); - // 发生异常时也尝试从Redis中删除进程ID - try { - RedisUtils.deleteObject("aihuman:process:" + bo.getId()); - } catch (Exception ex) { - log.error("从Redis中删除进程ID失败", ex); - } - return false; - } - } - - /** - * 销毁进程及其子进程(进程树) - * - * @param process 要销毁的进程 - */ - private void destroyProcessTree(Process process) { - try { - if (process.isAlive()) { - // 获取进程ID - String pid = getProcessId(process); - log.info("获取到进程ID: {}", pid); - - // 根据操作系统类型,使用不同的命令终止进程树 - if (System.getProperty("os.name").toLowerCase().contains("win")) { - // Windows系统使用taskkill命令终止进程树 - log.info("执行taskkill命令终止进程树: taskkill /F /T /PID {}", pid); - Process killProcess = Runtime.getRuntime().exec("taskkill /F /T /PID " + pid); - // 等待kill命令执行完成 - killProcess.waitFor(5, TimeUnit.SECONDS); - } else { - // Linux/Mac系统使用pkill命令终止进程树 - Runtime.getRuntime().exec("pkill -P " + pid); - process.destroy(); - } - } - } catch (Exception e) { - log.error("销毁进程树时发生异常", e); - // 如果出现异常,尝试使用普通销毁方法 - process.destroy(); - try { - // 强制销毁 - if (process.isAlive()) { - process.destroyForcibly(); - } - } catch (Exception ex) { - log.error("强制销毁进程失败", ex); - } - } - } - - /** - * 获取进程ID - * - * @param process 进程对象 - * @return 进程ID - */ - private String getProcessId(Process process) { - try { - // 不同JVM实现可能有所不同,这里尝试通过反射获取 - if (process.getClass().getName().equals("java.lang.Win32Process") || - process.getClass().getName().equals("java.lang.ProcessImpl")) { - Field f = process.getClass().getDeclaredField("handle"); - f.setAccessible(true); - long handl = f.getLong(process); - Kernel32 kernel = Kernel32.INSTANCE; - WinNT.HANDLE handle = new WinNT.HANDLE(); - handle.setPointer(Pointer.createConstant(handl)); - return String.valueOf(kernel.GetProcessId(handle)); - } else if (process.getClass().getName().equals("java.lang.UNIXProcess")) { - Field f = process.getClass().getDeclaredField("pid"); - f.setAccessible(true); - return String.valueOf(f.getInt(process)); - } - } catch (Exception e) { - log.error("获取进程ID失败", e); - } - - // 如果反射获取失败,尝试通过wmic命令获取 - try { - // 对于Windows系统,可以尝试使用wmic命令获取进程ID - if (System.getProperty("os.name").toLowerCase().contains("win")) { - ProcessHandle.Info info = process.toHandle().info(); - return String.valueOf(process.toHandle().pid()); - } - } catch (Exception e) { - log.error("通过ProcessHandle获取进程ID失败", e); - } - - return "unknown"; - } - - @PreDestroy - public void onDestroy() { - if (runningProcess != null && runningProcess.isAlive()) { - try { - log.info("应用关闭,正在停止数字人进程"); - destroyProcessTree(runningProcess); - - // 查找所有运行状态为运行中的配置,并更新为已停止 - LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); - lqw.eq(AihumanRealConfig::getRunStatus, "1"); - List runningConfigs = baseMapper.selectList(lqw); - for (AihumanRealConfig config : runningConfigs) { - config.setRunStatus("0"); - baseMapper.updateById(config); - - // 从Redis中删除对应的进程ID记录 - String redisKey = "aihuman:process:" + config.getId(); - RedisUtils.deleteObject(redisKey); - log.info("应用关闭,从Redis中删除进程ID:key={}", redisKey); - } - } catch (Exception e) { - log.error("停止数字人进程失败", e); - // 即使发生异常,也尝试清理Redis中的进程ID记录 - try { - LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); - lqw.eq(AihumanRealConfig::getRunStatus, "1"); - List runningConfigs = baseMapper.selectList(lqw); - for (AihumanRealConfig config : runningConfigs) { - RedisUtils.deleteObject("aihuman:process:" + config.getId()); - } - } catch (Exception ex) { - log.error("清理Redis中的进程ID记录失败", ex); - } - } - } - } - - // JNA接口定义,用于Windows系统获取进程ID - interface Kernel32 extends Library { - Kernel32 INSTANCE = (Kernel32) Native.loadLibrary("kernel32", Kernel32.class); - - int GetProcessId(WinNT.HANDLE hProcess); - } -} diff --git a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/service/impl/AihumanVolcengineServiceImpl.java b/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/service/impl/AihumanVolcengineServiceImpl.java deleted file mode 100644 index aa11aabd..00000000 --- a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/service/impl/AihumanVolcengineServiceImpl.java +++ /dev/null @@ -1,4 +0,0 @@ -package org.ruoyi.aihuman.service.impl; - -public class AihumanVolcengineServiceImpl { -} diff --git a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/volcengine/Bidirection.java b/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/volcengine/Bidirection.java deleted file mode 100644 index dc8ef8c9..00000000 --- a/ruoyi-modules/ruoyi-aihuman/src/main/java/org/ruoyi/aihuman/volcengine/Bidirection.java +++ /dev/null @@ -1,160 +0,0 @@ -package org.ruoyi.aihuman.volcengine; - -import com.fasterxml.jackson.databind.ObjectMapper; -import lombok.extern.slf4j.Slf4j; -import org.ruoyi.aihuman.protocol.EventType; -import org.ruoyi.aihuman.protocol.Message; -import org.ruoyi.aihuman.protocol.MsgType; -import org.ruoyi.aihuman.protocol.SpeechWebSocketClient; - -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.net.URI; -import java.nio.file.Files; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; - -@Slf4j -public class Bidirection { - private static final String ENDPOINT = "wss://openspeech.bytedance.com/api/v3/tts/bidirection"; - private static final ObjectMapper objectMapper = new ObjectMapper(); - - /** - * Get resource ID based on voice type - * - * @param voice Voice type string - * @return Corresponding resource ID - */ - public static String voiceToResourceId(String voice) { - // Map different voice types to resource IDs based on actual needs - if (voice.startsWith("S_")) { - return "volc.megatts.default"; - } - return "volc.service_type.10029"; - } - - public static void main(String[] args) throws Exception { - // Configure parameters - String appId = System.getProperty("appId", "1055299334"); - String accessToken = System.getProperty("accessToken", "fOHuq4R4dirMYiOruCU3Ek9q75zV0KVW"); - String resourceId = System.getProperty("resourceId", "seed-tts-2.0"); - String voice = System.getProperty("voice", "zh_female_vv_uranus_bigtts"); - String text = System.getProperty("text", "你好呀!我是AI合成的语音,很高兴认识你。"); - String encoding = System.getProperty("encoding", "mp3"); - - if (appId.isEmpty() || accessToken.isEmpty()) { - throw new IllegalArgumentException("Please set appId and accessToken system properties"); - } - - // Set request headers - Map headers = Map.of( - "X-Api-App-Key", appId, - "X-Api-Access-Key", accessToken, - "X-Api-Resource-Id", resourceId.isEmpty() ? voiceToResourceId(voice) : resourceId, - "X-Api-Connect-Id", UUID.randomUUID().toString()); - - // Create WebSocket client - SpeechWebSocketClient client = new SpeechWebSocketClient(new URI(ENDPOINT), headers); - try { - client.connectBlocking(); - Map request = Map.of( - "user", Map.of("uid", UUID.randomUUID().toString()), - "namespace", "BidirectionalTTS", - "req_params", Map.of( - "speaker", voice, - "audio_params", Map.of( - "format", encoding, - "sample_rate", 24000, - "enable_timestamp", true), - // additions requires a JSON string - "additions", objectMapper.writeValueAsString(Map.of( - "disable_markdown_filter", false)))); - - // Start connection - client.sendStartConnection(); - // Wait for connection started - client.waitForMessage(MsgType.FULL_SERVER_RESPONSE, EventType.CONNECTION_STARTED); - - // Process each sentence - String[] sentences = text.split("。"); - boolean audioReceived = false; - for (int i = 0; i < sentences.length; i++) { - if (sentences[i].trim().isEmpty()) { - continue; - } - - String sessionId = UUID.randomUUID().toString(); - ByteArrayOutputStream audioStream = new ByteArrayOutputStream(); - - // Start session - Map startReq = Map.of( - "user", request.get("user"), - "namespace", request.get("namespace"), - "req_params", request.get("req_params"), - "event", EventType.START_SESSION.getValue()); - client.sendStartSession(objectMapper.writeValueAsBytes(startReq), sessionId); - // Wait for session started - client.waitForMessage(MsgType.FULL_SERVER_RESPONSE, EventType.SESSION_STARTED); - - // Send text - for (char c : sentences[i].toCharArray()) { - // Create new req_params with text - @SuppressWarnings("unchecked") - Map currentReqParams = new HashMap<>( - (Map) request.get("req_params")); - currentReqParams.put("text", String.valueOf(c)); - - // Create current request - Map currentRequest = Map.of( - "user", request.get("user"), - "namespace", request.get("namespace"), - "req_params", currentReqParams, - "event", EventType.TASK_REQUEST.getValue()); - - client.sendTaskRequest(objectMapper.writeValueAsBytes(currentRequest), sessionId); - } - - // End session - client.sendFinishSession(sessionId); - - // Receive response - while (true) { - Message msg = client.receiveMessage(); - switch (msg.getType()) { - case FULL_SERVER_RESPONSE: - break; - case AUDIO_ONLY_SERVER: - if (!audioReceived && audioStream.size() > 0) { - audioReceived = true; - } - if (msg.getPayload() != null) { - audioStream.write(msg.getPayload()); - } - break; - default: - throw new RuntimeException("Unexpected message: " + msg); - } - if (msg.getEvent() == EventType.SESSION_FINISHED) { - break; - } - } - - if (audioStream.size() > 0) { - String fileName = String.format("%s_session_%d.%s", voice, i, encoding); - Files.write(new File(fileName).toPath(), audioStream.toByteArray()); - log.info("Audio saved to file: {}", fileName); - } - } - - if (!audioReceived) { - throw new RuntimeException("No audio data received"); - } - - // End connection - client.sendFinishConnection(); - } finally { - client.closeBlocking(); - } - } -} \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-aihuman/src/main/resources/mapper/AihumanInfoMapper.xml b/ruoyi-modules/ruoyi-aihuman/src/main/resources/mapper/AihumanInfoMapper.xml deleted file mode 100644 index 22bd47aa..00000000 --- a/ruoyi-modules/ruoyi-aihuman/src/main/resources/mapper/AihumanInfoMapper.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-aihuman/src/main/resources/mapper/aihuman/AihumanConfigMapper.xml b/ruoyi-modules/ruoyi-aihuman/src/main/resources/mapper/aihuman/AihumanConfigMapper.xml deleted file mode 100644 index 0cbe9dcb..00000000 --- a/ruoyi-modules/ruoyi-aihuman/src/main/resources/mapper/aihuman/AihumanConfigMapper.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/ruoyi-modules/ruoyi-aihuman/src/main/resources/mapper/aihuman/AihumanRealConfigMapper.xml b/ruoyi-modules/ruoyi-aihuman/src/main/resources/mapper/aihuman/AihumanRealConfigMapper.xml deleted file mode 100644 index 8c7011ca..00000000 --- a/ruoyi-modules/ruoyi-aihuman/src/main/resources/mapper/aihuman/AihumanRealConfigMapper.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - -