~
This commit is contained in:
29
mjkf-xinke-plugin/README.md
Normal file
29
mjkf-xinke-plugin/README.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# 插件模块
|
||||
|
||||
####登录鉴权插件: snowy-plugin-auth
|
||||
|
||||
####业务功能插件: snowy-plugin-biz
|
||||
|
||||
####C端功能插件: snowy-plugin-client
|
||||
|
||||
####多数据源插件: snowy-plugin-dbs
|
||||
|
||||
####开发工具插件: snowy-plugin-dev
|
||||
|
||||
####功能案例插件: snowy-plugin-exm
|
||||
|
||||
####工作流程插件: snowy-plugin-flw
|
||||
|
||||
####代码生成插件: snowy-plugin-gen
|
||||
|
||||
####支付功能插件: snowy-plugin-pay
|
||||
|
||||
####代码生成插件: snowy-plugin-gen
|
||||
|
||||
####移动端管理插件: snowy-plugin-mobile
|
||||
|
||||
####系统功能插件: snowy-plugin-sys
|
||||
|
||||
####动态租户插件: snowy-plugin-ten
|
||||
|
||||
####报表设计插件: snowy-plugin-urp
|
67
mjkf-xinke-plugin/mjkf-xinke-plugin-auth/pom.xml
Normal file
67
mjkf-xinke-plugin/mjkf-xinke-plugin-auth/pom.xml
Normal file
@@ -0,0 +1,67 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>mjkf.xinke</groupId>
|
||||
<artifactId>mjkf-xinke-plugin</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>mjkf-xinke-plugin-auth</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<description>登录鉴权插件</description>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<!-- 每个插件都要引入自己的对外接口 -->
|
||||
<dependency>
|
||||
<groupId>mjkf.xinke</groupId>
|
||||
<artifactId>mjkf-xinke-plugin-auth-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 引入开发工具接口,用于获取配置 -->
|
||||
<dependency>
|
||||
<groupId>mjkf.xinke</groupId>
|
||||
<artifactId>mjkf-xinke-plugin-dev-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 引入多租户接口,用于获取租户信息 -->
|
||||
<dependency>
|
||||
<groupId>mjkf.xinke</groupId>
|
||||
<artifactId>mjkf-xinke-plugin-ten-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- sa-token -->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- sa-token 整合 redis (使用jackson序列化方式) -->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-dao-redis-jackson</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Sa-Token插件:权限缓存与业务缓存分离 -->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-alone-redis</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Sa-Token 插件:整合SSO -->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-sso</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- JustAuth 第三方登录 -->
|
||||
<dependency>
|
||||
<groupId>me.zhyd.oauth</groupId>
|
||||
<artifactId>JustAuth</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
@@ -0,0 +1,138 @@
|
||||
|
||||
package mjkf.xinke.auth.core.config;
|
||||
|
||||
import cn.dev33.satoken.interceptor.SaInterceptor;
|
||||
import cn.dev33.satoken.stp.StpInterface;
|
||||
import cn.dev33.satoken.stp.StpLogic;
|
||||
import cn.dev33.satoken.strategy.SaStrategy;
|
||||
import com.github.xiaoymin.knife4j.spring.extension.OpenApiExtensionResolver;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.annotation.AnnotatedElementUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
import springfox.documentation.builders.ApiInfoBuilder;
|
||||
import springfox.documentation.builders.PathSelectors;
|
||||
import springfox.documentation.builders.RequestHandlerSelectors;
|
||||
import springfox.documentation.service.Contact;
|
||||
import springfox.documentation.spi.DocumentationType;
|
||||
import springfox.documentation.spring.web.plugins.Docket;
|
||||
import mjkf.xinke.auth.core.enums.SaClientTypeEnum;
|
||||
import mjkf.xinke.auth.core.util.StpClientLoginUserUtil;
|
||||
import mjkf.xinke.auth.core.util.StpLoginUserUtil;
|
||||
import mjkf.xinke.common.pojo.CommonResult;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* SaToken鉴权配置
|
||||
*
|
||||
*
|
||||
* @date 2021/10/9 14:24
|
||||
**/
|
||||
@Configuration
|
||||
public class AuthConfigure implements WebMvcConfigurer {
|
||||
|
||||
@Resource
|
||||
private OpenApiExtensionResolver openApiExtensionResolver;
|
||||
|
||||
/**
|
||||
* 注册Sa-Token的注解拦截器,打开注解式鉴权功能
|
||||
*
|
||||
* 注解的方式有以下几中,注解既可以加在接口方法上,也可加在Controller类上:
|
||||
* 1.@SaCheckLogin: 登录认证 —— 只有登录之后才能进入该方法(常用)
|
||||
* 2.@SaCheckRole("admin"): 角色认证 —— 必须具有指定角色标识才能进入该方法(常用)
|
||||
* 3.@SaCheckPermission("user:add"): 权限认证 —— 必须具有指定权限才能进入该方法(常用)
|
||||
* 4.@SaCheckSafe: 二级认证校验 —— 必须二级认证之后才能进入该方法
|
||||
* 5.@SaCheckBasic: HttpBasic认证 —— 只有通过 Basic 认证后才能进入该方法
|
||||
*
|
||||
* 在Controller中创建一个接口,默认不需要登录也不需要任何权限都可以访问的,只有加了上述注解才会校验
|
||||
**/
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
// 注册注解拦截器,并排除不需要注解鉴权的接口地址 (与登录拦截器无关,只是说明哪些接口不需要被拦截器拦截,此处都拦截)
|
||||
registry.addInterceptor(new SaInterceptor()).addPathPatterns("/**");
|
||||
}
|
||||
|
||||
@Bean("stpLogic")
|
||||
public StpLogic getStpLogic() {
|
||||
// 重写Sa-Token的StpLogic,默认客户端类型为B
|
||||
return new StpLogic(SaClientTypeEnum.B.getValue());
|
||||
}
|
||||
|
||||
@Bean("stpClientLogic")
|
||||
public StpLogic getStpClientLogic() {
|
||||
// 重写Sa-Token的StpLogic,默认客户端类型为C
|
||||
return new StpLogic(SaClientTypeEnum.C.getValue());
|
||||
}
|
||||
|
||||
@Bean
|
||||
public void rewriteSaStrategy() {
|
||||
// 重写Sa-Token的注解处理器,增加注解合并功能
|
||||
SaStrategy.me.getAnnotation = AnnotatedElementUtils::getMergedAnnotation;
|
||||
}
|
||||
|
||||
/**
|
||||
* 权限认证接口实现类,集成权限认证功能
|
||||
*
|
||||
*
|
||||
* @date 2022/7/7 16:16
|
||||
**/
|
||||
@Component
|
||||
public static class StpInterfaceImpl implements StpInterface {
|
||||
|
||||
/**
|
||||
* 返回一个账号所拥有的权限码集合
|
||||
*/
|
||||
@Override
|
||||
public List<String> getPermissionList(Object loginId, String loginType) {
|
||||
if (SaClientTypeEnum.B.getValue().equals(loginType)) {
|
||||
return StpLoginUserUtil.getLoginUser().getPermissionCodeList();
|
||||
} else {
|
||||
return StpClientLoginUserUtil.getClientLoginUser().getPermissionCodeList();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回一个账号所拥有的角色标识集合
|
||||
*/
|
||||
@Override
|
||||
public List<String> getRoleList(Object loginId, String loginType) {
|
||||
if (SaClientTypeEnum.B.getValue().equals(loginType)) {
|
||||
return StpLoginUserUtil.getLoginUser().getRoleCodeList();
|
||||
} else {
|
||||
return StpClientLoginUserUtil.getClientLoginUser().getRoleCodeList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* API文档分组配置
|
||||
*
|
||||
*
|
||||
* @date 2022/7/7 16:18
|
||||
**/
|
||||
@Bean(value = "authDocApi")
|
||||
public Docket authDocApi() {
|
||||
return new Docket(DocumentationType.SWAGGER_2)
|
||||
.apiInfo(new ApiInfoBuilder()
|
||||
.title("登录鉴权AUTH")
|
||||
.description("登录鉴权AUTH")
|
||||
.termsOfServiceUrl("https://www.xiaonuo.vip")
|
||||
.contact(new Contact("SNOWY_TEAM","https://www.xiaonuo.vip", "xuyuxiang29@foxmail.com"))
|
||||
.version("2.0.0")
|
||||
.build())
|
||||
.globalResponseMessage(RequestMethod.GET, CommonResult.responseList())
|
||||
.globalResponseMessage(RequestMethod.POST, CommonResult.responseList())
|
||||
.groupName("登录鉴权AUTH")
|
||||
.select()
|
||||
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
|
||||
.apis(RequestHandlerSelectors.basePackage("mjkf.xinke.auth"))
|
||||
.paths(PathSelectors.any())
|
||||
.build().extensions(openApiExtensionResolver.buildExtensions("登录鉴权AUTH"));
|
||||
}
|
||||
}
|
@@ -0,0 +1,56 @@
|
||||
|
||||
package mjkf.xinke.auth.core.util;
|
||||
|
||||
import cn.dev33.satoken.context.SaHolder;
|
||||
import cn.dev33.satoken.exception.*;
|
||||
import cn.hutool.http.HttpStatus;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import mjkf.xinke.common.pojo.CommonResult;
|
||||
import mjkf.xinke.common.util.CommonServletUtil;
|
||||
|
||||
@Slf4j
|
||||
public class AuthExceptionUtil {
|
||||
|
||||
/**
|
||||
* 根据错误类型获取对应的CommonResult(只处理SaToken相关异常)
|
||||
*
|
||||
*
|
||||
* @date 2021/10/11 15:52
|
||||
**/
|
||||
public static CommonResult<String> getCommonResult(Exception e) {
|
||||
CommonResult<String> commonResult;
|
||||
if (e instanceof NotLoginException) {
|
||||
|
||||
// 如果是未登录异常 401
|
||||
NotLoginException notLoginException = (NotLoginException) e;
|
||||
commonResult = CommonResult.get(HttpStatus.HTTP_UNAUTHORIZED, notLoginException.getMessage(), null);
|
||||
} else if (e instanceof NotRoleException) {
|
||||
|
||||
// 如果是角色异常 403
|
||||
NotRoleException notRoleException = (NotRoleException) e;
|
||||
commonResult = CommonResult.get(HttpStatus.HTTP_FORBIDDEN, "无此角色:" + notRoleException.getRole() +
|
||||
",接口地址:" + CommonServletUtil.getRequest().getServletPath(), null);
|
||||
} else if (e instanceof NotPermissionException) {
|
||||
|
||||
// 如果是权限异常 403
|
||||
NotPermissionException notPermissionException = (NotPermissionException) e;
|
||||
commonResult = CommonResult.get(HttpStatus.HTTP_FORBIDDEN, "无此权限:" + notPermissionException.getPermission(), null);
|
||||
} else if (e instanceof DisableServiceException) {
|
||||
|
||||
// 如果是被封禁异常 403
|
||||
DisableServiceException disableServiceException = (DisableServiceException) e;
|
||||
commonResult = CommonResult.get(HttpStatus.HTTP_FORBIDDEN, "账号被封禁:" + disableServiceException.getDisableTime() + "秒后解封", null);
|
||||
} else if (e instanceof SaTokenException) {
|
||||
|
||||
// 如果是SaToken异常 直接返回
|
||||
SaTokenException saTokenException = (SaTokenException) e;
|
||||
commonResult = CommonResult.error(saTokenException.getMessage());
|
||||
} else {
|
||||
// 未知异常才打印
|
||||
log.error(">>> 服务器未知异常,请求地址:{},具体信息:", CommonServletUtil.getRequest().getRequestURL(), e);
|
||||
// 未知异常返回服务器异常(此处不可能执行进入,因为本方法处理的一定是SaToken的异常,此处仅为安全性考虑)
|
||||
commonResult = CommonResult.error();
|
||||
}
|
||||
return commonResult;
|
||||
}
|
||||
}
|
@@ -0,0 +1,122 @@
|
||||
|
||||
package mjkf.xinke.auth.modular.login.controller;
|
||||
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
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.RestController;
|
||||
import mjkf.xinke.auth.core.annotation.SaClientCheckLogin;
|
||||
import mjkf.xinke.auth.core.enums.SaClientTypeEnum;
|
||||
import mjkf.xinke.auth.core.pojo.SaBaseClientLoginUser;
|
||||
import mjkf.xinke.auth.core.util.StpClientUtil;
|
||||
import mjkf.xinke.auth.modular.login.param.AuthAccountPasswordLoginParam;
|
||||
import mjkf.xinke.auth.modular.login.param.AuthGetPhoneValidCodeParam;
|
||||
import mjkf.xinke.auth.modular.login.param.AuthPhoneValidCodeLoginParam;
|
||||
import mjkf.xinke.auth.modular.login.result.AuthPicValidCodeResult;
|
||||
import mjkf.xinke.auth.modular.login.service.AuthService;
|
||||
import mjkf.xinke.common.pojo.CommonResult;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
|
||||
/**
|
||||
* C端登录控制器
|
||||
*
|
||||
*
|
||||
* @date 2021/12/23 21:50
|
||||
*/
|
||||
@Api(tags = "C端登录控制器")
|
||||
@ApiSupport(author = "SNOWY_TEAM", order = 1)
|
||||
@RestController
|
||||
@Validated
|
||||
public class AuthClientController {
|
||||
|
||||
@Resource
|
||||
private AuthService authService;
|
||||
|
||||
/**
|
||||
* C端获取图片验证码
|
||||
*
|
||||
*
|
||||
* @date 2022/7/8 9:26
|
||||
**/
|
||||
@ApiOperationSupport(order = 1)
|
||||
@ApiOperation("C端获取图片验证码")
|
||||
@GetMapping("/auth/c/getPicCaptcha")
|
||||
public CommonResult<AuthPicValidCodeResult> getPicCaptcha() {
|
||||
return CommonResult.data(authService.getPicCaptcha(SaClientTypeEnum.C.getValue()));
|
||||
}
|
||||
|
||||
/**
|
||||
* C端获取手机验证码
|
||||
*
|
||||
*
|
||||
* @date 2022/7/8 9:26
|
||||
**/
|
||||
@ApiOperationSupport(order = 2)
|
||||
@ApiOperation("C端获取手机验证码")
|
||||
@GetMapping("/auth/c/getPhoneValidCode")
|
||||
public CommonResult<String> getPhoneValidCode(@Valid AuthGetPhoneValidCodeParam authGetPhoneValidCodeParam) {
|
||||
return CommonResult.data(authService.getPhoneValidCode(authGetPhoneValidCodeParam, SaClientTypeEnum.C.getValue()));
|
||||
}
|
||||
|
||||
/**
|
||||
* C端账号密码登录
|
||||
*
|
||||
*
|
||||
* @date 2021/10/15 13:12
|
||||
**/
|
||||
@ApiOperationSupport(order = 3)
|
||||
@ApiOperation("C端账号密码登录")
|
||||
@PostMapping("/auth/c/doLogin")
|
||||
public CommonResult<String> doLogin(@RequestBody @Valid AuthAccountPasswordLoginParam authAccountPasswordLoginParam) {
|
||||
return CommonResult.data(authService.doLogin(authAccountPasswordLoginParam, SaClientTypeEnum.C.getValue()));
|
||||
}
|
||||
|
||||
/**
|
||||
* C端手机验证码登录
|
||||
*
|
||||
*
|
||||
* @date 2021/10/15 13:12
|
||||
**/
|
||||
@ApiOperationSupport(order = 4)
|
||||
@ApiOperation("C端手机验证码登录")
|
||||
@PostMapping("/auth/c/doLoginByPhone")
|
||||
public CommonResult<String> doLoginByPhone(@RequestBody @Valid AuthPhoneValidCodeLoginParam authPhoneValidCodeLoginParam) {
|
||||
return CommonResult.data(authService.doLoginByPhone(authPhoneValidCodeLoginParam, SaClientTypeEnum.C.getValue()));
|
||||
}
|
||||
|
||||
/**
|
||||
* C端退出
|
||||
*
|
||||
*
|
||||
* @date 2021/10/15 13:12
|
||||
**/
|
||||
@ApiOperationSupport(order = 5)
|
||||
@ApiOperation("C端退出")
|
||||
@SaClientCheckLogin
|
||||
@GetMapping("/auth/c/doLogout")
|
||||
public CommonResult<String> doLogout() {
|
||||
StpClientUtil.logout();
|
||||
return CommonResult.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* C端获取用户信息
|
||||
*
|
||||
*
|
||||
* @date 2021/10/15 13:12
|
||||
**/
|
||||
@ApiOperationSupport(order = 6)
|
||||
@ApiOperation("C端获取用户信息")
|
||||
@SaClientCheckLogin
|
||||
@GetMapping("/auth/c/getLoginUser")
|
||||
public CommonResult<SaBaseClientLoginUser> getLoginUser() {
|
||||
return CommonResult.data(authService.getClientLoginUser());
|
||||
}
|
||||
}
|
@@ -0,0 +1,122 @@
|
||||
|
||||
package mjkf.xinke.auth.modular.login.controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckLogin;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
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.RestController;
|
||||
import mjkf.xinke.auth.core.enums.SaClientTypeEnum;
|
||||
import mjkf.xinke.auth.core.pojo.SaBaseLoginUser;
|
||||
import mjkf.xinke.auth.modular.login.param.AuthAccountPasswordLoginParam;
|
||||
import mjkf.xinke.auth.modular.login.param.AuthGetPhoneValidCodeParam;
|
||||
import mjkf.xinke.auth.modular.login.param.AuthPhoneValidCodeLoginParam;
|
||||
import mjkf.xinke.auth.modular.login.result.AuthPicValidCodeResult;
|
||||
import mjkf.xinke.auth.modular.login.service.AuthService;
|
||||
import mjkf.xinke.common.pojo.CommonResult;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
|
||||
/**
|
||||
* B端登录控制器
|
||||
*
|
||||
*
|
||||
* @date 2021/12/23 21:50
|
||||
*/
|
||||
@Api(tags = "B端登录控制器")
|
||||
@ApiSupport(author = "SNOWY_TEAM", order = 2)
|
||||
@RestController
|
||||
@Validated
|
||||
public class AuthController {
|
||||
|
||||
@Resource
|
||||
private AuthService authService;
|
||||
|
||||
/**
|
||||
* B端获取图片验证码
|
||||
*
|
||||
*
|
||||
* @date 2022/7/8 9:26
|
||||
**/
|
||||
@ApiOperationSupport(order = 1)
|
||||
@ApiOperation("B端获取图片验证码")
|
||||
@GetMapping("/auth/b/getPicCaptcha")
|
||||
public CommonResult<AuthPicValidCodeResult> getPicCaptcha() {
|
||||
return CommonResult.data(authService.getPicCaptcha(SaClientTypeEnum.B.getValue()));
|
||||
}
|
||||
|
||||
/**
|
||||
* B端获取手机验证码
|
||||
*
|
||||
*
|
||||
* @date 2022/7/8 9:26
|
||||
**/
|
||||
@ApiOperationSupport(order = 2)
|
||||
@ApiOperation("B端获取手机验证码")
|
||||
@GetMapping("/auth/b/getPhoneValidCode")
|
||||
public CommonResult<String> getPhoneValidCode(@Valid AuthGetPhoneValidCodeParam authGetPhoneValidCodeParam) {
|
||||
return CommonResult.data(authService.getPhoneValidCode(authGetPhoneValidCodeParam, SaClientTypeEnum.B.getValue()));
|
||||
}
|
||||
|
||||
/**
|
||||
* B端账号密码登录
|
||||
*
|
||||
*
|
||||
* @date 2021/10/15 13:12
|
||||
**/
|
||||
@ApiOperationSupport(order = 3)
|
||||
@ApiOperation("B端账号密码登录")
|
||||
@PostMapping("/auth/b/doLogin")
|
||||
public CommonResult<String> doLogin(@RequestBody @Valid AuthAccountPasswordLoginParam authAccountPasswordLoginParam) {
|
||||
return CommonResult.data(authService.doLogin(authAccountPasswordLoginParam, SaClientTypeEnum.B.getValue()));
|
||||
}
|
||||
|
||||
/**
|
||||
* B端手机验证码登录
|
||||
*
|
||||
*
|
||||
* @date 2021/10/15 13:12
|
||||
**/
|
||||
@ApiOperationSupport(order = 4)
|
||||
@ApiOperation("B端手机验证码登录")
|
||||
@PostMapping("/auth/b/doLoginByPhone")
|
||||
public CommonResult<String> doLoginByPhone(@RequestBody @Valid AuthPhoneValidCodeLoginParam authPhoneValidCodeLoginParam) {
|
||||
return CommonResult.data(authService.doLoginByPhone(authPhoneValidCodeLoginParam, SaClientTypeEnum.B.getValue()));
|
||||
}
|
||||
|
||||
/**
|
||||
* B端退出
|
||||
*
|
||||
*
|
||||
* @date 2021/10/15 13:12
|
||||
**/
|
||||
@ApiOperationSupport(order = 5)
|
||||
@ApiOperation("B端退出")
|
||||
@SaCheckLogin
|
||||
@GetMapping("/auth/b/doLogout")
|
||||
public CommonResult<String> doLogout() {
|
||||
StpUtil.logout();
|
||||
return CommonResult.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* B端获取用户信息
|
||||
*
|
||||
*
|
||||
* @date 2021/10/15 13:12
|
||||
**/
|
||||
@ApiOperationSupport(order = 6)
|
||||
@ApiOperation("B端获取用户信息")
|
||||
@SaCheckLogin
|
||||
@GetMapping("/auth/b/getLoginUser")
|
||||
public CommonResult<SaBaseLoginUser> getLoginUser() {
|
||||
return CommonResult.data(authService.getLoginUser());
|
||||
}
|
||||
}
|
@@ -0,0 +1,43 @@
|
||||
|
||||
package mjkf.xinke.auth.modular.login.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
import mjkf.xinke.common.exception.CommonException;
|
||||
|
||||
/**
|
||||
* 登录设备类型枚举
|
||||
*
|
||||
*
|
||||
* @date 2021/10/11 14:02
|
||||
**/
|
||||
@Getter
|
||||
public enum AuthDeviceTypeEnum {
|
||||
|
||||
/**
|
||||
* PC端
|
||||
*/
|
||||
PC("PC"),
|
||||
|
||||
/**
|
||||
* 移动端
|
||||
*/
|
||||
APP("APP"),
|
||||
|
||||
/**
|
||||
* 小程序端
|
||||
*/
|
||||
MINI("MINI");
|
||||
|
||||
private final String value;
|
||||
|
||||
AuthDeviceTypeEnum(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public static void validate(String value) {
|
||||
boolean flag = PC.getValue().equals(value) || APP.getValue().equals(value) || MINI.getValue().equals(value);
|
||||
if(!flag) {
|
||||
throw new CommonException("不支持的登录设备类型:{}", value);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,75 @@
|
||||
|
||||
package mjkf.xinke.auth.modular.login.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 登录异常提示语枚举
|
||||
*
|
||||
*
|
||||
* @date 2021/10/11 14:02
|
||||
**/
|
||||
@Getter
|
||||
public enum AuthExceptionEnum {
|
||||
|
||||
/**
|
||||
* 验证码不能为空
|
||||
*/
|
||||
VALID_CODE_EMPTY("验证码不能为空"),
|
||||
|
||||
/**
|
||||
* 验证码请求号不能为空
|
||||
*/
|
||||
VALID_CODE_REQ_NO_EMPTY("验证码请求号不能为空"),
|
||||
|
||||
/**
|
||||
* 验证码错误
|
||||
*/
|
||||
VALID_CODE_ERROR("验证码错误"),
|
||||
|
||||
/**
|
||||
* 账号错误
|
||||
*/
|
||||
ACCOUNT_ERROR("账号错误"),
|
||||
|
||||
/**
|
||||
* 账号已停用
|
||||
*/
|
||||
ACCOUNT_DISABLED("账号已停用"),
|
||||
|
||||
/**
|
||||
* 密码错误
|
||||
*/
|
||||
PWD_ERROR("密码错误"),
|
||||
|
||||
/**
|
||||
* 手机号格式错误
|
||||
*/
|
||||
PHONE_FORMAT_ERROR("手机号格式错误"),
|
||||
|
||||
/**
|
||||
* 手机号不存在
|
||||
*/
|
||||
PHONE_ERROR("手机号不存在"),
|
||||
|
||||
/**
|
||||
* 客户端类型不能为空
|
||||
*/
|
||||
CLIENT_TYPE_EMPTY("客户端类型不能为空"),
|
||||
|
||||
/**
|
||||
* 客户端类型错误
|
||||
*/
|
||||
CLIENT_TYPE_ERROR("客户端类型错误"),
|
||||
|
||||
/**
|
||||
* 密码解密失败,请检查前端公钥
|
||||
*/
|
||||
PWD_DECRYPT_ERROR("密码解密失败,请检查前端公钥");
|
||||
|
||||
private final String value;
|
||||
|
||||
AuthExceptionEnum(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
@@ -0,0 +1,107 @@
|
||||
|
||||
package mjkf.xinke.auth.modular.login.listener;
|
||||
|
||||
import cn.dev33.satoken.listener.SaTokenListener;
|
||||
import cn.dev33.satoken.stp.SaLoginModel;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import org.springframework.stereotype.Component;
|
||||
import mjkf.xinke.auth.api.SaBaseLoginUserApi;
|
||||
import mjkf.xinke.auth.core.enums.SaClientTypeEnum;
|
||||
import mjkf.xinke.auth.core.pojo.SaBaseLoginUser;
|
||||
import mjkf.xinke.dev.api.DevLogApi;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* 自定义登录监听器
|
||||
*
|
||||
*
|
||||
* @date 2021/12/28 11:35
|
||||
**/
|
||||
@Component
|
||||
public class AuthListener implements SaTokenListener {
|
||||
|
||||
@Resource(name = "loginUserApi")
|
||||
private SaBaseLoginUserApi loginUserApi;
|
||||
|
||||
@Resource(name = "clientLoginUserApi")
|
||||
private SaBaseLoginUserApi clientLoginUserApi;
|
||||
|
||||
@Resource
|
||||
private DevLogApi devLogApi;
|
||||
|
||||
/** 每次登录时触发 */
|
||||
@Override
|
||||
public void doLogin(String loginType, Object loginId, String tokenValue, SaLoginModel loginModel) {
|
||||
// 更新用户的登录时间和登录ip等信息
|
||||
if(SaClientTypeEnum.B.getValue().equals(loginType)) {
|
||||
loginUserApi.updateUserLoginInfo(Convert.toStr(loginId), loginModel.getDevice());
|
||||
// 记录B端登录日志
|
||||
Object name = loginModel.getExtra("name");
|
||||
if(ObjectUtil.isNotEmpty(name)) {
|
||||
devLogApi.executeLoginLog(Convert.toStr(name));
|
||||
} else {
|
||||
devLogApi.executeLoginLog(null);
|
||||
}
|
||||
} else {
|
||||
clientLoginUserApi.updateUserLoginInfo(Convert.toStr(loginId), loginModel.getDevice());
|
||||
}
|
||||
}
|
||||
|
||||
/** 每次注销时触发 */
|
||||
@Override
|
||||
public void doLogout(String loginType, Object loginId, String tokenValue) {
|
||||
if(SaClientTypeEnum.B.getValue().equals(loginType)) {
|
||||
// 记录B端登出日志
|
||||
SaBaseLoginUser saBaseLoginUser = loginUserApi.getUserById(Convert.toStr(loginId));
|
||||
if(ObjectUtil.isNotEmpty(saBaseLoginUser)) {
|
||||
devLogApi.executeLogoutLog(saBaseLoginUser.getName());
|
||||
} else {
|
||||
devLogApi.executeLogoutLog(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** 每次被踢下线时触发 */
|
||||
@Override
|
||||
public void doKickout(String loginType, Object loginId, String tokenValue) {
|
||||
// ...
|
||||
}
|
||||
|
||||
/** 每次被顶下线时触发 */
|
||||
@Override
|
||||
public void doReplaced(String loginType, Object loginId, String tokenValue) {
|
||||
// ...
|
||||
}
|
||||
|
||||
/** 每次被封禁时触发 */
|
||||
@Override
|
||||
public void doDisable(String loginType, Object loginId, String service, int level, long disableTime) {
|
||||
// ...
|
||||
}
|
||||
|
||||
/** 每次被解封时触发 */
|
||||
@Override
|
||||
public void doUntieDisable(String loginType, Object loginId, String service) {
|
||||
// ...
|
||||
}
|
||||
|
||||
/** 每次创建Session时触发 */
|
||||
@Override
|
||||
public void doCreateSession(String id) {
|
||||
// ...
|
||||
}
|
||||
|
||||
/** 每次注销Session时触发 */
|
||||
@Override
|
||||
public void doLogoutSession(String id) {
|
||||
// ...
|
||||
}
|
||||
|
||||
/** 每次Token续期时触发 */
|
||||
@Override
|
||||
public void doRenewTimeout(String tokenValue, Object loginId, long timeout) {
|
||||
// ...
|
||||
}
|
||||
}
|
@@ -0,0 +1,41 @@
|
||||
|
||||
package mjkf.xinke.auth.modular.login.param;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
/**
|
||||
* 账号密码登录参数
|
||||
*
|
||||
*
|
||||
* @date 2022/7/7 16:46
|
||||
**/
|
||||
@Getter
|
||||
@Setter
|
||||
public class AuthAccountPasswordLoginParam {
|
||||
|
||||
/** 账号 */
|
||||
@ApiModelProperty(value = "账号", required = true, position = 1)
|
||||
@NotBlank(message = "账号不能为空")
|
||||
private String account;
|
||||
|
||||
/** 密码 */
|
||||
@ApiModelProperty(value = "密码", required = true, position = 2)
|
||||
@NotBlank(message = "密码不能为空")
|
||||
private String password;
|
||||
|
||||
/** 设备 */
|
||||
@ApiModelProperty(value = "设备", position = 3)
|
||||
private String device;
|
||||
|
||||
/** 验证码 */
|
||||
@ApiModelProperty(value = "验证码", position = 4)
|
||||
private String validCode;
|
||||
|
||||
/** 验证码请求号 */
|
||||
@ApiModelProperty(value = "验证码请求号", position = 5)
|
||||
private String validCodeReqNo;
|
||||
}
|
@@ -0,0 +1,34 @@
|
||||
|
||||
package mjkf.xinke.auth.modular.login.param;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
/**
|
||||
* 获取手机验证码参数
|
||||
*
|
||||
*
|
||||
* @date 2022/8/25 13:45
|
||||
**/
|
||||
@Getter
|
||||
@Setter
|
||||
public class AuthGetPhoneValidCodeParam {
|
||||
|
||||
/** 手机号 */
|
||||
@ApiModelProperty(value = "手机号", required = true, position = 1)
|
||||
@NotBlank(message = "手机号不能为空")
|
||||
private String phone;
|
||||
|
||||
/** 验证码 */
|
||||
@ApiModelProperty(value = "验证码", required = true, position = 2)
|
||||
@NotBlank(message = "验证码不能为空")
|
||||
private String validCode;
|
||||
|
||||
/** 验证码请求号 */
|
||||
@ApiModelProperty(value = "验证码请求号", required = true, position = 3)
|
||||
@NotBlank(message = "验证码请求号不能为空")
|
||||
private String validCodeReqNo;
|
||||
}
|
@@ -0,0 +1,38 @@
|
||||
|
||||
package mjkf.xinke.auth.modular.login.param;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
/**
|
||||
* 手机验证码登录参数
|
||||
*
|
||||
*
|
||||
* @date 2022/7/7 16:46
|
||||
**/
|
||||
@Getter
|
||||
@Setter
|
||||
public class AuthPhoneValidCodeLoginParam {
|
||||
|
||||
/** 手机号 */
|
||||
@ApiModelProperty(value = "手机号", required = true, position = 1)
|
||||
@NotBlank(message = "手机号不能为空")
|
||||
private String phone;
|
||||
|
||||
/** 验证码 */
|
||||
@ApiModelProperty(value = "验证码", required = true, position = 2)
|
||||
@NotBlank(message = "验证码不能为空")
|
||||
private String validCode;
|
||||
|
||||
/** 验证码请求号 */
|
||||
@ApiModelProperty(value = "验证码请求号", required = true, position = 3)
|
||||
@NotBlank(message = "验证码请求号不能为空")
|
||||
private String validCodeReqNo;
|
||||
|
||||
/** 设备 */
|
||||
@ApiModelProperty(value = "设备", position = 4)
|
||||
private String device;
|
||||
}
|
@@ -0,0 +1,25 @@
|
||||
|
||||
package mjkf.xinke.auth.modular.login.result;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* 图片验证码结果
|
||||
*
|
||||
*
|
||||
* @date 2022/7/8 9:28
|
||||
**/
|
||||
@Getter
|
||||
@Setter
|
||||
public class AuthPicValidCodeResult {
|
||||
|
||||
/** 验证码图片,Base64 */
|
||||
@ApiModelProperty(value = "验证码图片,Base64", position = 1)
|
||||
private String validCodeBase64;
|
||||
|
||||
/** 验证码请求号 */
|
||||
@ApiModelProperty(value = "验证码请求号", position = 2)
|
||||
private String validCodeReqNo;
|
||||
}
|
@@ -0,0 +1,74 @@
|
||||
|
||||
package mjkf.xinke.auth.modular.login.service;
|
||||
|
||||
import mjkf.xinke.auth.core.pojo.SaBaseClientLoginUser;
|
||||
import mjkf.xinke.auth.core.pojo.SaBaseLoginUser;
|
||||
import mjkf.xinke.auth.modular.login.param.AuthAccountPasswordLoginParam;
|
||||
import mjkf.xinke.auth.modular.login.param.AuthGetPhoneValidCodeParam;
|
||||
import mjkf.xinke.auth.modular.login.param.AuthPhoneValidCodeLoginParam;
|
||||
import mjkf.xinke.auth.modular.login.result.AuthPicValidCodeResult;
|
||||
|
||||
/**
|
||||
* 登录Service接口
|
||||
*
|
||||
*
|
||||
* @date 2021/12/23 21:51
|
||||
*/
|
||||
public interface AuthService {
|
||||
|
||||
/**
|
||||
* 获取图片验证码
|
||||
*
|
||||
*
|
||||
* @date 2021/12/28 14:46
|
||||
**/
|
||||
AuthPicValidCodeResult getPicCaptcha(String type);
|
||||
|
||||
/**
|
||||
* 获取手机验证码
|
||||
*
|
||||
*
|
||||
* @date 2021/12/28 14:46
|
||||
**/
|
||||
String getPhoneValidCode(AuthGetPhoneValidCodeParam authGetPhoneValidCodeParam, String type);
|
||||
|
||||
/**
|
||||
* 账号密码登录
|
||||
*
|
||||
*
|
||||
* @date 2021/12/28 14:46
|
||||
**/
|
||||
String doLogin(AuthAccountPasswordLoginParam authAccountPasswordLoginParam, String type);
|
||||
|
||||
/**
|
||||
* 手机验证码登录
|
||||
*
|
||||
*
|
||||
* @date 2021/12/28 14:46
|
||||
**/
|
||||
String doLoginByPhone(AuthPhoneValidCodeLoginParam authPhoneValidCodeLoginParam, String type);
|
||||
|
||||
/**
|
||||
* 获取B端登录用户信息
|
||||
*
|
||||
*
|
||||
* @date 2021/10/12 15:59
|
||||
**/
|
||||
SaBaseLoginUser getLoginUser();
|
||||
|
||||
/**
|
||||
* 获取C端登录用户信息
|
||||
*
|
||||
*
|
||||
* @date 2021/10/12 15:59
|
||||
**/
|
||||
SaBaseClientLoginUser getClientLoginUser();
|
||||
|
||||
/**
|
||||
* 根据用户id和客户端类型登录,用于第三方登录
|
||||
*
|
||||
*
|
||||
* @date 2022/7/9 14:44
|
||||
*/
|
||||
String doLoginById(String userId, String device, String type);
|
||||
}
|
@@ -0,0 +1,406 @@
|
||||
|
||||
package mjkf.xinke.auth.modular.login.service.impl;
|
||||
|
||||
import cn.dev33.satoken.stp.SaLoginModel;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.hutool.captcha.CaptchaUtil;
|
||||
import cn.hutool.captcha.CircleCaptcha;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.PhoneUtil;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
|
||||
import org.springframework.stereotype.Service;
|
||||
import mjkf.xinke.auth.api.SaBaseLoginUserApi;
|
||||
import mjkf.xinke.auth.core.enums.SaClientTypeEnum;
|
||||
import mjkf.xinke.auth.core.pojo.SaBaseClientLoginUser;
|
||||
import mjkf.xinke.auth.core.pojo.SaBaseLoginUser;
|
||||
import mjkf.xinke.auth.core.util.StpClientLoginUserUtil;
|
||||
import mjkf.xinke.auth.core.util.StpClientUtil;
|
||||
import mjkf.xinke.auth.core.util.StpLoginUserUtil;
|
||||
import mjkf.xinke.auth.modular.login.enums.AuthDeviceTypeEnum;
|
||||
import mjkf.xinke.auth.modular.login.enums.AuthExceptionEnum;
|
||||
import mjkf.xinke.auth.modular.login.param.AuthAccountPasswordLoginParam;
|
||||
import mjkf.xinke.auth.modular.login.param.AuthGetPhoneValidCodeParam;
|
||||
import mjkf.xinke.auth.modular.login.param.AuthPhoneValidCodeLoginParam;
|
||||
import mjkf.xinke.auth.modular.login.result.AuthPicValidCodeResult;
|
||||
import mjkf.xinke.auth.modular.login.service.AuthService;
|
||||
import mjkf.xinke.common.cache.CommonCacheOperator;
|
||||
import mjkf.xinke.common.exception.CommonException;
|
||||
import mjkf.xinke.common.util.CommonCryptogramUtil;
|
||||
import mjkf.xinke.common.util.CommonEmailUtil;
|
||||
import mjkf.xinke.dev.api.DevConfigApi;
|
||||
import mjkf.xinke.dev.api.DevSmsApi;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 登录Service接口实现类
|
||||
*
|
||||
*
|
||||
* @date 2021/12/23 21:52
|
||||
*/
|
||||
@Service
|
||||
public class AuthServiceImpl implements AuthService {
|
||||
|
||||
private static final String SNOWY_SYS_DEFAULT_CAPTCHA_OPEN_KEY = "SNOWY_SYS_DEFAULT_CAPTCHA_OPEN";
|
||||
|
||||
private static final String AUTH_VALID_CODE_CACHE_KEY = "auth-validCode:";
|
||||
|
||||
@Resource(name = "loginUserApi")
|
||||
private SaBaseLoginUserApi loginUserApi;
|
||||
|
||||
@Resource(name = "clientLoginUserApi")
|
||||
private SaBaseLoginUserApi clientLoginUserApi;
|
||||
|
||||
@Resource
|
||||
private DevConfigApi devConfigApi;
|
||||
|
||||
@Resource
|
||||
private DevSmsApi devSmsApi;
|
||||
|
||||
@Resource
|
||||
private CommonCacheOperator commonCacheOperator;
|
||||
|
||||
@Override
|
||||
public AuthPicValidCodeResult getPicCaptcha(String type) {
|
||||
// 生成验证码,随机4位字符
|
||||
CircleCaptcha circleCaptcha = CaptchaUtil.createCircleCaptcha(100, 38, 4, 10);
|
||||
// 定义返回结果
|
||||
AuthPicValidCodeResult authPicValidCodeResult = new AuthPicValidCodeResult();
|
||||
// 获取验证码的值
|
||||
String validCode = circleCaptcha.getCode();
|
||||
// 获取验证码的base64
|
||||
String validCodeBase64 = circleCaptcha.getImageBase64Data();
|
||||
// 生成请求号
|
||||
String validCodeReqNo = IdWorker.getIdStr();
|
||||
// 将base64返回前端
|
||||
authPicValidCodeResult.setValidCodeBase64(validCodeBase64);
|
||||
// 将请求号返回前端
|
||||
authPicValidCodeResult.setValidCodeReqNo(validCodeReqNo);
|
||||
// 将请求号作为key,验证码的值作为value放到redis,用于校验,5分钟有效
|
||||
commonCacheOperator.put(AUTH_VALID_CODE_CACHE_KEY + validCodeReqNo, validCode, 5 * 60);
|
||||
return authPicValidCodeResult;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPhoneValidCode(AuthGetPhoneValidCodeParam authGetPhoneValidCodeParam, String type) {
|
||||
// 手机号
|
||||
String phone = authGetPhoneValidCodeParam.getPhone();
|
||||
// 验证码
|
||||
String validCode = authGetPhoneValidCodeParam.getValidCode();
|
||||
// 验证码请求号
|
||||
String validCodeReqNo = authGetPhoneValidCodeParam.getValidCodeReqNo();
|
||||
// 校验参数
|
||||
validPhoneValidCodeParam(null, validCode, validCodeReqNo, type);
|
||||
// 生成手机验证码的值,随机6为数字
|
||||
String phoneValidCode = RandomUtil.randomNumbers(6);
|
||||
// 生成手机验证码的请求号
|
||||
String phoneValidCodeReqNo = IdWorker.getIdStr();
|
||||
|
||||
// TODO 使用阿里云执行发送验证码,将验证码作为短信内容的参数变量放入,
|
||||
// TODO 签名不传则使用系统默认配置的签名,支持传入多个参数,示例:{"name":"张三","number":"15038****76"}
|
||||
//devSmsApi.sendSmsAliyun(phone, null, "验证码模板号", JSONUtil.toJsonStr(JSONUtil.createObj().set("validCode", phoneValidCode)));
|
||||
|
||||
// TODO 使用腾讯云执行发送验证码,将验证码作为短信内容的参数变量放入,
|
||||
// TODO sdkAppId和签名不传则使用系统默认配置的sdkAppId和签名,支持传入多个参数,逗号拼接,示例:"张三,15038****76,进行中"
|
||||
devSmsApi.sendSmsTencent("sdkAppId", phone, "签名", "模板编码", phoneValidCode);
|
||||
|
||||
// 将请求号作为key,验证码的值作为value放到redis,用于校验,5分钟有效
|
||||
commonCacheOperator.put(AUTH_VALID_CODE_CACHE_KEY + phone + StrUtil.UNDERLINE + phoneValidCodeReqNo, phoneValidCode, 5 * 60);
|
||||
// 返回请求号
|
||||
return phoneValidCodeReqNo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验验证码方法
|
||||
*
|
||||
*
|
||||
* @date 2022/8/25 15:26
|
||||
**/
|
||||
private void validValidCode(String phoneOrEmail, String validCode, String validCodeReqNo) {
|
||||
// 依据请求号,取出缓存中的验证码进行校验
|
||||
Object existValidCode;
|
||||
if(ObjectUtil.isEmpty(phoneOrEmail)) {
|
||||
existValidCode = commonCacheOperator.get(AUTH_VALID_CODE_CACHE_KEY + validCodeReqNo);
|
||||
} else {
|
||||
existValidCode = commonCacheOperator.get(AUTH_VALID_CODE_CACHE_KEY + phoneOrEmail + StrUtil.UNDERLINE + validCodeReqNo);
|
||||
}
|
||||
// 为空则直接验证码错误
|
||||
if(ObjectUtil.isEmpty(existValidCode)) {
|
||||
throw new CommonException(AuthExceptionEnum.VALID_CODE_ERROR.getValue());
|
||||
}
|
||||
// 移除该验证码
|
||||
if(ObjectUtil.isEmpty(phoneOrEmail)) {
|
||||
commonCacheOperator.remove(AUTH_VALID_CODE_CACHE_KEY + validCodeReqNo);
|
||||
} else {
|
||||
commonCacheOperator.remove(AUTH_VALID_CODE_CACHE_KEY + phoneOrEmail + StrUtil.UNDERLINE + validCodeReqNo);
|
||||
}
|
||||
// 不一致则直接验证码错误
|
||||
if (!validCode.equals(Convert.toStr(existValidCode).toLowerCase())) {
|
||||
throw new CommonException("验证码错误");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验手机号与验证码等参数
|
||||
*
|
||||
*
|
||||
* @date 2022/8/25 14:29
|
||||
**/
|
||||
private void validPhoneValidCodeParam(String phoneOrEmail, String validCode, String validCodeReqNo, String type) {
|
||||
// 验证码正确则校验手机号格式
|
||||
if(ObjectUtil.isEmpty(phoneOrEmail)) {
|
||||
// 执行校验验证码
|
||||
validValidCode(null, validCode, validCodeReqNo);
|
||||
} else {
|
||||
if(!PhoneUtil.isMobile(phoneOrEmail) && !CommonEmailUtil.isEmail(phoneOrEmail)) {
|
||||
throw new CommonException(AuthExceptionEnum.PHONE_FORMAT_ERROR.getValue());
|
||||
}
|
||||
// 执行校验验证码
|
||||
validValidCode(phoneOrEmail, validCode, validCodeReqNo);
|
||||
|
||||
// 根据手机号获取用户信息,判断用户是否存在,根据B端或C端判断
|
||||
if(SaClientTypeEnum.B.getValue().equals(type)) {
|
||||
if(ObjectUtil.isEmpty(loginUserApi.getUserByPhone(phoneOrEmail))) {
|
||||
throw new CommonException(AuthExceptionEnum.PHONE_ERROR.getValue());
|
||||
}
|
||||
} else {
|
||||
if(ObjectUtil.isEmpty(clientLoginUserApi.getClientUserByPhone(phoneOrEmail))) {
|
||||
throw new CommonException(AuthExceptionEnum.PHONE_ERROR.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String doLogin(AuthAccountPasswordLoginParam authAccountPasswordLoginParam, String type) {
|
||||
// 获取账号
|
||||
String account = authAccountPasswordLoginParam.getAccount();
|
||||
// 获取密码
|
||||
String password = authAccountPasswordLoginParam.getPassword();
|
||||
// 获取设备
|
||||
String device = authAccountPasswordLoginParam.getDevice();
|
||||
// 默认指定为PC,如在小程序跟移动端的情况下,自行指定即可
|
||||
if(ObjectUtil.isEmpty(device)) {
|
||||
device = AuthDeviceTypeEnum.PC.getValue();
|
||||
} else {
|
||||
AuthDeviceTypeEnum.validate(device);
|
||||
}
|
||||
// 校验验证码
|
||||
String defaultCaptchaOpen = devConfigApi.getValueByKey(SNOWY_SYS_DEFAULT_CAPTCHA_OPEN_KEY);
|
||||
if(ObjectUtil.isNotEmpty(defaultCaptchaOpen)) {
|
||||
if(Convert.toBool(defaultCaptchaOpen)) {
|
||||
// 获取验证码
|
||||
String validCode = authAccountPasswordLoginParam.getValidCode();
|
||||
// 获取验证码请求号
|
||||
String validCodeReqNo = authAccountPasswordLoginParam.getValidCodeReqNo();
|
||||
// 开启验证码则必须传入验证码
|
||||
if(ObjectUtil.isEmpty(validCode)) {
|
||||
throw new CommonException(AuthExceptionEnum.VALID_CODE_EMPTY.getValue());
|
||||
}
|
||||
// 开启验证码则必须传入验证码请求号
|
||||
if(ObjectUtil.isEmpty(validCodeReqNo)) {
|
||||
throw new CommonException(AuthExceptionEnum.VALID_CODE_REQ_NO_EMPTY.getValue());
|
||||
}
|
||||
// 执行校验验证码
|
||||
validValidCode(null, validCode, validCodeReqNo);
|
||||
}
|
||||
}
|
||||
// SM2解密并获得前端传来的密码哈希值
|
||||
String passwordHash;
|
||||
try {
|
||||
// 解密,并做哈希值
|
||||
passwordHash = CommonCryptogramUtil.doHashValue(CommonCryptogramUtil.doSm2Decrypt(password));
|
||||
} catch (Exception e) {
|
||||
throw new CommonException(AuthExceptionEnum.PWD_DECRYPT_ERROR.getValue());
|
||||
}
|
||||
// 根据账号获取用户信息,根据B端或C端判断
|
||||
if(SaClientTypeEnum.B.getValue().equals(type)) {
|
||||
SaBaseLoginUser saBaseLoginUser = loginUserApi.getUserByAccount(account);
|
||||
if(ObjectUtil.isEmpty(saBaseLoginUser)) {
|
||||
throw new CommonException(AuthExceptionEnum.ACCOUNT_ERROR.getValue());
|
||||
}
|
||||
if (!saBaseLoginUser.getPassword().equals(passwordHash)) {
|
||||
throw new CommonException(AuthExceptionEnum.PWD_ERROR.getValue());
|
||||
}
|
||||
// 执行B端登录
|
||||
return execLoginB(saBaseLoginUser, device);
|
||||
} else {
|
||||
SaBaseClientLoginUser saBaseClientLoginUser = clientLoginUserApi.getClientUserByAccount(account);
|
||||
if(ObjectUtil.isEmpty(saBaseClientLoginUser)) {
|
||||
throw new CommonException(AuthExceptionEnum.ACCOUNT_ERROR.getValue());
|
||||
}
|
||||
if (!saBaseClientLoginUser.getPassword().equals(passwordHash)) {
|
||||
throw new CommonException(AuthExceptionEnum.PWD_ERROR.getValue());
|
||||
}
|
||||
// 执行C端登录
|
||||
return execLoginC(saBaseClientLoginUser, device);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String doLoginByPhone(AuthPhoneValidCodeLoginParam authPhoneValidCodeLoginParam, String type) {
|
||||
// 手机号
|
||||
String phone = authPhoneValidCodeLoginParam.getPhone();
|
||||
// 校验参数
|
||||
validPhoneValidCodeParam(phone, authPhoneValidCodeLoginParam.getValidCode(), authPhoneValidCodeLoginParam.getValidCodeReqNo(), type);
|
||||
// 设备
|
||||
String device = authPhoneValidCodeLoginParam.getDevice();
|
||||
// 默认指定为PC,如在小程序跟移动端的情况下,自行指定即可
|
||||
if(ObjectUtil.isEmpty(device)) {
|
||||
device = AuthDeviceTypeEnum.PC.getValue();
|
||||
} else {
|
||||
AuthDeviceTypeEnum.validate(device);
|
||||
}
|
||||
// 根据手机号获取用户信息,根据B端或C端判断
|
||||
if(SaClientTypeEnum.B.getValue().equals(type)) {
|
||||
SaBaseLoginUser saBaseLoginUser = loginUserApi.getUserByPhone(phone);
|
||||
if(ObjectUtil.isEmpty(saBaseLoginUser)) {
|
||||
throw new CommonException(AuthExceptionEnum.ACCOUNT_ERROR.getValue());
|
||||
}
|
||||
// 执行B端登录
|
||||
return execLoginB(saBaseLoginUser, device);
|
||||
} else {
|
||||
SaBaseClientLoginUser saBaseClientLoginUser = clientLoginUserApi.getClientUserByPhone(phone);
|
||||
if(ObjectUtil.isEmpty(saBaseClientLoginUser)) {
|
||||
throw new CommonException(AuthExceptionEnum.ACCOUNT_ERROR.getValue());
|
||||
}
|
||||
// 执行C端登录
|
||||
return execLoginC(saBaseClientLoginUser, device);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行B端登录
|
||||
*
|
||||
*
|
||||
* @date 2022/8/25 14:36
|
||||
**/
|
||||
private String execLoginB(SaBaseLoginUser saBaseLoginUser, String device) {
|
||||
// 校验状态
|
||||
if(!saBaseLoginUser.getEnabled()) {
|
||||
throw new CommonException(AuthExceptionEnum.ACCOUNT_DISABLED.getValue());
|
||||
}
|
||||
// 执行登录
|
||||
StpUtil.login(saBaseLoginUser.getId(), new SaLoginModel().setDevice(device).setExtra("name", saBaseLoginUser.getName()));
|
||||
// 角色集合
|
||||
List<JSONObject> roleList = loginUserApi.getRoleListByUserId(saBaseLoginUser.getId());
|
||||
// 角色id集合
|
||||
List<String> roleIdList = roleList.stream().map(jsonObject -> jsonObject.getStr("id")).collect(Collectors.toList());
|
||||
// 角色码集合
|
||||
List<String> roleCodeList = roleList.stream().map(jsonObject -> jsonObject.getStr("code")).collect(Collectors.toList());
|
||||
// 角色id和用户id集合
|
||||
List<String> userAndRoleIdList = CollectionUtil.unionAll(roleIdList, CollectionUtil.newArrayList(saBaseLoginUser.getId()));
|
||||
// 获取按钮码
|
||||
saBaseLoginUser.setButtonCodeList(loginUserApi.getButtonCodeListListByUserAndRoleIdList(userAndRoleIdList));
|
||||
// 获取移动端按钮码
|
||||
saBaseLoginUser.setMobileButtonCodeList(loginUserApi.getMobileButtonCodeListListByUserIdAndRoleIdList(userAndRoleIdList));
|
||||
// 获取数据范围
|
||||
saBaseLoginUser.setDataScopeList(Convert.toList(SaBaseLoginUser.DataScope.class,
|
||||
loginUserApi.getPermissionListByUserIdAndRoleIdList(userAndRoleIdList, saBaseLoginUser.getOrgId())));
|
||||
// 获取权限码
|
||||
saBaseLoginUser.setPermissionCodeList(saBaseLoginUser.getDataScopeList().stream()
|
||||
.map(SaBaseLoginUser.DataScope::getApiUrl).collect(Collectors.toList()));
|
||||
// 获取角色码
|
||||
saBaseLoginUser.setRoleCodeList(roleCodeList);
|
||||
// 缓存用户信息,此处使用TokenSession为了指定时间内无操作则自动下线
|
||||
StpUtil.getTokenSession().set("loginUser", saBaseLoginUser);
|
||||
// 返回token
|
||||
return StpUtil.getTokenInfo().tokenValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行C端登录
|
||||
*
|
||||
*
|
||||
* @date 2022/8/25 14:37
|
||||
**/
|
||||
private String execLoginC(SaBaseClientLoginUser saBaseClientLoginUser, String device) {
|
||||
// 校验状态
|
||||
if(!saBaseClientLoginUser.getEnabled()) {
|
||||
throw new CommonException(AuthExceptionEnum.ACCOUNT_DISABLED.getValue());
|
||||
}
|
||||
// 执行登录
|
||||
StpClientUtil.login(saBaseClientLoginUser.getId(), new SaLoginModel().setDevice(device).setExtra("name", saBaseClientLoginUser.getName()));
|
||||
// 角色集合
|
||||
List<JSONObject> roleList = loginUserApi.getRoleListByUserId(saBaseClientLoginUser.getId());
|
||||
// 角色id集合
|
||||
List<String> roleIdList = roleList.stream().map(jsonObject -> jsonObject.getStr("id")).collect(Collectors.toList());
|
||||
// 角色码集合
|
||||
List<String> roleCodeList = roleList.stream().map(jsonObject -> jsonObject.getStr("code")).collect(Collectors.toList());
|
||||
// 角色id和用户id集合
|
||||
List<String> userAndRoleIdList = CollectionUtil.unionAll(roleIdList, CollectionUtil.newArrayList(saBaseClientLoginUser.getId()));
|
||||
// 获取按钮码
|
||||
saBaseClientLoginUser.setButtonCodeList(clientLoginUserApi.getButtonCodeListListByUserAndRoleIdList(userAndRoleIdList));
|
||||
// 获取移动端按钮码
|
||||
saBaseClientLoginUser.setMobileButtonCodeList(clientLoginUserApi.getMobileButtonCodeListListByUserIdAndRoleIdList(userAndRoleIdList));
|
||||
// 获取数据范围
|
||||
saBaseClientLoginUser.setDataScopeList(Convert.toList(SaBaseClientLoginUser.DataScope.class,
|
||||
clientLoginUserApi.getPermissionListByUserIdAndRoleIdList(userAndRoleIdList, null)));
|
||||
// 获取权限码
|
||||
saBaseClientLoginUser.setPermissionCodeList(saBaseClientLoginUser.getDataScopeList().stream()
|
||||
.map(SaBaseClientLoginUser.DataScope::getApiUrl).collect(Collectors.toList()));
|
||||
// 获取角色码
|
||||
saBaseClientLoginUser.setRoleCodeList(roleCodeList);
|
||||
// 缓存用户信息,此处使用TokenSession为了指定时间内无操作则自动下线
|
||||
StpClientUtil.getTokenSession().set("loginUser", saBaseClientLoginUser);
|
||||
// 返回token
|
||||
return StpClientUtil.getTokenInfo().tokenValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取B端登录用户信息
|
||||
*
|
||||
*
|
||||
* @date 2021/10/12 15:59
|
||||
**/
|
||||
@Override
|
||||
public SaBaseLoginUser getLoginUser() {
|
||||
SaBaseLoginUser saBaseLoginUser = StpLoginUserUtil.getLoginUser();
|
||||
saBaseLoginUser.setPassword(null);
|
||||
saBaseLoginUser.setPermissionCodeList(null);
|
||||
saBaseLoginUser.setDataScopeList(null);
|
||||
return saBaseLoginUser;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取C端登录用户信息
|
||||
*
|
||||
*
|
||||
* @date 2021/10/12 15:59
|
||||
**/
|
||||
@Override
|
||||
public SaBaseClientLoginUser getClientLoginUser() {
|
||||
SaBaseClientLoginUser saBaseClientLoginUser = StpClientLoginUserUtil.getClientLoginUser();
|
||||
saBaseClientLoginUser.setPassword(null);
|
||||
saBaseClientLoginUser.setPermissionCodeList(null);
|
||||
saBaseClientLoginUser.setDataScopeList(null);
|
||||
return saBaseClientLoginUser;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String doLoginById(String userId, String device, String type) {
|
||||
// 根据id获取用户信息,根据B端或C端判断
|
||||
if(SaClientTypeEnum.B.getValue().equals(type)) {
|
||||
SaBaseLoginUser saBaseLoginUser = loginUserApi.getUserById(userId);
|
||||
if (ObjectUtil.isEmpty(saBaseLoginUser)) {
|
||||
throw new CommonException(AuthExceptionEnum.ACCOUNT_ERROR.getValue());
|
||||
}
|
||||
// 执行B端登录
|
||||
return execLoginB(saBaseLoginUser, device);
|
||||
} else {
|
||||
SaBaseClientLoginUser saBaseClientLoginUser = clientLoginUserApi.getClientUserById(userId);
|
||||
if (ObjectUtil.isEmpty(saBaseClientLoginUser)) {
|
||||
throw new CommonException(AuthExceptionEnum.ACCOUNT_ERROR.getValue());
|
||||
}
|
||||
// 执行C端登录
|
||||
return execLoginC(saBaseClientLoginUser, device);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,145 @@
|
||||
|
||||
package mjkf.xinke.auth.modular.monitor.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
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.RestController;
|
||||
import mjkf.xinke.auth.modular.monitor.param.AuthExitSessionParam;
|
||||
import mjkf.xinke.auth.modular.monitor.param.AuthExitTokenParam;
|
||||
import mjkf.xinke.auth.modular.monitor.param.AuthSessionPageParam;
|
||||
import mjkf.xinke.auth.modular.monitor.result.AuthSessionAnalysisResult;
|
||||
import mjkf.xinke.auth.modular.monitor.result.AuthSessionPageResult;
|
||||
import mjkf.xinke.auth.modular.monitor.service.AuthSessionService;
|
||||
import mjkf.xinke.common.annotation.CommonLog;
|
||||
import mjkf.xinke.common.pojo.CommonResult;
|
||||
import mjkf.xinke.common.pojo.CommonValidList;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
|
||||
/**
|
||||
* 会话治理控制器
|
||||
*
|
||||
*
|
||||
* @date 2022/6/24 15:20
|
||||
**/
|
||||
@Api(tags = "会话治理控制器")
|
||||
@ApiSupport(author = "SNOWY_TEAM", order = 3)
|
||||
@RestController
|
||||
@Validated
|
||||
public class AuthSessionController {
|
||||
|
||||
@Resource
|
||||
private AuthSessionService authSessionService;
|
||||
|
||||
/**
|
||||
* 会话统计
|
||||
*
|
||||
*
|
||||
* @date 2022/6/24 22:28
|
||||
*/
|
||||
@ApiOperationSupport(order = 1)
|
||||
@ApiOperation("会话统计")
|
||||
@GetMapping("/auth/session/analysis")
|
||||
public CommonResult<AuthSessionAnalysisResult> analysis() {
|
||||
return CommonResult.data(authSessionService.analysis());
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询B端会话
|
||||
*
|
||||
*
|
||||
* @date 2022/6/24 22:28
|
||||
*/
|
||||
@ApiOperationSupport(order = 2)
|
||||
@ApiOperation("查询B端会话")
|
||||
@GetMapping("/auth/session/b/page")
|
||||
public CommonResult<Page<AuthSessionPageResult>> pageForB(AuthSessionPageParam authSessionPageParam) {
|
||||
return CommonResult.data(authSessionService.pageForB(authSessionPageParam));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询C端会话
|
||||
*
|
||||
*
|
||||
* @date 2022/6/24 22:28
|
||||
*/
|
||||
@ApiOperationSupport(order = 3)
|
||||
@ApiOperation("查询C端会话")
|
||||
@GetMapping("/auth/session/c/page")
|
||||
public CommonResult<Page<AuthSessionPageResult>> pageForC(AuthSessionPageParam authSessionPageParam) {
|
||||
return CommonResult.data(authSessionService.pageForC(authSessionPageParam));
|
||||
}
|
||||
|
||||
/**
|
||||
* 强退B端会话
|
||||
*
|
||||
*
|
||||
* @date 2021/10/12 10:25
|
||||
**/
|
||||
@ApiOperationSupport(order = 4)
|
||||
@ApiOperation("强退B端会话")
|
||||
@CommonLog("强退B端会话")
|
||||
@PostMapping("/auth/session/b/exit")
|
||||
public CommonResult<String> exitSessionForB(@RequestBody @Valid @NotEmpty(message = "集合不能为空")
|
||||
CommonValidList<AuthExitSessionParam> authExitSessionParamList) {
|
||||
authSessionService.exitSessionForB(authExitSessionParamList);
|
||||
return CommonResult.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 强退C端会话
|
||||
*
|
||||
*
|
||||
* @date 2021/10/12 10:25
|
||||
**/
|
||||
@ApiOperationSupport(order = 5)
|
||||
@ApiOperation("强退C端会话")
|
||||
@CommonLog("强退C端会话")
|
||||
@PostMapping("/auth/session/c/exit")
|
||||
public CommonResult<String> exitSessionForC(@RequestBody @Valid @NotEmpty(message = "集合不能为空")
|
||||
CommonValidList<AuthExitSessionParam> authExitSessionParamList) {
|
||||
authSessionService.exitSessionForC(authExitSessionParamList);
|
||||
return CommonResult.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 强退B端token
|
||||
*
|
||||
*
|
||||
* @date 2021/10/12 10:25
|
||||
**/
|
||||
@ApiOperationSupport(order = 6)
|
||||
@ApiOperation("强退B端token")
|
||||
@CommonLog("强退B端token")
|
||||
@PostMapping("/auth/token/b/exit")
|
||||
public CommonResult<String> exitTokenForB(@RequestBody @Valid @NotEmpty(message = "集合不能为空")
|
||||
CommonValidList<AuthExitTokenParam> authExitTokenParamList) {
|
||||
authSessionService.exitTokenForB(authExitTokenParamList);
|
||||
return CommonResult.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 强退C端token
|
||||
*
|
||||
*
|
||||
* @date 2021/10/12 10:25
|
||||
**/
|
||||
@ApiOperationSupport(order = 7)
|
||||
@ApiOperation("强退C端token")
|
||||
@CommonLog("强退C端token")
|
||||
@PostMapping("/auth/token/c/exit")
|
||||
public CommonResult<String> exitTokenForC(@RequestBody @Valid @NotEmpty(message = "集合不能为空")
|
||||
CommonValidList<AuthExitTokenParam> authExitTokenParamList) {
|
||||
authSessionService.exitTokenForC(authExitTokenParamList);
|
||||
return CommonResult.ok();
|
||||
}
|
||||
}
|
@@ -0,0 +1,24 @@
|
||||
|
||||
package mjkf.xinke.auth.modular.monitor.param;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
/**
|
||||
* Session退出参数
|
||||
*
|
||||
*
|
||||
* @date 2022/6/24 22:28
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class AuthExitSessionParam {
|
||||
|
||||
/** 用户id */
|
||||
@ApiModelProperty(value = "用户id", required = true)
|
||||
@NotBlank(message = "userId不能为空")
|
||||
private String userId;
|
||||
}
|
@@ -0,0 +1,24 @@
|
||||
|
||||
package mjkf.xinke.auth.modular.monitor.param;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
/**
|
||||
* Token退出参数
|
||||
*
|
||||
*
|
||||
* @date 2022/6/24 22:28
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class AuthExitTokenParam {
|
||||
|
||||
/** token值 */
|
||||
@ApiModelProperty(value = "token值", required = true)
|
||||
@NotBlank(message = "tokenValue不能为空")
|
||||
private String tokenValue;
|
||||
}
|
@@ -0,0 +1,21 @@
|
||||
|
||||
package mjkf.xinke.auth.modular.monitor.param;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* 会话查询参数
|
||||
*
|
||||
*
|
||||
* @date 2022/7/28 14:48
|
||||
**/
|
||||
@Getter
|
||||
@Setter
|
||||
public class AuthSessionPageParam {
|
||||
|
||||
/** 用户id */
|
||||
@ApiModelProperty(value = "用户id")
|
||||
private String userId;
|
||||
}
|
@@ -0,0 +1,33 @@
|
||||
|
||||
package mjkf.xinke.auth.modular.monitor.result;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* 会话统计结果
|
||||
*
|
||||
*
|
||||
* @date 2022/7/19 9:29
|
||||
**/
|
||||
@Getter
|
||||
@Setter
|
||||
public class AuthSessionAnalysisResult {
|
||||
|
||||
/** 当前会话总数量 */
|
||||
@ApiModelProperty(value = "当前会话总数量", position = 1)
|
||||
private String currentSessionTotalCount;
|
||||
|
||||
/** 最大签发令牌数 */
|
||||
@ApiModelProperty(value = "最大签发令牌数", position = 2)
|
||||
private String maxTokenCount;
|
||||
|
||||
/** 最近1小时会话数 */
|
||||
@ApiModelProperty(value = "最近1小时会话数", position = 3)
|
||||
private String oneHourNewlyAdded;
|
||||
|
||||
/** BC端会话比例 */
|
||||
@ApiModelProperty(value = "BC端会话比例", position = 4)
|
||||
private String proportionOfBAndC;
|
||||
}
|
@@ -0,0 +1,115 @@
|
||||
|
||||
package mjkf.xinke.auth.modular.monitor.result;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* B端会话结果集
|
||||
*
|
||||
*
|
||||
* @date 2022/7/28 14:46
|
||||
**/
|
||||
@Getter
|
||||
@Setter
|
||||
public class AuthSessionPageResult {
|
||||
|
||||
/** id */
|
||||
@ApiModelProperty(value = "id", position = 1)
|
||||
private String id;
|
||||
|
||||
/** 头像 */
|
||||
@ApiModelProperty(value = "头像", position = 2)
|
||||
private String avatar;
|
||||
|
||||
/** 账号 */
|
||||
@ApiModelProperty(value = "账号", position = 3)
|
||||
private String account;
|
||||
|
||||
/** 姓名 */
|
||||
@ApiModelProperty(value = "姓名", position = 4)
|
||||
private String name;
|
||||
|
||||
/** 上次登录ip */
|
||||
@ApiModelProperty(value = "上次登录ip", position = 5)
|
||||
private String lastLoginIp;
|
||||
|
||||
/** 上次登录地点 */
|
||||
@ApiModelProperty(value = "上次登录地点", position = 6)
|
||||
private String lastLoginAddress;
|
||||
|
||||
/** 上次登录时间 */
|
||||
@ApiModelProperty(value = "上次登录时间", position = 7)
|
||||
private Date lastLoginTime;
|
||||
|
||||
/** 上次登录设备 */
|
||||
@ApiModelProperty(value = "上次登录设备", position = 8)
|
||||
private String lastLoginDevice;
|
||||
|
||||
/** 最新登录ip */
|
||||
@ApiModelProperty(value = "最新登录ip", position = 9)
|
||||
private String latestLoginIp;
|
||||
|
||||
/** 最新登录地点 */
|
||||
@ApiModelProperty(value = "最新登录地点", position = 10)
|
||||
private String latestLoginAddress;
|
||||
|
||||
/** 最新登录时间 */
|
||||
@ApiModelProperty(value = "最新登录时间", position = 11)
|
||||
private Date latestLoginTime;
|
||||
|
||||
/** 最新登录设备 */
|
||||
@ApiModelProperty(value = "最新登录设备", position = 12)
|
||||
private String latestLoginDevice;
|
||||
|
||||
/** 会话id */
|
||||
@ApiModelProperty(value = "会话id", position = 13)
|
||||
private String sessionId;
|
||||
|
||||
/** 会话创建时间 */
|
||||
@ApiModelProperty(value = "会话创建时间", position = 14)
|
||||
private Date sessionCreateTime;
|
||||
|
||||
/** 会话剩余有效期 */
|
||||
@ApiModelProperty(value = "会话剩余有效期", position = 15)
|
||||
private String sessionTimeout;
|
||||
|
||||
/** 令牌数量 */
|
||||
@ApiModelProperty(value = "令牌数量", position = 16)
|
||||
private Integer tokenCount;
|
||||
|
||||
/** 令牌信息集合 */
|
||||
@ApiModelProperty(value = "令牌信息集合", position = 17)
|
||||
private List<TokenSignInfo> tokenSignList;
|
||||
|
||||
/**
|
||||
* 令牌信息类
|
||||
*
|
||||
*
|
||||
* @date 2022/7/28 15:04
|
||||
**/
|
||||
@Getter
|
||||
@Setter
|
||||
public static class TokenSignInfo {
|
||||
|
||||
/** token值 */
|
||||
@ApiModelProperty(value = "token值", position = 1)
|
||||
private String tokenValue;
|
||||
|
||||
/** 登录设备 */
|
||||
@ApiModelProperty(value = "登录设备", position = 2)
|
||||
private String tokenDevice;
|
||||
|
||||
/** token剩余有效期 */
|
||||
@ApiModelProperty(value = "token剩余有效期", position = 3)
|
||||
private String tokenTimeout;
|
||||
|
||||
/** token剩余有效期百分比 */
|
||||
@ApiModelProperty(value = "token剩余有效期百分比", position = 4)
|
||||
private Double tokenTimeoutPercent;
|
||||
}
|
||||
}
|
@@ -0,0 +1,76 @@
|
||||
|
||||
package mjkf.xinke.auth.modular.monitor.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import mjkf.xinke.auth.modular.monitor.param.AuthExitSessionParam;
|
||||
import mjkf.xinke.auth.modular.monitor.param.AuthExitTokenParam;
|
||||
import mjkf.xinke.auth.modular.monitor.param.AuthSessionPageParam;
|
||||
import mjkf.xinke.auth.modular.monitor.result.AuthSessionAnalysisResult;
|
||||
import mjkf.xinke.auth.modular.monitor.result.AuthSessionPageResult;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 会话治理Service接口
|
||||
*
|
||||
*
|
||||
* @date 2022/6/24 15:46S
|
||||
**/
|
||||
public interface AuthSessionService {
|
||||
|
||||
/**
|
||||
* 会话统计
|
||||
*
|
||||
*
|
||||
* @date 2022/7/19 9:33
|
||||
**/
|
||||
AuthSessionAnalysisResult analysis();
|
||||
|
||||
/**
|
||||
* 查询B端会话
|
||||
*
|
||||
*
|
||||
* @date 2022/6/24 22:30
|
||||
*/
|
||||
Page<AuthSessionPageResult> pageForB(AuthSessionPageParam authSessionPageParam);
|
||||
|
||||
/**
|
||||
* 查询C端会话
|
||||
*
|
||||
*
|
||||
* @date 2022/6/24 22:30
|
||||
*/
|
||||
Page<AuthSessionPageResult> pageForC(AuthSessionPageParam authSessionPageParam);
|
||||
|
||||
/**
|
||||
* 强退B端会话
|
||||
*
|
||||
*
|
||||
* @date 2022/6/29 21:47
|
||||
*/
|
||||
void exitSessionForB(List<AuthExitSessionParam> authExitSessionParamList);
|
||||
|
||||
/**
|
||||
* 强退C端会话
|
||||
*
|
||||
*
|
||||
* @date 2022/6/29 21:47
|
||||
*/
|
||||
void exitSessionForC(List<AuthExitSessionParam> authExitSessionParamList);
|
||||
|
||||
/**
|
||||
* 强退B端token
|
||||
*
|
||||
*
|
||||
* @date 2022/6/29 21:47
|
||||
*/
|
||||
void exitTokenForB(List<AuthExitTokenParam> authExitTokenParamList);
|
||||
|
||||
/**
|
||||
* 强退C端token
|
||||
*
|
||||
*
|
||||
* @date 2022/6/29 21:47
|
||||
*/
|
||||
void exitTokenForC(List<AuthExitTokenParam> authExitTokenParamList);
|
||||
}
|
@@ -0,0 +1,227 @@
|
||||
|
||||
package mjkf.xinke.auth.modular.monitor.service.impl;
|
||||
|
||||
import cn.dev33.satoken.SaManager;
|
||||
import cn.dev33.satoken.session.SaSession;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.date.DateField;
|
||||
import cn.hutool.core.date.DateTime;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.NumberUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import org.springframework.stereotype.Service;
|
||||
import mjkf.xinke.auth.api.SaBaseLoginUserApi;
|
||||
import mjkf.xinke.auth.core.util.StpClientUtil;
|
||||
import mjkf.xinke.auth.modular.monitor.param.AuthExitSessionParam;
|
||||
import mjkf.xinke.auth.modular.monitor.param.AuthExitTokenParam;
|
||||
import mjkf.xinke.auth.modular.monitor.param.AuthSessionPageParam;
|
||||
import mjkf.xinke.auth.modular.monitor.result.AuthSessionAnalysisResult;
|
||||
import mjkf.xinke.auth.modular.monitor.result.AuthSessionPageResult;
|
||||
import mjkf.xinke.auth.modular.monitor.service.AuthSessionService;
|
||||
import mjkf.xinke.common.page.CommonPageRequest;
|
||||
import mjkf.xinke.common.util.CommonTimeFormatUtil;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 会话治理Service接口实现类
|
||||
*
|
||||
*
|
||||
* @date 2022/6/24 22:25
|
||||
*/
|
||||
@Service
|
||||
public class AuthSessionServiceImpl implements AuthSessionService {
|
||||
|
||||
@Resource(name = "loginUserApi")
|
||||
private SaBaseLoginUserApi loginUserApi;
|
||||
|
||||
@Resource(name = "clientLoginUserApi")
|
||||
private SaBaseLoginUserApi clientLoginUserApi;
|
||||
|
||||
@Override
|
||||
public AuthSessionAnalysisResult analysis() {
|
||||
AuthSessionAnalysisResult authSessionAnalysisResult = new AuthSessionAnalysisResult();
|
||||
List<JSONObject> sessionListB = StpUtil.searchSessionId("", -1, -1, true).stream().map(sessionId -> {
|
||||
JSONObject jsonObject = JSONUtil.createObj();
|
||||
String userId = StrUtil.split(sessionId, StrUtil.COLON).get(3);
|
||||
SaSession saSession = StpUtil.getSessionByLoginId(userId, false);
|
||||
int tokenCount = saSession.getTokenSignList().size();
|
||||
long createTime = saSession.getCreateTime();
|
||||
jsonObject.set("userId", userId);
|
||||
jsonObject.set("tokenCount", tokenCount);
|
||||
jsonObject.set("createTime", DateTime.of(createTime));
|
||||
return jsonObject;
|
||||
}).collect(Collectors.toList());
|
||||
|
||||
List<JSONObject> sessionListC = StpClientUtil.searchSessionId("", -1, -1, true).stream().map(sessionId -> {
|
||||
JSONObject jsonObject = JSONUtil.createObj();
|
||||
String userId = StrUtil.split(sessionId, StrUtil.COLON).get(3);
|
||||
SaSession saSession = StpClientUtil.getSessionByLoginId(userId, false);
|
||||
int tokenCount = saSession.getTokenSignList().size();
|
||||
long createTime = saSession.getCreateTime();
|
||||
jsonObject.set("userId", userId);
|
||||
jsonObject.set("tokenCount", tokenCount);
|
||||
jsonObject.set("createTime", DateTime.of(createTime));
|
||||
return jsonObject;
|
||||
}).collect(Collectors.toList());
|
||||
|
||||
List<Integer> tokenCountList = CollectionUtil.newArrayList();
|
||||
tokenCountList.addAll(sessionListB.stream().map(jsonObject -> jsonObject.getInt("tokenCount")).collect(Collectors.toList()));
|
||||
tokenCountList.addAll(sessionListC.stream().map(jsonObject -> jsonObject.getInt("tokenCount")).collect(Collectors.toList()));
|
||||
CollectionUtil.sort(tokenCountList, Comparator.comparingInt(Integer::intValue));
|
||||
int currentSessionTotalCount = sessionListB.size() + sessionListC.size();
|
||||
authSessionAnalysisResult.setCurrentSessionTotalCount(Convert.toStr(currentSessionTotalCount));
|
||||
authSessionAnalysisResult.setMaxTokenCount(Convert.toStr(tokenCountList.get(tokenCountList.size() - 1)));
|
||||
List<Date> sessionCreateTimeList = CollectionUtil.newArrayList();
|
||||
sessionCreateTimeList.addAll(sessionListB.stream().map(jsonObject -> jsonObject.getDate("createTime")).collect(Collectors.toList()));
|
||||
sessionCreateTimeList.addAll(sessionListC.stream().map(jsonObject -> jsonObject.getDate("createTime")).collect(Collectors.toList()));
|
||||
DateTime oneHourAgo = DateUtil.offset(DateTime.now(), DateField.HOUR, -1);
|
||||
authSessionAnalysisResult.setOneHourNewlyAdded(Convert.toStr(sessionCreateTimeList.stream().filter(date -> DateUtil.compare(oneHourAgo, date) <= 0).count()));
|
||||
authSessionAnalysisResult.setProportionOfBAndC(sessionListB.size() + StrUtil.SLASH + sessionListC.size());
|
||||
return authSessionAnalysisResult;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<AuthSessionPageResult> pageForB(AuthSessionPageParam authSessionPageParam) {
|
||||
Page<AuthSessionPageResult> defaultPage = CommonPageRequest.defaultPage();
|
||||
long current = defaultPage.getCurrent();
|
||||
int total = StpUtil.searchSessionId("", -1, Convert.toInt(defaultPage.getSize()), true).size();
|
||||
if(ObjectUtil.isNotEmpty(total)) {
|
||||
defaultPage = new Page<>(current, defaultPage.getSize(), total);
|
||||
String keyword = "";
|
||||
if(ObjectUtil.isNotEmpty(authSessionPageParam.getUserId())) {
|
||||
keyword = authSessionPageParam.getUserId();
|
||||
}
|
||||
List<String> userIdList = StpUtil.searchSessionId(keyword,
|
||||
Convert.toInt((current - 1) * defaultPage.getSize()),
|
||||
Convert.toInt(defaultPage.getSize()), true).stream().map(sessionId ->
|
||||
StrUtil.split(sessionId, StrUtil.COLON).get(3)).collect(Collectors.toList());
|
||||
if (ObjectUtil.isNotEmpty(userIdList)) {
|
||||
List<AuthSessionPageResult> authSessionPageResultList = loginUserApi.listUserByUserIdList(userIdList).stream().map(userJsonObject -> {
|
||||
SaSession saSession = StpUtil.getSessionByLoginId(userJsonObject.getStr("id"), false);
|
||||
AuthSessionPageResult authSessionPageResult = JSONUtil.toBean(userJsonObject, AuthSessionPageResult.class);
|
||||
authSessionPageResult.setSessionId(saSession.getId());
|
||||
authSessionPageResult.setSessionCreateTime(DateTime.of(saSession.getCreateTime()));
|
||||
long sessionTimeOut = saSession.getTimeout();
|
||||
if(sessionTimeOut == -1) {
|
||||
authSessionPageResult.setSessionTimeout("永久");
|
||||
} else {
|
||||
authSessionPageResult.setSessionTimeout(CommonTimeFormatUtil.formatSeconds(saSession.getTimeout()));
|
||||
}
|
||||
List<AuthSessionPageResult.TokenSignInfo> tokenInfoList = saSession.getTokenSignList().stream().map(tokenSign -> {
|
||||
AuthSessionPageResult.TokenSignInfo tokenSignInfo = new AuthSessionPageResult.TokenSignInfo();
|
||||
tokenSignInfo.setTokenValue(tokenSign.getValue());
|
||||
tokenSignInfo.setTokenDevice(tokenSign.getDevice());
|
||||
long tokenTimeout = SaManager.getSaTokenDao().getTimeout(StpUtil.stpLogic.splicingKeyTokenValue(tokenSign.getValue()));
|
||||
long tokenTimeoutConfig = StpUtil.stpLogic.getConfig().getTimeout();
|
||||
if(tokenTimeout == -1) {
|
||||
tokenSignInfo.setTokenTimeout("永久");
|
||||
tokenSignInfo.setTokenTimeoutPercent(100d);
|
||||
} else {
|
||||
tokenSignInfo.setTokenTimeout(CommonTimeFormatUtil.formatSeconds(SaManager.getSaTokenDao()
|
||||
.getTimeout(StpUtil.stpLogic.splicingKeyTokenValue(tokenSign.getValue()))));
|
||||
if(tokenTimeoutConfig == -1) {
|
||||
tokenSignInfo.setTokenTimeoutPercent(0d);
|
||||
} else {
|
||||
tokenSignInfo.setTokenTimeoutPercent(NumberUtil.div(tokenTimeout, tokenTimeoutConfig));
|
||||
}
|
||||
}
|
||||
return tokenSignInfo;
|
||||
}).collect(Collectors.toList());
|
||||
authSessionPageResult.setTokenCount(tokenInfoList.size());
|
||||
authSessionPageResult.setTokenSignList(tokenInfoList);
|
||||
return authSessionPageResult;
|
||||
}).collect(Collectors.toList());
|
||||
defaultPage.setRecords(authSessionPageResultList);
|
||||
}
|
||||
}
|
||||
return defaultPage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<AuthSessionPageResult> pageForC(AuthSessionPageParam authSessionPageParam) {
|
||||
Page<AuthSessionPageResult> defaultPage = CommonPageRequest.defaultPage();
|
||||
long current = defaultPage.getCurrent();
|
||||
int total = StpClientUtil.searchSessionId("", -1, Convert.toInt(defaultPage.getSize()), true).size();
|
||||
if(ObjectUtil.isNotEmpty(total)) {
|
||||
defaultPage = new Page<>(current, defaultPage.getSize(), total);
|
||||
String keyword = "";
|
||||
if(ObjectUtil.isNotEmpty(authSessionPageParam.getUserId())) {
|
||||
keyword = authSessionPageParam.getUserId();
|
||||
}
|
||||
List<String> userIdList = StpClientUtil.searchSessionId(keyword,
|
||||
Convert.toInt((current - 1) * defaultPage.getSize()),
|
||||
Convert.toInt(defaultPage.getSize()), true).stream().map(sessionId ->
|
||||
StrUtil.split(sessionId, StrUtil.COLON).get(3)).collect(Collectors.toList());
|
||||
if (ObjectUtil.isNotEmpty(userIdList)) {
|
||||
List<AuthSessionPageResult> authSessionPageResultList = clientLoginUserApi.listUserByUserIdList(userIdList).stream().map(userJsonObject -> {
|
||||
SaSession saSession = StpClientUtil.getSessionByLoginId(userJsonObject.getStr("id"), false);
|
||||
AuthSessionPageResult authSessionPageResult = JSONUtil.toBean(userJsonObject, AuthSessionPageResult.class);
|
||||
authSessionPageResult.setSessionId(saSession.getId());
|
||||
authSessionPageResult.setSessionCreateTime(DateTime.of(saSession.getCreateTime()));
|
||||
long sessionTimeOut = saSession.getTimeout();
|
||||
if(sessionTimeOut == -1) {
|
||||
authSessionPageResult.setSessionTimeout("永久");
|
||||
} else {
|
||||
authSessionPageResult.setSessionTimeout(CommonTimeFormatUtil.formatSeconds(saSession.getTimeout()));
|
||||
}
|
||||
List<AuthSessionPageResult.TokenSignInfo> tokenInfoList = saSession.getTokenSignList().stream().map(tokenSign -> {
|
||||
AuthSessionPageResult.TokenSignInfo tokenSignInfo = new AuthSessionPageResult.TokenSignInfo();
|
||||
tokenSignInfo.setTokenValue(tokenSign.getValue());
|
||||
tokenSignInfo.setTokenDevice(tokenSign.getDevice());
|
||||
long tokenTimeout = SaManager.getSaTokenDao().getTimeout(StpClientUtil.stpLogic.splicingKeyTokenValue(tokenSign.getValue()));
|
||||
long tokenTimeoutConfig = StpClientUtil.stpLogic.getConfig().getTimeout();
|
||||
if(tokenTimeout == -1) {
|
||||
tokenSignInfo.setTokenTimeout("永久");
|
||||
tokenSignInfo.setTokenTimeoutPercent(100d);
|
||||
} else {
|
||||
tokenSignInfo.setTokenTimeout(CommonTimeFormatUtil.formatSeconds(SaManager.getSaTokenDao()
|
||||
.getTimeout(StpClientUtil.stpLogic.splicingKeyTokenValue(tokenSign.getValue()))));
|
||||
if(tokenTimeoutConfig == -1) {
|
||||
tokenSignInfo.setTokenTimeoutPercent(0d);
|
||||
} else {
|
||||
tokenSignInfo.setTokenTimeoutPercent(NumberUtil.div(tokenTimeout, tokenTimeoutConfig));
|
||||
}
|
||||
}
|
||||
return tokenSignInfo;
|
||||
}).collect(Collectors.toList());
|
||||
authSessionPageResult.setTokenCount(tokenInfoList.size());
|
||||
authSessionPageResult.setTokenSignList(tokenInfoList);
|
||||
return authSessionPageResult;
|
||||
}).collect(Collectors.toList());
|
||||
defaultPage.setRecords(authSessionPageResultList);
|
||||
}
|
||||
}
|
||||
return defaultPage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exitSessionForB(List<AuthExitSessionParam> authExitSessionParamList) {
|
||||
authExitSessionParamList.forEach(authExitSessionParam -> StpUtil.logout(authExitSessionParam.getUserId()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exitSessionForC(List<AuthExitSessionParam> authExitSessionParamList) {
|
||||
authExitSessionParamList.forEach(authExitSessionParam -> StpClientUtil.logout(authExitSessionParam.getUserId()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exitTokenForB(List<AuthExitTokenParam> authExitTokenParamList) {
|
||||
authExitTokenParamList.forEach(authExitTokenParam -> StpUtil.logoutByTokenValue(authExitTokenParam.getTokenValue()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exitTokenForC(List<AuthExitTokenParam> authExitTokenParamList) {
|
||||
authExitTokenParamList.forEach(authExitTokenParam -> StpClientUtil.logoutByTokenValue(authExitTokenParam.getTokenValue()));
|
||||
}
|
||||
}
|
@@ -0,0 +1,47 @@
|
||||
|
||||
package mjkf.xinke.auth.modular.sso.controller;
|
||||
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import mjkf.xinke.auth.core.enums.SaClientTypeEnum;
|
||||
import mjkf.xinke.auth.modular.sso.param.AuthSsoTicketLoginParam;
|
||||
import mjkf.xinke.auth.modular.sso.service.AuthSsoService;
|
||||
import mjkf.xinke.common.pojo.CommonResult;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
|
||||
/**
|
||||
* 单点登录控制器
|
||||
*
|
||||
*
|
||||
* @date 2022/8/30 9:20
|
||||
**/
|
||||
@Api(tags = "单点登录控制器")
|
||||
@ApiSupport(author = "SNOWY_TEAM", order = 4)
|
||||
@RestController
|
||||
@Validated
|
||||
public class AuthSsoController {
|
||||
|
||||
@Resource
|
||||
private AuthSsoService authSsoService;
|
||||
|
||||
/**
|
||||
* 根据ticket执行单点登录
|
||||
*
|
||||
*
|
||||
* @date 2021/10/15 13:12
|
||||
**/
|
||||
@ApiOperationSupport(order = 1)
|
||||
@ApiOperation("根据ticket执行单点登录")
|
||||
@PostMapping("/auth/sso/doLogin")
|
||||
public CommonResult<String> doLogin(@RequestBody @Valid AuthSsoTicketLoginParam authAccountPasswordLoginParam) {
|
||||
return CommonResult.data(authSsoService.doLogin(authAccountPasswordLoginParam, SaClientTypeEnum.B.getValue()));
|
||||
}
|
||||
}
|
@@ -0,0 +1,28 @@
|
||||
|
||||
package mjkf.xinke.auth.modular.sso.param;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
/**
|
||||
* ticket单点登录登录参数
|
||||
*
|
||||
*
|
||||
* @date 2022/7/7 16:46
|
||||
**/
|
||||
@Getter
|
||||
@Setter
|
||||
public class AuthSsoTicketLoginParam {
|
||||
|
||||
/** ticket */
|
||||
@ApiModelProperty(value = "ticket", required = true, position = 1)
|
||||
@NotBlank(message = "ticket不能为空")
|
||||
private String ticket;
|
||||
|
||||
/** 设备 */
|
||||
@ApiModelProperty(value = "设备", position = 2)
|
||||
private String device;
|
||||
}
|
@@ -0,0 +1,21 @@
|
||||
|
||||
package mjkf.xinke.auth.modular.sso.service;
|
||||
|
||||
import mjkf.xinke.auth.modular.sso.param.AuthSsoTicketLoginParam;
|
||||
|
||||
/**
|
||||
* 单点登录Service接口
|
||||
*
|
||||
*
|
||||
* @date 2022/8/30 9:20
|
||||
**/
|
||||
public interface AuthSsoService {
|
||||
|
||||
/**
|
||||
* 根据ticket执行单点登录
|
||||
*
|
||||
*
|
||||
* @date 2022/8/30 9:36
|
||||
**/
|
||||
String doLogin(AuthSsoTicketLoginParam authAccountPasswordLoginParam, String value);
|
||||
}
|
@@ -0,0 +1,27 @@
|
||||
|
||||
package mjkf.xinke.auth.modular.sso.service.impl;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
import mjkf.xinke.auth.modular.login.service.AuthService;
|
||||
import mjkf.xinke.auth.modular.sso.param.AuthSsoTicketLoginParam;
|
||||
import mjkf.xinke.auth.modular.sso.service.AuthSsoService;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* 单点登录Service接口实现类
|
||||
*
|
||||
*
|
||||
* @date 2022/8/30 9:21
|
||||
**/
|
||||
@Service
|
||||
public class AuthSsoServiceImpl implements AuthSsoService {
|
||||
|
||||
@Resource
|
||||
private AuthService authService;
|
||||
|
||||
@Override
|
||||
public String doLogin(AuthSsoTicketLoginParam authAccountPasswordLoginParam, String device) {
|
||||
return null;
|
||||
}
|
||||
}
|
@@ -0,0 +1,77 @@
|
||||
|
||||
package mjkf.xinke.auth.modular.third.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import me.zhyd.oauth.model.AuthCallback;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import mjkf.xinke.auth.modular.third.entity.AuthThirdUser;
|
||||
import mjkf.xinke.auth.modular.third.param.AuthThirdCallbackParam;
|
||||
import mjkf.xinke.auth.modular.third.param.AuthThirdRenderParam;
|
||||
import mjkf.xinke.auth.modular.third.param.AuthThirdUserPageParam;
|
||||
import mjkf.xinke.auth.modular.third.result.AuthThirdRenderResult;
|
||||
import mjkf.xinke.auth.modular.third.service.AuthThirdService;
|
||||
import mjkf.xinke.common.pojo.CommonResult;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
|
||||
/**
|
||||
* 第三方登录控制器
|
||||
*
|
||||
*
|
||||
* @date 2022/7/8 16:18
|
||||
**/
|
||||
@Api(tags = "三方登录控制器")
|
||||
@ApiSupport(author = "SNOWY_TEAM", order = 5)
|
||||
@RestController
|
||||
@Validated
|
||||
public class AuthThirdController {
|
||||
|
||||
@Resource
|
||||
private AuthThirdService authThirdService;
|
||||
|
||||
/**
|
||||
* 第三方登录页面渲染
|
||||
*
|
||||
*
|
||||
* @date 2022/7/8 16:19
|
||||
**/
|
||||
@ApiOperationSupport(order = 1)
|
||||
@ApiOperation("第三方登录页面渲染")
|
||||
@GetMapping("/auth/third/render")
|
||||
public CommonResult<AuthThirdRenderResult> render(@Valid AuthThirdRenderParam authThirdRenderParam) {
|
||||
return CommonResult.data(authThirdService.render(authThirdRenderParam));
|
||||
}
|
||||
|
||||
/**
|
||||
* 第三方登录授权回调
|
||||
*
|
||||
*
|
||||
* @date 2022/7/8 16:42
|
||||
**/
|
||||
@ApiOperationSupport(order = 2)
|
||||
@ApiOperation("第三方登录授权回调")
|
||||
@GetMapping("/auth/third/callback")
|
||||
public CommonResult<String> callback(@Valid AuthThirdCallbackParam authThirdCallbackParam, AuthCallback authCallback) {
|
||||
return CommonResult.data(authThirdService.callback(authThirdCallbackParam, authCallback));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取三方用户分页
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 20:00
|
||||
*/
|
||||
@ApiOperationSupport(order = 3)
|
||||
@ApiOperation("获取三方用户分页")
|
||||
@GetMapping("/auth/third/page")
|
||||
public CommonResult<Page<AuthThirdUser>> page(AuthThirdUserPageParam authThirdUserPageParam) {
|
||||
return CommonResult.data(authThirdService.page(authThirdUserPageParam));
|
||||
}
|
||||
}
|
@@ -0,0 +1,66 @@
|
||||
|
||||
package mjkf.xinke.auth.modular.third.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.FieldStrategy;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import mjkf.xinke.common.pojo.CommonEntity;
|
||||
|
||||
/**
|
||||
* 第三方登录实体
|
||||
*
|
||||
*
|
||||
* @date 2022/7/9 14:29
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@TableName("AUTH_THIRD_USER")
|
||||
public class AuthThirdUser extends CommonEntity {
|
||||
|
||||
/** id */
|
||||
@ApiModelProperty(value = "id", position = 1)
|
||||
private String id;
|
||||
|
||||
/** 租户id */
|
||||
@ApiModelProperty(value = "租户id", position = 2)
|
||||
private String tenantId;
|
||||
|
||||
/** 三方用户id */
|
||||
@ApiModelProperty(value = "三方用户id", position = 3)
|
||||
private String thirdId;
|
||||
|
||||
/** 系统用户id */
|
||||
@ApiModelProperty(value = "系统用户id", position = 4)
|
||||
private String userId;
|
||||
|
||||
/** 头像 */
|
||||
@ApiModelProperty(value = "头像", position = 5)
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
private String avatar;
|
||||
|
||||
/** 姓名 */
|
||||
@ApiModelProperty(value = "姓名", position = 6)
|
||||
private String name;
|
||||
|
||||
/** 昵称 */
|
||||
@ApiModelProperty(value = "昵称", position = 7)
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
private String nickname;
|
||||
|
||||
/** 性别 */
|
||||
@ApiModelProperty(value = "性别", position = 8)
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
private String gender;
|
||||
|
||||
/** 分类 */
|
||||
@ApiModelProperty(value = "分类", position = 9)
|
||||
private String category;
|
||||
|
||||
/** 扩展信息 */
|
||||
@ApiModelProperty(value = "扩展信息", position = 10)
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
private String extJson;
|
||||
}
|
@@ -0,0 +1,38 @@
|
||||
|
||||
package mjkf.xinke.auth.modular.third.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
import mjkf.xinke.common.exception.CommonException;
|
||||
|
||||
/**
|
||||
* 第三方登录平台枚举
|
||||
*
|
||||
*
|
||||
* @date 2021/10/11 14:02
|
||||
**/
|
||||
@Getter
|
||||
public enum AuthThirdPlatformEnum {
|
||||
|
||||
/**
|
||||
* GITEE
|
||||
*/
|
||||
GITEE("GITEE"),
|
||||
|
||||
/**
|
||||
* WECHAT
|
||||
*/
|
||||
WECHAT("WECHAT");
|
||||
|
||||
private final String value;
|
||||
|
||||
AuthThirdPlatformEnum(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public static void validate(String value) {
|
||||
boolean flag = GITEE.getValue().equals(value) || WECHAT.getValue().equals(value);
|
||||
if(!flag) {
|
||||
throw new CommonException("不支持的第三方平台:{}", value);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,14 @@
|
||||
|
||||
package mjkf.xinke.auth.modular.third.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import mjkf.xinke.auth.modular.third.entity.AuthThirdUser;
|
||||
|
||||
/**
|
||||
* 第三方登录Mapper接口
|
||||
*
|
||||
*
|
||||
* @date 2022/7/9 14:35
|
||||
*/
|
||||
public interface AuthThirdMapper extends BaseMapper<AuthThirdUser> {
|
||||
}
|
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="mjkf.xinke.auth.modular.third.mapper.AuthThirdMapper">
|
||||
|
||||
|
||||
</mapper>
|
@@ -0,0 +1,34 @@
|
||||
|
||||
package mjkf.xinke.auth.modular.third.param;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
/**
|
||||
* 第三方登录回调参数
|
||||
*
|
||||
*
|
||||
* @date 2022/7/8 20:38
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class AuthThirdCallbackParam {
|
||||
|
||||
/** 第三方平台标识 */
|
||||
@ApiModelProperty(value = "第三方平台标识", required = true, position = 1)
|
||||
@NotBlank(message = "platform不能为空")
|
||||
private String platform;
|
||||
|
||||
/** 第三方回调code */
|
||||
@ApiModelProperty(value = "第三方回调code", required = true, position = 2)
|
||||
@NotBlank(message = "code不能为空")
|
||||
private String code;
|
||||
|
||||
/** 第三方回调state */
|
||||
@ApiModelProperty(value = "第三方回调state", required = true, position = 3)
|
||||
@NotBlank(message = "state不能为空")
|
||||
private String state;
|
||||
}
|
@@ -0,0 +1,24 @@
|
||||
|
||||
package mjkf.xinke.auth.modular.third.param;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
/**
|
||||
* 第三方登录授权参数
|
||||
*
|
||||
*
|
||||
* @date 2022/7/8 20:38
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class AuthThirdRenderParam {
|
||||
|
||||
/** 第三方平台标识 */
|
||||
@ApiModelProperty(value = "第三方平台标识", required = true)
|
||||
@NotBlank(message = "platform不能为空")
|
||||
private String platform;
|
||||
}
|
@@ -0,0 +1,41 @@
|
||||
|
||||
package mjkf.xinke.auth.modular.third.param;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* 三方用户查询参数
|
||||
*
|
||||
*
|
||||
* @date 2022/4/21 16:13
|
||||
**/
|
||||
@Getter
|
||||
@Setter
|
||||
public class AuthThirdUserPageParam {
|
||||
|
||||
/** 当前页 */
|
||||
@ApiModelProperty(value = "当前页码")
|
||||
private Integer current;
|
||||
|
||||
/** 每页条数 */
|
||||
@ApiModelProperty(value = "每页条数")
|
||||
private Integer size;
|
||||
|
||||
/** 排序字段 */
|
||||
@ApiModelProperty(value = "排序字段,字段驼峰名称,如:userName")
|
||||
private String sortField;
|
||||
|
||||
/** 排序方式 */
|
||||
@ApiModelProperty(value = "排序方式,升序:ASCEND;降序:DESCEND")
|
||||
private String sortOrder;
|
||||
|
||||
/** 三方用户分类 */
|
||||
@ApiModelProperty(value = "分类")
|
||||
private String category;
|
||||
|
||||
/** 用户名或昵称关键词 */
|
||||
@ApiModelProperty(value = "用户名或昵称关键词")
|
||||
private String searchKey;
|
||||
}
|
@@ -0,0 +1,25 @@
|
||||
|
||||
package mjkf.xinke.auth.modular.third.result;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* 第三方登录授权结果
|
||||
*
|
||||
*
|
||||
* @date 2022/7/8 20:39
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class AuthThirdRenderResult {
|
||||
|
||||
/** 授权地址 */
|
||||
@ApiModelProperty(value = "授权地址")
|
||||
private String authorizeUrl;
|
||||
|
||||
/** 状态码 */
|
||||
@ApiModelProperty(value = "状态码")
|
||||
private String state;
|
||||
}
|
@@ -0,0 +1,44 @@
|
||||
|
||||
package mjkf.xinke.auth.modular.third.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import me.zhyd.oauth.model.AuthCallback;
|
||||
import mjkf.xinke.auth.modular.third.entity.AuthThirdUser;
|
||||
import mjkf.xinke.auth.modular.third.param.AuthThirdCallbackParam;
|
||||
import mjkf.xinke.auth.modular.third.param.AuthThirdRenderParam;
|
||||
import mjkf.xinke.auth.modular.third.param.AuthThirdUserPageParam;
|
||||
import mjkf.xinke.auth.modular.third.result.AuthThirdRenderResult;
|
||||
|
||||
/**
|
||||
* 第三方登录Service接口
|
||||
*
|
||||
*
|
||||
* @date 2022/7/8 16:20
|
||||
**/
|
||||
public interface AuthThirdService extends IService<AuthThirdUser> {
|
||||
|
||||
/**
|
||||
* 第三方登录页面渲染,返回授权结果
|
||||
*
|
||||
*
|
||||
* @date 2022/7/8 16:37
|
||||
**/
|
||||
AuthThirdRenderResult render(AuthThirdRenderParam authThirdRenderParam);
|
||||
|
||||
/**
|
||||
* 第三方登录授权回调,返回登录token
|
||||
*
|
||||
*
|
||||
* @date 2022/7/8 16:42
|
||||
**/
|
||||
String callback(AuthThirdCallbackParam authThirdCallbackParam, AuthCallback authCallback);
|
||||
|
||||
/**
|
||||
* 获取三方用户分页
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 20:08
|
||||
*/
|
||||
Page<AuthThirdUser> page(AuthThirdUserPageParam authThirdUserPageParam);
|
||||
}
|
@@ -0,0 +1,218 @@
|
||||
|
||||
package mjkf.xinke.auth.modular.third.service.impl;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.xkcoding.http.HttpUtil;
|
||||
import com.xkcoding.http.support.hutool.HutoolImpl;
|
||||
import me.zhyd.oauth.config.AuthConfig;
|
||||
import me.zhyd.oauth.model.AuthCallback;
|
||||
import me.zhyd.oauth.model.AuthResponse;
|
||||
import me.zhyd.oauth.model.AuthUser;
|
||||
import me.zhyd.oauth.request.AuthGiteeRequest;
|
||||
import me.zhyd.oauth.request.AuthRequest;
|
||||
import me.zhyd.oauth.request.AuthWeChatOpenRequest;
|
||||
import me.zhyd.oauth.utils.AuthStateUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import mjkf.xinke.auth.api.SaBaseLoginUserApi;
|
||||
import mjkf.xinke.auth.core.enums.SaClientTypeEnum;
|
||||
import mjkf.xinke.auth.core.pojo.SaBaseLoginUser;
|
||||
import mjkf.xinke.auth.modular.login.enums.AuthDeviceTypeEnum;
|
||||
import mjkf.xinke.auth.modular.login.service.AuthService;
|
||||
import mjkf.xinke.auth.modular.third.entity.AuthThirdUser;
|
||||
import mjkf.xinke.auth.modular.third.enums.AuthThirdPlatformEnum;
|
||||
import mjkf.xinke.auth.modular.third.mapper.AuthThirdMapper;
|
||||
import mjkf.xinke.auth.modular.third.param.AuthThirdCallbackParam;
|
||||
import mjkf.xinke.auth.modular.third.param.AuthThirdRenderParam;
|
||||
import mjkf.xinke.auth.modular.third.param.AuthThirdUserPageParam;
|
||||
import mjkf.xinke.auth.modular.third.result.AuthThirdRenderResult;
|
||||
import mjkf.xinke.auth.modular.third.service.AuthThirdService;
|
||||
import mjkf.xinke.common.enums.CommonSortOrderEnum;
|
||||
import mjkf.xinke.common.exception.CommonException;
|
||||
import mjkf.xinke.common.page.CommonPageRequest;
|
||||
import mjkf.xinke.dev.api.DevConfigApi;
|
||||
import mjkf.xinke.ten.api.TenApi;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* 第三方登录Service接口实现类
|
||||
*
|
||||
*
|
||||
* @date 2022/7/8 16:20
|
||||
**/
|
||||
@Service
|
||||
public class AuthThirdServiceImpl extends ServiceImpl<AuthThirdMapper, AuthThirdUser> implements AuthThirdService {
|
||||
|
||||
private static final String SNOWY_THIRD_GITEE_CLIENT_ID_KEY = "SNOWY_THIRD_GITEE_CLIENT_ID";
|
||||
private static final String SNOWY_THIRD_GITEE_CLIENT_SECRET_KEY = "SNOWY_THIRD_GITEE_CLIENT_SECRET";
|
||||
private static final String SNOWY_THIRD_GITEE_REDIRECT_URL_KEY = "SNOWY_THIRD_GITEE_REDIRECT_URL";
|
||||
|
||||
private static final String SNOWY_THIRD_WECHAT_CLIENT_ID_KEY = "SNOWY_THIRD_WECHAT_CLIENT_ID";
|
||||
private static final String SNOWY_THIRD_WECHAT_CLIENT_SECRET_KEY = "SNOWY_THIRD_WECHAT_CLIENT_SECRET";
|
||||
private static final String SNOWY_THIRD_WECHAT_REDIRECT_URL_KEY = "SNOWY_THIRD_WECHAT_REDIRECT_URL";
|
||||
|
||||
@Resource
|
||||
private TenApi tenApi;
|
||||
|
||||
@Resource
|
||||
private DevConfigApi devConfigApi;
|
||||
|
||||
@Resource
|
||||
private AuthService authService;
|
||||
|
||||
@Resource(name = "loginUserApi")
|
||||
private SaBaseLoginUserApi loginUserApi;
|
||||
|
||||
@Resource(name = "clientLoginUserApi")
|
||||
private SaBaseLoginUserApi clientLoginUserApi;
|
||||
|
||||
@Override
|
||||
public AuthThirdRenderResult render(AuthThirdRenderParam authThirdRenderParam) {
|
||||
|
||||
// 获取请求
|
||||
AuthRequest authRequest = this.getAuthRequest(authThirdRenderParam.getPlatform());
|
||||
|
||||
// 获取状态
|
||||
String state = AuthStateUtils.createState();
|
||||
|
||||
// 构造授权地址
|
||||
String authorizeUrl = authRequest.authorize(state);
|
||||
|
||||
// 获取当前租户的域名拼接
|
||||
authorizeUrl = authorizeUrl + "&domain=" + tenApi.getCurrentTenDomain();
|
||||
|
||||
// 构造结果
|
||||
AuthThirdRenderResult authThirdRenderResult = new AuthThirdRenderResult();
|
||||
|
||||
// 返回授权地址
|
||||
authThirdRenderResult.setAuthorizeUrl(authorizeUrl);
|
||||
|
||||
// 返回状态码
|
||||
authThirdRenderResult.setState(state);
|
||||
return authThirdRenderResult;
|
||||
}
|
||||
|
||||
@SuppressWarnings("ALL")
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public String callback(AuthThirdCallbackParam authThirdCallbackParam, AuthCallback authCallback) {
|
||||
|
||||
// 获取请求
|
||||
AuthRequest authRequest = this.getAuthRequest(authThirdCallbackParam.getPlatform());
|
||||
|
||||
// 执行请求
|
||||
AuthResponse<AuthUser> authResponse = authRequest.login(authCallback);
|
||||
if (authResponse.ok()) {
|
||||
|
||||
// 授权的用户信息
|
||||
AuthUser authUser = authResponse.getData();
|
||||
|
||||
// 获取第三方用户id
|
||||
String uuid = authUser.getUuid();
|
||||
|
||||
// 获取第三方用户来源
|
||||
String source = authUser.getSource();
|
||||
|
||||
// 根据第三方用户id和用户来源获取用户信息
|
||||
AuthThirdUser authThirdUser = this.getOne(new LambdaQueryWrapper<AuthThirdUser>().eq(AuthThirdUser::getThirdId, uuid)
|
||||
.eq(AuthThirdUser::getCategory, source));
|
||||
|
||||
// 定义系统用户id
|
||||
String userId;
|
||||
if(ObjectUtil.isEmpty(authThirdUser)) {
|
||||
|
||||
// 如果用户不存在,则绑定用户并登录
|
||||
userId = this.bindUser(authUser);
|
||||
} else {
|
||||
// 否则直接获取用户id登录
|
||||
userId = authThirdUser.getUserId();
|
||||
}
|
||||
// TODO 此处使用PC端执行B端登录,返回token
|
||||
return authService.doLoginById(userId, AuthDeviceTypeEnum.PC.getValue(), SaClientTypeEnum.B.getValue());
|
||||
} else {
|
||||
throw new CommonException("第三方登录授权回调失败,原因:{}", authResponse.getMsg());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<AuthThirdUser> page(AuthThirdUserPageParam authThirdUserPageParam) {
|
||||
QueryWrapper<AuthThirdUser> queryWrapper = new QueryWrapper<>();
|
||||
if(ObjectUtil.isNotEmpty(authThirdUserPageParam.getCategory())) {
|
||||
queryWrapper.lambda().eq(AuthThirdUser::getCategory, authThirdUserPageParam.getCategory());
|
||||
}
|
||||
if(ObjectUtil.isNotEmpty(authThirdUserPageParam.getSearchKey())) {
|
||||
queryWrapper.and(q -> q.lambda().like(AuthThirdUser::getName, authThirdUserPageParam.getSearchKey())
|
||||
.or().like(AuthThirdUser::getNickname, authThirdUserPageParam.getSearchKey()));
|
||||
}
|
||||
if(ObjectUtil.isAllNotEmpty(authThirdUserPageParam.getSortField(), authThirdUserPageParam.getSortOrder())) {
|
||||
CommonSortOrderEnum.validate(authThirdUserPageParam.getSortOrder());
|
||||
queryWrapper.orderBy(true, authThirdUserPageParam.getSortOrder().equals(CommonSortOrderEnum.ASC.getValue()),
|
||||
StrUtil.toUnderlineCase(authThirdUserPageParam.getSortField()));
|
||||
} else {
|
||||
queryWrapper.lambda().orderByDesc(AuthThirdUser::getCreateTime);
|
||||
}
|
||||
return this.page(CommonPageRequest.defaultPage(), queryWrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* 绑定用户并返回用户id
|
||||
*
|
||||
*
|
||||
* @date 2022/7/9 14:58
|
||||
*/
|
||||
private String bindUser(AuthUser authUser) {
|
||||
// TODO 此处固定绑定超管
|
||||
SaBaseLoginUser saBaseLoginUser = loginUserApi.getUserByAccount("admin");
|
||||
if(ObjectUtil.isEmpty(saBaseLoginUser)) {
|
||||
throw new CommonException("第三方登录失败,无法绑定账号admin,原因:账户admin不存在");
|
||||
}
|
||||
AuthThirdUser authThirdUser = new AuthThirdUser();
|
||||
authThirdUser.setThirdId(authUser.getUuid());
|
||||
authThirdUser.setUserId(saBaseLoginUser.getId());
|
||||
authThirdUser.setAvatar(authUser.getAvatar());
|
||||
authThirdUser.setName(authUser.getUsername());
|
||||
authThirdUser.setNickname(authUser.getNickname());
|
||||
authThirdUser.setGender(authUser.getGender().getDesc());
|
||||
authThirdUser.setCategory(authUser.getSource());
|
||||
authThirdUser.setExtJson(JSONUtil.toJsonStr(authUser.getRawUserInfo()));
|
||||
this.save(authThirdUser);
|
||||
return authThirdUser.getUserId();
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建授权请求
|
||||
*
|
||||
*
|
||||
* @date 2022/7/8 16:48
|
||||
**/
|
||||
private AuthRequest getAuthRequest(String source) {
|
||||
AuthRequest authRequest = null;
|
||||
source = source.toUpperCase();
|
||||
HttpUtil.setHttp(new HutoolImpl());
|
||||
AuthThirdPlatformEnum.validate(source);
|
||||
if (source.equals(AuthThirdPlatformEnum.GITEE.getValue())) {
|
||||
// GITEE登录
|
||||
authRequest = new AuthGiteeRequest(AuthConfig.builder()
|
||||
.clientId(devConfigApi.getValueByKey(SNOWY_THIRD_GITEE_CLIENT_ID_KEY))
|
||||
.clientSecret(devConfigApi.getValueByKey(SNOWY_THIRD_GITEE_CLIENT_SECRET_KEY))
|
||||
.redirectUri(devConfigApi.getValueByKey(SNOWY_THIRD_GITEE_REDIRECT_URL_KEY))
|
||||
.build());
|
||||
}
|
||||
if(source.equals(AuthThirdPlatformEnum.WECHAT.getValue())){
|
||||
// 微信登录
|
||||
authRequest = new AuthWeChatOpenRequest(AuthConfig.builder()
|
||||
.clientId(devConfigApi.getValueByKey(SNOWY_THIRD_WECHAT_CLIENT_ID_KEY))
|
||||
.clientSecret(devConfigApi.getValueByKey(SNOWY_THIRD_WECHAT_CLIENT_SECRET_KEY))
|
||||
.redirectUri(devConfigApi.getValueByKey(SNOWY_THIRD_WECHAT_REDIRECT_URL_KEY))
|
||||
.build());
|
||||
}
|
||||
return authRequest;
|
||||
}
|
||||
}
|
48
mjkf-xinke-plugin/mjkf-xinke-plugin-biz/pom.xml
Normal file
48
mjkf-xinke-plugin/mjkf-xinke-plugin-biz/pom.xml
Normal file
@@ -0,0 +1,48 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>mjkf.xinke</groupId>
|
||||
<artifactId>mjkf-xinke-plugin</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>mjkf-xinke-plugin-biz</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<description>业务功能插件</description>
|
||||
|
||||
<dependencies>
|
||||
<!-- 每个插件都要引入自己的对外接口 -->
|
||||
<dependency>
|
||||
<groupId>mjkf.xinke</groupId>
|
||||
<artifactId>mjkf-xinke-plugin-biz-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 引入登录鉴权接口,用于获取登录用户 -->
|
||||
<dependency>
|
||||
<groupId>mjkf.xinke</groupId>
|
||||
<artifactId>mjkf-xinke-plugin-auth-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 引入系统接口,用于授权角色等功能 -->
|
||||
<dependency>
|
||||
<groupId>mjkf.xinke</groupId>
|
||||
<artifactId>mjkf-xinke-plugin-sys-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 引入开发工具接口,用于配置信息 -->
|
||||
<dependency>
|
||||
<groupId>mjkf.xinke</groupId>
|
||||
<artifactId>mjkf-xinke-plugin-dev-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 引入多数据源接口,用于提供数据源 -->
|
||||
<dependency>
|
||||
<groupId>mjkf.xinke</groupId>
|
||||
<artifactId>mjkf-xinke-plugin-dbs-api</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
@@ -0,0 +1,56 @@
|
||||
|
||||
package mjkf.xinke.biz.core.config;
|
||||
|
||||
import com.github.xiaoymin.knife4j.spring.extension.OpenApiExtensionResolver;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import springfox.documentation.builders.ApiInfoBuilder;
|
||||
import springfox.documentation.builders.PathSelectors;
|
||||
import springfox.documentation.builders.RequestHandlerSelectors;
|
||||
import springfox.documentation.service.Contact;
|
||||
import springfox.documentation.spi.DocumentationType;
|
||||
import springfox.documentation.spring.web.plugins.Docket;
|
||||
import mjkf.xinke.common.pojo.CommonResult;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* 业务相关配置
|
||||
*
|
||||
*
|
||||
* @date 2022/7/7 16:18
|
||||
**/
|
||||
@Configuration
|
||||
public class BizConfigure {
|
||||
|
||||
@Resource
|
||||
private OpenApiExtensionResolver openApiExtensionResolver;
|
||||
|
||||
/**
|
||||
* API文档分组配置
|
||||
*
|
||||
*
|
||||
* @date 2022/7/7 16:18
|
||||
**/
|
||||
@Bean(value = "bizDocApi")
|
||||
public Docket bizDocApi() {
|
||||
return new Docket(DocumentationType.SWAGGER_2)
|
||||
.apiInfo(new ApiInfoBuilder()
|
||||
.title("业务功能BIZ")
|
||||
.description("业务功能BIZ")
|
||||
.termsOfServiceUrl("https://www.xiaonuo.vip")
|
||||
.contact(new Contact("SNOWY_TEAM","https://www.xiaonuo.vip", "xuyuxiang29@foxmail.com"))
|
||||
.version("2.0.0")
|
||||
.build())
|
||||
.globalResponseMessage(RequestMethod.GET, CommonResult.responseList())
|
||||
.globalResponseMessage(RequestMethod.POST, CommonResult.responseList())
|
||||
.groupName("业务功能BIZ")
|
||||
.select()
|
||||
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
|
||||
.apis(RequestHandlerSelectors.basePackage("mjkf.xinke.biz"))
|
||||
.paths(PathSelectors.any())
|
||||
.build().extensions(openApiExtensionResolver.buildExtensions("业务功能BIZ"));
|
||||
}
|
||||
}
|
@@ -0,0 +1,28 @@
|
||||
|
||||
package mjkf.xinke.biz.core.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 系统内置的不可删除的标识枚举
|
||||
*
|
||||
*
|
||||
* @date 2022/4/21 19:56
|
||||
**/
|
||||
@Getter
|
||||
public enum BizBuildInEnum {
|
||||
|
||||
/**
|
||||
* 超管用户账号
|
||||
*/
|
||||
BUILD_IN_USER_ACCOUNT("superAdmin", "超管");
|
||||
|
||||
private final String value;
|
||||
|
||||
private final String name;
|
||||
|
||||
BizBuildInEnum(String value, String name) {
|
||||
this.value = value;
|
||||
this.name = name;
|
||||
}
|
||||
}
|
@@ -0,0 +1,36 @@
|
||||
|
||||
package mjkf.xinke.biz.core.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 业务模块数据类型枚举
|
||||
*
|
||||
*
|
||||
* @date 2023/3/3 10:40
|
||||
**/
|
||||
@Getter
|
||||
public enum BizDataTypeEnum {
|
||||
|
||||
/**
|
||||
* 机构
|
||||
*/
|
||||
ORG("ORG"),
|
||||
|
||||
/**
|
||||
* 岗位
|
||||
*/
|
||||
POSITION("POSITION"),
|
||||
|
||||
/**
|
||||
* 人员
|
||||
*/
|
||||
USER("USER");
|
||||
|
||||
private final String value;
|
||||
|
||||
BizDataTypeEnum(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,98 @@
|
||||
|
||||
package mjkf.xinke.biz.modular.dict.controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.hutool.core.lang.tree.Tree;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
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.RestController;
|
||||
import mjkf.xinke.biz.modular.dict.entity.BizDict;
|
||||
import mjkf.xinke.biz.modular.dict.param.BizDictEditParam;
|
||||
import mjkf.xinke.biz.modular.dict.param.BizDictPageParam;
|
||||
import mjkf.xinke.biz.modular.dict.service.BizDictService;
|
||||
import mjkf.xinke.common.annotation.CommonLog;
|
||||
import mjkf.xinke.common.pojo.CommonResult;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 业务字典控制器
|
||||
*
|
||||
*
|
||||
* @date 2022/6/21 14:58
|
||||
**/
|
||||
@Api(tags = "业务字典控制器")
|
||||
@ApiSupport(author = "SNOWY_TEAM", order = 4)
|
||||
@RestController
|
||||
@Validated
|
||||
public class BizDictController {
|
||||
|
||||
@Resource
|
||||
private BizDictService bizDictService;
|
||||
|
||||
/**
|
||||
* 获取业务字典分页
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 20:00
|
||||
*/
|
||||
@ApiOperationSupport(order = 1)
|
||||
@ApiOperation("获取业务字典分页")
|
||||
@SaCheckPermission("/biz/dict/page")
|
||||
@GetMapping("/biz/dict/page")
|
||||
public CommonResult<Page<BizDict>> page(BizDictPageParam bizDictPageParam) {
|
||||
return CommonResult.data(bizDictService.page(bizDictPageParam));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取业务字典树
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 20:00
|
||||
*/
|
||||
@ApiOperationSupport(order = 2)
|
||||
@ApiOperation("获取业务字典树")
|
||||
@SaCheckPermission("/biz/dict/tree")
|
||||
@GetMapping("/biz/dict/tree")
|
||||
public CommonResult<List<Tree<String>>> tree() {
|
||||
return CommonResult.data(bizDictService.tree());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有字典树
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 20:00
|
||||
*/
|
||||
@ApiOperationSupport(order = 3)
|
||||
@ApiOperation("获取所有字典树")
|
||||
@GetMapping("/biz/dict/treeAll")
|
||||
public CommonResult<List<Tree<String>>> treeAll() {
|
||||
return CommonResult.data(bizDictService.treeAll());
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑业务字典
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 20:47
|
||||
*/
|
||||
@ApiOperationSupport(order = 4)
|
||||
@ApiOperation("编辑业务字典")
|
||||
@CommonLog("编辑业务字典")
|
||||
@SaCheckPermission("/biz/dict/edit")
|
||||
@PostMapping("/biz/dict/edit")
|
||||
public CommonResult<String> edit(@RequestBody @Valid BizDictEditParam bizDictEditParam) {
|
||||
bizDictService.edit(bizDictEditParam);
|
||||
return CommonResult.ok();
|
||||
}
|
||||
}
|
@@ -0,0 +1,55 @@
|
||||
|
||||
package mjkf.xinke.biz.modular.dict.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.FieldStrategy;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import mjkf.xinke.common.pojo.CommonEntity;
|
||||
|
||||
/**
|
||||
* 业务字典实体
|
||||
*
|
||||
*
|
||||
* @date 2022/2/23 18:27
|
||||
**/
|
||||
@Getter
|
||||
@Setter
|
||||
@TableName("DEV_DICT")
|
||||
public class BizDict extends CommonEntity {
|
||||
|
||||
/** id */
|
||||
@ApiModelProperty(value = "id", position = 1)
|
||||
private String id;
|
||||
|
||||
/** 租户id */
|
||||
@ApiModelProperty(value = "租户id", position = 2)
|
||||
private String tenantId;
|
||||
|
||||
/** 父id */
|
||||
@ApiModelProperty(value = "父id", position = 3)
|
||||
private String parentId;
|
||||
|
||||
/** 字典文字 */
|
||||
@ApiModelProperty(value = "字典文字", position = 4)
|
||||
private String dictLabel;
|
||||
|
||||
/** 字典值 */
|
||||
@ApiModelProperty(value = "字典值", position = 5)
|
||||
private String dictValue;
|
||||
|
||||
/** 分类 */
|
||||
@ApiModelProperty(value = "分类", position = 6)
|
||||
private String category;
|
||||
|
||||
/** 排序码 */
|
||||
@ApiModelProperty(value = "排序码", position = 7)
|
||||
private Integer sortCode;
|
||||
|
||||
/** 扩展信息 */
|
||||
@ApiModelProperty(value = "扩展信息", position = 8)
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
private String extJson;
|
||||
}
|
@@ -0,0 +1,33 @@
|
||||
|
||||
package mjkf.xinke.biz.modular.dict.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
import mjkf.xinke.common.exception.CommonException;
|
||||
|
||||
/**
|
||||
* 业务字典分类枚举
|
||||
*
|
||||
*
|
||||
* @date 2022/7/6 22:21
|
||||
*/
|
||||
@Getter
|
||||
public enum BizDictCategoryEnum {
|
||||
|
||||
/**
|
||||
* 业务
|
||||
*/
|
||||
BIZ("BIZ");
|
||||
|
||||
private final String value;
|
||||
|
||||
BizDictCategoryEnum(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public static void validate(String value) {
|
||||
boolean flag = BIZ.getValue().equals(value);
|
||||
if(!flag) {
|
||||
throw new CommonException("不支持的字典分类:{}", value);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,14 @@
|
||||
|
||||
package mjkf.xinke.biz.modular.dict.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import mjkf.xinke.biz.modular.dict.entity.BizDict;
|
||||
|
||||
/**
|
||||
* 业务字典Mapper接口
|
||||
*
|
||||
*
|
||||
* @date 2022/4/22 10:40
|
||||
**/
|
||||
public interface BizDictMapper extends BaseMapper<BizDict> {
|
||||
}
|
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="mjkf.xinke.biz.modular.dict.mapper.BizDictMapper">
|
||||
|
||||
|
||||
</mapper>
|
@@ -0,0 +1,39 @@
|
||||
|
||||
package mjkf.xinke.biz.modular.dict.param;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 业务字典编辑参数
|
||||
*
|
||||
*
|
||||
* @date 2022/7/30 21:48
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class BizDictEditParam {
|
||||
|
||||
/** id */
|
||||
@ApiModelProperty(value = "id", position = 1)
|
||||
@NotBlank(message = "id不能为空")
|
||||
private String id;
|
||||
|
||||
/** 字典文字 */
|
||||
@ApiModelProperty(value = "字典文字", position = 2)
|
||||
@NotBlank(message = "dictLabel不能为空")
|
||||
private String dictLabel;
|
||||
|
||||
/** 排序码 */
|
||||
@ApiModelProperty(value = "排序码", position = 3)
|
||||
@NotNull(message = "sortCode不能为空")
|
||||
private Integer sortCode;
|
||||
|
||||
/** 扩展信息 */
|
||||
@ApiModelProperty(value = "扩展信息", position = 4)
|
||||
private String extJson;
|
||||
}
|
@@ -0,0 +1,41 @@
|
||||
|
||||
package mjkf.xinke.biz.modular.dict.param;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* 业务字典查询参数
|
||||
*
|
||||
*
|
||||
* @date 2022/7/30 21:49
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class BizDictPageParam {
|
||||
|
||||
/** 当前页 */
|
||||
@ApiModelProperty(value = "当前页码")
|
||||
private Integer current;
|
||||
|
||||
/** 每页条数 */
|
||||
@ApiModelProperty(value = "每页条数")
|
||||
private Integer size;
|
||||
|
||||
/** 排序字段 */
|
||||
@ApiModelProperty(value = "排序字段,字段驼峰名称,如:userName")
|
||||
private String sortField;
|
||||
|
||||
/** 排序方式 */
|
||||
@ApiModelProperty(value = "排序方式,升序:ASCEND;降序:DESCEND")
|
||||
private String sortOrder;
|
||||
|
||||
/** 父id */
|
||||
@ApiModelProperty(value = "父id")
|
||||
private String parentId;
|
||||
|
||||
/** 字典文字关键词 */
|
||||
@ApiModelProperty(value = "字典文字关键词")
|
||||
private String searchKey;
|
||||
}
|
@@ -0,0 +1,60 @@
|
||||
|
||||
package mjkf.xinke.biz.modular.dict.service;
|
||||
|
||||
import cn.hutool.core.lang.tree.Tree;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import mjkf.xinke.biz.modular.dict.entity.BizDict;
|
||||
import mjkf.xinke.biz.modular.dict.param.BizDictEditParam;
|
||||
import mjkf.xinke.biz.modular.dict.param.BizDictPageParam;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 业务字典Service接口
|
||||
*
|
||||
*
|
||||
* @date 2022/4/22 10:41
|
||||
**/
|
||||
public interface BizDictService extends IService<BizDict> {
|
||||
|
||||
/**
|
||||
* 获取业务字典分页
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 20:08
|
||||
*/
|
||||
Page<BizDict> page(BizDictPageParam bizDictPageParam);
|
||||
|
||||
/**
|
||||
* 获取业务字典树
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 20:08
|
||||
*/
|
||||
List<Tree<String>> tree();
|
||||
|
||||
/**
|
||||
* 获取所有字典树
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 20:08
|
||||
*/
|
||||
List<Tree<String>> treeAll();
|
||||
|
||||
/**
|
||||
* 编辑业务字典
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 21:13
|
||||
*/
|
||||
void edit(BizDictEditParam bizDictEditParam);
|
||||
|
||||
/**
|
||||
* 获取业务字典详情
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 21:18
|
||||
*/
|
||||
BizDict queryEntity(String id);
|
||||
}
|
@@ -0,0 +1,146 @@
|
||||
|
||||
package mjkf.xinke.biz.modular.dict.service.impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.lang.tree.Tree;
|
||||
import cn.hutool.core.lang.tree.TreeNode;
|
||||
import cn.hutool.core.lang.tree.TreeUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.fhs.trans.service.impl.DictionaryTransService;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.stereotype.Service;
|
||||
import mjkf.xinke.biz.modular.dict.entity.BizDict;
|
||||
import mjkf.xinke.biz.modular.dict.enums.BizDictCategoryEnum;
|
||||
import mjkf.xinke.biz.modular.dict.mapper.BizDictMapper;
|
||||
import mjkf.xinke.biz.modular.dict.param.BizDictEditParam;
|
||||
import mjkf.xinke.biz.modular.dict.param.BizDictPageParam;
|
||||
import mjkf.xinke.biz.modular.dict.service.BizDictService;
|
||||
import mjkf.xinke.common.enums.CommonSortOrderEnum;
|
||||
import mjkf.xinke.common.exception.CommonException;
|
||||
import mjkf.xinke.common.page.CommonPageRequest;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 字典Service接口实现类
|
||||
*
|
||||
*
|
||||
* @date 2022/4/22 10:41
|
||||
**/
|
||||
@Service
|
||||
public class BizDictServiceImpl extends ServiceImpl<BizDictMapper, BizDict> implements BizDictService, InitializingBean {
|
||||
|
||||
private static final String ROOT_PARENT_ID = "0";
|
||||
|
||||
@Resource
|
||||
private DictionaryTransService dictionaryTransService;
|
||||
|
||||
@Override
|
||||
public Page<BizDict> page(BizDictPageParam bizDictPageParam) {
|
||||
QueryWrapper<BizDict> queryWrapper = new QueryWrapper<>();
|
||||
// 查询部分字段
|
||||
queryWrapper.lambda().select(BizDict::getId, BizDict::getParentId, BizDict::getCategory, BizDict::getDictLabel,
|
||||
BizDict::getDictValue, BizDict::getSortCode).eq(BizDict::getCategory, BizDictCategoryEnum.BIZ.getValue());
|
||||
if (ObjectUtil.isNotEmpty(bizDictPageParam.getParentId())) {
|
||||
queryWrapper.lambda().eq(BizDict::getParentId, bizDictPageParam.getParentId())
|
||||
.or().eq(BizDict::getId, bizDictPageParam.getParentId());
|
||||
}
|
||||
if (ObjectUtil.isNotEmpty(bizDictPageParam.getSearchKey())) {
|
||||
queryWrapper.lambda().like(BizDict::getDictLabel, bizDictPageParam.getSearchKey());
|
||||
}
|
||||
if (ObjectUtil.isAllNotEmpty(bizDictPageParam.getSortField(), bizDictPageParam.getSortOrder())) {
|
||||
CommonSortOrderEnum.validate(bizDictPageParam.getSortOrder());
|
||||
queryWrapper.orderBy(true, bizDictPageParam.getSortOrder().equals(CommonSortOrderEnum.ASC.getValue()),
|
||||
StrUtil.toUnderlineCase(bizDictPageParam.getSortField()));
|
||||
} else {
|
||||
queryWrapper.lambda().orderByAsc(BizDict::getSortCode);
|
||||
}
|
||||
return this.page(CommonPageRequest.defaultPage(), queryWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Tree<String>> tree() {
|
||||
LambdaQueryWrapper<BizDict> lambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||
lambdaQueryWrapper.eq(BizDict::getCategory, BizDictCategoryEnum.BIZ.getValue()).orderByAsc(BizDict::getSortCode);
|
||||
List<BizDict> bizDictList = this.list(lambdaQueryWrapper);
|
||||
List<TreeNode<String>> treeNodeList = bizDictList.stream().map(bizDict ->
|
||||
new TreeNode<>(bizDict.getId(), bizDict.getParentId(),
|
||||
bizDict.getDictLabel(), bizDict.getSortCode()).setExtra(JSONUtil.parseObj(bizDict)))
|
||||
.collect(Collectors.toList());
|
||||
return TreeUtil.build(treeNodeList, "0");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Tree<String>> treeAll() {
|
||||
List<BizDict> bizDictList = this.list();
|
||||
List<TreeNode<String>> treeNodeList = bizDictList.stream().map(bizDict ->
|
||||
new TreeNode<>(bizDict.getId(), bizDict.getParentId(),
|
||||
bizDict.getDictLabel(), bizDict.getSortCode()).setExtra(JSONUtil.parseObj(bizDict)))
|
||||
.collect(Collectors.toList());
|
||||
return TreeUtil.build(treeNodeList, "0");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void edit(BizDictEditParam bizDictEditParam) {
|
||||
BizDict bizDict = this.queryEntity(bizDictEditParam.getId());
|
||||
checkParam(bizDictEditParam);
|
||||
BeanUtil.copyProperties(bizDictEditParam, bizDict);
|
||||
this.updateById(bizDict);
|
||||
refreshTransCache();
|
||||
}
|
||||
|
||||
private void checkParam(BizDictEditParam bizDictEditParam) {
|
||||
boolean hasSameDictLabel = this.count(new LambdaQueryWrapper<BizDict>()
|
||||
.eq(BizDict::getCategory, BizDictCategoryEnum.BIZ.getValue())
|
||||
.eq(BizDict::getDictLabel, bizDictEditParam.getDictLabel())
|
||||
.ne(BizDict::getId, bizDictEditParam.getId())) > 0;
|
||||
if (hasSameDictLabel) {
|
||||
throw new CommonException("存在重复的字典文字,名称为:{}", bizDictEditParam.getDictLabel());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BizDict queryEntity(String id) {
|
||||
BizDict bizDict = this.getById(id);
|
||||
if (ObjectUtil.isEmpty(bizDict)) {
|
||||
throw new CommonException("字典不存在,id值为:{}", id);
|
||||
}
|
||||
return bizDict;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
refreshTransCache();
|
||||
}
|
||||
|
||||
private void refreshTransCache() {
|
||||
// 异步不阻塞主线程,不会 增加启动用时
|
||||
CompletableFuture.supplyAsync(() -> {
|
||||
// 使用redis能解决共享问题,但是性能没有直接取缓存的好。
|
||||
dictionaryTransService.makeUseRedis();
|
||||
List<BizDict> bizDictList = super.list(new LambdaQueryWrapper<>());
|
||||
// 非root级别的字典根据ParentId分组
|
||||
Map<String,List<BizDict>> bizDictGroupByPIDMap = bizDictList.stream().filter(dict -> !ROOT_PARENT_ID
|
||||
.equals(dict.getParentId())).collect(Collectors.groupingBy(BizDict::getParentId));
|
||||
Map<String,String> parentDictIdValMap = bizDictList.stream().filter(dict -> ROOT_PARENT_ID
|
||||
.equals(dict.getParentId())).collect(Collectors.toMap(BizDict::getId, BizDict::getDictValue));
|
||||
for (String parentId : parentDictIdValMap.keySet()) {
|
||||
if(bizDictGroupByPIDMap.containsKey(parentId)){
|
||||
dictionaryTransService.refreshCache(parentDictIdValMap.get(parentId), bizDictGroupByPIDMap.get(parentId).stream()
|
||||
.collect(Collectors.toMap(BizDict::getDictValue, BizDict::getDictLabel)));
|
||||
}
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
}
|
@@ -0,0 +1,180 @@
|
||||
|
||||
package mjkf.xinke.biz.modular.org.controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.hutool.core.lang.tree.Tree;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
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.RestController;
|
||||
import mjkf.xinke.biz.modular.org.entity.BizOrg;
|
||||
import mjkf.xinke.biz.modular.org.param.*;
|
||||
import mjkf.xinke.biz.modular.org.service.BizOrgService;
|
||||
import mjkf.xinke.biz.modular.user.entity.BizUser;
|
||||
import mjkf.xinke.common.annotation.CommonLog;
|
||||
import mjkf.xinke.common.pojo.CommonResult;
|
||||
import mjkf.xinke.common.pojo.CommonValidList;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 机构控制器
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 19:55
|
||||
*/
|
||||
@Api(tags = "机构控制器")
|
||||
@ApiSupport(author = "SNOWY_TEAM", order = 1)
|
||||
@RestController
|
||||
@Validated
|
||||
public class BizOrgController {
|
||||
|
||||
@Resource
|
||||
private BizOrgService bizOrgService;
|
||||
|
||||
/**
|
||||
* 获取机构分页
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 20:00
|
||||
*/
|
||||
@ApiOperationSupport(order = 1)
|
||||
@ApiOperation("获取机构分页")
|
||||
@SaCheckPermission("/biz/org/page")
|
||||
@GetMapping("/biz/org/page")
|
||||
public CommonResult<Page<BizOrg>> page(BizOrgPageParam bizOrgPageParam) {
|
||||
return CommonResult.data(bizOrgService.page(bizOrgPageParam));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取机构树
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 20:00
|
||||
*/
|
||||
@ApiOperationSupport(order = 2)
|
||||
@ApiOperation("获取机构树")
|
||||
@SaCheckPermission("/biz/org/tree")
|
||||
@GetMapping("/biz/org/tree")
|
||||
public CommonResult<List<Tree<String>>> tree() {
|
||||
return CommonResult.data(bizOrgService.tree());
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加机构
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 20:47
|
||||
*/
|
||||
@ApiOperationSupport(order = 3)
|
||||
@ApiOperation("添加机构")
|
||||
@CommonLog("添加机构")
|
||||
@SaCheckPermission("/biz/org/add")
|
||||
@PostMapping("/biz/org/add")
|
||||
public CommonResult<String> add(@RequestBody @Valid BizOrgAddParam bizOrgAddParam) {
|
||||
bizOrgService.add(bizOrgAddParam);
|
||||
return CommonResult.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑机构
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 20:47
|
||||
*/
|
||||
@ApiOperationSupport(order = 4)
|
||||
@ApiOperation("编辑机构")
|
||||
@CommonLog("编辑机构")
|
||||
@SaCheckPermission("/biz/org/edit")
|
||||
@PostMapping("/biz/org/edit")
|
||||
public CommonResult<String> edit(@RequestBody @Valid BizOrgEditParam bizOrgEditParam) {
|
||||
bizOrgService.edit(bizOrgEditParam);
|
||||
return CommonResult.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除机构
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 20:00
|
||||
*/
|
||||
@ApiOperationSupport(order = 5)
|
||||
@ApiOperation("删除机构")
|
||||
@CommonLog("删除机构")
|
||||
@SaCheckPermission("/biz/org/delete")
|
||||
@PostMapping("/biz/org/delete")
|
||||
public CommonResult<String> delete(@RequestBody @Valid @NotEmpty(message = "集合不能为空")
|
||||
CommonValidList<BizOrgIdParam> bizOrgIdParamList) {
|
||||
bizOrgService.delete(bizOrgIdParamList);
|
||||
return CommonResult.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取机构详情
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 20:00
|
||||
*/
|
||||
@ApiOperationSupport(order = 6)
|
||||
@ApiOperation("获取机构详情")
|
||||
@SaCheckPermission("/biz/org/detail")
|
||||
@GetMapping("/biz/org/detail")
|
||||
public CommonResult<BizOrg> detail(@Valid BizOrgIdParam bizOrgIdParam) {
|
||||
return CommonResult.data(bizOrgService.detail(bizOrgIdParam));
|
||||
}
|
||||
|
||||
/* ====机构部分所需要用到的选择器==== */
|
||||
|
||||
/**
|
||||
* 获取机构树选择器
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 20:00
|
||||
*/
|
||||
@ApiOperationSupport(order = 7)
|
||||
@ApiOperation("获取机构树选择器")
|
||||
@SaCheckPermission("/biz/org/orgTreeSelector")
|
||||
@GetMapping("/biz/org/orgTreeSelector")
|
||||
public CommonResult<List<Tree<String>>> orgTreeSelector() {
|
||||
return CommonResult.data(bizOrgService.orgTreeSelector());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取人员选择器
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 20:00
|
||||
*/
|
||||
@ApiOperationSupport(order = 8)
|
||||
@ApiOperation("获取人员选择器")
|
||||
@SaCheckPermission("/biz/org/userSelector")
|
||||
@GetMapping("/biz/org/userSelector")
|
||||
public CommonResult<Page<BizUser>> userSelector(BizOrgSelectorUserParam bizOrgSelectorUserParam) {
|
||||
return CommonResult.data(bizOrgService.userSelector(bizOrgSelectorUserParam));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取机构动态字段的配置
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 20:00
|
||||
*/
|
||||
@ApiOperationSupport(order = 9)
|
||||
@ApiOperation("获取机构动态字段的配置")
|
||||
@SaCheckPermission("/biz/org/dynamicFieldConfigList")
|
||||
@GetMapping("/biz/org/dynamicFieldConfigList")
|
||||
public CommonResult<List<JSONObject>> dynamicFieldConfigList() {
|
||||
return CommonResult.data(bizOrgService.dynamicFieldConfigList());
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,65 @@
|
||||
|
||||
package mjkf.xinke.biz.modular.org.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.FieldStrategy;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.fhs.core.trans.anno.Trans;
|
||||
import com.fhs.core.trans.constant.TransType;
|
||||
import com.fhs.core.trans.vo.TransPojo;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import mjkf.xinke.biz.modular.user.entity.BizUser;
|
||||
import mjkf.xinke.common.pojo.CommonEntity;
|
||||
|
||||
/**
|
||||
* 机构实体
|
||||
*
|
||||
*
|
||||
* @date 2022/4/21 16:13
|
||||
**/
|
||||
@Getter
|
||||
@Setter
|
||||
@TableName("SYS_ORG")
|
||||
public class BizOrg extends CommonEntity implements TransPojo {
|
||||
|
||||
/** id */
|
||||
@ApiModelProperty(value = "id", position = 1)
|
||||
private String id;
|
||||
|
||||
/** 租户id */
|
||||
@ApiModelProperty(value = "租户id", position = 2)
|
||||
private String tenantId;
|
||||
|
||||
/** 父id */
|
||||
@ApiModelProperty(value = "父id", position = 3)
|
||||
private String parentId;
|
||||
|
||||
/** 主管id */
|
||||
@ApiModelProperty(value = "主管id", position = 4)
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
@Trans(type = TransType.SIMPLE, target = BizUser.class, fields = "name", alias = "director", ref = "directorName")
|
||||
private String directorId;
|
||||
|
||||
/** 名称 */
|
||||
@ApiModelProperty(value = "名称", position = 5)
|
||||
private String name;
|
||||
|
||||
/** 编码 */
|
||||
@ApiModelProperty(value = "编码", position = 6)
|
||||
private String code;
|
||||
|
||||
/** 分类 */
|
||||
@ApiModelProperty(value = "分类", position = 7)
|
||||
private String category;
|
||||
|
||||
/** 排序码 */
|
||||
@ApiModelProperty(value = "排序码", position = 8)
|
||||
private Integer sortCode;
|
||||
|
||||
/** 扩展信息 */
|
||||
@ApiModelProperty(value = "扩展信息", position = 9)
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
private String extJson;
|
||||
}
|
@@ -0,0 +1,34 @@
|
||||
|
||||
package mjkf.xinke.biz.modular.org.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
import mjkf.xinke.common.exception.CommonException;
|
||||
|
||||
/**
|
||||
* 机构分类枚举
|
||||
*
|
||||
*
|
||||
* @date 2022/4/21 19:56
|
||||
**/
|
||||
@Getter
|
||||
public enum BizOrgCategoryEnum {
|
||||
|
||||
/** 公司 */
|
||||
COMPANY("COMPANY"),
|
||||
|
||||
/** 部门 */
|
||||
DEPT("DEPT");
|
||||
|
||||
private final String value;
|
||||
|
||||
BizOrgCategoryEnum(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public static void validate(String value) {
|
||||
boolean flag = COMPANY.getValue().equals(value) || DEPT.getValue().equals(value);
|
||||
if(!flag) {
|
||||
throw new CommonException("不支持的机构分类:{}", value);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,14 @@
|
||||
|
||||
package mjkf.xinke.biz.modular.org.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import mjkf.xinke.biz.modular.org.entity.BizOrg;
|
||||
|
||||
/**
|
||||
* 机构Mapper接口
|
||||
*
|
||||
*
|
||||
* @date 2022/4/21 18:37
|
||||
**/
|
||||
public interface BizOrgMapper extends BaseMapper<BizOrg> {
|
||||
}
|
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="mjkf.xinke.biz.modular.org.mapper.BizOrgMapper">
|
||||
|
||||
|
||||
</mapper>
|
@@ -0,0 +1,48 @@
|
||||
|
||||
package mjkf.xinke.biz.modular.org.param;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 机构添加参数
|
||||
*
|
||||
*
|
||||
* @date 2022/4/21 16:13
|
||||
**/
|
||||
@Getter
|
||||
@Setter
|
||||
public class BizOrgAddParam {
|
||||
|
||||
/** 父id */
|
||||
@ApiModelProperty(value = "父id", required = true, position = 1)
|
||||
@NotBlank(message = "parentId不能为空")
|
||||
private String parentId;
|
||||
|
||||
/** 名称 */
|
||||
@ApiModelProperty(value = "名称", required = true, position = 2)
|
||||
@NotBlank(message = "name不能为空")
|
||||
private String name;
|
||||
|
||||
/** 分类 */
|
||||
@ApiModelProperty(value = "分类", required = true, position = 3)
|
||||
@NotBlank(message = "category不能为空")
|
||||
private String category;
|
||||
|
||||
/** 排序码 */
|
||||
@ApiModelProperty(value = "排序码", required = true, position = 4)
|
||||
@NotNull(message = "sortCode不能为空")
|
||||
private Integer sortCode;
|
||||
|
||||
/** 主管id */
|
||||
@ApiModelProperty(value = "主管id", position = 5)
|
||||
private String directorId;
|
||||
|
||||
/** 扩展JSON */
|
||||
@ApiModelProperty(value = "扩展JSON", position = 6)
|
||||
private String extJson;
|
||||
}
|
@@ -0,0 +1,53 @@
|
||||
|
||||
package mjkf.xinke.biz.modular.org.param;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 机构编辑参数
|
||||
*
|
||||
*
|
||||
* @date 2022/4/21 16:13
|
||||
**/
|
||||
@Getter
|
||||
@Setter
|
||||
public class BizOrgEditParam {
|
||||
|
||||
/** id */
|
||||
@ApiModelProperty(value = "id", required = true, position = 1)
|
||||
@NotBlank(message = "id不能为空")
|
||||
private String id;
|
||||
|
||||
/** 父id */
|
||||
@ApiModelProperty(value = "父id", required = true, position = 2)
|
||||
@NotBlank(message = "parentId不能为空")
|
||||
private String parentId;
|
||||
|
||||
/** 名称 */
|
||||
@ApiModelProperty(value = "名称", required = true, position = 3)
|
||||
@NotBlank(message = "name不能为空")
|
||||
private String name;
|
||||
|
||||
/** 分类 */
|
||||
@ApiModelProperty(value = "分类", required = true, position = 4)
|
||||
@NotBlank(message = "category不能为空")
|
||||
private String category;
|
||||
|
||||
/** 排序码 */
|
||||
@ApiModelProperty(value = "排序码", required = true, position = 5)
|
||||
@NotNull(message = "sortCode不能为空")
|
||||
private Integer sortCode;
|
||||
|
||||
/** 主管id */
|
||||
@ApiModelProperty(value = "主管id", position = 6)
|
||||
private String directorId;
|
||||
|
||||
/** 扩展JSON */
|
||||
@ApiModelProperty(value = "扩展JSON", position = 7)
|
||||
private String extJson;
|
||||
}
|
@@ -0,0 +1,24 @@
|
||||
|
||||
package mjkf.xinke.biz.modular.org.param;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
/**
|
||||
* 机构Id参数
|
||||
*
|
||||
*
|
||||
* @date 2022/4/21 16:13
|
||||
**/
|
||||
@Getter
|
||||
@Setter
|
||||
public class BizOrgIdParam {
|
||||
|
||||
/** id */
|
||||
@ApiModelProperty(value = "id", required = true)
|
||||
@NotBlank(message = "id不能为空")
|
||||
private String id;
|
||||
}
|
@@ -0,0 +1,41 @@
|
||||
|
||||
package mjkf.xinke.biz.modular.org.param;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* 机构查询参数
|
||||
*
|
||||
*
|
||||
* @date 2022/4/21 16:13
|
||||
**/
|
||||
@Getter
|
||||
@Setter
|
||||
public class BizOrgPageParam {
|
||||
|
||||
/** 当前页 */
|
||||
@ApiModelProperty(value = "当前页码")
|
||||
private Integer current;
|
||||
|
||||
/** 每页条数 */
|
||||
@ApiModelProperty(value = "每页条数")
|
||||
private Integer size;
|
||||
|
||||
/** 排序字段 */
|
||||
@ApiModelProperty(value = "排序字段,字段驼峰名称,如:userName")
|
||||
private String sortField;
|
||||
|
||||
/** 排序方式 */
|
||||
@ApiModelProperty(value = "排序方式,升序:ASCEND;降序:DESCEND")
|
||||
private String sortOrder;
|
||||
|
||||
/** 父id */
|
||||
@ApiModelProperty(value = "父id")
|
||||
private String parentId;
|
||||
|
||||
/** 名称关键词 */
|
||||
@ApiModelProperty(value = "名称关键词")
|
||||
private String searchKey;
|
||||
}
|
@@ -0,0 +1,33 @@
|
||||
|
||||
package mjkf.xinke.biz.modular.org.param;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* 机构列表选择器参数
|
||||
*
|
||||
*
|
||||
* @date 2022/4/21 16:13
|
||||
**/
|
||||
@Getter
|
||||
@Setter
|
||||
public class BizOrgSelectorOrgListParam {
|
||||
|
||||
/** 当前页 */
|
||||
@ApiModelProperty(value = "当前页码")
|
||||
private Integer current;
|
||||
|
||||
/** 每页条数 */
|
||||
@ApiModelProperty(value = "每页条数")
|
||||
private Integer size;
|
||||
|
||||
/** 父id */
|
||||
@ApiModelProperty(value = "父id")
|
||||
private String parentId;
|
||||
|
||||
/** 名称关键词 */
|
||||
@ApiModelProperty(value = "名称关键词")
|
||||
private String searchKey;
|
||||
}
|
@@ -0,0 +1,33 @@
|
||||
|
||||
package mjkf.xinke.biz.modular.org.param;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* 人员选择器参数
|
||||
*
|
||||
*
|
||||
* @date 2022/4/21 16:13
|
||||
**/
|
||||
@Getter
|
||||
@Setter
|
||||
public class BizOrgSelectorUserParam {
|
||||
|
||||
/** 当前页 */
|
||||
@ApiModelProperty(value = "当前页码")
|
||||
private Integer current;
|
||||
|
||||
/** 每页条数 */
|
||||
@ApiModelProperty(value = "每页条数")
|
||||
private Integer size;
|
||||
|
||||
/** 机构id */
|
||||
@ApiModelProperty(value = "机构id")
|
||||
private String orgId;
|
||||
|
||||
/** 姓名关键词 */
|
||||
@ApiModelProperty(value = "姓名关键词")
|
||||
private String searchKey;
|
||||
}
|
@@ -0,0 +1,173 @@
|
||||
|
||||
package mjkf.xinke.biz.modular.org.service;
|
||||
|
||||
import cn.hutool.core.lang.tree.Tree;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import mjkf.xinke.biz.modular.org.entity.BizOrg;
|
||||
import mjkf.xinke.biz.modular.org.param.*;
|
||||
import mjkf.xinke.biz.modular.user.entity.BizUser;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 机构Service接口
|
||||
*
|
||||
*
|
||||
* @date 2022/4/21 18:35
|
||||
**/
|
||||
public interface BizOrgService extends IService<BizOrg> {
|
||||
|
||||
/**
|
||||
* 获取机构分页
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 20:08
|
||||
*/
|
||||
Page<BizOrg> page(BizOrgPageParam bizOrgPageParam);
|
||||
|
||||
/**
|
||||
* 获取机构树
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 20:08
|
||||
*/
|
||||
List<Tree<String>> tree();
|
||||
|
||||
/**
|
||||
* 添加机构
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 20:48
|
||||
*/
|
||||
void add(BizOrgAddParam bizOrgAddParam);
|
||||
|
||||
/**
|
||||
* 编辑机构
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 21:13
|
||||
*/
|
||||
void edit(BizOrgEditParam bizOrgEditParam);
|
||||
|
||||
/**
|
||||
* 删除机构
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 21:18
|
||||
*/
|
||||
void delete(List<BizOrgIdParam> bizOrgIdParamList);
|
||||
|
||||
/**
|
||||
* 获取机构详情
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 21:18
|
||||
*/
|
||||
BizOrg detail(BizOrgIdParam bizOrgIdParam);
|
||||
|
||||
/**
|
||||
* 获取机构详情
|
||||
*
|
||||
*
|
||||
* @date 2022/7/25 19:42
|
||||
**/
|
||||
BizOrg queryEntity(String id);
|
||||
|
||||
/**
|
||||
* 获取所有机构
|
||||
*
|
||||
*
|
||||
* @date 2022/7/25 19:42
|
||||
**/
|
||||
List<BizOrg> getAllOrgList();
|
||||
|
||||
/**
|
||||
* 根据组织全名称获取组织id,有则返回,无则创建
|
||||
*
|
||||
*
|
||||
* @date 2023/3/7 15:44
|
||||
**/
|
||||
String getOrgIdByOrgFullNameWithCreate(String orgFullName);
|
||||
|
||||
/**
|
||||
* 根据id获取父子数据列表
|
||||
*
|
||||
*
|
||||
* @date 2022/8/15 14:55
|
||||
**/
|
||||
List<BizOrg> getParentAndChildListById(List<BizOrg> originDataList, String id, boolean includeSelf);
|
||||
|
||||
/**
|
||||
* 根据id获取所有的子数据列表
|
||||
*
|
||||
*
|
||||
* @date 2022/8/15 14:55
|
||||
**/
|
||||
List<BizOrg> getChildListById(List<BizOrg> originDataList, String id, boolean includeSelf);
|
||||
|
||||
/**
|
||||
* 根据id获取所有的父数据列表
|
||||
*
|
||||
*
|
||||
* @date 2022/8/15 14:55
|
||||
**/
|
||||
List<BizOrg> getParentListById(List<BizOrg> originDataList, String id, boolean includeSelf);
|
||||
|
||||
/**
|
||||
* 根据id获取数据
|
||||
*
|
||||
*
|
||||
* @date 2022/8/15 14:55
|
||||
**/
|
||||
BizOrg getById(List<BizOrg> originDataList, String id);
|
||||
|
||||
/**
|
||||
* 根据id获取父数据
|
||||
*
|
||||
*
|
||||
* @date 2022/8/15 14:55
|
||||
**/
|
||||
BizOrg getParentById(List<BizOrg> originDataList, String id);
|
||||
|
||||
/**
|
||||
* 根据id获取子数据
|
||||
*
|
||||
*
|
||||
* @date 2022/8/15 14:55
|
||||
**/
|
||||
BizOrg getChildById(List<BizOrg> originDataList, String id);
|
||||
|
||||
/**
|
||||
* 获取机构树选择器
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 20:08
|
||||
*/
|
||||
List<Tree<String>> orgTreeSelector();
|
||||
|
||||
/**
|
||||
* 获取机构列表选择器
|
||||
*
|
||||
*
|
||||
* @date 2022/7/22 13:34
|
||||
**/
|
||||
List<BizOrg> orgListSelector(BizOrgSelectorOrgListParam bizOrgSelectorOrgListParam);
|
||||
|
||||
/**
|
||||
* 获取人员选择器
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 20:08
|
||||
*/
|
||||
Page<BizUser> userSelector(BizOrgSelectorUserParam bizOrgSelectorUserParam);
|
||||
|
||||
/**
|
||||
* 获取动态字段配置
|
||||
*
|
||||
*
|
||||
* @date 2022/8/5 3:23
|
||||
*/
|
||||
List<JSONObject> dynamicFieldConfigList();
|
||||
}
|
@@ -0,0 +1,468 @@
|
||||
|
||||
package mjkf.xinke.biz.modular.org.service.impl;
|
||||
|
||||
import cn.hutool.core.annotation.AnnotationUtil;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.collection.CollStreamUtil;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.lang.Console;
|
||||
import cn.hutool.core.lang.tree.Tree;
|
||||
import cn.hutool.core.lang.tree.TreeNode;
|
||||
import cn.hutool.core.lang.tree.TreeUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import mjkf.xinke.auth.core.util.StpLoginUserUtil;
|
||||
import mjkf.xinke.biz.core.enums.BizDataTypeEnum;
|
||||
import mjkf.xinke.biz.modular.org.entity.BizOrg;
|
||||
import mjkf.xinke.biz.modular.org.enums.BizOrgCategoryEnum;
|
||||
import mjkf.xinke.biz.modular.org.mapper.BizOrgMapper;
|
||||
import mjkf.xinke.biz.modular.org.param.*;
|
||||
import mjkf.xinke.biz.modular.org.service.BizOrgService;
|
||||
import mjkf.xinke.biz.modular.position.entity.BizPosition;
|
||||
import mjkf.xinke.biz.modular.position.service.BizPositionService;
|
||||
import mjkf.xinke.biz.modular.user.entity.BizUser;
|
||||
import mjkf.xinke.biz.modular.user.service.BizUserService;
|
||||
import mjkf.xinke.common.enums.CommonSortOrderEnum;
|
||||
import mjkf.xinke.common.exception.CommonException;
|
||||
import mjkf.xinke.common.listener.CommonDataChangeEventCenter;
|
||||
import mjkf.xinke.common.page.CommonPageRequest;
|
||||
import mjkf.xinke.dbs.api.DbsApi;
|
||||
import mjkf.xinke.dev.api.DevDfcApi;
|
||||
import mjkf.xinke.sys.api.SysRoleApi;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 机构Service接口实现类
|
||||
*
|
||||
*
|
||||
* @date 2022/2/23 18:43
|
||||
**/
|
||||
@Service
|
||||
public class BizOrgServiceImpl extends ServiceImpl<BizOrgMapper, BizOrg> implements BizOrgService {
|
||||
|
||||
@Resource
|
||||
private SysRoleApi sysRoleApi;
|
||||
|
||||
@Resource
|
||||
private BizPositionService bizPositionService;
|
||||
|
||||
@Resource
|
||||
private BizUserService bizUserService;
|
||||
|
||||
@Resource
|
||||
private DbsApi dbsApi;
|
||||
|
||||
@Resource
|
||||
private DevDfcApi devDfcApi;
|
||||
|
||||
@Override
|
||||
public Page<BizOrg> page(BizOrgPageParam bizOrgPageParam) {
|
||||
QueryWrapper<BizOrg> queryWrapper = new QueryWrapper<>();
|
||||
// 查询部分字段
|
||||
queryWrapper.lambda().select(BizOrg::getId, BizOrg::getParentId, BizOrg::getName,
|
||||
BizOrg::getCategory, BizOrg::getSortCode);
|
||||
if(ObjectUtil.isNotEmpty(bizOrgPageParam.getParentId())) {
|
||||
queryWrapper.lambda().eq(BizOrg::getParentId, bizOrgPageParam.getParentId());
|
||||
}
|
||||
if(ObjectUtil.isNotEmpty(bizOrgPageParam.getSearchKey())) {
|
||||
queryWrapper.lambda().like(BizOrg::getName, bizOrgPageParam.getSearchKey());
|
||||
}
|
||||
if(ObjectUtil.isAllNotEmpty(bizOrgPageParam.getSortField(), bizOrgPageParam.getSortOrder())) {
|
||||
CommonSortOrderEnum.validate(bizOrgPageParam.getSortOrder());
|
||||
queryWrapper.orderBy(true, bizOrgPageParam.getSortOrder().equals(CommonSortOrderEnum.ASC.getValue()),
|
||||
StrUtil.toUnderlineCase(bizOrgPageParam.getSortField()));
|
||||
} else {
|
||||
queryWrapper.lambda().orderByAsc(BizOrg::getSortCode);
|
||||
}
|
||||
// 校验数据范围
|
||||
List<String> loginUserDataScope = StpLoginUserUtil.getLoginUserDataScope();
|
||||
if(ObjectUtil.isNotEmpty(loginUserDataScope)) {
|
||||
queryWrapper.lambda().in(BizOrg::getId, loginUserDataScope);
|
||||
} else {
|
||||
return new Page<>();
|
||||
}
|
||||
return this.page(CommonPageRequest.defaultPage(), queryWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Tree<String>> tree() {
|
||||
// 获取所有机构
|
||||
List<BizOrg> allOrgList = this.list();
|
||||
// 定义机构集合
|
||||
Set<BizOrg> bizOrgSet = CollectionUtil.newHashSet();
|
||||
// 校验数据范围
|
||||
List<String> loginUserDataScope = StpLoginUserUtil.getLoginUserDataScope();
|
||||
if(ObjectUtil.isNotEmpty(loginUserDataScope)) {
|
||||
loginUserDataScope.forEach(orgId -> bizOrgSet.addAll(this.getParentListById(allOrgList, orgId, true)));
|
||||
} else {
|
||||
return CollectionUtil.newArrayList();
|
||||
}
|
||||
List<TreeNode<String>> treeNodeList = bizOrgSet.stream().map(bizOrg ->
|
||||
new TreeNode<>(bizOrg.getId(), bizOrg.getParentId(),
|
||||
bizOrg.getName(), bizOrg.getSortCode()).setExtra(JSONUtil.parseObj(bizOrg)))
|
||||
.collect(Collectors.toList());
|
||||
return TreeUtil.build(treeNodeList, "0");
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public void add(BizOrgAddParam bizOrgAddParam) {
|
||||
BizOrgCategoryEnum.validate(bizOrgAddParam.getCategory());
|
||||
// 校验数据范围
|
||||
List<String> loginUserDataScope = StpLoginUserUtil.getLoginUserDataScope();
|
||||
if(ObjectUtil.isNotEmpty(loginUserDataScope)) {
|
||||
if(!loginUserDataScope.contains(bizOrgAddParam.getParentId())) {
|
||||
throw new CommonException("您没有权限在该机构下增加机构,机构id:{}", bizOrgAddParam.getParentId());
|
||||
}
|
||||
} else {
|
||||
throw new CommonException("您没有权限增加机构");
|
||||
}
|
||||
BizOrg bizOrg = BeanUtil.toBean(bizOrgAddParam, BizOrg.class);
|
||||
|
||||
// 重复名称
|
||||
boolean repeatName = this.count(new LambdaQueryWrapper<BizOrg>().eq(BizOrg::getParentId, bizOrg.getParentId())
|
||||
.eq(BizOrg::getName, bizOrg.getName())) > 0;
|
||||
if(repeatName) {
|
||||
throw new CommonException("存在重复的同级机构,名称为:{}", bizOrg.getName());
|
||||
}
|
||||
bizOrg.setCode(RandomUtil.randomString(10));
|
||||
this.save(bizOrg);
|
||||
|
||||
// 发布增加事件
|
||||
CommonDataChangeEventCenter.doAddWithData(BizDataTypeEnum.ORG.getValue(), JSONUtil.createArray().put(bizOrg));
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public void edit(BizOrgEditParam bizOrgEditParam) {
|
||||
BizOrgCategoryEnum.validate(bizOrgEditParam.getCategory());
|
||||
BizOrg bizOrg = this.queryEntity(bizOrgEditParam.getId());
|
||||
// 校验数据范围
|
||||
List<String> loginUserDataScope = StpLoginUserUtil.getLoginUserDataScope();
|
||||
if(ObjectUtil.isNotEmpty(loginUserDataScope)) {
|
||||
if(!loginUserDataScope.contains(bizOrg.getId())) {
|
||||
throw new CommonException("您没有权限编辑该机构,机构id:{}", bizOrg.getId());
|
||||
}
|
||||
if(!loginUserDataScope.contains(bizOrg.getParentId())) {
|
||||
throw new CommonException("您没有权限编辑该机构下的机构,机构id:{}", bizOrg.getParentId());
|
||||
}
|
||||
} else {
|
||||
throw new CommonException("您没有权限编辑该机构,机构id:{}", bizOrg.getId());
|
||||
}
|
||||
BeanUtil.copyProperties(bizOrgEditParam, bizOrg);
|
||||
boolean repeatName = this.count(new LambdaQueryWrapper<BizOrg>().eq(BizOrg::getParentId, bizOrg.getParentId())
|
||||
.eq(BizOrg::getName, bizOrg.getName()).ne(BizOrg::getId, bizOrg.getId())) > 0;
|
||||
if(repeatName) {
|
||||
throw new CommonException("存在重复的同级机构,名称为:{}", bizOrg.getName());
|
||||
}
|
||||
List<BizOrg> originDataList = this.list();
|
||||
boolean errorLevel = this.getChildListById(originDataList, bizOrg.getId(), true).stream()
|
||||
.map(BizOrg::getId).collect(Collectors.toList()).contains(bizOrg.getParentId());
|
||||
if(errorLevel) {
|
||||
throw new CommonException("不可选择上级机构:{}", this.getById(originDataList, bizOrg.getParentId()).getName());
|
||||
}
|
||||
this.updateById(bizOrg);
|
||||
|
||||
// 发布更新事件
|
||||
CommonDataChangeEventCenter.doUpdateWithData(BizDataTypeEnum.ORG.getValue(), JSONUtil.createArray().put(bizOrg));
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public void delete(List<BizOrgIdParam> bizOrgIdParamList) {
|
||||
List<String> orgIdList = CollStreamUtil.toList(bizOrgIdParamList, BizOrgIdParam::getId);
|
||||
if(ObjectUtil.isNotEmpty(orgIdList)) {
|
||||
// 校验数据范围
|
||||
List<String> loginUserDataScope = StpLoginUserUtil.getLoginUserDataScope();
|
||||
if(ObjectUtil.isNotEmpty(loginUserDataScope)) {
|
||||
if(!loginUserDataScope.containsAll(orgIdList)) {
|
||||
throw new CommonException("您没有权限删除这些机构,机构id:{}", orgIdList);
|
||||
}
|
||||
} else {
|
||||
throw new CommonException("您没有权限删除这些机构,机构id:{}", orgIdList);
|
||||
}
|
||||
List<BizOrg> allOrgList = this.list();
|
||||
// 获取所有子机构
|
||||
List<String> toDeleteOrgIdList = CollectionUtil.newArrayList();
|
||||
orgIdList.forEach(orgId -> toDeleteOrgIdList.addAll(this.getChildListById(allOrgList, orgId, true).stream()
|
||||
.map(BizOrg::getId).collect(Collectors.toList())));
|
||||
// 机构下有人不能删除(直属机构)
|
||||
boolean hasOrgUser = bizUserService.count(new LambdaQueryWrapper<BizUser>().in(BizUser::getOrgId, toDeleteOrgIdList)) > 0;
|
||||
if(hasOrgUser) {
|
||||
throw new CommonException("请先删除机构下的人员");
|
||||
}
|
||||
// 机构下有人不能删除(兼任机构)
|
||||
List<String> positionJsonList = bizUserService.list(new LambdaQueryWrapper<BizUser>()
|
||||
.isNotNull(BizUser::getPositionJson)).stream().map(BizUser::getPositionJson).collect(Collectors.toList());
|
||||
if(ObjectUtil.isNotEmpty(positionJsonList)) {
|
||||
List<String> positionOrgIdList = CollectionUtil.newArrayList();
|
||||
positionJsonList.forEach(positionJson -> JSONUtil.toList(JSONUtil.parseArray(positionJson), JSONObject.class)
|
||||
.forEach(jsonObject -> positionOrgIdList.add(jsonObject.getStr("orgId"))));
|
||||
boolean hasPositionUser = CollectionUtil.intersectionDistinct(toDeleteOrgIdList, CollectionUtil.removeNull(positionOrgIdList)).size() > 0;
|
||||
if(hasPositionUser) {
|
||||
throw new CommonException("请先删除机构下的人员");
|
||||
}
|
||||
}
|
||||
// 机构下有角色不能删除
|
||||
boolean hasRole = sysRoleApi.orgHasRole(toDeleteOrgIdList);
|
||||
if(hasRole) {
|
||||
throw new CommonException("请先删除机构下的角色");
|
||||
}
|
||||
// 机构下有岗位不能删除
|
||||
boolean hasPosition = bizPositionService.count(new LambdaQueryWrapper<BizPosition>().in(BizPosition::getOrgId, toDeleteOrgIdList)) > 0;
|
||||
if(hasPosition) {
|
||||
throw new CommonException("请先删除机构下的岗位");
|
||||
}
|
||||
// 执行删除
|
||||
this.removeByIds(toDeleteOrgIdList);
|
||||
|
||||
// 发布删除事件
|
||||
CommonDataChangeEventCenter.doDeleteWithDataId(BizDataTypeEnum.ORG.getValue(), toDeleteOrgIdList);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BizOrg detail(BizOrgIdParam bizOrgIdParam) {
|
||||
return this.queryEntity(bizOrgIdParam.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public BizOrg queryEntity(String id) {
|
||||
BizOrg bizOrg = this.getById(id);
|
||||
if(ObjectUtil.isEmpty(bizOrg)) {
|
||||
throw new CommonException("机构不存在,id值为:{}", id);
|
||||
}
|
||||
return bizOrg;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BizOrg> getAllOrgList() {
|
||||
return this.list(new LambdaQueryWrapper<BizOrg>().orderByAsc(BizOrg::getSortCode));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOrgIdByOrgFullNameWithCreate(String orgFullName) {
|
||||
List<BizOrg> allOrgList = this.getAllOrgList();
|
||||
List<Tree<String>> treeList = TreeUtil.build(allOrgList.stream().map(bizOrg ->
|
||||
new TreeNode<>(bizOrg.getId(), bizOrg.getParentId(), bizOrg.getName(), bizOrg.getSortCode()))
|
||||
.collect(Collectors.toList()), "0");
|
||||
return findOrgIdByOrgName("0", StrUtil.split(orgFullName, StrUtil.DASHED).iterator(), allOrgList, treeList);
|
||||
}
|
||||
|
||||
public String findOrgIdByOrgName(String parentId, Iterator<String> iterator, List<BizOrg> allOrgList, List<Tree<String>> treeList) {
|
||||
String orgName = iterator.next();
|
||||
if(ObjectUtil.isNotEmpty(treeList)) {
|
||||
List<Tree<String>> findList = treeList.stream().filter(tree -> tree.getName().equals(orgName)).collect(Collectors.toList());
|
||||
if(ObjectUtil.isNotEmpty(findList)) {
|
||||
if(iterator.hasNext()) {
|
||||
return findOrgIdByOrgName(findList.get(0).getId(), iterator, allOrgList, findList.get(0).getChildren());
|
||||
} else {
|
||||
return findList.get(0).getId();
|
||||
}
|
||||
}
|
||||
}
|
||||
String orgId = this.doCreateOrg(parentId, orgName, allOrgList);
|
||||
if(iterator.hasNext()) {
|
||||
return findOrgIdByOrgName(orgId, iterator, allOrgList, CollectionUtil.newArrayList());
|
||||
} else {
|
||||
return orgId;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行创建机构
|
||||
*
|
||||
*
|
||||
* @date 2023/3/8 9:38
|
||||
**/
|
||||
public String doCreateOrg(String parentId, String orgName, List<BizOrg> allOrgList) {
|
||||
//创建该机构
|
||||
BizOrg bizOrg = new BizOrg();
|
||||
bizOrg.setName(orgName);
|
||||
bizOrg.setCode(RandomUtil.randomString(10));
|
||||
bizOrg.setParentId(parentId);
|
||||
bizOrg.setCategory("0".equals(parentId)?BizOrgCategoryEnum.COMPANY.getValue():BizOrgCategoryEnum.DEPT.getValue());
|
||||
bizOrg.setSortCode(99);
|
||||
this.save(bizOrg);
|
||||
// 发布增加事件
|
||||
CommonDataChangeEventCenter.doAddWithData(BizDataTypeEnum.ORG.getValue(), JSONUtil.createArray().put(bizOrg));
|
||||
return bizOrg.getId();
|
||||
}
|
||||
|
||||
/* ====机构部分所需要用到的选择器==== */
|
||||
|
||||
@Override
|
||||
public List<Tree<String>> orgTreeSelector() {
|
||||
LambdaQueryWrapper<BizOrg> lambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||
// 校验数据范围
|
||||
List<String> loginUserDataScope = StpLoginUserUtil.getLoginUserDataScope();
|
||||
// 定义机构集合
|
||||
Set<BizOrg> bizOrgSet = CollectionUtil.newHashSet();
|
||||
if(ObjectUtil.isNotEmpty(loginUserDataScope)) {
|
||||
// 获取所有机构
|
||||
List<BizOrg> allOrgList = this.list();
|
||||
loginUserDataScope.forEach(orgId -> bizOrgSet.addAll(this.getParentListById(allOrgList, orgId, true)));
|
||||
List<String> loginUserDataScopeFullList = bizOrgSet.stream().map(BizOrg::getId).collect(Collectors.toList());
|
||||
lambdaQueryWrapper.in(BizOrg::getId, loginUserDataScopeFullList);
|
||||
} else {
|
||||
return CollectionUtil.newArrayList();
|
||||
}
|
||||
lambdaQueryWrapper.orderByAsc(BizOrg::getSortCode);
|
||||
List<BizOrg> bizOrgList = this.list(lambdaQueryWrapper);
|
||||
List<TreeNode<String>> treeNodeList = bizOrgList.stream().map(bizOrg ->
|
||||
new TreeNode<>(bizOrg.getId(), bizOrg.getParentId(), bizOrg.getName(), bizOrg.getSortCode()))
|
||||
.collect(Collectors.toList());
|
||||
return TreeUtil.build(treeNodeList, "0");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BizOrg> orgListSelector(BizOrgSelectorOrgListParam bizOrgSelectorOrgListParam) {
|
||||
LambdaQueryWrapper<BizOrg> lambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||
// 校验数据范围
|
||||
List<String> loginUserDataScope = StpLoginUserUtil.getLoginUserDataScope();
|
||||
if(ObjectUtil.isNotEmpty(loginUserDataScope)) {
|
||||
lambdaQueryWrapper.in(BizOrg::getId, loginUserDataScope);
|
||||
} else {
|
||||
return CollectionUtil.newArrayList();
|
||||
}
|
||||
// 查询部分字段
|
||||
lambdaQueryWrapper.select(BizOrg::getId, BizOrg::getParentId, BizOrg::getName,
|
||||
BizOrg::getCategory, BizOrg::getSortCode);
|
||||
if(ObjectUtil.isNotEmpty(bizOrgSelectorOrgListParam.getParentId())) {
|
||||
lambdaQueryWrapper.eq(BizOrg::getParentId, bizOrgSelectorOrgListParam.getParentId());
|
||||
}
|
||||
if(ObjectUtil.isNotEmpty(bizOrgSelectorOrgListParam.getSearchKey())) {
|
||||
lambdaQueryWrapper.like(BizOrg::getName, bizOrgSelectorOrgListParam.getSearchKey());
|
||||
}
|
||||
lambdaQueryWrapper.orderByAsc(BizOrg::getSortCode);
|
||||
return this.list(lambdaQueryWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<BizUser> userSelector(BizOrgSelectorUserParam bizOrgSelectorUserParam) {
|
||||
LambdaQueryWrapper<BizUser> lambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||
// 校验数据范围
|
||||
List<String> loginUserDataScope = StpLoginUserUtil.getLoginUserDataScope();
|
||||
if(ObjectUtil.isNotEmpty(loginUserDataScope)) {
|
||||
lambdaQueryWrapper.in(BizUser::getOrgId, loginUserDataScope);
|
||||
} else {
|
||||
return new Page<>();
|
||||
}
|
||||
// 只查询部分字段
|
||||
lambdaQueryWrapper.select(BizUser::getId, BizUser::getAvatar, BizUser::getOrgId, BizUser::getPositionId, BizUser::getAccount,
|
||||
BizUser::getName, BizUser::getSortCode, BizUser::getGender, BizUser::getEntryDate);
|
||||
if (ObjectUtil.isNotEmpty(bizOrgSelectorUserParam.getOrgId())) {
|
||||
// 如果机构id不为空,则查询该机构及其子机构下的所有人
|
||||
List<String> childOrgIdList = CollStreamUtil.toList(this.getChildListById(this
|
||||
.getAllOrgList(), bizOrgSelectorUserParam.getOrgId(), true), BizOrg::getId);
|
||||
if (ObjectUtil.isNotEmpty(childOrgIdList)) {
|
||||
lambdaQueryWrapper.in(BizUser::getOrgId, childOrgIdList);
|
||||
} else {
|
||||
return new Page<>();
|
||||
}
|
||||
}
|
||||
if(ObjectUtil.isNotEmpty(bizOrgSelectorUserParam.getSearchKey())) {
|
||||
lambdaQueryWrapper.like(BizUser::getName, bizOrgSelectorUserParam.getSearchKey());
|
||||
}
|
||||
lambdaQueryWrapper.orderByAsc(BizUser::getSortCode);
|
||||
return bizUserService.page(CommonPageRequest.defaultPage(), lambdaQueryWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<JSONObject> dynamicFieldConfigList() {
|
||||
String currentDataSourceId = dbsApi.getCurrentDataSourceId();
|
||||
String tableName = AnnotationUtil.getAnnotationValue(BizOrg.class, TableName.class);
|
||||
return devDfcApi.getTableFieldList(currentDataSourceId, tableName);
|
||||
}
|
||||
|
||||
/* ====以下为各种递归方法==== */
|
||||
|
||||
@Override
|
||||
public List<BizOrg> getParentAndChildListById(List<BizOrg> originDataList, String id, boolean includeSelf) {
|
||||
List<BizOrg> parentListById = this.getParentListById(originDataList, id, false);
|
||||
List<BizOrg> childListById = this.getChildListById(originDataList, id, true);
|
||||
parentListById.addAll(childListById);
|
||||
return parentListById;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BizOrg> getChildListById(List<BizOrg> originDataList, String id, boolean includeSelf) {
|
||||
List<BizOrg> resultList = CollectionUtil.newArrayList();
|
||||
execRecursionFindChild(originDataList, id, resultList);
|
||||
if(includeSelf) {
|
||||
BizOrg self = this.getById(originDataList, id);
|
||||
if(ObjectUtil.isNotEmpty(self)) {
|
||||
resultList.add(self);
|
||||
}
|
||||
}
|
||||
return resultList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BizOrg> getParentListById(List<BizOrg> originDataList, String id, boolean includeSelf) {
|
||||
List<BizOrg> resultList = CollectionUtil.newArrayList();
|
||||
execRecursionFindParent(originDataList, id, resultList);
|
||||
if(includeSelf) {
|
||||
BizOrg self = this.getById(originDataList, id);
|
||||
if(ObjectUtil.isNotEmpty(self)) {
|
||||
resultList.add(self);
|
||||
}
|
||||
}
|
||||
return resultList;
|
||||
}
|
||||
|
||||
|
||||
public void execRecursionFindChild(List<BizOrg> originDataList, String id, List<BizOrg> resultList) {
|
||||
originDataList.forEach(item -> {
|
||||
if(item.getParentId().equals(id)) {
|
||||
resultList.add(item);
|
||||
execRecursionFindChild(originDataList, item.getId(), resultList);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void execRecursionFindParent(List<BizOrg> originDataList, String id, List<BizOrg> resultList) {
|
||||
originDataList.forEach(item -> {
|
||||
if(item.getId().equals(id)) {
|
||||
BizOrg parent = this.getById(originDataList, item.getParentId());
|
||||
if(ObjectUtil.isNotEmpty(parent)) {
|
||||
resultList.add(parent);
|
||||
}
|
||||
execRecursionFindParent(originDataList, item.getParentId(), resultList);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public BizOrg getById(List<BizOrg> originDataList, String id) {
|
||||
int index = CollStreamUtil.toList(originDataList, BizOrg::getId).indexOf(id);
|
||||
return index == -1?null:originDataList.get(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BizOrg getParentById(List<BizOrg> originDataList, String id) {
|
||||
BizOrg self = this.getById(originDataList, id);
|
||||
return ObjectUtil.isNotEmpty(self)?self:this.getById(originDataList, self.getParentId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public BizOrg getChildById(List<BizOrg> originDataList, String id) {
|
||||
int index = CollStreamUtil.toList(originDataList, BizOrg::getParentId).indexOf(id);
|
||||
return index == -1?null:originDataList.get(index);
|
||||
}
|
||||
}
|
@@ -0,0 +1,164 @@
|
||||
|
||||
package mjkf.xinke.biz.modular.position.controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.hutool.core.lang.tree.Tree;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
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.RestController;
|
||||
import mjkf.xinke.biz.modular.position.entity.BizPosition;
|
||||
import mjkf.xinke.biz.modular.position.param.*;
|
||||
import mjkf.xinke.biz.modular.position.service.BizPositionService;
|
||||
import mjkf.xinke.common.annotation.CommonLog;
|
||||
import mjkf.xinke.common.pojo.CommonResult;
|
||||
import mjkf.xinke.common.pojo.CommonValidList;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 岗位控制器
|
||||
*
|
||||
*
|
||||
* @date 2022/4/25 20:40
|
||||
*/
|
||||
@Api(tags = "岗位控制器")
|
||||
@ApiSupport(author = "SNOWY_TEAM", order = 2)
|
||||
@RestController
|
||||
@Validated
|
||||
public class BizPositionController {
|
||||
|
||||
@Resource
|
||||
private BizPositionService bizPositionService;
|
||||
|
||||
/**
|
||||
* 获取岗位分页
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 20:00
|
||||
*/
|
||||
@ApiOperationSupport(order = 1)
|
||||
@ApiOperation("获取岗位分页")
|
||||
@SaCheckPermission("/biz/position/page")
|
||||
@GetMapping("/biz/position/page")
|
||||
public CommonResult<Page<BizPosition>> page(BizPositionPageParam bizPositionPageParam) {
|
||||
return CommonResult.data(bizPositionService.page(bizPositionPageParam));
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加岗位
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 20:47
|
||||
*/
|
||||
@ApiOperationSupport(order = 2)
|
||||
@ApiOperation("添加岗位")
|
||||
@CommonLog("添加岗位")
|
||||
@SaCheckPermission("/biz/position/add")
|
||||
@PostMapping("/biz/position/add")
|
||||
public CommonResult<String> add(@RequestBody @Valid BizPositionAddParam bizPositionAddParam) {
|
||||
bizPositionService.add(bizPositionAddParam);
|
||||
return CommonResult.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑岗位
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 20:47
|
||||
*/
|
||||
@ApiOperationSupport(order = 3)
|
||||
@ApiOperation("编辑岗位")
|
||||
@CommonLog("编辑岗位")
|
||||
@SaCheckPermission("/biz/position/edit")
|
||||
@PostMapping("/biz/position/edit")
|
||||
public CommonResult<String> edit(@RequestBody @Valid BizPositionEditParam bizPositionEditParam) {
|
||||
bizPositionService.edit(bizPositionEditParam);
|
||||
return CommonResult.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除岗位
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 20:00
|
||||
*/
|
||||
@ApiOperationSupport(order = 4)
|
||||
@ApiOperation("删除岗位")
|
||||
@CommonLog("删除岗位")
|
||||
@SaCheckPermission("/biz/position/delete")
|
||||
@PostMapping("/biz/position/delete")
|
||||
public CommonResult<String> delete(@RequestBody @Valid @NotEmpty(message = "集合不能为空")
|
||||
CommonValidList<BizPositionIdParam> bizPositionIdParamList) {
|
||||
bizPositionService.delete(bizPositionIdParamList);
|
||||
return CommonResult.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取岗位详情
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 20:00
|
||||
*/
|
||||
@ApiOperationSupport(order = 5)
|
||||
@ApiOperation("获取岗位详情")
|
||||
@SaCheckPermission("/biz/position/detail")
|
||||
@GetMapping("/biz/position/detail")
|
||||
public CommonResult<BizPosition> detail(@Valid BizPositionIdParam bizPositionIdParam) {
|
||||
return CommonResult.data(bizPositionService.detail(bizPositionIdParam));
|
||||
}
|
||||
|
||||
/* ====岗位部分所需要用到的选择器==== */
|
||||
|
||||
/**
|
||||
* 获取组织树选择器
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 20:00
|
||||
*/
|
||||
@ApiOperationSupport(order = 6)
|
||||
@ApiOperation("获取组织树选择器")
|
||||
@SaCheckPermission("/biz/position/orgTreeSelector")
|
||||
@GetMapping("/biz/position/orgTreeSelector")
|
||||
public CommonResult<List<Tree<String>>> orgTreeSelector() {
|
||||
return CommonResult.data(bizPositionService.orgTreeSelector());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取岗位选择器
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 20:00
|
||||
*/
|
||||
@ApiOperationSupport(order = 7)
|
||||
@ApiOperation("获取岗位选择器")
|
||||
@SaCheckPermission("/biz/position/positionSelector")
|
||||
@GetMapping("/biz/position/positionSelector")
|
||||
public CommonResult<Page<BizPosition>> positionSelector(BizPositionSelectorPositionParam bizPositionSelectorPositionParam) {
|
||||
return CommonResult.data(bizPositionService.positionSelector(bizPositionSelectorPositionParam));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取岗位动态字段的配置
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 20:00
|
||||
*/
|
||||
@ApiOperationSupport(order = 8)
|
||||
@ApiOperation("获取岗位动态字段的配置")
|
||||
@SaCheckPermission("/biz/position/dynamicFieldConfigList")
|
||||
@GetMapping("/biz/position/dynamicFieldConfigList")
|
||||
public CommonResult<List<JSONObject>> dynamicFieldConfigList() {
|
||||
return CommonResult.data(bizPositionService.dynamicFieldConfigList());
|
||||
}
|
||||
}
|
@@ -0,0 +1,56 @@
|
||||
|
||||
package mjkf.xinke.biz.modular.position.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.FieldStrategy;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.fhs.core.trans.vo.TransPojo;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import mjkf.xinke.common.pojo.CommonEntity;
|
||||
|
||||
/**
|
||||
* 岗位实体
|
||||
*
|
||||
*
|
||||
* @date 2022/4/21 16:13
|
||||
**/
|
||||
@Getter
|
||||
@Setter
|
||||
@TableName("SYS_POSITION")
|
||||
public class BizPosition extends CommonEntity implements TransPojo {
|
||||
|
||||
/** id */
|
||||
@ApiModelProperty(value = "id", position = 1)
|
||||
private String id;
|
||||
|
||||
/** 租户id */
|
||||
@ApiModelProperty(value = "租户id", position = 2)
|
||||
private String tenantId;
|
||||
|
||||
/** 机构id */
|
||||
@ApiModelProperty(value = "机构id", position = 3)
|
||||
private String orgId;
|
||||
|
||||
/** 名称 */
|
||||
@ApiModelProperty(value = "名称", position = 4)
|
||||
private String name;
|
||||
|
||||
/** 编码 */
|
||||
@ApiModelProperty(value = "编码", position = 5)
|
||||
private String code;
|
||||
|
||||
/** 分类 */
|
||||
@ApiModelProperty(value = "分类", position = 6)
|
||||
private String category;
|
||||
|
||||
/** 排序码 */
|
||||
@ApiModelProperty(value = "排序码", position = 7)
|
||||
private Integer sortCode;
|
||||
|
||||
/** 扩展信息 */
|
||||
@ApiModelProperty(value = "扩展信息", position = 8)
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
private String extJson;
|
||||
}
|
@@ -0,0 +1,37 @@
|
||||
|
||||
package mjkf.xinke.biz.modular.position.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
import mjkf.xinke.common.exception.CommonException;
|
||||
|
||||
/**
|
||||
* 岗位分类枚举
|
||||
*
|
||||
*
|
||||
* @date 2022/4/21 19:56
|
||||
**/
|
||||
@Getter
|
||||
public enum BizPositionCategoryEnum {
|
||||
|
||||
/** 高层 */
|
||||
HIGH("HIGH"),
|
||||
|
||||
/** 中层 */
|
||||
MIDDLE("MIDDLE"),
|
||||
|
||||
/** 基层 */
|
||||
LOW("LOW");
|
||||
|
||||
private final String value;
|
||||
|
||||
BizPositionCategoryEnum(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public static void validate(String value) {
|
||||
boolean flag = HIGH.getValue().equals(value) || MIDDLE.getValue().equals(value) || LOW.getValue().equals(value);
|
||||
if(!flag) {
|
||||
throw new CommonException("不支持的岗位分类:{}", value);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,14 @@
|
||||
|
||||
package mjkf.xinke.biz.modular.position.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import mjkf.xinke.biz.modular.position.entity.BizPosition;
|
||||
|
||||
/**
|
||||
* 岗位Mapper接口
|
||||
*
|
||||
*
|
||||
* @date 2022/4/21 18:37
|
||||
**/
|
||||
public interface BizPositionMapper extends BaseMapper<BizPosition> {
|
||||
}
|
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="mjkf.xinke.biz.modular.position.mapper.BizPositionMapper">
|
||||
|
||||
|
||||
</mapper>
|
@@ -0,0 +1,44 @@
|
||||
|
||||
package mjkf.xinke.biz.modular.position.param;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 岗位添加参数
|
||||
*
|
||||
*
|
||||
* @date 2022/4/21 16:13
|
||||
**/
|
||||
@Getter
|
||||
@Setter
|
||||
public class BizPositionAddParam {
|
||||
|
||||
/** 机构id */
|
||||
@ApiModelProperty(value = "机构id", required = true, position = 1)
|
||||
@NotBlank(message = "orgId不能为空")
|
||||
private String orgId;
|
||||
|
||||
/** 名称 */
|
||||
@ApiModelProperty(value = "名称", required = true, position = 2)
|
||||
@NotBlank(message = "name不能为空")
|
||||
private String name;
|
||||
|
||||
/** 分类 */
|
||||
@ApiModelProperty(value = "分类", required = true, position = 3)
|
||||
@NotBlank(message = "category不能为空")
|
||||
private String category;
|
||||
|
||||
/** 排序码 */
|
||||
@ApiModelProperty(value = "排序码", required = true, position = 4)
|
||||
@NotNull(message = "sortCode不能为空")
|
||||
private Integer sortCode;
|
||||
|
||||
/** 扩展JSON */
|
||||
@ApiModelProperty(value = "扩展JSON", position = 5)
|
||||
private String extJson;
|
||||
}
|
@@ -0,0 +1,49 @@
|
||||
|
||||
package mjkf.xinke.biz.modular.position.param;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 岗位编辑参数
|
||||
*
|
||||
*
|
||||
* @date 2022/4/21 16:13
|
||||
**/
|
||||
@Getter
|
||||
@Setter
|
||||
public class BizPositionEditParam {
|
||||
|
||||
/** id */
|
||||
@ApiModelProperty(value = "id", required = true, position = 1)
|
||||
@NotBlank(message = "id不能为空")
|
||||
private String id;
|
||||
|
||||
/** 机构id */
|
||||
@ApiModelProperty(value = "机构id", required = true, position = 2)
|
||||
@NotBlank(message = "orgId不能为空")
|
||||
private String orgId;
|
||||
|
||||
/** 名称 */
|
||||
@ApiModelProperty(value = "名称", required = true, position = 3)
|
||||
@NotBlank(message = "name不能为空")
|
||||
private String name;
|
||||
|
||||
/** 分类 */
|
||||
@ApiModelProperty(value = "分类", required = true, position = 4)
|
||||
@NotBlank(message = "category不能为空")
|
||||
private String category;
|
||||
|
||||
/** 排序码 */
|
||||
@ApiModelProperty(value = "排序码", required = true, position = 5)
|
||||
@NotNull(message = "sortCode不能为空")
|
||||
private Integer sortCode;
|
||||
|
||||
/** 扩展JSON */
|
||||
@ApiModelProperty(value = "扩展JSON", position = 6)
|
||||
private String extJson;
|
||||
}
|
@@ -0,0 +1,24 @@
|
||||
|
||||
package mjkf.xinke.biz.modular.position.param;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
/**
|
||||
* 岗位Id参数
|
||||
*
|
||||
*
|
||||
* @date 2022/4/21 16:13
|
||||
**/
|
||||
@Getter
|
||||
@Setter
|
||||
public class BizPositionIdParam {
|
||||
|
||||
/** id */
|
||||
@ApiModelProperty(value = "id", required = true)
|
||||
@NotBlank(message = "id不能为空")
|
||||
private String id;
|
||||
}
|
@@ -0,0 +1,45 @@
|
||||
|
||||
package mjkf.xinke.biz.modular.position.param;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* 岗位查询参数
|
||||
*
|
||||
*
|
||||
* @date 2022/4/21 16:13
|
||||
**/
|
||||
@Getter
|
||||
@Setter
|
||||
public class BizPositionPageParam {
|
||||
|
||||
/** 当前页 */
|
||||
@ApiModelProperty(value = "当前页码")
|
||||
private Integer current;
|
||||
|
||||
/** 每页条数 */
|
||||
@ApiModelProperty(value = "每页条数")
|
||||
private Integer size;
|
||||
|
||||
/** 排序字段 */
|
||||
@ApiModelProperty(value = "排序字段,字段驼峰名称,如:userName")
|
||||
private String sortField;
|
||||
|
||||
/** 排序方式 */
|
||||
@ApiModelProperty(value = "排序方式,升序:ASCEND;降序:DESCEND")
|
||||
private String sortOrder;
|
||||
|
||||
/** 机构id */
|
||||
@ApiModelProperty(value = "机构id")
|
||||
private String orgId;
|
||||
|
||||
/** 岗位分类 */
|
||||
@ApiModelProperty(value = "岗位分类")
|
||||
private String category;
|
||||
|
||||
/** 名称关键词 */
|
||||
@ApiModelProperty(value = "名称关键词")
|
||||
private String searchKey;
|
||||
}
|
@@ -0,0 +1,33 @@
|
||||
|
||||
package mjkf.xinke.biz.modular.position.param;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* 岗位选择器参数
|
||||
*
|
||||
*
|
||||
* @date 2022/4/21 16:13
|
||||
**/
|
||||
@Getter
|
||||
@Setter
|
||||
public class BizPositionSelectorPositionParam {
|
||||
|
||||
/** 当前页 */
|
||||
@ApiModelProperty(value = "当前页码")
|
||||
private Integer current;
|
||||
|
||||
/** 每页条数 */
|
||||
@ApiModelProperty(value = "每页条数")
|
||||
private Integer size;
|
||||
|
||||
/** 机构id */
|
||||
@ApiModelProperty(value = "机构id")
|
||||
private String orgId;
|
||||
|
||||
/** 名称关键词 */
|
||||
@ApiModelProperty(value = "名称关键词")
|
||||
private String searchKey;
|
||||
}
|
@@ -0,0 +1,102 @@
|
||||
|
||||
package mjkf.xinke.biz.modular.position.service;
|
||||
|
||||
import cn.hutool.core.lang.tree.Tree;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import mjkf.xinke.biz.modular.position.entity.BizPosition;
|
||||
import mjkf.xinke.biz.modular.position.param.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 岗位Service接口
|
||||
*
|
||||
*
|
||||
* @date 2022/4/21 18:35
|
||||
**/
|
||||
public interface BizPositionService extends IService<BizPosition> {
|
||||
|
||||
/**
|
||||
* 获取岗位分页
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 20:08
|
||||
*/
|
||||
Page<BizPosition> page(BizPositionPageParam bizPositionPageParam);
|
||||
|
||||
/**
|
||||
* 添加岗位
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 20:48
|
||||
*/
|
||||
void add(BizPositionAddParam bizPositionAddParam);
|
||||
|
||||
/**
|
||||
* 编辑岗位
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 21:13
|
||||
*/
|
||||
void edit(BizPositionEditParam bizPositionEditParam);
|
||||
|
||||
/**
|
||||
* 删除岗位
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 21:18
|
||||
*/
|
||||
void delete(List<BizPositionIdParam> bizPositionIdParamList);
|
||||
|
||||
/**
|
||||
* 获取岗位详情
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 21:18
|
||||
*/
|
||||
BizPosition detail(BizPositionIdParam bizPositionIdParam);
|
||||
|
||||
/**
|
||||
* 获取岗位详情
|
||||
*
|
||||
*
|
||||
* @date 2022/7/25 19:42
|
||||
**/
|
||||
BizPosition queryEntity(String id);
|
||||
|
||||
/**
|
||||
* 根据机构id和岗位名称获取岗位id,有则返回,无则创建
|
||||
*
|
||||
*
|
||||
* @date 2022/8/15 14:55
|
||||
**/
|
||||
String getPositionIdByPositionNameWithCreate(String orgId, String positionName);
|
||||
|
||||
/* ====岗位部分所需要用到的选择器==== */
|
||||
|
||||
/**
|
||||
* 获取机构树选择器
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 20:08
|
||||
*/
|
||||
List<Tree<String>> orgTreeSelector();
|
||||
|
||||
/**
|
||||
* 获取岗位选择器
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 20:08
|
||||
*/
|
||||
Page<BizPosition> positionSelector(BizPositionSelectorPositionParam bizPositionSelectorPositionParam);
|
||||
|
||||
/**
|
||||
* 获取动态字段配置
|
||||
*
|
||||
*
|
||||
* @date 2022/8/5 3:23
|
||||
*/
|
||||
List<JSONObject> dynamicFieldConfigList();
|
||||
}
|
@@ -0,0 +1,266 @@
|
||||
|
||||
package mjkf.xinke.biz.modular.position.service.impl;
|
||||
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.hutool.core.annotation.AnnotationUtil;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.collection.CollStreamUtil;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.lang.tree.Tree;
|
||||
import cn.hutool.core.lang.tree.TreeNode;
|
||||
import cn.hutool.core.lang.tree.TreeUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import mjkf.xinke.auth.core.util.StpLoginUserUtil;
|
||||
import mjkf.xinke.biz.core.enums.BizDataTypeEnum;
|
||||
import mjkf.xinke.biz.modular.org.entity.BizOrg;
|
||||
import mjkf.xinke.biz.modular.org.service.BizOrgService;
|
||||
import mjkf.xinke.biz.modular.position.entity.BizPosition;
|
||||
import mjkf.xinke.biz.modular.position.enums.BizPositionCategoryEnum;
|
||||
import mjkf.xinke.biz.modular.position.mapper.BizPositionMapper;
|
||||
import mjkf.xinke.biz.modular.position.param.*;
|
||||
import mjkf.xinke.biz.modular.position.service.BizPositionService;
|
||||
import mjkf.xinke.biz.modular.user.entity.BizUser;
|
||||
import mjkf.xinke.biz.modular.user.service.BizUserService;
|
||||
import mjkf.xinke.common.enums.CommonSortOrderEnum;
|
||||
import mjkf.xinke.common.exception.CommonException;
|
||||
import mjkf.xinke.common.listener.CommonDataChangeEventCenter;
|
||||
import mjkf.xinke.common.page.CommonPageRequest;
|
||||
import mjkf.xinke.dbs.api.DbsApi;
|
||||
import mjkf.xinke.dev.api.DevDfcApi;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 岗位Service接口实现类
|
||||
*
|
||||
*
|
||||
* @date 2022/2/23 18:43
|
||||
**/
|
||||
@Service
|
||||
public class BizPositionServiceImpl extends ServiceImpl<BizPositionMapper, BizPosition> implements BizPositionService {
|
||||
|
||||
@Resource
|
||||
private BizOrgService bizOrgService;
|
||||
|
||||
@Resource
|
||||
private BizUserService bizUserService;
|
||||
|
||||
@Resource
|
||||
private DbsApi dbsApi;
|
||||
|
||||
@Resource
|
||||
private DevDfcApi devDfcApi;
|
||||
|
||||
@Override
|
||||
public Page<BizPosition> page(BizPositionPageParam bizPositionPageParam) {
|
||||
QueryWrapper<BizPosition> queryWrapper = new QueryWrapper<>();
|
||||
// 查询部分字段
|
||||
queryWrapper.lambda().select(BizPosition::getId, BizPosition::getOrgId, BizPosition::getName,
|
||||
BizPosition::getCategory, BizPosition::getSortCode, BizPosition::getExtJson);
|
||||
if(ObjectUtil.isNotEmpty(bizPositionPageParam.getOrgId())) {
|
||||
queryWrapper.lambda().eq(BizPosition::getOrgId, bizPositionPageParam.getOrgId());
|
||||
}
|
||||
if(ObjectUtil.isNotEmpty(bizPositionPageParam.getCategory())) {
|
||||
queryWrapper.lambda().eq(BizPosition::getCategory, bizPositionPageParam.getCategory());
|
||||
}
|
||||
if(ObjectUtil.isAllNotEmpty(bizPositionPageParam.getSortField(), bizPositionPageParam.getSortOrder())) {
|
||||
CommonSortOrderEnum.validate(bizPositionPageParam.getSortOrder());
|
||||
queryWrapper.orderBy(true, bizPositionPageParam.getSortOrder().equals(CommonSortOrderEnum.ASC.getValue()),
|
||||
StrUtil.toUnderlineCase(bizPositionPageParam.getSortField()));
|
||||
} else {
|
||||
queryWrapper.lambda().orderByAsc(BizPosition::getSortCode);
|
||||
}
|
||||
// 校验数据范围
|
||||
List<String> loginUserDataScope = StpLoginUserUtil.getLoginUserDataScope();
|
||||
if(ObjectUtil.isNotEmpty(loginUserDataScope)) {
|
||||
queryWrapper.lambda().in(BizPosition::getOrgId, loginUserDataScope);
|
||||
} else {
|
||||
return new Page<>();
|
||||
}
|
||||
return this.page(CommonPageRequest.defaultPage(), queryWrapper);
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public void add(BizPositionAddParam bizPositionAddParam) {
|
||||
BizPositionCategoryEnum.validate(bizPositionAddParam.getCategory());
|
||||
// 校验数据范围
|
||||
List<String> loginUserDataScope = StpLoginUserUtil.getLoginUserDataScope();
|
||||
if(ObjectUtil.isNotEmpty(loginUserDataScope)) {
|
||||
if(!loginUserDataScope.contains(bizPositionAddParam.getOrgId())) {
|
||||
throw new CommonException("您没有权限在该机构下增加岗位,机构id:{}", bizPositionAddParam.getOrgId());
|
||||
}
|
||||
} else {
|
||||
throw new CommonException("您没有权限在该机构下增加岗位,机构id:{}", bizPositionAddParam.getOrgId());
|
||||
}
|
||||
BizPosition bizPosition = BeanUtil.toBean(bizPositionAddParam, BizPosition.class);
|
||||
boolean repeatName = this.count(new LambdaQueryWrapper<BizPosition>().eq(BizPosition::getOrgId, bizPosition.getOrgId())
|
||||
.eq(BizPosition::getName, bizPosition.getName())) > 0;
|
||||
if(repeatName) {
|
||||
throw new CommonException("同机构下存在重复的岗位,名称为:{}", bizPosition.getName());
|
||||
}
|
||||
bizPosition.setCode(RandomUtil.randomString(10));
|
||||
this.save(bizPosition);
|
||||
|
||||
// 发布增加事件
|
||||
CommonDataChangeEventCenter.doAddWithData(BizDataTypeEnum.POSITION.getValue(), JSONUtil.createArray().put(bizPosition));
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public void edit(BizPositionEditParam bizPositionEditParam) {
|
||||
BizPositionCategoryEnum.validate(bizPositionEditParam.getCategory());
|
||||
BizPosition bizPosition = this.queryEntity(bizPositionEditParam.getId());
|
||||
// 校验数据范围
|
||||
List<String> loginUserDataScope = StpLoginUserUtil.getLoginUserDataScope();
|
||||
if(ObjectUtil.isNotEmpty(loginUserDataScope)) {
|
||||
if(!loginUserDataScope.contains(bizPositionEditParam.getOrgId())) {
|
||||
throw new CommonException("您没有权限编辑该机构下的岗位,机构id:{}", bizPositionEditParam.getOrgId());
|
||||
}
|
||||
} else {
|
||||
if(!bizPositionEditParam.getId().equals(StpUtil.getLoginIdAsString())) {
|
||||
throw new CommonException("您没有权限编辑该机构下的岗位,机构id:{}", bizPositionEditParam.getOrgId());
|
||||
}
|
||||
}
|
||||
BeanUtil.copyProperties(bizPositionEditParam, bizPosition);
|
||||
boolean repeatName = this.count(new LambdaQueryWrapper<BizPosition>().eq(BizPosition::getOrgId, bizPosition.getOrgId())
|
||||
.eq(BizPosition::getName, bizPosition.getName()).ne(BizPosition::getId, bizPosition.getId())) > 0;
|
||||
if(repeatName) {
|
||||
throw new CommonException("同机构下存在重复的岗位,名称为:{}", bizPosition.getName());
|
||||
}
|
||||
this.updateById(bizPosition);
|
||||
|
||||
// 发布更新事件
|
||||
CommonDataChangeEventCenter.doUpdateWithData(BizDataTypeEnum.POSITION.getValue(), JSONUtil.createArray().put(bizPosition));
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public void delete(List<BizPositionIdParam> bizPositionIdParamList) {
|
||||
List<String> positionIdList = CollStreamUtil.toList(bizPositionIdParamList, BizPositionIdParam::getId);
|
||||
if(ObjectUtil.isNotEmpty(positionIdList)) {
|
||||
// 获取这些岗位的的机构id集合
|
||||
Set<String> positionOrgIdList = this.listByIds(positionIdList).stream().map(BizPosition::getOrgId).collect(Collectors.toSet());
|
||||
// 校验数据范围
|
||||
List<String> loginUserDataScope = StpLoginUserUtil.getLoginUserDataScope();
|
||||
if(ObjectUtil.isNotEmpty(loginUserDataScope)) {
|
||||
if(!loginUserDataScope.containsAll(positionOrgIdList)) {
|
||||
throw new CommonException("您没有权限删除这些机构下的岗位,机构id:{}", positionOrgIdList);
|
||||
}
|
||||
} else {
|
||||
throw new CommonException("您没有权限删除这些机构下的岗位,机构id:{}", positionOrgIdList);
|
||||
}
|
||||
// 岗位下有人不能删除(直属岗位)
|
||||
boolean hasOrgUser = bizUserService.count(new LambdaQueryWrapper<BizUser>().in(BizUser::getPositionId, positionIdList)) > 0;
|
||||
if(hasOrgUser) {
|
||||
throw new CommonException("请先删除岗位下的用户");
|
||||
}
|
||||
// 岗位下有人不能删除(兼任岗位)
|
||||
List<String> positionJsonList = bizUserService.list(new LambdaQueryWrapper<BizUser>()
|
||||
.isNotNull(BizUser::getPositionJson)).stream().map(BizUser::getPositionJson).collect(Collectors.toList());
|
||||
if(ObjectUtil.isNotEmpty(positionJsonList)) {
|
||||
List<String> extPositionIdList = CollectionUtil.newArrayList();
|
||||
positionJsonList.forEach(positionJson -> JSONUtil.toList(JSONUtil.parseArray(positionJson), JSONObject.class)
|
||||
.forEach(jsonObject -> extPositionIdList.add(jsonObject.getStr("positionId"))));
|
||||
boolean hasPositionUser = CollectionUtil.intersectionDistinct(positionIdList, CollectionUtil.removeNull(extPositionIdList)).size() > 0;
|
||||
if(hasPositionUser) {
|
||||
throw new CommonException("请先删除岗位下的用户");
|
||||
}
|
||||
}
|
||||
// 执行删除
|
||||
this.removeByIds(positionIdList);
|
||||
|
||||
// 发布删除事件
|
||||
CommonDataChangeEventCenter.doDeleteWithDataId(BizDataTypeEnum.POSITION.getValue(), positionIdList);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BizPosition detail(BizPositionIdParam bizPositionIdParam) {
|
||||
return this.queryEntity(bizPositionIdParam.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public BizPosition queryEntity(String id) {
|
||||
BizPosition bizPosition = this.getById(id);
|
||||
if(ObjectUtil.isEmpty(bizPosition)) {
|
||||
throw new CommonException("岗位不存在,id值为:{}", id);
|
||||
}
|
||||
return bizPosition;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPositionIdByPositionNameWithCreate(String orgId, String positionName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/* ====岗位部分所需要用到的选择器==== */
|
||||
|
||||
@Override
|
||||
public List<Tree<String>> orgTreeSelector() {
|
||||
LambdaQueryWrapper<BizOrg> lambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||
// 校验数据范围
|
||||
List<String> loginUserDataScope = StpLoginUserUtil.getLoginUserDataScope();
|
||||
// 定义机构集合
|
||||
Set<BizOrg> bizOrgSet = CollectionUtil.newHashSet();
|
||||
if(ObjectUtil.isNotEmpty(loginUserDataScope)) {
|
||||
// 获取所有机构
|
||||
List<BizOrg> allOrgList = bizOrgService.list();
|
||||
loginUserDataScope.forEach(orgId -> bizOrgSet.addAll(bizOrgService.getParentListById(allOrgList, orgId, true)));
|
||||
List<String> loginUserDataScopeFullList = bizOrgSet.stream().map(BizOrg::getId).collect(Collectors.toList());
|
||||
lambdaQueryWrapper.in(BizOrg::getId, loginUserDataScopeFullList);
|
||||
} else {
|
||||
return CollectionUtil.newArrayList();
|
||||
}
|
||||
lambdaQueryWrapper.orderByAsc(BizOrg::getSortCode);
|
||||
List<BizOrg> bizOrgList = bizOrgService.list(lambdaQueryWrapper);
|
||||
List<TreeNode<String>> treeNodeList = bizOrgList.stream().map(bizOrg ->
|
||||
new TreeNode<>(bizOrg.getId(), bizOrg.getParentId(), bizOrg.getName(), bizOrg.getSortCode()))
|
||||
.collect(Collectors.toList());
|
||||
return TreeUtil.build(treeNodeList, "0");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<BizPosition> positionSelector(BizPositionSelectorPositionParam bizPositionSelectorPositionParam) {
|
||||
LambdaQueryWrapper<BizPosition> lambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||
// 校验数据范围
|
||||
List<String> loginUserDataScope = StpLoginUserUtil.getLoginUserDataScope();
|
||||
if(ObjectUtil.isNotEmpty(loginUserDataScope)) {
|
||||
lambdaQueryWrapper.in(BizPosition::getOrgId, loginUserDataScope);
|
||||
} else {
|
||||
return new Page<>();
|
||||
}
|
||||
// 查询部分字段
|
||||
lambdaQueryWrapper.select(BizPosition::getId, BizPosition::getOrgId, BizPosition::getName,
|
||||
BizPosition::getCategory, BizPosition::getSortCode);
|
||||
if(ObjectUtil.isNotEmpty(bizPositionSelectorPositionParam.getOrgId())) {
|
||||
lambdaQueryWrapper.eq(BizPosition::getOrgId, bizPositionSelectorPositionParam.getOrgId());
|
||||
}
|
||||
if(ObjectUtil.isNotEmpty(bizPositionSelectorPositionParam.getSearchKey())) {
|
||||
lambdaQueryWrapper.like(BizPosition::getName, bizPositionSelectorPositionParam.getSearchKey());
|
||||
}
|
||||
lambdaQueryWrapper.orderByAsc(BizPosition::getSortCode);
|
||||
return this.page(CommonPageRequest.defaultPage(), lambdaQueryWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<JSONObject> dynamicFieldConfigList() {
|
||||
String currentDataSourceId = dbsApi.getCurrentDataSourceId();
|
||||
String tableName = AnnotationUtil.getAnnotationValue(BizPosition.class, TableName.class);
|
||||
return devDfcApi.getTableFieldList(currentDataSourceId, tableName);
|
||||
}
|
||||
}
|
@@ -0,0 +1,320 @@
|
||||
|
||||
package mjkf.xinke.biz.modular.user.controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.hutool.core.lang.tree.Tree;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
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.RestController;
|
||||
import mjkf.xinke.biz.modular.org.entity.BizOrg;
|
||||
import mjkf.xinke.biz.modular.position.entity.BizPosition;
|
||||
import mjkf.xinke.biz.modular.user.entity.BizUser;
|
||||
import mjkf.xinke.biz.modular.user.param.*;
|
||||
import mjkf.xinke.biz.modular.user.result.BizUserRoleResult;
|
||||
import mjkf.xinke.biz.modular.user.service.BizUserService;
|
||||
import mjkf.xinke.common.annotation.CommonLog;
|
||||
import mjkf.xinke.common.pojo.CommonResult;
|
||||
import mjkf.xinke.common.pojo.CommonValidList;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 人员控制器
|
||||
*
|
||||
*
|
||||
* @date 2022/4/22 9:34
|
||||
**/
|
||||
@Api(tags = "人员控制器")
|
||||
@ApiSupport(author = "SNOWY_TEAM", order = 9)
|
||||
@RestController
|
||||
@Validated
|
||||
public class BizUserController {
|
||||
|
||||
@Resource
|
||||
private BizUserService bizUserService;
|
||||
|
||||
/**
|
||||
* 获取人员分页
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 20:00
|
||||
*/
|
||||
@ApiOperationSupport(order = 1)
|
||||
@ApiOperation("获取人员分页")
|
||||
@SaCheckPermission("/biz/user/page")
|
||||
@GetMapping("/biz/user/page")
|
||||
public CommonResult<Page<BizUser>> page(BizUserPageParam bizUserPageParam) {
|
||||
return CommonResult.data(bizUserService.page(bizUserPageParam));
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加人员
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 20:47
|
||||
*/
|
||||
@ApiOperationSupport(order = 2)
|
||||
@ApiOperation("添加人员")
|
||||
@CommonLog("添加人员")
|
||||
@SaCheckPermission("/biz/user/add")
|
||||
@PostMapping("/biz/user/add")
|
||||
public CommonResult<String> add(@RequestBody @Valid BizUserAddParam bizUserAddParam) {
|
||||
bizUserService.add(bizUserAddParam);
|
||||
return CommonResult.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑人员
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 20:47
|
||||
*/
|
||||
@ApiOperationSupport(order = 3)
|
||||
@ApiOperation("编辑人员")
|
||||
@CommonLog("编辑人员")
|
||||
@SaCheckPermission("/biz/user/edit")
|
||||
@PostMapping("/biz/user/edit")
|
||||
public CommonResult<String> edit(@RequestBody @Valid BizUserEditParam bizUserEditParam) {
|
||||
bizUserService.edit(bizUserEditParam);
|
||||
return CommonResult.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除人员
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 20:00
|
||||
*/
|
||||
@ApiOperationSupport(order = 4)
|
||||
@ApiOperation("删除人员")
|
||||
@CommonLog("删除人员")
|
||||
@SaCheckPermission("/biz/user/delete")
|
||||
@PostMapping("/biz/user/delete")
|
||||
public CommonResult<String> delete(@RequestBody @Valid @NotEmpty(message = "集合不能为空")
|
||||
CommonValidList<BizUserIdParam> bizUserIdParamList) {
|
||||
bizUserService.delete(bizUserIdParamList);
|
||||
return CommonResult.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取人员详情
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 20:00
|
||||
*/
|
||||
@ApiOperationSupport(order = 5)
|
||||
@ApiOperation("获取人员详情")
|
||||
@SaCheckPermission("/biz/user/detail")
|
||||
@GetMapping("/biz/user/detail")
|
||||
public CommonResult<BizUser> detail(@Valid BizUserIdParam bizUserIdParam) {
|
||||
return CommonResult.data(bizUserService.detail(bizUserIdParam));
|
||||
}
|
||||
|
||||
/**
|
||||
* 禁用人员
|
||||
*
|
||||
*
|
||||
* @date 2021/10/13 14:01
|
||||
**/
|
||||
@ApiOperationSupport(order = 6)
|
||||
@ApiOperation("禁用人员")
|
||||
@CommonLog("禁用人员")
|
||||
@SaCheckPermission("/biz/user/disableUser")
|
||||
@PostMapping("/biz/user/disableUser")
|
||||
public CommonResult<String> disableUser(@RequestBody BizUserIdParam bizUserIdParam) {
|
||||
bizUserService.disableUser(bizUserIdParam);
|
||||
return CommonResult.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 启用人员
|
||||
*
|
||||
*
|
||||
* @date 2021/10/13 14:01
|
||||
**/
|
||||
@ApiOperationSupport(order = 7)
|
||||
@ApiOperation("启用人员")
|
||||
@CommonLog("启用人员")
|
||||
@SaCheckPermission("/biz/user/enableUser")
|
||||
@PostMapping("/biz/user/enableUser")
|
||||
public CommonResult<String> enableUser(@RequestBody @Valid BizUserIdParam bizUserIdParam) {
|
||||
bizUserService.enableUser(bizUserIdParam);
|
||||
return CommonResult.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置人员密码
|
||||
*
|
||||
*
|
||||
* @date 2021/10/13 14:01
|
||||
**/
|
||||
@ApiOperationSupport(order = 8)
|
||||
@ApiOperation("重置人员密码")
|
||||
@CommonLog("重置人员密码")
|
||||
@SaCheckPermission("/biz/user/resetPassword")
|
||||
@PostMapping("/biz/user/resetPassword")
|
||||
public CommonResult<String> resetPassword(@RequestBody @Valid BizUserIdParam bizUserIdParam) {
|
||||
bizUserService.resetPassword(bizUserIdParam);
|
||||
return CommonResult.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 人员拥有角色
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 20:00
|
||||
*/
|
||||
@ApiOperationSupport(order = 9)
|
||||
@ApiOperation("获取人员拥有角色")
|
||||
@SaCheckPermission("/biz/user/ownRole")
|
||||
@GetMapping("/biz/user/ownRole")
|
||||
public CommonResult<List<String>> ownRole(@Valid BizUserIdParam bizUserIdParam) {
|
||||
return CommonResult.data(bizUserService.ownRole(bizUserIdParam));
|
||||
}
|
||||
|
||||
/**
|
||||
* 给人员授权角色
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 20:00
|
||||
*/
|
||||
@ApiOperationSupport(order = 10)
|
||||
@ApiOperation("给人员授权角色")
|
||||
@CommonLog("给人员授权角色")
|
||||
@SaCheckPermission("/biz/user/grantRole")
|
||||
@PostMapping("/biz/user/grantRole")
|
||||
public CommonResult<String> grantRole(@RequestBody @Valid BizUserGrantRoleParam bizUserGrantRoleParam) {
|
||||
bizUserService.grantRole(bizUserGrantRoleParam);
|
||||
return CommonResult.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 人员导出
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 20:00
|
||||
*/
|
||||
@ApiOperationSupport(order = 11)
|
||||
@ApiOperation("人员导出")
|
||||
@CommonLog("人员导出")
|
||||
@SaCheckPermission("/biz/user/export")
|
||||
@GetMapping(value = "/biz/user/export", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
|
||||
public void exportUser(BizUserExportParam bizUserExportParam, HttpServletResponse response) throws IOException {
|
||||
bizUserService.exportUser(bizUserExportParam, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 按模板导出人员个人信息
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 20:00
|
||||
*/
|
||||
@ApiOperationSupport(order = 12)
|
||||
@ApiOperation("导出人员个人信息")
|
||||
@CommonLog("导出人员个人信息")
|
||||
@SaCheckPermission("/biz/user/exportUserInfo")
|
||||
@GetMapping(value = "/biz/user/exportUserInfo", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
|
||||
public void exportUserInfo(BizUserIdParam bizUserIdParam, HttpServletResponse response) throws IOException {
|
||||
bizUserService.exportUserInfo(bizUserIdParam, response);
|
||||
}
|
||||
|
||||
/* ====人员部分所需要用到的选择器==== */
|
||||
|
||||
/**
|
||||
* 获取机构树选择器
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 20:00
|
||||
*/
|
||||
@ApiOperationSupport(order = 13)
|
||||
@ApiOperation("获取机构树选择器")
|
||||
@SaCheckPermission("/biz/user/orgTreeSelector")
|
||||
@GetMapping("/biz/user/orgTreeSelector")
|
||||
public CommonResult<List<Tree<String>>> orgTreeSelector() {
|
||||
return CommonResult.data(bizUserService.orgTreeSelector());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取机构列表选择器
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 20:00
|
||||
*/
|
||||
@ApiOperationSupport(order = 14)
|
||||
@ApiOperation("获取机构列表选择器")
|
||||
@SaCheckPermission("/biz/user/orgListSelector")
|
||||
@GetMapping("/biz/user/orgListSelector")
|
||||
public CommonResult<Page<BizOrg>> orgListSelector(BizUserSelectorOrgListParam bizUserSelectorOrgListParam) {
|
||||
return CommonResult.data(bizUserService.orgListSelector(bizUserSelectorOrgListParam));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取岗位选择器
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 20:00
|
||||
*/
|
||||
@ApiOperationSupport(order = 15)
|
||||
@ApiOperation("获取岗位选择器")
|
||||
@SaCheckPermission("/biz/user/positionSelector")
|
||||
@GetMapping("/biz/user/positionSelector")
|
||||
public CommonResult<Page<BizPosition>> positionSelector(BizUserSelectorPositionParam bizUserSelectorPositionParam) {
|
||||
return CommonResult.data(bizUserService.positionSelector(bizUserSelectorPositionParam));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取角色选择器
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 20:00
|
||||
*/
|
||||
@ApiOperationSupport(order = 16)
|
||||
@ApiOperation("获取角色选择器")
|
||||
@SaCheckPermission("/biz/user/roleSelector")
|
||||
@GetMapping("/biz/user/roleSelector")
|
||||
public CommonResult<Page<BizUserRoleResult>> roleSelector(BizUserSelectorRoleParam bizUserSelectorRoleParam) {
|
||||
return CommonResult.data(bizUserService.roleSelector(bizUserSelectorRoleParam));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取人员选择器
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 20:00
|
||||
*/
|
||||
@ApiOperationSupport(order = 17)
|
||||
@ApiOperation("获取人员选择器")
|
||||
@SaCheckPermission("/biz/user/userSelector")
|
||||
@GetMapping("/biz/user/userSelector")
|
||||
public CommonResult<Page<BizUser>> userSelector(BizUserSelectorUserParam bizUserSelectorUserParam) {
|
||||
return CommonResult.data(bizUserService.userSelector(bizUserSelectorUserParam));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取人员动态字段的配置
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 20:00
|
||||
*/
|
||||
@ApiOperationSupport(order = 18)
|
||||
@ApiOperation("获取人员动态字段的配置")
|
||||
@SaCheckPermission("/biz/user/dynamicFieldConfigList")
|
||||
@GetMapping("/biz/user/dynamicFieldConfigList")
|
||||
public CommonResult<List<JSONObject>> dynamicFieldConfigList() {
|
||||
return CommonResult.data(bizUserService.dynamicFieldConfigList());
|
||||
}
|
||||
}
|
@@ -0,0 +1,271 @@
|
||||
|
||||
package mjkf.xinke.biz.modular.user.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.FieldStrategy;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.fhs.core.trans.anno.Trans;
|
||||
import com.fhs.core.trans.constant.TransType;
|
||||
import com.fhs.core.trans.vo.TransPojo;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import mjkf.xinke.biz.modular.org.entity.BizOrg;
|
||||
import mjkf.xinke.biz.modular.position.entity.BizPosition;
|
||||
import mjkf.xinke.common.handler.CommonSm4CbcTypeHandler;
|
||||
import mjkf.xinke.common.pojo.CommonEntity;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 人员实体
|
||||
*
|
||||
*
|
||||
* @date 2022/4/21 16:13
|
||||
**/
|
||||
@Getter
|
||||
@Setter
|
||||
@TableName(value = "SYS_USER", autoResultMap = true)
|
||||
public class BizUser extends CommonEntity implements TransPojo {
|
||||
|
||||
/** id */
|
||||
@TableId
|
||||
@ApiModelProperty(value = "id", position = 1)
|
||||
private String id;
|
||||
|
||||
/** 租户id */
|
||||
@ApiModelProperty(value = "租户id", position = 2)
|
||||
private String tenantId;
|
||||
|
||||
/** 头像 */
|
||||
@ApiModelProperty(value = "头像", position = 3)
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
private String avatar;
|
||||
|
||||
/** 签名 */
|
||||
@ApiModelProperty(value = "签名", position = 4)
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
private String signature;
|
||||
|
||||
/** 账号 */
|
||||
@ApiModelProperty(value = "账号", position = 5)
|
||||
private String account;
|
||||
|
||||
/** 密码 */
|
||||
@ApiModelProperty(value = "密码", position = 6)
|
||||
private String password;
|
||||
|
||||
/** 姓名 */
|
||||
@ApiModelProperty(value = "姓名", position = 7)
|
||||
private String name;
|
||||
|
||||
/** 昵称 */
|
||||
@ApiModelProperty(value = "昵称", position = 8)
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
private String nickname;
|
||||
|
||||
/** 性别 */
|
||||
@ApiModelProperty(value = "性别", position = 9)
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
@Trans(type = TransType.DICTIONARY, key = "GENDER")
|
||||
private String gender;
|
||||
|
||||
/** 年龄 */
|
||||
@ApiModelProperty(value = "年龄", position = 10)
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
private String age;
|
||||
|
||||
/** 出生日期 */
|
||||
@ApiModelProperty(value = "出生日期", position = 11)
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
private String birthday;
|
||||
|
||||
/** 民族 */
|
||||
@ApiModelProperty(value = "民族", position = 12)
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
private String nation;
|
||||
|
||||
/** 籍贯 */
|
||||
@ApiModelProperty(value = "籍贯", position = 13)
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
private String nativePlace;
|
||||
|
||||
/** 家庭住址 */
|
||||
@ApiModelProperty(value = "家庭住址", position = 14)
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
private String homeAddress;
|
||||
|
||||
/** 通信地址 */
|
||||
@ApiModelProperty(value = "通信地址", position = 15)
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
private String mailingAddress;
|
||||
|
||||
/** 证件类型 */
|
||||
@ApiModelProperty(value = "证件类型", position = 16)
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
private String idCardType;
|
||||
|
||||
/** 证件号码 */
|
||||
@ApiModelProperty(value = "证件号码", position = 17)
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED, typeHandler = CommonSm4CbcTypeHandler.class)
|
||||
private String idCardNumber;
|
||||
|
||||
/** 文化程度 */
|
||||
@ApiModelProperty(value = "文化程度", position = 18)
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
private String cultureLevel;
|
||||
|
||||
/** 政治面貌 */
|
||||
@ApiModelProperty(value = "政治面貌", position = 19)
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
private String politicalOutlook;
|
||||
|
||||
/** 毕业院校 */
|
||||
@ApiModelProperty(value = "毕业院校", position = 20)
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
private String college;
|
||||
|
||||
/** 学历 */
|
||||
@ApiModelProperty(value = "学历", position = 21)
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
private String education;
|
||||
|
||||
/** 学制 */
|
||||
@ApiModelProperty(value = "学制", position = 22)
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
private String eduLength;
|
||||
|
||||
/** 学位 */
|
||||
@ApiModelProperty(value = "学位", position = 23)
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
private String degree;
|
||||
|
||||
/** 手机 */
|
||||
@ApiModelProperty(value = "手机", position = 24)
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED, typeHandler = CommonSm4CbcTypeHandler.class)
|
||||
private String phone;
|
||||
|
||||
/** 邮箱 */
|
||||
@ApiModelProperty(value = "邮箱", position = 25)
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
private String email;
|
||||
|
||||
/** 家庭电话 */
|
||||
@ApiModelProperty(value = "家庭电话", position = 26)
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
private String homeTel;
|
||||
|
||||
/** 办公电话 */
|
||||
@ApiModelProperty(value = "办公电话", position = 27)
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
private String officeTel;
|
||||
|
||||
/** 紧急联系人 */
|
||||
@ApiModelProperty(value = "紧急联系人", position = 28)
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
private String emergencyContact;
|
||||
|
||||
/** 紧急联系人电话 */
|
||||
@ApiModelProperty(value = "紧急联系人电话", position = 29)
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED, typeHandler = CommonSm4CbcTypeHandler.class)
|
||||
private String emergencyPhone;
|
||||
|
||||
/** 紧急联系人地址 */
|
||||
@ApiModelProperty(value = "紧急联系人地址", position = 30)
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
private String emergencyAddress;
|
||||
|
||||
/** 员工编号 */
|
||||
@ApiModelProperty(value = "员工编号", position = 31)
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
private String empNo;
|
||||
|
||||
/** 入职日期 */
|
||||
@ApiModelProperty(value = "入职日期", position = 32)
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
private String entryDate;
|
||||
|
||||
/** 机构id */
|
||||
@ApiModelProperty(value = "机构id", position = 33)
|
||||
@Trans(type = TransType.SIMPLE, target = BizOrg.class, fields = "name", alias = "org", ref = "orgName")
|
||||
private String orgId;
|
||||
|
||||
/** 岗位id */
|
||||
@ApiModelProperty(value = "岗位id", position = 34)
|
||||
@Trans(type = TransType.SIMPLE, target = BizPosition.class, fields = "name", alias = "position", ref = "positionName")
|
||||
private String positionId;
|
||||
|
||||
/** 职级 */
|
||||
@ApiModelProperty(value = "职级", position = 35)
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
private String positionLevel;
|
||||
|
||||
/** 主管id */
|
||||
@ApiModelProperty(value = "主管id", position = 36)
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
@Trans(type = TransType.SIMPLE, target = BizUser.class, fields = "name", alias = "director", ref = "directorName")
|
||||
private String directorId;
|
||||
|
||||
/** 兼任信息 */
|
||||
@ApiModelProperty(value = "兼任信息", position = 37)
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
private String positionJson;
|
||||
|
||||
/** 上次登录ip */
|
||||
@ApiModelProperty(value = "上次登录ip", position = 38)
|
||||
private String lastLoginIp;
|
||||
|
||||
/** 上次登录地点 */
|
||||
@ApiModelProperty(value = "上次登录地点", position = 39)
|
||||
private String lastLoginAddress;
|
||||
|
||||
/** 上次登录时间 */
|
||||
@ApiModelProperty(value = "上次登录时间", position = 40)
|
||||
private Date lastLoginTime;
|
||||
|
||||
/** 上次登录设备 */
|
||||
@ApiModelProperty(value = "上次登录设备", position = 41)
|
||||
private String lastLoginDevice;
|
||||
|
||||
/** 最新登录ip */
|
||||
@ApiModelProperty(value = "最新登录ip", position = 42)
|
||||
private String latestLoginIp;
|
||||
|
||||
/** 最新登录地点 */
|
||||
@ApiModelProperty(value = "最新登录地点", position = 43)
|
||||
private String latestLoginAddress;
|
||||
|
||||
/** 最新登录时间 */
|
||||
@ApiModelProperty(value = "最新登录时间", position = 44)
|
||||
private Date latestLoginTime;
|
||||
|
||||
/** 最新登录设备 */
|
||||
@ApiModelProperty(value = "最新登录设备", position = 45)
|
||||
private String latestLoginDevice;
|
||||
|
||||
/** 用户状态 */
|
||||
@ApiModelProperty(value = "用户状态", position = 46)
|
||||
private String userStatus;
|
||||
|
||||
/** 排序码 */
|
||||
@ApiModelProperty(value = "排序码", position = 47)
|
||||
private Integer sortCode;
|
||||
|
||||
/** 扩展信息 */
|
||||
@ApiModelProperty(value = "扩展信息", position = 48)
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
private String extJson;
|
||||
|
||||
@ApiModelProperty(value = "机构名称", position = 49)
|
||||
@TableField(exist = false)
|
||||
private String orgName;
|
||||
|
||||
@ApiModelProperty(value = "岗位名称", position = 50)
|
||||
@TableField(exist = false)
|
||||
private String positionName;
|
||||
|
||||
@ApiModelProperty(value = "主管名称", position = 51)
|
||||
@TableField(exist = false)
|
||||
private String directorName;
|
||||
}
|
@@ -0,0 +1,34 @@
|
||||
|
||||
package mjkf.xinke.biz.modular.user.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
import mjkf.xinke.common.exception.CommonException;
|
||||
|
||||
/**
|
||||
* 角色分类枚举
|
||||
*
|
||||
*
|
||||
* @date 2022/4/21 19:56
|
||||
**/
|
||||
@Getter
|
||||
public enum BizRoleCategoryEnum {
|
||||
|
||||
/** 全局 */
|
||||
GLOBAL("GLOBAL"),
|
||||
|
||||
/** 组织 */
|
||||
ORG("ORG");
|
||||
|
||||
private final String value;
|
||||
|
||||
BizRoleCategoryEnum(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public static void validate(String value) {
|
||||
boolean flag = GLOBAL.getValue().equals(value) || ORG.getValue().equals(value);
|
||||
if(!flag) {
|
||||
throw new CommonException("不支持的角色分类:{}", value);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,38 @@
|
||||
|
||||
package mjkf.xinke.biz.modular.user.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
import mjkf.xinke.common.exception.CommonException;
|
||||
|
||||
/**
|
||||
* 人员状态枚举
|
||||
*
|
||||
*
|
||||
* @date 2022/4/27 21:47
|
||||
*/
|
||||
@Getter
|
||||
public enum BizUserStatusEnum {
|
||||
|
||||
/**
|
||||
* 正常
|
||||
*/
|
||||
ENABLE("ENABLE"),
|
||||
|
||||
/**
|
||||
* 停用
|
||||
*/
|
||||
DISABLED("DISABLED");
|
||||
|
||||
private final String value;
|
||||
|
||||
BizUserStatusEnum(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public static void validate(String value) {
|
||||
boolean flag = ENABLE.getValue().equals(value) || DISABLED.getValue().equals(value);
|
||||
if(!flag) {
|
||||
throw new CommonException("不支持的人员状态:{}", value);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,15 @@
|
||||
|
||||
package mjkf.xinke.biz.modular.user.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import mjkf.xinke.biz.modular.user.entity.BizUser;
|
||||
|
||||
/**
|
||||
* 人员Mapper接口
|
||||
*
|
||||
*
|
||||
* @date 2022/4/21 18:37
|
||||
**/
|
||||
public interface BizUserMapper extends BaseMapper<BizUser> {
|
||||
|
||||
}
|
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="mjkf.xinke.biz.modular.user.mapper.BizUserMapper">
|
||||
|
||||
</mapper>
|
@@ -0,0 +1,167 @@
|
||||
|
||||
package mjkf.xinke.biz.modular.user.param;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
/**
|
||||
* 人员添加参数
|
||||
*
|
||||
*
|
||||
* @date 2022/7/26 15:36
|
||||
**/
|
||||
@Getter
|
||||
@Setter
|
||||
public class BizUserAddParam {
|
||||
|
||||
/** 账号 */
|
||||
@ApiModelProperty(value = "账号", required = true, position = 1)
|
||||
@NotBlank(message = "account不能为空")
|
||||
private String account;
|
||||
|
||||
/** 姓名 */
|
||||
@ApiModelProperty(value = "姓名", required = true, position = 2)
|
||||
@NotBlank(message = "name不能为空")
|
||||
private String name;
|
||||
|
||||
/** 机构id */
|
||||
@ApiModelProperty(value = "机构id", required = true, position = 3)
|
||||
@NotBlank(message = "orgId不能为空")
|
||||
private String orgId;
|
||||
|
||||
/** 岗位id */
|
||||
@ApiModelProperty(value = "岗位id", required = true, position = 4)
|
||||
@NotBlank(message = "positionId不能为空")
|
||||
private String positionId;
|
||||
|
||||
/** 岗级 */
|
||||
@ApiModelProperty(value = "岗级", position = 5)
|
||||
private String positionLevel;
|
||||
|
||||
/** 主管id */
|
||||
@ApiModelProperty(value = "主管id", position = 6)
|
||||
private String directorId;
|
||||
|
||||
/** 头像 */
|
||||
@ApiModelProperty(value = "头像,图片base64", position = 7)
|
||||
private String avatar;
|
||||
|
||||
/** 签名 */
|
||||
@ApiModelProperty(value = "签名,图片base64", position = 8)
|
||||
private String signature;
|
||||
|
||||
/** 昵称 */
|
||||
@ApiModelProperty(value = "昵称", position = 9)
|
||||
private String nickname;
|
||||
|
||||
/** 性别 */
|
||||
@ApiModelProperty(value = "性别", position = 10)
|
||||
private String gender;
|
||||
|
||||
/** 年龄 */
|
||||
@ApiModelProperty(value = "年龄", position = 11)
|
||||
private String age;
|
||||
|
||||
/** 出生日期 */
|
||||
@ApiModelProperty(value = "出生日期", position = 12)
|
||||
private String birthday;
|
||||
|
||||
/** 民族 */
|
||||
@ApiModelProperty(value = "民族", position = 13)
|
||||
private String nation;
|
||||
|
||||
/** 籍贯 */
|
||||
@ApiModelProperty(value = "籍贯", position = 14)
|
||||
private String nativePlace;
|
||||
|
||||
/** 家庭住址 */
|
||||
@ApiModelProperty(value = "家庭住址", position = 15)
|
||||
private String homeAddress;
|
||||
|
||||
/** 通信地址 */
|
||||
@ApiModelProperty(value = "通信地址", position = 16)
|
||||
private String mailingAddress;
|
||||
|
||||
/** 证件类型 */
|
||||
@ApiModelProperty(value = "证件类型", position = 17)
|
||||
private String idCardType;
|
||||
|
||||
/** 证件号码 */
|
||||
@ApiModelProperty(value = "证件号码", position = 18)
|
||||
private String idCardNumber;
|
||||
|
||||
/** 文化程度 */
|
||||
@ApiModelProperty(value = "文化程度", position = 19)
|
||||
private String cultureLevel;
|
||||
|
||||
/** 政治面貌 */
|
||||
@ApiModelProperty(value = "政治面貌", position = 20)
|
||||
private String politicalOutlook;
|
||||
|
||||
/** 毕业院校 */
|
||||
@ApiModelProperty(value = "毕业院校", position = 21)
|
||||
private String college;
|
||||
|
||||
/** 学历 */
|
||||
@ApiModelProperty(value = "学历", position = 22)
|
||||
private String education;
|
||||
|
||||
/** 学制 */
|
||||
@ApiModelProperty(value = "学制", position = 23)
|
||||
private String eduLength;
|
||||
|
||||
/** 学位 */
|
||||
@ApiModelProperty(value = "学位", position = 24)
|
||||
private String degree;
|
||||
|
||||
/** 手机 */
|
||||
@ApiModelProperty(value = "手机", position = 25)
|
||||
private String phone;
|
||||
|
||||
/** 邮箱 */
|
||||
@ApiModelProperty(value = "邮箱", position = 26)
|
||||
private String email;
|
||||
|
||||
/** 家庭电话 */
|
||||
@ApiModelProperty(value = "家庭电话", position = 27)
|
||||
private String homeTel;
|
||||
|
||||
/** 办公电话 */
|
||||
@ApiModelProperty(value = "办公电话", position = 28)
|
||||
private String officeTel;
|
||||
|
||||
/** 紧急联系人 */
|
||||
@ApiModelProperty(value = "紧急联系人", position = 29)
|
||||
private String emergencyContact;
|
||||
|
||||
/** 紧急联系人电话 */
|
||||
@ApiModelProperty(value = "紧急联系人电话", position = 30)
|
||||
private String emergencyPhone;
|
||||
|
||||
/** 紧急联系人地址 */
|
||||
@ApiModelProperty(value = "紧急联系人地址", position = 31)
|
||||
private String emergencyAddress;
|
||||
|
||||
/** 员工编号 */
|
||||
@ApiModelProperty(value = "员工编号", position = 32)
|
||||
private String empNo;
|
||||
|
||||
/** 入职日期 */
|
||||
@ApiModelProperty(value = "员工编号", position = 33)
|
||||
private String entryDate;
|
||||
|
||||
/** 兼任信息 */
|
||||
@ApiModelProperty(value = "兼任信息", position = 34)
|
||||
private String positionJson;
|
||||
|
||||
/** 排序码 */
|
||||
@ApiModelProperty(value = "排序码", position = 35)
|
||||
private Integer sortCode;
|
||||
|
||||
/** 扩展信息 */
|
||||
@ApiModelProperty(value = "扩展信息", position = 36)
|
||||
private String extJson;
|
||||
}
|
@@ -0,0 +1,172 @@
|
||||
|
||||
package mjkf.xinke.biz.modular.user.param;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
/**
|
||||
* 人员编辑参数
|
||||
*
|
||||
*
|
||||
* @date 2022/7/26 15:43
|
||||
**/
|
||||
@Getter
|
||||
@Setter
|
||||
public class BizUserEditParam {
|
||||
|
||||
/** id */
|
||||
@ApiModelProperty(value = "id", required = true, position = 1)
|
||||
@NotBlank(message = "id不能为空")
|
||||
private String id;
|
||||
|
||||
/** 账号 */
|
||||
@ApiModelProperty(value = "账号", required = true, position = 2)
|
||||
@NotBlank(message = "account不能为空")
|
||||
private String account;
|
||||
|
||||
/** 姓名 */
|
||||
@ApiModelProperty(value = "姓名", required = true, position = 3)
|
||||
@NotBlank(message = "name不能为空")
|
||||
private String name;
|
||||
|
||||
/** 机构id */
|
||||
@ApiModelProperty(value = "机构id", required = true, position = 4)
|
||||
@NotBlank(message = "orgId不能为空")
|
||||
private String orgId;
|
||||
|
||||
/** 岗位id */
|
||||
@ApiModelProperty(value = "岗位id", required = true, position = 5)
|
||||
@NotBlank(message = "positionId不能为空")
|
||||
private String positionId;
|
||||
|
||||
/** 岗级 */
|
||||
@ApiModelProperty(value = "岗级", position = 6)
|
||||
private String positionLevel;
|
||||
|
||||
/** 主管id */
|
||||
@ApiModelProperty(value = "主管id", position = 7)
|
||||
private String directorId;
|
||||
|
||||
/** 头像 */
|
||||
@ApiModelProperty(value = "头像,图片base64", position = 8)
|
||||
private String avatar;
|
||||
|
||||
/** 签名 */
|
||||
@ApiModelProperty(value = "签名,图片base64", position = 9)
|
||||
private String signature;
|
||||
|
||||
/** 昵称 */
|
||||
@ApiModelProperty(value = "昵称", position = 10)
|
||||
private String nickname;
|
||||
|
||||
/** 性别 */
|
||||
@ApiModelProperty(value = "性别", position = 11)
|
||||
private String gender;
|
||||
|
||||
/** 年龄 */
|
||||
@ApiModelProperty(value = "年龄", position = 12)
|
||||
private String age;
|
||||
|
||||
/** 出生日期 */
|
||||
@ApiModelProperty(value = "出生日期", position = 13)
|
||||
private String birthday;
|
||||
|
||||
/** 民族 */
|
||||
@ApiModelProperty(value = "民族", position = 14)
|
||||
private String nation;
|
||||
|
||||
/** 籍贯 */
|
||||
@ApiModelProperty(value = "籍贯", position = 15)
|
||||
private String nativePlace;
|
||||
|
||||
/** 家庭住址 */
|
||||
@ApiModelProperty(value = "家庭住址", position = 16)
|
||||
private String homeAddress;
|
||||
|
||||
/** 通信地址 */
|
||||
@ApiModelProperty(value = "通信地址", position = 17)
|
||||
private String mailingAddress;
|
||||
|
||||
/** 证件类型 */
|
||||
@ApiModelProperty(value = "证件类型", position = 18)
|
||||
private String idCardType;
|
||||
|
||||
/** 证件号码 */
|
||||
@ApiModelProperty(value = "证件号码", position = 19)
|
||||
private String idCardNumber;
|
||||
|
||||
/** 文化程度 */
|
||||
@ApiModelProperty(value = "文化程度", position = 20)
|
||||
private String cultureLevel;
|
||||
|
||||
/** 政治面貌 */
|
||||
@ApiModelProperty(value = "政治面貌", position = 21)
|
||||
private String politicalOutlook;
|
||||
|
||||
/** 毕业院校 */
|
||||
@ApiModelProperty(value = "毕业院校", position = 22)
|
||||
private String college;
|
||||
|
||||
/** 学历 */
|
||||
@ApiModelProperty(value = "学历", position = 23)
|
||||
private String education;
|
||||
|
||||
/** 学制 */
|
||||
@ApiModelProperty(value = "学制", position = 24)
|
||||
private String eduLength;
|
||||
|
||||
/** 学位 */
|
||||
@ApiModelProperty(value = "学位", position = 25)
|
||||
private String degree;
|
||||
|
||||
/** 手机 */
|
||||
@ApiModelProperty(value = "手机", position = 26)
|
||||
private String phone;
|
||||
|
||||
/** 邮箱 */
|
||||
@ApiModelProperty(value = "邮箱", position = 27)
|
||||
private String email;
|
||||
|
||||
/** 家庭电话 */
|
||||
@ApiModelProperty(value = "家庭电话", position = 28)
|
||||
private String homeTel;
|
||||
|
||||
/** 办公电话 */
|
||||
@ApiModelProperty(value = "办公电话", position = 29)
|
||||
private String officeTel;
|
||||
|
||||
/** 紧急联系人 */
|
||||
@ApiModelProperty(value = "紧急联系人", position = 30)
|
||||
private String emergencyContact;
|
||||
|
||||
/** 紧急联系人电话 */
|
||||
@ApiModelProperty(value = "紧急联系人电话", position = 31)
|
||||
private String emergencyPhone;
|
||||
|
||||
/** 紧急联系人地址 */
|
||||
@ApiModelProperty(value = "紧急联系人地址", position = 32)
|
||||
private String emergencyAddress;
|
||||
|
||||
/** 员工编号 */
|
||||
@ApiModelProperty(value = "员工编号", position = 33)
|
||||
private String empNo;
|
||||
|
||||
/** 入职日期 */
|
||||
@ApiModelProperty(value = "员工编号", position = 34)
|
||||
private String entryDate;
|
||||
|
||||
/** 兼任信息 */
|
||||
@ApiModelProperty(value = "兼任信息", position = 35)
|
||||
private String positionJson;
|
||||
|
||||
/** 排序码 */
|
||||
@ApiModelProperty(value = "排序码", position = 36)
|
||||
private Integer sortCode;
|
||||
|
||||
/** 扩展信息 */
|
||||
@ApiModelProperty(value = "扩展信息", position = 37)
|
||||
private String extJson;
|
||||
}
|
@@ -0,0 +1,29 @@
|
||||
|
||||
package mjkf.xinke.biz.modular.user.param;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* 人员导出参数
|
||||
*
|
||||
*
|
||||
* @date 2022/7/26 16:00
|
||||
**/
|
||||
@Getter
|
||||
@Setter
|
||||
public class BizUserExportParam {
|
||||
|
||||
/** 人员状态 */
|
||||
@ApiModelProperty(value = "人员状态")
|
||||
private String userStatus;
|
||||
|
||||
/** 账号、姓名、手机号关键词 */
|
||||
@ApiModelProperty(value = "账号、姓名、手机号关键词")
|
||||
private String searchKey;
|
||||
|
||||
/** 人员id集合 */
|
||||
@ApiModelProperty(value = "人员id集合")
|
||||
private String userIds;
|
||||
}
|
@@ -0,0 +1,31 @@
|
||||
|
||||
package mjkf.xinke.biz.modular.user.param;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 人员授权角色参数
|
||||
*
|
||||
*
|
||||
* @date 2022/4/21 16:13
|
||||
**/
|
||||
@Getter
|
||||
@Setter
|
||||
public class BizUserGrantRoleParam {
|
||||
|
||||
/** id */
|
||||
@ApiModelProperty(value = "id", required = true, position = 1)
|
||||
@NotBlank(message = "id不能为空")
|
||||
private String id;
|
||||
|
||||
/** 角色id集合 */
|
||||
@ApiModelProperty(value = "角色id集合", required = true, position = 2)
|
||||
@NotNull(message = "roleIdList不能为空")
|
||||
private List<String> roleIdList;
|
||||
}
|
@@ -0,0 +1,24 @@
|
||||
|
||||
package mjkf.xinke.biz.modular.user.param;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
/**
|
||||
* 人员Id参数
|
||||
*
|
||||
*
|
||||
* @date 2022/4/21 16:13
|
||||
**/
|
||||
@Getter
|
||||
@Setter
|
||||
public class BizUserIdParam {
|
||||
|
||||
/** id */
|
||||
@ApiModelProperty(value = "id", required = true)
|
||||
@NotBlank(message = "id不能为空")
|
||||
private String id;
|
||||
}
|
@@ -0,0 +1,109 @@
|
||||
|
||||
package mjkf.xinke.biz.modular.user.param;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* 人员导入参数
|
||||
*
|
||||
*
|
||||
* @date 2022/7/8 13:22
|
||||
**/
|
||||
@Getter
|
||||
@Setter
|
||||
public class BizUserImportParam {
|
||||
|
||||
/** 账号 */
|
||||
private String account;
|
||||
|
||||
/** 姓名 */
|
||||
private String name;
|
||||
|
||||
/** 组织名称 */
|
||||
private String orgName;
|
||||
|
||||
/** 职位名称 */
|
||||
private String positionName;
|
||||
|
||||
/** 手机 */
|
||||
private String phone;
|
||||
|
||||
/** 邮箱 */
|
||||
private String email;
|
||||
|
||||
/** 主管名称 */
|
||||
private String directorName;
|
||||
|
||||
/** 员工编号 */
|
||||
private String empNo;
|
||||
|
||||
/** 入职日期 */
|
||||
private String entryDate;
|
||||
|
||||
/** 职级 */
|
||||
private String positionLevel;
|
||||
|
||||
/** 昵称 */
|
||||
private String nickname;
|
||||
|
||||
/** 性别 */
|
||||
private String gender;
|
||||
|
||||
/** 年龄 */
|
||||
private String age;
|
||||
|
||||
/** 出生日期 */
|
||||
private String birthday;
|
||||
|
||||
/** 民族 */
|
||||
private String nation;
|
||||
|
||||
/** 籍贯 */
|
||||
private String nativePlace;
|
||||
|
||||
/** 家庭住址 */
|
||||
private String homeAddress;
|
||||
|
||||
/** 通信地址 */
|
||||
private String mailingAddress;
|
||||
|
||||
/** 证件类型 */
|
||||
private String idCardType;
|
||||
|
||||
/** 证件号码 */
|
||||
private String idCardNumber;
|
||||
|
||||
/** 文化程度 */
|
||||
private String cultureLevel;
|
||||
|
||||
/** 政治面貌 */
|
||||
private String politicalOutlook;
|
||||
|
||||
/** 毕业院校 */
|
||||
private String college;
|
||||
|
||||
/** 学历 */
|
||||
private String education;
|
||||
|
||||
/** 学制 */
|
||||
private String eduLength;
|
||||
|
||||
/** 学位 */
|
||||
private String degree;
|
||||
|
||||
/** 家庭电话 */
|
||||
private String homeTel;
|
||||
|
||||
/** 办公电话 */
|
||||
private String officeTel;
|
||||
|
||||
/** 紧急联系人 */
|
||||
private String emergencyContact;
|
||||
|
||||
/** 紧急联系人电话 */
|
||||
private String emergencyPhone;
|
||||
|
||||
/** 紧急联系人地址 */
|
||||
private String emergencyAddress;
|
||||
}
|
@@ -0,0 +1,45 @@
|
||||
|
||||
package mjkf.xinke.biz.modular.user.param;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* 人员查询参数
|
||||
*
|
||||
*
|
||||
* @date 2022/7/26 16:00
|
||||
**/
|
||||
@Getter
|
||||
@Setter
|
||||
public class BizUserPageParam {
|
||||
|
||||
/** 当前页 */
|
||||
@ApiModelProperty(value = "当前页码")
|
||||
private Integer current;
|
||||
|
||||
/** 每页条数 */
|
||||
@ApiModelProperty(value = "每页条数")
|
||||
private Integer size;
|
||||
|
||||
/** 排序字段 */
|
||||
@ApiModelProperty(value = "排序字段,字段驼峰名称,如:userName")
|
||||
private String sortField;
|
||||
|
||||
/** 排序方式 */
|
||||
@ApiModelProperty(value = "排序方式,升序:ASCEND;降序:DESCEND")
|
||||
private String sortOrder;
|
||||
|
||||
/** 姓名关键词 */
|
||||
@ApiModelProperty(value = "账号、姓名、手机号关键词")
|
||||
private String searchKey;
|
||||
|
||||
/** 人员状态 */
|
||||
@ApiModelProperty(value = "人员状态")
|
||||
private String userStatus;
|
||||
|
||||
/** 所属机构 */
|
||||
@ApiModelProperty(value = "所属机构")
|
||||
private String orgId;
|
||||
}
|
@@ -0,0 +1,33 @@
|
||||
|
||||
package mjkf.xinke.biz.modular.user.param;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* 组织列表选择器参数
|
||||
*
|
||||
*
|
||||
* @date 2022/4/21 16:13
|
||||
**/
|
||||
@Getter
|
||||
@Setter
|
||||
public class BizUserSelectorOrgListParam {
|
||||
|
||||
/** 当前页 */
|
||||
@ApiModelProperty(value = "当前页码")
|
||||
private Integer current;
|
||||
|
||||
/** 每页条数 */
|
||||
@ApiModelProperty(value = "每页条数")
|
||||
private Integer size;
|
||||
|
||||
/** 父id */
|
||||
@ApiModelProperty(value = "父id")
|
||||
private String parentId;
|
||||
|
||||
/** 名称关键词 */
|
||||
@ApiModelProperty(value = "名称关键词")
|
||||
private String searchKey;
|
||||
}
|
@@ -0,0 +1,33 @@
|
||||
|
||||
package mjkf.xinke.biz.modular.user.param;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* 岗位选择器参数
|
||||
*
|
||||
*
|
||||
* @date 2022/7/26 15:58
|
||||
**/
|
||||
@Getter
|
||||
@Setter
|
||||
public class BizUserSelectorPositionParam {
|
||||
|
||||
/** 当前页 */
|
||||
@ApiModelProperty(value = "当前页码")
|
||||
private Integer current;
|
||||
|
||||
/** 每页条数 */
|
||||
@ApiModelProperty(value = "每页条数")
|
||||
private Integer size;
|
||||
|
||||
/** 机构id */
|
||||
@ApiModelProperty(value = "机构id")
|
||||
private String orgId;
|
||||
|
||||
/** 名称关键词 */
|
||||
@ApiModelProperty(value = "名称关键词")
|
||||
private String searchKey;
|
||||
}
|
@@ -0,0 +1,37 @@
|
||||
|
||||
package mjkf.xinke.biz.modular.user.param;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* 角色选择器参数
|
||||
*
|
||||
*
|
||||
* @date 2022/7/26 16:02
|
||||
**/
|
||||
@Getter
|
||||
@Setter
|
||||
public class BizUserSelectorRoleParam {
|
||||
|
||||
/** 当前页 */
|
||||
@ApiModelProperty(value = "当前页码")
|
||||
private Integer current;
|
||||
|
||||
/** 每页条数 */
|
||||
@ApiModelProperty(value = "每页条数")
|
||||
private Integer size;
|
||||
|
||||
/** 组织id */
|
||||
@ApiModelProperty(value = "组织id")
|
||||
private String orgId;
|
||||
|
||||
/** 角色分类 */
|
||||
@ApiModelProperty(value = "角色分类")
|
||||
private String category;
|
||||
|
||||
/** 名称关键词 */
|
||||
@ApiModelProperty(value = "名称关键词")
|
||||
private String searchKey;
|
||||
}
|
@@ -0,0 +1,33 @@
|
||||
|
||||
package mjkf.xinke.biz.modular.user.param;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* 用户选择器参数
|
||||
*
|
||||
*
|
||||
* @date 2022/7/26 16:03
|
||||
**/
|
||||
@Getter
|
||||
@Setter
|
||||
public class BizUserSelectorUserParam {
|
||||
|
||||
/** 当前页 */
|
||||
@ApiModelProperty(value = "当前页码")
|
||||
private Integer current;
|
||||
|
||||
/** 每页条数 */
|
||||
@ApiModelProperty(value = "每页条数")
|
||||
private Integer size;
|
||||
|
||||
/** 组织id */
|
||||
@ApiModelProperty(value = "组织id")
|
||||
private String orgId;
|
||||
|
||||
/** 姓名关键词 */
|
||||
@ApiModelProperty(value = "姓名关键词")
|
||||
private String searchKey;
|
||||
}
|
@@ -0,0 +1,236 @@
|
||||
|
||||
package mjkf.xinke.biz.modular.user.result;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import com.alibaba.excel.annotation.format.DateTimeFormat;
|
||||
import com.alibaba.excel.annotation.write.style.ColumnWidth;
|
||||
import com.alibaba.excel.annotation.write.style.HeadStyle;
|
||||
import com.alibaba.excel.enums.poi.FillPatternTypeEnum;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 人员导出结果集
|
||||
*
|
||||
*
|
||||
* @date 2022/7/8 13:22
|
||||
**/
|
||||
@Getter
|
||||
@Setter
|
||||
public class BizUserExportResult {
|
||||
|
||||
/** 机构分组 */
|
||||
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 40)
|
||||
@ExcelProperty({"人员信息", "机构分组"})
|
||||
private String groupName;
|
||||
|
||||
/** 头像 */
|
||||
@ColumnWidth(8)
|
||||
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 29)
|
||||
@ExcelProperty({"人员信息", "基本信息", "头像"})
|
||||
private byte[] avatar;
|
||||
|
||||
/** 账号 */
|
||||
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 29)
|
||||
@ExcelProperty({"人员信息", "基本信息", "账号"})
|
||||
private String account;
|
||||
|
||||
/** 姓名 */
|
||||
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 29)
|
||||
@ExcelProperty({"人员信息", "基本信息", "姓名"})
|
||||
private String name;
|
||||
|
||||
/** 昵称 */
|
||||
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 29)
|
||||
@ExcelProperty({"人员信息", "基本信息", "昵称"})
|
||||
private String nickname;
|
||||
|
||||
/** 性别 */
|
||||
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 29)
|
||||
@ExcelProperty({"人员信息", "基本信息", "性别"})
|
||||
private String gender;
|
||||
|
||||
/** 年龄 */
|
||||
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 29)
|
||||
@ExcelProperty({"人员信息", "基本信息", "年龄"})
|
||||
private String age;
|
||||
|
||||
/** 出生日期 */
|
||||
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 29)
|
||||
@ExcelProperty({"人员信息", "基本信息", "出生日期"})
|
||||
private String birthday;
|
||||
|
||||
/** 民族 */
|
||||
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 29)
|
||||
@ExcelProperty({"人员信息", "基本信息", "民族"})
|
||||
private String nation;
|
||||
|
||||
/** 籍贯 */
|
||||
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 29)
|
||||
@ExcelProperty({"人员信息", "基本信息", "籍贯"})
|
||||
private String nativePlace;
|
||||
|
||||
/** 家庭住址 */
|
||||
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 29)
|
||||
@ExcelProperty({"人员信息", "基本信息", "家庭住址"})
|
||||
private String homeAddress;
|
||||
|
||||
/** 通信地址 */
|
||||
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 29)
|
||||
@ExcelProperty({"人员信息", "基本信息", "通信地址"})
|
||||
private String mailingAddress;
|
||||
|
||||
/** 证件类型 */
|
||||
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 29)
|
||||
@ExcelProperty({"人员信息", "基本信息", "证件类型"})
|
||||
private String idCardType;
|
||||
|
||||
/** 证件号码 */
|
||||
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 29)
|
||||
@ExcelProperty({"人员信息", "基本信息", "证件号码"})
|
||||
private String idCardNumber;
|
||||
|
||||
/** 文化程度 */
|
||||
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 29)
|
||||
@ExcelProperty({"人员信息", "基本信息", "文化程度"})
|
||||
private String cultureLevel;
|
||||
|
||||
/** 政治面貌 */
|
||||
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 29)
|
||||
@ExcelProperty({"人员信息", "基本信息", "政治面貌"})
|
||||
private String politicalOutlook;
|
||||
|
||||
/** 毕业院校 */
|
||||
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 29)
|
||||
@ExcelProperty({"人员信息", "基本信息", "毕业院校"})
|
||||
private String college;
|
||||
|
||||
/** 学历 */
|
||||
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 29)
|
||||
@ExcelProperty({"人员信息", "基本信息", "学历"})
|
||||
private String education;
|
||||
|
||||
/** 学制 */
|
||||
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 29)
|
||||
@ExcelProperty({"人员信息", "基本信息", "学制"})
|
||||
private String eduLength;
|
||||
|
||||
/** 学位 */
|
||||
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 29)
|
||||
@ExcelProperty({"人员信息", "基本信息", "学位"})
|
||||
private String degree;
|
||||
|
||||
/** 手机 */
|
||||
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 29)
|
||||
@ExcelProperty({"人员信息", "基本信息", "手机"})
|
||||
private String phone;
|
||||
|
||||
/** 邮箱 */
|
||||
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 29)
|
||||
@ExcelProperty({"人员信息", "基本信息", "邮箱"})
|
||||
private String email;
|
||||
|
||||
/** 家庭电话 */
|
||||
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 29)
|
||||
@ExcelProperty({"人员信息", "基本信息", "家庭电话"})
|
||||
private String homeTel;
|
||||
|
||||
/** 办公电话 */
|
||||
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 29)
|
||||
@ExcelProperty({"人员信息", "基本信息", "办公电话"})
|
||||
private String officeTel;
|
||||
|
||||
/** 紧急联系人 */
|
||||
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 29)
|
||||
@ExcelProperty({"人员信息", "基本信息", "紧急联系人"})
|
||||
private String emergencyContact;
|
||||
|
||||
/** 紧急联系人电话 */
|
||||
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 29)
|
||||
@ExcelProperty({"人员信息", "基本信息", "紧急联系人电话"})
|
||||
private String emergencyPhone;
|
||||
|
||||
/** 紧急联系人地址 */
|
||||
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 29)
|
||||
@ExcelProperty({"人员信息", "基本信息", "紧急联系人地址"})
|
||||
private String emergencyAddress;
|
||||
|
||||
/** 员工编号 */
|
||||
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 34)
|
||||
@ExcelProperty({"人员信息", "员工信息", "员工编号"})
|
||||
private String empNo;
|
||||
|
||||
/** 入职日期 */
|
||||
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 34)
|
||||
@ExcelProperty({"人员信息", "员工信息", "入职日期"})
|
||||
private String entryDate;
|
||||
|
||||
/** 组织名称 */
|
||||
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 34)
|
||||
@ExcelProperty({"人员信息", "员工信息", "组织名称"})
|
||||
private String orgName;
|
||||
|
||||
/** 职位名称 */
|
||||
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 34)
|
||||
@ExcelProperty({"人员信息", "员工信息", "职位名称"})
|
||||
private String positionName;
|
||||
|
||||
/** 主管名称 */
|
||||
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 34)
|
||||
@ExcelProperty({"人员信息", "员工信息", "主管名称"})
|
||||
private String directorName;
|
||||
|
||||
/** 职级 */
|
||||
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 34)
|
||||
@ExcelProperty({"人员信息", "员工信息", "职级"})
|
||||
private String positionLevel;
|
||||
|
||||
/** 上次登录ip */
|
||||
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 42)
|
||||
@ExcelProperty({"人员信息", "系统信息", "上次登录ip"})
|
||||
private String lastLoginIp;
|
||||
|
||||
/** 上次登录地点 */
|
||||
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 42)
|
||||
@ExcelProperty({"人员信息", "系统信息", "上次登录地点"})
|
||||
private String lastLoginAddress;
|
||||
|
||||
/** 上次登录时间 */
|
||||
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 42)
|
||||
@DateTimeFormat("yyyy-MM-dd HH:mm:ss")
|
||||
@ExcelProperty({"人员信息", "系统信息", "上次登录时间"})
|
||||
private Date lastLoginTime;
|
||||
|
||||
/** 上次登录设备 */
|
||||
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 42)
|
||||
@ExcelProperty({"人员信息", "系统信息", "上次登录设备"})
|
||||
private String lastLoginDevice;
|
||||
|
||||
/** 最新登录ip */
|
||||
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 42)
|
||||
@ExcelProperty({"人员信息", "系统信息", "最新登录ip"})
|
||||
private String latestLoginIp;
|
||||
|
||||
/** 最新登录地点 */
|
||||
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 42)
|
||||
@ExcelProperty({"人员信息", "系统信息", "最新登录地点"})
|
||||
private String latestLoginAddress;
|
||||
|
||||
/** 最新登录时间 */
|
||||
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 42)
|
||||
@DateTimeFormat("yyyy-MM-dd HH:mm:ss")
|
||||
@ExcelProperty({"人员信息", "系统信息", "最新登录时间"})
|
||||
private Date latestLoginTime;
|
||||
|
||||
/** 最新登录设备 */
|
||||
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 42)
|
||||
@ExcelProperty({"人员信息", "系统信息", "最新登录设备"})
|
||||
private String latestLoginDevice;
|
||||
|
||||
/** 人员状态 */
|
||||
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 42)
|
||||
@ExcelProperty({"人员信息", "系统信息", "人员状态"})
|
||||
private String userStatus;
|
||||
}
|
@@ -0,0 +1,37 @@
|
||||
|
||||
package mjkf.xinke.biz.modular.user.result;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* 角色选择器结果
|
||||
*
|
||||
*
|
||||
* @date 2022/7/22 14:29
|
||||
**/
|
||||
@Getter
|
||||
@Setter
|
||||
public class BizUserRoleResult {
|
||||
|
||||
/** id */
|
||||
@ApiModelProperty(value = "id", position = 1)
|
||||
private String id;
|
||||
|
||||
/** 组织id */
|
||||
@ApiModelProperty(value = "机构id", position = 2)
|
||||
private String orgId;
|
||||
|
||||
/** 名称 */
|
||||
@ApiModelProperty(value = "名称", position = 3)
|
||||
private String name;
|
||||
|
||||
/** 分类 */
|
||||
@ApiModelProperty(value = "分类", position = 4)
|
||||
private String category;
|
||||
|
||||
/** 排序码 */
|
||||
@ApiModelProperty(value = "排序码", position = 5)
|
||||
private Integer sortCode;
|
||||
}
|
@@ -0,0 +1,179 @@
|
||||
|
||||
package mjkf.xinke.biz.modular.user.service;
|
||||
|
||||
import cn.hutool.core.lang.tree.Tree;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import mjkf.xinke.biz.modular.org.entity.BizOrg;
|
||||
import mjkf.xinke.biz.modular.position.entity.BizPosition;
|
||||
import mjkf.xinke.biz.modular.user.entity.BizUser;
|
||||
import mjkf.xinke.biz.modular.user.param.*;
|
||||
import mjkf.xinke.biz.modular.user.result.BizUserRoleResult;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 人员Service接口
|
||||
*
|
||||
*
|
||||
* @date 2022/4/21 18:35
|
||||
**/
|
||||
public interface BizUserService extends IService<BizUser> {
|
||||
|
||||
/**
|
||||
* 获取人员分页
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 20:08
|
||||
*/
|
||||
Page<BizUser> page(BizUserPageParam bizUserPageParam);
|
||||
|
||||
/**
|
||||
* 添加人员
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 20:48
|
||||
*/
|
||||
void add(BizUserAddParam bizUserAddParam);
|
||||
|
||||
/**
|
||||
* 编辑人员
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 21:13
|
||||
*/
|
||||
void edit(BizUserEditParam bizUserEditParam);
|
||||
|
||||
/**
|
||||
* 删除人员
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 21:18
|
||||
*/
|
||||
void delete(List<BizUserIdParam> bizUserIdParamList);
|
||||
|
||||
/**
|
||||
* 获取人员详情
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 21:18
|
||||
*/
|
||||
BizUser detail(BizUserIdParam bizUserIdPara);
|
||||
|
||||
/**
|
||||
* 获取人员详情
|
||||
*
|
||||
*
|
||||
* @date 2022/7/26 17:21
|
||||
**/
|
||||
BizUser queryEntity(String id);
|
||||
|
||||
/**
|
||||
* 禁用人员
|
||||
*
|
||||
*
|
||||
* @date 2022/7/5 18:20
|
||||
**/
|
||||
void disableUser(BizUserIdParam bizUserIdParam);
|
||||
|
||||
/**
|
||||
* 启用人员
|
||||
*
|
||||
*
|
||||
* @date 2022/7/5 18:21
|
||||
**/
|
||||
void enableUser(BizUserIdParam bizUserIdParam);
|
||||
|
||||
/**
|
||||
* 重置人员密码
|
||||
*
|
||||
*
|
||||
* @date 2022/7/5 18:22
|
||||
**/
|
||||
void resetPassword(BizUserIdParam bizUserIdParam);
|
||||
|
||||
/**
|
||||
* 获取人员拥有角色
|
||||
*
|
||||
*
|
||||
* @date 2022/5/13 21:00
|
||||
*/
|
||||
List<String> ownRole(BizUserIdParam bizUserIdParam);
|
||||
|
||||
/**
|
||||
* 给人员授权角色
|
||||
*
|
||||
*
|
||||
* @date 2022/4/29 11:13
|
||||
**/
|
||||
void grantRole(BizUserGrantRoleParam bizUserGrantRoleParam);
|
||||
|
||||
/**
|
||||
* 用户导出
|
||||
*
|
||||
*
|
||||
* @date 2022/8/8 13:16
|
||||
**/
|
||||
void exportUser(BizUserExportParam bizUserExportParam, HttpServletResponse response) throws IOException;
|
||||
|
||||
/**
|
||||
* 导出用户个人信息
|
||||
*
|
||||
*
|
||||
* @date 2022/8/8 13:16
|
||||
**/
|
||||
void exportUserInfo(BizUserIdParam bizUserIdParam, HttpServletResponse response) throws IOException;
|
||||
|
||||
/* ====人员部分所需要用到的选择器==== */
|
||||
|
||||
/**
|
||||
* 获取机构树选择器
|
||||
*
|
||||
*
|
||||
* @date 2022/5/13 21:00
|
||||
*/
|
||||
List<Tree<String>> orgTreeSelector();
|
||||
|
||||
/**
|
||||
* 获取机构列表选择器
|
||||
*
|
||||
*
|
||||
* @date 2022/7/22 13:34
|
||||
**/
|
||||
Page<BizOrg> orgListSelector(BizUserSelectorOrgListParam bizUserSelectorOrgListParam);
|
||||
|
||||
/**
|
||||
* 获取岗位选择器
|
||||
*
|
||||
*
|
||||
* @date 2022/5/13 21:00
|
||||
*/
|
||||
Page<BizPosition> positionSelector(BizUserSelectorPositionParam bizUserSelectorPositionParam);
|
||||
|
||||
/**
|
||||
* 获取角色选择器
|
||||
*
|
||||
*
|
||||
* @date 2022/5/13 21:00
|
||||
*/
|
||||
Page<BizUserRoleResult> roleSelector(BizUserSelectorRoleParam bizUserSelectorRoleParam);
|
||||
|
||||
/**
|
||||
* 获取人员选择器
|
||||
*
|
||||
*
|
||||
* @date 2022/4/24 20:08
|
||||
*/
|
||||
Page<BizUser> userSelector(BizUserSelectorUserParam bizUserSelectorUserParam);
|
||||
|
||||
/**
|
||||
* 获取动态字段配置
|
||||
*
|
||||
*
|
||||
* @date 2022/8/5 3:23
|
||||
*/
|
||||
List<JSONObject> dynamicFieldConfigList();
|
||||
}
|
@@ -0,0 +1,743 @@
|
||||
|
||||
package mjkf.xinke.biz.modular.user.service.impl;
|
||||
|
||||
import cn.afterturn.easypoi.cache.manager.POICacheManager;
|
||||
import cn.afterturn.easypoi.entity.ImageEntity;
|
||||
import cn.afterturn.easypoi.word.WordExportUtil;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.hutool.core.annotation.AnnotationUtil;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.collection.CollStreamUtil;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.date.DatePattern;
|
||||
import cn.hutool.core.date.DateTime;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.img.ImgUtil;
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.lang.tree.Tree;
|
||||
import cn.hutool.core.lang.tree.TreeNode;
|
||||
import cn.hutool.core.lang.tree.TreeUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.PhoneUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.alibaba.excel.EasyExcel;
|
||||
import com.alibaba.excel.metadata.data.WriteCellData;
|
||||
import com.alibaba.excel.write.handler.CellWriteHandler;
|
||||
import com.alibaba.excel.write.handler.context.CellWriteHandlerContext;
|
||||
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
|
||||
import com.alibaba.excel.write.metadata.style.WriteFont;
|
||||
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
|
||||
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
|
||||
import com.alibaba.excel.write.style.row.AbstractRowHeightStyleStrategy;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.fhs.trans.service.impl.TransService;
|
||||
import org.apache.poi.ss.usermodel.*;
|
||||
import org.apache.poi.xwpf.usermodel.XWPFDocument;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import mjkf.xinke.auth.core.util.StpLoginUserUtil;
|
||||
import mjkf.xinke.biz.core.enums.BizBuildInEnum;
|
||||
import mjkf.xinke.biz.core.enums.BizDataTypeEnum;
|
||||
import mjkf.xinke.biz.modular.org.entity.BizOrg;
|
||||
import mjkf.xinke.biz.modular.org.service.BizOrgService;
|
||||
import mjkf.xinke.biz.modular.position.entity.BizPosition;
|
||||
import mjkf.xinke.biz.modular.position.service.BizPositionService;
|
||||
import mjkf.xinke.biz.modular.user.entity.BizUser;
|
||||
import mjkf.xinke.biz.modular.user.enums.BizRoleCategoryEnum;
|
||||
import mjkf.xinke.biz.modular.user.enums.BizUserStatusEnum;
|
||||
import mjkf.xinke.biz.modular.user.mapper.BizUserMapper;
|
||||
import mjkf.xinke.biz.modular.user.param.*;
|
||||
import mjkf.xinke.biz.modular.user.result.BizUserRoleResult;
|
||||
import mjkf.xinke.biz.modular.user.service.BizUserService;
|
||||
import mjkf.xinke.common.enums.CommonSortOrderEnum;
|
||||
import mjkf.xinke.common.excel.CommonExcelCustomMergeStrategy;
|
||||
import mjkf.xinke.common.exception.CommonException;
|
||||
import mjkf.xinke.common.listener.CommonDataChangeEventCenter;
|
||||
import mjkf.xinke.common.page.CommonPageRequest;
|
||||
import mjkf.xinke.common.util.*;
|
||||
import mjkf.xinke.dbs.api.DbsApi;
|
||||
import mjkf.xinke.dev.api.DevConfigApi;
|
||||
import mjkf.xinke.dev.api.DevDfcApi;
|
||||
import mjkf.xinke.sys.api.SysRoleApi;
|
||||
import mjkf.xinke.sys.api.SysUserApi;
|
||||
import mjkf.xinke.biz.modular.user.result.BizUserExportResult;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 人员Service接口实现类
|
||||
*
|
||||
*
|
||||
* @date 2022/2/23 18:43
|
||||
**/
|
||||
@Service
|
||||
public class BizUserServiceImpl extends ServiceImpl<BizUserMapper, BizUser> implements BizUserService {
|
||||
|
||||
private static final String SNOWY_SYS_DEFAULT_PASSWORD_KEY = "SNOWY_SYS_DEFAULT_PASSWORD";
|
||||
|
||||
@Resource
|
||||
private TransService transService;
|
||||
|
||||
@Resource
|
||||
private DevConfigApi devConfigApi;
|
||||
|
||||
@Resource
|
||||
private SysUserApi sysUserApi;
|
||||
|
||||
@Resource
|
||||
private SysRoleApi sysRoleApi;
|
||||
|
||||
@Resource
|
||||
private BizOrgService bizOrgService;
|
||||
|
||||
@Resource
|
||||
private BizPositionService bizPositionService;
|
||||
|
||||
@Resource
|
||||
private DbsApi dbsApi;
|
||||
|
||||
@Resource
|
||||
private DevDfcApi devDfcApi;
|
||||
|
||||
@Override
|
||||
public Page<BizUser> page(BizUserPageParam bizUserPageParam) {
|
||||
QueryWrapper<BizUser> queryWrapper = new QueryWrapper<>();
|
||||
if (ObjectUtil.isNotEmpty(bizUserPageParam.getSearchKey())) {
|
||||
queryWrapper.lambda().like(BizUser::getAccount, bizUserPageParam.getSearchKey()).or()
|
||||
.like(BizUser::getName, bizUserPageParam.getSearchKey());
|
||||
}
|
||||
if (ObjectUtil.isNotEmpty(bizUserPageParam.getOrgId())) {
|
||||
queryWrapper.lambda().eq(BizUser::getOrgId, bizUserPageParam.getOrgId());
|
||||
}
|
||||
if (ObjectUtil.isNotEmpty(bizUserPageParam.getUserStatus())) {
|
||||
queryWrapper.lambda().eq(BizUser::getUserStatus, bizUserPageParam.getUserStatus());
|
||||
}
|
||||
if (ObjectUtil.isAllNotEmpty(bizUserPageParam.getSortField(), bizUserPageParam.getSortOrder())) {
|
||||
CommonSortOrderEnum.validate(bizUserPageParam.getSortOrder());
|
||||
queryWrapper.orderBy(true, bizUserPageParam.getSortOrder().equals(CommonSortOrderEnum.ASC.getValue()),
|
||||
StrUtil.toUnderlineCase(bizUserPageParam.getSortField()));
|
||||
} else {
|
||||
queryWrapper.lambda().orderByAsc(BizUser::getSortCode);
|
||||
}
|
||||
// 排除超管
|
||||
queryWrapper.lambda().ne(BizUser::getAccount, BizBuildInEnum.BUILD_IN_USER_ACCOUNT.getValue());
|
||||
// 校验数据范围
|
||||
List<String> loginUserDataScope = StpLoginUserUtil.getLoginUserDataScope();
|
||||
if(ObjectUtil.isNotEmpty(loginUserDataScope)) {
|
||||
queryWrapper.lambda().in(BizUser::getOrgId, loginUserDataScope);
|
||||
} else {
|
||||
queryWrapper.lambda().eq(BizUser::getId, StpUtil.getLoginIdAsString());
|
||||
}
|
||||
return this.page(CommonPageRequest.defaultPage(), queryWrapper);
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public void add(BizUserAddParam bizUserAddParam) {
|
||||
checkParam(bizUserAddParam);
|
||||
BizUser bizUser = BeanUtil.toBean(bizUserAddParam, BizUser.class);
|
||||
if(ObjectUtil.isEmpty(bizUser.getAvatar())) {
|
||||
// 设置默认头像
|
||||
bizUser.setAvatar(CommonAvatarUtil.generateImg(bizUser.getName()));
|
||||
}
|
||||
// 设置密码
|
||||
bizUser.setPassword(CommonCryptogramUtil.doHashValue(devConfigApi.getValueByKey(SNOWY_SYS_DEFAULT_PASSWORD_KEY)));
|
||||
// 设置状态
|
||||
bizUser.setUserStatus(BizUserStatusEnum.ENABLE.getValue());
|
||||
this.save(bizUser);
|
||||
|
||||
// 发布增加事件
|
||||
CommonDataChangeEventCenter.doAddWithData(BizDataTypeEnum.USER.getValue(), JSONUtil.createArray().put(bizUser));
|
||||
}
|
||||
|
||||
private void checkParam(BizUserAddParam bizUserAddParam) {
|
||||
// 校验数据范围
|
||||
List<String> loginUserDataScope = StpLoginUserUtil.getLoginUserDataScope();
|
||||
if(ObjectUtil.isNotEmpty(loginUserDataScope)) {
|
||||
if(!loginUserDataScope.contains(bizUserAddParam.getOrgId())) {
|
||||
throw new CommonException("您没有权限在该机构下增加人员,机构id:{}", bizUserAddParam.getOrgId());
|
||||
}
|
||||
} else {
|
||||
throw new CommonException("您没有权限在该机构下增加人员,机构id:{}", bizUserAddParam.getOrgId());
|
||||
}
|
||||
if (this.count(new LambdaQueryWrapper<BizUser>()
|
||||
.eq(BizUser::getAccount, bizUserAddParam.getAccount())) > 0) {
|
||||
throw new CommonException("存在重复的账号,账号为:{}", bizUserAddParam.getAccount());
|
||||
}
|
||||
if(ObjectUtil.isNotEmpty(bizUserAddParam.getPhone())) {
|
||||
if(!PhoneUtil.isMobile(bizUserAddParam.getPhone())) {
|
||||
throw new CommonException("手机号码:{}格式错误", bizUserAddParam.getPhone());
|
||||
}
|
||||
if (this.count(new LambdaQueryWrapper<BizUser>()
|
||||
.eq(BizUser::getPhone, CommonCryptogramUtil.doSm4CbcEncrypt(bizUserAddParam.getPhone()))) > 0) {
|
||||
throw new CommonException("存在重复的手机号,手机号为:{}", bizUserAddParam.getPhone());
|
||||
}
|
||||
}
|
||||
if(ObjectUtil.isNotEmpty(bizUserAddParam.getEmail())) {
|
||||
if(!CommonEmailUtil.isEmail(bizUserAddParam.getEmail())) {
|
||||
throw new CommonException("邮箱:{}格式错误", bizUserAddParam.getEmail());
|
||||
}
|
||||
if (this.count(new LambdaQueryWrapper<BizUser>()
|
||||
.eq(BizUser::getEmail, bizUserAddParam.getEmail())) > 0) {
|
||||
throw new CommonException("存在重复的邮箱,邮箱为:{}", bizUserAddParam.getEmail());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public void edit(BizUserEditParam bizUserEditParam) {
|
||||
BizUser bizUser = this.queryEntity(bizUserEditParam.getId());
|
||||
checkParam(bizUserEditParam);
|
||||
boolean updateSuperAdminAccount = bizUser.getAccount().equals(BizBuildInEnum.BUILD_IN_USER_ACCOUNT.getValue()) &&
|
||||
!bizUserEditParam.getAccount().equals(BizBuildInEnum.BUILD_IN_USER_ACCOUNT.getValue());
|
||||
if(updateSuperAdminAccount) {
|
||||
throw new CommonException("不可修改系统内置超管人员账号");
|
||||
}
|
||||
BeanUtil.copyProperties(bizUserEditParam, bizUser);
|
||||
this.updateById(bizUser);
|
||||
|
||||
// 发布更新事件
|
||||
CommonDataChangeEventCenter.doUpdateWithData(BizDataTypeEnum.USER.getValue(), JSONUtil.createArray().put(bizUser));
|
||||
}
|
||||
|
||||
private void checkParam(BizUserEditParam bizUserEditParam) {
|
||||
// 校验数据范围
|
||||
List<String> loginUserDataScope = StpLoginUserUtil.getLoginUserDataScope();
|
||||
if(ObjectUtil.isNotEmpty(loginUserDataScope)) {
|
||||
if(!loginUserDataScope.contains(bizUserEditParam.getOrgId())) {
|
||||
throw new CommonException("您没有权限编辑该机构下的人员,机构id:{}", bizUserEditParam.getOrgId());
|
||||
}
|
||||
} else {
|
||||
if(!bizUserEditParam.getId().equals(StpUtil.getLoginIdAsString())) {
|
||||
throw new CommonException("您没有权限编辑该机构下的人员,机构id:{}", bizUserEditParam.getOrgId());
|
||||
}
|
||||
}
|
||||
if (this.count(new LambdaQueryWrapper<BizUser>()
|
||||
.eq(BizUser::getAccount, bizUserEditParam.getAccount())
|
||||
.ne(BizUser::getId, bizUserEditParam.getId())) > 0) {
|
||||
throw new CommonException("存在重复的账号,账号为:{}", bizUserEditParam.getAccount());
|
||||
}
|
||||
if(ObjectUtil.isNotEmpty(bizUserEditParam.getPhone())) {
|
||||
if(!PhoneUtil.isMobile(bizUserEditParam.getPhone())) {
|
||||
throw new CommonException("手机号码:{}格式错误", bizUserEditParam.getPhone());
|
||||
}
|
||||
if (this.count(new LambdaQueryWrapper<BizUser>()
|
||||
.eq(BizUser::getPhone, CommonCryptogramUtil.doSm4CbcEncrypt(bizUserEditParam.getPhone()))
|
||||
.ne(BizUser::getId, bizUserEditParam.getId())) > 0) {
|
||||
throw new CommonException("存在重复的手机号,手机号为:{}", bizUserEditParam.getPhone());
|
||||
}
|
||||
}
|
||||
if(ObjectUtil.isNotEmpty(bizUserEditParam.getEmail())) {
|
||||
if(!CommonEmailUtil.isEmail(bizUserEditParam.getEmail())) {
|
||||
throw new CommonException("邮箱:{}格式错误", bizUserEditParam.getEmail());
|
||||
}
|
||||
if (this.count(new LambdaQueryWrapper<BizUser>()
|
||||
.eq(BizUser::getEmail, bizUserEditParam.getEmail())
|
||||
.ne(BizUser::getId, bizUserEditParam.getId())) > 0) {
|
||||
throw new CommonException("存在重复的邮箱,邮箱为:{}", bizUserEditParam.getEmail());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public void delete(List<BizUserIdParam> bizUserIdParamList) {
|
||||
List<String> bizUserIdList = CollStreamUtil.toList(bizUserIdParamList, BizUserIdParam::getId);
|
||||
if(ObjectUtil.isNotEmpty(bizUserIdList)) {
|
||||
boolean containsSuperAdminAccount = this.listByIds(bizUserIdList).stream().map(BizUser::getAccount)
|
||||
.collect(Collectors.toSet()).contains(BizBuildInEnum.BUILD_IN_USER_ACCOUNT.getValue());
|
||||
if(containsSuperAdminAccount) {
|
||||
throw new CommonException("不可删除系统内置超管人员");
|
||||
}
|
||||
// 获取这些人员的的机构id集合
|
||||
Set<String> userOrgIdList = this.listByIds(bizUserIdList).stream().map(BizUser::getOrgId).collect(Collectors.toSet());
|
||||
// 校验数据范围
|
||||
List<String> loginUserDataScope = StpLoginUserUtil.getLoginUserDataScope();
|
||||
if(ObjectUtil.isNotEmpty(loginUserDataScope)) {
|
||||
if(!loginUserDataScope.containsAll(userOrgIdList)) {
|
||||
throw new CommonException("您没有权限删除这些机构下的人员,机构id:{}",
|
||||
CollectionUtil.subtract(userOrgIdList, loginUserDataScope));
|
||||
}
|
||||
} else {
|
||||
if(bizUserIdList.size() != 1 || !bizUserIdList.get(0).equals(StpUtil.getLoginIdAsString())) {
|
||||
throw new CommonException("您没有权限删除这些机构下的人员,机构id:{}", userOrgIdList);
|
||||
}
|
||||
}
|
||||
// 清除【将这些人员作为主管】的信息
|
||||
this.update(new LambdaUpdateWrapper<BizUser>().in(BizUser::getDirectorId, bizUserIdList).set(BizUser::getDirectorId, null));
|
||||
|
||||
// 清除【将这些人员作为兼任岗位的主管】的信息
|
||||
this.list(new LambdaQueryWrapper<BizUser>() .isNotNull(BizUser::getPositionJson)).forEach(bizUser -> {
|
||||
List<JSONObject> handledJsonObjectList = JSONUtil.toList(JSONUtil.parseArray(bizUser.getPositionJson()),
|
||||
JSONObject.class).stream().peek(jsonObject -> {
|
||||
String directorId = jsonObject.getStr("directorId");
|
||||
if (ObjectUtil.isNotEmpty(directorId) && bizUserIdList.contains(directorId)) {
|
||||
jsonObject.remove("directorId");
|
||||
}
|
||||
}).collect(Collectors.toList());
|
||||
this.update(new LambdaUpdateWrapper<BizUser>().eq(BizUser::getId, bizUser.getId())
|
||||
.set(BizUser::getPositionJson, JSONUtil.toJsonStr(handledJsonObjectList)));
|
||||
});
|
||||
|
||||
// 清除【将这些人员作为主管】的机构的主管信息
|
||||
bizOrgService.update(new LambdaUpdateWrapper<BizOrg>().in(BizOrg::getDirectorId, bizUserIdList).set(BizOrg::getDirectorId, null));
|
||||
|
||||
// 执行删除
|
||||
this.removeByIds(bizUserIdList);
|
||||
|
||||
// 发布删除事件
|
||||
CommonDataChangeEventCenter.doDeleteWithDataId(BizDataTypeEnum.USER.getValue(), bizUserIdList);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BizUser detail(BizUserIdParam bizUserIdParam) {
|
||||
return this.queryEntity(bizUserIdParam.getId());
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public void disableUser(BizUserIdParam bizUserIdParam) {
|
||||
BizUser bizUser = this.detail(bizUserIdParam);
|
||||
// 校验数据范围
|
||||
List<String> loginUserDataScope = StpLoginUserUtil.getLoginUserDataScope();
|
||||
if(ObjectUtil.isNotEmpty(loginUserDataScope)) {
|
||||
if(!loginUserDataScope.contains(bizUser.getOrgId())) {
|
||||
throw new CommonException("您没有权限禁用该机构下的人员:{},机构id:{}", bizUser.getName(), bizUser.getOrgId());
|
||||
}
|
||||
} else {
|
||||
if(!bizUser.getId().equals(StpUtil.getLoginIdAsString())) {
|
||||
throw new CommonException("您没有权限禁用该机构下的人员:{},机构id:{}", bizUser.getName(), bizUser.getOrgId());
|
||||
}
|
||||
}
|
||||
this.update(new LambdaUpdateWrapper<BizUser>().eq(BizUser::getId,
|
||||
bizUserIdParam.getId()).set(BizUser::getUserStatus, BizUserStatusEnum.DISABLED.getValue()));
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public void enableUser(BizUserIdParam bizUserIdParam) {
|
||||
BizUser bizUser = this.detail(bizUserIdParam);
|
||||
// 校验数据范围
|
||||
List<String> loginUserDataScope = StpLoginUserUtil.getLoginUserDataScope();
|
||||
if(ObjectUtil.isNotEmpty(loginUserDataScope)) {
|
||||
if(!loginUserDataScope.contains(bizUser.getOrgId())) {
|
||||
throw new CommonException("您没有权限启用该机构下的人员:{},机构id:{}", bizUser.getName(), bizUser.getOrgId());
|
||||
}
|
||||
} else {
|
||||
if(!bizUser.getId().equals(StpUtil.getLoginIdAsString())) {
|
||||
throw new CommonException("您没有权限启用该机构下的人员:{},机构id:{}", bizUser.getName(), bizUser.getOrgId());
|
||||
}
|
||||
}
|
||||
this.update(new LambdaUpdateWrapper<BizUser>().eq(BizUser::getId,
|
||||
bizUserIdParam.getId()).set(BizUser::getUserStatus, BizUserStatusEnum.ENABLE.getValue()));
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public void resetPassword(BizUserIdParam bizUserIdParam) {
|
||||
BizUser bizUser = this.detail(bizUserIdParam);
|
||||
// 校验数据范围
|
||||
List<String> loginUserDataScope = StpLoginUserUtil.getLoginUserDataScope();
|
||||
if(ObjectUtil.isNotEmpty(loginUserDataScope)) {
|
||||
if(!loginUserDataScope.contains(bizUser.getOrgId())) {
|
||||
throw new CommonException("您没有权限为该机构下的人员:{}重置密码,机构id:{}", bizUser.getName(), bizUser.getOrgId());
|
||||
}
|
||||
} else {
|
||||
if(!bizUser.getId().equals(StpUtil.getLoginIdAsString())) {
|
||||
throw new CommonException("您没有权限为该机构下的人员:{}重置密码,机构id:{}", bizUser.getName(), bizUser.getOrgId());
|
||||
}
|
||||
}
|
||||
this.update(new LambdaUpdateWrapper<BizUser>().eq(BizUser::getId,
|
||||
bizUserIdParam.getId()).set(BizUser::getPassword,
|
||||
CommonCryptogramUtil.doHashValue(devConfigApi.getValueByKey(SNOWY_SYS_DEFAULT_PASSWORD_KEY))));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> ownRole(BizUserIdParam bizUserIdParam) {
|
||||
return sysUserApi.ownRole(bizUserIdParam.getId());
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public void grantRole(BizUserGrantRoleParam bizUserGrantRoleParam) {
|
||||
BizUser bizUser = this.queryEntity(bizUserGrantRoleParam.getId());
|
||||
// 校验数据范围
|
||||
List<String> loginUserDataScope = StpLoginUserUtil.getLoginUserDataScope();
|
||||
if(ObjectUtil.isNotEmpty(loginUserDataScope)) {
|
||||
if(!loginUserDataScope.contains(bizUser.getOrgId())) {
|
||||
throw new CommonException("您没有权限为该机构下的人员:{}授权角色,机构id:{}", bizUser.getName(), bizUser.getOrgId());
|
||||
}
|
||||
} else {
|
||||
if(!bizUser.getId().equals(StpUtil.getLoginIdAsString())) {
|
||||
throw new CommonException("您没有权限为该机构下的人员:{}授权角色,机构id:{}", bizUser.getName(), bizUser.getOrgId());
|
||||
}
|
||||
}
|
||||
sysUserApi.grantRole(bizUserGrantRoleParam.getId(), bizUserGrantRoleParam.getRoleIdList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exportUser(BizUserExportParam bizUserExportParam, HttpServletResponse response) throws IOException {
|
||||
File tempFile = null;
|
||||
try {
|
||||
QueryWrapper<BizUser> queryWrapper = new QueryWrapper<>();
|
||||
// 排除超管
|
||||
queryWrapper.lambda().ne(BizUser::getAccount, BizBuildInEnum.BUILD_IN_USER_ACCOUNT.getValue());
|
||||
// 校验数据范围
|
||||
List<String> loginUserDataScope = StpLoginUserUtil.getLoginUserDataScope();
|
||||
if(ObjectUtil.isNotEmpty(loginUserDataScope)) {
|
||||
queryWrapper.lambda().in(BizUser::getOrgId, loginUserDataScope);
|
||||
} else {
|
||||
queryWrapper.lambda().eq(BizUser::getId, StpUtil.getLoginIdAsString());
|
||||
}
|
||||
if(ObjectUtil.isNotEmpty(bizUserExportParam.getUserIds())) {
|
||||
queryWrapper.lambda().in(BizUser::getId, StrUtil.split(bizUserExportParam.getUserIds(), StrUtil.COMMA));
|
||||
} else {
|
||||
if (ObjectUtil.isNotEmpty(bizUserExportParam.getSearchKey())) {
|
||||
queryWrapper.lambda().like(BizUser::getAccount, bizUserExportParam.getSearchKey())
|
||||
.or().like(BizUser::getName, bizUserExportParam.getSearchKey())
|
||||
.or().like(BizUser::getPhone, bizUserExportParam.getSearchKey());
|
||||
}
|
||||
if (ObjectUtil.isNotEmpty(bizUserExportParam.getUserStatus())) {
|
||||
queryWrapper.lambda().eq(BizUser::getUserStatus, bizUserExportParam.getUserStatus());
|
||||
}
|
||||
}
|
||||
String fileName = "SNOWY2.0系统B端人员信息清单.xlsx";
|
||||
List<BizUser> bizUserList = this.list(queryWrapper);
|
||||
if(ObjectUtil.isEmpty(bizUserList)) {
|
||||
throw new CommonException("无数据可导出");
|
||||
}
|
||||
transService.transBatch(bizUserList);
|
||||
bizUserList = CollectionUtil.sort(bizUserList, Comparator.comparing(BizUser::getOrgId));
|
||||
List<BizUserExportResult> bizUserExportResultList = bizUserList.stream()
|
||||
.map(bizUser -> {
|
||||
BizUserExportResult bizUserExportResult = new BizUserExportResult();
|
||||
BeanUtil.copyProperties(bizUser, bizUserExportResult);
|
||||
bizUserExportResult.setGroupName(ObjectUtil.isNotEmpty(bizUserExportResult.getOrgName())?
|
||||
bizUserExportResult.getOrgName():"无组织");
|
||||
// 状态枚举转为文字
|
||||
bizUserExportResult.setUserStatus(bizUserExportResult.getUserStatus()
|
||||
.equalsIgnoreCase(BizUserStatusEnum.ENABLE.getValue())?"正常":"停用");
|
||||
// 将base64转为byte数组
|
||||
if (ObjectUtil.isNotEmpty(bizUser.getAvatar())) {
|
||||
bizUserExportResult.setAvatar(ImgUtil.toBytes(ImgUtil.toImage(StrUtil
|
||||
.split(bizUser.getAvatar(), StrUtil.COMMA).get(1)), ImgUtil.IMAGE_TYPE_PNG));
|
||||
}
|
||||
return bizUserExportResult;
|
||||
}).collect(Collectors.toList());
|
||||
// 创建临时文件
|
||||
tempFile = FileUtil.file(FileUtil.getTmpDir() + FileUtil.FILE_SEPARATOR + fileName);
|
||||
|
||||
// 头的策略
|
||||
WriteCellStyle headWriteCellStyle = new WriteCellStyle();
|
||||
WriteFont headWriteFont = new WriteFont();
|
||||
headWriteFont.setFontHeightInPoints((short) 14);
|
||||
headWriteCellStyle.setWriteFont(headWriteFont);
|
||||
// 水平垂直居中
|
||||
headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
|
||||
headWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
|
||||
|
||||
// 内容的策略
|
||||
WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
|
||||
// 这里需要指定 FillPatternType 为FillPatternType.SOLID_FOREGROUND 不然无法显示背景颜色.头默认了 FillPatternType所以可以不指定
|
||||
contentWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
|
||||
// 内容背景白色
|
||||
contentWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
|
||||
WriteFont contentWriteFont = new WriteFont();
|
||||
|
||||
// 内容字体大小
|
||||
contentWriteFont.setFontHeightInPoints((short) 12);
|
||||
contentWriteCellStyle.setWriteFont(contentWriteFont);
|
||||
|
||||
//设置边框样式,细实线
|
||||
contentWriteCellStyle.setBorderLeft(BorderStyle.THIN);
|
||||
contentWriteCellStyle.setBorderTop(BorderStyle.THIN);
|
||||
contentWriteCellStyle.setBorderRight(BorderStyle.THIN);
|
||||
contentWriteCellStyle.setBorderBottom(BorderStyle.THIN);
|
||||
|
||||
// 水平垂直居中
|
||||
contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.LEFT);
|
||||
contentWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
|
||||
|
||||
// 这个策略是 头是头的样式 内容是内容的样式 其他的策略可以自己实现
|
||||
HorizontalCellStyleStrategy horizontalCellStyleStrategy = new HorizontalCellStyleStrategy(headWriteCellStyle,
|
||||
contentWriteCellStyle);
|
||||
|
||||
// 写excel
|
||||
EasyExcel.write(tempFile.getPath(), BizUserExportResult.class)
|
||||
// 自定义样式
|
||||
.registerWriteHandler(horizontalCellStyleStrategy)
|
||||
// 自动列宽
|
||||
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
|
||||
// 机构分组合并单元格
|
||||
.registerWriteHandler(new CommonExcelCustomMergeStrategy(bizUserExportResultList.stream().map(BizUserExportResult::getGroupName)
|
||||
.collect(Collectors.toList()), 0))
|
||||
// 设置第一行字体
|
||||
.registerWriteHandler(new CellWriteHandler() {
|
||||
@Override
|
||||
public void afterCellDispose(CellWriteHandlerContext context) {
|
||||
WriteCellData<?> cellData = context.getFirstCellData();
|
||||
WriteCellStyle writeCellStyle = cellData.getOrCreateStyle();
|
||||
Integer rowIndex = context.getRowIndex();
|
||||
if(rowIndex == 0) {
|
||||
WriteFont headWriteFont = new WriteFont();
|
||||
headWriteFont.setFontName("宋体");
|
||||
headWriteFont.setBold(true);
|
||||
headWriteFont.setFontHeightInPoints((short) 16);
|
||||
writeCellStyle.setWriteFont(headWriteFont);
|
||||
}
|
||||
}
|
||||
})
|
||||
// 设置表头行高
|
||||
.registerWriteHandler(new AbstractRowHeightStyleStrategy() {
|
||||
@Override
|
||||
protected void setHeadColumnHeight(Row row, int relativeRowIndex) {
|
||||
if(relativeRowIndex == 0) {
|
||||
// 表头第一行
|
||||
row.setHeightInPoints(34);
|
||||
} else {
|
||||
// 表头其他行
|
||||
row.setHeightInPoints(30);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
protected void setContentColumnHeight(Row row, int relativeRowIndex) {
|
||||
// 内容行
|
||||
row.setHeightInPoints(20);
|
||||
}
|
||||
})
|
||||
.sheet("人员信息")
|
||||
.doWrite(bizUserExportResultList);
|
||||
CommonDownloadUtil.download(tempFile, response);
|
||||
} catch (Exception e) {
|
||||
log.error(">>> 人员导出异常:", e);
|
||||
CommonResponseUtil.renderError(response, "导出失败");
|
||||
} finally {
|
||||
FileUtil.del(tempFile);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exportUserInfo(BizUserIdParam bizUserIdParam, HttpServletResponse response) throws IOException {
|
||||
File destTemplateFile = null;
|
||||
File resultFile = null;
|
||||
try {
|
||||
BizUser bizUser = this.queryEntity(bizUserIdParam.getId());
|
||||
transService.transOne(bizUser);
|
||||
// 读取模板流
|
||||
InputStream inputStream = POICacheManager.getFile("userExportTemplate.docx");
|
||||
// 创建一个临时模板
|
||||
destTemplateFile = FileUtil.writeFromStream(inputStream, FileUtil.file(FileUtil.getTmpDir() +
|
||||
File.separator + "userExportTemplate.docx"));
|
||||
// 构造填充的参数
|
||||
Map<String, Object> map = BeanUtil.beanToMap(bizUser);
|
||||
String avatarBase64;
|
||||
if(ObjectUtil.isNotEmpty(bizUser.getAvatar())) {
|
||||
avatarBase64 = bizUser.getAvatar();
|
||||
} else {
|
||||
avatarBase64 = CommonAvatarUtil.generateImg(bizUser.getName());
|
||||
}
|
||||
// 头像
|
||||
ImageEntity imageEntity = new ImageEntity(ImgUtil.toBytes(ImgUtil.toImage(StrUtil
|
||||
.split(avatarBase64, StrUtil.COMMA).get(1)), ImgUtil.IMAGE_TYPE_PNG), 120, 160);
|
||||
map.put("avatar", imageEntity);
|
||||
if(ObjectUtil.isNotEmpty(bizUser.getBirthday())) {
|
||||
try {
|
||||
// 年龄
|
||||
long age = cn.hutool.core.date.DateUtil.betweenYear(cn.hutool.core.date.DateUtil.parseDate(bizUser.getBirthday()), DateTime.now(), true);
|
||||
if(age != 0) {
|
||||
map.put("age", age + "岁");
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
// 导出时间
|
||||
map.put("exportDateTime", DateUtil.format(DateTime.now(), DatePattern.CHINESE_DATE_PATTERN));
|
||||
// 生成doc
|
||||
XWPFDocument doc = WordExportUtil.exportWord07(destTemplateFile.getAbsolutePath(), map);
|
||||
// 生成临时导出文件
|
||||
resultFile = FileUtil.file(FileUtil.getTmpDir() + File.separator + "SNOWY2.0系统B端人员信息_" + bizUser.getName() + ".docx");
|
||||
// 写入
|
||||
BufferedOutputStream outputStream = FileUtil.getOutputStream(resultFile);
|
||||
doc.write(outputStream);
|
||||
outputStream.close();
|
||||
// 下载
|
||||
CommonDownloadUtil.download(resultFile, response);
|
||||
} catch (Exception e) {
|
||||
log.error(">>> 导出人员个人信息异常:", e);
|
||||
CommonResponseUtil.renderError(response, "导出失败");
|
||||
} finally {
|
||||
// 删除临时文件
|
||||
if(ObjectUtil.isNotEmpty(destTemplateFile)) {
|
||||
FileUtil.del(destTemplateFile);
|
||||
}
|
||||
if(ObjectUtil.isNotEmpty(resultFile)) {
|
||||
FileUtil.del(resultFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BizUser queryEntity(String id) {
|
||||
BizUser bizUser = this.getById(id);
|
||||
if(ObjectUtil.isEmpty(bizUser)) {
|
||||
throw new CommonException("人员不存在,id值为:{}", id);
|
||||
}
|
||||
return bizUser;
|
||||
}
|
||||
|
||||
/* ====人员部分所需要用到的选择器==== */
|
||||
|
||||
@Override
|
||||
public List<Tree<String>> orgTreeSelector() {
|
||||
LambdaQueryWrapper<BizOrg> lambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||
// 校验数据范围
|
||||
List<String> loginUserDataScope = StpLoginUserUtil.getLoginUserDataScope();
|
||||
// 定义机构集合
|
||||
Set<BizOrg> bizOrgSet = CollectionUtil.newHashSet();
|
||||
if(ObjectUtil.isNotEmpty(loginUserDataScope)) {
|
||||
// 获取所有机构
|
||||
List<BizOrg> allOrgList = bizOrgService.list();
|
||||
loginUserDataScope.forEach(orgId -> bizOrgSet.addAll(bizOrgService.getParentListById(allOrgList, orgId, true)));
|
||||
List<String> loginUserDataScopeFullList = bizOrgSet.stream().map(BizOrg::getId).collect(Collectors.toList());
|
||||
lambdaQueryWrapper.in(BizOrg::getId, loginUserDataScopeFullList);
|
||||
} else {
|
||||
return CollectionUtil.newArrayList();
|
||||
}
|
||||
lambdaQueryWrapper.orderByAsc(BizOrg::getSortCode);
|
||||
List<BizOrg> bizOrgList = bizOrgService.list(lambdaQueryWrapper);
|
||||
List<TreeNode<String>> treeNodeList = bizOrgList.stream().map(bizOrg ->
|
||||
new TreeNode<>(bizOrg.getId(), bizOrg.getParentId(), bizOrg.getName(), bizOrg.getSortCode()))
|
||||
.collect(Collectors.toList());
|
||||
return TreeUtil.build(treeNodeList, "0");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<BizOrg> orgListSelector(BizUserSelectorOrgListParam bizUserSelectorOrgListParam) {
|
||||
LambdaQueryWrapper<BizOrg> lambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||
// 校验数据范围
|
||||
List<String> loginUserDataScope = StpLoginUserUtil.getLoginUserDataScope();
|
||||
if(ObjectUtil.isNotEmpty(loginUserDataScope)) {
|
||||
lambdaQueryWrapper.in(BizOrg::getId, loginUserDataScope);
|
||||
} else {
|
||||
return new Page<>();
|
||||
}
|
||||
// 查询部分字段
|
||||
lambdaQueryWrapper.select(BizOrg::getId, BizOrg::getParentId, BizOrg::getName,
|
||||
BizOrg::getCategory, BizOrg::getSortCode);
|
||||
if(ObjectUtil.isNotEmpty(bizUserSelectorOrgListParam.getParentId())) {
|
||||
lambdaQueryWrapper.eq(BizOrg::getParentId, bizUserSelectorOrgListParam.getParentId());
|
||||
}
|
||||
if(ObjectUtil.isNotEmpty(bizUserSelectorOrgListParam.getSearchKey())) {
|
||||
lambdaQueryWrapper.like(BizOrg::getName, bizUserSelectorOrgListParam.getSearchKey());
|
||||
}
|
||||
lambdaQueryWrapper.orderByAsc(BizOrg::getSortCode);
|
||||
return bizOrgService.page(CommonPageRequest.defaultPage(), lambdaQueryWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<BizPosition> positionSelector(BizUserSelectorPositionParam bizUserSelectorPositionParam) {
|
||||
LambdaQueryWrapper<BizPosition> lambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||
// 校验数据范围
|
||||
List<String> loginUserDataScope = StpLoginUserUtil.getLoginUserDataScope();
|
||||
if(ObjectUtil.isNotEmpty(loginUserDataScope)) {
|
||||
lambdaQueryWrapper.in(BizPosition::getOrgId, loginUserDataScope);
|
||||
} else {
|
||||
return new Page<>();
|
||||
}
|
||||
// 查询部分字段
|
||||
lambdaQueryWrapper.select(BizPosition::getId, BizPosition::getOrgId, BizPosition::getName,
|
||||
BizPosition::getCategory, BizPosition::getSortCode);
|
||||
if(ObjectUtil.isNotEmpty(bizUserSelectorPositionParam.getOrgId())) {
|
||||
lambdaQueryWrapper.eq(BizPosition::getOrgId, bizUserSelectorPositionParam.getOrgId());
|
||||
}
|
||||
if(ObjectUtil.isNotEmpty(bizUserSelectorPositionParam.getSearchKey())) {
|
||||
lambdaQueryWrapper.like(BizPosition::getName, bizUserSelectorPositionParam.getSearchKey());
|
||||
}
|
||||
lambdaQueryWrapper.orderByAsc(BizPosition::getSortCode);
|
||||
return bizPositionService.page(CommonPageRequest.defaultPage(), lambdaQueryWrapper);
|
||||
}
|
||||
|
||||
@SuppressWarnings("ALL")
|
||||
@Override
|
||||
public Page<BizUserRoleResult> roleSelector(BizUserSelectorRoleParam bizUserSelectorRoleParam) {
|
||||
// 校验数据范围
|
||||
List<String> loginUserDataScope = StpLoginUserUtil.getLoginUserDataScope();
|
||||
if(ObjectUtil.isNotEmpty(loginUserDataScope)) {
|
||||
if(ObjectUtil.isNotEmpty(bizUserSelectorRoleParam.getOrgId())) {
|
||||
if(loginUserDataScope.contains(bizUserSelectorRoleParam.getOrgId())) {
|
||||
return BeanUtil.toBean(sysRoleApi.roleSelector(bizUserSelectorRoleParam.getOrgId(), bizUserSelectorRoleParam.getCategory(),
|
||||
bizUserSelectorRoleParam.getSearchKey(), loginUserDataScope, true), Page.class);
|
||||
} else {
|
||||
return new Page<>();
|
||||
}
|
||||
} else {
|
||||
if (ObjectUtil.isNotEmpty(bizUserSelectorRoleParam.getCategory()) & BizRoleCategoryEnum.GLOBAL.getValue().equals(bizUserSelectorRoleParam.getCategory())) {
|
||||
// 查询系统级别的
|
||||
return BeanUtil.toBean(sysRoleApi.roleSelector(null, bizUserSelectorRoleParam.getCategory(),
|
||||
bizUserSelectorRoleParam.getSearchKey(), null, true), Page.class);
|
||||
} else {
|
||||
return BeanUtil.toBean(sysRoleApi.roleSelector(null, bizUserSelectorRoleParam.getCategory(),
|
||||
bizUserSelectorRoleParam.getSearchKey(), loginUserDataScope, true), Page.class);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return new Page<>();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<BizUser> userSelector(BizUserSelectorUserParam bizUserSelectorUserParam) {
|
||||
LambdaQueryWrapper<BizUser> lambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||
// 校验数据范围
|
||||
List<String> loginUserDataScope = StpLoginUserUtil.getLoginUserDataScope();
|
||||
if(ObjectUtil.isNotEmpty(loginUserDataScope)) {
|
||||
lambdaQueryWrapper.in(BizUser::getOrgId, loginUserDataScope);
|
||||
} else {
|
||||
return new Page<>();
|
||||
}
|
||||
// 只查询部分字段
|
||||
lambdaQueryWrapper.select(BizUser::getId, BizUser::getAvatar, BizUser::getOrgId, BizUser::getPositionId, BizUser::getAccount,
|
||||
BizUser::getName, BizUser::getSortCode, BizUser::getGender, BizUser::getEntryDate);
|
||||
if (ObjectUtil.isNotEmpty(bizUserSelectorUserParam.getOrgId())) {
|
||||
// 如果机构id不为空,则查询该机构及其子机构下的所有人
|
||||
List<String> childOrgIdList = CollStreamUtil.toList(bizOrgService.getChildListById(bizOrgService
|
||||
.getAllOrgList(), bizUserSelectorUserParam.getOrgId(), true), BizOrg::getId);
|
||||
if (ObjectUtil.isNotEmpty(childOrgIdList)) {
|
||||
lambdaQueryWrapper.in(BizUser::getOrgId, childOrgIdList);
|
||||
} else {
|
||||
return new Page<>();
|
||||
}
|
||||
}
|
||||
if(ObjectUtil.isNotEmpty(bizUserSelectorUserParam.getSearchKey())) {
|
||||
lambdaQueryWrapper.like(BizUser::getName, bizUserSelectorUserParam.getSearchKey());
|
||||
}
|
||||
lambdaQueryWrapper.orderByAsc(BizUser::getSortCode);
|
||||
return this.page(CommonPageRequest.defaultPage(), lambdaQueryWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<JSONObject> dynamicFieldConfigList() {
|
||||
String currentDataSourceId = dbsApi.getCurrentDataSourceId();
|
||||
String tableName = AnnotationUtil.getAnnotationValue(BizUser.class, TableName.class);
|
||||
return devDfcApi.getTableFieldList(currentDataSourceId, tableName);
|
||||
}
|
||||
}
|
Binary file not shown.
36
mjkf-xinke-plugin/mjkf-xinke-plugin-client/pom.xml
Normal file
36
mjkf-xinke-plugin/mjkf-xinke-plugin-client/pom.xml
Normal file
@@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>mjkf.xinke</groupId>
|
||||
<artifactId>mjkf-xinke-plugin</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>mjkf-xinke-plugin-client</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<description>C端功能插件</description>
|
||||
|
||||
<dependencies>
|
||||
<!-- 每个插件都要引入自己的对外接口 -->
|
||||
<dependency>
|
||||
<groupId>mjkf.xinke</groupId>
|
||||
<artifactId>mjkf-xinke-plugin-client-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 引入登录鉴权接口,用于实现其C端登录所需逻辑 -->
|
||||
<dependency>
|
||||
<groupId>mjkf.xinke</groupId>
|
||||
<artifactId>mjkf-xinke-plugin-auth-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 引入开发工具接口,用于配置信息 -->
|
||||
<dependency>
|
||||
<groupId>mjkf.xinke</groupId>
|
||||
<artifactId>mjkf-xinke-plugin-dev-api</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
@@ -0,0 +1,57 @@
|
||||
|
||||
package mjkf.xinke.client.core.config;
|
||||
|
||||
import com.github.xiaoymin.knife4j.spring.extension.OpenApiExtensionResolver;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import springfox.documentation.builders.ApiInfoBuilder;
|
||||
import springfox.documentation.builders.PathSelectors;
|
||||
import springfox.documentation.builders.RequestHandlerSelectors;
|
||||
import springfox.documentation.service.Contact;
|
||||
import springfox.documentation.spi.DocumentationType;
|
||||
import springfox.documentation.spring.web.plugins.Docket;
|
||||
import mjkf.xinke.common.pojo.CommonResult;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* C端相关配置
|
||||
*
|
||||
*
|
||||
* @date 2022/7/7 16:18
|
||||
**/
|
||||
@Configuration
|
||||
public class ClientConfigure {
|
||||
|
||||
@Resource
|
||||
private OpenApiExtensionResolver openApiExtensionResolver;
|
||||
|
||||
/**
|
||||
* API文档分组配置
|
||||
*
|
||||
*
|
||||
* @date 2022/7/7 16:18
|
||||
**/
|
||||
@Bean(value = "clientDocApi")
|
||||
public Docket clientDocApi() {
|
||||
return new Docket(DocumentationType.SWAGGER_2)
|
||||
.apiInfo(new ApiInfoBuilder()
|
||||
.title("C端功能CLIENT")
|
||||
.description("C端功能CLIENT")
|
||||
.termsOfServiceUrl("https://www.xiaonuo.vip")
|
||||
.contact(new Contact("SNOWY_TEAM","https://www.xiaonuo.vip", "xuyuxiang29@foxmail.com"))
|
||||
.version("2.0.0")
|
||||
.build())
|
||||
.useDefaultResponseMessages(false)
|
||||
.globalResponseMessage(RequestMethod.GET, CommonResult.responseList())
|
||||
.globalResponseMessage(RequestMethod.POST, CommonResult.responseList())
|
||||
.groupName("C端功能CLIENT")
|
||||
.select()
|
||||
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
|
||||
.apis(RequestHandlerSelectors.basePackage("mjkf.xinke.client"))
|
||||
.paths(PathSelectors.any())
|
||||
.build().extensions(openApiExtensionResolver.buildExtensions("C端功能CLIENT"));
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user