diff --git a/CLAUDE.md b/CLAUDE.md index c35ebd5bc..d8339b17c 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -5,7 +5,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co ## Project Overview PigX is a proprietary enterprise-grade microservices platform built on Spring Cloud Alibaba, focusing on AI knowledge -management, document processing, and intelligent Q&A capabilities. The current version is 5.10.0. +management, document processing, and intelligent Q&A capabilities. The current version is 5.11.0. **Important**: This is NOT an open-source project. All rights reserved by the author. Commercial use requires proper licensing. @@ -13,8 +13,8 @@ licensing. ## Technology Stack - **Java Version**: Java 17 -- **Spring Boot**: 3.5.6 -- **Spring Cloud**: 2025.0.0 +- **Spring Boot**: 3.5.9 +- **Spring Cloud**: 2025.0.1 - **Spring Cloud Alibaba**: 2023.0.3.3 - **AI/ML Libraries**: - LangChain4j: 1.6.0 diff --git a/LICENSE b/LICENSE index a3640ace6..61149cbcb 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ - Copyright (c) 2018-2025, lengleng All rights reserved. + Copyright (c) 2018-2026, lengleng All rights reserved. 协议和授权 pigX并非一个开源软件,作者保留全部的权利。 diff --git a/db/0pigxx_boot.sql b/db/0pigxx_boot.sql index 4affc6981..4ddc85000 100644 --- a/db/0pigxx_boot.sql +++ b/db/0pigxx_boot.sql @@ -591,7 +591,7 @@ INSERT INTO `sys_menu` VALUES (2210,'参数管理',NULL,'/admin/param/index',NUL INSERT INTO `sys_menu` VALUES (2211,'参数新增','sys_syspublicparam_add',NULL,NULL,2210,NULL,'1',1,'0',NULL,'1',' ','2019-04-29 22:17:36',' ','2020-03-24 08:57:11','0',1); INSERT INTO `sys_menu` VALUES (2212,'参数删除','sys_syspublicparam_del',NULL,NULL,2210,NULL,'1',1,'0',NULL,'1',' ','2019-04-29 22:17:55',' ','2020-03-24 08:57:12','0',1); INSERT INTO `sys_menu` VALUES (2213,'参数编辑','sys_syspublicparam_edit',NULL,NULL,2210,NULL,'1',1,'0',NULL,'1',' ','2019-04-29 22:18:14',' ','2020-03-24 08:57:13','0',1); -INSERT INTO `sys_menu` VALUES (2214,'参数查看','sys_syspublicparam_edit',NULL,NULL,2210,NULL,'1',1,'0',NULL,'1',' ','2019-04-29 22:18:14',' ','2020-03-24 08:57:13','0',1); +INSERT INTO `sys_menu` VALUES (2214,'参数查看','sys_syspublicparam_view',NULL,NULL,2210,NULL,'1',1,'0',NULL,'1',' ','2019-04-29 22:18:14',' ','2020-03-24 08:57:13','0',1); INSERT INTO `sys_menu` VALUES (2300,'代码生成',NULL,'/gen/table/index',NULL,9000,'iconfont icon-daimashengcheng','1',2,'0','0','0','','2018-01-20 13:17:19','admin','2023-02-20 13:54:35','0',1); INSERT INTO `sys_menu` VALUES (2400,'终端管理',NULL,'/admin/client/index',NULL,2000,'iconfont icon-shouji','1',9,'1',NULL,'0','','2018-01-20 13:17:19','admin','2023-02-16 15:25:28','0',1); INSERT INTO `sys_menu` VALUES (2401,'客户端新增','sys_client_add',NULL,NULL,2400,'1','1',1,'0',NULL,'1',' ','2018-05-15 21:35:18',' ','2021-05-25 03:12:55','0',1); @@ -1311,7 +1311,7 @@ CREATE TABLE `sys_tenant` ( -- Records of sys_tenant -- ---------------------------- BEGIN; -INSERT INTO `sys_tenant` VALUES (1, '北京分公司', '1', '', NULL, NULL, NULL, NULL, NULL, '2019-05-15 00:00:00', '2099-12-31 00:00:00', '0', '0', '', 'admin', '2019-05-15 15:44:57', '2023-07-30 14:52:57', 1642752536722997250); +INSERT INTO `sys_tenant` VALUES (1, 'PIGX ADMIN', '1', '', NULL, NULL, NULL, NULL, NULL, '2019-05-15 00:00:00', '2099-12-31 00:00:00', '0', '0', '', 'admin', '2019-05-15 15:44:57', '2023-07-30 14:52:57', 1642752536722997250); COMMIT; @@ -1344,6 +1344,7 @@ CREATE TABLE `sys_user` ( `osc_id` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '开源中国标识', `wx_cp_userid` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '企业微信唯一ID', `wx_ding_userid` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '钉钉唯一ID', + `dept_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '主部门ID', `tenant_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '所属租户ID', PRIMARY KEY (`user_id`) USING BTREE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='用户表'; @@ -1352,7 +1353,7 @@ CREATE TABLE `sys_user` ( -- Records of sys_user -- ---------------------------- BEGIN; -INSERT INTO `sys_user` VALUES (1, 'admin', '$2a$10$c/Ae0pRjJtMZg3BnvVpO.eIK6WYWVbKTzqgdy3afR7w.vd.xi3Mgy', '', '17338122125', '/admin/sys-file/local/2a14ae08150e483c93e12ac8934173e2.png', '管理员666777', '管理员', 'sw@mail.pigxl.vip', ' ', 'admin', '2018-04-20 07:15:18', '2023-04-03 14:00:06', '0', '0', NULL, '0', NULL, 'oBxPy5E-v82xWGsfzZVzkD3wEX64', NULL, 'log4j', NULL, NULL,NULL,1); +INSERT INTO `sys_user` VALUES (1, 'admin', '$2a$10$c/Ae0pRjJtMZg3BnvVpO.eIK6WYWVbKTzqgdy3afR7w.vd.xi3Mgy', '', '17338122125', '/admin/sys-file/local/2a14ae08150e483c93e12ac8934173e2.png', '管理员666777', '管理员', 'sw@mail.pigxl.vip', ' ', 'admin', '2018-04-20 07:15:18', '2023-04-03 14:00:06', '0', '0', NULL, '0', NULL, 'oBxPy5E-v82xWGsfzZVzkD3wEX64', NULL, 'log4j', NULL, NULL,NULL,1,1); COMMIT; -- ---------------------------- diff --git a/db/2pigxx.sql b/db/2pigxx.sql index 7e20a2529..b7e8084f9 100644 --- a/db/2pigxx.sql +++ b/db/2pigxx.sql @@ -573,7 +573,7 @@ INSERT INTO `sys_menu` VALUES (2210,'参数管理',NULL,'/admin/param/index',NUL INSERT INTO `sys_menu` VALUES (2211,'参数新增','sys_syspublicparam_add',NULL,NULL,2210,NULL,'1',1,'0',NULL,'1',' ','2019-04-29 22:17:36',' ','2020-03-24 08:57:11','0',1); INSERT INTO `sys_menu` VALUES (2212,'参数删除','sys_syspublicparam_del',NULL,NULL,2210,NULL,'1',1,'0',NULL,'1',' ','2019-04-29 22:17:55',' ','2020-03-24 08:57:12','0',1); INSERT INTO `sys_menu` VALUES (2213,'参数编辑','sys_syspublicparam_edit',NULL,NULL,2210,NULL,'1',1,'0',NULL,'1',' ','2019-04-29 22:18:14',' ','2020-03-24 08:57:13','0',1); -INSERT INTO `sys_menu` VALUES (2214,'参数查看','sys_syspublicparam_edit',NULL,NULL,2210,NULL,'1',1,'0',NULL,'1',' ','2019-04-29 22:18:14',' ','2020-03-24 08:57:13','0',1); +INSERT INTO `sys_menu` VALUES (2214,'参数查看','sys_syspublicparam_view',NULL,NULL,2210,NULL,'1',1,'0',NULL,'1',' ','2019-04-29 22:18:14',' ','2020-03-24 08:57:13','0',1); INSERT INTO `sys_menu` VALUES (2300,'代码生成',NULL,'/gen/table/index',NULL,9000,'iconfont icon-daimashengcheng','1',2,'0','0','0','','2018-01-20 13:17:19','admin','2023-02-20 13:54:35','0',1); INSERT INTO `sys_menu` VALUES (2400,'终端管理',NULL,'/admin/client/index',NULL,2000,'iconfont icon-shouji','1',9,'1',NULL,'0','','2018-01-20 13:17:19','admin','2023-02-16 15:25:28','0',1); INSERT INTO `sys_menu` VALUES (2401,'客户端新增','sys_client_add',NULL,NULL,2400,'1','1',1,'0',NULL,'1',' ','2018-05-15 21:35:18',' ','2021-05-25 03:12:55','0',1); @@ -1295,7 +1295,7 @@ CREATE TABLE `sys_tenant` ( -- Records of sys_tenant -- ---------------------------- BEGIN; -INSERT INTO `sys_tenant` VALUES (1, '北京分公司', '1', '', NULL, NULL, NULL, NULL, NULL, '2019-05-15 00:00:00', '2099-12-31 00:00:00', '0', '0', '', 'admin', '2019-05-15 15:44:57', '2023-07-30 14:52:57', 1642752536722997250); +INSERT INTO `sys_tenant` VALUES (1, 'PIGX ADMIN', '1', '', NULL, NULL, NULL, NULL, NULL, '2019-05-15 00:00:00', '2099-12-31 00:00:00', '0', '0', '', 'admin', '2019-05-15 15:44:57', '2023-07-30 14:52:57', 1642752536722997250); COMMIT; @@ -1328,6 +1328,7 @@ CREATE TABLE `sys_user` ( `osc_id` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '开源中国标识', `wx_cp_userid` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '企业微信唯一ID', `wx_ding_userid` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '钉钉唯一ID', + `dept_id` bigint(20) DEFAULT NULL COMMENT '主部门ID', `tenant_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '所属租户ID', PRIMARY KEY (`user_id`) USING BTREE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='用户表'; @@ -1336,7 +1337,7 @@ CREATE TABLE `sys_user` ( -- Records of sys_user -- ---------------------------- BEGIN; -INSERT INTO `sys_user` VALUES (1, 'admin', '$2a$10$c/Ae0pRjJtMZg3BnvVpO.eIK6WYWVbKTzqgdy3afR7w.vd.xi3Mgy', '', '17338122125', '/admin/sys-file/local/2a14ae08150e483c93e12ac8934173e2.png', '管理员666777', '管理员', 'sw@mail.pigxl.vip', ' ', 'admin', '2018-04-20 07:15:18', '2023-04-03 14:00:06', '0', '0', NULL, '0', NULL, 'oBxPy5E-v82xWGsfzZVzkD3wEX64', NULL, 'log4j', NULL, NULL,NULL,1); +INSERT INTO `sys_user` VALUES (1, 'admin', '$2a$10$c/Ae0pRjJtMZg3BnvVpO.eIK6WYWVbKTzqgdy3afR7w.vd.xi3Mgy', '', '17338122125', '/admin/sys-file/local/2a14ae08150e483c93e12ac8934173e2.png', '管理员666777', '管理员', 'sw@mail.pigxl.vip', ' ', 'admin', '2018-04-20 07:15:18', '2023-04-03 14:00:06', '0', '0', NULL, '0', NULL, 'oBxPy5E-v82xWGsfzZVzkD3wEX64', NULL, 'log4j', NULL, NULL,NULL,1,1); COMMIT; -- ---------------------------- diff --git a/pigx-app-server/pigx-app-server-api/pom.xml b/pigx-app-server/pigx-app-server-api/pom.xml index ab037f89b..547542226 100644 --- a/pigx-app-server/pigx-app-server-api/pom.xml +++ b/pigx-app-server/pigx-app-server-api/pom.xml @@ -7,7 +7,7 @@ com.pig4cloud pigx-app-server - 5.10.0 + 5.11.0 pigx-app-server-api diff --git a/pigx-app-server/pigx-app-server-api/src/main/java/com/pig4cloud/pigx/app/api/dto/AppUserInfo.java b/pigx-app-server/pigx-app-server-api/src/main/java/com/pig4cloud/pigx/app/api/dto/AppUserInfo.java index 68fd258bf..45ac2f48e 100644 --- a/pigx-app-server/pigx-app-server-api/src/main/java/com/pig4cloud/pigx/app/api/dto/AppUserInfo.java +++ b/pigx-app-server/pigx-app-server-api/src/main/java/com/pig4cloud/pigx/app/api/dto/AppUserInfo.java @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-app-server/pigx-app-server-api/src/main/java/com/pig4cloud/pigx/app/api/entity/AppRole.java b/pigx-app-server/pigx-app-server-api/src/main/java/com/pig4cloud/pigx/app/api/entity/AppRole.java index ec63649a6..df89ff0be 100644 --- a/pigx-app-server/pigx-app-server-api/src/main/java/com/pig4cloud/pigx/app/api/entity/AppRole.java +++ b/pigx-app-server/pigx-app-server-api/src/main/java/com/pig4cloud/pigx/app/api/entity/AppRole.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-app-server/pigx-app-server-api/src/main/java/com/pig4cloud/pigx/app/api/entity/AppSocialDetails.java b/pigx-app-server/pigx-app-server-api/src/main/java/com/pig4cloud/pigx/app/api/entity/AppSocialDetails.java index d5cba8300..c56e33c48 100644 --- a/pigx-app-server/pigx-app-server-api/src/main/java/com/pig4cloud/pigx/app/api/entity/AppSocialDetails.java +++ b/pigx-app-server/pigx-app-server-api/src/main/java/com/pig4cloud/pigx/app/api/entity/AppSocialDetails.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-app-server/pigx-app-server-api/src/main/java/com/pig4cloud/pigx/app/api/entity/AppUser.java b/pigx-app-server/pigx-app-server-api/src/main/java/com/pig4cloud/pigx/app/api/entity/AppUser.java index e19428144..98ea669e7 100644 --- a/pigx-app-server/pigx-app-server-api/src/main/java/com/pig4cloud/pigx/app/api/entity/AppUser.java +++ b/pigx-app-server/pigx-app-server-api/src/main/java/com/pig4cloud/pigx/app/api/entity/AppUser.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-app-server/pigx-app-server-api/src/main/java/com/pig4cloud/pigx/app/api/entity/AppUserRole.java b/pigx-app-server/pigx-app-server-api/src/main/java/com/pig4cloud/pigx/app/api/entity/AppUserRole.java index 1de90b88d..d560c0731 100644 --- a/pigx-app-server/pigx-app-server-api/src/main/java/com/pig4cloud/pigx/app/api/entity/AppUserRole.java +++ b/pigx-app-server/pigx-app-server-api/src/main/java/com/pig4cloud/pigx/app/api/entity/AppUserRole.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-app-server/pigx-app-server-api/src/main/java/com/pig4cloud/pigx/app/api/enums/AppErrorCodes.java b/pigx-app-server/pigx-app-server-api/src/main/java/com/pig4cloud/pigx/app/api/enums/AppErrorCodes.java new file mode 100644 index 000000000..7de762840 --- /dev/null +++ b/pigx-app-server/pigx-app-server-api/src/main/java/com/pig4cloud/pigx/app/api/enums/AppErrorCodes.java @@ -0,0 +1,28 @@ +package com.pig4cloud.pigx.app.api.enums; + +/** + * App Server 模块错误编码 + * + * @author lengleng + * @date 2022/3/30 + */ +public interface AppErrorCodes { + + // === App 用户相关 === + String APP_USER_USERINFO_EMPTY = "app.user.userInfo.empty"; + + String APP_USER_USERNAME_EXISTING = "app.user.username.existing"; + + String APP_USER_IMPORT_SUCCEED = "app.user.import.succeed"; + + String APP_USER_QUERY_ERROR = "app.user.query.error"; + + // === App 角色相关 === + String APP_ROLE_ROLENAME_INEXISTENCE = "app.role.roleName.inexistence"; + + String APP_ROLE_NAMEORCODE_EXISTING = "app.role.nameOrCode.existing"; + + // === App 短信相关 === + String APP_SMS_OFTEN = "app.sms.often"; + +} diff --git a/pigx-app-server/pigx-app-server-api/src/main/java/com/pig4cloud/pigx/app/api/feign/RemoteAppUserService.java b/pigx-app-server/pigx-app-server-api/src/main/java/com/pig4cloud/pigx/app/api/feign/RemoteAppUserService.java index efa4bdfe4..7605a9e56 100644 --- a/pigx-app-server/pigx-app-server-api/src/main/java/com/pig4cloud/pigx/app/api/feign/RemoteAppUserService.java +++ b/pigx-app-server/pigx-app-server-api/src/main/java/com/pig4cloud/pigx/app/api/feign/RemoteAppUserService.java @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-app-server/pigx-app-server-api/src/main/java/com/pig4cloud/pigx/app/api/vo/AppRoleExcelVO.java b/pigx-app-server/pigx-app-server-api/src/main/java/com/pig4cloud/pigx/app/api/vo/AppRoleExcelVO.java index 436d9e305..e642897e0 100644 --- a/pigx-app-server/pigx-app-server-api/src/main/java/com/pig4cloud/pigx/app/api/vo/AppRoleExcelVO.java +++ b/pigx-app-server/pigx-app-server-api/src/main/java/com/pig4cloud/pigx/app/api/vo/AppRoleExcelVO.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-app-server/pigx-app-server-api/src/main/java/com/pig4cloud/pigx/app/api/vo/AppRoleVO.java b/pigx-app-server/pigx-app-server-api/src/main/java/com/pig4cloud/pigx/app/api/vo/AppRoleVO.java index 89532b06d..bc2b70ece 100644 --- a/pigx-app-server/pigx-app-server-api/src/main/java/com/pig4cloud/pigx/app/api/vo/AppRoleVO.java +++ b/pigx-app-server/pigx-app-server-api/src/main/java/com/pig4cloud/pigx/app/api/vo/AppRoleVO.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-app-server/pigx-app-server-api/src/main/resources/i18n/messages_en.properties b/pigx-app-server/pigx-app-server-api/src/main/resources/i18n/messages_en.properties new file mode 100644 index 000000000..aef21848c --- /dev/null +++ b/pigx-app-server/pigx-app-server-api/src/main/resources/i18n/messages_en.properties @@ -0,0 +1,14 @@ +# App Server Module i18n Messages - English + +# App user related +app.user.userInfo.empty=App user information is empty for {0} +app.user.username.existing=Username {0} already exists +app.user.import.succeed=User import succeeded; default password is the phone number +app.user.query.error=Failed to fetch current user information + +# App role related +app.role.roleName.inexistence=Role name {0} does not exist +app.role.nameOrCode.existing=Role name or code already exists ({0} {1}) + +# App SMS related +app.sms.often=Verification code sent too frequently diff --git a/pigx-app-server/pigx-app-server-api/src/main/resources/i18n/messages_zh_CN.properties b/pigx-app-server/pigx-app-server-api/src/main/resources/i18n/messages_zh_CN.properties new file mode 100644 index 000000000..1fc97d12c --- /dev/null +++ b/pigx-app-server/pigx-app-server-api/src/main/resources/i18n/messages_zh_CN.properties @@ -0,0 +1,14 @@ +# App Server 模块国际化消息 - 中文 + +# App 用户相关 +app.user.userInfo.empty={0} \u7528\u6237\u4FE1\u606F\u4E3A\u7A7A +app.user.username.existing={0} \u7528\u6237\u540D\u5DF2\u5B58\u5728 +app.user.import.succeed=\u7528\u6237\u5BFC\u5165\u6210\u529F\uFF0C\u9ED8\u8BA4\u5BC6\u7801\u4E3A\u624B\u673A\u53F7 +app.user.query.error=\u83B7\u53D6\u5F53\u524D\u7528\u6237\u4FE1\u606F\u5931\u8D25 + +# App 角色相关 +app.role.roleName.inexistence={0} \u89D2\u8272\u540D\u79F0\u4E0D\u5B58\u5728 +app.role.nameOrCode.existing={0} {1} \u89D2\u8272\u540D\u6216\u89D2\u8272\u7F16\u7801\u5DF2\u7ECF\u5B58\u5728 + +# App 短信相关 +app.sms.often=\u9A8C\u8BC1\u7801\u53D1\u9001\u8FC7\u9891\u7E41 diff --git a/pigx-app-server/pigx-app-server-biz/pom.xml b/pigx-app-server/pigx-app-server-biz/pom.xml index a41acf635..e68ea2d37 100644 --- a/pigx-app-server/pigx-app-server-biz/pom.xml +++ b/pigx-app-server/pigx-app-server-biz/pom.xml @@ -7,7 +7,7 @@ com.pig4cloud pigx-app-server - 5.10.0 + 5.11.0 pigx-app-server-biz @@ -112,9 +112,6 @@ repackage - - CLASSIC - diff --git a/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/controller/AppMobileController.java b/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/controller/AppMobileController.java index 9b93c5ebd..8612179b9 100644 --- a/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/controller/AppMobileController.java +++ b/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/controller/AppMobileController.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/controller/AppRoleController.java b/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/controller/AppRoleController.java index fbac78ae6..d4afe10be 100644 --- a/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/controller/AppRoleController.java +++ b/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/controller/AppRoleController.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/controller/AppSocialDetailsController.java b/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/controller/AppSocialDetailsController.java index dc8d6c5ea..c3d207be7 100644 --- a/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/controller/AppSocialDetailsController.java +++ b/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/controller/AppSocialDetailsController.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/controller/AppUserController.java b/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/controller/AppUserController.java index 9ccb5162f..a9e5f0cd7 100644 --- a/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/controller/AppUserController.java +++ b/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/controller/AppUserController.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -21,11 +21,11 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.pig4cloud.pigx.app.api.dto.AppUserDTO; import com.pig4cloud.pigx.app.api.entity.AppUser; +import com.pig4cloud.pigx.app.api.enums.AppErrorCodes; import com.pig4cloud.pigx.app.api.vo.AppUserExcelVO; import com.pig4cloud.pigx.app.service.AppUserService; import com.pig4cloud.pigx.common.core.constant.CommonConstants; import com.pig4cloud.pigx.common.core.constant.enums.UserTypeEnum; -import com.pig4cloud.pigx.common.core.exception.ErrorCodes; import com.pig4cloud.pigx.common.core.util.MsgUtils; import com.pig4cloud.pigx.common.core.util.R; import com.pig4cloud.pigx.common.excel.annotation.RequestExcel; @@ -58,150 +58,158 @@ import java.util.List; @SecurityRequirement(name = HttpHeaders.AUTHORIZATION) public class AppUserController { - private final AppUserService appUserService; + private final AppUserService appUserService; - @Inner - @GetMapping("/info/{username}") - public R info(@PathVariable String username) { - AppUser user = appUserService.getOne(Wrappers.query() - .lambda() - .eq(AppUser::getUsername, username) - .or() - .eq(AppUser::getPhone, username)); - if (user == null) { - return R.failed(MsgUtils.getMessage(ErrorCodes.APP_USER_USERINFO_EMPTY, username)); - } - return R.ok(appUserService.findUserInfo(user)); - } + @Inner + @GetMapping("/info/{username}") + public R info(@PathVariable String username) { + AppUser user = appUserService.getOne(Wrappers.query() + .lambda() + .eq(AppUser::getUsername, username) + .or() + .eq(AppUser::getPhone, username)); + if (user == null) { + return R.failed(MsgUtils.getMessage(AppErrorCodes.APP_USER_USERINFO_EMPTY, username)); + } + return R.ok(appUserService.findUserInfo(user)); + } - /** - * 获取当前用户全部信息 - * @return 用户信息 - */ - @GetMapping(value = { "/info" }) - public R info() { - String username = SecurityUtils.getUser().getUsername(); - AppUser user = appUserService.getOne(Wrappers.query().lambda().eq(AppUser::getUsername, username)); - if (user == null) { - return R.failed(MsgUtils.getMessage(ErrorCodes.SYS_USER_QUERY_ERROR)); - } - return R.ok(appUserService.findUserInfo(user)); - } + /** + * 获取当前用户全部信息 + * + * @return 用户信息 + */ + @GetMapping(value = {"/info"}) + public R info() { + String username = SecurityUtils.getUser().getUsername(); + AppUser user = appUserService.getOne(Wrappers.query().lambda().eq(AppUser::getUsername, username)); + if (user == null) { + return R.failed(MsgUtils.getMessage(AppErrorCodes.APP_USER_QUERY_ERROR)); + } + return R.ok(appUserService.findUserInfo(user)); + } - /** - * 分页查询 - * @param page 分页对象 - * @param appUserDTO app用户表 - * @return - */ - @Operation(summary = "分页查询", description = "分页查询") - @GetMapping("/page") - public R getAppUserPage(Page page, AppUserDTO appUserDTO) { - return R.ok(appUserService.getUsersWithRolePage(page, appUserDTO)); - } + /** + * 分页查询 + * + * @param page 分页对象 + * @param appUserDTO app用户表 + * @return + */ + @Operation(summary = "分页查询", description = "分页查询") + @GetMapping("/page") + public R getAppUserPage(Page page, AppUserDTO appUserDTO) { + return R.ok(appUserService.getUsersWithRolePage(page, appUserDTO)); + } - /** - * 通过id查询app用户表 - * @param userId id - * @return R - */ - @Operation(summary = "通过id查询", description = "通过id查询") - @GetMapping("/details/{userId}") - public R getById(@PathVariable("userId") Long userId) { - return R.ok(appUserService.selectUserVoById(userId)); - } + /** + * 通过id查询app用户表 + * + * @param userId id + * @return R + */ + @Operation(summary = "通过id查询", description = "通过id查询") + @GetMapping("/details/{userId}") + public R getById(@PathVariable("userId") Long userId) { + return R.ok(appUserService.selectUserVoById(userId)); + } - /** - * @return R - */ - @Operation(summary = "通过userName查询", description = "通过userName查询") - @GetMapping("/details") - public R getByUserName(AppUser user) { - AppUser one = appUserService.getOne(Wrappers.query(user), false); - return R.ok(one == null ? null : CommonConstants.SUCCESS); - } + /** + * @return R + */ + @Operation(summary = "通过userName查询", description = "通过userName查询") + @GetMapping("/details") + public R getByUserName(AppUser user) { + AppUser one = appUserService.getOne(Wrappers.query(user), false); + return R.ok(one == null ? null : CommonConstants.SUCCESS); + } - /** - * 新增app用户表 - * @param appUser app用户表 - * @return R - */ - @Operation(summary = "新增app用户表", description = "新增app用户表") - @SysLog("新增app用户表") - @PostMapping - @HasPermission("app_appuser_add") - public R save(@RequestBody AppUserDTO appUser) { - appUserService.saveUser(appUser); - return R.ok(); - } + /** + * 新增app用户表 + * + * @param appUser app用户表 + * @return R + */ + @Operation(summary = "新增app用户表", description = "新增app用户表") + @SysLog("新增app用户表") + @PostMapping + @HasPermission("app_appuser_add") + public R save(@RequestBody AppUserDTO appUser) { + appUserService.saveUser(appUser); + return R.ok(); + } - /** - * 修改app用户表 - * @param appUser app用户表 - * @return R - */ - @Operation(summary = "修改app用户表", description = "修改app用户表") - @SysLog("修改app用户表") - @PutMapping - @HasPermission("app_appuser_edit") - public R updateById(@RequestBody AppUserDTO appUser) { - return R.ok(appUserService.updateUser(appUser)); - } + /** + * 修改app用户表 + * + * @param appUser app用户表 + * @return R + */ + @Operation(summary = "修改app用户表", description = "修改app用户表") + @SysLog("修改app用户表") + @PutMapping + @HasPermission("app_appuser_edit") + public R updateById(@RequestBody AppUserDTO appUser) { + return R.ok(appUserService.updateUser(appUser)); + } - /** - * 通过id删除app用户表 - * @param ids userIds - * @return R - */ - @Operation(summary = "通过ids删除app用户表", description = "通过ids删除app用户表") - @SysLog("通过id删除app用户表") - @DeleteMapping - @HasPermission("app_appuser_del") - public R removeById(@RequestBody Long[] ids) { - return R.ok(appUserService.deleteAppUserByIds(ids)); - } + /** + * 通过id删除app用户表 + * + * @param ids userIds + * @return R + */ + @Operation(summary = "通过ids删除app用户表", description = "通过ids删除app用户表") + @SysLog("通过id删除app用户表") + @DeleteMapping + @HasPermission("app_appuser_del") + public R removeById(@RequestBody Long[] ids) { + return R.ok(appUserService.deleteAppUserByIds(ids)); + } - /** - * 导出excel 表格 - * @param appUser 查询条件 - * @return excel 文件流 - */ - @ResponseExcel - @GetMapping("/export") - @HasPermission("app_appuser_export") - public List export(AppUserDTO appUser) { - return appUserService.listUser(appUser); - } + /** + * 导出excel 表格 + * + * @param appUser 查询条件 + * @return excel 文件流 + */ + @ResponseExcel + @GetMapping("/export") + @HasPermission("app_appuser_export") + public List export(AppUserDTO appUser) { + return appUserService.listUser(appUser); + } - @SysLog("修改个人信息") - @PutMapping("/edit") - public R updateUserInfo(@Valid @RequestBody AppUserDTO userDto) { - if (UserTypeEnum.TOC.getStatus().equals(SecurityUtils.getUser().getUserType())) { - userDto.setUserId(SecurityUtils.getUser().getId()); - // TOC 以手机号为key - userDto.setUsername(SecurityUtils.getUser().getUsername()); - } - return appUserService.updateUserInfo(userDto); - } + @SysLog("修改个人信息") + @PutMapping("/edit") + public R updateUserInfo(@Valid @RequestBody AppUserDTO userDto) { + if (UserTypeEnum.TOC.getStatus().equals(SecurityUtils.getUser().getUserType())) { + userDto.setUserId(SecurityUtils.getUser().getId()); + // TOC 以手机号为key + userDto.setUsername(SecurityUtils.getUser().getUsername()); + } + return appUserService.updateUserInfo(userDto); + } - /** - * 导入用户 - * @param excelVOList 用户列表 - * @param bindingResult 错误信息列表 - * @return R - */ - @PostMapping("/import") - @HasPermission("app_appuser_export") - public R importUser(@RequestExcel List excelVOList, BindingResult bindingResult) { - return appUserService.importUser(excelVOList, bindingResult); - } + /** + * 导入用户 + * + * @param excelVOList 用户列表 + * @param bindingResult 错误信息列表 + * @return R + */ + @PostMapping("/import") + @HasPermission("app_appuser_export") + public R importUser(@RequestExcel List excelVOList, BindingResult bindingResult) { + return appUserService.importUser(excelVOList, bindingResult); + } - @Operation(summary = "注册app用户表", description = "注册app用户表") - @SysLog("注册app用户表") - @Inner(value = false) - @PostMapping("/register") - public R register(@RequestBody AppUserDTO appUser) { - return appUserService.registerAppUser(appUser); - } + @Operation(summary = "注册app用户表", description = "注册app用户表") + @SysLog("注册app用户表") + @Inner(value = false) + @PostMapping("/register") + public R register(@RequestBody AppUserDTO appUser) { + return appUserService.registerAppUser(appUser); + } } diff --git a/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/controller/AppUserRoleController.java b/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/controller/AppUserRoleController.java index de1945868..b3f1693ab 100644 --- a/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/controller/AppUserRoleController.java +++ b/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/controller/AppUserRoleController.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/handler/AbstractLoginHandler.java b/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/handler/AbstractLoginHandler.java index 2b2aff986..fd2503be8 100644 --- a/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/handler/AbstractLoginHandler.java +++ b/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/handler/AbstractLoginHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/handler/LoginHandler.java b/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/handler/LoginHandler.java index 1137d8f65..e9716b7ab 100644 --- a/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/handler/LoginHandler.java +++ b/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/handler/LoginHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/handler/MiniAppLoginHandler.java b/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/handler/MiniAppLoginHandler.java index 29bc6aeaa..737518a1e 100644 --- a/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/handler/MiniAppLoginHandler.java +++ b/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/handler/MiniAppLoginHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/handler/SmsLoginHandler.java b/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/handler/SmsLoginHandler.java index 321361bbf..2b4e26a50 100644 --- a/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/handler/SmsLoginHandler.java +++ b/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/handler/SmsLoginHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/mapper/AppRoleMapper.java b/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/mapper/AppRoleMapper.java index 9173e7f67..4c1bbaa47 100644 --- a/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/mapper/AppRoleMapper.java +++ b/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/mapper/AppRoleMapper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/mapper/AppSocialDetailsMapper.java b/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/mapper/AppSocialDetailsMapper.java index 0dc07fa1d..c5db03aa8 100644 --- a/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/mapper/AppSocialDetailsMapper.java +++ b/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/mapper/AppSocialDetailsMapper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/mapper/AppUserMapper.java b/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/mapper/AppUserMapper.java index 37a878e82..4a1284aa9 100644 --- a/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/mapper/AppUserMapper.java +++ b/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/mapper/AppUserMapper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/mapper/AppUserRoleMapper.java b/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/mapper/AppUserRoleMapper.java index a789cb6dd..e3a7445f1 100644 --- a/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/mapper/AppUserRoleMapper.java +++ b/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/mapper/AppUserRoleMapper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/service/AppMobileService.java b/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/service/AppMobileService.java index 702efb32a..dec7d91b8 100644 --- a/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/service/AppMobileService.java +++ b/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/service/AppMobileService.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/service/AppRoleService.java b/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/service/AppRoleService.java index a1cb464d4..755faa03a 100644 --- a/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/service/AppRoleService.java +++ b/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/service/AppRoleService.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/service/AppSocialDetailsService.java b/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/service/AppSocialDetailsService.java index 23085ae4c..cd9d142af 100644 --- a/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/service/AppSocialDetailsService.java +++ b/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/service/AppSocialDetailsService.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/service/AppUserRoleService.java b/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/service/AppUserRoleService.java index 23c941411..13c7b85af 100644 --- a/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/service/AppUserRoleService.java +++ b/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/service/AppUserRoleService.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/service/AppUserService.java b/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/service/AppUserService.java index 66655130a..2ddef6fcb 100644 --- a/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/service/AppUserService.java +++ b/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/service/AppUserService.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/service/impl/AppMobileServiceImpl.java b/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/service/impl/AppMobileServiceImpl.java index 18a96639b..3a522ccc5 100644 --- a/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/service/impl/AppMobileServiceImpl.java +++ b/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/service/impl/AppMobileServiceImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -20,11 +20,11 @@ package com.pig4cloud.pigx.app.service.impl; import cn.hutool.core.util.RandomUtil; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.toolkit.StringPool; +import com.pig4cloud.pigx.app.api.enums.AppErrorCodes; import com.pig4cloud.pigx.app.service.AppMobileService; import com.pig4cloud.pigx.common.core.constant.CacheConstants; import com.pig4cloud.pigx.common.core.constant.SecurityConstants; import com.pig4cloud.pigx.common.core.constant.enums.LoginTypeEnum; -import com.pig4cloud.pigx.common.core.exception.ErrorCodes; import com.pig4cloud.pigx.common.core.util.MsgUtils; import com.pig4cloud.pigx.common.core.util.R; import com.pig4cloud.pigx.common.data.cache.RedisUtils; @@ -43,24 +43,25 @@ import org.springframework.stereotype.Service; @AllArgsConstructor public class AppMobileServiceImpl implements AppMobileService { - /** - * 发送手机验证码 TODO: 调用短信网关发送验证码,测试返回前端 - * @param mobile mobile - * @return code - */ - @Override - public R sendSmsCode(String mobile) { - String codeObj = RedisUtils.get(CacheConstants.DEFAULT_CODE_KEY + LoginTypeEnum.APPSMS.getType() + StringPool.AT + mobile); + /** + * 发送手机验证码 TODO: 调用短信网关发送验证码,测试返回前端 + * + * @param mobile mobile + * @return code + */ + @Override + public R sendSmsCode(String mobile) { + String codeObj = RedisUtils.get(CacheConstants.DEFAULT_CODE_KEY + LoginTypeEnum.APPSMS.getType() + StringPool.AT + mobile); - if (StrUtil.isNotBlank(codeObj)) { - log.info("手机号验证码未过期:{},{}", mobile, codeObj); - return R.ok(Boolean.FALSE, MsgUtils.getMessage(ErrorCodes.SYS_APP_SMS_OFTEN)); - } + if (StrUtil.isNotBlank(codeObj)) { + log.info("手机号验证码未过期:{},{}", mobile, codeObj); + return R.ok(Boolean.FALSE, MsgUtils.getMessage(AppErrorCodes.APP_SMS_OFTEN)); + } - String code = RandomUtil.randomNumbers(Integer.parseInt(SecurityConstants.CODE_SIZE)); - log.debug("手机号生成验证码成功:{},{}", mobile, code); - RedisUtils.set(CacheConstants.DEFAULT_CODE_KEY + LoginTypeEnum.APPSMS.getType() + StringPool.AT + mobile, code, SecurityConstants.CODE_TIME); - return R.ok(Boolean.TRUE); - } + String code = RandomUtil.randomNumbers(Integer.parseInt(SecurityConstants.CODE_SIZE)); + log.debug("手机号生成验证码成功:{},{}", mobile, code); + RedisUtils.set(CacheConstants.DEFAULT_CODE_KEY + LoginTypeEnum.APPSMS.getType() + StringPool.AT + mobile, code, SecurityConstants.CODE_TIME); + return R.ok(Boolean.TRUE); + } } diff --git a/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/service/impl/AppRoleServiceImpl.java b/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/service/impl/AppRoleServiceImpl.java index b4a8293a4..7d620e75d 100644 --- a/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/service/impl/AppRoleServiceImpl.java +++ b/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/service/impl/AppRoleServiceImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -17,16 +17,20 @@ package com.pig4cloud.pigx.app.service.impl; import cn.hutool.core.collection.CollUtil; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.pig4cloud.pigx.app.api.entity.AppPageEntity; import com.pig4cloud.pigx.app.api.entity.AppRole; +import com.pig4cloud.pigx.app.api.enums.AppErrorCodes; +import com.pig4cloud.pigx.app.api.enums.PageTypeEnums; import com.pig4cloud.pigx.app.api.vo.AppRoleExcelVO; +import com.pig4cloud.pigx.app.mapper.AppPageMapper; import com.pig4cloud.pigx.app.mapper.AppRoleMapper; import com.pig4cloud.pigx.app.service.AppRoleService; -import com.pig4cloud.pigx.common.core.exception.ErrorCodes; import com.pig4cloud.pigx.common.core.util.MsgUtils; import com.pig4cloud.pigx.common.core.util.R; import com.pig4cloud.pigx.common.excel.vo.ErrorMessage; -import lombok.AllArgsConstructor; +import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.validation.BindingResult; @@ -35,79 +39,86 @@ import java.util.List; import java.util.Set; /** - * app角色表 + * APP角色服务实现类 + *

+ * 提供对APP角色相关的业务操作实现。 * - * @author aeizzz - * @date 2022-12-07 09:52:03 + * @author lengleng + * @date 2025/05/29 */ @Service -@AllArgsConstructor +@RequiredArgsConstructor public class AppRoleServiceImpl extends ServiceImpl implements AppRoleService { - @Override - public List findRolesByUserId(Long userId) { - return baseMapper.listRolesByUserId(userId); - } + private final AppPageMapper appPageMapper; - /** - * 删除用户的同时,把role_menu关系删除 - * @param ids roleIds - */ - @Override - public Boolean deleteRoleByIds(Long[] ids) { - this.removeBatchByIds(CollUtil.toList(ids)); - return Boolean.TRUE; - } + private final AppRoleMapper appRoleMapper; - /** - * 导入角色 - * @param excelVOList - * @param bindingResult - * @return - */ - @Override - public R importRole(List excelVOList, BindingResult bindingResult) { - // 通用校验获取失败的数据 - List errorMessageList = (List) bindingResult.getTarget(); + @Override + public List findRolesByUserId(Long userId) { + return baseMapper.listRolesByUserId(userId); + } - // 个性化校验逻辑 - List roleList = this.list(); + /** + * 删除用户的同时,把role_menu关系删除 + * + * @param ids roleIds + */ + @Override + public Boolean deleteRoleByIds(Long[] ids) { + this.removeBatchByIds(CollUtil.toList(ids)); + return Boolean.TRUE; + } - // 执行数据插入操作 组装 RoleDto - for (AppRoleExcelVO excel : excelVOList) { - Set errorMsg = new HashSet<>(); - // 检验角色名称或者角色编码是否存在 - boolean existRole = roleList.stream() - .anyMatch(appRole -> excel.getRoleName().equals(appRole.getRoleName()) - || excel.getRoleCode().equals(appRole.getRoleCode())); + /** + * 导入角色 + * + * @param excelVOList + * @param bindingResult + * @return + */ + @Override + public R importRole(List excelVOList, BindingResult bindingResult) { + // 通用校验获取失败的数据 + List errorMessageList = (List) bindingResult.getTarget(); - if (existRole) { - errorMsg.add(MsgUtils.getMessage(ErrorCodes.SYS_ROLE_NAMEORCODE_EXISTING, excel.getRoleName(), - excel.getRoleCode())); - } + // 个性化校验逻辑 + List roleList = this.list(); - // 数据合法情况 - if (CollUtil.isEmpty(errorMsg)) { - insertExcelRole(excel); - } - else { - // 数据不合法情况 - errorMessageList.add(new ErrorMessage(excel.getLineNum(), errorMsg)); - } - } - if (CollUtil.isNotEmpty(errorMessageList)) { - return R.failed(errorMessageList); - } - return R.ok(); + // 执行数据插入操作 组装 RoleDto + for (AppRoleExcelVO excel : excelVOList) { + Set errorMsg = new HashSet<>(); + // 检验角色名称或者角色编码是否存在 + boolean existRole = roleList.stream() + .anyMatch(appRole -> excel.getRoleName().equals(appRole.getRoleName()) + || excel.getRoleCode().equals(appRole.getRoleCode())); - } + if (existRole) { + errorMsg.add(MsgUtils.getMessage(AppErrorCodes.APP_ROLE_NAMEORCODE_EXISTING, excel.getRoleName(), + excel.getRoleCode())); + } - private void insertExcelRole(AppRoleExcelVO excel) { - AppRole appRole = new AppRole(); - appRole.setRoleName(excel.getRoleName()); - appRole.setRoleDesc(excel.getRoleDesc()); - appRole.setRoleCode(excel.getRoleCode()); - this.save(appRole); - } + // 数据合法情况 + if (CollUtil.isEmpty(errorMsg)) { + insertExcelRole(excel); + } else { + // 数据不合法情况 + errorMessageList.add(new ErrorMessage(excel.getLineNum(), errorMsg)); + } + } + if (CollUtil.isNotEmpty(errorMessageList)) { + return R.failed(errorMessageList); + } + return R.ok(); + + } + + private void insertExcelRole(AppRoleExcelVO excel) { + AppRole appRole = new AppRole(); + appRole.setRoleName(excel.getRoleName()); + appRole.setRoleDesc(excel.getRoleDesc()); + appRole.setRoleCode(excel.getRoleCode()); + this.save(appRole); + } } diff --git a/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/service/impl/AppSocialDetailsServiceImpl.java b/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/service/impl/AppSocialDetailsServiceImpl.java index fdfec8740..47b9bd033 100644 --- a/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/service/impl/AppSocialDetailsServiceImpl.java +++ b/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/service/impl/AppSocialDetailsServiceImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/service/impl/AppUserRoleServiceImpl.java b/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/service/impl/AppUserRoleServiceImpl.java index bc31adebc..0eeab146e 100644 --- a/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/service/impl/AppUserRoleServiceImpl.java +++ b/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/service/impl/AppUserRoleServiceImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/service/impl/AppUserServiceImpl.java b/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/service/impl/AppUserServiceImpl.java index 4381f7617..1ecccb968 100644 --- a/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/service/impl/AppUserServiceImpl.java +++ b/pigx-app-server/pigx-app-server-biz/src/main/java/com/pig4cloud/pigx/app/service/impl/AppUserServiceImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -29,6 +29,7 @@ import com.pig4cloud.pigx.app.api.dto.AppUserInfo; import com.pig4cloud.pigx.app.api.entity.AppRole; import com.pig4cloud.pigx.app.api.entity.AppUser; import com.pig4cloud.pigx.app.api.entity.AppUserRole; +import com.pig4cloud.pigx.app.api.enums.AppErrorCodes; import com.pig4cloud.pigx.app.api.vo.AppUserExcelVO; import com.pig4cloud.pigx.app.api.vo.AppUserVO; import com.pig4cloud.pigx.app.mapper.AppUserMapper; @@ -39,7 +40,6 @@ import com.pig4cloud.pigx.common.core.constant.CacheConstants; import com.pig4cloud.pigx.common.core.constant.CommonConstants; import com.pig4cloud.pigx.common.core.constant.enums.LoginTypeEnum; import com.pig4cloud.pigx.common.core.constant.enums.UserTypeEnum; -import com.pig4cloud.pigx.common.core.exception.ErrorCodes; import com.pig4cloud.pigx.common.core.util.MsgUtils; import com.pig4cloud.pigx.common.core.util.R; import com.pig4cloud.pigx.common.data.cache.RedisUtils; @@ -72,328 +72,338 @@ import java.util.Set; @Slf4j public class AppUserServiceImpl extends ServiceImpl implements AppUserService { - /** - * 密码编码器,用于密码加密 - */ - private static final PasswordEncoder ENCODER = new BCryptPasswordEncoder(); + /** + * 密码编码器,用于密码加密 + */ + private static final PasswordEncoder ENCODER = new BCryptPasswordEncoder(); - /** - * 用户角色关联服务 - */ - private final AppUserRoleService appUserRoleService; + /** + * 用户角色关联服务 + */ + private final AppUserRoleService appUserRoleService; - /** - * 角色服务 - */ - private final AppRoleService appRoleService; + /** + * 角色服务 + */ + private final AppRoleService appRoleService; - /** - * 缓存管理器 - */ - private final CacheManager cacheManager; + /** + * 缓存管理器 + */ + private final CacheManager cacheManager; - /** - * 更新用户信息 - * @param userDTO 用户数据传输对象 - * @return 更新结果 - */ - @Override - @CacheEvict(value = CacheConstants.USER_DETAILS_MINI, key = "#userDTO.username") - public Boolean updateUser(AppUserDTO userDTO) { - // 创建用户实体并复制属性 - AppUser appUser = new AppUser(); - BeanUtils.copyProperties(userDTO, appUser); + /** + * 更新用户信息 + * + * @param userDTO 用户数据传输对象 + * @return 更新结果 + */ + @Override + @CacheEvict(value = CacheConstants.USER_DETAILS_MINI, key = "#userDTO.username") + public Boolean updateUser(AppUserDTO userDTO) { + // 创建用户实体并复制属性 + AppUser appUser = new AppUser(); + BeanUtils.copyProperties(userDTO, appUser); - // 如果密码不为空,进行加密处理 - if (StrUtil.isNotBlank(userDTO.getPassword())) { - appUser.setPassword(ENCODER.encode(userDTO.getPassword())); - } - // 更新用户基本信息 - this.updateById(appUser); + // 如果密码不为空,进行加密处理 + if (StrUtil.isNotBlank(userDTO.getPassword())) { + appUser.setPassword(ENCODER.encode(userDTO.getPassword())); + } + // 更新用户基本信息 + this.updateById(appUser); - // 删除用户与角色的关联关系 - appUserRoleService.remove(Wrappers.lambdaQuery().eq(AppUserRole::getUserId, appUser.getUserId())); - // 重新建立用户与角色的关联关系 - userDTO.getRole().forEach(roleId -> { - AppUserRole appUserRole = new AppUserRole(); - appUserRole.setRoleId(roleId); - appUserRole.setUserId(userDTO.getUserId()); - appUserRole.insert(); - }); + // 删除用户与角色的关联关系 + appUserRoleService.remove(Wrappers.lambdaQuery().eq(AppUserRole::getUserId, appUser.getUserId())); + // 重新建立用户与角色的关联关系 + userDTO.getRole().forEach(roleId -> { + AppUserRole appUserRole = new AppUserRole(); + appUserRole.setRoleId(roleId); + appUserRole.setUserId(userDTO.getUserId()); + appUserRole.insert(); + }); - // 清除以手机号为key的用户缓存 - AppUser appUserInfo = baseMapper.selectById(userDTO.getUserId()); - cacheManager.getCache(CacheConstants.USER_DETAILS_MINI).evict(appUserInfo.getPhone()); - return Boolean.TRUE; - } + // 清除以手机号为key的用户缓存 + AppUser appUserInfo = baseMapper.selectById(userDTO.getUserId()); + cacheManager.getCache(CacheConstants.USER_DETAILS_MINI).evict(appUserInfo.getPhone()); + return Boolean.TRUE; + } - /** - * 新增用户 - * @param userDTO 用户数据传输对象 - * @return 保存结果 - */ - @Override - public Boolean saveUser(AppUserDTO userDTO) { - // 创建用户实体并复制属性 - AppUser appUser = new AppUser(); - BeanUtils.copyProperties(userDTO, appUser); - // 设置删除标志为正常状态 - appUser.setDelFlag(CommonConstants.STATUS_NORMAL); - // 对密码进行加密 - appUser.setPassword(ENCODER.encode(userDTO.getPassword())); - // 插入用户记录 - baseMapper.insert(appUser); + /** + * 新增用户 + * + * @param userDTO 用户数据传输对象 + * @return 保存结果 + */ + @Override + public Boolean saveUser(AppUserDTO userDTO) { + // 创建用户实体并复制属性 + AppUser appUser = new AppUser(); + BeanUtils.copyProperties(userDTO, appUser); + // 设置删除标志为正常状态 + appUser.setDelFlag(CommonConstants.STATUS_NORMAL); + // 对密码进行加密 + appUser.setPassword(ENCODER.encode(userDTO.getPassword())); + // 插入用户记录 + baseMapper.insert(appUser); - // 如果角色列表不为空,建立用户与角色的关联关系 - if (CollUtil.isNotEmpty(userDTO.getRole())) { - List userRoleList = userDTO.getRole().stream().map(roleId -> { - AppUserRole userRole = new AppUserRole(); - userRole.setUserId(appUser.getUserId()); - userRole.setRoleId(roleId); - return userRole; - }).toList(); - // 批量保存用户角色关联 - appUserRoleService.saveBatch(userRoleList); - } - return Boolean.TRUE; - } + // 如果角色列表不为空,建立用户与角色的关联关系 + if (CollUtil.isNotEmpty(userDTO.getRole())) { + List userRoleList = userDTO.getRole().stream().map(roleId -> { + AppUserRole userRole = new AppUserRole(); + userRole.setUserId(appUser.getUserId()); + userRole.setRoleId(roleId); + return userRole; + }).toList(); + // 批量保存用户角色关联 + appUserRoleService.saveBatch(userRoleList); + } + return Boolean.TRUE; + } - /** - * 查询全部用户(用于Excel导出) - * @param appUser 查询条件 - * @return 用户Excel视图对象列表 - */ - @Override - public List listUser(AppUserDTO appUser) { - // 查询所有用户 - List appUsers = baseMapper.selectList(null); - // 将用户实体转换为Excel视图对象 - List appUserExcelVOS = appUsers.stream().map(item -> { - AppUserExcelVO appUserExcelVO = new AppUserExcelVO(); - BeanUtils.copyProperties(item, appUserExcelVO); - return appUserExcelVO; - }).toList(); - return appUserExcelVOS; - } + /** + * 查询全部用户(用于Excel导出) + * + * @param appUser 查询条件 + * @return 用户Excel视图对象列表 + */ + @Override + public List listUser(AppUserDTO appUser) { + // 查询所有用户 + List appUsers = baseMapper.selectList(null); + // 将用户实体转换为Excel视图对象 + List appUserExcelVOS = appUsers.stream().map(item -> { + AppUserExcelVO appUserExcelVO = new AppUserExcelVO(); + BeanUtils.copyProperties(item, appUserExcelVO); + return appUserExcelVO; + }).toList(); + return appUserExcelVOS; + } - /** - * 分页查询用户(包含角色信息) - * @param page 分页参数 - * @param appUserDTO 查询条件 - * @return 分页结果 - */ - @Override - public IPage getUsersWithRolePage(Page page, AppUserDTO appUserDTO) { - return baseMapper.getUserVosPage(page, appUserDTO); - } + /** + * 分页查询用户(包含角色信息) + * + * @param page 分页参数 + * @param appUserDTO 查询条件 + * @return 分页结果 + */ + @Override + public IPage getUsersWithRolePage(Page page, AppUserDTO appUserDTO) { + return baseMapper.getUserVosPage(page, appUserDTO); + } - /** - * 查询用户详细信息(包含角色和权限) - * @param user 用户对象 - * @return 用户信息对象 - */ - @Override - public AppUserInfo findUserInfo(AppUser user) { - // 创建用户信息对象 - AppUserInfo info = new AppUserInfo(); - info.setAppUser(user); + /** + * 查询用户详细信息(包含角色和权限) + * + * @param user 用户对象 + * @return 用户信息对象 + */ + @Override + public AppUserInfo findUserInfo(AppUser user) { + // 创建用户信息对象 + AppUserInfo info = new AppUserInfo(); + info.setAppUser(user); - // 设置角色列表(ID数组) - List roleIds = appRoleService.findRolesByUserId(user.getUserId()) - .stream() - .map(AppRole::getRoleId) - .toList(); - info.setRoles(ArrayUtil.toArray(roleIds, Long.class)); + // 设置角色列表(ID数组) + List roleIds = appRoleService.findRolesByUserId(user.getUserId()) + .stream() + .map(AppRole::getRoleId) + .toList(); + info.setRoles(ArrayUtil.toArray(roleIds, Long.class)); - // 设置权限列表(暂为空) - Set permissions = new HashSet<>(); - info.setPermissions(ArrayUtil.toArray(permissions, String.class)); - return info; - } + // 设置权限列表(暂为空) + Set permissions = new HashSet<>(); + info.setPermissions(ArrayUtil.toArray(permissions, String.class)); + return info; + } - /** - * 更新用户个人信息 - * @param userDTO 用户数据传输对象 - * @return 操作结果 - */ - @Override - @CacheEvict(value = CacheConstants.USER_DETAILS_MINI, key = "#userDTO.username") - public R updateUserInfo(AppUserDTO userDTO) { - // 获取当前登录用户 - PigxUser user = SecurityUtils.getUser(); + /** + * 更新用户个人信息 + * + * @param userDTO 用户数据传输对象 + * @return 操作结果 + */ + @Override + @CacheEvict(value = CacheConstants.USER_DETAILS_MINI, key = "#userDTO.username") + public R updateUserInfo(AppUserDTO userDTO) { + // 获取当前登录用户 + PigxUser user = SecurityUtils.getUser(); - // C端客户修改手机号需要验证短信验证码 - if (UserTypeEnum.TOC.getStatus().equals(user.getUserType()) && StrUtil.isNotBlank(userDTO.getPhone())) { - // 构建验证码缓存key - String key = CacheConstants.DEFAULT_CODE_KEY + LoginTypeEnum.APPSMS.getType() + StringPool.AT - + userDTO.getPhone(); - // 获取缓存中的验证码 - String codeObj = RedisUtils.get(key); + // C端客户修改手机号需要验证短信验证码 + if (UserTypeEnum.TOC.getStatus().equals(user.getUserType()) && StrUtil.isNotBlank(userDTO.getPhone())) { + // 构建验证码缓存key + String key = CacheConstants.DEFAULT_CODE_KEY + LoginTypeEnum.APPSMS.getType() + StringPool.AT + + userDTO.getPhone(); + // 获取缓存中的验证码 + String codeObj = RedisUtils.get(key); - // 验证码不匹配,返回错误 - if (!userDTO.getMobileCode().equals(codeObj)) { - return R.failed("验证码错误"); - } - } + // 验证码不匹配,返回错误 + if (!userDTO.getMobileCode().equals(codeObj)) { + return R.failed("验证码错误"); + } + } - // 更新密码(如果提供了新密码) - if (StrUtil.isNotBlank(userDTO.getPassword())) { - userDTO.setPassword(ENCODER.encode(userDTO.getPassword())); - } + // 更新密码(如果提供了新密码) + if (StrUtil.isNotBlank(userDTO.getPassword())) { + userDTO.setPassword(ENCODER.encode(userDTO.getPassword())); + } - // 获取原用户信息并更新 - AppUser appUser = baseMapper.selectById(userDTO.getUserId()); - BeanUtils.copyProperties(userDTO, appUser); + // 获取原用户信息并更新 + AppUser appUser = baseMapper.selectById(userDTO.getUserId()); + BeanUtils.copyProperties(userDTO, appUser); - // 清除以手机号为key的用户缓存 - cacheManager.getCache(CacheConstants.USER_DETAILS_MINI).evict(user.getPhone()); - return R.ok(this.updateById(appUser)); - } + // 清除以手机号为key的用户缓存 + cacheManager.getCache(CacheConstants.USER_DETAILS_MINI).evict(user.getPhone()); + return R.ok(this.updateById(appUser)); + } - /** - * 根据用户ID查询用户视图对象 - * @param userId 用户ID - * @return 用户视图对象 - */ - @Override - public AppUserVO selectUserVoById(Long userId) { - return baseMapper.getUserVoById(userId); - } + /** + * 根据用户ID查询用户视图对象 + * + * @param userId 用户ID + * @return 用户视图对象 + */ + @Override + public AppUserVO selectUserVoById(Long userId) { + return baseMapper.getUserVoById(userId); + } - /** - * 批量删除用户 - * @param ids 用户ID数组 - * @return 删除结果 - */ - @Override - public Boolean deleteAppUserByIds(Long[] ids) { - // 获取缓存对象 - Cache cache = cacheManager.getCache(CacheConstants.USER_DETAILS_MINI); - // 清除用户缓存 - for (AppUser appUser : baseMapper.selectByIds(CollUtil.toList(ids))) { - cache.evict(appUser.getUsername()); - } + /** + * 批量删除用户 + * + * @param ids 用户ID数组 + * @return 删除结果 + */ + @Override + public Boolean deleteAppUserByIds(Long[] ids) { + // 获取缓存对象 + Cache cache = cacheManager.getCache(CacheConstants.USER_DETAILS_MINI); + // 清除用户缓存 + for (AppUser appUser : baseMapper.selectByIds(CollUtil.toList(ids))) { + cache.evict(appUser.getUsername()); + } - // 删除用户角色关联关系 - this.appUserRoleService - .remove(Wrappers.lambdaQuery().in(AppUserRole::getUserId, CollUtil.toList(ids))); + // 删除用户角色关联关系 + this.appUserRoleService + .remove(Wrappers.lambdaQuery().in(AppUserRole::getUserId, CollUtil.toList(ids))); - // 删除用户记录 - this.removeBatchByIds(CollUtil.toList(ids)); + // 删除用户记录 + this.removeBatchByIds(CollUtil.toList(ids)); - return Boolean.TRUE; - } + return Boolean.TRUE; + } - /** - * 注册APP用户 - * @param appUser 用户数据传输对象 - * @return 操作结果 - */ - @Override - public R registerAppUser(AppUserDTO appUser) { - // 检查手机号是否已被注册 - List appUserList = baseMapper - .selectList(Wrappers.lambdaQuery().eq(AppUser::getPhone, appUser.getPhone())); + /** + * 注册APP用户 + * + * @param appUser 用户数据传输对象 + * @return 操作结果 + */ + @Override + public R registerAppUser(AppUserDTO appUser) { + // 检查手机号是否已被注册 + List appUserList = baseMapper + .selectList(Wrappers.lambdaQuery().eq(AppUser::getPhone, appUser.getPhone())); - if (CollUtil.isNotEmpty(appUserList)) { - return R.failed("手机号已注册,请使用验证码直接登录"); - } + if (CollUtil.isNotEmpty(appUserList)) { + return R.failed("手机号已注册,请使用验证码直接登录"); + } - // 验证短信验证码 - String key = CacheConstants.DEFAULT_CODE_KEY + LoginTypeEnum.APPSMS.getType() + StringPool.AT - + appUser.getPhone(); - String codeObj = RedisUtils.get(key); + // 验证短信验证码 + String key = CacheConstants.DEFAULT_CODE_KEY + LoginTypeEnum.APPSMS.getType() + StringPool.AT + + appUser.getPhone(); + String codeObj = RedisUtils.get(key); - if (!appUser.getMobileCode().equals(codeObj)) { - return R.failed("验证码错误"); - } + if (!appUser.getMobileCode().equals(codeObj)) { + return R.failed("验证码错误"); + } - // 创建用户并保存 - AppUser app = new AppUser(); - BeanUtils.copyProperties(appUser, app); - appUser.setUsername(app.getPhone()); // 默认使用手机号作为用户名 - appUser.setDelFlag(CommonConstants.STATUS_NORMAL); - appUser.setPassword(ENCODER.encode(appUser.getPassword())); - baseMapper.insert(appUser); - return null; - } + // 创建用户并保存 + AppUser app = new AppUser(); + BeanUtils.copyProperties(appUser, app); + appUser.setUsername(app.getPhone()); // 默认使用手机号作为用户名 + appUser.setDelFlag(CommonConstants.STATUS_NORMAL); + appUser.setPassword(ENCODER.encode(appUser.getPassword())); + baseMapper.insert(appUser); + return null; + } - /** - * 导入用户(从Excel导入) - * @param excelVOList Excel数据列表 - * @param bindingResult 数据校验结果 - * @return 导入结果 - */ - @Override - public R importUser(List excelVOList, BindingResult bindingResult) { - // 获取通用校验失败的数据 - List errorMessageList = (List) bindingResult.getTarget(); + /** + * 导入用户(从Excel导入) + * + * @param excelVOList Excel数据列表 + * @param bindingResult 数据校验结果 + * @return 导入结果 + */ + @Override + public R importUser(List excelVOList, BindingResult bindingResult) { + // 获取通用校验失败的数据 + List errorMessageList = (List) bindingResult.getTarget(); - // 获取现有用户和角色列表,用于校验 - List userList = this.list(); - List roleList = appRoleService.list(); + // 获取现有用户和角色列表,用于校验 + List userList = this.list(); + List roleList = appRoleService.list(); - // 遍历Excel数据进行处理 - for (AppUserExcelVO excel : excelVOList) { - Set errorMsg = new HashSet<>(); + // 遍历Excel数据进行处理 + for (AppUserExcelVO excel : excelVOList) { + Set errorMsg = new HashSet<>(); - // 校验用户名是否已存在 - boolean exsitUserName = userList.stream() - .anyMatch(sysUser -> excel.getUsername().equals(sysUser.getUsername())); + // 校验用户名是否已存在 + boolean exsitUserName = userList.stream() + .anyMatch(sysUser -> excel.getUsername().equals(sysUser.getUsername())); - if (exsitUserName) { - errorMsg.add(MsgUtils.getMessage(ErrorCodes.SYS_USER_USERNAME_EXISTING, excel.getUsername())); - } + if (exsitUserName) { + errorMsg.add(MsgUtils.getMessage(AppErrorCodes.APP_USER_USERNAME_EXISTING, excel.getUsername())); + } - // 校验角色名称是否合法 - List roleNameList = StrUtil.split(excel.getRoleNameList(), StrUtil.COMMA); - List roleCollList = roleList.stream() - .filter(role -> roleNameList.stream().anyMatch(name -> role.getRoleName().equals(name))) - .toList(); + // 校验角色名称是否合法 + List roleNameList = StrUtil.split(excel.getRoleNameList(), StrUtil.COMMA); + List roleCollList = roleList.stream() + .filter(role -> roleNameList.stream().anyMatch(name -> role.getRoleName().equals(name))) + .toList(); - if (roleCollList.size() != roleNameList.size()) { - errorMsg.add(MsgUtils.getMessage(ErrorCodes.SYS_ROLE_ROLENAME_INEXISTENCE, excel.getRoleNameList())); - } + if (roleCollList.size() != roleNameList.size()) { + errorMsg.add(MsgUtils.getMessage(AppErrorCodes.APP_ROLE_ROLENAME_INEXISTENCE, excel.getRoleNameList())); + } - // 数据合法时执行插入 - if (CollUtil.isEmpty(errorMsg)) { - insertExcelUser(excel, roleCollList); - } - else { - // 记录不合法数据的错误信息 - errorMessageList.add(new ErrorMessage(excel.getLineNum(), errorMsg)); - } - } + // 数据合法时执行插入 + if (CollUtil.isEmpty(errorMsg)) { + insertExcelUser(excel, roleCollList); + } else { + // 记录不合法数据的错误信息 + errorMessageList.add(new ErrorMessage(excel.getLineNum(), errorMsg)); + } + } - // 存在错误信息时返回失败 - if (CollUtil.isNotEmpty(errorMessageList)) { - return R.failed(errorMessageList); - } - return R.ok(null, MsgUtils.getMessage(ErrorCodes.SYS_USER_IMPORT_SUCCEED)); - } + // 存在错误信息时返回失败 + if (CollUtil.isNotEmpty(errorMessageList)) { + return R.failed(errorMessageList); + } + return R.ok(null, MsgUtils.getMessage(AppErrorCodes.APP_USER_IMPORT_SUCCEED)); + } - /** - * 插入Excel导入的用户数据 - * @param excel Excel用户数据 - * @param roleCollList 角色列表 - */ - private void insertExcelUser(AppUserExcelVO excel, List roleCollList) { - // 创建用户DTO并设置基本信息 - AppUserDTO userDTO = new AppUserDTO(); - userDTO.setUsername(excel.getUsername()); - userDTO.setPhone(excel.getPhone()); - userDTO.setNickname(excel.getNickname()); - userDTO.setName(excel.getName()); - userDTO.setEmail(excel.getEmail()); - // 批量导入时初始密码设置为手机号 - userDTO.setPassword(userDTO.getPhone()); + /** + * 插入Excel导入的用户数据 + * + * @param excel Excel用户数据 + * @param roleCollList 角色列表 + */ + private void insertExcelUser(AppUserExcelVO excel, List roleCollList) { + // 创建用户DTO并设置基本信息 + AppUserDTO userDTO = new AppUserDTO(); + userDTO.setUsername(excel.getUsername()); + userDTO.setPhone(excel.getPhone()); + userDTO.setNickname(excel.getNickname()); + userDTO.setName(excel.getName()); + userDTO.setEmail(excel.getEmail()); + // 批量导入时初始密码设置为手机号 + userDTO.setPassword(userDTO.getPhone()); - // 获取角色ID列表 - List roleIdList = roleCollList.stream().map(AppRole::getRoleId).toList(); - userDTO.setRole(roleIdList); + // 获取角色ID列表 + List roleIdList = roleCollList.stream().map(AppRole::getRoleId).toList(); + userDTO.setRole(roleIdList); - // 保存用户 - this.saveUser(userDTO); - } + // 保存用户 + this.saveUser(userDTO); + } } diff --git a/pigx-app-server/pigx-app-server-biz/src/main/resources/mapper/AppRoleMapper.xml b/pigx-app-server/pigx-app-server-biz/src/main/resources/mapper/AppRoleMapper.xml index 0da7d0018..e00f6c9e0 100644 --- a/pigx-app-server/pigx-app-server-biz/src/main/resources/mapper/AppRoleMapper.xml +++ b/pigx-app-server/pigx-app-server-biz/src/main/resources/mapper/AppRoleMapper.xml @@ -2,7 +2,7 @@ + 2.5.2 + 4.7.8-20251028.120007 + 2.9.12.1-17 3.0.3 4.0.1 1.15.3 @@ -42,7 +44,7 @@ 1.7.0 7.1 0.21.0 - 2.17.1 + 2.25.2 1.59.1 0.33.0 1.0.0 @@ -52,7 +54,7 @@ 1.4.7 2.0.1 2.20.1 - 2.3 + 2.4.1 2.16.1 3.1 @@ -186,6 +188,22 @@ pigx-flow-api ${pigx.version} + + + com.pig4cloud + pigx-common-milvus + ${pigx.version} + + + com.pig4cloud + pigx-common-mcp + ${pigx.version} + + + com.pig4cloud + pigx-common-neo4j + ${pigx.version} + io.github.pig-mesh.ai @@ -463,6 +481,12 @@ nacos-client ${nacos.client.version} + + + org.quartz-scheduler + quartz + ${quartz.version} + org.apache.logging.log4j diff --git a/pigx-common/pigx-common-core/pom.xml b/pigx-common/pigx-common-core/pom.xml index cc8e456fb..7a806d938 100644 --- a/pigx-common/pigx-common-core/pom.xml +++ b/pigx-common/pigx-common-core/pom.xml @@ -1,7 +1,7 @@ @@ -216,9 +222,6 @@ repackage - - CLASSIC - diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/PigxAdminApplication.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/PigxAdminApplication.java index 3bbf726ca..503448481 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/PigxAdminApplication.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/PigxAdminApplication.java @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/config/DynamicRouteInitRunner.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/config/DynamicRouteInitRunner.java index 106c691f0..d834bc53b 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/config/DynamicRouteInitRunner.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/config/DynamicRouteInitRunner.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysAuditLogController.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysAuditLogController.java index 5736b94c2..4e6919b43 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysAuditLogController.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysAuditLogController.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysClientController.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysClientController.java index ea774643d..960dc7f5f 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysClientController.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysClientController.java @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysDeptController.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysDeptController.java index 193994188..1b0830e9e 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysDeptController.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysDeptController.java @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysDictController.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysDictController.java index 43e511fcb..75db60d2b 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysDictController.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysDictController.java @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysFileController.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysFileController.java index 8b3e37b9d..126f08858 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysFileController.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysFileController.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysI18nController.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysI18nController.java index 055650251..5d1ec1030 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysI18nController.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysI18nController.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysLogController.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysLogController.java index f86658be1..12ff0d888 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysLogController.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysLogController.java @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysMenuController.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysMenuController.java index 9ca8e83f4..8979d5a47 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysMenuController.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysMenuController.java @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysMessageController.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysMessageController.java index a9a78a766..79a2a0f67 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysMessageController.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysMessageController.java @@ -183,17 +183,20 @@ public class SysMessageController { /** * 发送短信验证码 - * @param mobile 手机号 - * @return {@link R } + * + * @param mobile 手机号 + * @param registered 是否已注册,默认true + * @return 发送结果 */ @Inner(value = false) @GetMapping("/send/smsCode") - public R sendSmsCode(@RequestParam String mobile) { - return sysMessageService.sendSmsCode(mobile); + public R sendSmsCode(@RequestParam String mobile, @RequestParam(required = false, defaultValue = "true") boolean registered) { + return sysMessageService.sendSmsCode(mobile, registered); } /** * 发送短信 + * * @param messageSmsDTO 消息 短信 DTO * @return {@link R } */ @@ -204,6 +207,7 @@ public class SysMessageController { /** * 发送邮件 + * * @param messageEmailDTO 留言内容 电子邮件 DTO * @return {@link R } */ @@ -214,17 +218,18 @@ public class SysMessageController { /** * 发送 webhook + * * @param messageHookDTO 消息挂钩 DTO * @return {@link R } */ @PostMapping("/send/hook") public R sendWebhook(@Valid @RequestBody MessageHookDTO messageHookDTO) { - return sysMessageService.sendHook(messageHookDTO); - } + return sysMessageService.sendHook(messageHookDTO); + } - @GetMapping("/list/hook") - public R listHookBizCode(MessageHookDTO messageHookDTO) { - return sysMessageService.listHookBizCode(messageHookDTO); - } + @GetMapping("/list/hook") + public R listHookBizCode(MessageHookDTO messageHookDTO) { + return sysMessageService.listHookBizCode(messageHookDTO); + } } diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysPostController.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysPostController.java index 37b58ff9d..985e16b98 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysPostController.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysPostController.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysPublicParamController.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysPublicParamController.java index 9e89c2111..2a1a69172 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysPublicParamController.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysPublicParamController.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysRoleController.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysRoleController.java index 6c1c4ab86..85dd4d041 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysRoleController.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysRoleController.java @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysRouteConfController.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysRouteConfController.java index 6fd568656..7d91afca7 100755 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysRouteConfController.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysRouteConfController.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysScheduleController.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysScheduleController.java index ba28d2c1f..a96ab4926 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysScheduleController.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysScheduleController.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysSocialDetailsController.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysSocialDetailsController.java index e32724de8..76f50c45b 100755 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysSocialDetailsController.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysSocialDetailsController.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysSystemInfoController.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysSystemInfoController.java index b4e24f8f0..080593810 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysSystemInfoController.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysSystemInfoController.java @@ -1,5 +1,7 @@ package com.pig4cloud.pigx.admin.controller; +import com.pig4cloud.pigx.admin.api.constant.UpmsErrorCodes; +import com.pig4cloud.pigx.common.core.util.MsgUtils; import com.pig4cloud.pigx.common.core.util.R; import com.pig4cloud.pigx.common.data.cache.RedisUtils; import io.swagger.v3.oas.annotations.security.SecurityRequirement; @@ -22,36 +24,37 @@ import java.util.*; @SecurityRequirement(name = HttpHeaders.AUTHORIZATION) public class SysSystemInfoController { - /** - * 缓存监控 - * @return R - */ - @GetMapping("/cache") - public R cache() { + /** + * 缓存监控 + * + * @return R + */ + @GetMapping("/cache") + public R cache() { Properties info = RedisUtils.execute((RedisCallback) RedisServerCommands::info); Properties commandStats = RedisUtils .execute((RedisCallback) connection -> connection.serverCommands().info("commandstats")); Object dbSize = RedisUtils.execute((RedisCallback) RedisServerCommands::dbSize); - if (commandStats == null) { - return R.failed("获取异常"); - } + if (commandStats == null) { + return R.failed(MsgUtils.getMessage(UpmsErrorCodes.SYS_SYSTEM_CACHE_FETCH_ERROR)); + } - Map result = new HashMap<>(3); - result.put("info", info); - result.put("dbSize", dbSize); + Map result = new HashMap<>(3); + result.put("info", info); + result.put("dbSize", dbSize); - List> pieList = new ArrayList<>(); - commandStats.stringPropertyNames().forEach(key -> { - Map data = new HashMap<>(2); - String property = commandStats.getProperty(key); - data.put("name", StringUtils.removeStart(key, "cmdstat_")); - data.put("value", StringUtils.substringBetween(property, "calls=", ",usec")); - pieList.add(data); - }); + List> pieList = new ArrayList<>(); + commandStats.stringPropertyNames().forEach(key -> { + Map data = new HashMap<>(2); + String property = commandStats.getProperty(key); + data.put("name", StringUtils.removeStart(key, "cmdstat_")); + data.put("value", StringUtils.substringBetween(property, "calls=", ",usec")); + pieList.add(data); + }); - result.put("commandStats", pieList); - return R.ok(result); - } + result.put("commandStats", pieList); + return R.ok(result); + } } diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysTenantController.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysTenantController.java index d2eb0d1cf..949c7f244 100755 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysTenantController.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysTenantController.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysTokenController.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysTokenController.java index a33eb29ec..17235e4ca 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysTokenController.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysTokenController.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysUserController.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysUserController.java index 5daf57c64..cc5deba18 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysUserController.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysUserController.java @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -24,6 +24,7 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.pig4cloud.pigx.admin.api.dto.UserDTO; import com.pig4cloud.pigx.admin.api.dto.UserInfo; +import com.pig4cloud.pigx.admin.api.entity.SysDept; import com.pig4cloud.pigx.admin.api.entity.SysUser; import com.pig4cloud.pigx.admin.api.vo.UserExcelVO; import com.pig4cloud.pigx.admin.service.SysUserService; @@ -61,238 +62,280 @@ import java.util.List; @SecurityRequirement(name = HttpHeaders.AUTHORIZATION) public class SysUserController { - private final SysUserService userService; + private final SysUserService userService; - /** - * 获取指定用户全部信息 - * @return 用户信息 - */ - @Inner - @GetMapping("/info/{username}") - public R info(@PathVariable String username) { - UserDTO userDTO = new UserDTO(); - userDTO.setUsername(username); - return userService.getUserInfo(userDTO); - } + /** + * 获取指定用户全部信息 + * + * @return 用户信息 + */ + @Inner + @GetMapping("/info/{username}") + public R info(@PathVariable String username) { + UserDTO userDTO = new UserDTO(); + userDTO.setUsername(username); + return userService.getUserInfo(userDTO); + } - /** - * 获取当前用户全部信息 - * @return 用户信息 - */ - @GetMapping(value = { "/info" }) - public R info() { - String username = SecurityUtils.getUser().getUsername(); - UserDTO userDTO = new UserDTO(); - userDTO.setUsername(username); - // 获取用户信息,不返回数据库密码字段 - R userInfoR = userService.getUserInfo(userDTO); - if (userInfoR.getData() != null) { - userInfoR.getData().setPassword(null); - } - return userInfoR; - } + /** + * 获取当前用户全部信息 + * + * @return 用户信息 + */ + @GetMapping(value = {"/info"}) + public R info() { + String username = SecurityUtils.getUser().getUsername(); + UserDTO userDTO = new UserDTO(); + userDTO.setUsername(username); + // 获取用户信息,不返回数据库密码字段 + R userInfoR = userService.getUserInfo(userDTO); + if (userInfoR.getData() != null) { + userInfoR.getData().setPassword(null); + } + return userInfoR; + } - /** - * 通过ID查询用户信息 - * @param id ID - * @return 用户信息 - */ - @GetMapping("/details/{id}") - public R user(@PathVariable Long id) { - return R.ok(userService.selectUserVoById(id)); - } + /** + * 通过ID查询用户信息 + * + * @param id ID + * @return 用户信息 + */ + @GetMapping("/details/{id}") + public R user(@PathVariable Long id) { + return R.ok(userService.selectUserVoById(id)); + } - /** - * 查询用户信息 - * @param query 查询条件 - * @return 不为空返回用户名 - */ - @Inner(value = false) - @GetMapping("/details") - public R getDetails(@ParameterObject SysUser query) { - // 根据用户名、手机号 查询不区分租户 - SysUser sysUser = TenantBroker.noneAs(() -> userService.getOne(Wrappers.query(query), false)); - return R.ok(sysUser == null ? null : CommonConstants.SUCCESS); - } + /** + * 查询用户信息 + * + * @param query 查询条件 + * @return 不为空返回用户名 + */ + @Inner(value = false) + @GetMapping("/details") + public R getDetails(@ParameterObject SysUser query) { + // 根据用户名、手机号 查询不区分租户 + SysUser sysUser = TenantBroker.noneAs(() -> userService.getOne(Wrappers.query(query), false)); + return R.ok(sysUser == null ? null : CommonConstants.SUCCESS); + } - /** - * 删除用户信息 - * @param ids ID - * @return R - */ - @SysLog("删除用户信息") - @DeleteMapping - @HasPermission("sys_user_del") - @Operation(summary = "删除用户", description = "根据ID删除用户") - public R userDel(@RequestBody Long[] ids) { - return R.ok(userService.deleteUserByIds(ids)); - } + /** + * 删除用户信息 + * + * @param ids ID + * @return R + */ + @SysLog("删除用户信息") + @DeleteMapping + @HasPermission("sys_user_del") + @Operation(summary = "删除用户", description = "根据ID删除用户") + public R userDel(@RequestBody Long[] ids) { + return R.ok(userService.deleteUserByIds(ids)); + } - /** - * 添加用户 - * @param userDto 用户信息 - * @return success/false - */ - @SysLog("添加用户") - @PostMapping - @HasPermission("sys_user_add") - public R user(@RequestBody UserDTO userDto) { - return R.ok(userService.saveUser(userDto)); - } + /** + * 添加用户 + * + * @param userDto 用户信息 + * @return success/false + */ + @SysLog("添加用户") + @PostMapping + @HasPermission("sys_user_add") + public R user(@RequestBody UserDTO userDto) { + return R.ok(userService.saveUser(userDto)); + } - /** - * 分页查询用户 - * @param page 参数集 - * @param userDTO 查询参数列表 - * @return 用户集合 - */ - @GetMapping("/page") - @HasPermission("sys_user_view") - public R getUserPage(@ParameterObject Page page, @ParameterObject UserDTO userDTO) { - return R.ok(userService.getUsersWithRolePage(page, userDTO)); - } + /** + * 分页查询用户 + * + * @param page 参数集 + * @param userDTO 查询参数列表 + * @return 用户集合 + */ + @GetMapping("/page") + @HasPermission("sys_user_view") + public R getUserPage(@ParameterObject Page page, @ParameterObject UserDTO userDTO) { + return R.ok(userService.getUsersWithRolePage(page, userDTO)); + } - /** - * 管理员更新用户信息 - * @param userDto 用户信息 - * @return R - */ - @SysLog("更新用户信息") - @PutMapping - @HasPermission("sys_user_edit") - public R updateUser(@Valid @RequestBody UserDTO userDto) { - return R.ok(userService.updateUser(userDto)); - } + /** + * 管理员更新用户信息 + * + * @param userDto 用户信息 + * @return R + */ + @SysLog("更新用户信息") + @PutMapping + @HasPermission("sys_user_edit") + public R updateUser(@Valid @RequestBody UserDTO userDto) { + return R.ok(userService.updateUser(userDto)); + } - /** - * 修改个人信息 (当前用户) - * @param userDto userDto - * @return success/false - */ - @SysLog("修改个人信息") - @PutMapping("/personal/edit") - public R updateUserInfo(@Valid @RequestBody UserDTO userDto) { - return userService.updateUserInfo(userDto); - } + /** + * 修改个人信息 (当前用户) + * + * @param userDto userDto + * @return success/false + */ + @SysLog("修改个人信息") + @PutMapping("/personal/edit") + public R updateUserInfo(@Valid @RequestBody UserDTO userDto) { + return userService.updateUserInfo(userDto); + } - /** - * 修改个人密码 (当前用户) - * @param userDto 用户DTO对象,包含需要修改密码的用户信息 - * @return R 返回结果对象,包含修改密码操作的结果信息 - */ - @PutMapping("/personal/password") - public R updateUserPassword(@RequestBody UserDTO userDto) { - String username = SecurityUtils.getUser().getUsername(); - userDto.setUsername(username); - return userService.changePassword(userDto); - } + /** + * 修改个人密码 (当前用户) + * + * @param userDto 用户DTO对象,包含需要修改密码的用户信息 + * @return R 返回结果对象,包含修改密码操作的结果信息 + */ + @PutMapping("/personal/password") + public R updateUserPassword(@RequestBody UserDTO userDto) { + String username = SecurityUtils.getUser().getUsername(); + userDto.setUsername(username); + return userService.changePassword(userDto); + } - /** - * @param username 用户名称 - * @return 上级部门用户列表 - */ - @GetMapping("/ancestor/{username}") - public R listAncestorUsers(@PathVariable String username) { - return R.ok(userService.listAncestorUsers(username)); - } + /** + * @param username 用户名称 + * @return 上级部门用户列表 + */ + @GetMapping("/ancestor/{username}") + public R listAncestorUsers(@PathVariable String username) { + return R.ok(userService.listAncestorUsers(username)); + } - /** - * 导出excel 表格 - * @param userDTO 查询条件 - * @return - */ - @ResponseExcel - @GetMapping("/export") - @HasPermission("sys_user_export") - public List export(UserDTO userDTO, Long[] ids) { - return userService.listUser(userDTO, ids); - } + /** + * 导出excel 表格 + * + * @param userDTO 查询条件 + * @return + */ + @ResponseExcel + @GetMapping("/export") + @HasPermission("sys_user_export") + public List export(UserDTO userDTO, Long[] ids) { + return userService.listUser(userDTO, ids); + } - /** - * 导入用户 - * @param excelVOList 用户列表 - * @param bindingResult 错误信息列表 - * @return R - */ - @PostMapping("/import") - @HasPermission("sys_user_export") - public R importUser(@RequestExcel List excelVOList, BindingResult bindingResult) { - return userService.importUser(excelVOList, bindingResult); - } + /** + * 导入用户 + * + * @param excelVOList 用户列表 + * @param bindingResult 错误信息列表 + * @return R + */ + @PostMapping("/import") + @HasPermission("sys_user_export") + public R importUser(@RequestExcel List excelVOList, BindingResult bindingResult) { + return userService.importUser(excelVOList, bindingResult); + } - /** - * 锁定指定用户 - * @param username 用户名 - * @return R - */ - @Inner - @PutMapping("/lock/{username}") - public R lockUser(@PathVariable String username) { - return userService.lockUser(username); - } + /** + * 锁定指定用户 + * + * @param username 用户名 + * @return R + */ + @Inner + @PutMapping("/lock/{username}") + public R lockUser(@PathVariable String username) { + return userService.lockUser(username); + } - /** - * 解绑定接口 - * @param type 需要解绑定的类型 - * @return R 返回结果对象,包含解绑定操作的结果信息 - */ - @PostMapping("/unbinding") - public R unbinding(String type) { - return userService.unbinding(type); - } + /** + * 解绑定接口 + * + * @param type 需要解绑定的类型 + * @return R 返回结果对象,包含解绑定操作的结果信息 + */ + @PostMapping("/unbinding") + public R unbinding(String type) { + return userService.unbinding(type); + } - /** - * 校验密码接口 - * @param password 需要校验的密码 - * @return R 返回结果对象,包含校验密码操作的结果信息 - */ - @PostMapping("/check") - public R check(String password) { - return userService.checkPassword(SecurityUtils.getUser().getUsername(), password); - } + /** + * 校验密码接口 + * + * @param password 需要校验的密码 + * @return R 返回结果对象,包含校验密码操作的结果信息 + */ + @PostMapping("/check") + public R check(String password) { + return userService.checkPassword(SecurityUtils.getUser().getUsername(), password); + } - /** - * 根据角色ID列表获取用户ID列表接口 - * @param roleIdList 角色ID列表 - * @return R 返回结果对象,包含根据角色ID列表获取到的用户ID列表信息 - */ - @Inner - @GetMapping("/getUserIdListByRoleIdList") - public R> getUserIdListByRoleIdList(Long[] roleIdList) { - return R.ok(userService.listUserIdByRoleIds(CollUtil.toList(roleIdList))); - } + /** + * 根据角色ID列表获取用户ID列表接口 + * + * @param roleIdList 角色ID列表 + * @return R 返回结果对象,包含根据角色ID列表获取到的用户ID列表信息 + */ + @Inner + @GetMapping("/getUserIdListByRoleIdList") + public R> getUserIdListByRoleIdList(Long[] roleIdList) { + return R.ok(userService.listUserIdByRoleIds(CollUtil.toList(roleIdList))); + } - /** - * 根据部门ID列表获取用户ID列表接口 - * @param deptIdList 部门ID列表 - * @return R 返回结果对象,包含根据部门ID列表获取到的用户ID列表信息 - */ - @Inner - @GetMapping("/getUserIdListByDeptIdList") - public R> getUserIdListByDeptIdList(Long[] deptIdList) { - return R.ok(userService.listUserIdByDeptIds(CollUtil.toList(deptIdList))); - } + /** + * 根据部门ID列表获取用户ID列表接口 + * + * @param deptIdList 部门ID列表 + * @return R 返回结果对象,包含根据部门ID列表获取到的用户ID列表信息 + */ + @Inner + @GetMapping("/getUserIdListByDeptIdList") + public R> getUserIdListByDeptIdList(Long[] deptIdList) { + return R.ok(userService.listUserIdByDeptIds(CollUtil.toList(deptIdList))); + } - /** - * 根据用户名获取用户列表 - * @param username 用户名 - * @return 用户列表 - */ - @GetMapping("/getUserListByUserName") - public R> getUserListByUserName(String username) { - return R.ok(TenantBroker - .noneAs(() -> userService.list(Wrappers.lambdaQuery().like(SysUser::getUsername, username)))); - } + /** + * 根据用户名获取用户列表 + * + * @param username 用户名 + * @return 用户列表 + */ + @GetMapping("/getUserListByUserName") + public R> getUserListByUserName(String username) { + return R.ok(TenantBroker + .noneAs(() -> userService.list(Wrappers.lambdaQuery().like(SysUser::getUsername, username)))); + } - /** - * 根据IDS获取用户列表 - * @param userIds ID列表 - * @return 用户列表 - */ - @GetMapping("/list") - public R> getUserListByIds(@RequestParam("userIds") List userIds) { - return R.ok(TenantBroker - .noneAs(() -> userService.list(Wrappers.lambdaQuery().in(SysUser::getUserId, userIds)))); - } + /** + * 根据IDS获取用户列表 + * + * @param userIds ID列表 + * @return 用户列表 + */ + @GetMapping("/list") + public R> getUserListByIds(@RequestParam("userIds") List userIds) { + return R.ok(TenantBroker + .noneAs(() -> userService.list(Wrappers.lambdaQuery().in(SysUser::getUserId, userIds)))); + } + + /** + * 获取当前用户的部门列表 + * + * @return 部门列表 + */ + @GetMapping("/personal/dept") + @Operation(summary = "获取当前用户的部门列表", description = "返回当前登录用户所属的所有部门") + public R> getUserDeptList() { + return R.ok(userService.getUserDeptList()); + } + + /** + * 切换当前用户的部门 + * + * @param userDTO 部门ID + * @return 操作结果 + */ + @PutMapping("/personal/dept/update") + @Operation(summary = "切换当前部门", description = "切换当前用户的工作部门") + public R updateUserDept(@RequestBody UserDTO userDTO) { + return userService.updateUserDept(userDTO.getDeptId()); + } } diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/AbstractLoginHandler.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/AbstractLoginHandler.java index f11ba6efd..1e51822bb 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/AbstractLoginHandler.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/AbstractLoginHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/CasLoginHandler.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/CasLoginHandler.java index 2975acd6f..88f4deda4 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/CasLoginHandler.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/CasLoginHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -17,6 +17,7 @@ package com.pig4cloud.pigx.admin.handler; +import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.pig4cloud.pigx.admin.api.dto.UserDTO; import com.pig4cloud.pigx.admin.api.dto.UserInfo; @@ -41,47 +42,54 @@ import org.springframework.stereotype.Component; @AllArgsConstructor public class CasLoginHandler extends AbstractLoginHandler { - private final SysSocialDetailsMapper sysSocialDetailsMapper; + private final SysSocialDetailsMapper sysSocialDetailsMapper; - private final SysUserService sysUserService; + private final SysUserService sysUserService; - /** - * cas 回到的ticket - *

- * 通过ticket 调用CAS获取唯一标识 - * @param ticket - * @return - */ - @Override - @SneakyThrows - public String identify(String ticket) { - SysSocialDetails condition = new SysSocialDetails(); - condition.setType(LoginTypeEnum.CAS.getType()); - SysSocialDetails socialDetails = sysSocialDetailsMapper.selectOne(new QueryWrapper<>(condition)); - // remark 字段填写 CAS 服务器的URL - Cas30ProxyTicketValidator cas30ProxyTicketValidator = new Cas30ProxyTicketValidator(socialDetails.getRemark()); - Assertion validate = cas30ProxyTicketValidator.validate(ticket, socialDetails.getRedirectUrl()); - return validate.getPrincipal().getName(); - } + /** + * cas 回到的ticket + *

+ * 通过ticket 调用CAS获取唯一标识 + * + * @param ticket + * @return + */ + @Override + @SneakyThrows + public String identify(String ticket) { + SysSocialDetails condition = new SysSocialDetails(); + condition.setType(LoginTypeEnum.CAS.getType()); + SysSocialDetails socialDetails = sysSocialDetailsMapper.selectOne(new QueryWrapper<>(condition)); + // remark 字段填写 CAS 服务器的URL + Cas30ProxyTicketValidator cas30ProxyTicketValidator = new Cas30ProxyTicketValidator(socialDetails.getRemark()); + Assertion validate = cas30ProxyTicketValidator.validate(ticket, socialDetails.getRedirectUrl()); + return validate.getPrincipal().getName(); + } - /** + /** * 根据用户名获取用户信息 + * * @param username 用户名 * @return 用户信息对象,如果用户不存在则返回null - */ - @Override - public UserInfo info(String username) { + */ + @Override + public UserInfo info(String username) { + if (StrUtil.isBlank(username)) { + log.warn("CAS用户名为空,无法获取用户信息"); + return null; + } + UserDTO userDTO = new UserDTO(); userDTO.setUsername(username); R userInfoR = sysUserService.getUserInfo(userDTO); if (userInfoR.getData() == null) { - log.info("CAS 不存在用户:{}", username); - return null; - } + log.info("CAS 不存在用户:{}", username); + return null; + } return userInfoR.getData(); - } + } } diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/DingTalkLoginHandler.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/DingTalkLoginHandler.java index 1f6e06d26..45aca172a 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/DingTalkLoginHandler.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/DingTalkLoginHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -17,6 +17,7 @@ package com.pig4cloud.pigx.admin.handler; +import cn.hutool.core.util.StrUtil; import cn.hutool.http.HttpRequest; import cn.hutool.http.HttpUtil; import cn.hutool.json.JSONUtil; @@ -91,6 +92,11 @@ public class DingTalkLoginHandler extends AbstractLoginHandler { */ @Override public UserInfo info(String openId) { + if (StrUtil.isBlank(openId)) { + log.warn("钉钉openId为空,无法获取用户信息"); + return null; + } + UserDTO userDTO = new UserDTO(); userDTO.setWxDingUserid(openId); diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/GiteeLoginHandler.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/GiteeLoginHandler.java index 3941d3ff8..77cc4043a 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/GiteeLoginHandler.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/GiteeLoginHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -17,6 +17,7 @@ package com.pig4cloud.pigx.admin.handler; +import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.URLUtil; import cn.hutool.http.HttpUtil; import cn.hutool.json.JSONObject; @@ -87,6 +88,10 @@ public class GiteeLoginHandler extends AbstractLoginHandler { */ @Override public UserInfo info(String identify) { + if (StrUtil.isBlank(identify)) { + log.warn("Gitee标识为空,无法获取用户信息"); + return null; + } UserDTO userDTO = new UserDTO(); userDTO.setGiteeLogin(identify); diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/LoginHandler.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/LoginHandler.java index 51dfd8703..a6124e96e 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/LoginHandler.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/LoginHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/MiniAppLoginHandler.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/MiniAppLoginHandler.java index ed48115c6..ca3b1cb1a 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/MiniAppLoginHandler.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/MiniAppLoginHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -17,10 +17,12 @@ package com.pig4cloud.pigx.admin.handler; +import cn.hutool.core.util.StrUtil; import cn.hutool.http.HttpUtil; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.pig4cloud.pigx.admin.api.constant.UpmsErrorCodes; import com.pig4cloud.pigx.admin.api.dto.UserDTO; import com.pig4cloud.pigx.admin.api.dto.UserInfo; import com.pig4cloud.pigx.admin.api.entity.SysSocialDetails; @@ -30,6 +32,7 @@ import com.pig4cloud.pigx.admin.service.SysUserService; import com.pig4cloud.pigx.common.core.constant.SecurityConstants; import com.pig4cloud.pigx.common.core.constant.enums.LoginTypeEnum; import com.pig4cloud.pigx.common.core.exception.CheckedException; +import com.pig4cloud.pigx.common.core.util.MsgUtils; import com.pig4cloud.pigx.common.core.util.R; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -46,72 +49,76 @@ import org.springframework.stereotype.Component; @AllArgsConstructor public class MiniAppLoginHandler extends AbstractLoginHandler { - private final SysUserService sysUserService; + private final SysUserService sysUserService; - private final SysSocialDetailsMapper sysSocialDetailsMapper; + private final SysSocialDetailsMapper sysSocialDetailsMapper; - /** - * 小程序登录传入code - *

- * 通过code 调用qq 获取唯一标识 - * - * @param code - * @return - */ - @Override - public String identify(String code) { - SysSocialDetails condition = new SysSocialDetails(); - condition.setType(LoginTypeEnum.MINI_APP.getType()); - SysSocialDetails socialDetails = sysSocialDetailsMapper.selectOne(new QueryWrapper<>(condition)); + /** + * 小程序登录传入code + *

+ * 通过code 调用qq 获取唯一标识 + * + * @param code + * @return + */ + @Override + public String identify(String code) { + SysSocialDetails condition = new SysSocialDetails(); + condition.setType(LoginTypeEnum.MINI_APP.getType()); + SysSocialDetails socialDetails = sysSocialDetailsMapper.selectOne(new QueryWrapper<>(condition)); - String url = String.format(SecurityConstants.MINI_APP_AUTHORIZATION_CODE_URL, socialDetails.getAppId(), - socialDetails.getAppSecret(), code); - String result = HttpUtil.get(url); - log.debug("微信小程序响应报文:{}", result); - JSONObject resultJsonObj = JSONUtil.parseObj(result); + String url = String.format(SecurityConstants.MINI_APP_AUTHORIZATION_CODE_URL, socialDetails.getAppId(), + socialDetails.getAppSecret(), code); + String result = HttpUtil.get(url); + log.debug("微信小程序响应报文:{}", result); + JSONObject resultJsonObj = JSONUtil.parseObj(result); - if (resultJsonObj.containsKey("errcode")) { - log.error("微信小程序登录失败:{}", result); - throw new CheckedException("微信小程序登录失败"); - } + if (resultJsonObj.containsKey("errcode")) { + log.error("微信小程序登录失败:{}", result); + throw new CheckedException(MsgUtils.getMessage(UpmsErrorCodes.SYS_MINIAPP_LOGIN_FAILED)); + } - Object obj = resultJsonObj.get("openid"); - return obj.toString(); - } + return resultJsonObj.getStr("openid"); + } - /** - * 根据openId获取用户信息 - * - * @param openId 用户openId - * @return 用户信息对象,未找到时返回null - */ - @Override - public UserInfo info(String openId) { - UserDTO userDTO = new UserDTO(); - userDTO.setMiniOpenid(openId); + /** + * 根据openId获取用户信息 + * + * @param openId 用户openId + * @return 用户信息对象,未找到时返回null + */ + @Override + public UserInfo info(String openId) { + if (StrUtil.isBlank(openId)) { + log.warn("小程序openId为空,无法获取用户信息"); + return null; + } - R userInfoR = sysUserService.getUserInfo(userDTO); + UserDTO userDTO = new UserDTO(); + userDTO.setMiniOpenid(openId); - if (userInfoR.getData() == null) { - log.info("小程序不存在用户:{}", openId); - return null; - } + R userInfoR = sysUserService.getUserInfo(userDTO); - return userInfoR.getData(); - } + if (userInfoR.getData() == null) { + log.info("小程序不存在用户:{}", openId); + return null; + } - /** - * 绑定逻辑 - * - * @param user 用户实体 - * @param identify 渠道返回唯一标识 - * @return - */ - @Override - public Boolean bind(SysUser user, String identify) { - user.setMiniOpenid(identify); - sysUserService.updateById(user); - return true; - } + return userInfoR.getData(); + } + + /** + * 绑定逻辑 + * + * @param user 用户实体 + * @param identify 渠道返回唯一标识 + * @return + */ + @Override + public Boolean bind(SysUser user, String identify) { + user.setMiniOpenid(identify); + sysUserService.updateById(user); + return true; + } } diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/OscChinaLoginHandler.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/OscChinaLoginHandler.java index b2bfeb0ca..8a51db533 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/OscChinaLoginHandler.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/OscChinaLoginHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -17,6 +17,7 @@ package com.pig4cloud.pigx.admin.handler; +import cn.hutool.core.util.StrUtil; import cn.hutool.http.HttpUtil; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; @@ -86,8 +87,7 @@ public class OscChinaLoginHandler extends AbstractLoginHandler { JSONObject userInfo = JSONUtil.parseObj(resp); // 开源中国唯一标识 - String id = userInfo.getStr("id"); - return id; + return userInfo.getStr("id"); } /** @@ -98,6 +98,11 @@ public class OscChinaLoginHandler extends AbstractLoginHandler { */ @Override public UserInfo info(String identify) { + if (StrUtil.isBlank(identify)) { + log.warn("开源中国标识为空,无法获取用户信息"); + return null; + } + UserDTO userDTO = new UserDTO(); userDTO.setOscId(identify); diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/SmsLoginHandler.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/SmsLoginHandler.java index f9bf59779..c59aa42cd 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/SmsLoginHandler.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/SmsLoginHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -17,6 +17,7 @@ package com.pig4cloud.pigx.admin.handler; +import cn.hutool.core.util.StrUtil; import com.pig4cloud.pigx.admin.api.dto.UserDTO; import com.pig4cloud.pigx.admin.api.dto.UserInfo; import com.pig4cloud.pigx.admin.api.entity.SysUser; @@ -48,23 +49,28 @@ public class SmsLoginHandler extends AbstractLoginHandler { } /** - * 通过手机号获取用户信息 - * @param identify 手机号标识 - * @return 用户信息,未找到时返回null + * 通过手机号获取用户信息 + * @param identify 手机号标识 + * @return 用户信息,未找到时返回null */ @Override public UserInfo info(String identify) { - UserDTO userDTO = new UserDTO(); - userDTO.setPhone(identify); - - R userInfoR = sysUserService.getUserInfo(userDTO); - - if (userInfoR.getData() == null) { - log.info("手机号 不存在用户:{}", identify); + if (StrUtil.isBlank(identify)) { + log.warn("手机号为空,无法获取用户信息"); return null; } - return userInfoR.getData(); + UserDTO userDTO = new UserDTO(); + userDTO.setPhone(identify); + + R userInfoR = sysUserService.getUserInfo(userDTO); + + if (userInfoR.getData() == null) { + log.info("手机号 不存在用户:{}", identify); + return null; + } + + return userInfoR.getData(); } /** diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/WeChatCPLoginHandler.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/WeChatCPLoginHandler.java index af636b1ba..5bdf80acc 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/WeChatCPLoginHandler.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/WeChatCPLoginHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -17,6 +17,7 @@ package com.pig4cloud.pigx.admin.handler; +import cn.hutool.core.util.StrUtil; import cn.hutool.http.HttpUtil; import cn.hutool.json.JSONUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; @@ -82,6 +83,11 @@ public class WeChatCPLoginHandler extends AbstractLoginHandler { */ @Override public UserInfo info(String openId) { + if (StrUtil.isBlank(openId)) { + log.warn("企业微信userid为空,无法获取用户信息"); + return null; + } + UserDTO userDTO = new UserDTO(); userDTO.setWxCpUserid(openId); diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/WeChatLoginHandler.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/WeChatLoginHandler.java index 2c347f6e7..f74287016 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/WeChatLoginHandler.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/WeChatLoginHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -17,6 +17,7 @@ package com.pig4cloud.pigx.admin.handler; +import cn.hutool.core.util.StrUtil; import cn.hutool.http.HttpUtil; import cn.hutool.json.JSONUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; @@ -42,63 +43,70 @@ import org.springframework.stereotype.Component; @AllArgsConstructor public class WeChatLoginHandler extends AbstractLoginHandler { - private final SysUserService sysUserService; + private final SysUserService sysUserService; - private final SysSocialDetailsMapper sysSocialDetailsMapper; + private final SysSocialDetailsMapper sysSocialDetailsMapper; - /** - * 微信登录传入code - *

- * 通过code 调用qq 获取唯一标识 - * @param code - * @return - */ - @Override - public String identify(String code) { - SysSocialDetails condition = new SysSocialDetails(); - condition.setType(LoginTypeEnum.WECHAT.getType()); - SysSocialDetails socialDetails = sysSocialDetailsMapper.selectOne(new QueryWrapper<>(condition)); + /** + * 微信登录传入code + *

+ * 通过code 调用qq 获取唯一标识 + * + * @param code + * @return + */ + @Override + public String identify(String code) { + SysSocialDetails condition = new SysSocialDetails(); + condition.setType(LoginTypeEnum.WECHAT.getType()); + SysSocialDetails socialDetails = sysSocialDetailsMapper.selectOne(new QueryWrapper<>(condition)); - String url = String.format(SecurityConstants.WX_AUTHORIZATION_CODE_URL, socialDetails.getAppId(), - socialDetails.getAppSecret(), code); - String result = HttpUtil.get(url); - log.debug("微信响应报文:{}", result); + String url = String.format(SecurityConstants.WX_AUTHORIZATION_CODE_URL, socialDetails.getAppId(), + socialDetails.getAppSecret(), code); + String result = HttpUtil.get(url); + log.debug("微信响应报文:{}", result); - Object obj = JSONUtil.parseObj(result).get("openid"); - return obj.toString(); - } + return JSONUtil.parseObj(result).getStr("openid"); + } - /** - * 根据微信openId获取用户信息 - * @param openId 微信openId - * @return 用户信息,未找到时返回null - */ - @Override - public UserInfo info(String openId) { - UserDTO userDTO = new UserDTO(); - userDTO.setWxOpenid(openId); + /** + * 根据微信openId获取用户信息 + * + * @param openId 微信openId + * @return 用户信息,未找到时返回null + */ + @Override + public UserInfo info(String openId) { + if (StrUtil.isBlank(openId)) { + log.warn("微信openId为空,无法获取用户信息"); + return null; + } - R userInfoR = sysUserService.getUserInfo(userDTO); + UserDTO userDTO = new UserDTO(); + userDTO.setWxOpenid(openId); - if (userInfoR.getData() == null) { - log.info("微信 不存在用户:{}", openId); - return null; - } + R userInfoR = sysUserService.getUserInfo(userDTO); - return userInfoR.getData(); - } + if (userInfoR.getData() == null) { + log.info("微信 不存在用户:{}", openId); + return null; + } - /** - * 绑定逻辑 - * @param user 用户实体 - * @param identify 渠道返回唯一标识 - * @return - */ - @Override - public Boolean bind(SysUser user, String identify) { - user.setWxOpenid(identify); - sysUserService.updateById(user); - return true; - } + return userInfoR.getData(); + } + + /** + * 绑定逻辑 + * + * @param user 用户实体 + * @param identify 渠道返回唯一标识 + * @return + */ + @Override + public Boolean bind(SysUser user, String identify) { + user.setWxOpenid(identify); + sysUserService.updateById(user); + return true; + } } diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysAuditLogMapper.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysAuditLogMapper.java index f13370900..c41b1e898 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysAuditLogMapper.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysAuditLogMapper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysDeptMapper.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysDeptMapper.java index 249b4a45e..ef66ea8ec 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysDeptMapper.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysDeptMapper.java @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysDictItemMapper.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysDictItemMapper.java index 5d7dd738c..53733af40 100755 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysDictItemMapper.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysDictItemMapper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysDictMapper.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysDictMapper.java index 4af6ffb4a..5b824d46f 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysDictMapper.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysDictMapper.java @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysFileGroupMapper.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysFileGroupMapper.java index c55dd9a1f..fcf384d7b 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysFileGroupMapper.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysFileGroupMapper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysFileMapper.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysFileMapper.java index 680c89624..8cad8a313 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysFileMapper.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysFileMapper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysI18nMapper.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysI18nMapper.java index 846ae3d13..887620cb0 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysI18nMapper.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysI18nMapper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysLogMapper.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysLogMapper.java index d6d84f549..e2a7ca1a0 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysLogMapper.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysLogMapper.java @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysMenuMapper.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysMenuMapper.java index d7dd20bbf..617c50834 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysMenuMapper.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysMenuMapper.java @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysOauthClientDetailsMapper.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysOauthClientDetailsMapper.java index 6e8201873..ec687633a 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysOauthClientDetailsMapper.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysOauthClientDetailsMapper.java @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysPostMapper.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysPostMapper.java index 08552c1c8..7af4a06c7 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysPostMapper.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysPostMapper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysPublicParamMapper.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysPublicParamMapper.java index 24c167c61..4f7cd86ce 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysPublicParamMapper.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysPublicParamMapper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysRoleMapper.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysRoleMapper.java index 97467348f..6626a9b56 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysRoleMapper.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysRoleMapper.java @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysRoleMenuMapper.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysRoleMenuMapper.java index a51573d48..9225215f7 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysRoleMenuMapper.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysRoleMenuMapper.java @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysRouteConfMapper.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysRouteConfMapper.java index d7e869a48..51f6731e5 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysRouteConfMapper.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysRouteConfMapper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysScheduleMapper.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysScheduleMapper.java index d81ceeec4..23d20c1ba 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysScheduleMapper.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysScheduleMapper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysSocialDetailsMapper.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysSocialDetailsMapper.java index ff606f46b..3d077dd78 100755 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysSocialDetailsMapper.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysSocialDetailsMapper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysTenantMapper.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysTenantMapper.java index 9a1f0b893..83c520001 100755 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysTenantMapper.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysTenantMapper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysTenantUserMapper.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysTenantUserMapper.java index 26200ad75..d59546fec 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysTenantUserMapper.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysTenantUserMapper.java @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysUserMapper.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysUserMapper.java index e0b9361f3..067f3fe12 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysUserMapper.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysUserMapper.java @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysUserRoleMapper.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysUserRoleMapper.java index 22d37d9f9..dd5d863ff 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysUserRoleMapper.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysUserRoleMapper.java @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysAuditLogService.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysAuditLogService.java index 93ee03f82..70974bf26 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysAuditLogService.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysAuditLogService.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysDeptService.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysDeptService.java index c62aeaf4c..e0cd38ecd 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysDeptService.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysDeptService.java @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysDictItemService.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysDictItemService.java index dc2f37f2d..427163f2a 100755 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysDictItemService.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysDictItemService.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysDictService.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysDictService.java index 265cebdf0..066f61183 100755 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysDictService.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysDictService.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysFileService.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysFileService.java index 6af8fab37..edca549fe 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysFileService.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysFileService.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysLogService.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysLogService.java index 221114342..71164a6a7 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysLogService.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysLogService.java @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysMenuService.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysMenuService.java index 02de41df8..278e7837a 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysMenuService.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysMenuService.java @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysMessageService.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysMessageService.java index 400acd4ff..14ccb1699 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysMessageService.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysMessageService.java @@ -37,6 +37,7 @@ public interface SysMessageService extends IService { /** * 读取信息 + * * @param id id * @return true/false */ @@ -44,6 +45,7 @@ public interface SysMessageService extends IService { /** * 获取信息 + * * @param id id * @return messageVO */ @@ -61,13 +63,16 @@ public interface SysMessageService extends IService { /** * 发送手机验证码 - * @param mobile mobile - * @return code + * + * @param mobile 手机号码 + * @param registered 是否已注册 + * @return 发送结果 */ - R sendSmsCode(String mobile); + R sendSmsCode(String mobile, boolean registered); /** * 发送短信 + * * @param messageSmsDTO 消息 短信 DTO * @return {@link R } */ @@ -75,6 +80,7 @@ public interface SysMessageService extends IService { /** * 发送邮件 + * * @param messageEmailDTO 留言内容 电子邮件 DTO * @return {@link R } */ @@ -82,6 +88,7 @@ public interface SysMessageService extends IService { /** * 发送钩子消息 + * * @param messageHookDTO 消息挂钩 DTO * @return {@link R } */ @@ -89,6 +96,7 @@ public interface SysMessageService extends IService { /** * 列出 Hook 业务代码 + * * @param messageHookDTO 消息钩子 DTO * @return {@link R } */ diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysOauthClientDetailsService.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysOauthClientDetailsService.java index f7fdad9a8..2ae021296 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysOauthClientDetailsService.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysOauthClientDetailsService.java @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysPostService.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysPostService.java index 645370813..9aae9fb15 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysPostService.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysPostService.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysPublicParamService.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysPublicParamService.java index d28b9619e..39ed14055 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysPublicParamService.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysPublicParamService.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysRoleMenuService.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysRoleMenuService.java index 73c6eb53a..ea828ac36 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysRoleMenuService.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysRoleMenuService.java @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysRoleService.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysRoleService.java index ea0502f82..424c2d85e 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysRoleService.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysRoleService.java @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysRouteConfService.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysRouteConfService.java index 42156b8cc..82c079f35 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysRouteConfService.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysRouteConfService.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysScheduleService.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysScheduleService.java index 7eb4295dc..c6e5f5cc7 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysScheduleService.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysScheduleService.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysSocialDetailsService.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysSocialDetailsService.java index 263653f91..b9e57c401 100755 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysSocialDetailsService.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysSocialDetailsService.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysTenantService.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysTenantService.java index 4d0c0fea4..7443bcac6 100755 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysTenantService.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysTenantService.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -114,8 +114,11 @@ public interface SysTenantService extends IService { R updateUserTenant(UserDTO userDto); /** - * 检查或更新租户信息 + * 获取或更新当前用户的租户信息 + *

+ * 如果当前租户已过期或无效,则自动切换到用户的其他有效租户 + * @return 当前有效的租户对象,如果无有效租户则返回null */ - Long getOrUpdateTenant(); + SysTenant getOrUpdateTenant(); } diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysUserRoleService.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysUserRoleService.java index 5b3d23262..dea4e2006 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysUserRoleService.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysUserRoleService.java @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysUserService.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysUserService.java index bfc61d1ba..ccbb74237 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysUserService.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysUserService.java @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -25,6 +25,7 @@ import com.baomidou.mybatisplus.extension.service.IService; import com.pig4cloud.pigx.admin.api.dto.RegisterUserDTO; import com.pig4cloud.pigx.admin.api.dto.UserDTO; import com.pig4cloud.pigx.admin.api.dto.UserInfo; +import com.pig4cloud.pigx.admin.api.entity.SysDept; import com.pig4cloud.pigx.admin.api.entity.SysUser; import com.pig4cloud.pigx.admin.api.vo.UserExcelVO; import com.pig4cloud.pigx.admin.api.vo.UserVO; @@ -39,142 +40,176 @@ import java.util.List; */ public interface SysUserService extends IService { - /** - * 查询用户信息 - * @param userDTO 用户数据传输对象 - * @return 用户信息对象 - */ - R getUserInfo(UserDTO userDTO); + /** + * 查询用户信息 + * + * @param userDTO 用户数据传输对象 + * @return 用户信息对象 + */ + R getUserInfo(UserDTO userDTO); - /** - * 分页查询用户信息(含有角色信息) - * @param page 分页对象 - * @param userDTO 参数列表 - * @return - */ - IPage getUsersWithRolePage(Page page, UserDTO userDTO); + /** + * 分页查询用户信息(含有角色信息) + * + * @param page 分页对象 + * @param userDTO 参数列表 + * @return + */ + IPage getUsersWithRolePage(Page page, UserDTO userDTO); - /** - * 删除用户 - * @param ids 用户 - * @return boolean - */ - Boolean deleteUserByIds(Long[] ids); + /** + * 删除用户 + * + * @param ids 用户 + * @return boolean + */ + Boolean deleteUserByIds(Long[] ids); - /** - * 更新当前用户基本信息 - * @param userDto 用户信息 - * @return Boolean - */ - R updateUserInfo(UserDTO userDto); + /** + * 更新当前用户基本信息 + * + * @param userDto 用户信息 + * @return Boolean + */ + R updateUserInfo(UserDTO userDto); - /** - * 更新指定用户信息 - * @param userDto 用户信息DTO对象 - * @return 更新操作是否成功 - */ - Boolean updateUser(UserDTO userDto); + /** + * 更新指定用户信息 + * + * @param userDto 用户信息DTO对象 + * @return 更新操作是否成功 + */ + Boolean updateUser(UserDTO userDto); - /** - * 通过ID查询用户信息 - * @param id 用户ID - * @return 用户信息 - */ - UserVO selectUserVoById(Long id); + /** + * 通过ID查询用户信息 + * + * @param id 用户ID + * @return 用户信息 + */ + UserVO selectUserVoById(Long id); - /** - * 查询上级部门的用户信息 - * @param username 用户名 - * @return R - */ - List listAncestorUsers(String username); + /** + * 查询上级部门的用户信息 + * + * @param username 用户名 + * @return R + */ + List listAncestorUsers(String username); - /** - * 保存用户信息 - * @param userDto DTO 对象 - * @return success/fail - */ - Boolean saveUser(UserDTO userDto); + /** + * 保存用户信息 + * + * @param userDto DTO 对象 + * @return success/fail + */ + Boolean saveUser(UserDTO userDto); - /** - * 查询全部的用户 - * @param userDTO 查询条件 - * @param ids 目标列表 - * @return list - */ - List listUser(UserDTO userDTO, Long[] ids); + /** + * 查询全部的用户 + * + * @param userDTO 查询条件 + * @param ids 目标列表 + * @return list + */ + List listUser(UserDTO userDTO, Long[] ids); - /** - * excel 导入用户 - * @param excelVOList excel 列表数据 - * @param bindingResult 错误数据 - * @return ok fail - */ - R importUser(List excelVOList, BindingResult bindingResult); + /** + * excel 导入用户 + * + * @param excelVOList excel 列表数据 + * @param bindingResult 错误数据 + * @return ok fail + */ + R importUser(List excelVOList, BindingResult bindingResult); - /** - * 注册用户 - * @param userDto 用户信息 - * @return success/false - */ - R registerUser(RegisterUserDTO userDto); + /** + * 注册用户 + * + * @param userDto 用户信息 + * @return success/false + */ + R registerUser(RegisterUserDTO userDto); - /** - * 锁定用户 - * @param username 用户名 - * @return R - */ - R lockUser(String username); + /** + * 锁定用户 + * + * @param username 用户名 + * @return R + */ + R lockUser(String username); - /** - * 修改用户密码 - * @param userDto 包含用户信息的DTO对象 - * @return 操作结果 - */ - R changePassword(UserDTO userDto); + /** + * 修改用户密码 + * + * @param userDto 包含用户信息的DTO对象 + * @return 操作结果 + */ + R changePassword(UserDTO userDto); - /** - * 解绑社交登录 - * @param type 社交登录类型 - * @return R - */ - R unbinding(String type); + /** + * 解绑社交登录 + * + * @param type 社交登录类型 + * @return R + */ + R unbinding(String type); - /** - * 校验密码 - * @param username 用户名 - * @param password 密码 - * @return R - */ - R checkPassword(String username, String password); + /** + * 校验密码 + * + * @param username 用户名 + * @param password 密码 + * @return R + */ + R checkPassword(String username, String password); - /** - * 根据角色ID列表获取用户ID列表接口 - * @param roleIdList 角色ID列表 - * @return List 返回结果对象,包含根据角色ID列表获取到的用户ID列表信息 - */ - List listUserIdByRoleIds(List roleIdList); + /** + * 根据角色ID列表获取用户ID列表接口 + * + * @param roleIdList 角色ID列表 + * @return List 返回结果对象,包含根据角色ID列表获取到的用户ID列表信息 + */ + List listUserIdByRoleIds(List roleIdList); - /** - * 根据部门ID列表获取用户ID列表接口 - * @param deptIdList 部门ID列表 - * @return List 返回结果对象,包含根据部门ID列表获取到的用户ID列表信息 - */ - List listUserIdByDeptIds(List deptIdList); + /** + * 根据部门ID列表获取用户ID列表接口 + * + * @param deptIdList 部门ID列表 + * @return List 返回结果对象,包含根据部门ID列表获取到的用户ID列表信息 + */ + List listUserIdByDeptIds(List deptIdList); - /** - * 重置用户密码 - * @param userDto 用户信息DTO - * @return 操作结果,包含是否成功的布尔值 - */ - R resetUserPassword(RegisterUserDTO userDto); + /** + * 重置用户密码 + * + * @param userDto 用户信息DTO + * @return 操作结果,包含是否成功的布尔值 + */ + R resetUserPassword(RegisterUserDTO userDto); - /** - * 找回用户密码 - * @param userDto 用户信息DTO - * @param code 验证码 - * @return 操作结果,包含是否成功的布尔值 - */ - R forgetUserPassword(RegisterUserDTO userDto, String code); + /** + * 找回用户密码 + * + * @param userDto 用户信息DTO + * @param code 验证码 + * @return 操作结果,包含是否成功的布尔值 + */ + R forgetUserPassword(RegisterUserDTO userDto, String code); + + /** + * 获取当前用户的部门列表 + * + * @return 部门列表 + */ + List getUserDeptList(); + + /** + * 切换用户当前部门 + * + * @param deptId 部门ID + * @return 操作结果 + */ + R updateUserDept(Long deptId); } diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/ConnectServiceImpl.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/ConnectServiceImpl.java index b86d6aa56..dcb067e23 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/ConnectServiceImpl.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/ConnectServiceImpl.java @@ -18,6 +18,7 @@ import com.dingtalk.api.response.OapiGettokenResponse; import com.dingtalk.api.response.OapiUserListidResponse; import com.dingtalk.api.response.OapiV2DepartmentListsubResponse; import com.dingtalk.api.response.OapiV2UserGetResponse; +import com.pig4cloud.pigx.admin.api.constant.UpmsErrorCodes; import com.pig4cloud.pigx.admin.api.dto.UserDTO; import com.pig4cloud.pigx.admin.api.entity.SysDept; import com.pig4cloud.pigx.admin.api.entity.SysSocialDetails; @@ -28,7 +29,6 @@ import com.pig4cloud.pigx.admin.service.SysDeptService; import com.pig4cloud.pigx.admin.service.SysUserService; import com.pig4cloud.pigx.common.core.constant.SecurityConstants; import com.pig4cloud.pigx.common.core.constant.enums.LoginTypeEnum; -import com.pig4cloud.pigx.common.core.exception.ErrorCodes; import com.pig4cloud.pigx.common.core.util.MsgUtils; import com.pig4cloud.pigx.common.core.util.R; import lombok.RequiredArgsConstructor; @@ -62,274 +62,306 @@ import java.util.List; @RequiredArgsConstructor public class ConnectServiceImpl implements ConnectService { - private final SysSocialDetailsMapper sysSocialDetailsMapper; + private final SysSocialDetailsMapper sysSocialDetailsMapper; - private final SysDeptService sysDeptService; + private final SysDeptService sysDeptService; - private final SysUserService sysUserService; + private final SysUserService sysUserService; - /** - * 同步钉钉部门 - * @return Boolean - */ - @Override - @Transactional(rollbackFor = Exception.class) - public Boolean syncDingDept() { - OapiV2DepartmentListsubRequest req = new OapiV2DepartmentListsubRequest(); - req.setDeptId(1L); - req.setLanguage("zh_CN"); + // JSON field name constants for DingTalk/WeChat API + private static final String FIELD_MOBILE = "mobile"; - // 数据库中现有的部门 - List deptList = sysDeptService.list(Wrappers.emptyWrapper()); + private static final String FIELD_AVATAR = "avatar"; - // 查询根部门下的所有部门 - List insertDept = queryChildDept(req, getDingAccessToken(), deptList); + private static final String FIELD_NICKNAME = "nickname"; - // 去重 + private static final String FIELD_NAME = "name"; + + private static final String FIELD_EMAIL = "email"; + + private static final String FIELD_DEPT_ID = "dept_id"; + + private static final String FIELD_PARENT_ID = "parent_id"; + + private static final String FIELD_DEPT_ORDER_LIST = "dept_order_list"; + + private static final String FIELD_USERID_LIST = "userid_list"; + + private static final String FIELD_RESULT = "result"; + + // WeChat Enterprise config field name constants + private static final String FIELD_AGENT_ID = "agentId"; + + private static final String FIELD_TOKEN = "token"; + + private static final String FIELD_AES_KEY = "aesKey"; + + // Language code constant + private static final String LANGUAGE_ZH_CN = "zh_CN"; + + /** + * 同步钉钉部门 + * + * @return Boolean + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean syncDingDept() { + OapiV2DepartmentListsubRequest req = new OapiV2DepartmentListsubRequest(); + req.setDeptId(1L); + req.setLanguage(LANGUAGE_ZH_CN); + + // 数据库中现有的部门 + List deptList = sysDeptService.list(Wrappers.emptyWrapper()); + + // 查询根部门下的所有部门 + List insertDept = queryChildDept(req, getDingAccessToken(), deptList); + + // 去重 List syncDept = insertDept.stream().distinct().toList(); - // 保存部门以及部门关系 - if (CollectionUtils.isNotEmpty(syncDept)) { - syncDept.forEach(sysDeptService::save); - } + // 保存部门以及部门关系 + if (CollectionUtils.isNotEmpty(syncDept)) { + syncDept.forEach(sysDeptService::save); + } - return Boolean.TRUE; - } + return Boolean.TRUE; + } - /** - * 同步部门下的钉钉用户 - * @param deptId 部门ID - * @return R - */ - @SneakyThrows - @Override - @Transactional(rollbackFor = Exception.class) - public R syncDingUser(Long deptId) { - // 数据库中现有用户 - List users = sysUserService.list(Wrappers.emptyWrapper()); + /** + * 同步部门下的钉钉用户 + * + * @param deptId 部门ID + * @return R + */ + @SneakyThrows + @Override + @Transactional(rollbackFor = Exception.class) + public R syncDingUser(Long deptId) { + // 数据库中现有用户 + List users = sysUserService.list(Wrappers.emptyWrapper()); - String token = getDingAccessToken(); + String token = getDingAccessToken(); - // 查询部门下的用户id列表 - DingTalkClient client = new DefaultDingTalkClient(SecurityConstants.DING_DEPT_USERIDS_URL); - OapiUserListidRequest req = new OapiUserListidRequest(); - req.setDeptId(deptId); - OapiUserListidResponse rsp = client.execute(req, token); + // 查询部门下的用户id列表 + DingTalkClient client = new DefaultDingTalkClient(SecurityConstants.DING_DEPT_USERIDS_URL); + OapiUserListidRequest req = new OapiUserListidRequest(); + req.setDeptId(deptId); + OapiUserListidResponse rsp = client.execute(req, token); - JSONObject jsonObject = JSONUtil.parseObj(rsp.getBody()); - JSONObject result = jsonObject.getJSONObject("result"); + JSONObject jsonObject = JSONUtil.parseObj(rsp.getBody()); + JSONObject result = jsonObject.getJSONObject(FIELD_RESULT); - if (result == null) { - return R.ok(); - } - List useridList = result.get("userid_list", List.class); + if (result == null) { + return R.ok(); + } + List useridList = result.get(FIELD_USERID_LIST, List.class); - // 查询用户详情 - for (String userid : useridList) { - DingTalkClient userClient = new DefaultDingTalkClient(SecurityConstants.DING_USER_INFO_URL); - OapiV2UserGetRequest userGetRequest = new OapiV2UserGetRequest(); - userGetRequest.setUserid(userid); - OapiV2UserGetResponse userGetResponse = userClient.execute(userGetRequest, token); - JSONObject userResult = JSONUtil.parseObj(userGetResponse.getBody()); - JSONObject userObj = JSONUtil.parseObj(userResult.get("result")); + // 查询用户详情 + for (String userid : useridList) { + DingTalkClient userClient = new DefaultDingTalkClient(SecurityConstants.DING_USER_INFO_URL); + OapiV2UserGetRequest userGetRequest = new OapiV2UserGetRequest(); + userGetRequest.setUserid(userid); + OapiV2UserGetResponse userGetResponse = userClient.execute(userGetRequest, token); + JSONObject userResult = JSONUtil.parseObj(userGetResponse.getBody()); + JSONObject userObj = JSONUtil.parseObj(userResult.get(FIELD_RESULT)); - boolean exist = users.stream() - .filter(user -> StrUtil.isNotBlank(user.getPhone())) - .anyMatch(user -> user.getPhone().equals(userObj.getStr("mobile"))); + boolean exist = users.stream() + .filter(user -> StrUtil.isNotBlank(user.getPhone())) + .anyMatch(user -> user.getPhone().equals(userObj.getStr(FIELD_MOBILE))); - if (exist || StrUtil.isBlank(userObj.getStr("mobile"))) { - log.info("用户已存在或手机号不合法 {}", userid); - continue; - } + if (exist || StrUtil.isBlank(userObj.getStr(FIELD_MOBILE))) { + log.info("用户已存在或手机号不合法 {}", userid); + continue; + } - // 用户部门信息 - JSONArray deptOrders = userObj.getJSONArray("dept_order_list"); - JSONObject deptInfo = (JSONObject) deptOrders.get(0); + // 用户部门信息 + JSONArray deptOrders = userObj.getJSONArray(FIELD_DEPT_ORDER_LIST); + JSONObject deptInfo = (JSONObject) deptOrders.get(0); - // 用户信息 - UserDTO userDTO = new UserDTO(); - userDTO.setDeptId(deptInfo.getLong("dept_id")); - userDTO.setAvatar(userObj.getStr("avatar")); - userDTO.setUsername(userObj.getStr("mobile")); - userDTO.setPhone(userObj.getStr("mobile")); - userDTO.setNickname(userObj.getStr("nickname")); - userDTO.setName(userObj.getStr("name")); - userDTO.setEmail(userObj.getStr("email")); - // 初始化密码为 手机号 - userDTO.setPassword(userObj.getStr("mobile")); - userDTO.setPasswordModifyTime(LocalDateTime.now()); - sysUserService.saveUser(userDTO); - } + // 用户信息 + UserDTO userDTO = new UserDTO(); + userDTO.setDeptId(deptInfo.getLong(FIELD_DEPT_ID)); + userDTO.setAvatar(userObj.getStr(FIELD_AVATAR)); + userDTO.setUsername(userObj.getStr(FIELD_MOBILE)); + userDTO.setPhone(userObj.getStr(FIELD_MOBILE)); + userDTO.setNickname(userObj.getStr(FIELD_NICKNAME)); + userDTO.setName(userObj.getStr(FIELD_NAME)); + userDTO.setEmail(userObj.getStr(FIELD_EMAIL)); + // 初始化密码为 手机号 + userDTO.setPassword(userObj.getStr(FIELD_MOBILE)); + userDTO.setPasswordModifyTime(LocalDateTime.now()); + sysUserService.saveUser(userDTO); + } - return R.ok(); - } + return R.ok(); + } - /** - * 同步企微部门 - * @return R - */ - @Override - @Transactional(rollbackFor = Exception.class) - public R syncCpDept() { - WxCpService wxCpService = new WxCpServiceImpl(); - wxCpService.setWxCpConfigStorage(getCpConfig()); + /** + * 同步企微部门 + * + * @return R + */ + @Override + @Transactional(rollbackFor = Exception.class) + public R syncCpDept() { + WxCpService wxCpService = new WxCpServiceImpl(); + wxCpService.setWxCpConfigStorage(getCpConfig()); - List departList; - try { - departList = wxCpService.getDepartmentService().list(null); - } - catch (WxErrorException e) { - log.error("获取企业微信部门列表失败", e); - return R.failed(MsgUtils.getMessage(ErrorCodes.SYS_CONNECT_CP_DEPT_SYNC_ERROR)); - } + List departList; + try { + departList = wxCpService.getDepartmentService().list(null); + } catch (WxErrorException e) { + log.error("获取企业微信部门列表失败", e); + return R.failed(MsgUtils.getMessage(UpmsErrorCodes.SYS_CONNECT_CP_DEPT_SYNC_ERROR)); + } - if (CollUtil.isEmpty(departList)) { - return R.ok(); - } + if (CollUtil.isEmpty(departList)) { + return R.ok(); + } - // 数据库中现有的部门 - List deptList = sysDeptService.list(Wrappers.emptyWrapper()); - departList.stream() - .filter(depart -> deptList.stream().noneMatch(sysDept -> depart.getName().equals(sysDept.getName()))) - .map(dept -> { - SysDept sysDept = new SysDept(); - sysDept.setName(dept.getName()); - sysDept.setDeptId(dept.getId()); - sysDept.setParentId(dept.getParentId()); - sysDept.setSortOrder(dept.getOrder().intValue()); - return sysDept; - }) - .forEach(sysDeptService::save); - return R.ok(); - } + // 数据库中现有的部门 + List deptList = sysDeptService.list(Wrappers.emptyWrapper()); + departList.stream() + .filter(depart -> deptList.stream().noneMatch(sysDept -> depart.getName().equals(sysDept.getName()))) + .map(dept -> { + SysDept sysDept = new SysDept(); + sysDept.setName(dept.getName()); + sysDept.setDeptId(dept.getId()); + sysDept.setParentId(dept.getParentId()); + sysDept.setSortOrder(dept.getOrder().intValue()); + return sysDept; + }) + .forEach(sysDeptService::save); + return R.ok(); + } - /** - * 同步企微用户 - * @return R - */ - @Override - public R syncCpUser() { - WxCpService wxCpService = new WxCpServiceImpl(); - wxCpService.setWxCpConfigStorage(getCpConfig()); + /** + * 同步企微用户 + * + * @return R + */ + @Override + public R syncCpUser() { + WxCpService wxCpService = new WxCpServiceImpl(); + wxCpService.setWxCpConfigStorage(getCpConfig()); - List cpUserList; - try { - cpUserList = wxCpService.getUserService().listByDepartment(1L, true, 0); - } - catch (WxErrorException e) { - log.error("获取企业微信用户列表失败", e); - return R.failed(MsgUtils.getMessage(ErrorCodes.SYS_CONNECT_CP_USER_SYNC_ERROR)); - } + List cpUserList; + try { + cpUserList = wxCpService.getUserService().listByDepartment(1L, true, 0); + } catch (WxErrorException e) { + log.error("获取企业微信用户列表失败", e); + return R.failed(MsgUtils.getMessage(UpmsErrorCodes.SYS_CONNECT_CP_USER_SYNC_ERROR)); + } - if (CollUtil.isEmpty(cpUserList)) { - return R.ok(); - } + if (CollUtil.isEmpty(cpUserList)) { + return R.ok(); + } - // 系统原有用户 - List userList = sysUserService.list(Wrappers.emptyWrapper()); + // 系统原有用户 + List userList = sysUserService.list(Wrappers.emptyWrapper()); - for (WxCpUser cpUser : cpUserList) { - boolean exist = userList.stream() - .filter(user -> StrUtil.isNotBlank(user.getPhone())) - .anyMatch(user -> user.getPhone().equals(cpUser.getMobile())); - if (exist || StrUtil.isBlank(cpUser.getMobile())) { - log.info("用户已存在或手机号不合法跳过 {}", cpUser); - continue; - } + for (WxCpUser cpUser : cpUserList) { + boolean exist = userList.stream() + .filter(user -> StrUtil.isNotBlank(user.getPhone())) + .anyMatch(user -> user.getPhone().equals(cpUser.getMobile())); + if (exist || StrUtil.isBlank(cpUser.getMobile())) { + log.info("用户已存在或手机号不合法跳过 {}", cpUser); + continue; + } - UserDTO user = new UserDTO(); - user.setUsername(cpUser.getMobile()); - user.setName(cpUser.getName()); - user.setDeptId(cpUser.getDepartIds()[0]); - user.setEmail(cpUser.getEmail()); - user.setPhone(cpUser.getMobile()); - user.setAvatar(cpUser.getAvatar()); - // 初始化密码为 手机号 - user.setPassword(cpUser.getMobile()); - sysUserService.saveUser(user); - } + UserDTO user = new UserDTO(); + user.setUsername(cpUser.getMobile()); + user.setName(cpUser.getName()); + user.setDeptId(cpUser.getDepartIds()[0]); + user.setEmail(cpUser.getEmail()); + user.setPhone(cpUser.getMobile()); + user.setAvatar(cpUser.getAvatar()); + // 初始化密码为 手机号 + user.setPassword(cpUser.getMobile()); + sysUserService.saveUser(user); + } - return R.ok(); - } + return R.ok(); + } - private String getDingAccessToken() { - SysSocialDetails dingTalk = sysSocialDetailsMapper.selectOne(Wrappers.lambdaQuery() - .eq(SysSocialDetails::getType, LoginTypeEnum.DINGTALK.getType())); + private String getDingAccessToken() { + SysSocialDetails dingTalk = sysSocialDetailsMapper.selectOne(Wrappers.lambdaQuery() + .eq(SysSocialDetails::getType, LoginTypeEnum.DINGTALK.getType())); - DingTalkClient client = new DefaultDingTalkClient(SecurityConstants.DING_OLD_GET_TOKEN); - OapiGettokenRequest request = new OapiGettokenRequest(); - request.setAppkey(dingTalk.getAppId()); - request.setAppsecret(dingTalk.getAppSecret()); - request.setHttpMethod(HttpMethod.GET.name()); - try { - OapiGettokenResponse response = client.execute(request); - return response.getAccessToken(); - } - catch (Exception e) { - log.error("调用钉钉异常", e); - } - return null; - } + DingTalkClient client = new DefaultDingTalkClient(SecurityConstants.DING_OLD_GET_TOKEN); + OapiGettokenRequest request = new OapiGettokenRequest(); + request.setAppkey(dingTalk.getAppId()); + request.setAppsecret(dingTalk.getAppSecret()); + request.setHttpMethod(HttpMethod.GET.name()); + try { + OapiGettokenResponse response = client.execute(request); + return response.getAccessToken(); + } catch (Exception e) { + log.error("调用钉钉异常", e); + } + return null; + } - public WxCpDefaultConfigImpl getCpConfig() { - SysSocialDetails cp = sysSocialDetailsMapper.selectOne(Wrappers.lambdaQuery() - .eq(SysSocialDetails::getType, LoginTypeEnum.WEIXIN_CP.getType())); + public WxCpDefaultConfigImpl getCpConfig() { + SysSocialDetails cp = sysSocialDetailsMapper.selectOne(Wrappers.lambdaQuery() + .eq(SysSocialDetails::getType, LoginTypeEnum.WEIXIN_CP.getType())); - WxCpDefaultConfigImpl config = new WxCpDefaultConfigImpl(); - config.setCorpId(cp.getAppId()); // 设置微信企业号的appid - config.setCorpSecret(cp.getAppSecret()); // 设置微信企业号的app - // corpSecret - JSONObject ext = JSONUtil.parseObj(cp.getExt()); - config.setAgentId(ext.getInt("agentId")); // 设置微信企业号应用ID - config.setToken(ext.getStr("token")); // 设置微信企业号应用的token - config.setAesKey(ext.getStr("aesKey")); // 设置微信企业号应用的EncodingAESKey + WxCpDefaultConfigImpl config = new WxCpDefaultConfigImpl(); + config.setCorpId(cp.getAppId()); // 设置微信企业号的appid + config.setCorpSecret(cp.getAppSecret()); // 设置微信企业号的app + // corpSecret + JSONObject ext = JSONUtil.parseObj(cp.getExt()); + config.setAgentId(ext.getInt(FIELD_AGENT_ID)); // 设置微信企业号应用ID + config.setToken(ext.getStr(FIELD_TOKEN)); // 设置微信企业号应用的token + config.setAesKey(ext.getStr(FIELD_AES_KEY)); // 设置微信企业号应用的EncodingAESKey - return config; - } + return config; + } - /** - * 查询当前部门下的所有部门 - */ - @SneakyThrows - private List queryChildDept(OapiV2DepartmentListsubRequest req, String token, List deptList) { - List sysDepts = new LinkedList<>(); + /** + * 查询当前部门下的所有部门 + */ + @SneakyThrows + private List queryChildDept(OapiV2DepartmentListsubRequest req, String token, List deptList) { + List sysDepts = new LinkedList<>(); - // 调用Api查询 - DingTalkClient client = new DefaultDingTalkClient(SecurityConstants.DING_OLD_DEPT_URL); - OapiV2DepartmentListsubResponse rsp = client.execute(req, token); + // 调用Api查询 + DingTalkClient client = new DefaultDingTalkClient(SecurityConstants.DING_OLD_DEPT_URL); + OapiV2DepartmentListsubResponse rsp = client.execute(req, token); - JSONObject result = JSONUtil.parseObj(rsp.getBody()); - List resultList = result.get("result", List.class); + JSONObject result = JSONUtil.parseObj(rsp.getBody()); + List resultList = result.get(FIELD_RESULT, List.class); - if (CollUtil.isEmpty(resultList)) { - return sysDepts; - } + if (CollUtil.isEmpty(resultList)) { + return sysDepts; + } - // 过滤出数据库存在的部门 - List depts = resultList.stream() - .filter(dept -> deptList.stream().noneMatch(sysDept -> sysDept.getName().equals(dept.get("name")))) - .map(dept -> { - SysDept sysDept = new SysDept(); - sysDept.setName(Convert.toStr(dept.get("name"))); - sysDept.setDeptId(Convert.toLong(dept.get("dept_id"))); - sysDept.setParentId(Convert.toLong(dept.get("parent_id"))); - return sysDept; - }) + // 过滤出数据库存在的部门 + List depts = resultList.stream() + .filter(dept -> deptList.stream().noneMatch(sysDept -> sysDept.getName().equals(dept.get(FIELD_NAME)))) + .map(dept -> { + SysDept sysDept = new SysDept(); + sysDept.setName(Convert.toStr(dept.get(FIELD_NAME))); + sysDept.setDeptId(Convert.toLong(dept.get(FIELD_DEPT_ID))); + sysDept.setParentId(Convert.toLong(dept.get(FIELD_PARENT_ID))); + return sysDept; + }) .toList(); - // 递归查询下一级 - if (CollectionUtils.isNotEmpty(depts)) { - sysDepts.addAll(depts); - depts.forEach(dept -> { - OapiV2DepartmentListsubRequest request = new OapiV2DepartmentListsubRequest(); - request.setDeptId(dept.getDeptId()); - request.setLanguage("zh_CN"); - List childDept = queryChildDept(request, token, deptList); - sysDepts.addAll(childDept); - }); - } + // 递归查询下一级 + if (CollectionUtils.isNotEmpty(depts)) { + sysDepts.addAll(depts); + depts.forEach(dept -> { + OapiV2DepartmentListsubRequest request = new OapiV2DepartmentListsubRequest(); + request.setDeptId(dept.getDeptId()); + request.setLanguage(LANGUAGE_ZH_CN); + List childDept = queryChildDept(request, token, deptList); + sysDepts.addAll(childDept); + }); + } - return sysDepts; - } + return sysDepts; + } } diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysAuditLogServiceImpl.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysAuditLogServiceImpl.java index 7634febab..7210a22f2 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysAuditLogServiceImpl.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysAuditLogServiceImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysDeptServiceImpl.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysDeptServiceImpl.java index 104b10713..ac03a6a8c 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysDeptServiceImpl.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysDeptServiceImpl.java @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -30,12 +30,14 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.github.yulichang.wrapper.MPJLambdaWrapper; import com.pig4cloud.pigx.admin.api.constant.OrgTypeEnum; import com.pig4cloud.pigx.admin.api.constant.PostCodeEnum; +import com.pig4cloud.pigx.admin.api.constant.UpmsErrorCodes; import com.pig4cloud.pigx.admin.api.entity.*; import com.pig4cloud.pigx.admin.api.utils.DataUtil; import com.pig4cloud.pigx.admin.api.vo.DeptExcelVO; import com.pig4cloud.pigx.admin.api.vo.OrgTreeVO; import com.pig4cloud.pigx.admin.mapper.*; import com.pig4cloud.pigx.admin.service.SysDeptService; +import com.pig4cloud.pigx.common.core.util.MsgUtils; import com.pig4cloud.pigx.common.core.util.R; import com.pig4cloud.pigx.common.data.datascope.DataScope; import com.pig4cloud.pigx.common.excel.vo.ErrorMessage; @@ -59,329 +61,336 @@ import java.util.*; @AllArgsConstructor public class SysDeptServiceImpl extends ServiceImpl implements SysDeptService { - private final SysUserMapper userMapper; + private final SysUserMapper userMapper; - private final SysDeptMapper deptMapper; + private final SysDeptMapper deptMapper; - private final SysPostMapper postMapper; + private final SysPostMapper postMapper; - private final SysRoleMapper roleMapper; + private final SysRoleMapper roleMapper; - private final SysUserDeptMapper userDeptMapper; + private final SysUserDeptMapper userDeptMapper; - private final SysUserPostMapper userPostMapper; + private final SysUserPostMapper userPostMapper; - /** - * 删除部门 - * @param id 部门 ID - * @return 成功、失败 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public Boolean removeDeptById(Long id) { - // 级联删除部门 - List idList = this.listDescendant(id).stream().map(SysDept::getDeptId).toList(); + /** + * 删除部门 + * + * @param id 部门 ID + * @return 成功、失败 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean removeDeptById(Long id) { + // 级联删除部门 + List idList = this.listDescendant(id).stream().map(SysDept::getDeptId).toList(); - Optional.ofNullable(idList).filter(CollUtil::isNotEmpty).ifPresent(this::removeByIds); + Optional.ofNullable(idList).filter(CollUtil::isNotEmpty).ifPresent(this::removeByIds); - return Boolean.TRUE; - } + return Boolean.TRUE; + } - /** - * 查询全部部门树 - * @param deptName - * @param parentId - * @return 树 部门名称 - */ - @Override - public List> selectTree(String deptName, Long parentId) { - // 查询全部部门 - List deptAllList = deptMapper - .selectList(Wrappers.lambdaQuery().like(StrUtil.isNotBlank(deptName), SysDept::getName, deptName)); - // 查询数据权限内部门 - List deptOwnIdList = deptMapper - .selectListByScope( - Wrappers.lambdaQuery().like(StrUtil.isNotBlank(deptName), SysDept::getName, deptName), - DataScope.of()) - .stream() - .map(SysDept::getDeptId) - .toList(); + /** + * 查询全部部门树 + * + * @param deptName + * @param parentId + * @return 树 部门名称 + */ + @Override + public List> selectTree(String deptName, Long parentId) { + // 查询全部部门 + List deptAllList = deptMapper + .selectList(Wrappers.lambdaQuery().like(StrUtil.isNotBlank(deptName), SysDept::getName, deptName)); + // 查询数据权限内部门 + List deptOwnIdList = deptMapper + .selectListByScope( + Wrappers.lambdaQuery().like(StrUtil.isNotBlank(deptName), SysDept::getName, deptName), + DataScope.of()) + .stream() + .map(SysDept::getDeptId) + .toList(); - // 权限内部门 - List> collect = deptAllList.stream() - .filter(dept -> dept.getDeptId().intValue() != dept.getParentId()) - .sorted(Comparator.comparingInt(SysDept::getSortOrder)) - .map(dept -> { - TreeNode treeNode = new TreeNode<>(); - treeNode.setId(dept.getDeptId()); - treeNode.setParentId(dept.getParentId()); - treeNode.setName(dept.getName()); - treeNode.setWeight(dept.getSortOrder()); - // 有权限不返回标识 - Map extra = new HashMap<>(8); - extra.put("isLock", !deptOwnIdList.contains(dept.getDeptId())); - extra.put("createTime", dept.getCreateTime()); - treeNode.setExtra(extra); - return treeNode; - }) - .toList(); + // 权限内部门 + List> collect = deptAllList.stream() + .filter(dept -> dept.getDeptId().intValue() != dept.getParentId()) + .sorted(Comparator.comparingInt(SysDept::getSortOrder)) + .map(dept -> { + TreeNode treeNode = new TreeNode<>(); + treeNode.setId(dept.getDeptId()); + treeNode.setParentId(dept.getParentId()); + treeNode.setName(dept.getName()); + treeNode.setWeight(dept.getSortOrder()); + // 有权限不返回标识 + Map extra = new HashMap<>(8); + extra.put("isLock", !deptOwnIdList.contains(dept.getDeptId())); + extra.put("createTime", dept.getCreateTime()); + treeNode.setExtra(extra); + return treeNode; + }) + .toList(); - // 模糊查询 不组装树结构 直接返回 表格方便编辑 - if (StrUtil.isNotBlank(deptName)) { - return collect.stream().map(node -> { - Tree tree = new Tree<>(); - tree.putAll(node.getExtra()); - BeanUtils.copyProperties(node, tree); - return tree; - }).toList(); - } + // 模糊查询 不组装树结构 直接返回 表格方便编辑 + if (StrUtil.isNotBlank(deptName)) { + return collect.stream().map(node -> { + Tree tree = new Tree<>(); + tree.putAll(node.getExtra()); + BeanUtils.copyProperties(node, tree); + return tree; + }).toList(); + } - return TreeUtil.build(collect, parentId == null ? 0 : parentId); - } + return TreeUtil.build(collect, parentId == null ? 0 : parentId); + } - /** - * 导出部门 - * @return - */ - @Override - public List listExcelVo() { - List list = this.list(); - List deptExcelVos = list.stream().map(item -> { - DeptExcelVO deptExcelVo = new DeptExcelVO(); - deptExcelVo.setName(item.getName()); - Optional first = this.list() - .stream() - .filter(it -> item.getParentId().equals(it.getDeptId())) - .map(SysDept::getName) - .findFirst(); - deptExcelVo.setParentName(first.orElse("根部门")); - deptExcelVo.setSortOrder(item.getSortOrder()); - return deptExcelVo; - }).toList(); - return deptExcelVos; - } + /** + * 导出部门 + * + * @return + */ + @Override + public List listExcelVo() { + List list = this.list(); + List deptExcelVos = list.stream().map(item -> { + DeptExcelVO deptExcelVo = new DeptExcelVO(); + deptExcelVo.setName(item.getName()); + Optional first = this.list() + .stream() + .filter(it -> item.getParentId().equals(it.getDeptId())) + .map(SysDept::getName) + .findFirst(); + deptExcelVo.setParentName(first.orElse("根部门")); + deptExcelVo.setSortOrder(item.getSortOrder()); + return deptExcelVo; + }).toList(); + return deptExcelVos; + } - @Override - public R importDept(List excelVOList, BindingResult bindingResult) { - List errorMessageList = (List) bindingResult.getTarget(); + @Override + public R importDept(List excelVOList, BindingResult bindingResult) { + List errorMessageList = (List) bindingResult.getTarget(); - List deptList = this.list(); - for (DeptExcelVO item : excelVOList) { - Set errorMsg = new HashSet<>(); - boolean exsitUsername = deptList.stream().anyMatch(sysDept -> item.getName().equals(sysDept.getName())); - if (exsitUsername) { - errorMsg.add("部门名称已经存在"); - } - SysDept one = this.getOne(Wrappers.lambdaQuery().eq(SysDept::getName, item.getParentName())); - if (item.getParentName().equals("根部门")) { - one = new SysDept(); - one.setDeptId(0L); - } - if (one == null) { - errorMsg.add("上级部门不存在"); - } - if (CollUtil.isEmpty(errorMsg)) { - SysDept sysDept = new SysDept(); - sysDept.setName(item.getName()); - sysDept.setParentId(one.getDeptId()); - sysDept.setSortOrder(item.getSortOrder()); - baseMapper.insert(sysDept); - } - else { - // 数据不合法情况 - errorMessageList.add(new ErrorMessage(item.getLineNum(), errorMsg)); - } - } - if (CollUtil.isNotEmpty(errorMessageList)) { - return R.failed(errorMessageList); - } - return R.ok(null, "部门导入成功"); - } + List deptList = this.list(); + for (DeptExcelVO item : excelVOList) { + Set errorMsg = new HashSet<>(); + boolean exsitUsername = deptList.stream().anyMatch(sysDept -> item.getName().equals(sysDept.getName())); + if (exsitUsername) { + errorMsg.add("部门名称已经存在"); + } + SysDept one = this.getOne(Wrappers.lambdaQuery().eq(SysDept::getName, item.getParentName())); + if (item.getParentName().equals("根部门")) { + one = new SysDept(); + one.setDeptId(0L); + } + if (one == null) { + errorMsg.add("上级部门不存在"); + } + if (CollUtil.isEmpty(errorMsg)) { + SysDept sysDept = new SysDept(); + sysDept.setName(item.getName()); + sysDept.setParentId(one.getDeptId()); + sysDept.setSortOrder(item.getSortOrder()); + baseMapper.insert(sysDept); + } else { + // 数据不合法情况 + errorMessageList.add(new ErrorMessage(item.getLineNum(), errorMsg)); + } + } + if (CollUtil.isNotEmpty(errorMessageList)) { + return R.failed(errorMessageList); + } + return R.ok(null, MsgUtils.getMessage(UpmsErrorCodes.SYS_DEPT_IMPORT_SUCCEED)); + } - /** - * 查询所有子节点 (包含当前节点) - * @param deptId 部门ID 目标部门ID - * @return ID - */ - @Override - public List listDescendant(Long deptId) { - // 查询全部部门 - List allDeptList = baseMapper.selectList(Wrappers.emptyWrapper()); + /** + * 查询所有子节点 (包含当前节点) + * + * @param deptId 部门ID 目标部门ID + * @return ID + */ + @Override + public List listDescendant(Long deptId) { + // 查询全部部门 + List allDeptList = baseMapper.selectList(Wrappers.emptyWrapper()); - // 递归查询所有子节点 - List resDeptList = new ArrayList<>(); - recursiveDept(allDeptList, deptId, resDeptList); + // 递归查询所有子节点 + List resDeptList = new ArrayList<>(); + recursiveDept(allDeptList, deptId, resDeptList); - // 添加当前节点 - resDeptList.addAll(allDeptList.stream().filter(sysDept -> deptId.equals(sysDept.getDeptId())).toList()); - return resDeptList; - } + // 添加当前节点 + resDeptList.addAll(allDeptList.stream().filter(sysDept -> deptId.equals(sysDept.getDeptId())).toList()); + return resDeptList; + } - /** - * 获取部门负责人 - *

- * 1. 根据dept 查询用户 2. 筛选用户列表中 post - * @param deptId deptId - * @return user id list - */ - @Override - public List listDeptLeader(Long deptId) { + /** + * 获取部门负责人 + *

+ * 1. 根据dept 查询用户 2. 筛选用户列表中 post + * + * @param deptId deptId + * @return user id list + */ + @Override + public List listDeptLeader(Long deptId) { - List userDeptList = userDeptMapper - .selectList(Wrappers.lambdaQuery().eq(SysUserDept::getDeptId, deptId)); - if (CollUtil.isEmpty(userDeptList)) { - return null; - } + List userDeptList = userDeptMapper + .selectList(Wrappers.lambdaQuery().eq(SysUserDept::getDeptId, deptId)); + if (CollUtil.isEmpty(userDeptList)) { + return null; + } - SysPost deptLeader = postMapper - .selectOne(Wrappers.lambdaQuery().eq(SysPost::getPostCode, PostCodeEnum.TEAM_LEADER.getCode())); - if (deptLeader == null) { - return null; - } + SysPost deptLeader = postMapper + .selectOne(Wrappers.lambdaQuery().eq(SysPost::getPostCode, PostCodeEnum.TEAM_LEADER.getCode())); + if (deptLeader == null) { + return null; + } - List userIdList = userDeptList.stream().map(SysUserDept::getUserId).toList(); - return userPostMapper.selectList(Wrappers.lambdaQuery().in(SysUserPost::getUserId, userIdList)) - .stream() - .filter(post -> Objects.equals(post.getPostId(), deptLeader.getPostId())) - .map(SysUserPost::getUserId) - .toList(); - } + List userIdList = userDeptList.stream().map(SysUserDept::getUserId).toList(); + return userPostMapper.selectList(Wrappers.lambdaQuery().in(SysUserPost::getUserId, userIdList)) + .stream() + .filter(post -> Objects.equals(post.getPostId(), deptLeader.getPostId())) + .map(SysUserPost::getUserId) + .toList(); + } - /** - * 根据父部门ID和类型获取组织树 - * @param parentDeptId 父部门ID - * @param type 类型 - * @return 组织树信息 - */ - public Map listOrgTree(Long parentDeptId, String type) { + /** + * 根据父部门ID和类型获取组织树 + * + * @param parentDeptId 父部门ID + * @param type 类型 + * @return 组织树信息 + */ + public Map listOrgTree(Long parentDeptId, String type) { - List orgs = new LinkedList<>(); + List orgs = new LinkedList<>(); - if (StrUtil.equals(type, OrgTypeEnum.ROLE.getType())) { - // 角色 - List roleList = roleMapper.selectList(Wrappers.emptyWrapper()); + if (StrUtil.equals(type, OrgTypeEnum.ROLE.getType())) { + // 角色 + List roleList = roleMapper.selectList(Wrappers.emptyWrapper()); - roleList.forEach(role -> { - OrgTreeVO orgTreeVo = new OrgTreeVO(); - orgTreeVo.setId(role.getRoleId()); - orgTreeVo.setName(role.getRoleName()); - orgTreeVo.setType(OrgTypeEnum.ROLE.getType()); - orgTreeVo.setSelected(false); - orgs.add(orgTreeVo); - }); + roleList.forEach(role -> { + OrgTreeVO orgTreeVo = new OrgTreeVO(); + orgTreeVo.setId(role.getRoleId()); + orgTreeVo.setName(role.getRoleName()); + orgTreeVo.setType(OrgTypeEnum.ROLE.getType()); + orgTreeVo.setSelected(false); + orgs.add(orgTreeVo); + }); - return Dict.create() - .set("roleList", orgs) - .set("postList", new ArrayList<>()) - .set("childDepartments", orgs) - .set("employees", new ArrayList<>()); - } + return Dict.create() + .set("roleList", orgs) + .set("postList", new ArrayList<>()) + .set("childDepartments", orgs) + .set("employees", new ArrayList<>()); + } - if (StrUtil.equals(type, OrgTypeEnum.POST.getType())) { - // 角色 - List postList = postMapper.selectList(Wrappers.emptyWrapper()); + if (StrUtil.equals(type, OrgTypeEnum.POST.getType())) { + // 角色 + List postList = postMapper.selectList(Wrappers.emptyWrapper()); - postList.forEach(post -> { - OrgTreeVO orgTreeVo = new OrgTreeVO(); - orgTreeVo.setId(post.getPostId()); - orgTreeVo.setName(post.getPostName()); - orgTreeVo.setType(OrgTypeEnum.POST.getType()); - orgTreeVo.setSelected(false); - orgs.add(orgTreeVo); - }); + postList.forEach(post -> { + OrgTreeVO orgTreeVo = new OrgTreeVO(); + orgTreeVo.setId(post.getPostId()); + orgTreeVo.setName(post.getPostName()); + orgTreeVo.setType(OrgTypeEnum.POST.getType()); + orgTreeVo.setSelected(false); + orgs.add(orgTreeVo); + }); - return Dict.create() - .set("roleList", new ArrayList<>()) - .set("postList", orgs) - .set("childDepartments", orgs) - .set("employees", new ArrayList<>()); - } + return Dict.create() + .set("roleList", new ArrayList<>()) + .set("postList", orgs) + .set("childDepartments", orgs) + .set("employees", new ArrayList<>()); + } - Dict dict = Dict.create() - .set("titleDepartments", new ArrayList<>()) - .set("roleList", new ArrayList<>()) - .set("postList", new ArrayList<>()) - .set("employees", new ArrayList<>()); + Dict dict = Dict.create() + .set("titleDepartments", new ArrayList<>()) + .set("roleList", new ArrayList<>()) + .set("postList", new ArrayList<>()) + .set("employees", new ArrayList<>()); - List deptList = this.list( - Wrappers.lambdaQuery().eq(Objects.nonNull(parentDeptId), SysDept::getParentId, parentDeptId)); + List deptList = this.list( + Wrappers.lambdaQuery().eq(Objects.nonNull(parentDeptId), SysDept::getParentId, parentDeptId)); - // 查询所有部门及员工 - List deptVoList = new ArrayList<>(); - deptList.forEach(dept -> { - OrgTreeVO orgTreeVo = new OrgTreeVO(); - orgTreeVo.setId(dept.getDeptId()); - orgTreeVo.setName(dept.getName()); - orgTreeVo.setType(OrgTypeEnum.DEPT.getType()); - orgTreeVo.setSelected(false); - deptVoList.add(orgTreeVo); - }); - dict.set("childDepartments", deptVoList); + // 查询所有部门及员工 + List deptVoList = new ArrayList<>(); + deptList.forEach(dept -> { + OrgTreeVO orgTreeVo = new OrgTreeVO(); + orgTreeVo.setId(dept.getDeptId()); + orgTreeVo.setName(dept.getName()); + orgTreeVo.setType(OrgTypeEnum.DEPT.getType()); + orgTreeVo.setSelected(false); + deptVoList.add(orgTreeVo); + }); + dict.set("childDepartments", deptVoList); - if (!StrUtil.equals(type, OrgTypeEnum.DEPT.getType())) { + if (!StrUtil.equals(type, OrgTypeEnum.DEPT.getType())) { - List userVoList = new ArrayList<>(); + List userVoList = new ArrayList<>(); - MPJLambdaWrapper userQuery = new MPJLambdaWrapper<>(); - userQuery.selectAll(SysUser.class) - .leftJoin(SysUserDept.class, SysUserDept::getUserId, SysUser::getUserId) - .eq(SysUserDept::getDeptId, parentDeptId); + MPJLambdaWrapper userQuery = new MPJLambdaWrapper<>(); + userQuery.selectAll(SysUser.class) + .leftJoin(SysUserDept.class, SysUserDept::getUserId, SysUser::getUserId) + .eq(SysUserDept::getDeptId, parentDeptId); - List userList = userMapper.selectJoinList(userQuery); + List userList = userMapper.selectJoinList(userQuery); - userList.forEach(user -> { - OrgTreeVO orgTreeVo = new OrgTreeVO(); - orgTreeVo.setId(user.getUserId()); - orgTreeVo.setName(user.getUsername()); - orgTreeVo.setType(OrgTypeEnum.USER.getType()); - orgTreeVo.setSelected(false); - orgTreeVo.setAvatar(user.getAvatar()); - userVoList.add(orgTreeVo); - }); - dict.set("employees", userVoList); - } + userList.forEach(user -> { + OrgTreeVO orgTreeVo = new OrgTreeVO(); + orgTreeVo.setId(user.getUserId()); + orgTreeVo.setName(user.getUsername()); + orgTreeVo.setType(OrgTypeEnum.USER.getType()); + orgTreeVo.setSelected(false); + orgTreeVo.setAvatar(user.getAvatar()); + userVoList.add(orgTreeVo); + }); + dict.set("employees", userVoList); + } - if (parentDeptId > 0) { - List allDept = this.list(); - List depts = DataUtil.selectParentByDept(parentDeptId, allDept); - dict.set("titleDepartments", CollUtil.reverse(depts)); - } + if (parentDeptId > 0) { + List allDept = this.list(); + List depts = DataUtil.selectParentByDept(parentDeptId, allDept); + dict.set("titleDepartments", CollUtil.reverse(depts)); + } - return dict; - } + return dict; + } - /** - * 模糊搜索用户 - * @param username 用户名/拼音/首字母 - * @return 匹配到的用户 - */ - public List getOrgTreeUser(String username) { - return userMapper.selectList(Wrappers.lambdaQuery().like(SysUser::getUsername, username)) - .stream() - .map(user -> { - OrgTreeVO orgTreeVo = new OrgTreeVO(); - orgTreeVo.setId(user.getUserId()); - orgTreeVo.setName(user.getUsername()); - orgTreeVo.setType(OrgTypeEnum.USER.getType()); - orgTreeVo.setSelected(false); - orgTreeVo.setAvatar(user.getAvatar()); - return orgTreeVo; - }) - .toList(); - } + /** + * 模糊搜索用户 + * + * @param username 用户名/拼音/首字母 + * @return 匹配到的用户 + */ + public List getOrgTreeUser(String username) { + return userMapper.selectList(Wrappers.lambdaQuery().like(SysUser::getUsername, username)) + .stream() + .map(user -> { + OrgTreeVO orgTreeVo = new OrgTreeVO(); + orgTreeVo.setId(user.getUserId()); + orgTreeVo.setName(user.getUsername()); + orgTreeVo.setType(OrgTypeEnum.USER.getType()); + orgTreeVo.setSelected(false); + orgTreeVo.setAvatar(user.getAvatar()); + return orgTreeVo; + }) + .toList(); + } - /** - * 递归查询所有子节点。 - * @param allDeptList 所有部门列表 - * @param parentId 父部门ID - * @param resDeptList 结果集合 - */ - private void recursiveDept(List allDeptList, Long parentId, List resDeptList) { - // 使用 Stream API 进行筛选和遍历 - allDeptList.stream().filter(sysDept -> sysDept.getParentId().equals(parentId)).forEach(sysDept -> { - resDeptList.add(sysDept); - recursiveDept(allDeptList, sysDept.getDeptId(), resDeptList); - }); - } + /** + * 递归查询所有子节点。 + * + * @param allDeptList 所有部门列表 + * @param parentId 父部门ID + * @param resDeptList 结果集合 + */ + private void recursiveDept(List allDeptList, Long parentId, List resDeptList) { + // 使用 Stream API 进行筛选和遍历 + allDeptList.stream().filter(sysDept -> sysDept.getParentId().equals(parentId)).forEach(sysDept -> { + resDeptList.add(sysDept); + recursiveDept(allDeptList, sysDept.getDeptId(), resDeptList); + }); + } } diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysDictItemServiceImpl.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysDictItemServiceImpl.java index c9a1a2da0..b1166b48c 100755 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysDictItemServiceImpl.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysDictItemServiceImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -17,6 +17,7 @@ package com.pig4cloud.pigx.admin.service.impl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.pig4cloud.pigx.admin.api.constant.UpmsErrorCodes; import com.pig4cloud.pigx.admin.api.entity.SysDict; import com.pig4cloud.pigx.admin.api.entity.SysDictItem; import com.pig4cloud.pigx.admin.mapper.SysDictItemMapper; @@ -24,7 +25,6 @@ import com.pig4cloud.pigx.admin.service.SysDictItemService; import com.pig4cloud.pigx.admin.service.SysDictService; import com.pig4cloud.pigx.common.core.constant.CacheConstants; import com.pig4cloud.pigx.common.core.constant.enums.DictTypeEnum; -import com.pig4cloud.pigx.common.core.exception.ErrorCodes; import com.pig4cloud.pigx.common.core.util.MsgUtils; import com.pig4cloud.pigx.common.core.util.R; import lombok.AllArgsConstructor; @@ -41,41 +41,43 @@ import org.springframework.stereotype.Service; @AllArgsConstructor public class SysDictItemServiceImpl extends ServiceImpl implements SysDictItemService { - private final SysDictService dictService; + private final SysDictService dictService; - /** - * 删除字典项 - * @param id 字典项ID - * @return - */ - @Override - @CacheEvict(value = CacheConstants.DICT_DETAILS, allEntries = true) - public R removeDictItem(Long id) { - // 根据ID查询字典ID - SysDictItem dictItem = this.getById(id); - SysDict dict = dictService.getById(dictItem.getDictId()); - // 系统内置 - if (DictTypeEnum.SYSTEM.getType().equals(dict.getSystemFlag())) { - return R.failed(MsgUtils.getMessage(ErrorCodes.SYS_DICT_DELETE_SYSTEM)); - } - return R.ok(this.removeById(id)); - } + /** + * 删除字典项 + * + * @param id 字典项ID + * @return + */ + @Override + @CacheEvict(value = CacheConstants.DICT_DETAILS, allEntries = true) + public R removeDictItem(Long id) { + // 根据ID查询字典ID + SysDictItem dictItem = this.getById(id); + SysDict dict = dictService.getById(dictItem.getDictId()); + // 系统内置 + if (DictTypeEnum.SYSTEM.getType().equals(dict.getSystemFlag())) { + return R.failed(MsgUtils.getMessage(UpmsErrorCodes.SYS_DICT_DELETE_SYSTEM)); + } + return R.ok(this.removeById(id)); + } - /** - * 更新字典项 - * @param item 字典项 - * @return - */ - @Override - @CacheEvict(value = CacheConstants.DICT_DETAILS, key = "#item.dictType") - public R updateDictItem(SysDictItem item) { - // 查询字典 - SysDict dict = dictService.getById(item.getDictId()); - // 系统内置 - if (DictTypeEnum.SYSTEM.getType().equals(dict.getSystemFlag())) { - return R.failed(MsgUtils.getMessage(ErrorCodes.SYS_DICT_UPDATE_SYSTEM)); - } - return R.ok(this.updateById(item)); - } + /** + * 更新字典项 + * + * @param item 字典项 + * @return + */ + @Override + @CacheEvict(value = CacheConstants.DICT_DETAILS, key = "#item.dictType") + public R updateDictItem(SysDictItem item) { + // 查询字典 + SysDict dict = dictService.getById(item.getDictId()); + // 系统内置 + if (DictTypeEnum.SYSTEM.getType().equals(dict.getSystemFlag())) { + return R.failed(MsgUtils.getMessage(UpmsErrorCodes.SYS_DICT_UPDATE_SYSTEM)); + } + return R.ok(this.updateById(item)); + } } diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysDictServiceImpl.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysDictServiceImpl.java index 49e2e6602..b16a84d03 100755 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysDictServiceImpl.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysDictServiceImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -19,6 +19,7 @@ package com.pig4cloud.pigx.admin.service.impl; import cn.hutool.core.collection.CollUtil; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.pig4cloud.pigx.admin.api.constant.UpmsErrorCodes; import com.pig4cloud.pigx.admin.api.entity.SysDict; import com.pig4cloud.pigx.admin.api.entity.SysDictItem; import com.pig4cloud.pigx.admin.mapper.SysDictItemMapper; @@ -26,7 +27,6 @@ import com.pig4cloud.pigx.admin.mapper.SysDictMapper; import com.pig4cloud.pigx.admin.service.SysDictService; import com.pig4cloud.pigx.common.core.constant.CacheConstants; import com.pig4cloud.pigx.common.core.constant.enums.DictTypeEnum; -import com.pig4cloud.pigx.common.core.exception.ErrorCodes; import com.pig4cloud.pigx.common.core.util.MsgUtils; import com.pig4cloud.pigx.common.core.util.R; import lombok.AllArgsConstructor; @@ -46,55 +46,58 @@ import java.util.List; @AllArgsConstructor public class SysDictServiceImpl extends ServiceImpl implements SysDictService { - private final SysDictItemMapper dictItemMapper; + private final SysDictItemMapper dictItemMapper; - /** - * 根据ID 删除字典 - * @param ids 字典ID 列表 - * @return - */ - @Override - @Transactional(rollbackFor = Exception.class) - @CacheEvict(value = CacheConstants.DICT_DETAILS, allEntries = true) - public R removeDictByIds(Long[] ids) { + /** + * 根据ID 删除字典 + * + * @param ids 字典ID 列表 + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + @CacheEvict(value = CacheConstants.DICT_DETAILS, allEntries = true) + public R removeDictByIds(Long[] ids) { - List dictIdList = baseMapper.selectByIds(CollUtil.toList(ids)) - .stream() - .filter(sysDict -> !sysDict.getSystemFlag().equals(DictTypeEnum.SYSTEM.getType()))// 系统内置类型不删除 - .map(SysDict::getId) + List dictIdList = baseMapper.selectByIds(CollUtil.toList(ids)) + .stream() + .filter(sysDict -> !sysDict.getSystemFlag().equals(DictTypeEnum.SYSTEM.getType()))// 系统内置类型不删除 + .map(SysDict::getId) .toList(); - baseMapper.deleteByIds(dictIdList); + baseMapper.deleteByIds(dictIdList); - dictItemMapper.delete(Wrappers.lambdaQuery().in(SysDictItem::getDictId, dictIdList)); - return R.ok(); - } + dictItemMapper.delete(Wrappers.lambdaQuery().in(SysDictItem::getDictId, dictIdList)); + return R.ok(); + } - /** - * 更新字典 - * @param dict 字典 - * @return - */ - @Override - @CacheEvict(value = CacheConstants.DICT_DETAILS, key = "#dict.dictType") - public R updateDict(SysDict dict) { - SysDict sysDict = this.getById(dict.getId()); - // 系统内置 - if (DictTypeEnum.SYSTEM.getType().equals(sysDict.getSystemFlag())) { - return R.failed(MsgUtils.getMessage(ErrorCodes.SYS_DICT_UPDATE_SYSTEM)); - } - this.updateById(dict); - return R.ok(dict); - } + /** + * 更新字典 + * + * @param dict 字典 + * @return + */ + @Override + @CacheEvict(value = CacheConstants.DICT_DETAILS, key = "#dict.dictType") + public R updateDict(SysDict dict) { + SysDict sysDict = this.getById(dict.getId()); + // 系统内置 + if (DictTypeEnum.SYSTEM.getType().equals(sysDict.getSystemFlag())) { + return R.failed(MsgUtils.getMessage(UpmsErrorCodes.SYS_DICT_UPDATE_SYSTEM)); + } + this.updateById(dict); + return R.ok(dict); + } - /** - * 同步缓存 (清空缓存) - * @return R - */ - @Override - @CacheEvict(value = CacheConstants.DICT_DETAILS, allEntries = true) - public R syncDictCache() { - return R.ok(); - } + /** + * 同步缓存 (清空缓存) + * + * @return R + */ + @Override + @CacheEvict(value = CacheConstants.DICT_DETAILS, allEntries = true) + public R syncDictCache() { + return R.ok(); + } } diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysFileServiceImpl.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysFileServiceImpl.java index 719aae494..822253a29 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysFileServiceImpl.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysFileServiceImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysI18nServiceImpl.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysI18nServiceImpl.java index dd97a2457..6dda66de6 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysI18nServiceImpl.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysI18nServiceImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysLogServiceImpl.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysLogServiceImpl.java index e220383bc..3ae84be2a 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysLogServiceImpl.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysLogServiceImpl.java @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysMenuServiceImpl.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysMenuServiceImpl.java index 4c6cb0064..c7a0247e6 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysMenuServiceImpl.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysMenuServiceImpl.java @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -27,6 +27,7 @@ import cn.hutool.core.util.BooleanUtil; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.pig4cloud.pigx.admin.api.constant.UpmsErrorCodes; import com.pig4cloud.pigx.admin.api.entity.SysI18nEntity; import com.pig4cloud.pigx.admin.api.entity.SysMenu; import com.pig4cloud.pigx.admin.api.entity.SysRoleMenu; @@ -37,9 +38,10 @@ import com.pig4cloud.pigx.admin.service.SysMenuService; import com.pig4cloud.pigx.common.core.constant.CacheConstants; import com.pig4cloud.pigx.common.core.constant.CommonConstants; import com.pig4cloud.pigx.common.core.constant.enums.MenuTypeEnum; -import com.pig4cloud.pigx.common.core.exception.ErrorCodes; +import com.pig4cloud.pigx.common.core.constant.enums.YesNoEnum; import com.pig4cloud.pigx.common.core.util.MsgUtils; import com.pig4cloud.pigx.common.core.util.R; +import com.pig4cloud.pigx.common.security.util.SecurityUtils; import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -66,134 +68,155 @@ import java.util.function.Predicate; @Slf4j public class SysMenuServiceImpl extends ServiceImpl implements SysMenuService { - private final SysRoleMenuMapper sysRoleMenuMapper; + private final SysRoleMenuMapper sysRoleMenuMapper; - private final SysI18nService sysI18nService; + private final SysI18nService sysI18nService; - @Override - @Cacheable(value = CacheConstants.MENU_DETAILS, key = "#roleId", unless = "#result.isEmpty()") - public List findMenuByRoleId(Long roleId) { - return baseMapper.listMenusByRoleId(roleId); - } + @Override + @Cacheable(value = CacheConstants.MENU_DETAILS, key = "#roleId", unless = "#result.isEmpty()") + public List findMenuByRoleId(Long roleId) { + return baseMapper.listMenusByRoleId(roleId); + } - @Override - @Transactional(rollbackFor = Exception.class) - @CacheEvict(value = CacheConstants.MENU_DETAILS, allEntries = true) - public R removeMenuById(Long id) { - // 查询父节点为当前节点的节点 - List menuList = this.list(Wrappers.query().lambda().eq(SysMenu::getParentId, id)); - if (CollUtil.isNotEmpty(menuList)) { - return R.failed(MsgUtils.getMessage(ErrorCodes.SYS_MENU_DELETE_EXISTING)); - } + @Override + @Transactional(rollbackFor = Exception.class) + @CacheEvict(value = CacheConstants.MENU_DETAILS, allEntries = true) + public R removeMenuById(Long id) { + // 1. 检查菜单是否存在 + SysMenu menu = this.getById(id); + if (menu == null) { + return R.failed(MsgUtils.getMessage(UpmsErrorCodes.SYS_MENU_NOT_FOUND)); + } - sysRoleMenuMapper.delete(Wrappers.query().lambda().eq(SysRoleMenu::getMenuId, id)); - // 删除当前菜单及其子菜单 - return R.ok(this.removeById(id)); - } + // 2. 递归收集当前菜单及所有子孙菜单的ID + List menuIdsToDelete = new ArrayList<>(); + collectMenuIds(id, menuIdsToDelete); - @Override - @CacheEvict(value = CacheConstants.MENU_DETAILS, allEntries = true) - public Boolean updateMenuById(SysMenu sysMenu) { - return this.updateById(sysMenu); - } + // 3. 批量删除所有角色-菜单关联 + if (CollUtil.isNotEmpty(menuIdsToDelete)) { + sysRoleMenuMapper.delete(Wrappers.lambdaQuery().in(SysRoleMenu::getMenuId, menuIdsToDelete)); + } - /** - * 构建树查询 1. 不是懒加载情况,查询全部 2. 是懒加载,根据parentId 查询 2.1 父节点为空,则查询ID -1 - * @param parentId 父节点ID - * @param menuName 菜单名称 - * @return - */ - @Override - public List> treeMenu(Long parentId, String menuName, String type) { - Long parent = parentId == null ? CommonConstants.MENU_TREE_ROOT_ID : parentId; + // 4. 批量逻辑删除菜单 + return R.ok(this.removeByIds(menuIdsToDelete)); + } - List> collect = baseMapper - .selectList(Wrappers.lambdaQuery() - .eq(Objects.nonNull(parentId), SysMenu::getParentId, parentId) - .like(StrUtil.isNotBlank(menuName), SysMenu::getName, menuName) - .eq(StrUtil.isNotBlank(type), SysMenu::getMenuType, type) - .orderByAsc(SysMenu::getSortOrder)) - .stream() - .map(getNodeFunction()) - .toList(); + /** + * 递归收集菜单ID及其所有子孙菜单ID + * + * @param menuId 菜单ID + * @param menuIds 收集结果列表 + */ + private void collectMenuIds(Long menuId, List menuIds) { + menuIds.add(menuId); - // 模糊查询 不组装树结构 直接返回 表格方便编辑 - if (StrUtil.isNotBlank(menuName)) { - return collect.stream().map(node -> { - Tree tree = new Tree<>(); - tree.putAll(node.getExtra()); - BeanUtils.copyProperties(node, tree); - return tree; + List children = this.list(Wrappers.lambdaQuery().eq(SysMenu::getParentId, menuId)); + + if (CollUtil.isNotEmpty(children)) { + for (SysMenu child : children) { + collectMenuIds(child.getMenuId(), menuIds); + } + } + } + + @Override + @CacheEvict(value = CacheConstants.MENU_DETAILS, allEntries = true) + public Boolean updateMenuById(SysMenu sysMenu) { + return this.updateById(sysMenu); + } + + /** + * 构建树查询 1. 不是懒加载情况,查询全部 2. 是懒加载,根据parentId 查询 2.1 父节点为空,则查询ID -1 + * + * @param parentId 父节点ID + * @param menuName 菜单名称 + * @return + */ + @Override + public List> treeMenu(Long parentId, String menuName, String type) { + Long parent = parentId == null ? CommonConstants.MENU_TREE_ROOT_ID : parentId; + + List> collect = baseMapper.selectList(Wrappers.lambdaQuery().eq(Objects.nonNull(parentId), SysMenu::getParentId, parentId).like(StrUtil.isNotBlank(menuName), SysMenu::getName, menuName).eq(StrUtil.isNotBlank(type), SysMenu::getMenuType, type).orderByAsc(SysMenu::getSortOrder)).stream().map(getNodeFunction()).toList(); + + // 模糊查询 不组装树结构 直接返回 表格方便编辑 + if (StrUtil.isNotBlank(menuName)) { + return collect.stream().map(node -> { + Tree tree = new Tree<>(); + tree.putAll(node.getExtra()); + BeanUtils.copyProperties(node, tree); + return tree; }).toList(); - } + } - return TreeUtil.build(collect, parent); - } + return TreeUtil.build(collect, parent); + } - /** - * 查询菜单 - * @param all 全部菜单 - * @param type 类型 - * @param parentId 父节点ID - * @return - */ - @Override - public List> filterMenu(Set all, String type, Long parentId) { - List list = sysI18nService.list(); - List> collect = all.stream().filter(menuTypePredicate(type)).peek(item -> { - Optional first = list.stream().filter(it -> it.getZhCn().equals(item.getName())).findFirst(); - first.ifPresent(sysI18nEntity -> item.setName(sysI18nEntity.getName())); + /** + * 查询菜单 + * + * @param all 全部菜单 + * @param type 类型 + * @param parentId 父节点ID + * @return + */ + @Override + public List> filterMenu(Set all, String type, Long parentId) { + List list = sysI18nService.list(); + List> collect = all.stream().filter(menuTypePredicate(type)).peek(item -> { + Optional first = list.stream().filter(it -> it.getZhCn().equals(item.getName())).findFirst(); + first.ifPresent(sysI18nEntity -> item.setName(sysI18nEntity.getName())); }).map(getNodeFunction()).toList(); - Long parent = parentId == null ? CommonConstants.MENU_TREE_ROOT_ID : parentId; - return TreeUtil.build(collect, parent); - } + Long parent = parentId == null ? CommonConstants.MENU_TREE_ROOT_ID : parentId; + return TreeUtil.build(collect, parent); + } - @NotNull - private Function> getNodeFunction() { - return menu -> { - TreeNode node = new TreeNode<>(); - node.setId(menu.getMenuId()); - node.setName(menu.getName()); - node.setParentId(menu.getParentId()); - node.setWeight(menu.getSortOrder()); - // 扩展属性 - Map extra = new HashMap<>(); - extra.put("path", menu.getPath()); - extra.put("componentPath", menu.getComponent()); - extra.put("menuType", menu.getMenuType()); - extra.put("permission", menu.getPermission()); - extra.put("sortOrder", menu.getSortOrder()); + @NotNull + private Function> getNodeFunction() { + return menu -> { + TreeNode node = new TreeNode<>(); + node.setId(menu.getMenuId()); + node.setName(menu.getName()); + node.setParentId(menu.getParentId()); + node.setWeight(menu.getSortOrder()); + // 扩展属性 + Map extra = new HashMap<>(); + extra.put("path", menu.getPath()); + extra.put("componentPath", menu.getComponent()); + extra.put("menuType", menu.getMenuType()); + extra.put("permission", menu.getPermission()); + extra.put("sortOrder", menu.getSortOrder()); - // 适配 vue3 - Map meta = new HashMap<>(); - meta.put("title", menu.getName()); - meta.put("isLink", menu.getPath() != null && menu.getPath().startsWith("http") ? menu.getPath() : ""); - meta.put("isHide", !BooleanUtil.toBooleanObject(menu.getVisible())); - meta.put("isKeepAlive", BooleanUtil.toBooleanObject(menu.getKeepAlive())); - meta.put("isAffix", false); - meta.put("isIframe", BooleanUtil.toBooleanObject(menu.getEmbedded())); - meta.put("icon", menu.getIcon()); + // 适配 vue3 + Map meta = new HashMap<>(); + meta.put("title", menu.getName()); + meta.put("isLink", menu.getPath() != null && menu.getPath().startsWith("http") ? menu.getPath() : ""); + meta.put("isHide", !BooleanUtil.toBooleanObject(menu.getVisible())); + meta.put("isKeepAlive", BooleanUtil.toBooleanObject(menu.getKeepAlive())); + meta.put("isAffix", false); + meta.put("isIframe", BooleanUtil.toBooleanObject(menu.getEmbedded())); + meta.put("icon", menu.getIcon()); - extra.put("meta", meta); - node.setExtra(extra); - return node; - }; - } + extra.put("meta", meta); + node.setExtra(extra); + return node; + }; + } - /** - * menu 类型断言 - * @param type 类型 - * @return Predicate - */ - private Predicate menuTypePredicate(String type) { - return vo -> { - if (MenuTypeEnum.TOP_MENU.getDescription().equals(type)) { - return MenuTypeEnum.TOP_MENU.getType().equals(vo.getMenuType()); - } - // 其他查询 左侧 + 顶部 - return !MenuTypeEnum.BUTTON.getType().equals(vo.getMenuType()); - }; - } + /** + * menu 类型断言 + * + * @param type 类型 + * @return Predicate + */ + private Predicate menuTypePredicate(String type) { + return vo -> { + if (MenuTypeEnum.TOP_MENU.getDescription().equals(type)) { + return MenuTypeEnum.TOP_MENU.getType().equals(vo.getMenuType()); + } + // 其他查询 左侧 + 顶部 + return !MenuTypeEnum.BUTTON.getType().equals(vo.getMenuType()); + }; + } } diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysMessageServiceImpl.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysMessageServiceImpl.java index cebfeb7bc..a0dbb1660 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysMessageServiceImpl.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysMessageServiceImpl.java @@ -23,6 +23,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.github.yulichang.wrapper.MPJLambdaWrapper; import com.pig4cloud.pigx.admin.api.constant.SmsBizCodeEnum; import com.pig4cloud.pigx.admin.api.constant.SystemConfigTypeEnum; +import com.pig4cloud.pigx.admin.api.constant.UpmsErrorCodes; import com.pig4cloud.pigx.admin.api.dto.MessageEmailDTO; import com.pig4cloud.pigx.admin.api.dto.MessageHookDTO; import com.pig4cloud.pigx.admin.api.dto.MessageSmsDTO; @@ -39,10 +40,11 @@ import com.pig4cloud.pigx.common.core.constant.SecurityConstants; import com.pig4cloud.pigx.common.core.constant.enums.LoginTypeEnum; import com.pig4cloud.pigx.common.core.constant.enums.YesNoEnum; import com.pig4cloud.pigx.common.core.exception.CheckedException; -import com.pig4cloud.pigx.common.core.exception.ErrorCodes; import com.pig4cloud.pigx.common.core.util.MsgUtils; import com.pig4cloud.pigx.common.core.util.R; +import com.pig4cloud.pigx.common.core.util.WebUtils; import com.pig4cloud.pigx.common.data.cache.RedisUtils; +import com.pig4cloud.pigx.common.data.resolver.ParamResolver; import com.pig4cloud.pigx.common.data.tenant.TenantBroker; import com.pig4cloud.pigx.common.data.tenant.TenantContextHolder; import com.pig4cloud.pigx.common.file.core.FileTemplate; @@ -97,428 +99,454 @@ import java.util.Objects; @Service @RequiredArgsConstructor public class SysMessageServiceImpl extends ServiceImpl - implements SysMessageService { + implements SysMessageService { - /** - * 支持短信服务商 - */ - private static final Class[] SUPPORT_CONFIG_CLAZZ = { AlibabaConfig.class, CloopenConfig.class, CtyunConfig.class, - EmayConfig.class, HuaweiConfig.class, JdCloudConfig.class, NeteaseConfig.class, TencentConfig.class, - UniConfig.class, YunpianConfig.class, ZhutongConfig.class, DingZhongConfig.class, QiNiuConfig.class }; + /** + * 支持短信服务商 + */ + private static final Class[] SUPPORT_CONFIG_CLAZZ = {AlibabaConfig.class, CloopenConfig.class, CtyunConfig.class, + EmayConfig.class, HuaweiConfig.class, JdCloudConfig.class, NeteaseConfig.class, TencentConfig.class, + UniConfig.class, YunpianConfig.class, ZhutongConfig.class, DingZhongConfig.class, QiNiuConfig.class}; - private final RemoteLogService remoteLogService; + private final RemoteLogService remoteLogService; - private final SysSystemConfigMapper sysSystemConfigMapper; + private final SysSystemConfigMapper sysSystemConfigMapper; - private final SysMessageRelationMapper relationMapper; + private final SysMessageRelationMapper relationMapper; - private final SysUserMapper userMapper; + private final SysUserMapper userMapper; - private final SysFileMapper fileMapper; + private final SysFileMapper fileMapper; - private final FileTemplate fileTemplate; + private final FileTemplate fileTemplate; - /** - * 发送信息 - * @param id id - * @return true/false - */ - @Override - @Transactional(rollbackFor = Exception.class) - public Boolean sendMessage(Long id) { - // 更新信息状态 - SysMessageEntity sysMessage = new SysMessageEntity(); - sysMessage.setSendFlag(YesNoEnum.YES.getCode()); - baseMapper.update(sysMessage, Wrappers.lambdaQuery().eq(SysMessageEntity::getId, id)); - return Boolean.TRUE; - } + /** + * 发送信息 + * + * @param id id + * @return true/false + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean sendMessage(Long id) { + // 更新信息状态 + SysMessageEntity sysMessage = new SysMessageEntity(); + sysMessage.setSendFlag(YesNoEnum.YES.getCode()); + baseMapper.update(sysMessage, Wrappers.lambdaQuery().eq(SysMessageEntity::getId, id)); + return Boolean.TRUE; + } - /** - * 保存消息及其关联关系 - * @param sysMessage 消息对象 - * @return 是否保存成功 - */ - @Transactional(rollbackFor = Exception.class) - public Boolean saveOrUpdateMessage(SysMessageVO sysMessage) { - SysMessageEntity messageEntity = new SysMessageEntity(); - BeanUtils.copyProperties(sysMessage, messageEntity); + /** + * 保存消息及其关联关系 + * + * @param sysMessage 消息对象 + * @return 是否保存成功 + */ + @Transactional(rollbackFor = Exception.class) + public Boolean saveOrUpdateMessage(SysMessageVO sysMessage) { + SysMessageEntity messageEntity = new SysMessageEntity(); + BeanUtils.copyProperties(sysMessage, messageEntity); - if (Objects.isNull(sysMessage.getId())) { - baseMapper.insert(messageEntity); - } - else { - baseMapper.updateById(sysMessage); - } + if (Objects.isNull(sysMessage.getId())) { + baseMapper.insert(messageEntity); + } else { + baseMapper.updateById(sysMessage); + } - // 删除原有用户 - relationMapper.delete(Wrappers.lambdaQuery() - .eq(SysMessageRelationEntity::getMsgId, messageEntity.getId())); + // 删除原有用户 + relationMapper.delete(Wrappers.lambdaQuery() + .eq(SysMessageRelationEntity::getMsgId, messageEntity.getId())); - List userList = sysMessage.getUserList(); - if (CollUtil.isNotEmpty(userList)) { - userList.forEach(user -> { - SysMessageRelationEntity relationEntity = new SysMessageRelationEntity(); - relationEntity.setMsgId(messageEntity.getId()); - relationEntity.setUserId(user.getId()); - relationMapper.insert(relationEntity); - }); - } - else { - userMapper.selectList(Wrappers.emptyWrapper()).stream().map(SysUser::getUserId).forEach(userId -> { - SysMessageRelationEntity relationEntity = new SysMessageRelationEntity(); - relationEntity.setMsgId(messageEntity.getId()); - relationEntity.setUserId(userId); - relationMapper.insert(relationEntity); - }); - } - return Boolean.TRUE; - } + List userList = sysMessage.getUserList(); + if (CollUtil.isNotEmpty(userList)) { + userList.forEach(user -> { + SysMessageRelationEntity relationEntity = new SysMessageRelationEntity(); + relationEntity.setMsgId(messageEntity.getId()); + relationEntity.setUserId(user.getId()); + relationMapper.insert(relationEntity); + }); + } else { + userMapper.selectList(Wrappers.emptyWrapper()).stream().map(SysUser::getUserId).forEach(userId -> { + SysMessageRelationEntity relationEntity = new SysMessageRelationEntity(); + relationEntity.setMsgId(messageEntity.getId()); + relationEntity.setUserId(userId); + relationMapper.insert(relationEntity); + }); + } + return Boolean.TRUE; + } - /** - * 获取用户的信息列表 - * @return list - */ - @Override - public IPage pageUserMessage(Page page, SysMessageVO sysMessage) { - MPJLambdaWrapper wrapper = new MPJLambdaWrapper() - .selectAll(SysMessageEntity.class) - .select(SysMessageRelationEntity::getReadFlag) - .leftJoin(SysMessageRelationEntity.class, SysMessageRelationEntity::getMsgId, SysMessageEntity::getId) - .eq(SysMessageRelationEntity::getUserId, SecurityUtils.getUser().getId()) - .eq(SysMessageEntity::getSendFlag, YesNoEnum.YES.getCode()) - .eq(StrUtil.isNotBlank(sysMessage.getCategory()), SysMessageEntity::getCategory, sysMessage.getCategory()) - .eq(StrUtil.isNotBlank(sysMessage.getReadFlag()), SysMessageRelationEntity::getReadFlag, - sysMessage.getReadFlag()) - .orderByDesc(SysMessageEntity::getSort) - .orderByDesc(SysMessageEntity::getCreateTime); - return baseMapper.selectJoinPage(page, SysMessageVO.class, wrapper); - } + /** + * 获取用户的信息列表 + * + * @return list + */ + @Override + public IPage pageUserMessage(Page page, SysMessageVO sysMessage) { + MPJLambdaWrapper wrapper = new MPJLambdaWrapper() + .selectAll(SysMessageEntity.class) + .select(SysMessageRelationEntity::getReadFlag) + .leftJoin(SysMessageRelationEntity.class, SysMessageRelationEntity::getMsgId, SysMessageEntity::getId) + .eq(SysMessageRelationEntity::getUserId, SecurityUtils.getUser().getId()) + .eq(SysMessageEntity::getSendFlag, YesNoEnum.YES.getCode()) + .eq(StrUtil.isNotBlank(sysMessage.getCategory()), SysMessageEntity::getCategory, sysMessage.getCategory()) + .eq(StrUtil.isNotBlank(sysMessage.getReadFlag()), SysMessageRelationEntity::getReadFlag, + sysMessage.getReadFlag()) + .orderByDesc(SysMessageEntity::getSort) + .orderByDesc(SysMessageEntity::getCreateTime); + return baseMapper.selectJoinPage(page, SysMessageVO.class, wrapper); + } - /** - * 读取信息 - * @param id id - * @return true/false - */ - @Override - public Boolean readMessage(Long id) { - SysMessageRelationEntity relationEntity = new SysMessageRelationEntity(); - relationEntity.setReadFlag(YesNoEnum.YES.getCode()); - relationMapper.update(relationEntity, - Wrappers.lambdaQuery() - .eq(SysMessageRelationEntity::getMsgId, id) - .eq(SysMessageRelationEntity::getUserId, SecurityUtils.getUser().getId())); - return Boolean.TRUE; - } + /** + * 读取信息 + * + * @param id id + * @return true/false + */ + @Override + public Boolean readMessage(Long id) { + SysMessageRelationEntity relationEntity = new SysMessageRelationEntity(); + relationEntity.setReadFlag(YesNoEnum.YES.getCode()); + relationMapper.update(relationEntity, + Wrappers.lambdaQuery() + .eq(SysMessageRelationEntity::getMsgId, id) + .eq(SysMessageRelationEntity::getUserId, SecurityUtils.getUser().getId())); + return Boolean.TRUE; + } - /** - * 获取信息 - * @param id id - * @return messageVO - */ - @Override - public SysMessageVO getMessage(Long id) { - SysMessageEntity messageEntity = baseMapper.selectById(id); - SysMessageVO SysMessageVO = new SysMessageVO(); - BeanUtils.copyProperties(messageEntity, SysMessageVO); + /** + * 获取信息 + * + * @param id id + * @return messageVO + */ + @Override + public SysMessageVO getMessage(Long id) { + SysMessageEntity messageEntity = baseMapper.selectById(id); + SysMessageVO SysMessageVO = new SysMessageVO(); + BeanUtils.copyProperties(messageEntity, SysMessageVO); - // 全体通知 - if (messageEntity.getAllFlag().equals(YesNoEnum.YES.getCode())) { - return SysMessageVO; - } - List userIdList = relationMapper - .selectList(Wrappers.lambdaQuery().eq(SysMessageRelationEntity::getMsgId, id)) - .stream() - .map(SysMessageRelationEntity::getUserId) - .toList(); + // 全体通知 + if (messageEntity.getAllFlag().equals(YesNoEnum.YES.getCode())) { + return SysMessageVO; + } + List userIdList = relationMapper + .selectList(Wrappers.lambdaQuery().eq(SysMessageRelationEntity::getMsgId, id)) + .stream() + .map(SysMessageRelationEntity::getUserId) + .toList(); - if (CollUtil.isNotEmpty(userIdList)) { - List orgNodeUserVoList = userMapper.selectByIds(userIdList).stream().map(user -> { - OrgTreeVO nodeUserVo = new OrgTreeVO(); - nodeUserVo.setId(user.getUserId()); - nodeUserVo.setAvatar(user.getAvatar()); - nodeUserVo.setName(user.getName()); - return nodeUserVo; - }).toList(); + if (CollUtil.isNotEmpty(userIdList)) { + List orgNodeUserVoList = userMapper.selectByIds(userIdList).stream().map(user -> { + OrgTreeVO nodeUserVo = new OrgTreeVO(); + nodeUserVo.setId(user.getUserId()); + nodeUserVo.setAvatar(user.getAvatar()); + nodeUserVo.setName(user.getName()); + return nodeUserVo; + }).toList(); - SysMessageVO.setUserList(orgNodeUserVoList); - } + SysMessageVO.setUserList(orgNodeUserVoList); + } - return SysMessageVO; - } + return SysMessageVO; + } - /** - * 查询用户阅读情况 - * @param page 分页 - * @param messageId 消息ID - * @param name 姓名 - * @return page - */ - @Override - public Page pageUserRead(Page page, Long messageId, String name) { - MPJLambdaWrapper wrapper = new MPJLambdaWrapper() - .selectAll(SysMessageRelationEntity.class) - .select(SysUser::getUsername, SysUser::getName, SysUser::getUserId) - .select(SysMessageEntity::getTitle) - .leftJoin(SysUser.class, SysUser::getUserId, SysMessageRelationEntity::getUserId) - .leftJoin(SysMessageEntity.class, SysMessageEntity::getId, SysMessageRelationEntity::getMsgId) - .eq(SysMessageRelationEntity::getMsgId, messageId) - .like(StrUtil.isNotBlank(name), SysUser::getName, name); - return relationMapper.selectJoinPage(page, SysMessageReadVO.class, wrapper); - } + /** + * 查询用户阅读情况 + * + * @param page 分页 + * @param messageId 消息ID + * @param name 姓名 + * @return page + */ + @Override + public Page pageUserRead(Page page, Long messageId, String name) { + MPJLambdaWrapper wrapper = new MPJLambdaWrapper() + .selectAll(SysMessageRelationEntity.class) + .select(SysUser::getUsername, SysUser::getName, SysUser::getUserId) + .select(SysMessageEntity::getTitle) + .leftJoin(SysUser.class, SysUser::getUserId, SysMessageRelationEntity::getUserId) + .leftJoin(SysMessageEntity.class, SysMessageEntity::getId, SysMessageRelationEntity::getMsgId) + .eq(SysMessageRelationEntity::getMsgId, messageId) + .like(StrUtil.isNotBlank(name), SysUser::getName, name); + return relationMapper.selectJoinPage(page, SysMessageReadVO.class, wrapper); + } - /** - * 发送手机验证码 TODO: 调用短信网关发送验证码,测试返回前端 - * @param mobile mobile - * @return code - */ - @Override - public R sendSmsCode(String mobile) { - List userList = TenantBroker - .noneAs(() -> userMapper.selectList(Wrappers.query().lambda().eq(SysUser::getPhone, mobile))); + /** + * 发送手机验证码 + * + * @param mobile 手机号码 + * @param registered 是否已注册 + * @return 发送结果 + */ + @Override + public R sendSmsCode(String mobile, boolean registered) { + // IP 限制校验,单位时间内同一IP发送次数限制 + String clientIp = WebUtils.getIP(); + String ipLimitKey = CacheConstants.DEFAULT_CODE_KEY + "IP_LIMIT:" + clientIp; + if (StrUtil.isNotBlank(clientIp)) { + Long maxTimes = ParamResolver.getLong("SMS_IP_LIMIT_TIMES", 5L); + Long ipSendTimes = RedisUtils.increment(ipLimitKey, 1L); + // 设置过期时间 + RedisUtils.expire(ipLimitKey, SecurityConstants.CODE_TIME); - if (CollUtil.isEmpty(userList)) { - log.info("手机号未注册:{}", mobile); - return R.ok(Boolean.FALSE, MsgUtils.getMessage(ErrorCodes.SYS_APP_PHONE_UNREGISTERED, mobile)); - } + if (ipSendTimes > maxTimes) { + log.info("IP发送验证码过于频繁:{}, 已发送{}次", clientIp, ipSendTimes); + return R.failed(Boolean.FALSE, MsgUtils.getMessage(UpmsErrorCodes.SYS_APP_SMS_OFTEN)); + } + } - String codeObj = RedisUtils - .get(CacheConstants.DEFAULT_CODE_KEY + LoginTypeEnum.SMS.getType() + StringPool.AT + mobile); + List userList = TenantBroker + .noneAs(() -> userMapper.selectList(Wrappers.query().lambda().eq(SysUser::getPhone, mobile))); - if (StrUtil.isNotBlank(codeObj)) { - log.info("手机号验证码未过期:{},{}", mobile, codeObj); - return R.ok(Boolean.FALSE, MsgUtils.getMessage(ErrorCodes.SYS_APP_SMS_OFTEN)); - } + if (registered && CollUtil.isEmpty(userList)) { + log.info("手机号未注册:{}", mobile); + return R.failed(Boolean.FALSE, MsgUtils.getMessage(UpmsErrorCodes.SYS_APP_PHONE_UNREGISTERED, mobile)); + } - String code = RandomUtil.randomNumbers(Integer.parseInt(SecurityConstants.CODE_SIZE)); - log.info("手机号生成验证码成功:{},{}", mobile, code); - RedisUtils.set(CacheConstants.DEFAULT_CODE_KEY + LoginTypeEnum.SMS.getType() + StringPool.AT + mobile, code, - SecurityConstants.CODE_TIME); + String codeObj = RedisUtils + .get(CacheConstants.DEFAULT_CODE_KEY + LoginTypeEnum.SMS.getType() + StringPool.AT + mobile); - // 发送 - return this.sendSms(MessageSmsDTO.builder() - .mobile(mobile) - .biz(SmsBizCodeEnum.SMS_NORMAL_CODE.getCode()) - .param(code) - .build()); - } + if (StrUtil.isNotBlank(codeObj)) { + log.info("手机号验证码未过期:{},{}", mobile, codeObj); + return R.failed(Boolean.FALSE, MsgUtils.getMessage(UpmsErrorCodes.SYS_APP_SMS_OFTEN)); + } - /** - * 发送短信 - * @param messageSmsDTO 消息 短信 DTO - * @return {@link R } - */ - @Override - public R sendSms(MessageSmsDTO messageSmsDTO) { + String code = RandomUtil.randomNumbers(Integer.parseInt(SecurityConstants.CODE_SIZE)); + log.info("手机号生成验证码成功:{},{}", mobile, code); + RedisUtils.set(CacheConstants.DEFAULT_CODE_KEY + LoginTypeEnum.SMS.getType() + StringPool.AT + mobile, code, + SecurityConstants.CODE_TIME); - // 根据业务编码获取短信通道配置 - List configEntityList = sysSystemConfigMapper - .selectList(Wrappers.lambdaQuery() - .eq(SysSystemConfigEntity::getConfigType, SystemConfigTypeEnum.SMS.getValue()) - .eq(SysSystemConfigEntity::getConfigStatus, YesNoEnum.YES.getCode()) - .eq(SysSystemConfigEntity::getConfigKey, messageSmsDTO.getBizCode())); - if (CollUtil.isEmpty(configEntityList)) { - return R.failed("发送失败,短信通道配置不存在"); - } + // 发送 + return this.sendSms(MessageSmsDTO.builder() + .mobile(mobile) + .biz(SmsBizCodeEnum.SMS_NORMAL_CODE.getCode()) + .param(code) + .build()); + } - SysSystemConfigEntity configEntity = configEntityList.get(0); - JSONObject configMap = JSONUtil.parseObj(configEntity.getConfigValue()); + /** + * 发送短信 + * + * @param messageSmsDTO 消息 短信 DTO + * @return {@link R } + */ + @Override + public R sendSms(MessageSmsDTO messageSmsDTO) { - // 组装SMS4J 的发送对象 - SmsBlend smsBlend = SmsFactory.getSmsBlend(messageSmsDTO.getBizCode()); - if (Objects.isNull(smsBlend)) { - Class targetClass = Arrays.stream(SUPPORT_CONFIG_CLAZZ) - .filter(config -> config.getSimpleName() - .toLowerCase() - .contains(configMap.getStr(MessageSmsDTO.Fields.supplier))) - .findFirst() - .orElseThrow(() -> new CheckedException("发送失败,短信通道配置不存在")); - BaseConfig baseConfig = (BaseConfig) JSONUtil.toBean(configEntity.getConfigValue(), targetClass); + // 根据业务编码获取短信通道配置 + List configEntityList = sysSystemConfigMapper + .selectList(Wrappers.lambdaQuery() + .eq(SysSystemConfigEntity::getConfigType, SystemConfigTypeEnum.SMS.getValue()) + .eq(SysSystemConfigEntity::getConfigStatus, YesNoEnum.YES.getCode()) + .eq(SysSystemConfigEntity::getConfigKey, messageSmsDTO.getBizCode())); + if (CollUtil.isEmpty(configEntityList)) { + return R.failed(MsgUtils.getMessage(UpmsErrorCodes.SYS_MESSAGE_SMS_CHANNEL_MISSING)); + } - // 如果渠道扩展参数不为空则增加特性化参数 - if (StrUtil.isNotBlank(configMap.getStr(MessageSmsDTO.Fields.extParams))) { - JSONObject extParams = configMap.getJSONObject(MessageSmsDTO.Fields.extParams); - BeanUtil.copyProperties(extParams, baseConfig); - } + SysSystemConfigEntity configEntity = configEntityList.get(0); + JSONObject configMap = JSONUtil.parseObj(configEntity.getConfigValue()); - baseConfig.setConfigId(configEntity.getConfigKey()); - SmsFactory.createSmsBlend(baseConfig); - smsBlend = SmsFactory.getSmsBlend(messageSmsDTO.getBizCode()); - } + // 组装SMS4J 的发送对象 + SmsBlend smsBlend = SmsFactory.getSmsBlend(messageSmsDTO.getBizCode()); + if (Objects.isNull(smsBlend)) { + Class targetClass = Arrays.stream(SUPPORT_CONFIG_CLAZZ) + .filter(config -> config.getSimpleName() + .toLowerCase() + .contains(configMap.getStr(MessageSmsDTO.Fields.supplier))) + .findFirst() + .orElseThrow(() -> new CheckedException( + MsgUtils.getMessage(UpmsErrorCodes.SYS_MESSAGE_SMS_CHANNEL_MISSING))); + BaseConfig baseConfig = (BaseConfig) JSONUtil.toBean(configEntity.getConfigValue(), targetClass); - // 异步发送短信 - SysLogDTO sysLog = SysLogUtils.getSysLog(); - Long start = System.currentTimeMillis(); - sysLog.setTenantId(TenantContextHolder.getTenantId()); - for (String mobile : messageSmsDTO.getMobiles()) { - smsBlend.sendMessageAsync(mobile, configMap.getStr(MessageSmsDTO.Fields.templateId), - messageSmsDTO.getParams(), smsResponse -> { - log.info("发送短信结果:{}", smsResponse); - sysLog.setTitle(String.format("发送短信 %s", mobile)); - sysLog.setLogType(LogTypeEnum.NORMAL.getType()); - sysLog.setServiceId(SystemConfigTypeEnum.SMS.getValue()); - sysLog.setParams(JacksonSensitiveFieldUtil.writeValueAsString(messageSmsDTO)); - sysLog.setTime(System.currentTimeMillis() - start); - sysLog.setException(JacksonSensitiveFieldUtil.writeValueAsString(smsResponse)); - remoteLogService.saveLog(sysLog); - }); - } - return R.ok(); - } + // 如果渠道扩展参数不为空则增加特性化参数 + if (StrUtil.isNotBlank(configMap.getStr(MessageSmsDTO.Fields.extParams))) { + JSONObject extParams = configMap.getJSONObject(MessageSmsDTO.Fields.extParams); + BeanUtil.copyProperties(extParams, baseConfig); + } - /** - * 发送钩子消息 - * @param messageHookDTO 消息挂钩 DTO - * @return {@link R } - */ - @Override - public R sendHook(MessageHookDTO messageHookDTO) { + baseConfig.setConfigId(configEntity.getConfigKey()); + SmsFactory.createSmsBlend(baseConfig); + smsBlend = SmsFactory.getSmsBlend(messageSmsDTO.getBizCode()); + } - // 根据业务编码获取短信通道配置 - List configEntityList = sysSystemConfigMapper - .selectList(Wrappers.lambdaQuery() - .eq(SysSystemConfigEntity::getConfigType, SystemConfigTypeEnum.WEBHOOK.getValue()) - .eq(SysSystemConfigEntity::getConfigStatus, YesNoEnum.YES.getCode()) - .eq(SysSystemConfigEntity::getConfigKey, messageHookDTO.getBizCode())); - if (CollUtil.isEmpty(configEntityList)) { - return R.failed("发送失败,短信通道配置不存在"); - } + // 异步发送短信 + SysLogDTO sysLog = SysLogUtils.getSysLog(); + Long start = System.currentTimeMillis(); + sysLog.setTenantId(TenantContextHolder.getTenantId()); + for (String mobile : messageSmsDTO.getMobiles()) { + smsBlend.sendMessageAsync(mobile, configMap.getStr(MessageSmsDTO.Fields.templateId), + messageSmsDTO.getParams(), smsResponse -> { + log.info("发送短信结果:{}", smsResponse); + sysLog.setTitle(String.format("发送短信 %s", mobile)); + sysLog.setLogType(LogTypeEnum.NORMAL.getType()); + sysLog.setServiceId(SystemConfigTypeEnum.SMS.getValue()); + sysLog.setParams(JacksonSensitiveFieldUtil.writeValueAsString(messageSmsDTO)); + sysLog.setTime(System.currentTimeMillis() - start); + sysLog.setException(JacksonSensitiveFieldUtil.writeValueAsString(smsResponse)); + remoteLogService.saveLog(sysLog); + }); + } + return R.ok(); + } - SysSystemConfigEntity configEntity = configEntityList.get(0); - JSONObject configMap = JSONUtil.parseObj(configEntity.getConfigValue()); - String supplier = configMap.getStr("supplier"); + /** + * 发送钩子消息 + * + * @param messageHookDTO 消息挂钩 DTO + * @return {@link R } + */ + @Override + public R sendHook(MessageHookDTO messageHookDTO) { - // 根据配置创建服务实例并注册 - OaSender alarm = OaFactory.getSmsOaBlend(messageHookDTO.getBizCode()); - if (Objects.isNull(alarm)) { - if (StrUtil.equalsAnyIgnoreCase(OaType.DING_TALK.toString(), supplier)) { - DingTalkConfig dingTalkConfig = new DingTalkConfig(); - dingTalkConfig.setConfigId(messageHookDTO.getBizCode()); - dingTalkConfig.setSign(configMap.getStr("sign")); - dingTalkConfig.setTokenId(configMap.getStr("tokenId")); - OaFactory.createAndRegisterOaSender(dingTalkConfig); - } - if (StrUtil.equalsAnyIgnoreCase(OaType.BYTE_TALK.toString(), supplier)) { - ByteTalkConfig byteTalkConfig = new ByteTalkConfig(); - byteTalkConfig.setConfigId(messageHookDTO.getBizCode()); - byteTalkConfig.setSign(configMap.getStr("sign")); - byteTalkConfig.setTokenId(configMap.getStr("tokenId")); - OaFactory.createAndRegisterOaSender(byteTalkConfig); - } + // 根据业务编码获取短信通道配置 + List configEntityList = sysSystemConfigMapper + .selectList(Wrappers.lambdaQuery() + .eq(SysSystemConfigEntity::getConfigType, SystemConfigTypeEnum.WEBHOOK.getValue()) + .eq(SysSystemConfigEntity::getConfigStatus, YesNoEnum.YES.getCode()) + .eq(SysSystemConfigEntity::getConfigKey, messageHookDTO.getBizCode())); + if (CollUtil.isEmpty(configEntityList)) { + return R.failed(MsgUtils.getMessage(UpmsErrorCodes.SYS_MESSAGE_SMS_CHANNEL_MISSING)); + } - if (StrUtil.equalsAnyIgnoreCase(OaType.WE_TALK.toString(), supplier)) { - WeTalkConfig weTalkConfig = new WeTalkConfig(); - weTalkConfig.setConfigId(messageHookDTO.getBizCode()); - weTalkConfig.setSign(configMap.getStr("sign")); - weTalkConfig.setTokenId(configMap.getStr("tokenId")); - OaFactory.createAndRegisterOaSender(weTalkConfig); - } - alarm = OaFactory.getSmsOaBlend(messageHookDTO.getBizCode()); - } + SysSystemConfigEntity configEntity = configEntityList.get(0); + JSONObject configMap = JSONUtil.parseObj(configEntity.getConfigValue()); + String supplier = configMap.getStr("supplier"); - Request request = new Request(); - request.setContent(messageHookDTO.getMessageContent()); - request.setTitle(messageHookDTO.getMessageTitle()); - request.setMessageUrl(messageHookDTO.getMessageUrl()); - request.setPicUrl(messageHookDTO.getPicUrl()); - request.setIsNoticeAll(messageHookDTO.isNoticeAll()); - request.setPhoneList(messageHookDTO.getPhoneList()); + // 根据配置创建服务实例并注册 + OaSender alarm = OaFactory.getSmsOaBlend(messageHookDTO.getBizCode()); + if (Objects.isNull(alarm)) { + if (StrUtil.equalsAnyIgnoreCase(OaType.DING_TALK.toString(), supplier)) { + DingTalkConfig dingTalkConfig = new DingTalkConfig(); + dingTalkConfig.setConfigId(messageHookDTO.getBizCode()); + dingTalkConfig.setSign(configMap.getStr("sign")); + dingTalkConfig.setTokenId(configMap.getStr("tokenId")); + OaFactory.createAndRegisterOaSender(dingTalkConfig); + } + if (StrUtil.equalsAnyIgnoreCase(OaType.BYTE_TALK.toString(), supplier)) { + ByteTalkConfig byteTalkConfig = new ByteTalkConfig(); + byteTalkConfig.setConfigId(messageHookDTO.getBizCode()); + byteTalkConfig.setSign(configMap.getStr("sign")); + byteTalkConfig.setTokenId(configMap.getStr("tokenId")); + OaFactory.createAndRegisterOaSender(byteTalkConfig); + } - SysLogDTO sysLog = SysLogUtils.getSysLog(); - sysLog.setTenantId(TenantContextHolder.getTenantId()); - Long start = System.currentTimeMillis(); - alarm.senderAsync(request, - MessageType.valueOf(String.format("%s_%s", supplier, messageHookDTO.getMessageType()).toUpperCase()), - response -> { - log.info("发送Hook结果:{}", response); - sysLog.setTitle(String.format("发送Hook %s", messageHookDTO.getBizCode())); - sysLog.setLogType(LogTypeEnum.NORMAL.getType()); - sysLog.setServiceId(SystemConfigTypeEnum.WEBHOOK.getValue()); - sysLog.setParams(JacksonSensitiveFieldUtil.writeValueAsString(messageHookDTO)); - sysLog.setTime(System.currentTimeMillis() - start); - sysLog.setException(JacksonSensitiveFieldUtil.writeValueAsString(response)); - remoteLogService.saveLog(sysLog); - }); - return R.ok(); - } + if (StrUtil.equalsAnyIgnoreCase(OaType.WE_TALK.toString(), supplier)) { + WeTalkConfig weTalkConfig = new WeTalkConfig(); + weTalkConfig.setConfigId(messageHookDTO.getBizCode()); + weTalkConfig.setSign(configMap.getStr("sign")); + weTalkConfig.setTokenId(configMap.getStr("tokenId")); + OaFactory.createAndRegisterOaSender(weTalkConfig); + } + alarm = OaFactory.getSmsOaBlend(messageHookDTO.getBizCode()); + } - /** - * 发送邮件 - * @param messageEmailDTO 留言内容 电子邮件 DTO - * @return {@link R } - */ - @SneakyThrows - @Override - public R sendEmail(MessageEmailDTO messageEmailDTO) { - // 根据业务编码获取短信通道配置 - List configEntityList = sysSystemConfigMapper - .selectList(Wrappers.lambdaQuery() - .eq(SysSystemConfigEntity::getConfigType, SystemConfigTypeEnum.EMAIL.getValue()) - .eq(SysSystemConfigEntity::getConfigStatus, YesNoEnum.YES.getCode()) - .eq(SysSystemConfigEntity::getConfigKey, messageEmailDTO.getBizCode())); - if (CollUtil.isEmpty(configEntityList)) { - return R.failed("发送失败,通道配置不存在"); - } - SysSystemConfigEntity configEntity = configEntityList.get(0); - JSONObject configMap = JSONUtil.parseObj(configEntity.getConfigValue()); + Request request = new Request(); + request.setContent(messageHookDTO.getMessageContent()); + request.setTitle(messageHookDTO.getMessageTitle()); + request.setMessageUrl(messageHookDTO.getMessageUrl()); + request.setPicUrl(messageHookDTO.getPicUrl()); + request.setIsNoticeAll(messageHookDTO.isNoticeAll()); + request.setPhoneList(messageHookDTO.getPhoneList()); - List tempFileList = new ArrayList<>(); - if (CollUtil.isNotEmpty(messageEmailDTO.getAttachmentList())) { - TenantContextHolder.setTenantSkip(); - for (String fileName : messageEmailDTO.getAttachmentList()) { - SysFile sysFile = fileMapper - .selectOne(Wrappers.lambdaQuery().eq(SysFile::getFileName, fileName)); - S3Object s3Object = fileTemplate.getObject(sysFile.getBucketName(), sysFile.getDir(), fileName); - File file = FileUtil.file(FileUtil.getTmpDirPath(), sysFile.getOriginal()); - tempFileList.add(file); - IoUtil.copy(s3Object.getObjectContent(), FileUtil.getOutputStream(file)); - } - } + SysLogDTO sysLog = SysLogUtils.getSysLog(); + sysLog.setTenantId(TenantContextHolder.getTenantId()); + Long start = System.currentTimeMillis(); + alarm.senderAsync(request, + MessageType.valueOf(String.format("%s_%s", supplier, messageHookDTO.getMessageType()).toUpperCase()), + response -> { + log.info("发送Hook结果:{}", response); + sysLog.setTitle(String.format("发送Hook %s", messageHookDTO.getBizCode())); + sysLog.setLogType(LogTypeEnum.NORMAL.getType()); + sysLog.setServiceId(SystemConfigTypeEnum.WEBHOOK.getValue()); + sysLog.setParams(JacksonSensitiveFieldUtil.writeValueAsString(messageHookDTO)); + sysLog.setTime(System.currentTimeMillis() - start); + sysLog.setException(JacksonSensitiveFieldUtil.writeValueAsString(response)); + remoteLogService.saveLog(sysLog); + }); + return R.ok(); + } - MailAccount account = new MailAccount(); - account.setHost(configMap.getStr("smtpServer")); - account.setPort(configMap.getInt("port")); - account.setAuth(configMap.getBool("isAuth")); - account.setSslEnable(configMap.getBool("isSSL")); - account.setFrom(configMap.getStr("username")); - account.setUser(configMap.getStr("username")); - account.setPass(configMap.getStr("password")); + /** + * 发送邮件 + * + * @param messageEmailDTO 留言内容 电子邮件 DTO + * @return {@link R } + */ + @SneakyThrows + @Override + public R sendEmail(MessageEmailDTO messageEmailDTO) { + // 根据业务编码获取短信通道配置 + List configEntityList = sysSystemConfigMapper + .selectList(Wrappers.lambdaQuery() + .eq(SysSystemConfigEntity::getConfigType, SystemConfigTypeEnum.EMAIL.getValue()) + .eq(SysSystemConfigEntity::getConfigStatus, YesNoEnum.YES.getCode()) + .eq(SysSystemConfigEntity::getConfigKey, messageEmailDTO.getBizCode())); + if (CollUtil.isEmpty(configEntityList)) { + return R.failed(MsgUtils.getMessage(UpmsErrorCodes.SYS_MESSAGE_CHANNEL_MISSING)); + } + SysSystemConfigEntity configEntity = configEntityList.get(0); + JSONObject configMap = JSONUtil.parseObj(configEntity.getConfigValue()); - // 渲染模板 - TemplateEngine engine = TemplateUtil.createEngine(new TemplateConfig()); - Template template = engine.getTemplate(configMap.getStr("html")); - String result = template.render(messageEmailDTO.getHtmlValues()); + List tempFileList = new ArrayList<>(); + if (CollUtil.isNotEmpty(messageEmailDTO.getAttachmentList())) { + TenantContextHolder.setTenantSkip(); + for (String fileName : messageEmailDTO.getAttachmentList()) { + SysFile sysFile = fileMapper + .selectOne(Wrappers.lambdaQuery().eq(SysFile::getFileName, fileName)); + S3Object s3Object = fileTemplate.getObject(sysFile.getBucketName(), sysFile.getDir(), fileName); + File file = FileUtil.file(FileUtil.getTmpDirPath(), sysFile.getOriginal()); + tempFileList.add(file); + IoUtil.copy(s3Object.getObjectContent(), FileUtil.getOutputStream(file)); + } + } - Long start = System.currentTimeMillis(); - MailUtil.send(account, messageEmailDTO.getMailAddress(), messageEmailDTO.getCcList(), - messageEmailDTO.getBccList(), messageEmailDTO.getTitle(), result, true, - tempFileList.toArray(new File[0])); - Long end = System.currentTimeMillis(); - // 写入日志 - SysLogDTO sysLog = SysLogUtils.getSysLog(); - sysLog.setTitle(String.format("发送邮件 %s", messageEmailDTO.getTitle())); - sysLog.setLogType(LogTypeEnum.NORMAL.getType()); - sysLog.setServiceId(SystemConfigTypeEnum.EMAIL.getValue()); - sysLog.setParams(JacksonSensitiveFieldUtil.writeValueAsString(messageEmailDTO)); - sysLog.setTenantId(TenantContextHolder.getTenantId()); - sysLog.setTime(end - start); - remoteLogService.saveLog(sysLog); - // 删除临时文件 - tempFileList.forEach(FileUtil::del); - return R.ok(); - } + MailAccount account = new MailAccount(); + account.setHost(configMap.getStr("smtpServer")); + account.setPort(configMap.getInt("port")); + account.setAuth(configMap.getBool("isAuth")); + account.setSslEnable(configMap.getBool("isSSL")); + account.setFrom(configMap.getStr("username")); + account.setUser(configMap.getStr("username")); + account.setPass(configMap.getStr("password")); - /** - * 列出 Hook 业务代码 - * @param messageHookDTO 消息钩子 DTO - * @return {@link R } - */ - @Override - public R listHookBizCode(MessageHookDTO messageHookDTO) { - List configEntityList = sysSystemConfigMapper - .selectList(Wrappers.lambdaQuery() - .eq(SysSystemConfigEntity::getConfigType, messageHookDTO.getMessageType()) - .eq(SysSystemConfigEntity::getConfigStatus, YesNoEnum.YES.getCode())); - return R.ok(configEntityList); - } + // 渲染模板 + TemplateEngine engine = TemplateUtil.createEngine(new TemplateConfig()); + Template template = engine.getTemplate(configMap.getStr("html")); + String result = template.render(messageEmailDTO.getHtmlValues()); + + Long start = System.currentTimeMillis(); + MailUtil.send(account, messageEmailDTO.getMailAddress(), messageEmailDTO.getCcList(), + messageEmailDTO.getBccList(), messageEmailDTO.getTitle(), result, true, + tempFileList.toArray(new File[0])); + Long end = System.currentTimeMillis(); + // 写入日志 + SysLogDTO sysLog = SysLogUtils.getSysLog(); + sysLog.setTitle(String.format("发送邮件 %s", messageEmailDTO.getTitle())); + sysLog.setLogType(LogTypeEnum.NORMAL.getType()); + sysLog.setServiceId(SystemConfigTypeEnum.EMAIL.getValue()); + sysLog.setParams(JacksonSensitiveFieldUtil.writeValueAsString(messageEmailDTO)); + sysLog.setTenantId(TenantContextHolder.getTenantId()); + sysLog.setTime(end - start); + remoteLogService.saveLog(sysLog); + // 删除临时文件 + tempFileList.forEach(FileUtil::del); + return R.ok(); + } + + /** + * 列出 Hook 业务代码 + * + * @param messageHookDTO 消息钩子 DTO + * @return {@link R } + */ + @Override + public R listHookBizCode(MessageHookDTO messageHookDTO) { + List configEntityList = sysSystemConfigMapper + .selectList(Wrappers.lambdaQuery() + .eq(SysSystemConfigEntity::getConfigType, messageHookDTO.getMessageType()) + .eq(SysSystemConfigEntity::getConfigStatus, YesNoEnum.YES.getCode())); + return R.ok(configEntityList); + } } diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysOauthClientDetailsServiceImpl.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysOauthClientDetailsServiceImpl.java index bf69815e3..2fcfaf88c 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysOauthClientDetailsServiceImpl.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysOauthClientDetailsServiceImpl.java @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysPostServiceImpl.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysPostServiceImpl.java index ed1af86b3..9038d487f 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysPostServiceImpl.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysPostServiceImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -21,11 +21,11 @@ import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ArrayUtil; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.pig4cloud.pigx.admin.api.constant.UpmsErrorCodes; import com.pig4cloud.pigx.admin.api.entity.SysPost; import com.pig4cloud.pigx.admin.api.vo.PostExcelVO; import com.pig4cloud.pigx.admin.mapper.SysPostMapper; import com.pig4cloud.pigx.admin.service.SysPostService; -import com.pig4cloud.pigx.common.core.exception.ErrorCodes; import com.pig4cloud.pigx.common.core.util.MsgUtils; import com.pig4cloud.pigx.common.core.util.R; import com.pig4cloud.pigx.common.excel.vo.ErrorMessage; @@ -45,71 +45,72 @@ import java.util.Set; @Service public class SysPostServiceImpl extends ServiceImpl implements SysPostService { - /** - * 导入岗位 - * @param excelVOList 岗位列表 - * @param bindingResult 错误信息列表 - * @return ok fail - */ - @Override - public R importPost(List excelVOList, BindingResult bindingResult) { - // 通用校验获取失败的数据 - List errorMessageList = (List) bindingResult.getTarget(); + /** + * 导入岗位 + * + * @param excelVOList 岗位列表 + * @param bindingResult 错误信息列表 + * @return ok fail + */ + @Override + public R importPost(List excelVOList, BindingResult bindingResult) { + // 通用校验获取失败的数据 + List errorMessageList = (List) bindingResult.getTarget(); - // 个性化校验逻辑 - List postList = this.list(); + // 个性化校验逻辑 + List postList = this.list(); - // 执行数据插入操作 组装 PostDto - for (PostExcelVO excel : excelVOList) { - Set errorMsg = new HashSet<>(); - // 检验岗位名称或者岗位编码是否存在 - boolean existPost = postList.stream() - .anyMatch(post -> excel.getPostName().equals(post.getPostName()) - || excel.getPostCode().equals(post.getPostCode())); + // 执行数据插入操作 组装 PostDto + for (PostExcelVO excel : excelVOList) { + Set errorMsg = new HashSet<>(); + // 检验岗位名称或者岗位编码是否存在 + boolean existPost = postList.stream() + .anyMatch(post -> excel.getPostName().equals(post.getPostName()) + || excel.getPostCode().equals(post.getPostCode())); - if (existPost) { - errorMsg.add(MsgUtils.getMessage(ErrorCodes.SYS_POST_NAMEORCODE_EXISTING, excel.getPostName(), - excel.getPostCode())); - } + if (existPost) { + errorMsg.add(MsgUtils.getMessage(UpmsErrorCodes.SYS_POST_NAMEORCODE_EXISTING, excel.getPostName(), + excel.getPostCode())); + } - // 数据合法情况 - if (CollUtil.isEmpty(errorMsg)) { - insertExcelPost(excel); - } - else { - // 数据不合法 - errorMessageList.add(new ErrorMessage(excel.getLineNum(), errorMsg)); - } - } - if (CollUtil.isNotEmpty(errorMessageList)) { - return R.failed(errorMessageList); - } - return R.ok(); - } + // 数据合法情况 + if (CollUtil.isEmpty(errorMsg)) { + insertExcelPost(excel); + } else { + // 数据不合法 + errorMessageList.add(new ErrorMessage(excel.getLineNum(), errorMsg)); + } + } + if (CollUtil.isNotEmpty(errorMessageList)) { + return R.failed(errorMessageList); + } + return R.ok(); + } - /** - * 导出excel 表格 - * @return - */ - @Override - public List listPost(SysPost query, Long[] ids) { - List postList = this - .list(Wrappers.lambdaQuery(query).in(ArrayUtil.isNotEmpty(ids), SysPost::getPostId, CollUtil.toList(ids))); - // 转换成execl 对象输出 - return postList.stream().map(post -> { - PostExcelVO postExcelVO = new PostExcelVO(); - BeanUtil.copyProperties(post, postExcelVO); - return postExcelVO; + /** + * 导出excel 表格 + * + * @return + */ + @Override + public List listPost(SysPost query, Long[] ids) { + List postList = this + .list(Wrappers.lambdaQuery(query).in(ArrayUtil.isNotEmpty(ids), SysPost::getPostId, CollUtil.toList(ids))); + // 转换成execl 对象输出 + return postList.stream().map(post -> { + PostExcelVO postExcelVO = new PostExcelVO(); + BeanUtil.copyProperties(post, postExcelVO); + return postExcelVO; }).toList(); - } + } - /** - * 插入excel Post - */ - private void insertExcelPost(PostExcelVO excel) { - SysPost sysPost = new SysPost(); - BeanUtil.copyProperties(excel, sysPost); - this.save(sysPost); - } + /** + * 插入excel Post + */ + private void insertExcelPost(PostExcelVO excel) { + SysPost sysPost = new SysPost(); + BeanUtil.copyProperties(excel, sysPost); + this.save(sysPost); + } } diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysPublicParamServiceImpl.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysPublicParamServiceImpl.java index 2fb01860e..688b2d454 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysPublicParamServiceImpl.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysPublicParamServiceImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -20,12 +20,12 @@ package com.pig4cloud.pigx.admin.service.impl; import cn.hutool.core.collection.CollUtil; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.pig4cloud.pigx.admin.api.constant.UpmsErrorCodes; import com.pig4cloud.pigx.admin.api.entity.SysPublicParam; import com.pig4cloud.pigx.admin.mapper.SysPublicParamMapper; import com.pig4cloud.pigx.admin.service.SysPublicParamService; import com.pig4cloud.pigx.common.core.constant.CacheConstants; import com.pig4cloud.pigx.common.core.constant.enums.DictTypeEnum; -import com.pig4cloud.pigx.common.core.exception.ErrorCodes; import com.pig4cloud.pigx.common.core.util.MsgUtils; import com.pig4cloud.pigx.common.core.util.R; import lombok.AllArgsConstructor; @@ -46,74 +46,78 @@ import java.util.Map; @Service @AllArgsConstructor public class SysPublicParamServiceImpl extends ServiceImpl - implements SysPublicParamService { + implements SysPublicParamService { - @Override - @Cacheable(value = CacheConstants.PARAMS_DETAILS, key = "#publicKey", unless = "#result == null ") - public String getSysPublicParamKeyToValue(String publicKey) { - SysPublicParam sysPublicParam = this.baseMapper - .selectOne(Wrappers.lambdaQuery().eq(SysPublicParam::getPublicKey, publicKey)); + @Override + @Cacheable(value = CacheConstants.PARAMS_DETAILS, key = "#publicKey", unless = "#result == null ") + public String getSysPublicParamKeyToValue(String publicKey) { + SysPublicParam sysPublicParam = this.baseMapper + .selectOne(Wrappers.lambdaQuery().eq(SysPublicParam::getPublicKey, publicKey)); - if (sysPublicParam != null) { - return sysPublicParam.getPublicValue(); - } - return null; - } + if (sysPublicParam != null) { + return sysPublicParam.getPublicValue(); + } + return null; + } - /** - * 通过key查询公共参数指定值 - * @param keys 参数列表 - * @return Map - */ - @Override - public Map getSysPublicParamsKeyToValue(String[] keys) { - List paramList = this.baseMapper - .selectList(Wrappers.lambdaQuery().in(SysPublicParam::getPublicKey, CollUtil.toList(keys))); - Map result = new HashMap<>(8); - paramList.forEach(param -> result.put(param.getPublicKey(), param.getPublicValue())); - return result; - } + /** + * 通过key查询公共参数指定值 + * + * @param keys 参数列表 + * @return Map + */ + @Override + public Map getSysPublicParamsKeyToValue(String[] keys) { + List paramList = this.baseMapper + .selectList(Wrappers.lambdaQuery().in(SysPublicParam::getPublicKey, CollUtil.toList(keys))); + Map result = new HashMap<>(8); + paramList.forEach(param -> result.put(param.getPublicKey(), param.getPublicValue())); + return result; + } - /** - * 更新参数 - * @param sysPublicParam - * @return - */ - @Override - @CacheEvict(value = CacheConstants.PARAMS_DETAILS, key = "#sysPublicParam.publicKey") - public R updateParam(SysPublicParam sysPublicParam) { - SysPublicParam param = this.getById(sysPublicParam.getPublicId()); - // 系统内置 - if (DictTypeEnum.SYSTEM.getType().equals(param.getSystemFlag())) { - return R.failed(MsgUtils.getMessage(ErrorCodes.SYS_PARAM_DELETE_SYSTEM)); - } - return R.ok(this.updateById(sysPublicParam)); - } + /** + * 更新参数 + * + * @param sysPublicParam + * @return + */ + @Override + @CacheEvict(value = CacheConstants.PARAMS_DETAILS, key = "#sysPublicParam.publicKey") + public R updateParam(SysPublicParam sysPublicParam) { + SysPublicParam param = this.getById(sysPublicParam.getPublicId()); + // 系统内置 + if (DictTypeEnum.SYSTEM.getType().equals(param.getSystemFlag())) { + return R.failed(MsgUtils.getMessage(UpmsErrorCodes.SYS_PARAM_DELETE_SYSTEM)); + } + return R.ok(this.updateById(sysPublicParam)); + } - /** - * 删除参数 - * @param publicIds 参数ID列表 - * @return - */ - @Override - @CacheEvict(value = CacheConstants.PARAMS_DETAILS, allEntries = true) - public R removeParamByIds(Long[] publicIds) { - List idList = this.baseMapper.selectByIds(CollUtil.toList(publicIds)) - .stream() - .filter(p -> !p.getSystemFlag().equals(DictTypeEnum.SYSTEM.getType()))// 系统内置的跳过不能删除 - .map(SysPublicParam::getPublicId) + /** + * 删除参数 + * + * @param publicIds 参数ID列表 + * @return + */ + @Override + @CacheEvict(value = CacheConstants.PARAMS_DETAILS, allEntries = true) + public R removeParamByIds(Long[] publicIds) { + List idList = this.baseMapper.selectByIds(CollUtil.toList(publicIds)) + .stream() + .filter(p -> !p.getSystemFlag().equals(DictTypeEnum.SYSTEM.getType()))// 系统内置的跳过不能删除 + .map(SysPublicParam::getPublicId) .toList(); - return R.ok(this.removeBatchByIds(idList)); - } + return R.ok(this.removeBatchByIds(idList)); + } - /** - * 同步缓存 - * @return R - */ - @Override - @CacheEvict(value = CacheConstants.PARAMS_DETAILS, allEntries = true) - public R syncParamCache() { - return R.ok(); - } + /** + * 同步缓存 + * + * @return R + */ + @Override + @CacheEvict(value = CacheConstants.PARAMS_DETAILS, allEntries = true) + public R syncParamCache() { + return R.ok(); + } } diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysRoleMenuServiceImpl.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysRoleMenuServiceImpl.java index 6cecdcf30..f57916052 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysRoleMenuServiceImpl.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysRoleMenuServiceImpl.java @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysRoleServiceImpl.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysRoleServiceImpl.java index 0ea273cb3..3bb2b5542 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysRoleServiceImpl.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysRoleServiceImpl.java @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -24,6 +24,7 @@ import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ArrayUtil; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.pig4cloud.pigx.admin.api.constant.UpmsErrorCodes; import com.pig4cloud.pigx.admin.api.entity.SysRole; import com.pig4cloud.pigx.admin.api.entity.SysRoleMenu; import com.pig4cloud.pigx.admin.api.vo.RoleExcelVO; @@ -32,7 +33,6 @@ import com.pig4cloud.pigx.admin.mapper.SysRoleMapper; import com.pig4cloud.pigx.admin.service.SysRoleMenuService; import com.pig4cloud.pigx.admin.service.SysRoleService; import com.pig4cloud.pigx.common.core.constant.CacheConstants; -import com.pig4cloud.pigx.common.core.exception.ErrorCodes; import com.pig4cloud.pigx.common.core.util.MsgUtils; import com.pig4cloud.pigx.common.core.util.R; import com.pig4cloud.pigx.common.data.tenant.TenantContextHolder; @@ -59,120 +59,125 @@ import java.util.Set; @AllArgsConstructor public class SysRoleServiceImpl extends ServiceImpl implements SysRoleService { - private SysRoleMenuService roleMenuService; + private SysRoleMenuService roleMenuService; - /** - * 通过用户ID查询角色信息 - * @param userId 用户ID - * @return 角色信息列表 - */ - @Override - public List findRolesByUserId(Long userId) { - return baseMapper.listRolesByUserId(userId, TenantContextHolder.getTenantId()); - } + /** + * 通过用户ID查询角色信息 + * + * @param userId 用户ID + * @return 角色信息列表 + */ + @Override + public List findRolesByUserId(Long userId) { + return baseMapper.listRolesByUserId(userId, TenantContextHolder.getTenantId()); + } - /** - * 根据角色ID 查询角色列表,注意缓存删除 - * @param roleIdList 角色ID列表 - * @param key 缓存key - * @return - */ - @Override - @Cacheable(value = CacheConstants.ROLE_DETAILS, key = "#key", unless = "#result.isEmpty()") - public List findRolesByRoleIds(List roleIdList, String key) { - return baseMapper.selectByIds(roleIdList); - } + /** + * 根据角色ID 查询角色列表,注意缓存删除 + * + * @param roleIdList 角色ID列表 + * @param key 缓存key + * @return + */ + @Override + @Cacheable(value = CacheConstants.ROLE_DETAILS, key = "#key", unless = "#result.isEmpty()") + public List findRolesByRoleIds(List roleIdList, String key) { + return baseMapper.selectByIds(roleIdList); + } - /** - * 通过角色ID,删除角色,并清空角色菜单缓存 - * @param ids - * @return - */ - @Override - @Transactional(rollbackFor = Exception.class) - public Boolean removeRoleByIds(Long[] ids) { - roleMenuService - .remove(Wrappers.update().lambda().in(SysRoleMenu::getRoleId, CollUtil.toList(ids))); - return this.removeBatchByIds(CollUtil.toList(ids)); - } + /** + * 通过角色ID,删除角色,并清空角色菜单缓存 + * + * @param ids + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean removeRoleByIds(Long[] ids) { + roleMenuService + .remove(Wrappers.update().lambda().in(SysRoleMenu::getRoleId, CollUtil.toList(ids))); + return this.removeBatchByIds(CollUtil.toList(ids)); + } - /** - * 根据角色菜单列表 - * @param roleVo 角色&菜单列表 - * @return - */ - @Override - public Boolean updateRoleMenus(RoleMenuVO roleVo) { - return roleMenuService.saveRoleMenus(roleVo.getRoleId(), roleVo.getMenuIds()); - } + /** + * 根据角色菜单列表 + * + * @param roleVo 角色&菜单列表 + * @return + */ + @Override + public Boolean updateRoleMenus(RoleMenuVO roleVo) { + return roleMenuService.saveRoleMenus(roleVo.getRoleId(), roleVo.getMenuIds()); + } - /** - * 导入角色 - * @param excelVOList 角色列表 - * @param bindingResult 错误信息列表 - * @return ok fail - */ - @Override - public R importRole(List excelVOList, BindingResult bindingResult) { - // 通用校验获取失败的数据 - List errorMessageList = (List) bindingResult.getTarget(); + /** + * 导入角色 + * + * @param excelVOList 角色列表 + * @param bindingResult 错误信息列表 + * @return ok fail + */ + @Override + public R importRole(List excelVOList, BindingResult bindingResult) { + // 通用校验获取失败的数据 + List errorMessageList = (List) bindingResult.getTarget(); - // 个性化校验逻辑 - List roleList = this.list(); + // 个性化校验逻辑 + List roleList = this.list(); - // 执行数据插入操作 组装 RoleDto - for (RoleExcelVO excel : excelVOList) { - Set errorMsg = new HashSet<>(); - // 检验角色名称或者角色编码是否存在 - boolean existRole = roleList.stream() - .anyMatch(sysRole -> excel.getRoleName().equals(sysRole.getRoleName()) - || excel.getRoleCode().equals(sysRole.getRoleCode())); + // 执行数据插入操作 组装 RoleDto + for (RoleExcelVO excel : excelVOList) { + Set errorMsg = new HashSet<>(); + // 检验角色名称或者角色编码是否存在 + boolean existRole = roleList.stream() + .anyMatch(sysRole -> excel.getRoleName().equals(sysRole.getRoleName()) + || excel.getRoleCode().equals(sysRole.getRoleCode())); - if (existRole) { - errorMsg.add(MsgUtils.getMessage(ErrorCodes.SYS_ROLE_NAMEORCODE_EXISTING, excel.getRoleName(), - excel.getRoleCode())); - } + if (existRole) { + errorMsg.add(MsgUtils.getMessage(UpmsErrorCodes.SYS_ROLE_NAMEORCODE_EXISTING, excel.getRoleName(), + excel.getRoleCode())); + } - // 数据合法情况 - if (CollUtil.isEmpty(errorMsg)) { - insertExcelRole(excel); - } - else { - // 数据不合法情况 - errorMessageList.add(new ErrorMessage(excel.getLineNum(), errorMsg)); - } - } - if (CollUtil.isNotEmpty(errorMessageList)) { - return R.failed(errorMessageList); - } - return R.ok(); - } + // 数据合法情况 + if (CollUtil.isEmpty(errorMsg)) { + insertExcelRole(excel); + } else { + // 数据不合法情况 + errorMessageList.add(new ErrorMessage(excel.getLineNum(), errorMsg)); + } + } + if (CollUtil.isNotEmpty(errorMessageList)) { + return R.failed(errorMessageList); + } + return R.ok(); + } - /** - * 查询全部的角色 - * @return list - */ - @Override - public List listRole(SysRole sysRole, Long[] ids) { + /** + * 查询全部的角色 + * + * @return list + */ + @Override + public List listRole(SysRole sysRole, Long[] ids) { List roleList = this.list( Wrappers.lambdaQuery(sysRole).in(ArrayUtil.isNotEmpty(ids), SysRole::getRoleId, CollUtil.toList(ids))); - // 转换成execl 对象输出 - return roleList.stream().map(role -> { - RoleExcelVO roleExcelVO = new RoleExcelVO(); - BeanUtil.copyProperties(role, roleExcelVO); - return roleExcelVO; + // 转换成execl 对象输出 + return roleList.stream().map(role -> { + RoleExcelVO roleExcelVO = new RoleExcelVO(); + BeanUtil.copyProperties(role, roleExcelVO); + return roleExcelVO; }).toList(); - } + } - /** - * 插入excel Role - */ - private void insertExcelRole(RoleExcelVO excel) { - SysRole sysRole = new SysRole(); - sysRole.setRoleName(excel.getRoleName()); - sysRole.setRoleDesc(excel.getRoleDesc()); - sysRole.setRoleCode(excel.getRoleCode()); - this.save(sysRole); - } + /** + * 插入excel Role + */ + private void insertExcelRole(RoleExcelVO excel) { + SysRole sysRole = new SysRole(); + sysRole.setRoleName(excel.getRoleName()); + sysRole.setRoleDesc(excel.getRoleDesc()); + sysRole.setRoleCode(excel.getRoleCode()); + this.save(sysRole); + } } diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysRouteConfServiceImpl.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysRouteConfServiceImpl.java index ead05c659..4d01381ee 100755 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysRouteConfServiceImpl.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysRouteConfServiceImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysScheduleServiceImpl.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysScheduleServiceImpl.java index 8a7303006..34dfc7201 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysScheduleServiceImpl.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysScheduleServiceImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysSocialDetailsServiceImpl.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysSocialDetailsServiceImpl.java index d6b1b60fd..a528c4821 100755 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysSocialDetailsServiceImpl.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysSocialDetailsServiceImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysTenantServiceImpl.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysTenantServiceImpl.java index 4c64aaae1..82417fe84 100755 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysTenantServiceImpl.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysTenantServiceImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -67,475 +67,510 @@ import java.util.*; @AllArgsConstructor public class SysTenantServiceImpl extends ServiceImpl implements SysTenantService { - private final SysOauthClientDetailsService clientServices; + private final SysOauthClientDetailsService clientServices; - private final SysRoleMenuMapper roleMenuMapper; + private final SysRoleMenuMapper roleMenuMapper; - private final SysDictItemService dictItemService; + private final SysDictItemService dictItemService; - private final SysPublicParamService paramService; + private final SysPublicParamService paramService; - private final SysRoleService roleService; + private final SysRoleService roleService; - private final SysMenuService menuService; + private final SysMenuService menuService; - private final SysDeptService deptService; + private final SysDeptService deptService; - private final SysDictService dictService; + private final SysDictService dictService; - private final SysUserMapper sysUserMapper; + private final SysUserMapper sysUserMapper; - private final SysTenantUserMapper sysTenantUserMapper; + private final SysTenantUserMapper sysTenantUserMapper; - private final SysUserPostMapper sysUserPostMapper; + private final SysUserPostMapper sysUserPostMapper; - private final SysUserRoleMapper sysUserRoleMapper; + private final SysUserRoleMapper sysUserRoleMapper; - private final SysUserDeptMapper sysUserDeptMapper; + private final SysUserDeptMapper sysUserDeptMapper; - private final SysRoleMapper sysRoleMapper; + private final SysRoleMapper sysRoleMapper; - private final SysDeptMapper sysDeptMapper; + private final SysDeptMapper sysDeptMapper; - private final SysPostMapper sysPostMapper; + private final SysPostMapper sysPostMapper; - private final CacheManager cacheManager; + private final CacheManager cacheManager; - /** - * 获取正常状态租户 - *

- * 1. 状态正常 2. 开始时间小于等于当前时间 3. 结束时间大于等于当前时间 - * @return - */ - @Override - @Cacheable(value = CacheConstants.TENANT_DETAILS) - public List getNormalTenant() { - return baseMapper - .selectList(Wrappers.lambdaQuery().eq(SysTenant::getStatus, TenantStateEnum.NORMAL.getCode())); - } + /** + * 获取正常状态租户 + *

+ * 1. 状态正常 2. 开始时间小于等于当前时间 3. 结束时间大于等于当前时间 + * + * @return + */ + @Override + @Cacheable(value = CacheConstants.TENANT_DETAILS) + public List getNormalTenant() { + return baseMapper + .selectList(Wrappers.lambdaQuery().eq(SysTenant::getStatus, TenantStateEnum.NORMAL.getCode())); + } - /** - * 保存租户 - *

- * 1. 保存租户 2. 初始化权限相关表 - sys_user - sys_role - sys_menu - sys_user_role - - * sys_role_menu - sys_dict - sys_dict_item - sys_client_details - sys_public_params - * @param sysTenant 租户实体 - * @return - */ - @Override - @Transactional(rollbackFor = Exception.class) - @CacheEvict(value = CacheConstants.TENANT_DETAILS) - public Boolean saveTenant(SysTenant sysTenant) { - this.save(sysTenant); - // 查询系统默认租户配置参数 - TenantDefaultConfig tenantDefault = new TenantDefaultConfig(); + /** + * 保存租户 + *

+ * 1. 保存租户 2. 初始化权限相关表 - sys_user - sys_role - sys_menu - sys_user_role - + * sys_role_menu - sys_dict - sys_dict_item - sys_client_details - sys_public_params + * + * @param sysTenant 租户实体 + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + @CacheEvict(value = CacheConstants.TENANT_DETAILS) + public Boolean saveTenant(SysTenant sysTenant) { + this.save(sysTenant); + // 查询系统默认租户配置参数 + TenantDefaultConfig tenantDefault = new TenantDefaultConfig(); - List dictList = new ArrayList<>(32); - List dictIdList = new ArrayList<>(32); - List dictItemList = new ArrayList<>(64); - List menuList = new ArrayList<>(128); - List clientDetailsList = new ArrayList<>(16); - List publicParamList = new ArrayList<>(64); + List dictList = new ArrayList<>(32); + List dictIdList = new ArrayList<>(32); + List dictItemList = new ArrayList<>(64); + List menuList = new ArrayList<>(128); + List clientDetailsList = new ArrayList<>(16); + List publicParamList = new ArrayList<>(64); - TenantBroker.runAs(tenantDefault.getTenantDefaultId(), (id) -> { - // 查询系统内置字典 - dictList.addAll(dictService.list()); - // 查询系统内置字典项目 - dictIdList.addAll(dictList.stream().map(SysDict::getId).toList()); - dictItemList.addAll( - dictItemService.list(Wrappers.lambdaQuery().in(SysDictItem::getDictId, dictIdList))); - List newMenuList = menuService.list(Wrappers.lambdaQuery() - .in(SysMenu::getMenuId, StrUtil.split(sysTenant.getMenuId(), CharUtil.COMMA))); - // 查询当前租户菜单 - menuList.addAll(newMenuList); - // 查询客户端配置 - clientDetailsList.addAll(clientServices.list()); - // 查询系统参数配置 - publicParamList.addAll(paramService.list()); - }); + TenantBroker.runAs(tenantDefault.getTenantDefaultId(), (id) -> { + // 查询系统内置字典 + dictList.addAll(dictService.list()); + // 查询系统内置字典项目 + dictIdList.addAll(dictList.stream().map(SysDict::getId).toList()); + dictItemList.addAll( + dictItemService.list(Wrappers.lambdaQuery().in(SysDictItem::getDictId, dictIdList))); + List newMenuList = menuService.list(Wrappers.lambdaQuery() + .in(SysMenu::getMenuId, + StrUtil.split(sysTenant.getMenuId(), CharUtil.COMMA).stream().map(Long::parseLong).toList())); + // 查询当前租户菜单 + menuList.addAll(newMenuList); + // 查询客户端配置 + clientDetailsList.addAll(clientServices.list()); + // 查询系统参数配置 + publicParamList.addAll(paramService.list()); + }); - // 保证插入租户为新的租户 - TenantBroker.applyAs(sysTenant.getId(), (id -> { - // 插入部门 - SysDept dept = new SysDept(); - dept.setName(tenantDefault.getTenantDefaultDeptname()); - dept.setParentId(0L); - deptService.save(dept); + // 保证插入租户为新的租户 + TenantBroker.applyAs(sysTenant.getId(), (id -> { + // 插入部门 + SysDept dept = new SysDept(); + dept.setName(tenantDefault.getTenantDefaultDeptname()); + dept.setParentId(0L); + dept.setSortOrder(0); + deptService.save(dept); - // 构造普通用户角色 - SysRole roleDefault = new SysRole(); - roleDefault.setRoleCode(tenantDefault.getUserDefaultRolecode()); - roleDefault.setRoleName(tenantDefault.getUserDefaultRolename()); - roleDefault.setDsType(DataScopeTypeEnum.SELF_LEVEL.getType()); - roleService.save(roleDefault); + // 构造普通用户角色 + SysRole roleDefault = new SysRole(); + roleDefault.setRoleCode(tenantDefault.getUserDefaultRolecode()); + roleDefault.setRoleName(tenantDefault.getUserDefaultRolename()); + roleDefault.setDsType(DataScopeTypeEnum.SELF_LEVEL.getType()); + roleService.save(roleDefault); - // 构造新角色 管理员角色 - SysRole role = new SysRole(); - role.setRoleCode(tenantDefault.getTenantDefaultRolecode()); - role.setRoleName(tenantDefault.getTenantDefaultRolename()); - role.setDsType(DataScopeTypeEnum.ALL.getType()); - roleService.save(role); - // 插入新的菜单 - saveTenantMenu(menuList, CommonConstants.MENU_TREE_ROOT_ID, CommonConstants.MENU_TREE_ROOT_ID); + // 构造新角色 管理员角色 + SysRole role = new SysRole(); + role.setRoleCode(tenantDefault.getTenantDefaultRolecode()); + role.setRoleName(tenantDefault.getTenantDefaultRolename()); + role.setDsType(DataScopeTypeEnum.ALL.getType()); + roleService.save(role); + // 插入新的菜单 + saveTenantMenu(menuList, CommonConstants.MENU_TREE_ROOT_ID, CommonConstants.MENU_TREE_ROOT_ID); - // 重新查询出所有的菜单关联角色 - List list = menuService.list(); + // 重新查询出所有的菜单关联角色 + List list = menuService.list(); - // 查询全部菜单,构造角色菜单关系 - List roleMenuList = list.stream().map(menu -> { - SysRoleMenu roleMenu = new SysRoleMenu(); - roleMenu.setRoleId(role.getRoleId()); - roleMenu.setMenuId(menu.getMenuId()); - return roleMenu; - }).toList(); - roleMenuList.forEach(roleMenuMapper::insert); - // 插入系统字典 - dictService.saveBatch(dictList.stream().peek(d -> d.setId(null)).toList()); - // 处理字典项最新关联的字典ID - List itemList = dictList.stream() - .flatMap(dict -> dictItemList.stream() - .filter(item -> item.getDictType().equals(dict.getDictType())) - .peek(item -> { - item.setDictId(dict.getId()); - item.setId(null); - })) - .toList(); + // 查询全部菜单,构造角色菜单关系 + List roleMenuList = list.stream().map(menu -> { + SysRoleMenu roleMenu = new SysRoleMenu(); + roleMenu.setRoleId(role.getRoleId()); + roleMenu.setMenuId(menu.getMenuId()); + return roleMenu; + }).toList(); + roleMenuList.forEach(roleMenuMapper::insert); + // 插入系统字典 + dictService.saveBatch(dictList.stream().peek(d -> d.setId(null)).toList()); + // 处理字典项最新关联的字典ID + List itemList = dictList.stream() + .flatMap(dict -> dictItemList.stream() + .filter(item -> item.getDictType().equals(dict.getDictType())) + .peek(item -> { + item.setDictId(dict.getId()); + item.setId(null); + })) + .toList(); - // 插入客户端 - clientServices.saveBatch(clientDetailsList.stream().peek(d -> d.setId(null)).toList()); - // 插入系统配置 - paramService.saveBatch(publicParamList.stream().peek(d -> d.setPublicId(null)).toList()); - return dictItemService.saveBatch(itemList); - })); + // 插入客户端 + clientServices.saveBatch(clientDetailsList.stream().peek(d -> d.setId(null)).toList()); + // 插入系统配置 + paramService.saveBatch(publicParamList.stream().peek(d -> d.setPublicId(null)).toList()); + return dictItemService.saveBatch(itemList); + })); - SpringContextHolder.publishEvent(new ClientDetailsInitRunner.ClientDetailsInitEvent(sysTenant)); + SpringContextHolder.publishEvent(new ClientDetailsInitRunner.ClientDetailsInitEvent(sysTenant)); - return Boolean.TRUE; - } + return Boolean.TRUE; + } - /** - * 修改租户 - * @param tenantDTO 新旧套餐数据 - * @return true/false - */ - @Override - @Transactional(rollbackFor = Exception.class) - @CacheEvict(value = CacheConstants.TENANT_DETAILS, allEntries = true) - public Boolean updateTenant(SysTenant tenantDTO) { - SysTenant oldTenant = baseMapper.selectById(tenantDTO.getId()); - List newMenuIdList = StrUtil.split(tenantDTO.getMenuId(), CharUtil.COMMA); - List oldMenuIdList = StrUtil.split(oldTenant.getMenuId(), CharUtil.COMMA); + /** + * 修改租户 + * + * @param tenantDTO 新旧套餐数据 + * @return true/false + */ + @Override + @Transactional(rollbackFor = Exception.class) + @CacheEvict(value = CacheConstants.TENANT_DETAILS, allEntries = true) + public Boolean updateTenant(SysTenant tenantDTO) { + SysTenant oldTenant = baseMapper.selectById(tenantDTO.getId()); + List newMenuIdList = StrUtil.split(tenantDTO.getMenuId(), CharUtil.COMMA); + List oldMenuIdList = StrUtil.split(oldTenant.getMenuId(), CharUtil.COMMA); - // 更新租户信息 - updateById(tenantDTO); + // 更新租户信息 + updateById(tenantDTO); - // 如果没有修改租户套餐 - TenantDefaultConfig tenantDefault = new TenantDefaultConfig(); - List sysMenuList = TenantBroker.applyAs(tenantDefault.getTenantDefaultId(), id -> menuService.list()); - if (tenantDefault.getTenantDefaultId().equals(tenantDTO.getId())) { - return Boolean.TRUE; - } + // 如果没有修改租户套餐 + TenantDefaultConfig tenantDefault = new TenantDefaultConfig(); + List sysMenuList = TenantBroker.applyAs(tenantDefault.getTenantDefaultId(), id -> menuService.list()); + if (tenantDefault.getTenantDefaultId().equals(tenantDTO.getId())) { + return Boolean.TRUE; + } - // 比较新旧套餐是否一致 - if (CollUtil.isEqualList(newMenuIdList, oldMenuIdList)) { - return Boolean.TRUE; - } + // 比较新旧套餐是否一致 + if (CollUtil.isEqualList(newMenuIdList, oldMenuIdList)) { + return Boolean.TRUE; + } - // 0. 计算两个差集,差集表示变化的功能项 - Collection disjunctionList = CollUtil.disjunction(newMenuIdList, oldMenuIdList); - // 1. 如果旧套餐包含差集元素则删除 - CollUtil.intersection(oldMenuIdList, disjunctionList) - .forEach(menuId -> TenantBroker.runAs(tenantDTO.getId(), (tenantId -> { - // 查询租户菜单元信息 - SysMenu menu = CollUtil.findOneByField(sysMenuList, SysMenu.Fields.menuId, Long.parseLong(menuId)); + // 0. 计算两个差集,差集表示变化的功能项 + Collection disjunctionList = CollUtil.disjunction(newMenuIdList, oldMenuIdList); + // 1. 如果旧套餐包含差集元素则删除 + CollUtil.intersection(oldMenuIdList, disjunctionList) + .forEach(menuId -> TenantBroker.runAs(tenantDTO.getId(), (tenantId -> { + // 查询租户菜单元信息 + SysMenu menu = CollUtil.findOneByField(sysMenuList, SysMenu.Fields.menuId, Long.parseLong(menuId)); - // 根据path 或者 permisson 删除目标租户菜单 - menuService.remove(Wrappers.lambdaQuery() - .eq(StrUtil.isNotBlank(menu.getPath()), SysMenu::getPath, menu.getPath()) - .or() - .eq(StrUtil.isNotBlank(menu.getPermission()), SysMenu::getPermission, menu.getPermission())); - }))); + if (Objects.isNull(menu)) { + return; + } - // 2. 如果旧套餐不包含差集元素则新增 - List newTenantMenuIdList = CollUtil.subtract(disjunctionList, oldMenuIdList) - .stream() - .map(menuId -> TenantBroker.applyAs(tenantDTO.getId(), (tenantId -> { - // 查询租户菜单元信息 - SysMenu menu = CollUtil.findOneByField(sysMenuList, SysMenu.Fields.menuId, Long.parseLong(menuId)); + // 根据path 或者 permisson 删除目标租户菜单 + menuService.remove(Wrappers.lambdaQuery() + .eq(StrUtil.isNotBlank(menu.getPath()), SysMenu::getPath, menu.getPath()) + .or() + .eq(StrUtil.isNotBlank(menu.getPermission()), SysMenu::getPermission, menu.getPermission())); + }))); - // 新增租户菜单,但未维护上下级关系 - SysMenu newMenu = new SysMenu(); - BeanUtils.copyProperties(menu, newMenu, SysMenu.Fields.menuId); - menuService.save(newMenu); - return newMenu; - }))) - .toList(); + // 2. 如果旧套餐不包含差集元素则新增 + List newTenantMenuIdList = CollUtil.subtract(disjunctionList, oldMenuIdList) + .stream() + .map(menuId -> TenantBroker.applyAs(tenantDTO.getId(), (tenantId -> { + // 查询租户菜单元信息 + SysMenu menu = CollUtil.findOneByField(sysMenuList, SysMenu.Fields.menuId, Long.parseLong(menuId)); - // 3. 更新新增菜单上下级关系 - for (SysMenu tenantMenu : newTenantMenuIdList) { - // 查询租户菜单父元信息 - SysMenu parentMenu = CollUtil.findOneByField(sysMenuList, SysMenu.Fields.menuId, tenantMenu.getParentId()); - // 查询目标租户父菜单元信息 - TenantBroker.runAs(tenantDTO.getId(), tenantId -> { - // 如何菜单父节点是根节点则直接插入,不要查询父节点判断 - if (Objects.equals(tenantMenu.getParentId(), CommonConstants.MENU_TREE_ROOT_ID)) { - menuService.updateById(tenantMenu); - return; - } + // 新增租户菜单,但未维护上下级关系 + SysMenu newMenu = new SysMenu(); + BeanUtils.copyProperties(menu, newMenu, SysMenu.Fields.menuId); + menuService.save(newMenu); + return newMenu; + }))) + .toList(); - // 根据path 或者 permisson 查询目标父菜单 - SysMenu tenantParentMenu = menuService.getOne(Wrappers.lambdaQuery() - .eq(StrUtil.isNotBlank(parentMenu.getPath()), SysMenu::getPath, parentMenu.getPath()) - .or() - .eq(StrUtil.isNotBlank(parentMenu.getPermission()), SysMenu::getPermission, - parentMenu.getPermission()), - false); + // 3. 更新新增菜单上下级关系 + for (SysMenu tenantMenu : newTenantMenuIdList) { + // 查询租户菜单父元信息 + SysMenu parentMenu = CollUtil.findOneByField(sysMenuList, SysMenu.Fields.menuId, tenantMenu.getParentId()); + // 查询目标租户父菜单元信息 + TenantBroker.runAs(tenantDTO.getId(), tenantId -> { + // 如何菜单父节点是根节点则直接插入,不要查询父节点判断 + if (Objects.equals(tenantMenu.getParentId(), CommonConstants.MENU_TREE_ROOT_ID)) { + menuService.updateById(tenantMenu); + return; + } - tenantMenu.setParentId(tenantParentMenu.getMenuId()); - menuService.updateById(tenantMenu); - }); - } + // 根据path 或者 permisson 查询目标父菜单 + SysMenu tenantParentMenu = menuService.getOne(Wrappers.lambdaQuery() + .eq(StrUtil.isNotBlank(parentMenu.getPath()), SysMenu::getPath, parentMenu.getPath()) + .or() + .eq(StrUtil.isNotBlank(parentMenu.getPermission()), SysMenu::getPermission, + parentMenu.getPermission()), + false); - // 清空指定租户的菜单权限缓存 - Set keys = RedisUtils.keys(String.format("%s:%s::*", tenantDTO.getId(), CacheConstants.MENU_DETAILS)); - if (CollUtil.isNotEmpty(keys)) { - RedisUtils.delete(keys.toArray(new String[0])); - } - return Boolean.TRUE; - } + tenantMenu.setParentId(tenantParentMenu.getMenuId()); + menuService.updateById(tenantMenu); + }); + } - /** - * 获取用户所属租户列表 - * @return 用户所属租户列表 - */ - @Override - public List getUserTenant() { - MPJLambdaWrapper wrapper = new MPJLambdaWrapper().selectAll(SysTenant.class) - .leftJoin(SysTenantUser.class, SysTenantUser::getTenantId, SysTenant::getId) - .eq(SysTenantUser::getUserId, SecurityUtils.getUser().getId()) - .eq(SysTenant::getStatus, TenantStateEnum.NORMAL.getCode()); + // 清空指定租户的菜单权限缓存 + Set keys = RedisUtils.keys(String.format("%s:%s::*", tenantDTO.getId(), CacheConstants.MENU_DETAILS)); + if (CollUtil.isNotEmpty(keys)) { + RedisUtils.delete(keys.toArray(new String[0])); + } + return Boolean.TRUE; + } - return baseMapper.selectJoinList(wrapper) - .stream() - .filter(tenant -> tenant.getStartTime().isBefore(LocalDateTime.now())) - .filter(tenant -> tenant.getEndTime().isAfter(LocalDateTime.now())) - .toList(); - } + /** + * 获取用户所属租户列表 + * + * @return 用户所属租户列表 + */ + @Override + public List getUserTenant() { + MPJLambdaWrapper wrapper = new MPJLambdaWrapper().selectAll(SysTenant.class) + .leftJoin(SysTenantUser.class, SysTenantUser::getTenantId, SysTenant::getId) + .eq(SysTenantUser::getUserId, SecurityUtils.getUser().getId()) + .eq(SysTenant::getStatus, TenantStateEnum.NORMAL.getCode()); - /** - * 获取用户租户分页信息 - * @param page 分页参数 - * @param userDTO 用户信息 - * @return 用户租户分页结果 - */ - @Override - public Page getUserTenantPage(Page page, UserDTO userDTO) { - MPJLambdaWrapper wrapper = new MPJLambdaWrapper().selectAll(SysUser.class) - .innerJoin(SysTenantUser.class, SysTenantUser::getUserId, SysUser::getUserId) - .like(StrUtil.isNotBlank(userDTO.getUsername()), SysUser::getUsername, userDTO.getUsername()) - .like(StrUtil.isNotBlank(userDTO.getPhone()), SysUser::getPhone, userDTO.getPhone()) - .like(StrUtil.isNotBlank(userDTO.getEmail()), SysUser::getEmail, userDTO.getEmail()) - .eq(Objects.nonNull(userDTO.getTenantId()), SysTenantUser::getTenantId, userDTO.getTenantId()); - return TenantBroker.noneAs(() -> sysUserMapper.selectJoinPage(page, wrapper)); - } + return baseMapper.selectJoinList(wrapper) + .stream() + .filter(tenant -> tenant.getStartTime().isBefore(LocalDateTime.now())) + .filter(tenant -> tenant.getEndTime().isAfter(LocalDateTime.now())) + .toList(); + } - /** - * 移除租户用户 - * @param tenantUserDTO 租户用户信息 - * @return 是否移除成功 - */ - @Override - public Boolean removeTenantUser(SysTenantUserDTO tenantUserDTO) { - ArrayList userIdList = CollUtil.toList(tenantUserDTO.getUserIds()); + /** + * 获取用户租户分页信息 + * + * @param page 分页参数 + * @param userDTO 用户信息 + * @return 用户租户分页结果 + */ + @Override + public Page getUserTenantPage(Page page, UserDTO userDTO) { + MPJLambdaWrapper wrapper = new MPJLambdaWrapper().selectAll(SysUser.class) + .innerJoin(SysTenantUser.class, SysTenantUser::getUserId, SysUser::getUserId) + .like(StrUtil.isNotBlank(userDTO.getUsername()), SysUser::getUsername, userDTO.getUsername()) + .like(StrUtil.isNotBlank(userDTO.getPhone()), SysUser::getPhone, userDTO.getPhone()) + .like(StrUtil.isNotBlank(userDTO.getEmail()), SysUser::getEmail, userDTO.getEmail()) + .eq(Objects.nonNull(userDTO.getTenantId()), SysTenantUser::getTenantId, userDTO.getTenantId()); + return TenantBroker.noneAs(() -> sysUserMapper.selectJoinPage(page, wrapper)); + } - // 删除租户用户关系 - sysTenantUserMapper.delete(Wrappers.lambdaQuery() - .eq(SysTenantUser::getTenantId, tenantUserDTO.getTenantId()) - .in(SysTenantUser::getUserId, userIdList)); + /** + * 移除租户用户 + * + * @param tenantUserDTO 租户用户信息 + * @return 是否移除成功 + */ + @Override + public Boolean removeTenantUser(SysTenantUserDTO tenantUserDTO) { + ArrayList userIdList = CollUtil.toList(tenantUserDTO.getUserIds()); - TenantBroker.runAs(tenantUserDTO.getTenantId(), (tenantId -> { - // 删除用户岗位 - sysUserPostMapper.delete(Wrappers.lambdaQuery().in(SysUserPost::getUserId, userIdList)); - // 删除用户角色 - sysUserRoleMapper.delete(Wrappers.lambdaQuery().in(SysUserRole::getUserId, userIdList)); - // 删除用户部门 - sysUserDeptMapper.delete(Wrappers.lambdaQuery().in(SysUserDept::getUserId, userIdList)); - })); - return Boolean.TRUE; - } + // 删除租户用户关系 + sysTenantUserMapper.delete(Wrappers.lambdaQuery() + .eq(SysTenantUser::getTenantId, tenantUserDTO.getTenantId()) + .in(SysTenantUser::getUserId, userIdList)); - /** - * 根据用户信息查询租户用户列表 - * @param userDTO 用户信息传输对象 - * @return 租户用户列表 - */ - @Override - public List listTenantUser(UserDTO userDTO) { - return TenantBroker.noneAs(() -> sysUserMapper.selectList(Wrappers.lambdaQuery() - .ne(SysUser::getTenantId, userDTO.getTenantId()) - .like(StrUtil.isNotBlank(userDTO.getUsername()), SysUser::getUsername, userDTO.getUsername()))); - } + TenantBroker.runAs(tenantUserDTO.getTenantId(), (tenantId -> { + // 删除用户岗位 + sysUserPostMapper.delete(Wrappers.lambdaQuery().in(SysUserPost::getUserId, userIdList)); + // 删除用户角色 + sysUserRoleMapper.delete(Wrappers.lambdaQuery().in(SysUserRole::getUserId, userIdList)); + // 删除用户部门 + sysUserDeptMapper.delete(Wrappers.lambdaQuery().in(SysUserDept::getUserId, userIdList)); + })); + return Boolean.TRUE; + } - /** - * 保存租户用户信息 - * @param tenantUserDTO 租户用户信息DTO - * @return 保存是否成功 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public Boolean saveTenantUser(SysTenantUserDTO tenantUserDTO) { - TenantBroker.runAs(tenantUserDTO.getTenantId(), (tenantId -> { - for (Long userId : tenantUserDTO.getUserIds()) { - List sysTenantUsers = sysTenantUserMapper - .selectList(Wrappers.lambdaQuery() - .eq(SysTenantUser::getTenantId, tenantId) - .eq(SysTenantUser::getUserId, userId)); - if (CollUtil.isEmpty(sysTenantUsers)) { - // 插入租户用户关系 - SysTenantUser sysTenantUser = new SysTenantUser(); - sysTenantUser.setUserId(userId); - sysTenantUser.setTenantId(tenantId); - sysTenantUserMapper.insert(sysTenantUser); - } + /** + * 根据用户信息查询租户用户列表 + * + * @param userDTO 用户信息传输对象 + * @return 租户用户列表 + */ + @Override + public List listTenantUser(UserDTO userDTO) { + return TenantBroker.noneAs(() -> sysUserMapper.selectList(Wrappers.lambdaQuery() + .like(StrUtil.isNotBlank(userDTO.getUsername()), SysUser::getUsername, userDTO.getUsername()))); + } - List userRoleList = sysUserRoleMapper.selectList(Wrappers.lambdaQuery() - .eq(SysUserRole::getUserId, userId) - .eq(SysUserRole::getRoleId, tenantUserDTO.getRoleId())); - if (CollUtil.isEmpty(userRoleList)) { - // 插入用户角色关系 - SysUserRole sysUserRole = new SysUserRole(); - sysUserRole.setUserId(userId); - sysUserRole.setRoleId(tenantUserDTO.getRoleId()); - sysUserRoleMapper.insert(sysUserRole); - } + /** + * 保存租户用户信息 + * + * @param tenantUserDTO 租户用户信息DTO + * @return 保存是否成功 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean saveTenantUser(SysTenantUserDTO tenantUserDTO) { + TenantBroker.runAs(tenantUserDTO.getTenantId(), (tenantId -> { + for (Long userId : tenantUserDTO.getUserIds()) { + List sysTenantUsers = sysTenantUserMapper + .selectList(Wrappers.lambdaQuery() + .eq(SysTenantUser::getTenantId, tenantId) + .eq(SysTenantUser::getUserId, userId)); + if (CollUtil.isEmpty(sysTenantUsers)) { + // 插入租户用户关系 + SysTenantUser sysTenantUser = new SysTenantUser(); + sysTenantUser.setUserId(userId); + sysTenantUser.setTenantId(tenantId); + sysTenantUserMapper.insert(sysTenantUser); + } - List userDeptList = sysUserDeptMapper.selectList(Wrappers.lambdaQuery() - .eq(SysUserDept::getUserId, userId) - .eq(SysUserDept::getDeptId, tenantUserDTO.getDeptId())); + List userRoleList = sysUserRoleMapper.selectList(Wrappers.lambdaQuery() + .eq(SysUserRole::getUserId, userId) + .eq(SysUserRole::getRoleId, tenantUserDTO.getRoleId())); + if (CollUtil.isEmpty(userRoleList)) { + // 插入用户角色关系 + SysUserRole sysUserRole = new SysUserRole(); + sysUserRole.setUserId(userId); + sysUserRole.setRoleId(tenantUserDTO.getRoleId()); + sysUserRoleMapper.insert(sysUserRole); + } - if (CollUtil.isEmpty(userDeptList)) { - // 插入用户部门关系 - SysUserDept sysUserDept = new SysUserDept(); - sysUserDept.setUserId(userId); - sysUserDept.setDeptId(tenantUserDTO.getDeptId()); - sysUserDeptMapper.insert(sysUserDept); - } + List userDeptList = sysUserDeptMapper.selectList(Wrappers.lambdaQuery() + .eq(SysUserDept::getUserId, userId) + .eq(SysUserDept::getDeptId, tenantUserDTO.getDeptId())); - List userPostList = sysUserPostMapper.selectList(Wrappers.lambdaQuery() - .eq(SysUserPost::getUserId, userId) - .eq(SysUserPost::getPostId, tenantUserDTO.getPostId())); + if (CollUtil.isEmpty(userDeptList)) { + // 插入用户部门关系 + SysUserDept sysUserDept = new SysUserDept(); + sysUserDept.setUserId(userId); + sysUserDept.setDeptId(tenantUserDTO.getDeptId()); + sysUserDeptMapper.insert(sysUserDept); + } - if (CollUtil.isEmpty(userPostList) && Objects.nonNull(tenantUserDTO.getPostId())) { - // 插入用户岗位关系 - SysUserPost sysUserPost = new SysUserPost(); - sysUserPost.setUserId(userId); - sysUserPost.setPostId(tenantUserDTO.getPostId()); - sysUserPostMapper.insert(sysUserPost); - } - } - })); - return Boolean.TRUE; - } + List userPostList = sysUserPostMapper.selectList(Wrappers.lambdaQuery() + .eq(SysUserPost::getUserId, userId) + .eq(SysUserPost::getPostId, tenantUserDTO.getPostId())); - /** - * 获取租户角色列表 - * @param userDTO 用户信息 - * @return 租户角色列表 - */ - @Override - public Map listTenantOrg(UserDTO userDTO) { - return TenantBroker.applyAs(userDTO.getTenantId(), tenantId -> { - // 过滤有权限配置的菜单 - List sysRoles = sysRoleMapper.selectList(Wrappers.lambdaQuery()) - .stream() - .filter(role -> roleMenuMapper - .exists(Wrappers.lambdaQuery().eq(SysRoleMenu::getRoleId, role.getRoleId()))) - .toList(); - List sysDepts = sysDeptMapper.selectList(Wrappers.lambdaQuery()); - List sysPosts = sysPostMapper.selectList(Wrappers.lambdaQuery()); - return Map.of("sysRoles", sysRoles, "sysDepts", sysDepts, "sysPosts", sysPosts); - }); - } + if (CollUtil.isEmpty(userPostList) && Objects.nonNull(tenantUserDTO.getPostId())) { + // 插入用户岗位关系 + SysUserPost sysUserPost = new SysUserPost(); + sysUserPost.setUserId(userId); + sysUserPost.setPostId(tenantUserDTO.getPostId()); + sysUserPostMapper.insert(sysUserPost); + } + } + })); + return Boolean.TRUE; + } - /** - * 移除租户 - * @param ids 租户ID列表 - * @return 是否移除成功 - */ - @Override - @CacheEvict(value = CacheConstants.TENANT_DETAILS, allEntries = true) - public Boolean removeTenant(Long[] ids) { - baseMapper.deleteByIds(CollUtil.toList(ids)); - sysTenantUserMapper - .delete(Wrappers.lambdaQuery().in(SysTenantUser::getTenantId, CollUtil.toList(ids))); - return Boolean.TRUE; - } + /** + * 获取租户角色列表 + * + * @param userDTO 用户信息 + * @return 租户角色列表 + */ + @Override + public Map listTenantOrg(UserDTO userDTO) { + return TenantBroker.applyAs(userDTO.getTenantId(), tenantId -> { + // 过滤有权限配置的菜单 + List sysRoles = sysRoleMapper.selectList(Wrappers.lambdaQuery()) + .stream() + .filter(role -> roleMenuMapper + .exists(Wrappers.lambdaQuery().eq(SysRoleMenu::getRoleId, role.getRoleId()))) + .toList(); + List sysDepts = sysDeptMapper.selectList(Wrappers.lambdaQuery()); + List sysPosts = sysPostMapper.selectList(Wrappers.lambdaQuery()); + return Map.of("sysRoles", sysRoles, "sysDepts", sysDepts, "sysPosts", sysPosts); + }); + } - /** - * 更新用户租户信息 - * @param userDto 用户数据传输对象 - * @return 更新结果 - */ - @Override - @CacheEvict(value = CacheConstants.USER_DETAILS, key = "#userDto.username") - public R updateUserTenant(UserDTO userDto) { - return R.ok(TenantBroker.noneAs(() -> sysUserMapper.update(Wrappers.lambdaUpdate() - .set(SysUser::getTenantId, userDto.getTenantId()) - .eq(SysUser::getUserId, userDto.getUserId())))); - } + /** + * 移除租户 + * + * @param ids 租户ID列表 + * @return 是否移除成功 + */ + @Override + @CacheEvict(value = CacheConstants.TENANT_DETAILS, allEntries = true) + public Boolean removeTenant(Long[] ids) { + baseMapper.deleteByIds(CollUtil.toList(ids)); + sysTenantUserMapper + .delete(Wrappers.lambdaQuery().in(SysTenantUser::getTenantId, CollUtil.toList(ids))); + return Boolean.TRUE; + } - /** - * 保存新的租户菜单,维护成新的菜单 - * @param menuList 菜单列表 - * @param originParentId 原始上级 - * @param targetParentId 目标上级 - */ - private void saveTenantMenu(List menuList, Long originParentId, Long targetParentId) { - menuList.stream().filter(menu -> menu.getParentId().equals(originParentId)).forEach(menu -> { - // 保存菜单原始menuId, 方便查询子节点使用 - Long originMenuId = menu.getMenuId(); - menu.setMenuId(null); - menu.setParentId(targetParentId); - menuService.save(menu); - // 查找此节点的子节点,然后子节点的重新插入父节点更改为新的menuId - saveTenantMenu(menuList, originMenuId, menu.getMenuId()); - }); - } + /** + * 更新用户租户信息 + * + * @param userDto 用户数据传输对象 + * @return 更新结果 + */ + @Override + @CacheEvict(value = CacheConstants.USER_DETAILS, key = "#userDto.username") + public R updateUserTenant(UserDTO userDto) { + return R.ok(TenantBroker.noneAs(() -> sysUserMapper.update(Wrappers.lambdaUpdate() + .set(SysUser::getTenantId, userDto.getTenantId()) + .eq(SysUser::getUserId, userDto.getUserId())))); + } - /** - * 获取或更新当前用户的租户信息 - * @return 更新后的租户ID,如果无需更新则返回null - */ - @Override - public Long getOrUpdateTenant() { - PigxUser loginUser = SecurityUtils.getUser(); - boolean match = this.getNormalTenant() - .stream() - .filter(tenant -> tenant.getStartTime().isBefore(LocalDateTime.now())) - .filter(tenant -> tenant.getEndTime().isAfter(LocalDateTime.now())) - .anyMatch(tenant -> tenant.getId().equals(loginUser.getTenantId())); + /** + * 保存新的租户菜单,维护成新的菜单 + * + * @param menuList 菜单列表 + * @param originParentId 原始上级 + * @param targetParentId 目标上级 + */ + private void saveTenantMenu(List menuList, Long originParentId, Long targetParentId) { + menuList.stream().filter(menu -> menu.getParentId().equals(originParentId)).forEach(menu -> { + // 保存菜单原始menuId, 方便查询子节点使用 + Long originMenuId = menu.getMenuId(); + menu.setMenuId(null); + menu.setParentId(targetParentId); + menuService.save(menu); + // 查找此节点的子节点,然后子节点的重新插入父节点更改为新的menuId + saveTenantMenu(menuList, originMenuId, menu.getMenuId()); + }); + } - if (!match) { - SysTenantUser tenantUser = sysTenantUserMapper.selectOne(Wrappers.lambdaQuery() - .eq(SysTenantUser::getUserId, SecurityUtils.getUser().getId()) - .ne(SysTenantUser::getTenantId, loginUser.getTenantId()), false); - // 如果当前用户没有租户信息,则不进行任何操作 - if (Objects.isNull(tenantUser)) { - return null; - } + /** + * 获取或更新当前用户的租户信息 + *

+ * 如果当前租户已过期或无效,则自动切换到用户的其他有效租户 + * + * @return 当前有效的租户对象,如果无有效租户则返回null + */ + @Override + public SysTenant getOrUpdateTenant() { + PigxUser loginUser = SecurityUtils.getUser(); + // 通过代理对象调用以确保 @Cacheable 生效,避免自调用导致缓存失效 + List normalTenantList = SpringContextHolder.getBean(SysTenantService.class) + .getNormalTenant() + .stream() + .filter(tenant -> tenant.getStartTime().isBefore(LocalDateTime.now())) + .filter(tenant -> tenant.getEndTime().isAfter(LocalDateTime.now())) + .toList(); - // 切换至状态正常的租户 - UserDTO userDTO = new UserDTO(); - userDTO.setUserId(loginUser.getId()); - userDTO.setTenantId(tenantUser.getTenantId()); - userDTO.setUsername(loginUser.getUsername()); - updateUserTenant(userDTO); - cacheManager.getCache(CacheConstants.USER_DETAILS).evict(loginUser.getUsername()); - return tenantUser.getTenantId(); - } + boolean match = normalTenantList.stream() + .anyMatch(tenant -> tenant.getId().equals(loginUser.getTenantId())); - return null; - } + if (match) { + // 当前租户有效,返回当前租户对象 + return normalTenantList.stream() + .filter(tenant -> tenant.getId().equals(loginUser.getTenantId())) + .findFirst() + .orElse(null); + } + + SysTenantUser tenantUser = sysTenantUserMapper.selectOne(Wrappers.lambdaQuery() + .eq(SysTenantUser::getUserId, SecurityUtils.getUser().getId()) + .ne(SysTenantUser::getTenantId, loginUser.getTenantId()), false); + // 如果当前用户没有租户信息,则不进行任何操作 + if (Objects.isNull(tenantUser)) { + return null; + } + + // 切换至状态正常的租户 + UserDTO userDTO = new UserDTO(); + userDTO.setUserId(loginUser.getId()); + userDTO.setTenantId(tenantUser.getTenantId()); + userDTO.setUsername(loginUser.getUsername()); + updateUserTenant(userDTO); + cacheManager.getCache(CacheConstants.USER_DETAILS).evict(loginUser.getUsername()); + + // 返回切换后的租户对象 + return normalTenantList.stream() + .filter(tenant -> tenant.getId().equals(tenantUser.getTenantId())) + .findFirst() + .orElseGet(() -> baseMapper.selectById(tenantUser.getTenantId())); + + } } @@ -545,36 +580,36 @@ public class SysTenantServiceImpl extends ServiceImpl args = Arrays.stream(ReflectUtil.getFields(this.getClass())) - .map(Field::getName) - .map(StrUtil::toUnderlineCase) - .map(String::toUpperCase) - .toList(); - Map paramsMap = ParamResolver.getMap(args.toArray(new String[] {})); - for (Field field : ReflectUtil.getFields(this.getClass())) { - String key = StrUtil.toUnderlineCase(field.getName()).toUpperCase(); - if (paramsMap.containsKey(key)) { - field.set(this, paramsMap.get(key)); - } - } - } + @SneakyThrows + public TenantDefaultConfig() { + List args = Arrays.stream(ReflectUtil.getFields(this.getClass())) + .map(Field::getName) + .map(StrUtil::toUnderlineCase) + .map(String::toUpperCase) + .toList(); + Map paramsMap = ParamResolver.getMap(args.toArray(new String[]{})); + for (Field field : ReflectUtil.getFields(this.getClass())) { + String key = StrUtil.toUnderlineCase(field.getName()).toUpperCase(); + if (paramsMap.containsKey(key)) { + field.set(this, paramsMap.get(key)); + } + } + } } diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysUserRoleServiceImpl.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysUserRoleServiceImpl.java index 688bec355..3684700c4 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysUserRoleServiceImpl.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysUserRoleServiceImpl.java @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysUserServiceImpl.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysUserServiceImpl.java index 77c9f8637..95c26468a 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysUserServiceImpl.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysUserServiceImpl.java @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2018-2025, lengleng All rights reserved. + * Copyright (c) 2018-2026, lengleng All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -28,6 +28,7 @@ import com.baomidou.mybatisplus.core.toolkit.StringPool; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.pig4cloud.pigx.admin.api.constant.UpmsErrorCodes; import com.pig4cloud.pigx.admin.api.constant.UserStateEnum; import com.pig4cloud.pigx.admin.api.dto.RegisterUserDTO; import com.pig4cloud.pigx.admin.api.dto.UserDTO; @@ -41,7 +42,6 @@ import com.pig4cloud.pigx.common.audit.annotation.Audit; import com.pig4cloud.pigx.common.core.constant.CacheConstants; import com.pig4cloud.pigx.common.core.constant.CommonConstants; import com.pig4cloud.pigx.common.core.constant.enums.LoginTypeEnum; -import com.pig4cloud.pigx.common.core.exception.ErrorCodes; import com.pig4cloud.pigx.common.core.util.MsgUtils; import com.pig4cloud.pigx.common.core.util.R; import com.pig4cloud.pigx.common.data.cache.RedisUtils; @@ -76,640 +76,747 @@ import java.util.stream.Collectors; @AllArgsConstructor public class SysUserServiceImpl extends ServiceImpl implements SysUserService { - private static final PasswordEncoder ENCODER = new BCryptPasswordEncoder(); - - private final SysMenuService sysMenuService; - - private final SysRoleService sysRoleService; - - private final SysPostService sysPostService; - - private final SysDeptService sysDeptService; - - private final SysTenantService sysTenantService; - - private final SysUserRoleMapper sysUserRoleMapper; - - private final SysUserPostMapper sysUserPostMapper; - - private final SysUserDeptMapper sysUserDeptMapper; - - private final SysTenantUserMapper sysTenantUserMapper; - - private final CacheManager cacheManager; - - private final SysDeptMapper sysDeptMapper; - - /** - * 保存用户信息 - * @param userDto DTO 对象 - * @return success/fail - */ - @Override - @Transactional(rollbackFor = Exception.class) - public Boolean saveUser(UserDTO userDto) { - SysUser sysUser = new SysUser(); - BeanUtils.copyProperties(userDto, sysUser); - sysUser.setLockFlag( - StrUtil.isBlank(userDto.getLockFlag()) ? UserStateEnum.NORMAL.getCode() : userDto.getLockFlag()); - sysUser.setCreateBy(userDto.getUsername()); - sysUser.setUpdateBy(userDto.getUsername()); - sysUser.setPassword(ENCODER.encode(userDto.getPassword())); - sysUser.setPasswordModifyTime(LocalDateTime.now()); - baseMapper.insert(sysUser); - // 保存用户岗位信息 - Optional.ofNullable(userDto.getPost()).ifPresent(posts -> { - posts.stream().map(postId -> { - SysUserPost userPost = new SysUserPost(); - userPost.setUserId(sysUser.getUserId()); - userPost.setPostId(postId); - return userPost; - }).forEach(sysUserPostMapper::insert); - }); - - // 如果角色为空,赋默认角色 - if (CollUtil.isEmpty(userDto.getRole())) { - // 获取默认角色编码 - String defaultRole = ParamResolver.getStr("USER_DEFAULT_ROLE"); - // 默认角色 - SysRole sysRole = sysRoleService - .getOne(Wrappers.lambdaQuery().eq(SysRole::getRoleCode, defaultRole)); - userDto.setRole(Collections.singletonList(sysRole.getRoleId())); - } - - // 插入用户角色关系表 - userDto.getRole().stream().map(roleId -> { - SysUserRole userRole = new SysUserRole(); - userRole.setUserId(sysUser.getUserId()); - userRole.setRoleId(roleId); - return userRole; - }).forEach(sysUserRoleMapper::insert); - - // 插入用户部门信息 - if (Objects.nonNull(userDto.getDeptId())) { - SysUserDept sysUserDept = new SysUserDept(); - sysUserDept.setUserId(sysUser.getUserId()); - sysUserDept.setDeptId(userDto.getDeptId()); - sysUserDeptMapper.insert(sysUserDept); - } - - // 插入用户租户关系表 - SysTenantUser sysTenantUser = new SysTenantUser(); - sysTenantUser.setUserId(sysUser.getUserId()); - sysTenantUser.setTenantId(Objects.nonNull(SecurityUtils.getUser()) ? SecurityUtils.getUser().getTenantId() - : userDto.getTenantId()); - sysTenantUserMapper.insert(sysTenantUser); - return Boolean.TRUE; - } - - /** - * 根据用户信息查询用户全部信息,包括角色和权限 - * @param userDTO 用户信息DTO - * @return 包含用户角色和权限的用户信息对象 - */ - @Override - public R getUserInfo(UserDTO userDTO) { - UserVO dbUser = baseMapper.getUserVo(userDTO); - - if (dbUser == null) { - return R.failed(MsgUtils.getMessage(ErrorCodes.SYS_USER_USERINFO_EMPTY, userDTO.getUsername())); - } - - // 设置角色列表 (ID) - UserInfo userInfo = new UserInfo(); - BeanUtils.copyProperties(dbUser, userInfo); - // 设置权限列表(menu.permission) - List permissions = dbUser.getRoleList() - .stream() - .map(SysRole::getRoleId) - .flatMap(roleId -> sysMenuService.findMenuByRoleId(roleId).stream()) - .map(SysMenu::getPermission) - .filter(StrUtil::isNotEmpty) - .toList(); - userInfo.setPermissions(permissions); - - // 如果是登录成功以后查询租户信息并进行校验 - if (Objects.nonNull(SecurityUtils.getUser())) { - Long updateTenantId = sysTenantService.getOrUpdateTenant(); - if (Objects.nonNull(updateTenantId)) { - userInfo.setTenantId(updateTenantId); - } - } - - return R.ok(userInfo); - } - - /** - * 分页查询用户信息(含有角色信息) - * @param page 分页对象 - * @param userDTO 参数列表 - * @return - */ - @Override - public IPage getUsersWithRolePage(Page page, UserDTO userDTO) { - userDTO.setTenantId(SecurityUtils.getUser().getTenantId()); - return baseMapper.getUserVosPage(page, userDTO, DataScope.of()); - } - - /** - * 通过ID查询用户信息 - * @param id 用户ID - * @return 用户信息 - */ - @Override - public UserVO selectUserVoById(Long id) { - return baseMapper.getUserVoById(id); - } - - /** - * 删除用户 - * @param ids 用户ID 列表 - * @return Boolean - */ - @Override - @Transactional(rollbackFor = Exception.class) - public Boolean deleteUserByIds(Long[] ids) { - // 删除 spring cache - List userList = baseMapper.selectByIds(CollUtil.toList(ids)); - Cache cache = cacheManager.getCache(CacheConstants.USER_DETAILS); - for (SysUser sysUser : userList) { - cache.evict(sysUser.getUsername()); - } - - // 删除用户角色 - sysUserRoleMapper.delete(Wrappers.lambdaQuery().in(SysUserRole::getUserId, CollUtil.toList(ids))); - sysUserDeptMapper.delete(Wrappers.lambdaQuery().in(SysUserDept::getUserId, CollUtil.toList(ids))); - sysUserPostMapper.delete(Wrappers.lambdaQuery().in(SysUserPost::getUserId, CollUtil.toList(ids))); - sysTenantUserMapper.delete(Wrappers.lambdaQuery() - .in(SysTenantUser::getUserId, CollUtil.toList(ids)) - .eq(SysTenantUser::getTenantId, SecurityUtils.getUser().getTenantId())); - this.removeBatchByIds(CollUtil.toList(ids)); - return Boolean.TRUE; - } - - @Override - @CacheEvict(value = CacheConstants.USER_DETAILS, key = "#userDto.username") - public R updateUserInfo(UserDTO userDto) { - Long userId = SecurityUtils.getUser().getId(); - SysUser sysUser = new SysUser(); - sysUser.setPhone(userDto.getPhone()); - sysUser.setUserId(userId); - sysUser.setAvatar(userDto.getAvatar()); - sysUser.setNickname(userDto.getNickname()); - sysUser.setName(userDto.getName()); - sysUser.setEmail(userDto.getEmail()); - return R.ok(this.updateById(sysUser)); - } - - @Override - @Transactional(rollbackFor = Exception.class) - @Audit(name = "用户更新", spel = "@sysUserMapper.selectById(#userDto.userId)") - @CacheEvict(value = CacheConstants.USER_DETAILS, key = "#userDto.username") - public Boolean updateUser(UserDTO userDto) { - // 更新用户表信息 - SysUser sysUser = new SysUser(); - BeanUtils.copyProperties(userDto, sysUser); - sysUser.setUpdateTime(LocalDateTime.now()); - - if (StrUtil.isNotBlank(userDto.getPassword())) { - sysUser.setPassword(ENCODER.encode(userDto.getPassword())); - } - - this.updateById(sysUser); - - // 更新用户角色表 - if (userDto.getRole() != null) { - sysUserRoleMapper - .delete(Wrappers.lambdaQuery().eq(SysUserRole::getUserId, userDto.getUserId())); - userDto.getRole().stream().map(roleId -> { - SysUserRole userRole = new SysUserRole(); - userRole.setUserId(sysUser.getUserId()); - userRole.setRoleId(roleId); - return userRole; - }).forEach(SysUserRole::insert); - } - - // 更新用户岗位表 - if (userDto.getPost() != null) { - sysUserPostMapper - .delete(Wrappers.lambdaQuery().eq(SysUserPost::getUserId, userDto.getUserId())); - userDto.getPost().stream().map(postId -> { - SysUserPost userPost = new SysUserPost(); - userPost.setUserId(sysUser.getUserId()); - userPost.setPostId(postId); - return userPost; - }).forEach(SysUserPost::insert); - } - - // 更新用户部门表 - if (Objects.nonNull(userDto.getDeptId())) { - sysUserDeptMapper - .delete(Wrappers.lambdaQuery().eq(SysUserDept::getUserId, userDto.getUserId())); - SysUserDept sysUserDept = new SysUserDept(); - sysUserDept.setUserId(sysUser.getUserId()); - sysUserDept.setDeptId(userDto.getDeptId()); - sysUserDept.insert(); - } - - return Boolean.TRUE; - } - - /** - * 查询上级部门的用户信息 - * @param username 用户名 - * @return R - */ - @Override - public List listAncestorUsers(String username) { - SysUser sysUser = this.getOne(Wrappers.query().lambda().eq(SysUser::getUsername, username)); - - // 查询所属部门 - List sysDeptList = sysDeptMapper.listDeptsByUserId(sysUser.getUserId(), sysUser.getTenantId()); - if (CollUtil.isEmpty(sysDeptList)) { - return null; - } - - // 查询用户部门ID - List parentDeptList = sysDeptList.stream().map(SysDept::getParentId).toList(); - List userIdList = sysUserDeptMapper - .selectList(Wrappers.lambdaQuery().in(SysUserDept::getDeptId, parentDeptList)) - .stream() - .map(SysUserDept::getUserId) - .toList(); - return this.list(Wrappers.lambdaQuery().in(SysUser::getUserId, userIdList)); - } - - /** - * 查询全部的用户 - * @param userDTO 查询条件 - * @param ids ids 用户列表 - * @return list - */ - @Override - public List listUser(UserDTO userDTO, Long[] ids) { - // 根据数据权限查询全部的用户信息 - userDTO.setTenantId(SecurityUtils.getUser().getTenantId()); - List voList = baseMapper.getUserVoListByScope(userDTO, ids, DataScope.of()); - return voList.stream().map(userVO -> { - UserExcelVO excelVO = new UserExcelVO(); - BeanUtils.copyProperties(userVO, excelVO); - // 转换角色名称 - String roleNameList = userVO.getRoleList() - .stream() - .map(SysRole::getRoleName) - .collect(Collectors.joining(StrUtil.COMMA)); - excelVO.setRoleNameList(roleNameList); - // 转化岗位名称 - String postNameList = userVO.getPostList() - .stream() - .map(SysPost::getPostName) - .collect(Collectors.joining(StrUtil.COMMA)); - excelVO.setPostNameList(postNameList); - // 转化部门名称 - String deptNameList = userVO.getDeptList() - .stream() - .map(SysDept::getName) - .collect(Collectors.joining(StrUtil.COMMA)); - excelVO.setDeptNameList(deptNameList); - return excelVO; - }).toList(); - } - - /** - * excel 导入用户, 插入正确的 错误的提示行号 - * @param excelVOList excel 列表数据 - * @param bindingResult 错误数据 - * @return ok fail - */ - @Override - public R importUser(List excelVOList, BindingResult bindingResult) { - // 通用校验获取失败的数据 - List errorMessageList = (List) bindingResult.getTarget(); - List deptList = sysDeptService.list(); - List roleList = sysRoleService.list(); - List postList = sysPostService.list(); - - // 执行数据插入操作 组装 UserDto - for (UserExcelVO excel : excelVOList) { - // 个性化校验逻辑 - List userList = TenantBroker.noneAs(this::list); - - Set errorMsg = new HashSet<>(); - // 校验用户名是否存在 - boolean exsitUserName = userList.stream() - .anyMatch(sysUser -> excel.getUsername().equals(sysUser.getUsername())); - - if (exsitUserName) { - errorMsg.add(MsgUtils.getMessage(ErrorCodes.SYS_USER_USERNAME_EXISTING, excel.getUsername())); - } - - // 校验手机号是否存在 - boolean exsitPhone = userList.stream().anyMatch(sysUser -> excel.getPhone().equals(sysUser.getPhone())); - if (exsitPhone) { - errorMsg.add(MsgUtils.getMessage(ErrorCodes.SYS_USER_PHONE_EXISTING, excel.getPhone())); - } - - // 判断输入的部门名称列表是否合法 - Optional deptOptional = deptList.stream() - .filter(dept -> excel.getDeptNameList().equals(dept.getName())) - .findFirst(); - if (deptOptional.isEmpty()) { - errorMsg.add(MsgUtils.getMessage(ErrorCodes.SYS_DEPT_DEPTNAME_INEXISTENCE, excel.getDeptNameList())); - } - - // 判断输入的角色名称列表是否合法 - List roleNameList = StrUtil.split(excel.getRoleNameList(), StrUtil.COMMA); - List roleCollList = roleList.stream() - .filter(role -> roleNameList.stream().anyMatch(name -> role.getRoleName().equals(name))) - .toList(); - - if (roleCollList.size() != roleNameList.size()) { - errorMsg.add(MsgUtils.getMessage(ErrorCodes.SYS_ROLE_ROLENAME_INEXISTENCE, excel.getRoleNameList())); - } - - // 判断输入的部门名称列表是否合法 - List postNameList = StrUtil.split(excel.getPostNameList(), StrUtil.COMMA); - List postCollList = postList.stream() - .filter(post -> postNameList.stream().anyMatch(name -> post.getPostName().equals(name))) - .toList(); - - if (postCollList.size() != postNameList.size()) { - errorMsg.add(MsgUtils.getMessage(ErrorCodes.SYS_POST_POSTNAME_INEXISTENCE, excel.getPostNameList())); - } - - // 数据合法情况 - if (CollUtil.isEmpty(errorMsg)) { - insertExcelUser(excel, deptOptional, roleCollList, postCollList); - } - else { - // 数据不合法情况 - errorMessageList.add(new ErrorMessage(excel.getLineNum(), errorMsg)); - } - - } - - if (CollUtil.isNotEmpty(errorMessageList)) { - return R.failed(errorMessageList); - } - return R.ok(null, MsgUtils.getMessage(ErrorCodes.SYS_USER_IMPORT_SUCCEED)); - } - - /** - * 插入excel User - */ - private void insertExcelUser(UserExcelVO excel, Optional deptOptional, List roleCollList, - List postCollList) { - UserDTO userDTO = new UserDTO(); - userDTO.setUsername(excel.getUsername()); - userDTO.setPhone(excel.getPhone()); - userDTO.setNickname(excel.getNickname()); - userDTO.setName(excel.getName()); - userDTO.setEmail(excel.getEmail()); - userDTO.setLockFlag(excel.getLockFlag()); - // 批量导入初始密码为手机号 - userDTO.setPasswordModifyTime(LocalDateTime.now()); - userDTO.setPassword(userDTO.getPhone()); - // 根据部门名称查询部门ID - userDTO.setDeptId(deptOptional.get().getDeptId()); - // 插入岗位名称 - List postIdList = postCollList.stream().map(SysPost::getPostId).toList(); - userDTO.setPost(postIdList); - // 根据角色名称查询角色ID - List roleIdList = roleCollList.stream().map(SysRole::getRoleId).toList(); - userDTO.setRole(roleIdList); - // 插入用户 - this.saveUser(userDTO); - } - - /** - * 注册用户 赋予用户默认角色 - * @param userDto 用户信息 - * @return success/false - */ - @Override - @Transactional(rollbackFor = Exception.class) - public R registerUser(RegisterUserDTO userDto) { - // 判断用户名是否存在 - boolean usernameExists = TenantBroker - .noneAs(() -> this.exists(Wrappers.lambdaQuery().eq(SysUser::getUsername, userDto.getUsername()))); - if (usernameExists) { - String message = MsgUtils.getMessage(ErrorCodes.SYS_USER_USERNAME_EXISTING, userDto.getUsername()); - return R.failed(message); - } - - // 判断手机号是否存在 - boolean phoneExists = TenantBroker - .noneAs(() -> this.exists(Wrappers.lambdaQuery().eq(SysUser::getPhone, userDto.getPhone()))); - if (phoneExists) { - String message = MsgUtils.getMessage(ErrorCodes.SYS_USER_PHONE_EXISTING, userDto.getPhone()); - return R.failed(message); - } - - // 单独的用户避免越权 - UserDTO user = new UserDTO(); - BeanUtils.copyProperties(userDto, user); - return R.ok(saveUser(user)); - } - - /** - * 锁定用户 - * @param username 用户名 - * @return 操作结果,包含是否成功 - */ - @Override - @CacheEvict(value = CacheConstants.USER_DETAILS, key = "#username") - public R lockUser(String username) { - SysUser sysUser = baseMapper.selectOne(Wrappers.lambdaQuery().eq(SysUser::getUsername, username)); - - if (Objects.nonNull(sysUser)) { - sysUser.setLockFlag(UserStateEnum.LOCK.getCode()); - baseMapper.updateById(sysUser); - } - return R.ok(); - } - - /** - * 修改用户密码 - * @param userDto 用户数据传输对象,包含原密码和新密码 - * @return 操作结果 - * @CacheEvict 清除用户详情缓存 - */ - @Override - @CacheEvict(value = CacheConstants.USER_DETAILS, key = "#userDto.username") - public R changePassword(UserDTO userDto) { - SysUser user = baseMapper.selectById(SecurityUtils.getUser().getId()); - if (StrUtil.isEmpty(userDto.getPassword())) { - return R.failed("原密码不能为空"); - } - - if (!ENCODER.matches(userDto.getPassword(), user.getPassword())) { - log.info("原密码错误,修改个人信息失败:{}", userDto.getUsername()); - return R.failed(MsgUtils.getMessage(ErrorCodes.SYS_USER_UPDATE_PASSWORDERROR)); - } - - if (StrUtil.isEmpty(userDto.getNewpassword1())) { - return R.failed("新密码不能为空"); - } - String password = ENCODER.encode(userDto.getNewpassword1()); - - this.update(Wrappers.lambdaUpdate() - .set(SysUser::getPassword, password) - .set(SysUser::getPasswordModifyTime, LocalDateTime.now()) - .eq(SysUser::getUserId, user.getUserId())); - return R.ok(); - } - - /** - * 解绑用户第三方登录账号 - * @param type 登录类型,参见LoginTypeEnum枚举 - * @return 操作结果,成功返回R.ok(),失败返回R.failed() - */ - @Override - public R unbinding(String type) { - PigxUser user = SecurityUtils.getUser(); - LambdaUpdateWrapper wrapper = null; - - // 微信开放平台 (普通用户扫码登录) - if (type.equals(LoginTypeEnum.WECHAT.getType())) { - wrapper = Wrappers.lambdaUpdate() - .set(SysUser::getWxOpenid, null) - .eq(SysUser::getUserId, user.getId()); - // 码云登录 (方便申请) - } - else if (type.equals(LoginTypeEnum.GITEE.getType())) { - wrapper = Wrappers.lambdaUpdate() - .set(SysUser::getGiteeLogin, null) - .eq(SysUser::getUserId, user.getId()); - // 企业微信登录 - } - else if (type.equals(LoginTypeEnum.WEIXIN_CP.getType())) { - wrapper = Wrappers.lambdaUpdate() - .set(SysUser::getWxCpUserid, null) - .eq(SysUser::getUserId, user.getId()); - // 钉钉登录 - } - else if (type.equals(LoginTypeEnum.DINGTALK.getType())) { - wrapper = Wrappers.lambdaUpdate() - .set(SysUser::getWxDingUserid, null) - .eq(SysUser::getUserId, user.getId()); - } - - if (Objects.isNull(wrapper)) { - return R.failed("解绑账号类型不存在"); - } - this.update(wrapper); - return R.ok(); - } - - /** - * 检查用户密码是否正确 - * @param username 用户名 - * @param password 待验证的密码 - * @return 验证结果,成功返回R.ok(),失败返回R.failed() - */ - @Override - public R checkPassword(String username, String password) { - SysUser condition = new SysUser(); - condition.setUsername(username); - SysUser sysUser = this.getOne(new QueryWrapper<>(condition)); - - if (!ENCODER.matches(password, sysUser.getPassword())) { - log.info("原密码错误"); - return R.failed("密码输入错误"); - } - else { - return R.ok(); - } - } - - /** - * 重置用户密码 - * @param userDto 用户信息DTO,包含用户名、原密码和新密码等信息 - * @return 返回操作结果,成功返回true,失败返回错误信息 - */ - @Override - @CacheEvict(value = CacheConstants.USER_DETAILS, key = "#userDto.username") - public R resetUserPassword(RegisterUserDTO userDto) { - // 校验密码 - R checkedPassword = checkPassword(userDto.getUsername(), userDto.getPassword()); - if (!checkedPassword.isOk()) { - return checkedPassword; - } - - // 新密码校验 - if (StrUtil.equals(userDto.getPassword(), userDto.getNewpassword1())) { - return R.failed("新旧密码不能相同"); - } - - // 重置密码 - String password = ENCODER.encode(userDto.getNewpassword1()); - this.update(Wrappers.lambdaUpdate() - .set(SysUser::getPassword, password) - .set(SysUser::getPasswordModifyTime, LocalDateTime.now()) - .set(SysUser::getPasswordExpireFlag, CommonConstants.STATUS_NORMAL) - .eq(SysUser::getUsername, userDto.getUsername())); - return R.ok(); - } - - /** - * 忘记用户密码 - * @param userDto 用户信息DTO - * @param code 验证码 - * @return 操作结果,成功返回true - */ - @Override - public R forgetUserPassword(RegisterUserDTO userDto, String code) { - if (StrUtil.isBlank(userDto.getPhone())) { - return R.failed("非法参数"); - } - - String codeObj = RedisUtils - .get(CacheConstants.DEFAULT_CODE_KEY + LoginTypeEnum.SMS.getType() + StringPool.AT + userDto.getPhone()); - if (!StrUtil.equals(codeObj, code)) { - return R.failed("验证码错误"); - } - - TenantBroker.noneAs(() -> { - String username = lambdaQuery().select(SysUser::getUsername) - .eq(SysUser::getPhone, userDto.getPhone()) - .one() - .getUsername(); - - // 重置密码 - String password = ENCODER.encode(userDto.getNewpassword1()); - this.update(Wrappers.lambdaUpdate() - .set(SysUser::getPassword, password) - .set(SysUser::getPasswordModifyTime, LocalDateTime.now()) - .set(SysUser::getPasswordExpireFlag, CommonConstants.STATUS_NORMAL) - .eq(SysUser::getPhone, userDto.getPhone())); - cacheManager.getCache(CacheConstants.USER_DETAILS).evict(username); - return username; - }); - - return R.ok(); - } - - @Override - public List listUserIdByRoleIds(List roleIdList) { - return sysUserRoleMapper.selectList(Wrappers.lambdaQuery().in(SysUserRole::getRoleId, roleIdList)) - .stream() - .map(SysUserRole::getUserId) - .toList(); - } - - /** - * 根据部门ID列表获取用户ID列表接口 - * @param deptIdList 部门ID列表 - * @return List 返回结果对象,包含根据部门ID列表获取到的用户ID列表信息 - */ - @Override - public List listUserIdByDeptIds(List deptIdList) { - List userList = sysUserDeptMapper - .selectList(Wrappers.lambdaQuery().in(SysUserDept::getDeptId, deptIdList)) - .stream() - .map(SysUserDept::getUserId) - .toList(); - return baseMapper.selectList(Wrappers.lambdaQuery().in(SysUser::getUserId, userList)); - } + private static final PasswordEncoder ENCODER = new BCryptPasswordEncoder(); + + private final SysMenuService sysMenuService; + + private final SysRoleService sysRoleService; + + private final SysPostService sysPostService; + + private final SysDeptService sysDeptService; + + private final SysTenantService sysTenantService; + + private final SysUserRoleMapper sysUserRoleMapper; + + private final SysUserPostMapper sysUserPostMapper; + + private final SysUserDeptMapper sysUserDeptMapper; + + private final SysTenantUserMapper sysTenantUserMapper; + + private final CacheManager cacheManager; + + private final SysDeptMapper sysDeptMapper; + + /** + * 保存用户信息 + * + * @param userDto DTO 对象 + * @return success/fail + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean saveUser(UserDTO userDto) { + SysUser sysUser = new SysUser(); + BeanUtils.copyProperties(userDto, sysUser); + sysUser.setLockFlag( + StrUtil.isBlank(userDto.getLockFlag()) ? UserStateEnum.NORMAL.getCode() : userDto.getLockFlag()); + sysUser.setCreateBy(userDto.getUsername()); + sysUser.setUpdateBy(userDto.getUsername()); + sysUser.setPassword(ENCODER.encode(userDto.getPassword())); + sysUser.setPasswordModifyTime(LocalDateTime.now()); + baseMapper.insert(sysUser); + // 保存用户岗位信息 + Optional.ofNullable(userDto.getPost()).ifPresent(posts -> { + posts.stream().map(postId -> { + SysUserPost userPost = new SysUserPost(); + userPost.setUserId(sysUser.getUserId()); + userPost.setPostId(postId); + return userPost; + }).forEach(sysUserPostMapper::insert); + }); + + // 如果角色为空,赋默认角色 + if (CollUtil.isEmpty(userDto.getRole())) { + // 获取默认角色编码 + String defaultRole = ParamResolver.getStr("USER_DEFAULT_ROLE"); + // 默认角色 + SysRole sysRole = sysRoleService + .getOne(Wrappers.lambdaQuery().eq(SysRole::getRoleCode, defaultRole)); + userDto.setRole(Collections.singletonList(sysRole.getRoleId())); + } + + // 插入用户角色关系表 + userDto.getRole().stream().map(roleId -> { + SysUserRole userRole = new SysUserRole(); + userRole.setUserId(sysUser.getUserId()); + userRole.setRoleId(roleId); + return userRole; + }).forEach(sysUserRoleMapper::insert); + + // 插入用户部门信息 + List deptIdList = CollUtil.isNotEmpty(userDto.getDeptIds()) ? userDto.getDeptIds() + : (Objects.nonNull(userDto.getDeptId()) ? Collections.singletonList(userDto.getDeptId()) : null); + + if (CollUtil.isNotEmpty(deptIdList)) { + // 设置第一个部门为主部门 + sysUser.setDeptId(deptIdList.get(0)); + baseMapper.updateById(sysUser); + + // 插入用户部门关联关系 + deptIdList.forEach(deptId -> { + SysUserDept sysUserDept = new SysUserDept(); + sysUserDept.setUserId(sysUser.getUserId()); + sysUserDept.setDeptId(deptId); + sysUserDeptMapper.insert(sysUserDept); + }); + } + + // 插入用户租户关系表 + SysTenantUser sysTenantUser = new SysTenantUser(); + sysTenantUser.setUserId(sysUser.getUserId()); + sysTenantUser.setTenantId(Objects.nonNull(SecurityUtils.getUser()) ? SecurityUtils.getUser().getTenantId() + : userDto.getTenantId()); + sysTenantUserMapper.insert(sysTenantUser); + return Boolean.TRUE; + } + + /** + * 根据用户信息查询用户全部信息,包括角色和权限 + * + * @param userDTO 用户信息DTO + * @return 包含用户角色和权限的用户信息对象 + */ + @Override + public R getUserInfo(UserDTO userDTO) { + UserVO dbUser = baseMapper.getUserVo(userDTO); + + if (dbUser == null) { + return R.failed(MsgUtils.getMessage(UpmsErrorCodes.SYS_USER_USERINFO_EMPTY, userDTO.getUsername())); + } + + // 设置角色列表 (ID) + UserInfo userInfo = new UserInfo(); + BeanUtils.copyProperties(dbUser, userInfo); + // 设置权限列表(menu.permission) + List permissions = dbUser.getRoleList() + .stream() + .map(SysRole::getRoleId) + .flatMap(roleId -> sysMenuService.findMenuByRoleId(roleId).stream()) + .map(SysMenu::getPermission) + .filter(StrUtil::isNotEmpty) + .toList(); + userInfo.setPermissions(permissions); + + // 如果是登录成功以后查询租户信息并进行校验 + if (Objects.nonNull(SecurityUtils.getUser())) { + SysTenant updateTenant = sysTenantService.getOrUpdateTenant(); + if (Objects.nonNull(updateTenant)) { + userInfo.setTenantId(updateTenant.getId()); + userInfo.setTenantName(updateTenant.getName()); + } + } + + return R.ok(userInfo); + } + + /** + * 分页查询用户信息(含有角色信息) + * + * @param page 分页对象 + * @param userDTO 参数列表 + * @return + */ + @Override + public IPage getUsersWithRolePage(Page page, UserDTO userDTO) { + userDTO.setTenantId(SecurityUtils.getUser().getTenantId()); + return baseMapper.getUserVosPage(page, userDTO, DataScope.of()); + } + + /** + * 通过ID查询用户信息 + * + * @param id 用户ID + * @return 用户信息 + */ + @Override + public UserVO selectUserVoById(Long id) { + return baseMapper.getUserVoById(id); + } + + /** + * 删除用户 + * + * @param ids 用户ID 列表 + * @return Boolean + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean deleteUserByIds(Long[] ids) { + // 删除 spring cache + List userList = baseMapper.selectByIds(CollUtil.toList(ids)); + Cache cache = cacheManager.getCache(CacheConstants.USER_DETAILS); + for (SysUser sysUser : userList) { + cache.evict(sysUser.getUsername()); + } + + // 删除用户角色 + sysUserRoleMapper.delete(Wrappers.lambdaQuery().in(SysUserRole::getUserId, CollUtil.toList(ids))); + sysUserDeptMapper.delete(Wrappers.lambdaQuery().in(SysUserDept::getUserId, CollUtil.toList(ids))); + sysUserPostMapper.delete(Wrappers.lambdaQuery().in(SysUserPost::getUserId, CollUtil.toList(ids))); + sysTenantUserMapper.delete(Wrappers.lambdaQuery() + .in(SysTenantUser::getUserId, CollUtil.toList(ids)) + .eq(SysTenantUser::getTenantId, SecurityUtils.getUser().getTenantId())); + this.removeBatchByIds(CollUtil.toList(ids)); + return Boolean.TRUE; + } + + @Override + @CacheEvict(value = CacheConstants.USER_DETAILS, key = "#userDto.username") + public R updateUserInfo(UserDTO userDto) { + Long userId = SecurityUtils.getUser().getId(); + SysUser sysUser = new SysUser(); + sysUser.setUserId(userId); + sysUser.setAvatar(userDto.getAvatar()); + sysUser.setNickname(userDto.getNickname()); + sysUser.setName(userDto.getName()); + sysUser.setEmail(userDto.getEmail()); + + // 校验手机号 + if (StrUtil.isNotBlank(userDto.getPhone())) { + Object codeObj = RedisUtils.get(CacheConstants.DEFAULT_CODE_KEY + LoginTypeEnum.SMS.getType() + + StringPool.AT + userDto.getPhone()); + if (!StrUtil.equals(userDto.getCode(), codeObj.toString())) { + return R.failed(MsgUtils.getMessage(UpmsErrorCodes.SYS_APP_SMS_ERROR)); + } + } + + return R.ok(this.updateById(sysUser)); + } + + @Override + @Transactional(rollbackFor = Exception.class) + @Audit(name = "用户更新", spel = "@sysUserMapper.selectById(#userDto.userId)") + @CacheEvict(value = CacheConstants.USER_DETAILS, key = "#userDto.username") + public Boolean updateUser(UserDTO userDto) { + // 更新用户表信息 + SysUser sysUser = new SysUser(); + BeanUtils.copyProperties(userDto, sysUser); + sysUser.setUpdateTime(LocalDateTime.now()); + + if (StrUtil.isNotBlank(userDto.getPassword())) { + sysUser.setPassword(ENCODER.encode(userDto.getPassword())); + } + + this.updateById(sysUser); + + // 更新用户角色表 + if (userDto.getRole() != null) { + sysUserRoleMapper + .delete(Wrappers.lambdaQuery().eq(SysUserRole::getUserId, userDto.getUserId())); + userDto.getRole().stream().map(roleId -> { + SysUserRole userRole = new SysUserRole(); + userRole.setUserId(sysUser.getUserId()); + userRole.setRoleId(roleId); + return userRole; + }).forEach(SysUserRole::insert); + } + + // 更新用户岗位表 + if (userDto.getPost() != null) { + sysUserPostMapper + .delete(Wrappers.lambdaQuery().eq(SysUserPost::getUserId, userDto.getUserId())); + userDto.getPost().stream().map(postId -> { + SysUserPost userPost = new SysUserPost(); + userPost.setUserId(sysUser.getUserId()); + userPost.setPostId(postId); + return userPost; + }).forEach(SysUserPost::insert); + } + + // 更新用户部门表 + List deptIdList = CollUtil.isNotEmpty(userDto.getDeptIds()) ? userDto.getDeptIds() + : (Objects.nonNull(userDto.getDeptId()) ? Collections.singletonList(userDto.getDeptId()) : null); + + if (CollUtil.isNotEmpty(deptIdList)) { + // 设置第一个部门为主部门 + sysUser.setDeptId(deptIdList.get(0)); + this.updateById(sysUser); + + // 删除原有部门关联关系 + sysUserDeptMapper + .delete(Wrappers.lambdaQuery().eq(SysUserDept::getUserId, userDto.getUserId())); + + // 插入新的部门关联关系 + deptIdList.forEach(deptId -> { + SysUserDept sysUserDept = new SysUserDept(); + sysUserDept.setUserId(sysUser.getUserId()); + sysUserDept.setDeptId(deptId); + sysUserDept.insert(); + }); + } + + // 同时清理用户失败次数的缓存 + String key = String.format("%s%s:%s", CacheConstants.GLOBALLY + , CacheConstants.LOGIN_ERROR_TIMES, userDto.getUsername()); + RedisUtils.delete(key); + + return Boolean.TRUE; + } + + /** + * 查询上级部门的用户信息 + * + * @param username 用户名 + * @return R + */ + @Override + public List listAncestorUsers(String username) { + SysUser sysUser = this.getOne(Wrappers.query().lambda().eq(SysUser::getUsername, username)); + + // 查询所属部门 + List sysDeptList = sysDeptMapper.listDeptsByUserId(sysUser.getUserId(), sysUser.getTenantId()); + if (CollUtil.isEmpty(sysDeptList)) { + return null; + } + + // 查询用户部门ID + List parentDeptList = sysDeptList.stream().map(SysDept::getParentId).toList(); + List userIdList = sysUserDeptMapper + .selectList(Wrappers.lambdaQuery().in(SysUserDept::getDeptId, parentDeptList)) + .stream() + .map(SysUserDept::getUserId) + .toList(); + return this.list(Wrappers.lambdaQuery().in(SysUser::getUserId, userIdList)); + } + + /** + * 查询全部的用户 + * + * @param userDTO 查询条件 + * @param ids ids 用户列表 + * @return list + */ + @Override + public List listUser(UserDTO userDTO, Long[] ids) { + // 根据数据权限查询全部的用户信息 + userDTO.setTenantId(SecurityUtils.getUser().getTenantId()); + List voList = baseMapper.getUserVoListByScope(userDTO, ids, DataScope.of()); + return voList.stream().map(userVO -> { + UserExcelVO excelVO = new UserExcelVO(); + BeanUtils.copyProperties(userVO, excelVO); + // 转换角色名称 + String roleNameList = userVO.getRoleList() + .stream() + .map(SysRole::getRoleName) + .collect(Collectors.joining(StrUtil.COMMA)); + excelVO.setRoleNameList(roleNameList); + // 转化岗位名称 + String postNameList = userVO.getPostList() + .stream() + .map(SysPost::getPostName) + .collect(Collectors.joining(StrUtil.COMMA)); + excelVO.setPostNameList(postNameList); + // 转化部门名称 + String deptNameList = userVO.getDeptList() + .stream() + .map(SysDept::getName) + .collect(Collectors.joining(StrUtil.COMMA)); + excelVO.setDeptNameList(deptNameList); + return excelVO; + }).toList(); + } + + /** + * excel 导入用户, 插入正确的 错误的提示行号 + * + * @param excelVOList excel 列表数据 + * @param bindingResult 错误数据 + * @return ok fail + */ + @Override + public R importUser(List excelVOList, BindingResult bindingResult) { + // 通用校验获取失败的数据 + List errorMessageList = (List) bindingResult.getTarget(); + List deptList = sysDeptService.list(); + List roleList = sysRoleService.list(); + List postList = sysPostService.list(); + + // 执行数据插入操作 组装 UserDto + for (UserExcelVO excel : excelVOList) { + // 个性化校验逻辑 + List userList = TenantBroker.noneAs(this::list); + + Set errorMsg = new HashSet<>(); + // 校验用户名是否存在 + boolean exsitUserName = userList.stream() + .anyMatch(sysUser -> excel.getUsername().equals(sysUser.getUsername())); + + if (exsitUserName) { + errorMsg.add(MsgUtils.getMessage(UpmsErrorCodes.SYS_USER_USERNAME_EXISTING, excel.getUsername())); + } + + // 校验手机号是否存在 + boolean exsitPhone = userList.stream().anyMatch(sysUser -> excel.getPhone().equals(sysUser.getPhone())); + if (exsitPhone) { + errorMsg.add(MsgUtils.getMessage(UpmsErrorCodes.SYS_USER_PHONE_EXISTING, excel.getPhone())); + } + + // 判断输入的部门名称列表是否合法 + Optional deptOptional = deptList.stream() + .filter(dept -> excel.getDeptNameList().equals(dept.getName())) + .findFirst(); + if (deptOptional.isEmpty()) { + errorMsg.add(MsgUtils.getMessage(UpmsErrorCodes.SYS_DEPT_DEPTNAME_INEXISTENCE, excel.getDeptNameList())); + } + + // 判断输入的角色名称列表是否合法 + List roleNameList = StrUtil.split(excel.getRoleNameList(), StrUtil.COMMA); + List roleCollList = roleList.stream() + .filter(role -> roleNameList.stream().anyMatch(name -> role.getRoleName().equals(name))) + .toList(); + + if (roleCollList.size() != roleNameList.size()) { + errorMsg.add(MsgUtils.getMessage(UpmsErrorCodes.SYS_ROLE_ROLENAME_INEXISTENCE, excel.getRoleNameList())); + } + + // 判断输入的部门名称列表是否合法 + List postNameList = StrUtil.split(excel.getPostNameList(), StrUtil.COMMA); + List postCollList = postList.stream() + .filter(post -> postNameList.stream().anyMatch(name -> post.getPostName().equals(name))) + .toList(); + + if (postCollList.size() != postNameList.size()) { + errorMsg.add(MsgUtils.getMessage(UpmsErrorCodes.SYS_POST_POSTNAME_INEXISTENCE, excel.getPostNameList())); + } + + // 数据合法情况 + if (CollUtil.isEmpty(errorMsg)) { + insertExcelUser(excel, deptOptional, roleCollList, postCollList); + } else { + // 数据不合法情况 + errorMessageList.add(new ErrorMessage(excel.getLineNum(), errorMsg)); + } + + } + + if (CollUtil.isNotEmpty(errorMessageList)) { + return R.failed(errorMessageList); + } + return R.ok(null, MsgUtils.getMessage(UpmsErrorCodes.SYS_USER_IMPORT_SUCCEED)); + } + + /** + * 插入excel User + */ + private void insertExcelUser(UserExcelVO excel, Optional deptOptional, List roleCollList, + List postCollList) { + UserDTO userDTO = new UserDTO(); + userDTO.setUsername(excel.getUsername()); + userDTO.setPhone(excel.getPhone()); + userDTO.setNickname(excel.getNickname()); + userDTO.setName(excel.getName()); + userDTO.setEmail(excel.getEmail()); + userDTO.setLockFlag(excel.getLockFlag()); + // 批量导入初始密码为手机号 + userDTO.setPasswordModifyTime(LocalDateTime.now()); + userDTO.setPassword(userDTO.getPhone()); + // 根据部门名称查询部门ID + userDTO.setDeptId(deptOptional.get().getDeptId()); + // 插入岗位名称 + List postIdList = postCollList.stream().map(SysPost::getPostId).toList(); + userDTO.setPost(postIdList); + // 根据角色名称查询角色ID + List roleIdList = roleCollList.stream().map(SysRole::getRoleId).toList(); + userDTO.setRole(roleIdList); + // 插入用户 + this.saveUser(userDTO); + } + + /** + * 注册用户 赋予用户默认角色 + * + * @param userDto 用户信息 + * @return success/false + */ + @Override + @Transactional(rollbackFor = Exception.class) + public R registerUser(RegisterUserDTO userDto) { + // 校验短信验证码 + if (StrUtil.isBlank(userDto.getCode())) { + return R.failed(MsgUtils.getMessage(UpmsErrorCodes.SYS_PARAM_ILLEGAL)); + } + String codeObj = RedisUtils + .get(CacheConstants.DEFAULT_CODE_KEY + LoginTypeEnum.SMS.getType() + StringPool.AT + userDto.getPhone()); + if (!StrUtil.equals(codeObj, userDto.getCode())) { + return R.failed(MsgUtils.getMessage(UpmsErrorCodes.SYS_APP_SMS_ERROR)); + } + + // 判断用户名是否存在 + boolean usernameExists = TenantBroker + .noneAs(() -> this.exists(Wrappers.lambdaQuery().eq(SysUser::getUsername, userDto.getUsername()))); + if (usernameExists) { + String message = MsgUtils.getMessage(UpmsErrorCodes.SYS_USER_USERNAME_EXISTING, userDto.getUsername()); + return R.failed(message); + } + + // 判断手机号是否存在 + boolean phoneExists = TenantBroker + .noneAs(() -> this.exists(Wrappers.lambdaQuery().eq(SysUser::getPhone, userDto.getPhone()))); + if (phoneExists) { + String message = MsgUtils.getMessage(UpmsErrorCodes.SYS_USER_PHONE_EXISTING, userDto.getPhone()); + return R.failed(message); + } + + // 单独的用户避免越权 + UserDTO user = new UserDTO(); + BeanUtils.copyProperties(userDto, user); + return R.ok(saveUser(user)); + } + + /** + * 锁定用户 + * + * @param username 用户名 + * @return 操作结果,包含是否成功 + */ + @Override + @CacheEvict(value = CacheConstants.USER_DETAILS, key = "#username") + public R lockUser(String username) { + SysUser sysUser = baseMapper.selectOne(Wrappers.lambdaQuery().eq(SysUser::getUsername, username)); + + if (Objects.nonNull(sysUser)) { + sysUser.setLockFlag(UserStateEnum.LOCK.getCode()); + baseMapper.updateById(sysUser); + } + return R.ok(); + } + + /** + * 修改用户密码 + * + * @param userDto 用户数据传输对象,包含原密码和新密码 + * @return 操作结果 + * @CacheEvict 清除用户详情缓存 + */ + @Override + @CacheEvict(value = CacheConstants.USER_DETAILS, key = "#userDto.username") + public R changePassword(UserDTO userDto) { + SysUser user = baseMapper.selectById(SecurityUtils.getUser().getId()); + if (StrUtil.isEmpty(userDto.getPassword())) { + return R.failed(MsgUtils.getMessage(UpmsErrorCodes.SYS_USER_OLD_PASSWORD_EMPTY)); + } + + if (!ENCODER.matches(userDto.getPassword(), user.getPassword())) { + log.info("原密码错误,修改个人信息失败:{}", userDto.getUsername()); + return R.failed(MsgUtils.getMessage(UpmsErrorCodes.SYS_USER_UPDATE_PASSWORDERROR)); + } + + if (StrUtil.isEmpty(userDto.getNewpassword1())) { + return R.failed(MsgUtils.getMessage(UpmsErrorCodes.SYS_USER_NEW_PASSWORD_EMPTY)); + } + String password = ENCODER.encode(userDto.getNewpassword1()); + + this.update(Wrappers.lambdaUpdate() + .set(SysUser::getPassword, password) + .set(SysUser::getPasswordModifyTime, LocalDateTime.now()) + .eq(SysUser::getUserId, user.getUserId())); + return R.ok(); + } + + /** + * 解绑用户第三方登录账号 + * + * @param type 登录类型,参见LoginTypeEnum枚举 + * @return 操作结果,成功返回R.ok(),失败返回R.failed() + */ + @Override + public R unbinding(String type) { + PigxUser user = SecurityUtils.getUser(); + LambdaUpdateWrapper wrapper = null; + + // 微信开放平台 (普通用户扫码登录) + if (type.equals(LoginTypeEnum.WECHAT.getType())) { + wrapper = Wrappers.lambdaUpdate() + .set(SysUser::getWxOpenid, null) + .eq(SysUser::getUserId, user.getId()); + // 码云登录 (方便申请) + } else if (type.equals(LoginTypeEnum.GITEE.getType())) { + wrapper = Wrappers.lambdaUpdate() + .set(SysUser::getGiteeLogin, null) + .eq(SysUser::getUserId, user.getId()); + // 企业微信登录 + } else if (type.equals(LoginTypeEnum.WEIXIN_CP.getType())) { + wrapper = Wrappers.lambdaUpdate() + .set(SysUser::getWxCpUserid, null) + .eq(SysUser::getUserId, user.getId()); + // 钉钉登录 + } else if (type.equals(LoginTypeEnum.DINGTALK.getType())) { + wrapper = Wrappers.lambdaUpdate() + .set(SysUser::getWxDingUserid, null) + .eq(SysUser::getUserId, user.getId()); + } + + if (Objects.isNull(wrapper)) { + return R.failed(MsgUtils.getMessage(UpmsErrorCodes.SYS_USER_UNBIND_TYPE_NOT_FOUND)); + } + this.update(wrapper); + return R.ok(); + } + + /** + * 检查用户密码是否正确 + * + * @param username 用户名 + * @param password 待验证的密码 + * @return 验证结果,成功返回R.ok(),失败返回R.failed() + */ + @Override + public R checkPassword(String username, String password) { + SysUser sysUser = this.getOne(Wrappers.lambdaQuery().eq(SysUser::getUsername, username)); + boolean matches = ENCODER.matches(password, sysUser.getPassword()); + return matches ? R.ok(true) : R.ok(false, MsgUtils.getMessage(UpmsErrorCodes.SYS_USER_PASSWORD_MISMATCH)); + } + + /** + * 重置用户密码 + * + * @param userDto 用户信息DTO,包含用户名、原密码和新密码等信息 + * @return 返回操作结果,成功返回true,失败返回错误信息 + */ + @Override + @CacheEvict(value = CacheConstants.USER_DETAILS, key = "#userDto.username") + public R resetUserPassword(RegisterUserDTO userDto) { + // 校验密码 + R checkedPassword = checkPassword(userDto.getUsername(), userDto.getPassword()); + if (!checkedPassword.isOk()) { + return checkedPassword; + } + + // 新密码校验 + if (StrUtil.equals(userDto.getPassword(), userDto.getNewpassword1())) { + return R.failed(MsgUtils.getMessage(UpmsErrorCodes.SYS_USER_PASSWORD_SAME)); + } + + // 重置密码 + String password = ENCODER.encode(userDto.getNewpassword1()); + this.update(Wrappers.lambdaUpdate() + .set(SysUser::getPassword, password) + .set(SysUser::getPasswordModifyTime, LocalDateTime.now()) + .set(SysUser::getPasswordExpireFlag, CommonConstants.STATUS_NORMAL) + .eq(SysUser::getUsername, userDto.getUsername())); + return R.ok(); + } + + /** + * 忘记用户密码 + * + * @param userDto 用户信息DTO + * @param code 验证码 + * @return 操作结果,成功返回true + */ + @Override + public R forgetUserPassword(RegisterUserDTO userDto, String code) { + if (StrUtil.isBlank(userDto.getPhone())) { + return R.failed(MsgUtils.getMessage(UpmsErrorCodes.SYS_PARAM_ILLEGAL)); + } + + String codeObj = RedisUtils + .get(CacheConstants.DEFAULT_CODE_KEY + LoginTypeEnum.SMS.getType() + StringPool.AT + userDto.getPhone()); + if (!StrUtil.equals(codeObj, code)) { + return R.failed(MsgUtils.getMessage(UpmsErrorCodes.SYS_APP_SMS_ERROR)); + } + + TenantBroker.noneAs(() -> { + String username = lambdaQuery().select(SysUser::getUsername) + .eq(SysUser::getPhone, userDto.getPhone()) + .one() + .getUsername(); + + // 重置密码 + String password = ENCODER.encode(userDto.getNewpassword1()); + this.update(Wrappers.lambdaUpdate() + .set(SysUser::getPassword, password) + .set(SysUser::getPasswordModifyTime, LocalDateTime.now()) + .set(SysUser::getPasswordExpireFlag, CommonConstants.STATUS_NORMAL) + .eq(SysUser::getPhone, userDto.getPhone())); + cacheManager.getCache(CacheConstants.USER_DETAILS).evict(username); + return username; + }); + + return R.ok(); + } + + @Override + public List listUserIdByRoleIds(List roleIdList) { + return sysUserRoleMapper.selectList(Wrappers.lambdaQuery().in(SysUserRole::getRoleId, roleIdList)) + .stream() + .map(SysUserRole::getUserId) + .toList(); + } + + /** + * 根据部门ID列表获取用户ID列表接口 + * + * @param deptIdList 部门ID列表 + * @return List 返回结果对象,包含根据部门ID列表获取到的用户ID列表信息 + */ + @Override + public List listUserIdByDeptIds(List deptIdList) { + List userList = sysUserDeptMapper + .selectList(Wrappers.lambdaQuery().in(SysUserDept::getDeptId, deptIdList)) + .stream() + .map(SysUserDept::getUserId) + .toList(); + return baseMapper.selectList(Wrappers.lambdaQuery().in(SysUser::getUserId, userList)); + } + + /** + * 获取当前用户的部门列表 + * + * @return 部门列表,主部门排在第一位 + */ + @Override + public List getUserDeptList() { + Long userId = SecurityUtils.getUser().getId(); + + // 1. 查询用户的所有部门关联 + List userDepts = sysUserDeptMapper.selectList( + Wrappers.lambdaQuery() + .eq(SysUserDept::getUserId, userId) + ); + + if (CollUtil.isEmpty(userDepts)) { + return Collections.emptyList(); + } + + // 2. 提取部门ID列表 + List deptIds = userDepts.stream() + .map(SysUserDept::getDeptId) + .toList(); + + // 3. 查询部门详细信息 + return sysDeptService.list( + Wrappers.lambdaQuery() + .in(SysDept::getDeptId, deptIds) + ); + + } + + /** + * 切换用户当前部门 + * + * @param deptId 部门ID + * @return 操作结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public R updateUserDept(Long deptId) { + PigxUser user = SecurityUtils.getUser(); + Long userId = user.getId(); + String username = user.getUsername(); + + // 1. 直接更新用户表的主部门ID + this.update(Wrappers.lambdaUpdate() + .set(SysUser::getDeptId, deptId) + .eq(SysUser::getUserId, userId)); + + // 2. 清除用户缓存,触发权限重新计算 + cacheManager.getCache(CacheConstants.USER_DETAILS).evict(username); + + return R.ok(true, MsgUtils.getMessage(UpmsErrorCodes.SYS_DEPT_SWITCH_SUCCEED)); + } } diff --git a/pigx-upms/pigx-upms-biz/src/main/resources/mapper/SysDeptMapper.xml b/pigx-upms/pigx-upms-biz/src/main/resources/mapper/SysDeptMapper.xml index 0ea564cea..10a2feb26 100644 --- a/pigx-upms/pigx-upms-biz/src/main/resources/mapper/SysDeptMapper.xml +++ b/pigx-upms/pigx-upms-biz/src/main/resources/mapper/SysDeptMapper.xml @@ -1,7 +1,7 @@ + + INNER JOIN sys_user_dept ud ON u.user_id = ud.user_id + AND ud.dept_id = #{query.deptId} + AND ud.tenant_id = #{query.tenantId} + WHERE u.del_flag = '0' AND u.tenant_id = #{query.tenantId} - AND (ud.tenant_id = #{query.tenantId} OR ud.tenant_id IS NULL) @@ -126,11 +130,6 @@ AND u.username LIKE #{usernameLike} - - - AND ud.dept_id = #{query.deptId} - - @@ -142,23 +141,23 @@