Jelajahi Sumber

bump: 发布 1.7.0

https://helio.uncarbon.cc/#/i18n/zh-CN/appendix/change-log
Uncarbon 3 tahun lalu
induk
melakukan
f6fa1e6fc7
50 mengubah file dengan 360 tambahan dan 484 penghapusan
  1. 1 1
      README.md
  2. 1 1
      attachments/schema/MySQL/helio_boot.sql
  3. 1 1
      attachments/schema/PostgreSQL/helio_boot.sql
  4. 2 2
      pom.xml
  5. 17 8
      src/main/java/cc/uncarbon/config/AsyncConfiguration.java
  6. 7 2
      src/main/java/cc/uncarbon/config/CustomInterceptorConfiguration.java
  7. 29 0
      src/main/java/cc/uncarbon/config/NotFoundConfiguration.java
  8. 0 39
      src/main/java/cc/uncarbon/interceptor/AppSaTokenRouteInterceptor.java
  9. 5 0
      src/main/java/cc/uncarbon/module/app/constant/AppConstant.java
  10. 33 11
      src/main/java/cc/uncarbon/module/sys/aspect/SysLogAspect.java
  11. 22 0
      src/main/java/cc/uncarbon/module/sys/aspect/extension/SysLogAspectExtension.java
  12. 31 0
      src/main/java/cc/uncarbon/module/sys/aspect/extension/SysLogAspectExtensionForSysUserLogin.java
  13. 13 0
      src/main/java/cc/uncarbon/module/sys/constant/SysConstant.java
  14. 6 7
      src/main/java/cc/uncarbon/module/sys/model/request/AdminBindRoleMenuRelationDTO.java
  15. 6 7
      src/main/java/cc/uncarbon/module/sys/model/request/AdminBindUserRoleRelationDTO.java
  16. 0 29
      src/main/java/cc/uncarbon/module/sys/model/request/AdminKickOutSysUserDTO.java
  17. 0 30
      src/main/java/cc/uncarbon/module/sys/model/request/AdminListSysDeptDTO.java
  18. 0 26
      src/main/java/cc/uncarbon/module/sys/model/request/AdminListSysMenuDTO.java
  19. 0 14
      src/main/java/cc/uncarbon/module/sys/model/request/AdminListSysRoleDTO.java
  20. 0 14
      src/main/java/cc/uncarbon/module/sys/model/request/AdminListSysTenantDTO.java
  21. 0 14
      src/main/java/cc/uncarbon/module/sys/model/request/AdminListSysUserDTO.java
  22. 3 5
      src/main/java/cc/uncarbon/module/sys/model/request/AdminResetSysUserPasswordDTO.java
  23. 3 0
      src/main/java/cc/uncarbon/module/sys/model/request/SysUserLoginDTO.java
  24. 0 2
      src/main/java/cc/uncarbon/module/sys/model/response/SysDataDictBO.java
  25. 0 6
      src/main/java/cc/uncarbon/module/sys/model/response/SysDeptBO.java
  26. 0 2
      src/main/java/cc/uncarbon/module/sys/model/response/SysLogBO.java
  27. 3 4
      src/main/java/cc/uncarbon/module/sys/model/response/SysMenuBO.java
  28. 0 2
      src/main/java/cc/uncarbon/module/sys/model/response/SysParamBO.java
  29. 0 2
      src/main/java/cc/uncarbon/module/sys/model/response/SysRoleBO.java
  30. 0 2
      src/main/java/cc/uncarbon/module/sys/model/response/SysTenantBO.java
  31. 3 4
      src/main/java/cc/uncarbon/module/sys/model/response/SysUserBO.java
  32. 0 2
      src/main/java/cc/uncarbon/module/sys/model/response/SysUserBaseInfoBO.java
  33. 0 2
      src/main/java/cc/uncarbon/module/sys/model/response/VbenAdminMenuMetaVO.java
  34. 0 2
      src/main/java/cc/uncarbon/module/sys/model/response/VbenAdminUserInfoVO.java
  35. 7 5
      src/main/java/cc/uncarbon/module/sys/service/SysDataDictService.java
  36. 10 39
      src/main/java/cc/uncarbon/module/sys/service/SysDeptService.java
  37. 12 8
      src/main/java/cc/uncarbon/module/sys/service/SysLogService.java
  38. 15 38
      src/main/java/cc/uncarbon/module/sys/service/SysMenuService.java
  39. 6 5
      src/main/java/cc/uncarbon/module/sys/service/SysParamService.java
  40. 21 43
      src/main/java/cc/uncarbon/module/sys/service/SysRoleMenuRelationService.java
  41. 14 27
      src/main/java/cc/uncarbon/module/sys/service/SysRoleService.java
  42. 10 10
      src/main/java/cc/uncarbon/module/sys/service/SysTenantService.java
  43. 5 4
      src/main/java/cc/uncarbon/module/sys/service/SysUserRoleRelationService.java
  44. 31 14
      src/main/java/cc/uncarbon/module/sys/service/SysUserService.java
  45. 11 9
      src/main/java/cc/uncarbon/module/sys/web/auth/AdminAuthController.java
  46. 2 3
      src/main/java/cc/uncarbon/module/sys/web/sys/AdminSysDeptController.java
  47. 6 13
      src/main/java/cc/uncarbon/module/sys/web/sys/AdminSysMenuController.java
  48. 5 11
      src/main/java/cc/uncarbon/module/sys/web/sys/AdminSysRoleController.java
  49. 19 12
      src/main/java/cc/uncarbon/module/sys/web/sys/AdminSysUserController.java
  50. 0 2
      src/main/resources/application.yml

+ 1 - 1
README.md

@@ -5,7 +5,7 @@
 
 JDK compatibility: 1.8 - 17
 
-[官方文档](https://helio.uncarbon.cc/)
+[官方文档](https://helio.uncarbon.cc/) [主要技术栈依赖](https://helio.uncarbon.cc/#/i18n/zh-CN/helio-starters/dependencies) [前端演示站](https://helio-demo.uncarbon.cc/)
 
 需要先安装 `MySQL`、`Redis` 等必需中间件
 

+ 1 - 1
attachments/schema/MySQL/helio_boot.sql

@@ -148,7 +148,7 @@ VALUES (1, 0, 1, 0, '2021-06-01 17:16:48', NULL, '2021-06-02 17:14:16', NULL, '
         'ant-design:setting-outlined', 3, 1, 'LAYOUT', ''),
        (2, 0, 1, 0, '2021-06-01 17:13:13', NULL, '2021-07-18 00:10:33', 'admin', '中控台', 0, 0, 'Dashboard',
         'ant-design:appstore-outlined', 1, 1, 'LAYOUT', ''),
-       (3, 0, 1, 0, '2021-06-01 17:14:22', NULL, '2021-06-02 11:24:38', NULL, '分析页(默认页必须分配, 否则进不去后台)', 2, 1,
+       (3, 0, 1, 0, '2021-06-01 17:14:22', NULL, '2021-06-02 11:24:38', NULL, '分析页(后台登录后默认页)', 2, 1,
         'Dashboard:analysis', 'ant-design:fund-outlined', 1, 1, '/dashboard/analysis/index', ''),
        (4, 0, 1, 0, '2021-06-01 17:14:47', NULL, '2021-06-02 11:32:23', NULL, '工作台', 2, 1, 'Dashboard:workbench',
         'ant-design:database-outlined', 2, 1, '/dashboard/workbench/index', ''),

+ 1 - 1
attachments/schema/PostgreSQL/helio_boot.sql

@@ -251,7 +251,7 @@ INSERT INTO "sys_menu"
 VALUES (2, 0, 1, 0, '2021-06-01 17:13:13', NULL, '2021-07-18 00:10:33', 'admin', '中控台', 0, 0, 'Dashboard',
         'ant-design:appstore-outlined', 1, 1, 'LAYOUT', '');
 INSERT INTO "sys_menu"
-VALUES (3, 0, 1, 0, '2021-06-01 17:14:22', NULL, '2021-06-02 11:24:38', NULL, '分析页(默认页必须分配, 否则进不去后台)', 2, 1,
+VALUES (3, 0, 1, 0, '2021-06-01 17:14:22', NULL, '2021-06-02 11:24:38', NULL, '分析页(后台登录后默认页)', 2, 1,
         'Dashboard:analysis', 'ant-design:fund-outlined', 1, 1, '/dashboard/analysis/index', '');
 INSERT INTO "sys_menu"
 VALUES (4, 0, 1, 0, '2021-06-01 17:14:47', NULL, '2021-06-02 11:32:23', NULL, '工作台', 2, 1, 'Dashboard:workbench',

+ 2 - 2
pom.xml

@@ -7,12 +7,12 @@
     <parent>
         <groupId>cc.uncarbon.framework</groupId>
         <artifactId>helio-starters</artifactId>
-        <version>1.6.0</version>
+        <version>1.7.0</version>
     </parent>
 
     <artifactId>helio-boot</artifactId>
     <!-- 程序版本号,建议每次打包发布时都调整以作区分 -->
-    <version>1.6.0</version>
+    <version>1.7.0</version>
 
     <properties>
     </properties>

+ 17 - 8
src/main/java/cc/uncarbon/config/AsyncConfiguration.java

@@ -1,7 +1,5 @@
 package cc.uncarbon.config;
 
-import java.util.concurrent.Executor;
-import java.util.concurrent.ThreadPoolExecutor;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
@@ -12,6 +10,9 @@ import org.springframework.scheduling.annotation.AsyncConfigurer;
 import org.springframework.scheduling.annotation.EnableAsync;
 import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
 
+import java.util.concurrent.Executor;
+import java.util.concurrent.ThreadPoolExecutor;
+
 
 /**
  * @author Uncarbon
@@ -29,13 +30,23 @@ public class AsyncConfiguration implements AsyncConfigurer {
     public ThreadPoolTaskExecutor taskExecutor() {
         final String threadNamePrefix = "taskExecutor-";
 
+        log.debug("[异步任务线程池] 创建默认线程池【taskExecutor】,该线程池参数可通过 spring.task.execution 调节 >> " +
+                        "corePoolSize核心线程池大小={}, maxPoolSize最大线程数={}, queueCapacity队列容量={}" +
+                        ", rejectedExecutionHandler拒绝策略={}",
+                taskExecutionProperties.getPool().getCoreSize(),
+                taskExecutionProperties.getPool().getMaxSize(),
+                taskExecutionProperties.getPool().getQueueCapacity(),
+                "CallerRunsPolicy"
+                );
+
         ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
-        // 核心线程池大小 or 10
+        // 核心线程池大小,默认 8
         executor.setCorePoolSize(taskExecutionProperties.getPool().getCoreSize());
-        // 最大线程数 or 50
+        // 最大线程数,默认 Integer.MAX_VALUE
         executor.setMaxPoolSize(taskExecutionProperties.getPool().getMaxSize());
-        // 队列容量 or 10
+        // 队列容量,默认 Integer.MAX_VALUE
         executor.setQueueCapacity(taskExecutionProperties.getPool().getQueueCapacity());
+        // 拒绝策略
         executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
         // 线程名前缀
         executor.setThreadNamePrefix(threadNamePrefix);
@@ -48,15 +59,13 @@ public class AsyncConfiguration implements AsyncConfigurer {
 
     @Override
     public Executor getAsyncExecutor() {
-        log.debug("Creating Default Async Task Executor");
         return this.taskExecutor();
     }
 
     @Override
     public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
         return (ex, method, params) -> {
-            log.error("执行异步任务'{}'出错", method);
-            ex.printStackTrace();
+            log.error("[异步任务线程池] 执行异步任务【{}】时出错 >> 堆栈\t\n", method, ex);
         };
     }
 }

+ 7 - 2
src/main/java/cc/uncarbon/config/CustomInterceptorConfiguration.java

@@ -3,10 +3,11 @@ package cc.uncarbon.config;
 import cc.uncarbon.framework.core.props.HelioProperties;
 import cc.uncarbon.framework.satoken.interceptor.DefaultSaTokenParseInterceptor;
 import cc.uncarbon.interceptor.AdminSaTokenParseInterceptor;
-import cc.uncarbon.interceptor.AppSaTokenRouteInterceptor;
 import cc.uncarbon.module.app.constant.AppConstant;
 import cc.uncarbon.module.sys.constant.SysConstant;
 import cn.dev33.satoken.interceptor.SaAnnotationInterceptor;
+import cn.dev33.satoken.interceptor.SaRouteInterceptor;
+import cn.dev33.satoken.stp.StpUtil;
 import lombok.RequiredArgsConstructor;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
@@ -41,9 +42,13 @@ public class CustomInterceptorConfiguration implements WebMvcConfigurer {
         /*
         2. App-路由拦截器, 使几乎所有接口都需要登录
         放行接口请在配置文件的 helio.security.exclude-routes 中设置
+
+        @see http://sa-token.dev33.cn/doc/index.html#/use/route-check
          */
         registry
-                .addInterceptor(new AppSaTokenRouteInterceptor(helioProperties))
+                .addInterceptor(new SaRouteInterceptor(
+                        (req, res, handler) -> StpUtil.checkLogin()
+                ))
                 .addPathPatterns(AppConstant.APP_MODULE_CONTEXT_PATH + "/**")
                 .excludePathPatterns(helioProperties.getSecurity().getExcludeRoutes());
 

+ 29 - 0
src/main/java/cc/uncarbon/config/NotFoundConfiguration.java

@@ -0,0 +1,29 @@
+package cc.uncarbon.config;
+
+import org.springframework.boot.web.servlet.error.ErrorController;
+import org.springframework.http.HttpHeaders;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.servlet.NoHandlerFoundException;
+import springfox.documentation.annotations.ApiIgnore;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * 由于除 404 以外的异常都会被全局异常处理掉,所以走到这里的请求都是 404 了
+ *
+ * @author Uncarbon
+ */
+@RestController
+public class NotFoundConfiguration implements ErrorController {
+
+    /**
+     * 屏蔽 swagger 文档生成;主动抛出异常,由全局异常处理接管
+     */
+    @ApiIgnore
+    @RequestMapping(value = "/error")
+    public void error(HttpServletRequest request) throws NoHandlerFoundException {
+        throw new NoHandlerFoundException(request.getMethod(), request.getRequestURI(), new HttpHeaders());
+    }
+
+}

+ 0 - 39
src/main/java/cc/uncarbon/interceptor/AppSaTokenRouteInterceptor.java

@@ -1,39 +0,0 @@
-package cc.uncarbon.interceptor;
-
-import cc.uncarbon.framework.core.props.HelioProperties;
-import cc.uncarbon.module.app.constant.AppConstant;
-import cn.dev33.satoken.interceptor.SaRouteInterceptor;
-import cn.dev33.satoken.router.SaRouter;
-import cn.dev33.satoken.stp.StpUtil;
-import lombok.NonNull;
-import lombok.RequiredArgsConstructor;
-import org.springframework.web.servlet.ModelAndView;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.util.Collections;
-
-/**
- * 路由拦截器,自定义验证规则
- * http://sa-token.dev33.cn/doc/index.html#/use/route-check
- * @author Uncarbon
- */
-@RequiredArgsConstructor
-public class AppSaTokenRouteInterceptor extends SaRouteInterceptor {
-
-    private final HelioProperties helioProperties;
-
-
-    @Override
-    public void postHandle(@NonNull HttpServletRequest request, @NonNull HttpServletResponse response, @NonNull Object handler, ModelAndView modelAndView) {
-        /*
-        App登录验证
-        这里是按路由匹配,除了配置文件中指定的URI外,其他URI都需要登录才行
-         */
-        SaRouter
-                .match(Collections.singletonList(AppConstant.APP_MODULE_CONTEXT_PATH + "/**"))
-                .notMatch(helioProperties.getSecurity().getExcludeRoutes())
-                .check(StpUtil::checkLogin)
-                ;
-    }
-}

+ 5 - 0
src/main/java/cc/uncarbon/module/app/constant/AppConstant.java

@@ -2,10 +2,15 @@ package cc.uncarbon.module.app.constant;
 
 
 /**
+ * C端接口常量
+ *
  * @author Uncarbon
  */
 public interface AppConstant {
 
+    /**
+     * C端接口路由前缀
+     */
     String APP_MODULE_CONTEXT_PATH = "/app";
 
 }

+ 33 - 11
src/main/java/cc/uncarbon/module/sys/aspect/SysLogAspect.java

@@ -1,7 +1,9 @@
 package cc.uncarbon.module.sys.aspect;
 
 import cc.uncarbon.framework.core.context.UserContextHolder;
+import cc.uncarbon.framework.satoken.util.IPUtil;
 import cc.uncarbon.module.sys.annotation.SysLog;
+import cc.uncarbon.module.sys.aspect.extension.SysLogAspectExtension;
 import cc.uncarbon.module.sys.constant.SysConstant;
 import cc.uncarbon.module.sys.entity.SysLogEntity;
 import cc.uncarbon.module.sys.enums.SysLogStatusEnum;
@@ -16,8 +18,11 @@ import org.aspectj.lang.annotation.Around;
 import org.aspectj.lang.annotation.Aspect;
 import org.aspectj.lang.annotation.Pointcut;
 import org.aspectj.lang.reflect.MethodSignature;
+import org.springframework.beans.factory.ObjectProvider;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
 
 import java.util.Arrays;
 import java.util.HashMap;
@@ -35,9 +40,11 @@ import java.util.stream.Collectors;
 public class SysLogAspect {
 
     private final SysLogService sysLogService;
+    private final ObjectProvider<SysLogAspectExtension> extensions;
     // Bean 属性复制配置项
     private static final CopyOptions copyOptions4MaskingArgs = new CopyOptions();
 
+
     static {
         copyOptions4MaskingArgs.setIgnoreNullValue(false);
         copyOptions4MaskingArgs.setIgnoreProperties(SysConstant.SENSITIVE_FIELDS);
@@ -55,18 +62,17 @@ public class SysLogAspect {
         Object executeResult;
         executeResult = point.proceed();
 
+        MethodSignature methodSignature = (MethodSignature) point.getSignature();
+        SysLog sysLogAnnotation = methodSignature.getMethod().getAnnotation(SysLog.class);
+
         SysLogEntity sysLogEntity = new SysLogEntity()
+                // 记录操作人
                 .setUserId(UserContextHolder.getUserId())
                 .setUsername(UserContextHolder.getUserName())
-                ;
-
-        // 记录请求方法
-        MethodSignature methodSignature = (MethodSignature) point.getSignature();
-        sysLogEntity.setMethod(methodSignature.toString());
-
-        // 记录操作内容
-        SysLog sysLogAnnotation = methodSignature.getMethod().getAnnotation(SysLog.class);
-        sysLogEntity.setOperation(sysLogAnnotation.value());
+                // 记录请求方法
+                .setMethod(methodSignature.toString())
+                // 记录操作内容
+                .setOperation(sysLogAnnotation.value());
 
         /*
         记录请求参数
@@ -81,12 +87,28 @@ public class SysLogAspect {
                 }
         ).collect(Collectors.joining(",")));
 
-        // 记录IP地址
-        sysLogEntity.setIp(UserContextHolder.getClientIP());
+        /*
+        记录IP地址
+        https://gitee.com/uncarbon97/helio-boot/issues/I5KN1X
+         */
+        String ip = UserContextHolder.getClientIP();
+        if (ip == null) {
+            // 兜底处理,直接从当前线程的请求头中拿
+            ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+            if (requestAttributes != null) {
+                ip = IPUtil.getClientIPAddress(requestAttributes.getRequest());
+            }
+        }
+        sysLogEntity.setIp(ip);
 
         // 记录状态
         sysLogEntity.setStatus(SysLogStatusEnum.SUCCESS);
 
+        // 执行扩展 - 保存到 DB 前
+        for (SysLogAspectExtension extension : extensions) {
+            extension.beforeSaving(sysLogAnnotation, point, sysLogEntity);
+        }
+
         this.callSysLogServiceSave(sysLogEntity);
         // --------------------End @SysLog--------------------
 

+ 22 - 0
src/main/java/cc/uncarbon/module/sys/aspect/extension/SysLogAspectExtension.java

@@ -0,0 +1,22 @@
+package cc.uncarbon.module.sys.aspect.extension;
+
+import cc.uncarbon.module.sys.annotation.SysLog;
+import cc.uncarbon.module.sys.entity.SysLogEntity;
+import org.aspectj.lang.ProceedingJoinPoint;
+
+/**
+ * SysLog 切面实现类扩展
+ *
+ * @author Uncarbon
+ */
+public interface SysLogAspectExtension {
+
+    /**
+     * 保存到 DB 前
+     * @param sysLogAnnotation 注解
+     * @param point 切面 point
+     * @param sysLogEntity 日志实体对象
+     */
+    void beforeSaving(SysLog sysLogAnnotation, ProceedingJoinPoint point, SysLogEntity sysLogEntity);
+
+}

+ 31 - 0
src/main/java/cc/uncarbon/module/sys/aspect/extension/SysLogAspectExtensionForSysUserLogin.java

@@ -0,0 +1,31 @@
+package cc.uncarbon.module.sys.aspect.extension;
+
+import cc.uncarbon.module.sys.annotation.SysLog;
+import cc.uncarbon.module.sys.constant.SysConstant;
+import cc.uncarbon.module.sys.entity.SysLogEntity;
+import cc.uncarbon.module.sys.model.request.SysUserLoginDTO;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.springframework.stereotype.Component;
+
+/**
+ * SysLog 切面实现类扩展 for 登录后台用户
+ *
+ * @author Uncarbon
+ */
+@Component
+public class SysLogAspectExtensionForSysUserLogin implements SysLogAspectExtension {
+
+    @Override
+    public void beforeSaving(SysLog sysLogAnnotation, ProceedingJoinPoint point, SysLogEntity sysLogEntity) {
+        if (SysConstant.SysLogOperation.SYS_USER_LOGIN.equals(sysLogAnnotation.value())) {
+            // 仅针对特定注解扩展
+            for (Object arg : point.getArgs()) {
+                if (arg instanceof SysUserLoginDTO) {
+                    SysUserLoginDTO dto = (SysUserLoginDTO) arg;
+                    sysLogEntity.setUsername(dto.getUsername());
+                    sysLogEntity.setIp(dto.getClientIP());
+                }
+            }
+        }
+    }
+}

+ 13 - 0
src/main/java/cc/uncarbon/module/sys/constant/SysConstant.java

@@ -2,10 +2,15 @@ package cc.uncarbon.module.sys.constant;
 
 
 /**
+ * 系统管理常量
+ *
  * @author Uncarbon
  */
 public interface SysConstant {
 
+    /**
+     * 后台管理接口路由前缀
+     */
     String SYS_MODULE_CONTEXT_PATH = "/sys";
 
     /**
@@ -28,4 +33,12 @@ public interface SysConstant {
      */
     String[] SENSITIVE_FIELDS = {"password", "oldPassword", "newPassword", "confirmNewPassword", "passwordOfNewUser", "randomPassword", "tenantAdminPassword"};
 
+    /**
+     * SysLog 系统日志操作内容
+     */
+    interface SysLogOperation {
+
+        String SYS_USER_LOGIN = "登录后台用户";
+
+    }
 }

+ 6 - 7
src/main/java/cc/uncarbon/module/sys/model/request/AdminBindRoleMenuRelationDTO.java

@@ -1,15 +1,15 @@
 package cc.uncarbon.module.sys.model.request;
 
 import io.swagger.annotations.ApiModelProperty;
-import java.io.Serializable;
-import java.util.Set;
-import javax.validation.constraints.NotNull;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 import lombok.experimental.Accessors;
 
+import java.io.Serializable;
+import java.util.Set;
+
 
 /**
  * 后台管理-绑定角色与菜单关联关系
@@ -22,11 +22,10 @@ import lombok.experimental.Accessors;
 @Data
 public class AdminBindRoleMenuRelationDTO implements Serializable {
 
-    @ApiModelProperty(value = "角色ID", required = true)
-    @NotNull(message = "角色ID不能为空")
-    private Long roleId;
-
     @ApiModelProperty(value = "菜单Ids(空=清理关联关系后不再绑定任何菜单)")
     private Set<Long> menuIds;
 
+    @ApiModelProperty(value = "角色ID", hidden = true)
+    private Long roleId;
+
 }

+ 6 - 7
src/main/java/cc/uncarbon/module/sys/model/request/AdminBindUserRoleRelationDTO.java

@@ -1,15 +1,15 @@
 package cc.uncarbon.module.sys.model.request;
 
 import io.swagger.annotations.ApiModelProperty;
-import java.io.Serializable;
-import java.util.Set;
-import javax.validation.constraints.NotNull;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 import lombok.experimental.Accessors;
 
+import java.io.Serializable;
+import java.util.Set;
+
 
 /**
  * 后台管理-绑定用户与角色关联关系
@@ -22,11 +22,10 @@ import lombok.experimental.Accessors;
 @Data
 public class AdminBindUserRoleRelationDTO implements Serializable {
 
-    @ApiModelProperty(value = "用户ID", required = true)
-    @NotNull(message = "用户ID不能为空")
-    private Long userId;
-
     @ApiModelProperty(value = "角色Ids(空=清理关联关系后不再绑定任何角色)")
     private Set<Long> roleIds;
 
+    @ApiModelProperty(value = "用户ID", hidden = true)
+    private Long userId;
+
 }

+ 0 - 29
src/main/java/cc/uncarbon/module/sys/model/request/AdminKickOutSysUserDTO.java

@@ -1,29 +0,0 @@
-package cc.uncarbon.module.sys.model.request;
-
-import io.swagger.annotations.ApiModelProperty;
-import lombok.AllArgsConstructor;
-import lombok.Builder;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-import lombok.experimental.Accessors;
-
-import javax.validation.constraints.NotNull;
-import java.io.Serializable;
-
-
-/**
- * 后台管理-踢某用户下线
- * @author Uncarbon
- */
-@Accessors(chain = true)
-@Builder
-@AllArgsConstructor
-@NoArgsConstructor
-@Data
-public class AdminKickOutSysUserDTO implements Serializable {
-
-    @ApiModelProperty(value = "用户ID", required = true)
-    @NotNull(message = "用户ID不能为空")
-    private Long userId;
-
-}

+ 0 - 30
src/main/java/cc/uncarbon/module/sys/model/request/AdminListSysDeptDTO.java

@@ -1,30 +0,0 @@
-package cc.uncarbon.module.sys.model.request;
-
-import io.swagger.annotations.ApiModelProperty;
-import lombok.AllArgsConstructor;
-import lombok.Builder;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-import lombok.experimental.Accessors;
-
-import java.io.Serializable;
-
-
-/**
- * 后台管理-分页列表部门
- * @author Uncarbon
- */
-@Accessors(chain = true)
-@Builder
-@AllArgsConstructor
-@NoArgsConstructor
-@Data
-public class AdminListSysDeptDTO implements Serializable {
-
-    @ApiModelProperty(value = "名称(关键词)")
-    private String title;
-
-    @ApiModelProperty(value = "上级ID(无上级节点设置为0)")
-    private Long parentId;
-
-}

+ 0 - 26
src/main/java/cc/uncarbon/module/sys/model/request/AdminListSysMenuDTO.java

@@ -1,26 +0,0 @@
-package cc.uncarbon.module.sys.model.request;
-
-import io.swagger.annotations.ApiModelProperty;
-import java.io.Serializable;
-import lombok.AllArgsConstructor;
-import lombok.Builder;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-import lombok.experimental.Accessors;
-
-
-/**
- * 后台管理-列表后台菜单
- * @author Uncarbon
- */
-@Accessors(chain = true)
-@Builder
-@AllArgsConstructor
-@NoArgsConstructor
-@Data
-public class AdminListSysMenuDTO implements Serializable {
-
-    @ApiModelProperty(value = "保留")
-    private String reserved;
-
-}

+ 0 - 14
src/main/java/cc/uncarbon/module/sys/model/request/AdminListSysRoleDTO.java

@@ -1,17 +1,13 @@
 package cc.uncarbon.module.sys.model.request;
 
-import cc.uncarbon.framework.core.constant.HelioConstant;
-import com.fasterxml.jackson.annotation.JsonFormat;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 import lombok.experimental.Accessors;
-import org.springframework.format.annotation.DateTimeFormat;
 
 import java.io.Serializable;
-import java.time.LocalDateTime;
 
 
 /**
@@ -31,14 +27,4 @@ public class AdminListSysRoleDTO implements Serializable {
     @ApiModelProperty(value = "值(关键词)")
     private String value;
 
-    @ApiModelProperty(value = "时间区间起")
-    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = HelioConstant.Jackson.DATE_TIME_FORMAT)
-    @DateTimeFormat(pattern = HelioConstant.Jackson.DATE_TIME_FORMAT)
-    private LocalDateTime beginAt;
-
-    @ApiModelProperty(value = "时间区间止")
-    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = HelioConstant.Jackson.DATE_TIME_FORMAT)
-    @DateTimeFormat(pattern = HelioConstant.Jackson.DATE_TIME_FORMAT)
-    private LocalDateTime endAt;
-
 }

+ 0 - 14
src/main/java/cc/uncarbon/module/sys/model/request/AdminListSysTenantDTO.java

@@ -1,18 +1,14 @@
 package cc.uncarbon.module.sys.model.request;
 
-import cc.uncarbon.framework.core.constant.HelioConstant;
 import cc.uncarbon.module.sys.enums.GenericStatusEnum;
-import com.fasterxml.jackson.annotation.JsonFormat;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 import lombok.experimental.Accessors;
-import org.springframework.format.annotation.DateTimeFormat;
 
 import java.io.Serializable;
-import java.time.LocalDateTime;
 
 
 /**
@@ -35,14 +31,4 @@ public class AdminListSysTenantDTO implements Serializable {
     @ApiModelProperty(value = "状态")
     private GenericStatusEnum status;
 
-    @ApiModelProperty(value = "时间区间起")
-    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = HelioConstant.Jackson.DATE_TIME_FORMAT)
-    @DateTimeFormat(pattern = HelioConstant.Jackson.DATE_TIME_FORMAT)
-    private LocalDateTime beginAt;
-
-    @ApiModelProperty(value = "时间区间止")
-    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = HelioConstant.Jackson.DATE_TIME_FORMAT)
-    @DateTimeFormat(pattern = HelioConstant.Jackson.DATE_TIME_FORMAT)
-    private LocalDateTime endAt;
-
 }

+ 0 - 14
src/main/java/cc/uncarbon/module/sys/model/request/AdminListSysUserDTO.java

@@ -1,17 +1,13 @@
 package cc.uncarbon.module.sys.model.request;
 
-import cc.uncarbon.framework.core.constant.HelioConstant;
-import com.fasterxml.jackson.annotation.JsonFormat;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 import lombok.experimental.Accessors;
-import org.springframework.format.annotation.DateTimeFormat;
 
 import java.io.Serializable;
-import java.time.LocalDateTime;
 
 
 /**
@@ -28,14 +24,4 @@ public class AdminListSysUserDTO implements Serializable {
     @ApiModelProperty(value = "手机号(关键词)")
     private String phoneNo;
 
-    @ApiModelProperty(value = "时间区间起")
-    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = HelioConstant.Jackson.DATE_TIME_FORMAT)
-    @DateTimeFormat(pattern = HelioConstant.Jackson.DATE_TIME_FORMAT)
-    private LocalDateTime beginAt;
-
-    @ApiModelProperty(value = "时间区间止")
-    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = HelioConstant.Jackson.DATE_TIME_FORMAT)
-    @DateTimeFormat(pattern = HelioConstant.Jackson.DATE_TIME_FORMAT)
-    private LocalDateTime endAt;
-
 }

+ 3 - 5
src/main/java/cc/uncarbon/module/sys/model/request/AdminResetSysUserPasswordDTO.java

@@ -8,7 +8,6 @@ import lombok.NoArgsConstructor;
 import lombok.experimental.Accessors;
 
 import javax.validation.constraints.NotBlank;
-import javax.validation.constraints.NotNull;
 import javax.validation.constraints.Size;
 import java.io.Serializable;
 
@@ -24,13 +23,12 @@ import java.io.Serializable;
 @Data
 public class AdminResetSysUserPasswordDTO implements Serializable {
 
-    @ApiModelProperty(value = "用户ID", required = true)
-    @NotNull(message = "用户ID不能为空")
-    private Long userId;
-
     @ApiModelProperty(value = "随机新密码", required = true)
     @Size(min = 16, max = 64, message = "随机新密码须为16-64位")
     @NotBlank(message = "随机新密码不能为空")
     private String randomPassword;
 
+    @ApiModelProperty(value = "用户ID", hidden  = true)
+    private Long userId;
+
 }

+ 3 - 0
src/main/java/cc/uncarbon/module/sys/model/request/SysUserLoginDTO.java

@@ -48,4 +48,7 @@ public class SysUserLoginDTO implements Serializable {
     @ApiModelProperty(value = "验证码答案(可选,需自行对接业务逻辑)")
     private String captchaAnswer;
 
+    @ApiModelProperty(value = "客户端IP地址", hidden = true)
+    private String clientIP;
+
 }

+ 0 - 2
src/main/java/cc/uncarbon/module/sys/model/response/SysDataDictBO.java

@@ -2,7 +2,6 @@ package cc.uncarbon.module.sys.model.response;
 
 import cc.uncarbon.framework.core.constant.HelioConstant;
 import com.fasterxml.jackson.annotation.JsonFormat;
-import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
@@ -20,7 +19,6 @@ import java.time.LocalDateTime;
  *
  * @author Uncarbon
  */
-@ApiModel(value = "数据字典")
 @Accessors(chain = true)
 @Builder
 @AllArgsConstructor

+ 0 - 6
src/main/java/cc/uncarbon/module/sys/model/response/SysDeptBO.java

@@ -3,7 +3,6 @@ package cc.uncarbon.module.sys.model.response;
 import cc.uncarbon.framework.core.constant.HelioConstant;
 import cc.uncarbon.module.sys.enums.GenericStatusEnum;
 import com.fasterxml.jackson.annotation.JsonFormat;
-import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
@@ -14,14 +13,12 @@ import org.springframework.format.annotation.DateTimeFormat;
 
 import java.io.Serializable;
 import java.time.LocalDateTime;
-import java.util.List;
 
 
 /**
  * 部门BO
  * @author Uncarbon
  */
-@ApiModel(value = "部门")
 @Accessors(chain = true)
 @Builder
 @AllArgsConstructor
@@ -54,7 +51,4 @@ public class SysDeptBO implements Serializable {
     @ApiModelProperty(value = "状态")
     private GenericStatusEnum status;
 
-    @ApiModelProperty(value = "子项数据")
-    private List<SysDeptBO> children;
-
 }

+ 0 - 2
src/main/java/cc/uncarbon/module/sys/model/response/SysLogBO.java

@@ -3,7 +3,6 @@ package cc.uncarbon.module.sys.model.response;
 import cc.uncarbon.framework.core.constant.HelioConstant;
 import cc.uncarbon.module.sys.enums.SysLogStatusEnum;
 import com.fasterxml.jackson.annotation.JsonFormat;
-import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
@@ -20,7 +19,6 @@ import java.time.LocalDateTime;
  * 后台操作日志BO
  * @author Uncarbon
  */
-@ApiModel(value = "后台操作日志")
 @Accessors(chain = true)
 @Builder
 @AllArgsConstructor

+ 3 - 4
src/main/java/cc/uncarbon/module/sys/model/response/SysMenuBO.java

@@ -4,10 +4,7 @@ import cc.uncarbon.framework.core.constant.HelioConstant;
 import cc.uncarbon.module.sys.enums.GenericStatusEnum;
 import cc.uncarbon.module.sys.enums.SysMenuTypeEnum;
 import com.fasterxml.jackson.annotation.JsonFormat;
-import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
-import java.io.Serializable;
-import java.time.LocalDateTime;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Data;
@@ -15,12 +12,14 @@ import lombok.NoArgsConstructor;
 import lombok.experimental.Accessors;
 import org.springframework.format.annotation.DateTimeFormat;
 
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
 
 /**
  * 后台菜单BO
  * @author Uncarbon
  */
-@ApiModel(value = "后台菜单")
 @Accessors(chain = true)
 @Builder
 @AllArgsConstructor

+ 0 - 2
src/main/java/cc/uncarbon/module/sys/model/response/SysParamBO.java

@@ -2,7 +2,6 @@ package cc.uncarbon.module.sys.model.response;
 
 import cc.uncarbon.framework.core.constant.HelioConstant;
 import com.fasterxml.jackson.annotation.JsonFormat;
-import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
@@ -19,7 +18,6 @@ import java.time.LocalDateTime;
  * 系统参数BO
  * @author Uncarbon
  */
-@ApiModel(value = "系统参数")
 @Accessors(chain = true)
 @Builder
 @AllArgsConstructor

+ 0 - 2
src/main/java/cc/uncarbon/module/sys/model/response/SysRoleBO.java

@@ -2,7 +2,6 @@ package cc.uncarbon.module.sys.model.response;
 
 import cc.uncarbon.framework.core.constant.HelioConstant;
 import com.fasterxml.jackson.annotation.JsonFormat;
-import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
@@ -20,7 +19,6 @@ import java.util.Collection;
  * 后台角色BO
  * @author Uncarbon
  */
-@ApiModel(value = "后台角色")
 @Accessors(chain = true)
 @Builder
 @AllArgsConstructor

+ 0 - 2
src/main/java/cc/uncarbon/module/sys/model/response/SysTenantBO.java

@@ -3,7 +3,6 @@ package cc.uncarbon.module.sys.model.response;
 import cc.uncarbon.framework.core.constant.HelioConstant;
 import cc.uncarbon.module.sys.enums.GenericStatusEnum;
 import com.fasterxml.jackson.annotation.JsonFormat;
-import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
@@ -20,7 +19,6 @@ import java.time.LocalDateTime;
  * 系统租户BO
  * @author Uncarbon
  */
-@ApiModel(value = "系统租户")
 @Accessors(chain = true)
 @Builder
 @AllArgsConstructor

+ 3 - 4
src/main/java/cc/uncarbon/module/sys/model/response/SysUserBO.java

@@ -4,10 +4,7 @@ import cc.uncarbon.framework.core.constant.HelioConstant;
 import cc.uncarbon.module.sys.enums.GenderEnum;
 import cc.uncarbon.module.sys.enums.SysUserStatusEnum;
 import com.fasterxml.jackson.annotation.JsonFormat;
-import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
-import java.io.Serializable;
-import java.time.LocalDateTime;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Data;
@@ -15,12 +12,14 @@ import lombok.NoArgsConstructor;
 import lombok.experimental.Accessors;
 import org.springframework.format.annotation.DateTimeFormat;
 
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
 
 /**
  * 后台用户BO
  * @author Uncarbon
  */
-@ApiModel(value = "后台用户")
 @Accessors(chain = true)
 @Builder
 @AllArgsConstructor

+ 0 - 2
src/main/java/cc/uncarbon/module/sys/model/response/SysUserBaseInfoBO.java

@@ -2,7 +2,6 @@ package cc.uncarbon.module.sys.model.response;
 
 import cc.uncarbon.module.sys.enums.GenderEnum;
 import cc.uncarbon.module.sys.enums.SysUserStatusEnum;
-import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
@@ -18,7 +17,6 @@ import java.io.Serializable;
  * 仅保留基本信息
  * @author Uncarbon
  */
-@ApiModel(value = "后台用户基本信息")
 @Accessors(chain = true)
 @Builder
 @AllArgsConstructor

+ 0 - 2
src/main/java/cc/uncarbon/module/sys/model/response/VbenAdminMenuMetaVO.java

@@ -1,6 +1,5 @@
 package cc.uncarbon.module.sys.model.response;
 
-import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
@@ -15,7 +14,6 @@ import java.io.Serializable;
  * 后台菜单子项详情 for VbenAdmin
  * @author Uncarbon
  */
-@ApiModel(value = "后台菜单子项详情")
 @Accessors(chain = true)
 @Builder
 @AllArgsConstructor

+ 0 - 2
src/main/java/cc/uncarbon/module/sys/model/response/VbenAdminUserInfoVO.java

@@ -1,6 +1,5 @@
 package cc.uncarbon.module.sys.model.response;
 
-import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
@@ -16,7 +15,6 @@ import java.time.LocalDateTime;
  * 后台用户 for VbenAdmin
  * @author Uncarbon
  */
-@ApiModel(value = "后台用户")
 @Accessors(chain = true)
 @Builder
 @AllArgsConstructor

+ 7 - 5
src/main/java/cc/uncarbon/module/sys/service/SysDataDictService.java

@@ -12,6 +12,7 @@ import cc.uncarbon.module.sys.mapper.SysDataDictMapper;
 import cc.uncarbon.module.sys.model.request.AdminInsertOrUpdateSysDataDictDTO;
 import cc.uncarbon.module.sys.model.request.AdminListSysDataDictDTO;
 import cc.uncarbon.module.sys.model.response.SysDataDictBO;
+import cc.uncarbon.module.sys.model.response.SysParamBO;
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.StrUtil;
@@ -175,11 +176,12 @@ public class SysDataDictService extends HelioBaseServiceImpl<SysDataDictMapper,
      * @return BO 分页
      */
     private PageResult<SysDataDictBO> entityPage2BOPage(Page<SysDataDictEntity> entityPage) {
-        PageResult<SysDataDictBO> ret = new PageResult<>();
-        BeanUtil.copyProperties(entityPage, ret);
-        ret.setRecords(this.entityList2BOs(entityPage.getRecords()));
-
-        return ret;
+        return new PageResult<SysDataDictBO>()
+                .setCurrent(entityPage.getCurrent())
+                .setSize(entityPage.getSize())
+                .setTotal(entityPage.getTotal())
+                .setRecords(this.entityList2BOs(entityPage.getRecords()))
+                ;
     }
 
     /**

+ 10 - 39
src/main/java/cc/uncarbon/module/sys/service/SysDeptService.java

@@ -10,22 +10,21 @@ import cc.uncarbon.module.sys.entity.SysUserDeptRelationEntity;
 import cc.uncarbon.module.sys.enums.SysErrorEnum;
 import cc.uncarbon.module.sys.mapper.SysDeptMapper;
 import cc.uncarbon.module.sys.model.request.AdminInsertOrUpdateSysDeptDTO;
-import cc.uncarbon.module.sys.model.request.AdminListSysDeptDTO;
 import cc.uncarbon.module.sys.model.response.SysDeptBO;
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.ObjectUtil;
-import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
 
 /**
  * 部门
@@ -43,15 +42,10 @@ public class SysDeptService extends HelioBaseServiceImpl<SysDeptMapper, SysDeptE
     /**
      * 后台管理-列表
      */
-    public List<SysDeptBO> adminList(AdminListSysDeptDTO dto) {
+    public List<SysDeptBO> adminList() {
         List<SysDeptEntity> entityList = this.list(
                 new QueryWrapper<SysDeptEntity>()
                         .lambda()
-                        // 名称
-                        .like(StrUtil.isNotBlank(dto.getTitle()), SysDeptEntity::getTitle,
-                                StrUtil.cleanBlank(dto.getTitle()))
-                        // 上级ID
-                        .eq(ObjectUtil.isNotNull(dto.getParentId()), SysDeptEntity::getParentId, dto.getParentId())
                         // 排序
                         .orderByAsc(SysDeptEntity::getSort)
         );
@@ -95,7 +89,7 @@ public class SysDeptService extends HelioBaseServiceImpl<SysDeptMapper, SysDeptE
         this.checkExistence(dto);
 
         if (ObjectUtil.isNull(dto.getParentId())) {
-            dto.setParentId(0L);
+            dto.setParentId(SysConstant.ROOT_PARENT_ID);
         }
 
         dto.setId(null);
@@ -117,7 +111,7 @@ public class SysDeptService extends HelioBaseServiceImpl<SysDeptMapper, SysDeptE
         this.checkExistence(dto);
 
         if (ObjectUtil.isNull(dto.getParentId())) {
-            dto.setParentId(0L);
+            dto.setParentId(SysConstant.ROOT_PARENT_ID);
         }
 
         SysDeptEntity entity = new SysDeptEntity();
@@ -180,6 +174,7 @@ public class SysDeptService extends HelioBaseServiceImpl<SysDeptMapper, SysDeptE
 
         // 可以在此处为BO填充字段
         if (SysConstant.ROOT_PARENT_ID.equals(bo.getParentId())) {
+            // 返回前端时,不显示 parentId = 0
             bo.setParentId(null);
         }
 
@@ -200,10 +195,7 @@ public class SysDeptService extends HelioBaseServiceImpl<SysDeptMapper, SysDeptE
         // 深拷贝
         List<SysDeptBO> ret = new ArrayList<>(entityList.size());
         entityList.forEach(
-                entity -> {
-                    SysDeptBO bo = this.entity2BO(entity);
-                    ret.add(this.traverseChildren(bo));
-                }
+                entity -> ret.add(this.entity2BO(entity))
         );
 
         return ret;
@@ -229,25 +221,4 @@ public class SysDeptService extends HelioBaseServiceImpl<SysDeptMapper, SysDeptE
             throw new BusinessException(400, "已存在相同部门,请重新输入");
         }
     }
-
-    /**
-     * 递归遍历子级
-     *
-     * @param bo BO
-     * @return SysDeptBO
-     */
-    private SysDeptBO traverseChildren(SysDeptBO bo) {
-        List<SysDeptBO> children = this.adminList(
-                AdminListSysDeptDTO.builder()
-                        .parentId(bo.getId())
-                        .build()
-        );
-        if (CollUtil.isEmpty(children)) {
-            children = null;
-        }
-
-        bo.setChildren(children);
-
-        return bo;
-    }
 }

+ 12 - 8
src/main/java/cc/uncarbon/module/sys/service/SysLogService.java

@@ -15,13 +15,14 @@ import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
 
 /**
  * 后台操作日志
@@ -40,6 +41,8 @@ public class SysLogService extends HelioBaseServiceImpl<SysLogMapper, SysLogEnti
                 new Page<>(pageParam.getPageNum(), pageParam.getPageSize()),
                 new QueryWrapper<SysLogEntity>()
                         .lambda()
+                        // 仅返回给前端少量字段
+                        .select(SysLogEntity::getCreatedAt, SysLogEntity::getUsername, SysLogEntity::getOperation, SysLogEntity::getIp, SysLogEntity::getStatus)
                         // 用户账号
                         .like(StrUtil.isNotBlank(dto.getUsername()), SysLogEntity::getUsername, StrUtil.cleanBlank(dto.getUsername()))
                         // 操作内容
@@ -133,11 +136,12 @@ public class SysLogService extends HelioBaseServiceImpl<SysLogMapper, SysLogEnti
      * @return BO 分页
      */
     private PageResult<SysLogBO> entityPage2BOPage(Page<SysLogEntity> entityPage) {
-        PageResult<SysLogBO> ret = new PageResult<>();
-        BeanUtil.copyProperties(entityPage, ret);
-        ret.setRecords(this.entityList2BOs(entityPage.getRecords()));
-
-        return ret;
+        return new PageResult<SysLogBO>()
+                .setCurrent(entityPage.getCurrent())
+                .setSize(entityPage.getSize())
+                .setTotal(entityPage.getTotal())
+                .setRecords(this.entityList2BOs(entityPage.getRecords()))
+                ;
     }
 
 }

+ 15 - 38
src/main/java/cc/uncarbon/module/sys/service/SysMenuService.java

@@ -3,6 +3,7 @@ package cc.uncarbon.module.sys.service;
 import cc.uncarbon.framework.core.constant.HelioConstant;
 import cc.uncarbon.framework.core.context.UserContextHolder;
 import cc.uncarbon.framework.core.exception.BusinessException;
+import cc.uncarbon.framework.core.function.StreamFunction;
 import cc.uncarbon.framework.crud.service.impl.HelioBaseServiceImpl;
 import cc.uncarbon.module.sys.annotation.SysLog;
 import cc.uncarbon.module.sys.constant.SysConstant;
@@ -12,7 +13,6 @@ import cc.uncarbon.module.sys.enums.SysErrorEnum;
 import cc.uncarbon.module.sys.enums.SysMenuTypeEnum;
 import cc.uncarbon.module.sys.mapper.SysMenuMapper;
 import cc.uncarbon.module.sys.model.request.AdminInsertOrUpdateSysMenuDTO;
-import cc.uncarbon.module.sys.model.request.AdminListSysMenuDTO;
 import cc.uncarbon.module.sys.model.response.SysMenuBO;
 import cc.uncarbon.module.sys.model.response.VbenAdminMenuMetaVO;
 import cn.hutool.core.bean.BeanUtil;
@@ -23,22 +23,14 @@ import cn.hutool.core.util.IdUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-import java.util.function.BinaryOperator;
-import java.util.stream.Collectors;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.util.*;
+import java.util.stream.Collectors;
+
 
 /**
  * 后台菜单
@@ -58,7 +50,7 @@ public class SysMenuService extends HelioBaseServiceImpl<SysMenuMapper, SysMenuE
     /**
      * 后台管理-列表
      */
-    public List<SysMenuBO> adminList(AdminListSysMenuDTO dto) {
+    public List<SysMenuBO> adminList() {
         List<SysMenuEntity> entityList = this.list(
                 new QueryWrapper<SysMenuEntity>()
                         .lambda()
@@ -153,9 +145,9 @@ public class SysMenuService extends HelioBaseServiceImpl<SysMenuMapper, SysMenuE
      * 后台管理-取侧边菜单
      */
     public List<SysMenuBO> adminListSideMenu() {
-        Set<Long> visibleMenuIds = this.listCurrentUserVisibleMenuId();
+        Set<Long> visibleMenuIds = this.listCurrentUserVisibleMenuIds();
 
-        List<SysMenuTypeEnum> requiredMenuTypes = CollUtil.newArrayList(SysMenuTypeEnum.DIR, SysMenuTypeEnum.MENU,
+        List<SysMenuTypeEnum> requiredMenuTypes = Arrays.asList(SysMenuTypeEnum.DIR, SysMenuTypeEnum.MENU,
                 SysMenuTypeEnum.EXTERNAL_LINK);
         return this.listByIds(visibleMenuIds, requiredMenuTypes);
     }
@@ -164,9 +156,9 @@ public class SysMenuService extends HelioBaseServiceImpl<SysMenuMapper, SysMenuE
      * 后台管理-取所有可见菜单 包括按钮类型
      */
     public List<SysMenuBO> adminListVisibleMenu() {
-        Set<Long> visibleMenuIds = this.listCurrentUserVisibleMenuId();
+        Set<Long> visibleMenuIds = this.listCurrentUserVisibleMenuIds();
 
-        List<SysMenuTypeEnum> requiredMenuTypes = CollUtil.newArrayList(SysMenuTypeEnum.DIR, SysMenuTypeEnum.MENU,
+        List<SysMenuTypeEnum> requiredMenuTypes = Arrays.asList(SysMenuTypeEnum.DIR, SysMenuTypeEnum.MENU,
                 SysMenuTypeEnum.EXTERNAL_LINK, SysMenuTypeEnum.BUTTON);
         return this.listByIds(visibleMenuIds, requiredMenuTypes);
     }
@@ -197,7 +189,7 @@ public class SysMenuService extends HelioBaseServiceImpl<SysMenuMapper, SysMenuE
                     } else {
                         // 非超级管理员则通过角色ID,关联查询拥有的菜单,菜单上有权限名
 
-                        Set<Long> menuIds = sysRoleMenuRelationService.listMenuIdByRoleId(roleId);
+                        Set<Long> menuIds = sysRoleMenuRelationService.listMenuIdsByRoleIds(Collections.singleton(roleId));
                         if (CollUtil.isEmpty(menuIds)) {
                             permissions = Collections.emptySet();
                         } else {
@@ -225,7 +217,7 @@ public class SysMenuService extends HelioBaseServiceImpl<SysMenuMapper, SysMenuE
     /**
      * 根据菜单ID集合,取权限名集合
      */
-    public Set<String> listPermissionByMenuIds(Collection<Long> menuIds) {
+    public Set<String> listPermissionsByMenuIds(Collection<Long> menuIds) {
         if (CollUtil.isEmpty(menuIds)) {
             return Collections.emptySet();
         }
@@ -325,7 +317,7 @@ public class SysMenuService extends HelioBaseServiceImpl<SysMenuMapper, SysMenuE
      *
      * @return 菜单Ids
      */
-    private Set<Long> listCurrentUserVisibleMenuId() {
+    private Set<Long> listCurrentUserVisibleMenuIds() {
         // 1. 取当前账号拥有角色Ids
         Set<Long> roleIds = UserContextHolder.getUserContext().getRolesIds();
         SysErrorEnum.NO_ROLE_AVAILABLE_FOR_CURRENT_USER.assertNotEmpty(roleIds);
@@ -336,7 +328,7 @@ public class SysMenuService extends HelioBaseServiceImpl<SysMenuMapper, SysMenuE
                         .lambda()
                         .select(SysMenuEntity::getId, SysMenuEntity::getParentId)
                         .eq(SysMenuEntity::getStatus, GenericStatusEnum.ENABLED)
-        ).stream().collect(Collectors.toMap(SysMenuEntity::getId, SysMenuEntity::getParentId, ignoredThrowingMerger()));
+        ).stream().collect(Collectors.toMap(SysMenuEntity::getId, SysMenuEntity::getParentId, StreamFunction.ignoredThrowingMerger()));
 
         // 3. 超级管理员直接返回所有菜单
         if (roleIds.contains(SysConstant.SUPER_ADMIN_ROLE_ID)) {
@@ -344,7 +336,7 @@ public class SysMenuService extends HelioBaseServiceImpl<SysMenuMapper, SysMenuE
         }
 
         // 4. 根据现有角色,获取直接关联的菜单ID
-        Set<Long> directlyRelatedMenuIds = sysRoleMenuRelationService.listMenuIdByRoleIds(roleIds);
+        Set<Long> directlyRelatedMenuIds = sysRoleMenuRelationService.listMenuIdsByRoleIds(roleIds);
         SysErrorEnum.NO_MENU_AVAILABLE_FOR_CURRENT_ROLE.assertNotEmpty(directlyRelatedMenuIds);
 
         // 5. 因为直接关联的菜单ID,可能不包含父级菜单,使得级联关系缺失,这里得给他补上
@@ -373,12 +365,7 @@ public class SysMenuService extends HelioBaseServiceImpl<SysMenuMapper, SysMenuE
             return Collections.emptyList();
         }
 
-        List<SysMenuBO> ret = new ArrayList<>(entityList.size());
-        entityList.forEach(
-                each -> ret.add(this.entity2BO(each))
-        );
-
-        return ret;
+        return this.entityList2BOs(entityList);
     }
 
     /**
@@ -443,14 +430,4 @@ public class SysMenuService extends HelioBaseServiceImpl<SysMenuMapper, SysMenuE
 
         return ret;
     }
-
-    /**
-     * 原来键冲突会报错,使用自定义函数来无视
-     *
-     * @param <T> 键类型
-     * @return 键
-     */
-    private static <T> BinaryOperator<T> ignoredThrowingMerger() {
-        return (u, v) -> u;
-    }
 }

+ 6 - 5
src/main/java/cc/uncarbon/module/sys/service/SysParamService.java

@@ -213,11 +213,12 @@ public class SysParamService extends HelioBaseServiceImpl<SysParamMapper, SysPar
      * @return BO 分页
      */
     private PageResult<SysParamBO> entityPage2BOPage(Page<SysParamEntity> entityPage) {
-        PageResult<SysParamBO> ret = new PageResult<>();
-        BeanUtil.copyProperties(entityPage, ret);
-        ret.setRecords(this.entityList2BOs(entityPage.getRecords()));
-
-        return ret;
+        return new PageResult<SysParamBO>()
+                .setCurrent(entityPage.getCurrent())
+                .setSize(entityPage.getSize())
+                .setTotal(entityPage.getTotal())
+                .setRecords(this.entityList2BOs(entityPage.getRecords()))
+                ;
     }
 
     /**

+ 21 - 43
src/main/java/cc/uncarbon/module/sys/service/SysRoleMenuRelationService.java

@@ -6,19 +6,14 @@ import cc.uncarbon.module.sys.mapper.SysRoleMenuRelationMapper;
 import cn.hutool.core.collection.CollUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Objects;
-import java.util.Set;
-import java.util.stream.Collectors;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.util.*;
+import java.util.stream.Collectors;
+
 
 /**
  * 后台角色-可见菜单关联
@@ -37,21 +32,22 @@ public class SysRoleMenuRelationService extends HelioBaseServiceImpl<SysRoleMenu
      * @param roleIds 角色Ids
      * @return 菜单Ids
      */
-    public Set<Long> listMenuIdByRoleIds(Collection<Long> roleIds) throws IllegalArgumentException {
+    public Set<Long> listMenuIdsByRoleIds(Collection<Long> roleIds) throws IllegalArgumentException {
         if (CollUtil.isEmpty(roleIds)) {
             throw new IllegalArgumentException("roleIds不能为空");
         }
 
         // aka * 16
         Set<Long> ret = new HashSet<>(roleIds.size() << 4);
-        roleIds.forEach(
-                roleId -> ret.addAll(this.list(
+        for (Long roleId : roleIds) {
+            ret.addAll(
+                    this.list(
                             new QueryWrapper<SysRoleMenuRelationEntity>()
                                     .lambda()
                                     .select(SysRoleMenuRelationEntity::getMenuId)
                                     .eq(SysRoleMenuRelationEntity::getRoleId, roleId)
-                    ).stream().map(SysRoleMenuRelationEntity::getMenuId).collect(Collectors.toSet()))
-        );
+                    ).stream().map(SysRoleMenuRelationEntity::getMenuId).collect(Collectors.toSet()));
+        }
 
         return ret;
     }
@@ -59,7 +55,7 @@ public class SysRoleMenuRelationService extends HelioBaseServiceImpl<SysRoleMenu
     /**
      * 绑定角色ID与菜单ID关联关系,增量更新
      *
-     * @param roleId 角色ID
+     * @param roleId  角色ID
      * @param menuIds 新菜单ID集合
      */
     @Transactional(rollbackFor = Exception.class)
@@ -91,43 +87,25 @@ public class SysRoleMenuRelationService extends HelioBaseServiceImpl<SysRoleMenu
          */
         Set<Long> existingMenuIds = this.list(menuIdsQuery).stream().map(SysRoleMenuRelationEntity::getMenuId)
                 .collect(Collectors.toSet());
-
         menuIds.removeAll(existingMenuIds);
 
+        if (CollUtil.isEmpty(menuIds)) {
+            // 没有需要增量更新的部分
+            return;
+        }
+
         /*
-        构造 && 批量插入
+        批量插入需要增量更新的部分
          */
-        if (!menuIds.isEmpty()) {
-            List<SysRoleMenuRelationEntity> entityList = new ArrayList<>();
-            menuIds.forEach(
-                    menuId -> entityList.add(SysRoleMenuRelationEntity.builder()
+        List<SysRoleMenuRelationEntity> entityList = new ArrayList<>(menuIds.size());
+        for (Long menuId : menuIds) {
+            entityList.add(
+                    SysRoleMenuRelationEntity.builder()
                             .roleId(roleId)
                             .menuId(menuId)
                             .build()
-                    )
             );
-
-            this.saveBatch(entityList);
         }
-    }
-
-    /**
-     * 根据角色Ids取菜单Ids
-     * 因为多种角色容易出现交集,所以干脆用 Set
-     *
-     * @param roleId 角色Id
-     * @return 菜单Ids
-     */
-    public Set<Long> listMenuIdByRoleId(Long roleId) {
-        if (Objects.isNull(roleId)) {
-           return Collections.emptySet();
-        }
-
-        return this.list(
-                new QueryWrapper<SysRoleMenuRelationEntity>()
-                        .lambda()
-                        .select(SysRoleMenuRelationEntity::getMenuId)
-                        .eq(SysRoleMenuRelationEntity::getRoleId, roleId)
-        ).stream().map(SysRoleMenuRelationEntity::getMenuId).collect(Collectors.toSet());
+        this.saveBatch(entityList);
     }
 }

+ 14 - 27
src/main/java/cc/uncarbon/module/sys/service/SysRoleService.java

@@ -2,6 +2,7 @@ package cc.uncarbon.module.sys.service;
 
 import cc.uncarbon.framework.core.constant.HelioConstant;
 import cc.uncarbon.framework.core.exception.BusinessException;
+import cc.uncarbon.framework.core.function.StreamFunction;
 import cc.uncarbon.framework.core.page.PageParam;
 import cc.uncarbon.framework.core.page.PageResult;
 import cc.uncarbon.framework.crud.service.impl.HelioBaseServiceImpl;
@@ -15,23 +16,17 @@ import cc.uncarbon.module.sys.model.request.AdminListSysRoleDTO;
 import cc.uncarbon.module.sys.model.response.SysRoleBO;
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.function.BinaryOperator;
-import java.util.stream.Collectors;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.util.*;
+import java.util.stream.Collectors;
+
 
 /**
  * 后台角色
@@ -62,8 +57,6 @@ public class SysRoleService extends HelioBaseServiceImpl<SysRoleMapper, SysRoleE
                         .like(StrUtil.isNotBlank(dto.getTitle()), SysRoleEntity::getTitle, StrUtil.cleanBlank(dto.getTitle()))
                         // 值
                         .like(StrUtil.isNotBlank(dto.getValue()), SysRoleEntity::getValue, StrUtil.cleanBlank(dto.getValue()))
-                        // 时间区间
-                        .between(ObjectUtil.isNotNull(dto.getBeginAt()) && ObjectUtil.isNotNull(dto.getEndAt()), SysRoleEntity::getCreatedAt, dto.getBeginAt(), dto.getEndAt())
                         // 排序
                         .orderByDesc(SysRoleEntity::getCreatedAt)
         );
@@ -148,7 +141,7 @@ public class SysRoleService extends HelioBaseServiceImpl<SysRoleMapper, SysRoleE
      * @return 新菜单ID集合对应的权限名
      */
     public Set<String> adminBindMenus(AdminBindRoleMenuRelationDTO dto) {
-        Set<String> newPermissions = sysMenuService.listPermissionByMenuIds(dto.getMenuIds());
+        Set<String> newPermissions = sysMenuService.listPermissionsByMenuIds(dto.getMenuIds());
         sysRoleMenuRelationService.cleanAndBind(dto.getRoleId(), dto.getMenuIds());
 
         return newPermissions;
@@ -176,7 +169,7 @@ public class SysRoleService extends HelioBaseServiceImpl<SysRoleMapper, SysRoleE
         BeanUtil.copyProperties(entity, bo);
 
         // 可以在此处为BO填充字段
-        bo.setMenuIds(sysRoleMenuRelationService.listMenuIdByRoleIds(CollUtil.newHashSet(bo.getId())));
+        bo.setMenuIds(sysRoleMenuRelationService.listMenuIdsByRoleIds(Collections.singleton(bo.getId())));
         return bo;
     }
 
@@ -203,11 +196,12 @@ public class SysRoleService extends HelioBaseServiceImpl<SysRoleMapper, SysRoleE
      * @return BO 分页
      */
     private PageResult<SysRoleBO> entityPage2BOPage(Page<SysRoleEntity> entityPage) {
-        PageResult<SysRoleBO> ret = new PageResult<>();
-        BeanUtil.copyProperties(entityPage, ret);
-        ret.setRecords(this.entityList2BOs(entityPage.getRecords()));
-
-        return ret;
+        return new PageResult<SysRoleBO>()
+                .setCurrent(entityPage.getCurrent())
+                .setSize(entityPage.getSize())
+                .setTotal(entityPage.getTotal())
+                .setRecords(this.entityList2BOs(entityPage.getRecords()))
+                ;
     }
 
     /**
@@ -238,7 +232,7 @@ public class SysRoleService extends HelioBaseServiceImpl<SysRoleMapper, SysRoleE
      * @return 失败返回空 map
      */
     public Map<Long, String> getRoleMapByUserId(Long userId) {
-        Set<Long> roleIds = sysUserRoleRelationService.listRoleIdByUserId(userId);
+        Set<Long> roleIds = sysUserRoleRelationService.listRoleIdsByUserId(userId);
 
         if (CollUtil.isEmpty(roleIds)) {
             return Collections.emptyMap();
@@ -250,13 +244,6 @@ public class SysRoleService extends HelioBaseServiceImpl<SysRoleMapper, SysRoleE
                         .lambda()
                         .select(SysRoleEntity::getId, SysRoleEntity::getValue)
                         .in(SysRoleEntity::getId, roleIds)
-        ).stream().collect(Collectors.toMap(SysRoleEntity::getId, SysRoleEntity::getValue, this.ignoredThrowingMerger()));
-    }
-
-    /**
-     * 主动忽略 map key 重复错误,不然 key 重复的话,转换成 map 的过程会抛异常
-     */
-    private <T> BinaryOperator<T> ignoredThrowingMerger() {
-        return (u, v) -> u;
+        ).stream().collect(Collectors.toMap(SysRoleEntity::getId, SysRoleEntity::getValue, StreamFunction.ignoredThrowingMerger()));
     }
 }

+ 10 - 10
src/main/java/cc/uncarbon/module/sys/service/SysTenantService.java

@@ -18,14 +18,15 @@ import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
 
 /**
  * 系统租户
@@ -53,8 +54,6 @@ public class SysTenantService extends HelioBaseServiceImpl<SysTenantMapper, SysT
                         .eq(ObjectUtil.isNotNull(dto.getTenantId()), SysTenantEntity::getTenantId, dto.getTenantId())
                         // 状态
                         .eq(ObjectUtil.isNotNull(dto.getStatus()), SysTenantEntity::getStatus, dto.getStatus())
-                        // 时间区间
-                        .between(ObjectUtil.isNotNull(dto.getBeginAt()) && ObjectUtil.isNotNull(dto.getEndAt()), SysTenantEntity::getCreatedAt, dto.getBeginAt(), dto.getEndAt())
                         // 排序
                         .orderByDesc(SysTenantEntity::getCreatedAt)
         );
@@ -202,11 +201,12 @@ public class SysTenantService extends HelioBaseServiceImpl<SysTenantMapper, SysT
      * @return BO 分页
      */
     private PageResult<SysTenantBO> entityPage2BOPage(Page<SysTenantEntity> entityPage) {
-        PageResult<SysTenantBO> ret = new PageResult<>();
-        BeanUtil.copyProperties(entityPage, ret);
-        ret.setRecords(this.entityList2BOs(entityPage.getRecords()));
-
-        return ret;
+        return new PageResult<SysTenantBO>()
+                .setCurrent(entityPage.getCurrent())
+                .setSize(entityPage.getSize())
+                .setTotal(entityPage.getTotal())
+                .setRecords(this.entityList2BOs(entityPage.getRecords()))
+                ;
     }
 
 }

+ 5 - 4
src/main/java/cc/uncarbon/module/sys/service/SysUserRoleRelationService.java

@@ -5,13 +5,14 @@ import cc.uncarbon.module.sys.entity.SysUserRoleRelationEntity;
 import cc.uncarbon.module.sys.mapper.SysUserRoleRelationMapper;
 import cn.hutool.core.collection.CollUtil;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
-import java.util.Collection;
-import java.util.Set;
-import java.util.stream.Collectors;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.util.Collection;
+import java.util.Set;
+import java.util.stream.Collectors;
+
 
 /**
  * 后台用户-角色关联
@@ -50,7 +51,7 @@ public class SysUserRoleRelationService extends HelioBaseServiceImpl<SysUserRole
      * @param userId 用户ID
      * @return 失败返回空列表
      */
-    public Set<Long> listRoleIdByUserId(Long userId) throws IllegalArgumentException {
+    public Set<Long> listRoleIdsByUserId(Long userId) throws IllegalArgumentException {
         if (userId == null) {
             throw new IllegalArgumentException("userId不能为空");
         }

+ 31 - 14
src/main/java/cc/uncarbon/module/sys/service/SysUserService.java

@@ -9,6 +9,7 @@ import cc.uncarbon.framework.core.page.PageResult;
 import cc.uncarbon.framework.core.props.HelioProperties;
 import cc.uncarbon.framework.crud.service.impl.HelioBaseServiceImpl;
 import cc.uncarbon.module.sys.annotation.SysLog;
+import cc.uncarbon.module.sys.constant.SysConstant;
 import cc.uncarbon.module.sys.entity.SysTenantEntity;
 import cc.uncarbon.module.sys.entity.SysUserEntity;
 import cc.uncarbon.module.sys.enums.GenericStatusEnum;
@@ -16,7 +17,10 @@ import cc.uncarbon.module.sys.enums.SysErrorEnum;
 import cc.uncarbon.module.sys.enums.SysUserStatusEnum;
 import cc.uncarbon.module.sys.mapper.SysUserMapper;
 import cc.uncarbon.module.sys.model.request.*;
-import cc.uncarbon.module.sys.model.response.*;
+import cc.uncarbon.module.sys.model.response.SysDeptBO;
+import cc.uncarbon.module.sys.model.response.SysUserBO;
+import cc.uncarbon.module.sys.model.response.SysUserLoginBO;
+import cc.uncarbon.module.sys.model.response.VbenAdminUserInfoVO;
 import cc.uncarbon.module.sys.util.PwdUtil;
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.collection.CollUtil;
@@ -150,6 +154,8 @@ public class SysUserService extends HelioBaseServiceImpl<SysUserMapper, SysUserE
 
         SysUserEntity updateEntity = new SysUserEntity();
         BeanUtil.copyProperties(dto, updateEntity);
+        // 手动处理异名字段
+        updateEntity.setPin(dto.getUsername());
 
         sysUserDeptRelationService.cleanAndBind(dto.getId(), dto.getDeptId());
 
@@ -169,7 +175,7 @@ public class SysUserService extends HelioBaseServiceImpl<SysUserMapper, SysUserE
     /**
      * 后台管理-登录
      */
-    @SysLog(value = "登录后台用户")
+    @SysLog(value = SysConstant.SysLogOperation.SYS_USER_LOGIN)
     public SysUserLoginBO adminLogin(SysUserLoginDTO dto) {
         /*
         如果启用了多租户功能,并且前端指定了租户ID,则先查库确认租户是否有效
@@ -194,7 +200,7 @@ public class SysUserService extends HelioBaseServiceImpl<SysUserMapper, SysUserE
             throw new BusinessException(SysErrorEnum.INCORRECT_PIN_OR_PWD);
         }
 
-        if (SysUserStatusEnum.BANNED.equals(sysUserEntity.getStatus())) {
+        if (SysUserStatusEnum.BANNED == sysUserEntity.getStatus()) {
             throw new BusinessException(SysErrorEnum.BANNED_USER);
         }
 
@@ -209,11 +215,7 @@ public class SysUserService extends HelioBaseServiceImpl<SysUserMapper, SysUserE
             TenantContextHolder.setTenantContext(tenantContext);
         }
 
-        try {
-            this.updateLastLoginAt(sysUserEntity.getId(), LocalDateTimeUtil.now());
-        } catch (Exception ignored) {
-            // 实际开发环境请删除本try-catch块
-        }
+        this.updateLastLoginAt(sysUserEntity.getId(), LocalDateTimeUtil.now());
 
         // 取账号完整信息
         SysUserBO sysUserBO = this.entity2BO(sysUserEntity);
@@ -300,6 +302,19 @@ public class SysUserService extends HelioBaseServiceImpl<SysUserMapper, SysUserE
         return this.getBaseMapper().getUserByPin(pin);
     }
 
+    /**
+     * 后台管理 - 取指定用户关联角色ID
+     * @param userId 用户ID
+     * @return 角色Ids
+     */
+    public Set<Long> listRelatedRoleIds(Long userId) {
+        if (ObjectUtil.isNull(userId)) {
+            return Collections.emptySet();
+        }
+
+        return sysRoleService.getRoleMapByUserId(userId).keySet();
+    }
+
     /*
     ----------------------------------------------------------------
                         私有方法 private methods
@@ -321,6 +336,7 @@ public class SysUserService extends HelioBaseServiceImpl<SysUserMapper, SysUserE
         BeanUtil.copyProperties(entity, bo);
 
         // 可以在此处为BO填充字段
+        bo.setUsername(entity.getPin());
         SysDeptBO dept = sysDeptService.getPlainDeptByUserId(bo.getId());
         if (dept != null) {
             bo
@@ -359,11 +375,12 @@ public class SysUserService extends HelioBaseServiceImpl<SysUserMapper, SysUserE
      * @return BO 分页
      */
     private PageResult<SysUserBO> entityPage2BOPage(Page<SysUserEntity> entityPage) {
-        PageResult<SysUserBO> ret = new PageResult<>();
-        BeanUtil.copyProperties(entityPage, ret);
-        ret.setRecords(this.entityList2BOs(entityPage.getRecords()));
-
-        return ret;
+        return new PageResult<SysUserBO>()
+                .setCurrent(entityPage.getCurrent())
+                .setSize(entityPage.getSize())
+                .setTotal(entityPage.getTotal())
+                .setRecords(this.entityList2BOs(entityPage.getRecords()))
+                ;
     }
 
     /**
@@ -391,7 +408,7 @@ public class SysUserService extends HelioBaseServiceImpl<SysUserMapper, SysUserE
             throw new BusinessException(SysErrorEnum.INVALID_TENANT);
         }
 
-        if (GenericStatusEnum.DISABLED.equals(tenantEntity.getStatus())) {
+        if (GenericStatusEnum.DISABLED == tenantEntity.getStatus()) {
             throw new BusinessException(SysErrorEnum.DISABLED_TENANT);
         }
 

+ 11 - 9
src/main/java/cc/uncarbon/module/sys/web/auth/AdminAuthController.java

@@ -7,6 +7,7 @@ import cc.uncarbon.framework.core.context.TenantContextHolder;
 import cc.uncarbon.framework.core.context.UserContext;
 import cc.uncarbon.framework.core.context.UserContextHolder;
 import cc.uncarbon.framework.web.model.response.ApiResult;
+import cc.uncarbon.framework.web.util.IPUtil;
 import cc.uncarbon.helper.CaptchaHelper;
 import cc.uncarbon.helper.RolePermissionCacheHelper;
 import cc.uncarbon.module.sys.constant.SysConstant;
@@ -22,17 +23,15 @@ import cn.hutool.captcha.AbstractCaptcha;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiImplicitParam;
 import io.swagger.annotations.ApiOperation;
-import java.io.IOException;
-import javax.servlet.http.HttpServletResponse;
-import javax.validation.Valid;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.http.MediaType;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.Valid;
+import java.io.IOException;
 
 
 /**
@@ -54,7 +53,10 @@ public class AdminAuthController {
 
     @ApiOperation(value = "登录", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
     @PostMapping(value = "/login")
-    public ApiResult<SysUserLoginVO> login(@RequestBody @Valid SysUserLoginDTO dto) {
+    public ApiResult<SysUserLoginVO> login(HttpServletRequest request, @RequestBody @Valid SysUserLoginDTO dto) {
+        // 从请求中得到客户端IP地址
+        dto.setClientIP(IPUtil.getClientIPAddress(request));
+
         // RPC调用, 失败抛异常, 成功返回用户信息
         SysUserLoginBO userInfo = sysUserService.adminLogin(dto);
 

+ 2 - 3
src/main/java/cc/uncarbon/module/sys/web/sys/AdminSysDeptController.java

@@ -6,7 +6,6 @@ import cc.uncarbon.framework.web.model.request.IdsDTO;
 import cc.uncarbon.framework.web.model.response.ApiResult;
 import cc.uncarbon.module.sys.constant.SysConstant;
 import cc.uncarbon.module.sys.model.request.AdminInsertOrUpdateSysDeptDTO;
-import cc.uncarbon.module.sys.model.request.AdminListSysDeptDTO;
 import cc.uncarbon.module.sys.model.response.SysDeptBO;
 import cc.uncarbon.module.sys.service.SysDeptService;
 import cc.uncarbon.module.sys.util.AdminStpUtil;
@@ -41,8 +40,8 @@ public class AdminSysDeptController {
     @SaCheckPermission(type = AdminStpUtil.TYPE, value = PERMISSION_PREFIX + HelioConstant.Permission.RETRIEVE)
     @ApiOperation(value = "列表", produces = MediaType.APPLICATION_JSON_VALUE)
     @GetMapping
-    public ApiResult<List<SysDeptBO>> list(AdminListSysDeptDTO dto) {
-        return ApiResult.data(sysDeptService.adminList(dto));
+    public ApiResult<List<SysDeptBO>> list() {
+        return ApiResult.data(sysDeptService.adminList());
     }
 
     @SaCheckPermission(type = AdminStpUtil.TYPE, value = PERMISSION_PREFIX + HelioConstant.Permission.RETRIEVE)

+ 6 - 13
src/main/java/cc/uncarbon/module/sys/web/sys/AdminSysMenuController.java

@@ -5,7 +5,6 @@ import cc.uncarbon.framework.web.model.request.IdsDTO;
 import cc.uncarbon.framework.web.model.response.ApiResult;
 import cc.uncarbon.module.sys.constant.SysConstant;
 import cc.uncarbon.module.sys.model.request.AdminInsertOrUpdateSysMenuDTO;
-import cc.uncarbon.module.sys.model.request.AdminListSysMenuDTO;
 import cc.uncarbon.module.sys.model.response.SysMenuBO;
 import cc.uncarbon.module.sys.service.SysMenuService;
 import cc.uncarbon.module.sys.util.AdminStpUtil;
@@ -13,19 +12,13 @@ import cn.dev33.satoken.annotation.SaCheckLogin;
 import cn.dev33.satoken.annotation.SaCheckPermission;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
-import java.util.List;
-import javax.validation.Valid;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.http.MediaType;
-import org.springframework.web.bind.annotation.DeleteMapping;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.PutMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+import java.util.List;
 
 
 /**
@@ -47,8 +40,8 @@ public class AdminSysMenuController {
     @SaCheckPermission(type = AdminStpUtil.TYPE, value = PERMISSION_PREFIX + HelioConstant.Permission.RETRIEVE)
     @ApiOperation(value = "列表", produces = MediaType.APPLICATION_JSON_VALUE)
     @GetMapping
-    public ApiResult<List<SysMenuBO>> list(AdminListSysMenuDTO dto) {
-        return ApiResult.data(sysMenuService.adminList(dto));
+    public ApiResult<List<SysMenuBO>> list() {
+        return ApiResult.data(sysMenuService.adminList());
     }
 
     @SaCheckPermission(type = AdminStpUtil.TYPE, value = PERMISSION_PREFIX + HelioConstant.Permission.RETRIEVE)

+ 5 - 11
src/main/java/cc/uncarbon/module/sys/web/sys/AdminSysRoleController.java

@@ -17,19 +17,12 @@ import cn.dev33.satoken.annotation.SaCheckLogin;
 import cn.dev33.satoken.annotation.SaCheckPermission;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
-import javax.validation.Valid;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.http.MediaType;
-import org.springframework.web.bind.annotation.DeleteMapping;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.PutMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
 
+import javax.validation.Valid;
 import java.util.Set;
 
 
@@ -98,8 +91,9 @@ public class AdminSysRoleController {
 
     @SaCheckPermission(type = AdminStpUtil.TYPE, value = PERMISSION_PREFIX + "bindMenus")
     @ApiOperation(value = "绑定角色与菜单关联关系", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
-    @PostMapping(value = "/bindMenus")
-    public ApiResult<?> bindMenus(@RequestBody @Valid AdminBindRoleMenuRelationDTO dto) {
+    @PutMapping(value = "/{id}/menus")
+    public ApiResult<?> bindMenus(@PathVariable Long id, @RequestBody @Valid AdminBindRoleMenuRelationDTO dto) {
+        dto.setRoleId(id);
         Set<String> newPermissions = sysRoleService.adminBindMenus(dto);
 
         // 覆盖更新缓存

+ 19 - 12
src/main/java/cc/uncarbon/module/sys/web/sys/AdminSysUserController.java

@@ -23,6 +23,7 @@ import org.springframework.http.MediaType;
 import org.springframework.web.bind.annotation.*;
 
 import javax.validation.Valid;
+import java.util.Set;
 
 
 /**
@@ -91,8 +92,9 @@ public class AdminSysUserController {
 
     @SaCheckPermission(type = AdminStpUtil.TYPE, value = PERMISSION_PREFIX + "resetPassword")
     @ApiOperation(value = "重置某用户密码", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
-    @PostMapping(value = "/resetPassword")
-    public ApiResult<?> resetPassword(@RequestBody @Valid AdminResetSysUserPasswordDTO dto) {
+    @PutMapping(value = "/{userId}/password")
+    public ApiResult<?> resetPassword(@PathVariable Long userId, @RequestBody @Valid AdminResetSysUserPasswordDTO dto) {
+        dto.setUserId(userId);
         sysUserService.adminResetUserPassword(dto);
 
         // 踢出原登录
@@ -121,26 +123,31 @@ public class AdminSysUserController {
 
     @SaCheckPermission(type = AdminStpUtil.TYPE, value = PERMISSION_PREFIX + "bindRoles")
     @ApiOperation(value = "绑定用户与角色关联关系", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
-    @PostMapping(value = "/bindRoles")
-    public ApiResult<?> bindRoles(@RequestBody @Valid AdminBindUserRoleRelationDTO dto) {
+    @PutMapping(value = "/{userId}/roles")
+    public ApiResult<?> bindRoles(@PathVariable Long userId, @RequestBody AdminBindUserRoleRelationDTO dto) {
+        dto.setUserId(userId);
         sysUserService.adminBindRoles(dto);
+
         // 该用户会被强制踢下线,以更新对应权限;可以视业务需要决定是否删除该代码
-        this.kickOut(
-                AdminKickOutSysUserDTO.builder()
-                        .userId(dto.getUserId())
-                        .build()
-        );
+        this.kickOut(dto.getUserId());
 
         return ApiResult.success();
     }
 
     @SaCheckPermission(type = AdminStpUtil.TYPE, value = PERMISSION_PREFIX + "kickOut")
     @ApiOperation(value = "踢某用户下线", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
-    @PostMapping(value = "/kickOut")
-    public ApiResult<?> kickOut(@RequestBody @Valid AdminKickOutSysUserDTO dto) {
-        AdminStpUtil.kickout(dto.getUserId());
+    @PostMapping(value = "/{userId}/kickOut")
+    public ApiResult<?> kickOut(@PathVariable Long userId) {
+        AdminStpUtil.kickout(userId);
 
         return ApiResult.success();
     }
 
+    @SaCheckPermission(type = AdminStpUtil.TYPE, value = PERMISSION_PREFIX + HelioConstant.Permission.RETRIEVE)
+    @ApiOperation(value = "取指定用户关联角色ID", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
+    @GetMapping(value = "/{userId}/relatedRoleIds")
+    public ApiResult<Set<Long>> listRelatedRoleIds(@PathVariable Long userId) {
+        return ApiResult.data(sysUserService.listRelatedRoleIds(userId));
+    }
+
 }

+ 0 - 2
src/main/resources/application.yml

@@ -65,8 +65,6 @@ server:
   port: 7003
 
 mybatis-plus:
-  # 枚举和XML扫描,支持统配符 * 或者 ; 分割
-  type-enums-package: cc.uncarbon.module.*.enums
   mapper-locations: classpath*:/mapper/**/*.xml
 
 logging: