feat: 新增minio存储、腾讯网易翻译
This commit is contained in:
@@ -18,4 +18,4 @@ chmod 777 /home/docker/rocketmq/timerwheel/
|
||||
- **打开目录**: 当前文件夹下输入 cmd 回车
|
||||
- **执行命令**: docker-compose up -d
|
||||
- **导入nacos数据库**: [mysql-schema.sql](../mysql-schema.sql)
|
||||
- **导入nacos命名空间数据**: [nacos_config_export_20251126080946.zip](../nacos/nacos_config_export_20251126080946.zip)
|
||||
- **导入nacos命名空间数据**: [nacos_config.zip](../nacos/nacos_config.zip)
|
||||
Binary file not shown.
@@ -11,7 +11,7 @@
|
||||
Target Server Version : 80030 (8.0.30)
|
||||
File Encoding : 65001
|
||||
|
||||
Date: 05/12/2025 13:33:00
|
||||
Date: 12/12/2025 08:54:53
|
||||
*/
|
||||
|
||||
SET NAMES utf8mb4;
|
||||
@@ -37,7 +37,7 @@ CREATE TABLE `ai_api_key` (
|
||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 101622399644673 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'AI API 密钥表' ROW_FORMAT = Dynamic;
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 103155220632065 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'AI API 密钥表' ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of ai_api_key
|
||||
@@ -106,7 +106,7 @@ CREATE TABLE `ai_chat_conversation` (
|
||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||
`tenant_id` bigint NULL DEFAULT NULL COMMENT '租户编号',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 103094306752513 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'AI 聊天对话表' ROW_FORMAT = Dynamic;
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 104976064475137 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'AI 聊天对话表' ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of ai_chat_conversation
|
||||
@@ -138,7 +138,7 @@ CREATE TABLE `ai_chat_message` (
|
||||
`tenant_id` bigint NOT NULL DEFAULT 1 COMMENT '租户编号',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
INDEX `idx_msg_type`(`msg_type` ASC) USING BTREE COMMENT '消息内容类型索引'
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 103085163169795 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'AI 聊天消息表' ROW_FORMAT = Dynamic;
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 104860544949251 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'AI 聊天消息表' ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of ai_chat_message
|
||||
@@ -349,7 +349,7 @@ CREATE TABLE `ai_model` (
|
||||
INDEX `idx_user_id`(`user_id` ASC) USING BTREE,
|
||||
INDEX `idx_public_status`(`public_status` ASC) USING BTREE,
|
||||
INDEX `idx_user_public`(`user_id` ASC, `public_status` ASC) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 100761590051841 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'AI 模型表' ROW_FORMAT = Dynamic;
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 103155279352321 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'AI 模型表' ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of ai_model
|
||||
@@ -372,7 +372,7 @@ CREATE TABLE `ai_model_usage_record` (
|
||||
`tenant_id` bigint NOT NULL DEFAULT 1 COMMENT '租户编号',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE INDEX `uk_user_model`(`user_id` ASC, `model_id` ASC) USING BTREE COMMENT '用户-模型唯一索引'
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 103085163169793 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'AI 公开模型使用记录表' ROW_FORMAT = Dynamic;
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 104860544949249 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'AI 公开模型使用记录表' ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of ai_model_usage_record
|
||||
@@ -451,10 +451,10 @@ INSERT INTO `ai_platform` VALUES (5, 'HunYuan', '混元', 'Tencent (混元)', 'h
|
||||
INSERT INTO `ai_platform` VALUES (6, 'ZhiPu', '智谱', 'Zhipu (智谱)', 'glm-4, glm-3-turbo, glm-4v', 'https://open.bigmodel.cn/dev/api', '请前往智谱 AI 官网查看可用模型列表', 6, 0, '', '2025-11-11 01:19:48', '', '2025-11-11 02:33:25', b'0', 1);
|
||||
INSERT INTO `ai_platform` VALUES (7, 'XingHuo', '星火', 'XingHuo (星火)', 'generalv3.5, generalv3, generalv2.1', 'https://www.xfyun.cn/doc/spark/Web.html', '请前往讯飞星火官网查看可用模型列表', 7, 0, '', '2025-11-11 01:19:48', '', '2025-11-11 02:33:25', b'0', 1);
|
||||
INSERT INTO `ai_platform` VALUES (8, 'DouBao', '豆包', 'DouBao (豆包)', 'doubao-lite-4k, doubao-lite-32k, doubao-pro-4k', 'https://www.volcengine.com/docs/82379', '请前往字节豆包官网查看可用模型列表', 8, 0, '', '2025-11-11 01:19:48', '', '2025-11-11 02:33:25', b'0', 1);
|
||||
INSERT INTO `ai_platform` VALUES (9, 'SiliconFlow', '硅基流动', 'SiliconFlow (硅基流动)', 'Qwen/Qwen2-7B-Instruct, meta-llama/Llama-2-7b-chat-hf, Wan-AI/Wan2.2-T2V-A14B, THUDM/GLM-Z1-9B-0414, Kwai-Kolors/Kolors, deepseek-ai/DeepSeek-R1-0528-Qwen3-8B, DeepSeek-R1-0528-Qwen3-8B, tencent/Hunyuan-MT-7B, deepseek-ai/DeepSeek-R1-Distill-Qwen-7B, DeepSeek-R1-Distill-Qwen-7B, deepseek-ai/DeepSeek-V3.2-Exp', 'https://docs.siliconflow.cn/cn/userguide/capabilities/text-generation', '请前往硅基流动官网查看可用模型列表', 2, 0, '', '2025-11-11 01:19:48', '', '2025-11-12 11:15:26', b'0', 1);
|
||||
INSERT INTO `ai_platform` VALUES (9, 'SiliconFlow', '硅基流动', 'SiliconFlow (硅基流动)', 'Qwen/Qwen2-7B-Instruct, meta-llama/Llama-2-7b-chat-hf, Wan-AI/Wan2.2-T2V-A14B, THUDM/GLM-Z1-9B-0414, Kwai-Kolors/Kolors, deepseek-ai/DeepSeek-R1-0528-Qwen3-8B, DeepSeek-R1-0528-Qwen3-8B, tencent/Hunyuan-MT-7B, deepseek-ai/DeepSeek-R1-Distill-Qwen-7B, DeepSeek-R1-Distill-Qwen-7B, deepseek-ai/DeepSeek-V3.2-Exp, deepseek-ai/DeepSeek-V3.1-Terminus, Qwen/Qwen3-Omni-30B-A3B-Thinking', 'https://docs.siliconflow.cn/cn/userguide/capabilities/text-generation', '请前往硅基流动官网查看可用模型列表', 2, 0, '', '2025-11-11 01:19:48', '', '2025-11-12 11:15:26', b'0', 1);
|
||||
INSERT INTO `ai_platform` VALUES (10, 'MiniMax', 'MiniMax', 'MiniMax', 'abab6.5-chat, abab5.5-chat, abab5-chat', 'https://www.minimaxi.com/document/guides/chat', '请前往 MiniMax 官网查看可用模型列表', 10, 0, '', '2025-11-11 01:19:48', '', '2025-11-11 02:33:25', b'0', 1);
|
||||
INSERT INTO `ai_platform` VALUES (11, 'BaiChuan', '百川智能', 'BaiChuan (百川)', 'Baichuan2-Turbo, Baichuan2-Turbo-192k, Baichuan2-53B', 'https://platform.baichuan-ai.com/docs/api', '请前往百川智能官网查看可用模型列表', 11, 0, '', '2025-11-11 01:19:48', '', '2025-11-11 02:33:25', b'0', 1);
|
||||
INSERT INTO `ai_platform` VALUES (12, 'GiteeAI', 'Gitee AI', 'Gitee AI (魔力方舟)', 'tts-1, tts-1-hd, gpt-4o, gpt-4o-mini', 'https://ai.gitee.com/docs', '请前往 Gitee AI 魔力方舟官网查看可用模型列表', 2, 0, '', '2025-11-11 01:19:48', '', '2025-11-12 11:15:29', b'0', 1);
|
||||
INSERT INTO `ai_platform` VALUES (12, 'GiteeAI', 'Gitee AI', 'Gitee AI (魔力方舟)', 'tts-1, tts-1-hd, gpt-4o, gpt-4o-mini, Kimi-K2-Thinking', 'https://ai.gitee.com/docs', '请前往 Gitee AI 魔力方舟官网查看可用模型列表', 2, 0, '', '2025-11-11 01:19:48', '', '2025-11-12 11:15:29', b'0', 1);
|
||||
INSERT INTO `ai_platform` VALUES (13, 'OpenAI', 'OpenAI', 'OpenAI', 'gpt-4, gpt-4-turbo, gpt-3.5-turbo, gpt-4o', 'https://platform.openai.com/docs/models', '请前往 OpenAI 官网查看可用模型列表', 13, 0, '', '2025-11-11 01:19:48', '', '2025-11-11 02:33:25', b'0', 1);
|
||||
INSERT INTO `ai_platform` VALUES (14, 'AzureOpenAI', 'Azure OpenAI', 'Azure OpenAI', 'gpt-4, gpt-35-turbo, gpt-4-turbo', 'https://learn.microsoft.com/en-us/azure/ai-services/openai/concepts/models', '请前往 Azure OpenAI 官网查看可用模型列表', 14, 0, '', '2025-11-11 01:19:48', '', '2025-11-11 02:33:25', b'0', 1);
|
||||
INSERT INTO `ai_platform` VALUES (15, 'Anthropic', 'Anthropic', 'Anthropic', 'claude-3-opus, claude-3-sonnet, claude-3-haiku', 'https://docs.anthropic.com/claude/docs/models-overview', '请前往 Anthropic 官网查看可用模型列表', 15, 0, '', '2025-11-11 01:19:48', '', '2025-11-11 02:33:25', b'0', 1);
|
||||
@@ -2295,8 +2295,8 @@ CREATE TABLE `def_user` (
|
||||
-- ----------------------------
|
||||
-- Records of def_user
|
||||
-- ----------------------------
|
||||
INSERT INTO `def_user` VALUES (61170828519936, 2, '15147891644', 'HuLa小管家', '', '022', NULL, NULL, '', NULL, b'0', '', '', '1', b'1', '', '2025-08-11 11:11:03.139', '{\"createIp\": \"206.237.119.215\", \"updateIp\": \"120.231.232.41\", \"createIpDetail\": null, \"updateIpDetail\": null}', '2025-12-01 20:30:50', 6, NULL, 'a4d5c225e6709ba025272a31c7e90e0121d5e5ba16695afe0b61370bedb677d0', 'Dawn', '2025-07-07 15:27:02', 1, '2025-03-27 04:23:08', NULL, '2025-07-16 12:26:15', 0, 1);
|
||||
INSERT INTO `def_user` VALUES (61170828519937, 2, '13275346112', 'Dawn', '2439646234@qq.com', 'https://cdn.hulaspark.com/avatar/2439646234/6ec99d37b8ba1296c325d2d36b46a14d.webp', NULL, NULL, '', NULL, b'0', '', '', '1', b'1', '', '2025-08-11 11:11:03.189', '{\"createIp\": \"206.237.119.215\", \"updateIp\": \"116.24.64.57\", \"createIpDetail\": null, \"updateIpDetail\": {\"ip\": \"116.24.64.57\", \"isp\": \"电信\", \"area\": \"\", \"city\": \"深圳\", \"isp_id\": \"\", \"region\": \"广东省\", \"city_id\": \"\", \"country\": \"中国\", \"region_id\": \"\", \"country_id\": \"\"}}', NULL, 0, NULL, 'a4d5c225e6709ba025272a31c7e90e0121d5e5ba16695afe0b61370bedb677d0', 'Dawn', '2025-12-05 00:04:51', 1, '2025-03-27 04:23:08', NULL, '2025-12-05 01:04:45', 0, 1);
|
||||
INSERT INTO `def_user` VALUES (61170828519936, 2, '15147891644', 'HuLa小管家', '', '022', NULL, NULL, '', NULL, b'0', '', '', '1', b'1', '', '2025-08-11 11:11:03.139', '{\"createIp\": \"\", \"updateIp\": \"\", \"createIpDetail\": null, \"updateIpDetail\": null}', '2025-12-01 20:30:50', 6, NULL, 'a4d5c225e6709ba025272a31c7e90e0121d5e5ba16695afe0b61370bedb677d0', 'Dawn', '2025-07-07 15:27:02', 1, '2025-03-27 04:23:08', NULL, '2025-07-16 12:26:15', 0, 1);
|
||||
INSERT INTO `def_user` VALUES (61170828519937, 2, '13275346112', 'Dawn', '2439646234@qq.com', 'https://cdn.hulaspark.com/avatar/2439646234/6ec99d37b8ba1296c325d2d36b46a14d.webp', NULL, NULL, '', NULL, b'0', '', '', '1', b'1', '', '2025-08-11 11:11:03.189', '{\"createIp\": \"206.237.119.215\", \"updateIp\": \"120.231.232.9\", \"createIpDetail\": null, \"updateIpDetail\": {\"ip\": \"120.231.232.9\", \"isp\": \"移动\", \"area\": \"\", \"city\": \"深圳\", \"isp_id\": \"\", \"region\": \"广东省\", \"city_id\": \"\", \"country\": \"中国\", \"region_id\": \"\", \"country_id\": \"\"}}', NULL, 0, NULL, 'a4d5c225e6709ba025272a31c7e90e0121d5e5ba16695afe0b61370bedb677d0', 'Dawn', '2025-12-10 21:24:19', 1, '2025-03-27 04:23:08', 61170828529941, '2025-12-10 21:30:16', 0, 1);
|
||||
INSERT INTO `def_user` VALUES (61170828529941, 1, '24396462341', 'Dawn', '24396462341@qq.com', 'https://cdn.hulaspark.com/avatar/2439646234/6ec99d37b8ba1296c325d2d36b46a14d.webp', NULL, NULL, '', NULL, b'0', '', '', '1', b'1', '', '2025-08-11 11:11:03.189', '{\"createIp\": \"206.237.119.215\", \"updateIp\": \"116.24.64.57\", \"createIpDetail\": null, \"updateIpDetail\": {\"ip\": \"116.24.64.57\", \"isp\": \"电信\", \"area\": \"\", \"city\": \"深圳\", \"isp_id\": \"\", \"region\": \"广东省\", \"city_id\": \"\", \"country\": \"中国\", \"region_id\": \"\", \"country_id\": \"\"}}', NULL, 0, NULL, 'a4d5c225e6709ba025272a31c7e90e0121d5e5ba16695afe0b61370bedb677d0', 'Dawn', '2025-12-04 16:17:54', 1, '2025-03-27 04:23:08', NULL, '2025-12-04 17:19:56', 0, 1);
|
||||
|
||||
-- ----------------------------
|
||||
@@ -2373,7 +2373,7 @@ CREATE TABLE `extend_interface_log` (
|
||||
-- Records of extend_interface_log
|
||||
-- ----------------------------
|
||||
INSERT INTO `extend_interface_log` VALUES (66567882983426, 244439130119864323, '阿里短信', 0, 1, '2025-08-26 16:37:01', '2025-08-26 16:37:00', NULL, '2025-08-26 16:37:00', NULL, 0, 0);
|
||||
INSERT INTO `extend_interface_log` VALUES (655249535051914248, 244881451621810192, '腾讯邮件', 1667, 65, '2025-12-05 13:14:22', '2025-07-16 18:41:01', NULL, '2025-07-16 18:41:01', NULL, 0, 0);
|
||||
INSERT INTO `extend_interface_log` VALUES (655249535051914248, 244881451621810192, '腾讯邮件', 1783, 67, '2025-12-11 08:29:55', '2025-07-16 18:41:01', NULL, '2025-07-16 18:41:01', NULL, 0, 0);
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for extend_interface_logging
|
||||
@@ -2587,7 +2587,7 @@ CREATE TABLE `worker_node` (
|
||||
`created` timestamp NULL DEFAULT NULL COMMENT '创建时间',
|
||||
`is_del` tinyint(1) NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 1061 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = 'DB;WorkerID Assigner for UID Generator' ROW_FORMAT = Dynamic;
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 1083 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = 'DB;WorkerID Assigner for UID Generator' ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of worker_node
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
Target Server Version : 80030 (8.0.30)
|
||||
File Encoding : 65001
|
||||
|
||||
Date: 05/12/2025 13:33:06
|
||||
Date: 12/12/2025 08:54:58
|
||||
*/
|
||||
|
||||
SET NAMES utf8mb4;
|
||||
@@ -66,9 +66,9 @@ INSERT INTO `base_config` VALUES (107, 'youdao_config', '{\"title\":\"有道AppS
|
||||
INSERT INTO `base_config` VALUES (108, 'tencent_config', '{\"title\":\"腾讯ApiKey\",\"componentType\":\"text\",\"value\":\"\",\"configKey\":\"tencentApiKey\",\"type\":\"tencent_config\"}', 'tencentApiKey', '50i2McgXHpY8e6T3qXMKEzsk1w45zoa', 0, '2025-12-04 07:23:36.000', '2025-12-05 05:28:56.749', 3, NULL, 0);
|
||||
INSERT INTO `base_config` VALUES (109, 'tencent_config', '{\"title\":\"腾讯SecretId\",\"componentType\":\"text\",\"value\":\"\",\"configKey\":\"tencentSecretId\",\"type\":\"tencent_config\"}', 'tencentSecretId', 'AKI2z0EVlw1zsfHnS2H4nQs8KU2yX0JVV', 0, '2025-12-04 07:23:36.000', '2025-12-05 05:28:54.258', 3, NULL, 0);
|
||||
INSERT INTO `base_config` VALUES (110, 'tencent_config', '{\"title\":\"腾讯MapKey\",\"componentType\":\"text\",\"value\":\"\",\"configKey\":\"tencentMapKey\",\"type\":\"tencent_config\"}', 'tencentMapKey', 'PF1-34XCC-J6N2D-A3Q3-5K4F4G', 0, '2025-12-04 07:23:36.000', '2025-12-05 05:28:51.944', 3, NULL, 0);
|
||||
INSERT INTO `base_config` VALUES (111, 'ice_server_config', '{\"title\":\"ICE Server URLs(JSON数组或逗号分隔)\",\"componentType\":\"text\",\"value\":\"[]\",\"configKey\":\"iceServerUrls\",\"type\":\"ice_server_config\"}', 'iceServerUrls', '[]', 0, '2025-12-04 07:23:36.000', '2025-12-04 07:23:36.000', 3, NULL, 0);
|
||||
INSERT INTO `base_config` VALUES (112, 'ice_server_config', '{\"title\":\"ICE Server Username\",\"componentType\":\"text\",\"value\":\"\",\"configKey\":\"iceServerUsername\",\"type\":\"ice_server_config\"}', 'iceServerUsername', '', 0, '2025-12-04 07:23:36.000', '2025-12-04 07:23:36.000', 3, NULL, 0);
|
||||
INSERT INTO `base_config` VALUES (113, 'ice_server_config', '{\"title\":\"ICE Server Credential\",\"componentType\":\"text\",\"value\":\"\",\"configKey\":\"iceServerCredential\",\"type\":\"ice_server_config\"}', 'iceServerCredential', '', 0, '2025-12-04 07:23:36.000', '2025-12-04 07:23:36.000', 3, NULL, 0);
|
||||
INSERT INTO `base_config` VALUES (111, 'ice_server_config', '{\"title\":\"ICE Server URLs(JSON数组或逗号分隔)\",\"componentType\":\"text\",\"value\":\"[]\",\"configKey\":\"iceServerUrls\",\"type\":\"ice_server_config\"}', 'iceServerUrls', '[]', 0, '2025-12-04 07:23:39.000', '2025-12-04 07:23:39.000', 3, NULL, 0);
|
||||
INSERT INTO `base_config` VALUES (112, 'ice_server_config', '{\"title\":\"ICE Server Username\",\"componentType\":\"text\",\"value\":\"\",\"configKey\":\"iceServerUsername\",\"type\":\"ice_server_config\"}', 'iceServerUsername', '', 0, '2025-12-04 07:23:39.000', '2025-12-04 07:23:39.000', 3, NULL, 0);
|
||||
INSERT INTO `base_config` VALUES (113, 'ice_server_config', '{\"title\":\"ICE Server Credential\",\"componentType\":\"text\",\"value\":\"\",\"configKey\":\"iceServerCredential\",\"type\":\"ice_server_config\"}', 'iceServerCredential', '', 0, '2025-12-04 07:23:39.000', '2025-12-04 07:23:39.000', 3, NULL, 0);
|
||||
INSERT INTO `base_config` VALUES (114, 'translate_config', '{\"title\":\"翻译引擎\",\"componentType\":\"text\",\"value\":\"youdao\",\"configKey\":\"translateDefault\",\"type\":\"translate_config\"}', 'translateDefault', 'youdao', 0, '2025-12-04 10:42:44.000', '2025-12-04 10:42:44.000', 3, NULL, 0);
|
||||
|
||||
-- ----------------------------
|
||||
@@ -88,7 +88,7 @@ CREATE TABLE `im_announcements` (
|
||||
`is_del` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否删除',
|
||||
`tenant_id` bigint NOT NULL DEFAULT 1,
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 94625993966593 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_as_ci COMMENT = '聊天公告表' ROW_FORMAT = Dynamic;
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 104683855277057 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_as_ci COMMENT = '聊天公告表' ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of im_announcements
|
||||
@@ -165,7 +165,7 @@ CREATE TABLE `im_contact` (
|
||||
INDEX `idx_create_time`(`create_time` ASC) USING BTREE,
|
||||
INDEX `idx_update_time`(`update_time` ASC) USING BTREE,
|
||||
INDEX `idx_contact_room_uid_hide`(`room_id` ASC, `uid` ASC, `hide` ASC) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 69082079619944 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '会话列表' ROW_FORMAT = Dynamic;
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 69082079622096 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '会话列表' ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of im_contact
|
||||
@@ -338,7 +338,7 @@ CREATE TABLE `im_group_member` (
|
||||
INDEX `idx_create_time`(`create_time` ASC) USING BTREE,
|
||||
INDEX `idx_update_time`(`update_time` ASC) USING BTREE,
|
||||
INDEX `idx_group_member_uid_isdel_groupid`(`uid` ASC, `is_del` ASC, `group_id` ASC) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 103117702162434 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '群成员表' ROW_FORMAT = Dynamic;
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 105220961071106 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '群成员表' ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of im_group_member
|
||||
@@ -401,7 +401,7 @@ CREATE TABLE `im_message` (
|
||||
INDEX `idx_from_uid`(`from_uid` ASC) USING BTREE,
|
||||
INDEX `idx_create_time`(`create_time` ASC) USING BTREE,
|
||||
INDEX `idx_update_time`(`update_time` ASC) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 103117702162440 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '消息表' ROW_FORMAT = Dynamic;
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 105220961071112 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '消息表' ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of im_message
|
||||
@@ -431,7 +431,7 @@ CREATE TABLE `im_message_mark` (
|
||||
INDEX `idx_uid`(`uid` ASC) USING BTREE,
|
||||
INDEX `idx_create_time`(`create_time` ASC) USING BTREE,
|
||||
INDEX `idx_update_time`(`update_time` ASC) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 102919517104129 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '消息标记表' ROW_FORMAT = Dynamic;
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 104399619877889 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '消息标记表' ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of im_message_mark
|
||||
@@ -463,7 +463,7 @@ CREATE TABLE `im_notice` (
|
||||
INDEX `idx_receiver_type`(`receiver_id` ASC, `event_type` ASC) USING BTREE,
|
||||
INDEX `idx_sender`(`sender_id` ASC) USING BTREE,
|
||||
INDEX `idx_related`(`apply_id` ASC) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 102865033095171 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin COMMENT = '统一通知表' ROW_FORMAT = Dynamic;
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 105095249391619 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin COMMENT = '统一通知表' ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of im_notice
|
||||
@@ -513,12 +513,12 @@ CREATE TABLE `im_room` (
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
INDEX `idx_create_time`(`create_time` ASC) USING BTREE,
|
||||
INDEX `idx_update_time`(`update_time` ASC) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 103117702162435 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '房间表' ROW_FORMAT = Dynamic;
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 105220961071107 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '房间表' ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of im_room
|
||||
-- ----------------------------
|
||||
INSERT INTO `im_room` VALUES (1, 1, 1, '2025-12-05 13:12:56.750', 103117702162439, NULL, '2024-07-10 11:17:15.521', '2025-12-05 05:12:56.772', 1, 1, NULL, 0);
|
||||
INSERT INTO `im_room` VALUES (1, 1, 1, '2025-12-11 08:30:32.937', 105220961071111, NULL, '2024-07-10 11:17:15.521', '2025-12-11 00:30:32.982', 1, 1, NULL, 0);
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for im_room_friend
|
||||
@@ -543,7 +543,7 @@ CREATE TABLE `im_room_friend` (
|
||||
INDEX `idx_room_id`(`room_id` ASC) USING BTREE,
|
||||
INDEX `idx_create_time`(`create_time` ASC) USING BTREE,
|
||||
INDEX `idx_update_time`(`update_time` ASC) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 103117702162436 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '单聊房间表' ROW_FORMAT = Dynamic;
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 105220961071108 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '单聊房间表' ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of im_room_friend
|
||||
@@ -572,7 +572,7 @@ CREATE TABLE `im_room_group` (
|
||||
INDEX `idx_room_id`(`room_id` ASC) USING BTREE,
|
||||
INDEX `idx_create_time`(`create_time` ASC) USING BTREE,
|
||||
INDEX `idx_update_time`(`update_time` ASC) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 101643924399107 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '群聊房间表' ROW_FORMAT = Dynamic;
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 104683683310602 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '群聊房间表' ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of im_room_group
|
||||
@@ -654,13 +654,13 @@ CREATE TABLE `im_user` (
|
||||
INDEX `idx_update_time`(`update_time` ASC) USING BTREE,
|
||||
INDEX `idx_active_status_last_opt_time`(`last_opt_time` ASC) USING BTREE,
|
||||
INDEX `account_UNIQUE`(`account` ASC) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 103117702162433 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '用户表' ROW_FORMAT = Dynamic;
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 105220961071105 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '用户表' ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of im_user
|
||||
-- ----------------------------
|
||||
INSERT INTO `im_user` VALUES (1, 61170828519936, 2, 'HuLa小管家', '022', '', 'bot', NULL, '', 0, '2025-07-07 15:27:01.711', '{\"createIp\": \"206.237.119.215\", \"updateIp\": \"116.24.64.57\", \"createIpDetail\": null, \"updateIpDetail\": {\"ip\": \"116.24.64.57\", \"isp\": \"电信\", \"area\": \"\", \"city\": \"深圳\", \"isp_id\": null, \"region\": \"广东省\", \"city_id\": null, \"country\": \"中国\", \"region_id\": null, \"country_id\": null}}', 6, 0, '', '2025-03-27 04:23:08.393', '2025-12-02 11:37:40.510', 0, 61170828529941, 0, '2025-05-09 18:24:37.089', 0, 1, 10);
|
||||
INSERT INTO `im_user` VALUES (10937855681024, 61170828519937, 3, 'Dawn', 'https://cdn.hulaspark.com/avatar/2439646234/97320189485dca88dcc7a70054445a56.webp', '2439646234@qq.com', '13275346112', NULL, '', 11, '2025-07-30 15:31:57.651', '{\"createIp\": \"206.237.119.215\", \"updateIp\": \"116.24.64.57\", \"createIpDetail\": null, \"updateIpDetail\": {\"ip\": \"116.24.64.57\", \"isp\": \"电信\", \"area\": \"\", \"city\": \"深圳\", \"isp_id\": null, \"region\": \"广东省\", \"city_id\": null, \"country\": \"中国\", \"region_id\": null, \"country_id\": null}}', 6, 0, '', '2025-03-27 04:23:08.393', '2025-12-03 08:33:26.968', 0, 61170828529941, 0, '2025-09-20 21:35:31.415', 0, 1, 10);
|
||||
INSERT INTO `im_user` VALUES (1, 61170828519936, 2, 'HuLa小管家', '022', '', 'bot', NULL, '', 0, '2025-07-07 15:27:01.711', '{\"createIp\": \"206.237.119.215\", \"updateIp\": \"113.89.33.218\", \"createIpDetail\": null, \"updateIpDetail\": {\"ip\": \"113.89.33.218\", \"isp\": \"电信\", \"area\": \"\", \"city\": \"深圳\", \"isp_id\": null, \"region\": \"广东省\", \"city_id\": null, \"country\": \"中国\", \"region_id\": null, \"country_id\": null}}', 6, 0, '', '2025-03-27 04:23:08.393', '2025-12-08 16:54:04.446', 0, NULL, 0, '2025-05-09 18:24:37.089', 0, 1, 10);
|
||||
INSERT INTO `im_user` VALUES (10937855681024, 61170828519937, 3, 'Dawn', 'https://cdn.hulaspark.com/avatar/2439646234/97320189485dca88dcc7a70054445a56.webp', '2439646234@qq.com', '13275346112', NULL, '', 11, '2025-07-30 15:31:57.651', '{\"createIp\": \"206.237.119.215\", \"updateIp\": \"120.231.232.9\", \"createIpDetail\": null, \"updateIpDetail\": {\"ip\": \"120.231.232.9\", \"isp\": \"移动\", \"area\": \"\", \"city\": \"深圳\", \"isp_id\": null, \"region\": \"广东省\", \"city_id\": null, \"country\": \"中国\", \"region_id\": null, \"country_id\": null}}', 6, 0, '', '2025-03-27 04:23:08.393', '2025-12-10 21:30:15.675', 0, 61170828529941, 0, '2025-09-20 21:35:31.415', 0, 1, 10);
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for im_user_apply
|
||||
@@ -690,7 +690,7 @@ CREATE TABLE `im_user_apply` (
|
||||
INDEX `idx_target_id`(`target_id` ASC) USING BTREE,
|
||||
INDEX `idx_create_time`(`create_time` ASC) USING BTREE,
|
||||
INDEX `idx_update_time`(`update_time` ASC) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 102865033095169 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '用户申请表' ROW_FORMAT = Dynamic;
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 105095249391617 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '用户申请表' ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of im_user_apply
|
||||
@@ -717,7 +717,7 @@ CREATE TABLE `im_user_backpack` (
|
||||
INDEX `idx_uid`(`uid` ASC) USING BTREE,
|
||||
INDEX `idx_create_time`(`create_time` ASC) USING BTREE,
|
||||
INDEX `idx_update_time`(`update_time` ASC) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 103117702162443 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '用户背包表' ROW_FORMAT = Dynamic;
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 105220961071115 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '用户背包表' ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of im_user_backpack
|
||||
@@ -793,7 +793,7 @@ CREATE TABLE `im_user_friend` (
|
||||
INDEX `idx_uid_friend_uid`(`uid` ASC, `friend_uid` ASC) USING BTREE,
|
||||
INDEX `idx_create_time`(`create_time` ASC) USING BTREE,
|
||||
INDEX `idx_update_time`(`update_time` ASC) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 103117702162438 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '用户联系人表' ROW_FORMAT = Dynamic;
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 105220961071110 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '用户联系人表' ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of im_user_friend
|
||||
@@ -971,7 +971,7 @@ CREATE TABLE `secure_invoke_record` (
|
||||
`is_del` tinyint NOT NULL DEFAULT 0 COMMENT '是否删除',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
INDEX `idx_next_retry_time`(`next_retry_time` ASC) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 103117702162442 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '本地消息表' ROW_FORMAT = Dynamic;
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 105220961071114 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '本地消息表' ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of secure_invoke_record
|
||||
@@ -990,7 +990,7 @@ CREATE TABLE `worker_node` (
|
||||
`modified` timestamp NULL DEFAULT NULL COMMENT '修改时间',
|
||||
`created` timestamp NULL DEFAULT NULL COMMENT '创建时间',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 245 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = 'DB;WorkerID Assigner for UID Generator' ROW_FORMAT = Dynamic;
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 250 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = 'DB;WorkerID Assigner for UID Generator' ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of worker_node
|
||||
|
||||
@@ -59,7 +59,7 @@ public class AuthenticationSaInterceptor implements WebFilter, Ordered {
|
||||
exchange.getAttributes().put(SaReactorHolder.EXCHANGE_KEY, chain);
|
||||
|
||||
// ---------- 全局认证处理 仅后台需要鉴权
|
||||
if("1".equals(exchange.getRequest().getHeaders().getFirst(JWT_KEY_SYSTEM_TYPE))){
|
||||
if("10".equals(exchange.getRequest().getHeaders().getFirst(JWT_KEY_SYSTEM_TYPE))){
|
||||
try {
|
||||
// 写入全局上下文 (同步)
|
||||
SaReactorSyncHolder.setContext(exchange);
|
||||
|
||||
@@ -6,11 +6,13 @@ import com.luohuo.flex.im.sensitive.MyWordFactory;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* @author nyh
|
||||
*/
|
||||
@Configuration
|
||||
@Slf4j
|
||||
public class SensitiveWordConfig {
|
||||
|
||||
@Resource
|
||||
@@ -23,10 +25,12 @@ public class SensitiveWordConfig {
|
||||
*/
|
||||
@Bean
|
||||
public SensitiveWordBs sensitiveWordBs() {
|
||||
int size = myWordFactory.getWordList().size();
|
||||
log.info("敏感词初始化加载数量: {}", size);
|
||||
return SensitiveWordBs.newInstance()
|
||||
.filterStrategy(DFAFilter.getInstance())
|
||||
.sensitiveWord(myWordFactory)
|
||||
.init();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,6 +52,7 @@ public class BotMsgHandler extends AbstractMsgHandler<TextMsgReq> {
|
||||
AssertUtil.isNotEmpty(replyMsg, "回复消息不存在");
|
||||
AssertUtil.equal(replyMsg.getRoomId(), roomId, "只能回复相同会话内的消息");
|
||||
}
|
||||
AssertUtil.isFalse(sensitiveWordBs.hasSensitiveWord(body.getContent()), "消息包含敏感词,小黑子注意点");
|
||||
if (CollectionUtil.isNotEmpty(body.getAtUidList())) {
|
||||
//前端传入的@用户列表可能会重复,需要去重
|
||||
List<Long> atUidList = body.getAtUidList().stream().distinct().collect(Collectors.toList());
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.luohuo.flex.im.core.chat.service.strategy.msg;
|
||||
|
||||
import com.luohuo.flex.im.common.utils.discover.PrioritizedUrlDiscover;
|
||||
import com.luohuo.basic.validator.utils.AssertUtil;
|
||||
import com.luohuo.flex.im.domain.UrlInfo;
|
||||
import com.luohuo.flex.im.common.utils.sensitiveword.SensitiveWordBs;
|
||||
import com.luohuo.flex.im.core.chat.dao.MessageDao;
|
||||
@@ -31,6 +32,11 @@ public class NoticeMsgHandler extends AbstractMsgHandler<NoticeMsgDTO> {
|
||||
return MessageTypeEnum.NOTICE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void checkMsg(NoticeMsgDTO body, Long roomId, Long uid) {
|
||||
AssertUtil.isFalse(sensitiveWordBs.hasSensitiveWord(body.getContent()), "消息包含敏感词,请重新输入");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveMsg(Message message, NoticeMsgDTO body) {
|
||||
MessageExtra extra = Optional.ofNullable(message.getExtra()).orElse(new MessageExtra());
|
||||
|
||||
@@ -52,6 +52,7 @@ public class TextMsgHandler extends AbstractMsgHandler<TextMsgReq> {
|
||||
AssertUtil.isNotEmpty(replyMsg, "回复消息不存在");
|
||||
AssertUtil.equal(replyMsg.getRoomId(), roomId, "只能回复相同会话内的消息");
|
||||
}
|
||||
AssertUtil.isFalse(sensitiveWordBs.hasSensitiveWord(body.getContent()), "消息包含敏感词,请重新输入");
|
||||
if (CollectionUtil.isNotEmpty(body.getAtUidList())) {
|
||||
//前端传入的@用户列表可能会重复,需要去重
|
||||
List<Long> atUidList = body.getAtUidList().stream().distinct().collect(Collectors.toList());
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.luohuo.flex.im.core.sensitive;
|
||||
|
||||
import com.luohuo.basic.annotation.log.WebLog;
|
||||
import com.luohuo.basic.base.R;
|
||||
import com.luohuo.flex.im.common.utils.sensitiveword.SensitiveWordBs;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@Validated
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/sensitiveWord")
|
||||
@Tag(name = "敏感词")
|
||||
public class SensitiveWordController {
|
||||
|
||||
private final SensitiveWordBs sensitiveWordBs;
|
||||
|
||||
@PostMapping("/refresh")
|
||||
@Operation(summary = "刷新敏感词词库")
|
||||
@WebLog("刷新敏感词词库")
|
||||
public R<Boolean> refresh() {
|
||||
sensitiveWordBs.init();
|
||||
return R.success(true);
|
||||
}
|
||||
|
||||
@PostMapping("/check")
|
||||
@Operation(summary = "检测并过滤文本")
|
||||
@WebLog("检测并过滤文本")
|
||||
public R<CheckResp> check(@RequestParam("text") String text) {
|
||||
boolean hit = sensitiveWordBs.hasSensitiveWord(text);
|
||||
String filtered = sensitiveWordBs.filter(text);
|
||||
return R.success(new CheckResp(hit, filtered));
|
||||
}
|
||||
|
||||
public static class CheckResp {
|
||||
public final boolean hit;
|
||||
public final String filtered;
|
||||
|
||||
public CheckResp(boolean hit, String filtered) {
|
||||
this.hit = hit;
|
||||
this.filtered = filtered;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,13 @@ public interface FeedService {
|
||||
|
||||
FeedVo feedDetail(Long feedId, Long uid);
|
||||
|
||||
/**
|
||||
* 获取指定用户最新一条可见的朋友圈
|
||||
* @param targetUid 被查看的用户ID
|
||||
* @param requesterUid 当前查看人ID
|
||||
*/
|
||||
FeedVo getLatestByUser(Long targetUid, Long requesterUid);
|
||||
|
||||
FeedPermission getFeedPermission(Long uid, Long feedId);
|
||||
|
||||
Boolean editFeed(Long uid, FeedParam param);
|
||||
|
||||
@@ -13,6 +13,7 @@ import com.luohuo.flex.im.domain.entity.ItemConfig;
|
||||
import com.luohuo.flex.im.domain.entity.User;
|
||||
import com.luohuo.flex.im.domain.entity.UserBackpack;
|
||||
import com.luohuo.flex.im.domain.enums.ItemTypeEnum;
|
||||
import com.luohuo.flex.im.enums.UserTypeEnum;
|
||||
import com.luohuo.flex.im.domain.vo.response.ChatMemberListResp;
|
||||
import com.luohuo.flex.model.entity.base.IpDetail;
|
||||
import com.luohuo.flex.model.entity.base.IpInfo;
|
||||
@@ -83,12 +84,18 @@ public class UserSummaryCache extends AbstractRedisStringCache<Long, SummeryInfo
|
||||
summeryInfoDTO.setLocPlace(Optional.ofNullable(user.getIpInfo()).map(IpInfo::getUpdateIpDetail).map(IpDetail::getCity).orElse(null));
|
||||
summeryInfoDTO.setWearingItemId(user.getItemId());
|
||||
summeryInfoDTO.setItemIds(userBackpacks.stream().map(UserBackpack::getItemId).collect(Collectors.toList()));
|
||||
summeryInfoDTO.setUserType(user.getUserType());
|
||||
summeryInfoDTO.setEmail(user.getEmail());
|
||||
summeryInfoDTO.setOpenId(user.getOpenId());
|
||||
summeryInfoDTO.setSex(user.getSex());
|
||||
summeryInfoDTO.setResume(user.getResume());
|
||||
summeryInfoDTO.setLastOptTime(user.getLastOptTime());
|
||||
summeryInfoDTO.setUserType(user.getUserType());
|
||||
summeryInfoDTO.setEmail(user.getEmail());
|
||||
summeryInfoDTO.setOpenId(user.getOpenId());
|
||||
summeryInfoDTO.setSex(user.getSex());
|
||||
summeryInfoDTO.setResume(user.getResume());
|
||||
summeryInfoDTO.setLastOptTime(user.getLastOptTime());
|
||||
if (Objects.equals(user.getUserType(), UserTypeEnum.BOT.getValue())) {
|
||||
summeryInfoDTO.setWearingItemId(null);
|
||||
summeryInfoDTO.setItemIds(Collections.emptyList());
|
||||
summeryInfoDTO.setEmail(null);
|
||||
summeryInfoDTO.setResume(null);
|
||||
}
|
||||
return summeryInfoDTO;
|
||||
}).filter(Objects::nonNull).collect(Collectors.toMap(SummeryInfoDTO::getUid, Function.identity()));
|
||||
}
|
||||
|
||||
@@ -390,6 +390,19 @@ public class FeedServiceImpl implements FeedService {
|
||||
return feedVos.isEmpty() ? null : feedVos.get(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeedVo getLatestByUser(Long targetUid, Long requesterUid) {
|
||||
Feed latest = feedDao.lambdaQuery()
|
||||
.eq(Feed::getUid, targetUid)
|
||||
.orderByDesc(Feed::getCreateTime)
|
||||
.last("limit 1")
|
||||
.one();
|
||||
if (ObjectUtil.isNull(latest)) {
|
||||
return null;
|
||||
}
|
||||
return feedDetail(latest.getId(), requesterUid);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取朋友圈的可见权限
|
||||
* @param feedId
|
||||
|
||||
@@ -51,6 +51,7 @@ import com.luohuo.flex.model.vo.query.BindEmailReq;
|
||||
import com.luohuo.flex.im.domain.vo.resp.user.BadgeResp;
|
||||
import com.luohuo.flex.im.domain.vo.resp.user.UserInfoResp;
|
||||
import com.luohuo.flex.im.core.user.service.UserService;
|
||||
import com.luohuo.flex.im.core.user.service.FeedService;
|
||||
import com.luohuo.flex.im.core.user.service.adapter.UserAdapter;
|
||||
import com.luohuo.flex.im.core.user.service.cache.UserSummaryCache;
|
||||
|
||||
@@ -81,6 +82,7 @@ public class UserServiceImpl implements UserService {
|
||||
private final UserCache userCache;
|
||||
private final UserSummaryCache userSummaryCache;
|
||||
private final SensitiveWordBs sensitiveWordBs;
|
||||
private final FeedService feedService;
|
||||
|
||||
@Override
|
||||
public Boolean refreshIpInfo(Long uid, IpInfo ipInfo) {
|
||||
@@ -120,7 +122,9 @@ public class UserServiceImpl implements UserService {
|
||||
public UserInfoResp getUserInfo(Long uid) {
|
||||
SummeryInfoDTO userInfo = userSummaryCache.get(uid);
|
||||
Integer countByValidItemId = userBackpackDao.getCountByValidItemId(uid, ItemEnum.MODIFY_NAME_CARD.getId());
|
||||
return UserAdapter.buildUserInfoResp(userInfo, countByValidItemId);
|
||||
UserInfoResp resp = UserAdapter.buildUserInfoResp(userInfo, countByValidItemId);
|
||||
resp.setLatestFeed(feedService.getLatestByUser(uid, uid));
|
||||
return resp;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.luohuo.flex.im.domain.vo.resp.user;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import com.luohuo.flex.im.domain.vo.req.feed.FeedVo;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
@@ -52,6 +53,9 @@ public class UserInfoResp implements Serializable {
|
||||
@Schema(description = "是否开启上下文[AI模块]")
|
||||
private Boolean context;
|
||||
|
||||
@Schema(description = "调用次数[AI模块]")
|
||||
private Integer num;
|
||||
@Schema(description = "调用次数[AI模块]")
|
||||
private Integer num;
|
||||
|
||||
@Schema(description = "最新动态")
|
||||
private FeedVo latestFeed;
|
||||
}
|
||||
|
||||
@@ -207,11 +207,7 @@ public class ResourceBiz {
|
||||
log.debug("level={}, label={}", level, item.getName());
|
||||
RouterMeta meta = null;
|
||||
if (StrUtil.isNotEmpty(item.getMetaJson()) && !StrPool.BRACE.equals(item.getMetaJson())) {
|
||||
try {
|
||||
meta = JsonUtil.parse(item.getMetaJson(), RouterMeta.class);
|
||||
} catch (Exception ignored) {
|
||||
try { meta = objectMapper.readValue(item.getMetaJson(), RouterMeta.class); } catch (Exception ignored2) {}
|
||||
}
|
||||
meta = JsonUtil.parseJson(item.getMetaJson(), RouterMeta.class);
|
||||
}
|
||||
if (meta == null && item.getMeta() != null) {
|
||||
meta = item.getMeta();
|
||||
@@ -261,11 +257,7 @@ public class ResourceBiz {
|
||||
log.debug("level={}, label={}", level, item.getName());
|
||||
RouterMeta meta = null;
|
||||
if (StrUtil.isNotEmpty(item.getMetaJson()) && !StrPool.BRACE.equals(item.getMetaJson())) {
|
||||
try {
|
||||
meta = JsonUtil.parse(item.getMetaJson(), RouterMeta.class);
|
||||
} catch (Exception ignored) {
|
||||
try { meta = objectMapper.readValue(item.getMetaJson(), RouterMeta.class); } catch (Exception ignored2) {}
|
||||
}
|
||||
meta = JsonUtil.parseJson(item.getMetaJson(), RouterMeta.class);
|
||||
}
|
||||
if (meta == null && item.getMeta() != null) {
|
||||
meta = item.getMeta();
|
||||
@@ -346,11 +338,7 @@ public class ResourceBiz {
|
||||
RouterMeta meta = null;
|
||||
if (item.getMeta() == null) {
|
||||
if (StrUtil.isNotEmpty(item.getMetaJson()) && !StrPool.BRACE.equals(item.getMetaJson())) {
|
||||
try {
|
||||
meta = JsonUtil.parse(item.getMetaJson(), RouterMeta.class);
|
||||
} catch (Exception ignored) {
|
||||
try { meta = objectMapper.readValue(item.getMetaJson(), RouterMeta.class); } catch (Exception ignored2) {}
|
||||
}
|
||||
meta = JsonUtil.parseJson(item.getMetaJson(), RouterMeta.class);
|
||||
}
|
||||
if (meta == null && item.getMeta() != null) {
|
||||
meta = item.getMeta();
|
||||
|
||||
@@ -83,49 +83,49 @@ import static com.luohuo.basic.context.ContextConstants.*;
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public abstract class AbstractTokenGranter implements TokenGranter {
|
||||
protected final SystemProperties systemProperties;
|
||||
protected final DefClientService defClientService;
|
||||
protected final DefUserService defUserService;
|
||||
protected final BaseEmployeeService baseEmployeeService;
|
||||
protected final BaseOrgService baseOrgService;
|
||||
protected final SaTokenConfig saTokenConfig;
|
||||
protected final SystemProperties systemProperties;
|
||||
protected final DefClientService defClientService;
|
||||
protected final DefUserService defUserService;
|
||||
protected final BaseEmployeeService baseEmployeeService;
|
||||
protected final BaseOrgService baseOrgService;
|
||||
protected final SaTokenConfig saTokenConfig;
|
||||
protected final ImUserApi imUserApi;
|
||||
protected final StpInterfaceBiz stpInterfaceBiz;
|
||||
@Override
|
||||
public R<LoginResultVO> login(LoginParamVO loginParam) {
|
||||
// 1. 参数校验
|
||||
R<LoginResultVO> result = checkParam(loginParam);
|
||||
if (!result.getsuccess()) {
|
||||
return result;
|
||||
}
|
||||
result = checkAuthorization();
|
||||
if (!result.getsuccess()) {
|
||||
return result;
|
||||
}
|
||||
@Override
|
||||
public R<LoginResultVO> login(LoginParamVO loginParam) {
|
||||
// 1. 参数校验
|
||||
R<LoginResultVO> result = checkParam(loginParam);
|
||||
if (!result.getsuccess()) {
|
||||
return result;
|
||||
}
|
||||
result = checkAuthorization();
|
||||
if (!result.getsuccess()) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// 2. 验证码
|
||||
result = checkCaptcha(loginParam);
|
||||
if (!result.getsuccess()) {
|
||||
return result;
|
||||
}
|
||||
// 2. 验证码
|
||||
result = checkCaptcha(loginParam);
|
||||
if (!result.getsuccess()) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// 3. 查找用户
|
||||
// 3. 查找用户
|
||||
DefUser defUser = getUser(loginParam);
|
||||
|
||||
// 5. 判断密码
|
||||
result = checkUserPassword(loginParam, defUser);
|
||||
if (!result.getsuccess()) {
|
||||
throw new BizException(result.getMsg());
|
||||
}
|
||||
// 5. 判断密码
|
||||
result = checkUserPassword(loginParam, defUser);
|
||||
if (!result.getsuccess()) {
|
||||
throw new BizException(result.getMsg());
|
||||
}
|
||||
|
||||
// 6. 检查用户状态
|
||||
result = checkUserState(defUser);
|
||||
if (!result.getsuccess()) {
|
||||
return result;
|
||||
}
|
||||
// 6. 检查用户状态
|
||||
result = checkUserState(defUser);
|
||||
if (!result.getsuccess()) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// 7. 查询单位
|
||||
Org org = findOrg(defUser);
|
||||
// 7. 查询单位
|
||||
Org org = findOrg(defUser);
|
||||
|
||||
// 8. 查询对应系统中的uid
|
||||
Long uid = findUid(defUser.getId(), defUser.getTenantId(), defUser.getSystemType());
|
||||
@@ -133,13 +133,13 @@ public abstract class AbstractTokenGranter implements TokenGranter {
|
||||
// 9. 发布登录事件
|
||||
defUser.refreshIp(ContextUtil.getIP());
|
||||
|
||||
// 10. 封装token
|
||||
LoginResultVO loginResultVO = buildResult(uid, defUser, org, loginParam.getDeviceType(), loginParam.getClientId());
|
||||
LoginStatusDTO loginStatus = LoginStatusDTO.success(defUser.getId(), uid, defUser.getSystemType(), loginParam.getDeviceType());
|
||||
// 10. 封装token
|
||||
LoginResultVO loginResultVO = buildResult(uid, defUser, org, loginParam.getDeviceType(), loginParam.getClientId());
|
||||
LoginStatusDTO loginStatus = LoginStatusDTO.success(defUser.getId(), uid, defUser.getSystemType(), loginParam.getDeviceType());
|
||||
SpringUtils.publishEvent(new UserOnlineEvent(this, ContextUtil.getTenantId(), uid, defUser.getId(), defUser.getLastLoginTime(), defUser.getIpInfo()));
|
||||
SpringUtils.publishEvent(new LoginEvent(loginStatus));
|
||||
return R.success(loginResultVO);
|
||||
}
|
||||
return R.success(loginResultVO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 统一登录接口,后续增加需要登录的系统模块只需要在对应的系统新增对应的表即可,用于存储对应的系统中的头像、昵称等信息
|
||||
@@ -156,227 +156,227 @@ public abstract class AbstractTokenGranter implements TokenGranter {
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查参数
|
||||
*
|
||||
* @param loginParam 登录参数
|
||||
* @return com.luohuo.basic.base.R<com.luohuo.flex.oauth.vo.result.LoginResultVO>
|
||||
* @author tangyh
|
||||
* @date 2022/10/5 12:38 PM
|
||||
* @create [2022/10/5 12:38 PM ] [tangyh] [初始创建]
|
||||
*/
|
||||
protected abstract R<LoginResultVO> checkParam(LoginParamVO loginParam);
|
||||
* 检查参数
|
||||
*
|
||||
* @param loginParam 登录参数
|
||||
* @return com.luohuo.basic.base.R<com.luohuo.flex.oauth.vo.result.LoginResultVO>
|
||||
* @author tangyh
|
||||
* @date 2022/10/5 12:38 PM
|
||||
* @create [2022/10/5 12:38 PM ] [tangyh] [初始创建]
|
||||
*/
|
||||
protected abstract R<LoginResultVO> checkParam(LoginParamVO loginParam);
|
||||
|
||||
/**
|
||||
* 检测客户端
|
||||
*
|
||||
* @return com.luohuo.basic.base.R<com.luohuo.flex.oauth.vo.result.LoginResultVO>
|
||||
* @author tangyh
|
||||
* @date 2022/10/5 12:38 PM
|
||||
* @create [2022/10/5 12:38 PM ] [tangyh] [初始创建]
|
||||
*/
|
||||
protected R<LoginResultVO> checkAuthorization() {
|
||||
String basicHeader = JakartaServletUtil.getHeader(WebUtils.request(), AUTHORIZATION_KEY, StrPool.UTF_8);
|
||||
String[] authorization = Base64Util.getAuthorization(basicHeader);
|
||||
DefClient defAuthorization = defClientService.getClient(authorization[0], authorization[1]);
|
||||
/**
|
||||
* 检测客户端
|
||||
*
|
||||
* @return com.luohuo.basic.base.R<com.luohuo.flex.oauth.vo.result.LoginResultVO>
|
||||
* @author tangyh
|
||||
* @date 2022/10/5 12:38 PM
|
||||
* @create [2022/10/5 12:38 PM ] [tangyh] [初始创建]
|
||||
*/
|
||||
protected R<LoginResultVO> checkAuthorization() {
|
||||
String basicHeader = JakartaServletUtil.getHeader(WebUtils.request(), AUTHORIZATION_KEY, StrPool.UTF_8);
|
||||
String[] authorization = Base64Util.getAuthorization(basicHeader);
|
||||
DefClient defAuthorization = defClientService.getClient(authorization[0], authorization[1]);
|
||||
|
||||
if (defAuthorization == null) {
|
||||
return R.fail("请在.env文件中配置正确的客户端ID或者客户端秘钥");
|
||||
}
|
||||
if (!defAuthorization.getState()) {
|
||||
return R.fail("客户端[%s]已被禁用", defAuthorization.getClientId());
|
||||
}
|
||||
return R.success(null);
|
||||
}
|
||||
if (defAuthorization == null) {
|
||||
return R.fail("请在.env文件中配置正确的客户端ID或者客户端秘钥");
|
||||
}
|
||||
if (!defAuthorization.getState()) {
|
||||
return R.fail("客户端[%s]已被禁用", defAuthorization.getClientId());
|
||||
}
|
||||
return R.success(null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 检查验证码
|
||||
*
|
||||
* @param loginParam 登录参数
|
||||
* @return com.luohuo.basic.base.R<com.luohuo.flex.oauth.vo.result.LoginResultVO>
|
||||
* @author tangyh
|
||||
* @date 2022/10/5 12:38 PM
|
||||
* @create [2022/10/5 12:38 PM ] [tangyh] [初始创建]
|
||||
*/
|
||||
protected R<LoginResultVO> checkCaptcha(LoginParamVO loginParam) {
|
||||
return R.success(null);
|
||||
}
|
||||
/**
|
||||
* 检查验证码
|
||||
*
|
||||
* @param loginParam 登录参数
|
||||
* @return com.luohuo.basic.base.R<com.luohuo.flex.oauth.vo.result.LoginResultVO>
|
||||
* @author tangyh
|
||||
* @date 2022/10/5 12:38 PM
|
||||
* @create [2022/10/5 12:38 PM ] [tangyh] [初始创建]
|
||||
*/
|
||||
protected R<LoginResultVO> checkCaptcha(LoginParamVO loginParam) {
|
||||
return R.success(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询用户
|
||||
*
|
||||
* @param loginParam 登录参数
|
||||
* @return com.luohuo.flex.system.entity.tenant.DefUser
|
||||
* @author tangyh
|
||||
* @date 2022/10/5 12:38 PM
|
||||
* @create [2022/10/5 12:38 PM ] [tangyh] [初始创建]
|
||||
*/
|
||||
protected abstract DefUser getUser(LoginParamVO loginParam);
|
||||
/**
|
||||
* 查询用户
|
||||
*
|
||||
* @param loginParam 登录参数
|
||||
* @return com.luohuo.flex.system.entity.tenant.DefUser
|
||||
* @author tangyh
|
||||
* @date 2022/10/5 12:38 PM
|
||||
* @create [2022/10/5 12:38 PM ] [tangyh] [初始创建]
|
||||
*/
|
||||
protected abstract DefUser getUser(LoginParamVO loginParam);
|
||||
|
||||
/**
|
||||
* 检查用户账号密码是否正确
|
||||
*
|
||||
* @param loginParam loginParam
|
||||
* @param user user
|
||||
* @return com.luohuo.basic.base.R<com.luohuo.flex.oauth.vo.result.LoginResultVO>
|
||||
* @author tangyh
|
||||
* @date 2022/10/5 12:38 PM
|
||||
* @create [2022/10/5 12:38 PM ] [tangyh] [初始创建]
|
||||
*/
|
||||
/**
|
||||
* 检查用户账号密码是否正确
|
||||
*
|
||||
* @param loginParam loginParam
|
||||
* @param user user
|
||||
* @return com.luohuo.basic.base.R<com.luohuo.flex.oauth.vo.result.LoginResultVO>
|
||||
* @author tangyh
|
||||
* @date 2022/10/5 12:38 PM
|
||||
* @create [2022/10/5 12:38 PM ] [tangyh] [初始创建]
|
||||
*/
|
||||
|
||||
protected R<LoginResultVO> checkUserPassword(LoginParamVO loginParam, DefUser user) {
|
||||
return R.success(null);
|
||||
}
|
||||
protected R<LoginResultVO> checkUserPassword(LoginParamVO loginParam, DefUser user) {
|
||||
return R.success(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查用户状态是否正常
|
||||
*
|
||||
* @param user user
|
||||
* @return com.luohuo.basic.base.R<com.luohuo.flex.oauth.vo.result.LoginResultVO>
|
||||
* @author tangyh
|
||||
* @date 2022/10/5 12:38 PM
|
||||
* @create [2022/10/5 12:38 PM ] [tangyh] [初始创建]
|
||||
*/
|
||||
protected R<LoginResultVO> checkUserState(DefUser user) {
|
||||
// 用户被禁用
|
||||
if (!user.getState()) {
|
||||
String msg = "您已被禁用,请联系管理员开通账号!";
|
||||
SpringUtils.publishEvent(new LoginEvent(LoginStatusDTO.fail(user.getId(), LoginStatusEnum.USER_ERROR, msg)));
|
||||
return R.fail(msg);
|
||||
}
|
||||
return R.success(null);
|
||||
}
|
||||
/**
|
||||
* 检查用户状态是否正常
|
||||
*
|
||||
* @param user user
|
||||
* @return com.luohuo.basic.base.R<com.luohuo.flex.oauth.vo.result.LoginResultVO>
|
||||
* @author tangyh
|
||||
* @date 2022/10/5 12:38 PM
|
||||
* @create [2022/10/5 12:38 PM ] [tangyh] [初始创建]
|
||||
*/
|
||||
protected R<LoginResultVO> checkUserState(DefUser user) {
|
||||
// 用户被禁用
|
||||
if (!user.getState()) {
|
||||
String msg = "您已被禁用,请联系管理员开通账号!";
|
||||
SpringUtils.publishEvent(new LoginEvent(LoginStatusDTO.fail(user.getId(), LoginStatusEnum.USER_ERROR, msg)));
|
||||
return R.fail(msg);
|
||||
}
|
||||
return R.success(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询员工信息
|
||||
*
|
||||
* @param defUser 用户信息
|
||||
* @return com.luohuo.flex.oauth.granter.AbstractTokenGranter.Employee
|
||||
* @author tangyh
|
||||
* @date 2022/10/5 12:38 PM
|
||||
* @create [2022/10/5 12:38 PM ] [tangyh] [初始创建]
|
||||
*/
|
||||
protected Employee getEmployee(DefUser defUser) {
|
||||
// 用户被禁用无法登陆, 员工被禁用无法访问当前企业的数据, 企业被禁用所有员工无法
|
||||
List<BaseEmployeeResultVO> employeeList = baseEmployeeService.listEmployeeByUserId(defUser.getId());
|
||||
Long employeeId = null;
|
||||
Long userId = defUser.getId();
|
||||
UserStatusEnum userStatus = UserStatusEnum.NORMAL;
|
||||
if (CollUtil.isNotEmpty(employeeList)) {
|
||||
BaseEmployeeResultVO defaultEmployee = employeeList.get(0);
|
||||
// 正常状态
|
||||
if (StateEnum.ENABLE.eq(defaultEmployee.getState())) {
|
||||
employeeId = defaultEmployee.getId();
|
||||
} else {
|
||||
userStatus = UserStatusEnum.USER_DISABLE;
|
||||
}
|
||||
} else {
|
||||
userStatus = UserStatusEnum.USER_DISABLE;
|
||||
}
|
||||
log.info("userStatus={}, userId={}, employeeId={}", userStatus, userId, employeeId);
|
||||
return Employee.builder().employeeId(employeeId).build();
|
||||
}
|
||||
/**
|
||||
* 查询员工信息
|
||||
*
|
||||
* @param defUser 用户信息
|
||||
* @return com.luohuo.flex.oauth.granter.AbstractTokenGranter.Employee
|
||||
* @author tangyh
|
||||
* @date 2022/10/5 12:38 PM
|
||||
* @create [2022/10/5 12:38 PM ] [tangyh] [初始创建]
|
||||
*/
|
||||
protected Employee getEmployee(DefUser defUser) {
|
||||
// 用户被禁用无法登陆, 员工被禁用无法访问当前企业的数据, 企业被禁用所有员工无法
|
||||
List<BaseEmployeeResultVO> employeeList = baseEmployeeService.listEmployeeByUserId(defUser.getId());
|
||||
Long employeeId = null;
|
||||
Long userId = defUser.getId();
|
||||
UserStatusEnum userStatus = UserStatusEnum.NORMAL;
|
||||
if (CollUtil.isNotEmpty(employeeList)) {
|
||||
BaseEmployeeResultVO defaultEmployee = employeeList.get(0);
|
||||
// 正常状态
|
||||
if (StateEnum.ENABLE.eq(defaultEmployee.getState())) {
|
||||
employeeId = defaultEmployee.getId();
|
||||
} else {
|
||||
userStatus = UserStatusEnum.USER_DISABLE;
|
||||
}
|
||||
} else {
|
||||
userStatus = UserStatusEnum.USER_DISABLE;
|
||||
}
|
||||
log.info("userStatus={}, userId={}, employeeId={}", userStatus, userId, employeeId);
|
||||
return Employee.builder().employeeId(employeeId).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询单位和部门信息
|
||||
*
|
||||
* @param defUser 员工信息
|
||||
* @return com.luohuo.flex.oauth.granter.AbstractTokenGranter.Org
|
||||
* @author tangyh
|
||||
* @date 2022/10/5 12:40 PM
|
||||
* @create [2022/10/5 12:40 PM ] [tangyh] [初始创建]
|
||||
*/
|
||||
protected Org findOrg(DefUser defUser) {
|
||||
/**
|
||||
* 查询单位和部门信息
|
||||
*
|
||||
* @param defUser 员工信息
|
||||
* @return com.luohuo.flex.oauth.granter.AbstractTokenGranter.Org
|
||||
* @author tangyh
|
||||
* @date 2022/10/5 12:40 PM
|
||||
* @create [2022/10/5 12:40 PM ] [tangyh] [初始创建]
|
||||
*/
|
||||
protected Org findOrg(DefUser defUser) {
|
||||
if(defUser.getSystemType().equals(LoginEnum.IM.getVal())){
|
||||
return new Org();
|
||||
}
|
||||
Long uid = defUser.getId();
|
||||
Long uid = defUser.getId();
|
||||
|
||||
// 当前所属部门
|
||||
Long currentDeptId = null;
|
||||
// 当前所属单位
|
||||
Long currentCompanyId = null;
|
||||
// 当前所属顶级单位
|
||||
Long currentTopCompanyId = null;
|
||||
if (uid != null) {
|
||||
BaseEmployee baseEmployee = baseEmployeeService.getByIdCache(uid);
|
||||
// 当前所属部门
|
||||
Long currentDeptId = null;
|
||||
// 当前所属单位
|
||||
Long currentCompanyId = null;
|
||||
// 当前所属顶级单位
|
||||
Long currentTopCompanyId = null;
|
||||
if (uid != null) {
|
||||
BaseEmployee baseEmployee = baseEmployeeService.getByIdCache(uid);
|
||||
|
||||
// 当前用户尚不属于任意租户
|
||||
if (baseEmployee == null) {
|
||||
return Org.builder()
|
||||
.currentTopCompanyId(null)
|
||||
.currentCompanyId(null)
|
||||
.currentDeptId(null).build();
|
||||
}
|
||||
// 当前用户尚不属于任意租户
|
||||
if (baseEmployee == null) {
|
||||
return Org.builder()
|
||||
.currentTopCompanyId(null)
|
||||
.currentCompanyId(null)
|
||||
.currentDeptId(null).build();
|
||||
}
|
||||
|
||||
boolean flag = false;
|
||||
// 上次登录的部门
|
||||
if (baseEmployee.getLastDeptId() != null) {
|
||||
currentDeptId = baseEmployee.getLastDeptId();
|
||||
// TODO 若用户变更了部门,是否有问题
|
||||
} else {
|
||||
// 上次登录部门为空,则随机选择一个部门
|
||||
List<BaseOrg> deptList = baseOrgService.findDeptByEmployeeId(uid, null);
|
||||
BaseOrg defaultDept = baseOrgService.getDefaultOrg(deptList, null);
|
||||
boolean flag = false;
|
||||
// 上次登录的部门
|
||||
if (baseEmployee.getLastDeptId() != null) {
|
||||
currentDeptId = baseEmployee.getLastDeptId();
|
||||
// TODO 若用户变更了部门,是否有问题
|
||||
} else {
|
||||
// 上次登录部门为空,则随机选择一个部门
|
||||
List<BaseOrg> deptList = baseOrgService.findDeptByEmployeeId(uid, null);
|
||||
BaseOrg defaultDept = baseOrgService.getDefaultOrg(deptList, null);
|
||||
|
||||
currentDeptId = defaultDept != null ? defaultDept.getId() : null;
|
||||
baseEmployee.setLastDeptId(currentDeptId);
|
||||
currentDeptId = defaultDept != null ? defaultDept.getId() : null;
|
||||
baseEmployee.setLastDeptId(currentDeptId);
|
||||
|
||||
flag = currentDeptId != null;
|
||||
}
|
||||
flag = currentDeptId != null;
|
||||
}
|
||||
|
||||
BaseOrg defaultCompany;
|
||||
if (baseEmployee.getLastCompanyId() != null) {
|
||||
currentCompanyId = baseEmployee.getLastCompanyId();
|
||||
BaseOrg defaultCompany;
|
||||
if (baseEmployee.getLastCompanyId() != null) {
|
||||
currentCompanyId = baseEmployee.getLastCompanyId();
|
||||
|
||||
defaultCompany = baseOrgService.getByIdCache(currentCompanyId);
|
||||
} else {
|
||||
if (currentDeptId != null) {
|
||||
defaultCompany = baseOrgService.getCompanyByDeptId(currentDeptId);
|
||||
} else {
|
||||
// currentDeptId 为空,员工可能直接挂在单位下、也可能挂不属于任何部门
|
||||
List<BaseOrg> companyList = baseOrgService.findCompanyByEmployeeId(uid);
|
||||
defaultCompany = baseOrgService.getDefaultOrg(companyList, baseEmployee.getLastCompanyId());
|
||||
}
|
||||
defaultCompany = baseOrgService.getByIdCache(currentCompanyId);
|
||||
} else {
|
||||
if (currentDeptId != null) {
|
||||
defaultCompany = baseOrgService.getCompanyByDeptId(currentDeptId);
|
||||
} else {
|
||||
// currentDeptId 为空,员工可能直接挂在单位下、也可能挂不属于任何部门
|
||||
List<BaseOrg> companyList = baseOrgService.findCompanyByEmployeeId(uid);
|
||||
defaultCompany = baseOrgService.getDefaultOrg(companyList, baseEmployee.getLastCompanyId());
|
||||
}
|
||||
|
||||
currentCompanyId = defaultCompany != null ? defaultCompany.getId() : null;
|
||||
baseEmployee.setLastCompanyId(currentCompanyId);
|
||||
flag = flag || currentCompanyId != null;
|
||||
currentCompanyId = defaultCompany != null ? defaultCompany.getId() : null;
|
||||
baseEmployee.setLastCompanyId(currentCompanyId);
|
||||
flag = flag || currentCompanyId != null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (defaultCompany != null) {
|
||||
Long rootId = TreeUtil.getTopNodeId(defaultCompany.getTreePath());
|
||||
BaseOrg rootCompany;
|
||||
if (rootId != null) {
|
||||
rootCompany = baseOrgService.getByIdCache(rootId);
|
||||
} else {
|
||||
rootCompany = defaultCompany;
|
||||
}
|
||||
currentTopCompanyId = rootCompany != null ? rootCompany.getId() : null;
|
||||
}
|
||||
if (defaultCompany != null) {
|
||||
Long rootId = TreeUtil.getTopNodeId(defaultCompany.getTreePath());
|
||||
BaseOrg rootCompany;
|
||||
if (rootId != null) {
|
||||
rootCompany = baseOrgService.getByIdCache(rootId);
|
||||
} else {
|
||||
rootCompany = defaultCompany;
|
||||
}
|
||||
currentTopCompanyId = rootCompany != null ? rootCompany.getId() : null;
|
||||
}
|
||||
|
||||
if (flag) {
|
||||
baseEmployeeService.updateById(baseEmployee);
|
||||
}
|
||||
}
|
||||
return Org.builder()
|
||||
.currentTopCompanyId(currentTopCompanyId)
|
||||
.currentCompanyId(currentCompanyId)
|
||||
.currentDeptId(currentDeptId).build();
|
||||
}
|
||||
if (flag) {
|
||||
baseEmployeeService.updateById(baseEmployee);
|
||||
}
|
||||
}
|
||||
return Org.builder()
|
||||
.currentTopCompanyId(currentTopCompanyId)
|
||||
.currentCompanyId(currentCompanyId)
|
||||
.currentDeptId(currentDeptId).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建返回值
|
||||
*
|
||||
* @param userInfo 员工信息
|
||||
* @param org 机构信息
|
||||
/**
|
||||
* 构建返回值
|
||||
*
|
||||
* @param userInfo 员工信息
|
||||
* @param org 机构信息
|
||||
* @param deviceType 登录设备
|
||||
* @param clientId 设备指纹
|
||||
* @return com.luohuo.flex.oauth.vo.result.LoginResultVO
|
||||
* @author 乾乾
|
||||
*/
|
||||
protected LoginResultVO buildResult(Long uid, DefUser userInfo, Org org, String deviceType, String clientId) {
|
||||
* @return com.luohuo.flex.oauth.vo.result.LoginResultVO
|
||||
* @author 乾乾
|
||||
*/
|
||||
protected LoginResultVO buildResult(Long uid, DefUser userInfo, Org org, String deviceType, String clientId) {
|
||||
// 0. 处理同设备登录用户
|
||||
String combinedDeviceType = kickout(uid, userInfo, deviceType);
|
||||
|
||||
@@ -385,31 +385,31 @@ public abstract class AbstractTokenGranter implements TokenGranter {
|
||||
StpUtil.login(loginId, combinedDeviceType);
|
||||
|
||||
// 2. 配置登录设备、租户信息等等
|
||||
SaSession tokenSession = StpUtil.getTokenSession();
|
||||
tokenSession.setLoginId(userInfo.getId());
|
||||
SaSession tokenSession = StpUtil.getTokenSession();
|
||||
tokenSession.setLoginId(userInfo.getId());
|
||||
tokenSession.set(JWT_KEY_SYSTEM_TYPE, userInfo.getSystemType());
|
||||
tokenSession.set(JWT_KEY_DEVICE, deviceType);
|
||||
tokenSession.set(CLIENT_ID, clientId);
|
||||
if (org.getCurrentTopCompanyId() != null) {
|
||||
tokenSession.set(JWT_KEY_TOP_COMPANY_ID, org.getCurrentTopCompanyId());
|
||||
} else {
|
||||
tokenSession.delete(JWT_KEY_TOP_COMPANY_ID);
|
||||
}
|
||||
if (org.getCurrentCompanyId() != null) {
|
||||
tokenSession.set(JWT_KEY_COMPANY_ID, org.getCurrentCompanyId());
|
||||
} else {
|
||||
tokenSession.delete(JWT_KEY_COMPANY_ID);
|
||||
}
|
||||
if (org.getCurrentDeptId() != null) {
|
||||
tokenSession.set(JWT_KEY_DEPT_ID, org.getCurrentDeptId());
|
||||
} else {
|
||||
tokenSession.delete(JWT_KEY_DEPT_ID);
|
||||
}
|
||||
if (userInfo.getId() != null) {
|
||||
tokenSession.set(JWT_KEY_U_ID, uid);
|
||||
} else {
|
||||
tokenSession.delete(JWT_KEY_U_ID);
|
||||
}
|
||||
if (org.getCurrentTopCompanyId() != null) {
|
||||
tokenSession.set(JWT_KEY_TOP_COMPANY_ID, org.getCurrentTopCompanyId());
|
||||
} else {
|
||||
tokenSession.delete(JWT_KEY_TOP_COMPANY_ID);
|
||||
}
|
||||
if (org.getCurrentCompanyId() != null) {
|
||||
tokenSession.set(JWT_KEY_COMPANY_ID, org.getCurrentCompanyId());
|
||||
} else {
|
||||
tokenSession.delete(JWT_KEY_COMPANY_ID);
|
||||
}
|
||||
if (org.getCurrentDeptId() != null) {
|
||||
tokenSession.set(JWT_KEY_DEPT_ID, org.getCurrentDeptId());
|
||||
} else {
|
||||
tokenSession.delete(JWT_KEY_DEPT_ID);
|
||||
}
|
||||
if (userInfo.getId() != null) {
|
||||
tokenSession.set(JWT_KEY_U_ID, uid);
|
||||
} else {
|
||||
tokenSession.delete(JWT_KEY_U_ID);
|
||||
}
|
||||
if (userInfo.getTenantId() != null) {
|
||||
tokenSession.set(HEADER_TENANT_ID, userInfo.getTenantId());
|
||||
} else {
|
||||
@@ -424,17 +424,17 @@ public abstract class AbstractTokenGranter implements TokenGranter {
|
||||
tokenSession.set("roleList", roleList);
|
||||
}
|
||||
|
||||
LoginResultVO resultVO = new LoginResultVO();
|
||||
resultVO.setToken(StpUtil.getTokenValue());
|
||||
LoginResultVO resultVO = new LoginResultVO();
|
||||
resultVO.setToken(StpUtil.getTokenValue());
|
||||
resultVO.setClient(deviceType);
|
||||
resultVO.setExpire(Long.valueOf(StpUtil.getTokenTimeout()));
|
||||
resultVO.setExpire(Long.valueOf(StpUtil.getTokenTimeout()));
|
||||
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.set(JWT_KEY_USER_ID, userInfo.getId());
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.set(JWT_KEY_USER_ID, userInfo.getId());
|
||||
obj.set(JWT_KEY_U_ID, uid);
|
||||
obj.set(JWT_KEY_DEVICE, deviceType);
|
||||
obj.set(JWT_KEY_SYSTEM_TYPE, userInfo.getSystemType());
|
||||
obj.set(HEADER_TENANT_ID, userInfo.getTenantId());
|
||||
obj.set(HEADER_TENANT_ID, userInfo.getTenantId());
|
||||
ContextUtil.setTenantId(userInfo.getTenantId());
|
||||
|
||||
// 后台系统才需要
|
||||
@@ -446,11 +446,11 @@ public abstract class AbstractTokenGranter implements TokenGranter {
|
||||
|
||||
resultVO.setUid(uid);
|
||||
obj.set(CLIENT_ID, clientId);
|
||||
resultVO.setRefreshToken(SaTempUtil.createToken(obj.toString(), 2 * saTokenConfig.getTimeout()));
|
||||
resultVO.setRefreshToken(SaTempUtil.createToken(obj.toString(), 2 * saTokenConfig.getTimeout()));
|
||||
|
||||
log.info("用户:{} 登录成功", userInfo.getUsername());
|
||||
return resultVO;
|
||||
}
|
||||
log.info("用户:{} 登录成功", userInfo.getUsername());
|
||||
return resultVO;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理挤下线的逻辑
|
||||
@@ -502,8 +502,8 @@ public abstract class AbstractTokenGranter implements TokenGranter {
|
||||
* 退出登录时 临时token还存在
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public R<Boolean> logout() {
|
||||
@Override
|
||||
public R<Boolean> logout() {
|
||||
try {
|
||||
String tokenValue = StpUtil.getTokenValue();
|
||||
String deviceType = StpUtil.getLoginDevice();
|
||||
@@ -535,95 +535,96 @@ public abstract class AbstractTokenGranter implements TokenGranter {
|
||||
log.debug("Token已失效,无需清理");
|
||||
throw TokenExceedException.expired();
|
||||
}
|
||||
return R.success(true);
|
||||
}
|
||||
return R.success(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoginResultVO switchOrg(Long orgId, String clientId) {
|
||||
StpUtil.checkLogin();
|
||||
Long userId = ContextUtil.getUserId();
|
||||
DefUser defUser = defUserService.getByIdCache(userId);
|
||||
if (defUser == null) {
|
||||
throw UnauthorizedException.wrap(ResponseEnum.JWT_TOKEN_EXPIRED);
|
||||
}
|
||||
@Override
|
||||
public LoginResultVO switchOrg(Long orgId, String clientId) {
|
||||
StpUtil.checkLogin();
|
||||
Long userId = ContextUtil.getUserId();
|
||||
DefUser defUser = defUserService.getByIdCache(userId);
|
||||
if (defUser == null) {
|
||||
throw UnauthorizedException.wrap(ResponseEnum.JWT_TOKEN_EXPIRED);
|
||||
}
|
||||
|
||||
if (!Convert.toBool(defUser.getState(), Boolean.valueOf(true))) {
|
||||
throw UnauthorizedException.wrap(ResponseEnum.JWT_USER_DISABLE);
|
||||
}
|
||||
if (!Convert.toBool(defUser.getState(), Boolean.valueOf(true))) {
|
||||
throw UnauthorizedException.wrap(ResponseEnum.JWT_USER_DISABLE);
|
||||
}
|
||||
|
||||
BaseEmployee employee = baseEmployeeService.getEmployeeByUser(userId);
|
||||
ArgumentAssert.notNull(employee, "您不属于该公司,无法切换");
|
||||
if (!Convert.toBool(employee.getState(), Boolean.valueOf(true))) {
|
||||
throw BizException.wrap(ResponseEnum.JWT_EMPLOYEE_DISABLE);
|
||||
}
|
||||
BaseEmployee employee = baseEmployeeService.getEmployeeByUser(userId);
|
||||
ArgumentAssert.notNull(employee, "您不属于该公司,无法切换");
|
||||
if (!Convert.toBool(employee.getState(), Boolean.valueOf(true))) {
|
||||
throw BizException.wrap(ResponseEnum.JWT_EMPLOYEE_DISABLE);
|
||||
}
|
||||
|
||||
Long topCompanyId = null;
|
||||
Long companyId = null;
|
||||
Long deptId = null;
|
||||
if (orgId != null) {
|
||||
BaseOrg selectOrg = baseOrgService.getByIdCache(orgId);
|
||||
ArgumentAssert.notNull(selectOrg, "该部门不存在");
|
||||
Long companyId = null;
|
||||
Long deptId = null;
|
||||
if (orgId != null) {
|
||||
BaseOrg selectOrg = baseOrgService.getByIdCache(orgId);
|
||||
ArgumentAssert.notNull(selectOrg, "该部门不存在");
|
||||
|
||||
if (OrgTypeEnum.COMPANY.eq(selectOrg.getType())) {
|
||||
companyId = selectOrg.getId();
|
||||
if (OrgTypeEnum.COMPANY.eq(selectOrg.getType())) {
|
||||
companyId = selectOrg.getId();
|
||||
|
||||
Long rootId = TreeUtil.getTopNodeId(selectOrg.getTreePath());
|
||||
if (rootId != null) {
|
||||
BaseOrg rootCompany = baseOrgService.getByIdCache(rootId);
|
||||
topCompanyId = rootCompany != null ? rootCompany.getId() : companyId;
|
||||
} else {
|
||||
topCompanyId = companyId;
|
||||
}
|
||||
} else {
|
||||
deptId = selectOrg.getId();
|
||||
Long rootId = TreeUtil.getTopNodeId(selectOrg.getTreePath());
|
||||
if (rootId != null) {
|
||||
BaseOrg rootCompany = baseOrgService.getByIdCache(rootId);
|
||||
topCompanyId = rootCompany != null ? rootCompany.getId() : companyId;
|
||||
} else {
|
||||
topCompanyId = companyId;
|
||||
}
|
||||
} else {
|
||||
deptId = selectOrg.getId();
|
||||
|
||||
BaseOrg company = baseOrgService.getCompanyByDeptId(deptId);
|
||||
if (company != null) {
|
||||
companyId = company.getId();
|
||||
BaseOrg company = baseOrgService.getCompanyByDeptId(deptId);
|
||||
if (company != null) {
|
||||
companyId = company.getId();
|
||||
|
||||
Long rootId = TreeUtil.getTopNodeId(company.getTreePath());
|
||||
if (rootId != null) {
|
||||
BaseOrg rootCompany = baseOrgService.getByIdCache(rootId);
|
||||
topCompanyId = rootCompany != null ? rootCompany.getId() : companyId;
|
||||
} else {
|
||||
topCompanyId = companyId;
|
||||
}
|
||||
}
|
||||
}
|
||||
Long rootId = TreeUtil.getTopNodeId(company.getTreePath());
|
||||
if (rootId != null) {
|
||||
BaseOrg rootCompany = baseOrgService.getByIdCache(rootId);
|
||||
topCompanyId = rootCompany != null ? rootCompany.getId() : companyId;
|
||||
} else {
|
||||
topCompanyId = companyId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
baseEmployeeService.updateOrgInfo(employee.getId(), companyId, deptId);
|
||||
} else {
|
||||
baseEmployeeService.updateOrgInfo(employee.getId(), companyId, deptId);
|
||||
}
|
||||
baseEmployeeService.updateOrgInfo(employee.getId(), companyId, deptId);
|
||||
} else {
|
||||
baseEmployeeService.updateOrgInfo(employee.getId(), companyId, deptId);
|
||||
}
|
||||
|
||||
Org org = Org.builder()
|
||||
.currentTopCompanyId(topCompanyId)
|
||||
.currentCompanyId(companyId)
|
||||
.currentDeptId(deptId)
|
||||
.build();
|
||||
Org org = Org.builder()
|
||||
.currentTopCompanyId(topCompanyId)
|
||||
.currentCompanyId(companyId)
|
||||
.currentDeptId(deptId)
|
||||
.build();
|
||||
|
||||
LoginResultVO loginResultVO = buildResult(ContextUtil.getUid(), defUser, org, StpUtil.getLoginType(), clientId);
|
||||
String deviceType = StpUtil.getTokenSession().getString(JWT_KEY_DEVICE);
|
||||
LoginResultVO loginResultVO = buildResult(ContextUtil.getUid(), defUser, org, deviceType, clientId);
|
||||
|
||||
LoginStatusDTO loginStatus = LoginStatusDTO.switchOrg(defUser.getId(), employee.getId());
|
||||
SpringUtils.publishEvent(new LoginEvent(loginStatus));
|
||||
return loginResultVO;
|
||||
}
|
||||
LoginStatusDTO loginStatus = LoginStatusDTO.switchOrg(defUser.getId(), employee.getId());
|
||||
SpringUtils.publishEvent(new LoginEvent(loginStatus));
|
||||
return loginResultVO;
|
||||
}
|
||||
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
private static class Employee {
|
||||
private Long employeeId;
|
||||
}
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
private static class Employee {
|
||||
private Long employeeId;
|
||||
}
|
||||
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
@NoArgsConstructor
|
||||
private static class Org {
|
||||
private Long currentCompanyId;
|
||||
private Long currentTopCompanyId;
|
||||
private Long currentDeptId;
|
||||
}
|
||||
private static class Org {
|
||||
private Long currentCompanyId;
|
||||
private Long currentTopCompanyId;
|
||||
private Long currentDeptId;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
package com.luohuo.flex;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.luohuo.basic.base.R;
|
||||
import com.luohuo.flex.service.SysConfigService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import java.util.Base64;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/anyTenant/map")
|
||||
@Tag(name = "腾讯地图代理")
|
||||
@RequiredArgsConstructor
|
||||
public class MapController {
|
||||
|
||||
private final SysConfigService sysConfigService;
|
||||
@Resource(name = "restTemplate")
|
||||
private RestTemplate restTemplate;
|
||||
|
||||
@GetMapping("/coord/translate")
|
||||
@Operation(summary = "坐标转换 WGS84->GCJ-02")
|
||||
public R<JSONObject> coordTranslate(@RequestParam("lat") double lat,
|
||||
@RequestParam("lng") double lng) {
|
||||
String key = sysConfigService.get("tencentMapKey");
|
||||
String url = "https://apis.map.qq.com/ws/coord/v1/translate?locations=" + lat + "," + lng + "&type=1&key=" + key;
|
||||
String resp = restTemplate.getForObject(url, String.class);
|
||||
JSONObject json = JSON.parseObject(resp == null ? "{}" : resp);
|
||||
if (json.getIntValue("status") == 0) {
|
||||
var arr = json.getJSONArray("locations");
|
||||
var loc = arr != null && !arr.isEmpty() ? arr.getJSONObject(0) : new JSONObject();
|
||||
JSONObject data = new JSONObject();
|
||||
data.put("lat", loc.getDouble("lat"));
|
||||
data.put("lng", loc.getDouble("lng"));
|
||||
return R.success(data);
|
||||
}
|
||||
JSONObject err = new JSONObject();
|
||||
err.put("status", json.getIntValue("status"));
|
||||
err.put("message", json.getString("message"));
|
||||
return R.success(err);
|
||||
}
|
||||
|
||||
@GetMapping("/geocoder/reverse")
|
||||
@Operation(summary = "逆地理编码")
|
||||
public R<JSONObject> reverseGeocode(@RequestParam("lat") double lat,
|
||||
@RequestParam("lng") double lng) {
|
||||
String key = sysConfigService.get("tencentMapKey");
|
||||
String url = "https://apis.map.qq.com/ws/geocoder/v1/?location=" + lat + "," + lng + "&key=" + key + "&get_poi=1";
|
||||
String resp = restTemplate.getForObject(url, String.class);
|
||||
JSONObject json = JSON.parseObject(resp == null ? "{}" : resp);
|
||||
if (json.getIntValue("status") == 0) {
|
||||
return R.success(json.getJSONObject("result"));
|
||||
}
|
||||
JSONObject err = new JSONObject();
|
||||
err.put("status", json.getIntValue("status"));
|
||||
err.put("message", json.getString("message"));
|
||||
return R.success(err);
|
||||
}
|
||||
|
||||
@GetMapping(value = "/static", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@Operation(summary = "静态地图图片")
|
||||
public R<JSONObject> staticMap(@RequestParam("lat") double lat,
|
||||
@RequestParam("lng") double lng,
|
||||
@RequestParam(value = "zoom", required = false, defaultValue = "18") int zoom,
|
||||
@RequestParam(value = "width", required = false, defaultValue = "600") int width,
|
||||
@RequestParam(value = "height", required = false, defaultValue = "400") int height) {
|
||||
String key = sysConfigService.get("tencentMapKey");
|
||||
String size = width + "*" + height;
|
||||
String url = "https://apis.map.qq.com/ws/staticmap/v2/?center=" + lat + "," + lng + "&zoom=" + zoom + "&size=" + size + "&format=png&key=" + key + "&markers=size:large|color:blue|label:A|" + lat + "," + lng;
|
||||
byte[] bytes = restTemplate.getForObject(url, byte[].class);
|
||||
String base64 = bytes == null ? "" : Base64.getEncoder().encodeToString(bytes);
|
||||
JSONObject data = new JSONObject();
|
||||
data.put("dataUrl", StringUtils.hasText(base64) ? ("data:image/png;base64," + base64) : "");
|
||||
return R.success(data);
|
||||
}
|
||||
}
|
||||
@@ -53,10 +53,19 @@ public final class JsonUtil {
|
||||
if (StrUtil.isEmpty(content)) {
|
||||
return null;
|
||||
}
|
||||
String s = content.trim();
|
||||
boolean jsonLike = StrUtil.startWith(s, "{") || StrUtil.startWith(s, "[");
|
||||
try {
|
||||
if (jsonLike) {
|
||||
return getInstance().readValue(s, valueType);
|
||||
}
|
||||
return getInstance().convertValue(content, valueType);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
try {
|
||||
return getInstance().readValue(s, valueType);
|
||||
} catch (Exception e2) {
|
||||
log.error(e2.getMessage(), e2);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -65,23 +74,81 @@ public final class JsonUtil {
|
||||
if (StrUtil.isEmpty(content)) {
|
||||
return null;
|
||||
}
|
||||
return getInstance().convertValue(content, typeReference);
|
||||
}
|
||||
String s = content.trim();
|
||||
boolean jsonLike = StrUtil.startWith(s, "{") || StrUtil.startWith(s, "[");
|
||||
try {
|
||||
if (jsonLike) {
|
||||
return getInstance().readValue(s, typeReference);
|
||||
}
|
||||
return getInstance().convertValue(content, typeReference);
|
||||
} catch (Exception e) {
|
||||
try {
|
||||
return getInstance().readValue(s, typeReference);
|
||||
} catch (Exception e2) {
|
||||
log.error(e2.getMessage(), e2);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static <T> T parseJson(String content, Class<T> valueType) {
|
||||
if (StrUtil.isEmpty(content)) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return getInstance().readValue(content, valueType);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static <T> T parseJson(String content, TypeReference<T> typeReference) {
|
||||
if (StrUtil.isEmpty(content)) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return getInstance().readValue(content, typeReference);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static <T> T parse(byte[] bytes, Class<T> valueType) {
|
||||
return getInstance().convertValue(bytes, valueType);
|
||||
try {
|
||||
return getInstance().readValue(bytes, valueType);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static <T> T parse(byte[] bytes, TypeReference<T> typeReference) {
|
||||
return getInstance().convertValue(bytes, typeReference);
|
||||
try {
|
||||
return getInstance().readValue(bytes, typeReference);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static <T> T parse(InputStream in, Class<T> valueType) {
|
||||
return getInstance().convertValue(in, valueType);
|
||||
try {
|
||||
return getInstance().readValue(in, valueType);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static <T> T parse(InputStream in, TypeReference<T> typeReference) {
|
||||
return getInstance().convertValue(in, typeReference);
|
||||
try {
|
||||
return getInstance().readValue(in, typeReference);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -106,16 +173,24 @@ public final class JsonUtil {
|
||||
}
|
||||
|
||||
public static Map<String, Object> toMap(String content) {
|
||||
return getInstance().convertValue(content, Map.class);
|
||||
try {
|
||||
return getInstance().readValue(content, Map.class);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
public static <T> Map<String, T> toMap(String content, Class<T> valueTypeRef) {
|
||||
Map<String, Map<String, Object>> map = getInstance().convertValue(content, new TypeReference<>() {
|
||||
});
|
||||
Map<String, T> result = new HashMap<>(CollHelper.initialCapacity(map.size()));
|
||||
map.forEach((key, value) -> result.put(key, toPojo(value, valueTypeRef)));
|
||||
|
||||
return result;
|
||||
try {
|
||||
Map<String, Map<String, Object>> map = getInstance().readValue(content, new TypeReference<>() {});
|
||||
Map<String, T> result = new HashMap<>(CollHelper.initialCapacity(map.size()));
|
||||
map.forEach((key, value) -> result.put(key, toPojo(value, valueTypeRef)));
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
public static <T> T toPojo(Map fromValue, Class<T> toValueType) {
|
||||
|
||||
BIN
preview/wx.png
BIN
preview/wx.png
Binary file not shown.
|
Before Width: | Height: | Size: 243 KiB After Width: | Height: | Size: 212 KiB |
Reference in New Issue
Block a user