This commit is contained in:
淋雨一直走YH
2023-09-28 15:38:29 +08:00
commit 7bc57c75dc
1480 changed files with 144393 additions and 0 deletions

View File

@@ -0,0 +1,42 @@
<?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-sys</artifactId>
<packaging>jar</packaging>
<description>系统功能插件</description>
<dependencies>
<!-- 每个插件都要引入自己的对外接口 -->
<dependency>
<groupId>mjkf.xinke</groupId>
<artifactId>mjkf-xinke-plugin-sys-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-dev-api</artifactId>
</dependency>
<!-- 引入移动端接口,用于移动端菜单信息 -->
<dependency>
<groupId>mjkf.xinke</groupId>
<artifactId>mjkf-xinke-plugin-mobile-api</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,56 @@
package mjkf.xinke.sys.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 SysConfigure {
@Resource
private OpenApiExtensionResolver openApiExtensionResolver;
/**
* API文档分组配置
*
*
* @date 2022/7/7 16:18
**/
@Bean(value = "sysDocApi")
public Docket sysDocApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(new ApiInfoBuilder()
.title("系统功能SYS")
.description("系统功能SYS")
.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("系统功能SYS")
.select()
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
.apis(RequestHandlerSelectors.basePackage("mjkf.xinke.sys"))
.paths(PathSelectors.any())
.build().extensions(openApiExtensionResolver.buildExtensions("系统功能SYS"));
}
}

View File

@@ -0,0 +1,41 @@
package mjkf.xinke.sys.core.enums;
import lombok.Getter;
/**
* 系统内置的不可删除的标识枚举
*
*
* @date 2022/4/21 19:56
**/
@Getter
public enum SysBuildInEnum {
/** 超管用户账号 */
BUILD_IN_USER_ACCOUNT("superAdmin", "超管"),
/** 超管角色编码 */
BUILD_IN_ROLE_CODE("superAdmin", "超管"),
/** 系统内置系统模块编码 */
BUILD_IN_MODULE_CODE("system", "系统内置"),
/** 系统内置业务模块编码 */
BUILD_IN_MODULE_CODE_BIZ("biz", "系统内置"),
/** 系统内置单页面编码 */
BUILD_IN_SPA_CODE("system", "系统内置"),
/** 系统内置非租户菜单编码 */
BUILD_IN_NO_TEN_MENU_CODE("noten", "非租户菜单");
private final String value;
private final String name;
SysBuildInEnum(String value, String name) {
this.value = value;
this.name = name;
}
}

View File

@@ -0,0 +1,46 @@
package mjkf.xinke.sys.core.enums;
import lombok.Getter;
/**
* 系统模块数据类型枚举
*
*
* @date 2023/3/3 10:40
**/
@Getter
public enum SysDataTypeEnum {
/**
* 组织
*/
ORG("ORG"),
/**
* 职位
*/
POSITION("POSITION"),
/**
* 资源
*/
RESOURCE("RESOURCE"),
/**
* 角色
*/
ROLE("ROLE"),
/**
* 用户
*/
USER("USER");
private final String value;
SysDataTypeEnum(String value) {
this.value = value;
}
}

View File

@@ -0,0 +1,54 @@
package mjkf.xinke.sys.core.listener;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.json.JSONArray;
import org.springframework.stereotype.Component;
import mjkf.xinke.auth.core.pojo.SaBaseLoginUser;
import mjkf.xinke.auth.core.util.StpLoginUserUtil;
import mjkf.xinke.common.listener.CommonDataChangeListener;
import mjkf.xinke.sys.core.enums.SysDataTypeEnum;
import java.util.List;
/**
* 系统模块数据变化侦听器
*
*
* @date 2023/3/3 10:44
**/
@Component
public class SysDataChangeListener implements CommonDataChangeListener {
@Override
public void doAddWithDataIdList(String dataType, List<String> dataIdList) {
// 如果检测到机构增加,则将该机构加入到当前登录用户的数据范围缓存
if(dataType.equals(SysDataTypeEnum.ORG.getValue())) {
SaBaseLoginUser saBaseLoginUser = StpLoginUserUtil.getLoginUser();
saBaseLoginUser.getDataScopeList().forEach(dataScope -> dataScope.getDataScope().addAll(dataIdList));
saBaseLoginUser.setDataScopeList(saBaseLoginUser.getDataScopeList());
// 重新缓存当前登录用户信息
StpUtil.getTokenSession().set("loginUser", saBaseLoginUser);
}
}
@Override
public void doAddWithDataList(String dataType, JSONArray jsonArray) {
// 此处可做额外处理
}
@Override
public void doUpdateWithDataIdList(String dataType, List<String> dataIdList) {
// 此处可做额外处理
}
@Override
public void doUpdateWithDataList(String dataType, JSONArray jsonArray) {
// 此处可做额外处理
}
@Override
public void doDeleteWithDataIdList(String dataType, List<String> dataIdList) {
// 此处可做额外处理
}
}

View File

@@ -0,0 +1,163 @@
package mjkf.xinke.sys.modular.index.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 org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import mjkf.xinke.common.annotation.CommonLog;
import mjkf.xinke.common.pojo.CommonResult;
import mjkf.xinke.common.pojo.CommonValidList;
import mjkf.xinke.sys.modular.index.param.*;
import mjkf.xinke.sys.modular.index.result.*;
import mjkf.xinke.sys.modular.index.service.SysIndexService;
import javax.annotation.Resource;
import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import java.util.List;
/**
* 系统首页控制器
*
*
* @date 2022/9/2 10:44
*/
@Api(tags = "系统首页控制器")
@ApiSupport(author = "SNOWY_TEAM", order = 0)
@RestController
@Validated
public class SysIndexController {
@Resource
private SysIndexService sysIndexService;
/**
* 添加当前用户日程
*
*
* @date 2022/4/24 20:47
*/
@ApiOperationSupport(order = 1)
@ApiOperation("添加日程")
@CommonLog("添加日程")
@PostMapping("/sys/index/schedule/add")
public CommonResult<String> addSchedule(@RequestBody @Valid SysIndexScheduleAddParam sysIndexScheduleAddParam) {
sysIndexService.addSchedule(sysIndexScheduleAddParam);
return CommonResult.ok();
}
/**
* 删除日程
*
*
* @date 2022/4/24 20:00
*/
@ApiOperationSupport(order = 2)
@ApiOperation("删除日程")
@CommonLog("删除日程")
@PostMapping("/sys/index/schedule/deleteSchedule")
public CommonResult<String> deleteSchedule(@RequestBody @Valid @NotEmpty(message = "集合不能为空")
CommonValidList<SysIndexScheduleIdParam> sysIndexScheduleIdParamList) {
sysIndexService.deleteSchedule(sysIndexScheduleIdParamList);
return CommonResult.ok();
}
/**
* 获取当前用户日程列表
*
*
* @date 2022/4/24 20:00
*/
@ApiOperationSupport(order = 3)
@ApiOperation("获取日程列表")
@GetMapping("/sys/index/schedule/list")
public CommonResult<List<SysIndexScheduleListResult>> scheduleList(@Valid SysIndexScheduleListParam sysIndexScheduleListParam) {
return CommonResult.data(sysIndexService.scheduleList(sysIndexScheduleListParam));
}
/**
* 获取当前用户站内信列表
*
*
* @date 2022/4/24 20:00
*/
@ApiOperationSupport(order = 4)
@ApiOperation("获取当前用户站内信列表")
@GetMapping("/sys/index/message/list")
public CommonResult<List<SysIndexMessageListResult>> messageList(SysIndexMessageListParam sysIndexMessageListParam) {
return CommonResult.data(sysIndexService.messageList(sysIndexMessageListParam));
}
/**
* 获取站内信详情
*
*
* @date 2022/4/24 20:00
*/
@ApiOperationSupport(order = 5)
@ApiOperation("获取站内信详情")
@GetMapping("/sys/index/message/detail")
public CommonResult<SysIndexMessageDetailResult> messageDetail(@Valid SysIndexMessageIdParam sysIndexMessageIdParam) {
return CommonResult.data(sysIndexService.messageDetail(sysIndexMessageIdParam));
}
/**
* 站内信全部标记已读
*
* @author diantu
* @date 2023/7/10
*/
@ApiOperationSupport(order = 6)
@ApiOperation("站内信全部标记已读")
@PostMapping("/sys/index/message/allMessageMarkRead")
public CommonResult<String> allMessageMarkRead() {
sysIndexService.allMessageMarkRead();
return CommonResult.ok();
}
/**
* 获取当前用户访问日志列表
*
*
* @date 2022/4/24 20:00
*/
@ApiOperationSupport(order = 7)
@ApiOperation("获取当前用户访问日志列表")
@GetMapping("/sys/index/visLog/list")
public CommonResult<List<SysIndexVisLogListResult>> visLogList() {
return CommonResult.data(sysIndexService.visLogList());
}
/**
* 获取当前用户操作日志列表
*
*
* @date 2022/4/24 20:00
*/
@ApiOperationSupport(order = 8)
@ApiOperation("获取当前用户操作日志列表")
@GetMapping("/sys/index/opLog/list")
public CommonResult<List<SysIndexOpLogListResult>> opLogList() {
return CommonResult.data(sysIndexService.opLogList());
}
/**
* 创建sse连接
*
* @author diantu
* @date 2023/7/10
**/
@ApiOperationSupport(order = 9)
@ApiOperation("创建sse连接")
@GetMapping("/dev/message/createSseConnect")
public SseEmitter createSseConnect(String clientId){
return sysIndexService.createSseConnect(clientId);
}
}

View File

@@ -0,0 +1,24 @@
package mjkf.xinke.sys.modular.index.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import javax.validation.constraints.NotBlank;
/**
* 站内信Id参数
*
*
* @date 2022/9/2 11:06
*/
@Getter
@Setter
public class SysIndexMessageIdParam {
/** id */
@ApiModelProperty(value = "id", required = true)
@NotBlank(message = "id不能为空")
private String id;
}

View File

@@ -0,0 +1,21 @@
package mjkf.xinke.sys.modular.index.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
/**
* 站内信列表参数
*
*
* @date 2022/6/21 15:34
**/
@Getter
@Setter
public class SysIndexMessageListParam {
/** 条数" */
@ApiModelProperty(value = "条数")
private Integer limit;
}

View File

@@ -0,0 +1,42 @@
package mjkf.xinke.sys.modular.index.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import javax.validation.constraints.NotBlank;
/**
* 日程添加参数
*
*
* @date 2022/9/2 11:06
*/
@Getter
@Setter
public class SysIndexScheduleAddParam {
/** 日程日期 */
@ApiModelProperty(value = "日程日期", required = true, position = 1)
@NotBlank(message = "scheduleDate不能为空")
private String scheduleDate;
/** 日程时间 */
@ApiModelProperty(value = "日程时间", required = true, position = 2)
@NotBlank(message = "scheduleTime不能为空")
private String scheduleTime;
/** 日程内容 */
@ApiModelProperty(value = "日程内容", required = true, position = 3)
@NotBlank(message = "scheduleContent不能为空")
private String scheduleContent;
/** 用户id */
@ApiModelProperty(value = "用户id", hidden = true, position = 4)
private String scheduleUserId;
/** 用户姓名 */
@ApiModelProperty(value = "用户姓名", hidden = true, position = 5)
private String scheduleUserName;
}

View File

@@ -0,0 +1,24 @@
package mjkf.xinke.sys.modular.index.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import javax.validation.constraints.NotBlank;
/**
* 日程Id参数
*
*
* @date 2022/9/2 11:06
*/
@Getter
@Setter
public class SysIndexScheduleIdParam {
/** 日程id */
@ApiModelProperty(value = "id", required = true)
@NotBlank(message = "id不能为空")
private String id;
}

View File

@@ -0,0 +1,24 @@
package mjkf.xinke.sys.modular.index.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import javax.validation.constraints.NotBlank;
/**
* 日程列表查询参数
*
*
* @date 2022/9/2 11:06
*/
@Getter
@Setter
public class SysIndexScheduleListParam {
/** 日程日期 */
@ApiModelProperty(value = "日程日期", required = true)
@NotBlank(message = "scheduleDate不能为空")
private String scheduleDate;
}

View File

@@ -0,0 +1,66 @@
package mjkf.xinke.sys.modular.index.result;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
/**
* 站内信详情结果
*
*
* @date 2022/7/31 16:39
*/
@Getter
@Setter
public class SysIndexMessageDetailResult {
/** id */
@ApiModelProperty(value = "主键", position = 1)
private String id;
/** 分类 */
@ApiModelProperty(value = "分类", position = 2)
private String category;
/** 主题 */
@ApiModelProperty(value = "主题", position = 3)
private String subject;
/** 正文 */
@ApiModelProperty(value = "正文", position = 4)
private String content;
/** 扩展信息 */
@ApiModelProperty(value = "扩展信息", position = 5)
private String extJson;
/** 接收信息集合 */
@ApiModelProperty(value = "接收信息集合", position = 6)
private List<DevReceiveInfo> receiveInfoList;
/**
* 接收信息类
*
*
* @date 2022/7/31 16:42
*/
@Getter
@Setter
public static class DevReceiveInfo {
/** 接收人ID */
@ApiModelProperty(value = "接收人ID", position = 1)
private String receiveUserId;
/** 接收人姓名 */
@ApiModelProperty(value = "接收人姓名", position = 2)
private String receiveUserName;
/** 是否已读 */
@ApiModelProperty(value = "是否已读", position = 3)
private Boolean read;
}
}

View File

@@ -0,0 +1,55 @@
package mjkf.xinke.sys.modular.index.result;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import java.util.Date;
/**
* 站内信列表结果
*
*
* @date 2022/7/31 16:39
*/
@Getter
@Setter
public class SysIndexMessageListResult {
/** id */
@ApiModelProperty(value = "主键", position = 1)
private String id;
/** 分类 */
@ApiModelProperty(value = "分类", position = 2)
private String category;
/** 主题 */
@ApiModelProperty(value = "主题", position = 3)
private String subject;
/** 正文 */
@ApiModelProperty(value = "正文", position = 4)
private String content;
/** 扩展信息 */
@ApiModelProperty(value = "扩展信息", position = 5)
private String extJson;
/** 创建时间 */
@ApiModelProperty(value = "创建时间", position = 6)
private Date createTime;
/** 创建人 */
@ApiModelProperty(value = "创建人", position = 7)
private String createUser;
/** 更新时间 */
@ApiModelProperty(value = "更新时间", position = 8)
private Date updateTime;
/** 更新人 */
@ApiModelProperty(value = "更新人", position = 9)
private String updateUser;
}

View File

@@ -0,0 +1,117 @@
package mjkf.xinke.sys.modular.index.result;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import java.util.Date;
/**
* 操作日志结果
*
*
* @date 2022/9/2 15:02
*/
@Getter
@Setter
public class SysIndexOpLogListResult {
/** id */
@ApiModelProperty(value = "主键", position = 1)
private String id;
/** 租户id */
@ApiModelProperty(value = "租户id", position = 2)
private String tenantId;
/** 日志分类 */
@ApiModelProperty(value = "日志分类", position = 3)
private String category;
/** 日志名称 */
@ApiModelProperty(value = "日志名称", position = 4)
private String name;
/** 执行状态 */
@ApiModelProperty(value = "执行状态", position = 5)
private String exeStatus;
/** 具体消息 */
@ApiModelProperty(value = "具体消息", position = 6)
private String exeMessage;
/** 操作ip */
@ApiModelProperty(value = "操作ip", position = 7)
private String opIp;
/** 操作地址 */
@ApiModelProperty(value = "操作地址", position = 8)
private String opAddress;
/** 操作浏览器 */
@ApiModelProperty(value = "操作浏览器", position = 9)
private String opBrowser;
/** 操作系统 */
@ApiModelProperty(value = "操作系统", position = 10)
private String opOs;
/** 类名称 */
@ApiModelProperty(value = "类名称", position = 11)
private String className;
/** 方法名称 */
@ApiModelProperty(value = "方法名称", position = 12)
private String methodName;
/** 请求方式 */
@ApiModelProperty(value = "请求方式", position = 13)
private String reqMethod;
/** 请求地址 */
@ApiModelProperty(value = "请求地址", position = 14)
private String reqUrl;
/** 请求参数 */
@ApiModelProperty(value = "请求参数", position = 15)
private String paramJson;
/** 返回结果 */
@ApiModelProperty(value = "返回结果", position = 16)
private String resultJson;
/** 操作时间 */
@ApiModelProperty(value = "操作时间", position = 17)
private Date opTime;
/** 操作人姓名 */
@ApiModelProperty(value = "操作人姓名", position = 18)
private String opUser;
/** 签名数据 */
@ApiModelProperty(value = "签名数据", position = 19)
private String signData;
/** 创建时间 */
@ApiModelProperty(value = "创建时间", position = 20)
@TableField(fill = FieldFill.INSERT)
private Date createTime;
/** 创建人 */
@ApiModelProperty(value = "创建人", position = 21)
@TableField(fill = FieldFill.INSERT)
private String createUser;
/** 更新时间 */
@ApiModelProperty(value = "更新时间", position = 22)
@TableField(fill = FieldFill.UPDATE)
private Date updateTime;
/** 更新人 */
@ApiModelProperty(value = "更新人", position = 23)
@TableField(fill = FieldFill.UPDATE)
private String updateUser;
}

View File

@@ -0,0 +1,41 @@
package mjkf.xinke.sys.modular.index.result;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
/**
* 日程列表结果
*
*
* @date 2022/9/2 11:21
*/
@Getter
@Setter
public class SysIndexScheduleListResult {
/** id */
@ApiModelProperty(value = "主键", position = 1)
private String id;
/** 用户id */
@ApiModelProperty(value = "用户id", position = 2)
private String scheduleUserId;
/** 用户姓名 */
@ApiModelProperty(value = "用户姓名", position = 3)
private String scheduleUserName;
/** 日程日期 */
@ApiModelProperty(value = "日程日期", position = 4)
private String scheduleDate;
/** 日程时间 */
@ApiModelProperty(value = "日程时间", position = 5)
private String scheduleTime;
/** 日程内容 */
@ApiModelProperty(value = "日程内容", position = 6)
private String scheduleContent;
}

View File

@@ -0,0 +1,93 @@
package mjkf.xinke.sys.modular.index.result;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import java.util.Date;
/**
* 访问日志结果
*
*
* @date 2022/9/2 15:02
*/
@Getter
@Setter
public class SysIndexVisLogListResult {
/** id */
@ApiModelProperty(value = "主键", position = 1)
private String id;
/** 租户id */
@ApiModelProperty(value = "租户id", position = 2)
private String tenantId;
/** 日志分类 */
@ApiModelProperty(value = "日志分类", position = 3)
private String category;
/** 日志名称 */
@ApiModelProperty(value = "日志名称", position = 4)
private String name;
/** 执行状态 */
@ApiModelProperty(value = "执行状态", position = 5)
private String exeStatus;
/** 具体消息 */
@ApiModelProperty(value = "具体消息", position = 6)
private String exeMessage;
/** 操作ip */
@ApiModelProperty(value = "操作ip", position = 7)
private String opIp;
/** 操作地址 */
@ApiModelProperty(value = "操作地址", position = 8)
private String opAddress;
/** 操作浏览器 */
@ApiModelProperty(value = "操作浏览器", position = 9)
private String opBrowser;
/** 操作系统 */
@ApiModelProperty(value = "操作系统", position = 10)
private String opOs;
/** 操作时间 */
@ApiModelProperty(value = "操作时间", position = 11)
private Date opTime;
/** 操作人姓名 */
@ApiModelProperty(value = "操作人姓名", position = 12)
private String opUser;
/** 签名数据 */
@ApiModelProperty(value = "签名数据", position = 13)
private String signData;
/** 创建时间 */
@ApiModelProperty(value = "创建时间", position = 14)
@TableField(fill = FieldFill.INSERT)
private Date createTime;
/** 创建人 */
@ApiModelProperty(value = "创建人", position = 15)
@TableField(fill = FieldFill.INSERT)
private String createUser;
/** 更新时间 */
@ApiModelProperty(value = "更新时间", position = 16)
@TableField(fill = FieldFill.UPDATE)
private Date updateTime;
/** 更新人 */
@ApiModelProperty(value = "更新人", position = 17)
@TableField(fill = FieldFill.UPDATE)
private String updateUser;
}

View File

@@ -0,0 +1,90 @@
package mjkf.xinke.sys.modular.index.service;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import mjkf.xinke.common.pojo.CommonValidList;
import mjkf.xinke.sys.modular.index.param.*;
import mjkf.xinke.sys.modular.index.result.*;
import java.util.List;
/**
* 系统首页Service接口
*
*
* @date 2022/9/2 10:45
*/
public interface SysIndexService {
/**
* 添加当前用户日程
*
*
* @date 2022/9/2 11:13
*/
void addSchedule(SysIndexScheduleAddParam sysIndexScheduleAddParam);
/**
* 删除日程
*
*
* @date 2022/9/2 11:32
*/
void deleteSchedule(CommonValidList<SysIndexScheduleIdParam> sysIndexScheduleIdParamList);
/**
* 获取当前用户日程列表
*
*
* @date 2022/9/2 11:23
*/
List<SysIndexScheduleListResult> scheduleList(SysIndexScheduleListParam sysIndexScheduleListParam);
/**
* 获取当前用户站内信列表
*
*
* @date 2022/9/2 11:36
*/
List<SysIndexMessageListResult> messageList(SysIndexMessageListParam sysIndexMessageListParam);
/**
* 获取站内信详情
*
*
* @date 2022/9/2 11:44
*/
SysIndexMessageDetailResult messageDetail(SysIndexMessageIdParam sysIndexMessageIdParam);
/**
* 站内信全部标记已读
*
* @author diantu
* @date 2023/7/10
*/
void allMessageMarkRead();
/**
* 获取当前用户访问日志列表
*
*
* @date 2022/9/4 15:11
*/
List<SysIndexVisLogListResult> visLogList();
/**
* 获取当前用户操作日志列表
*
*
* @date 2022/9/4 15:11
*/
List<SysIndexOpLogListResult> opLogList();
/**
* 创建连接
*
* @author diantu
* @date 2023/7/10
**/
public SseEmitter createSseConnect(String clientId);
}

View File

@@ -0,0 +1,119 @@
package mjkf.xinke.sys.modular.index.service.impl;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.stereotype.Service;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import mjkf.xinke.auth.core.pojo.SaBaseLoginUser;
import mjkf.xinke.auth.core.util.StpLoginUserUtil;
import mjkf.xinke.common.pojo.CommonValidList;
import mjkf.xinke.common.sse.CommonSseParam;
import mjkf.xinke.dev.api.DevLogApi;
import mjkf.xinke.dev.api.DevMessageApi;
import mjkf.xinke.dev.api.DevSseApi;
import mjkf.xinke.sys.modular.index.param.*;
import mjkf.xinke.sys.modular.index.result.*;
import mjkf.xinke.sys.modular.index.service.SysIndexService;
import mjkf.xinke.sys.modular.relation.entity.SysRelation;
import mjkf.xinke.sys.modular.relation.enums.SysRelationCategoryEnum;
import mjkf.xinke.sys.modular.relation.service.SysRelationService;
import javax.annotation.Resource;
import java.util.List;
import java.util.function.Consumer;
import java.util.stream.Collectors;
/**
* 系统首页Service接口实现类
*
*
* @date 2022/9/2 10:45
*/
@Service
public class SysIndexServiceImpl implements SysIndexService {
@Resource
private SysRelationService sysRelationService;
@Resource
private DevMessageApi devMessageApi;
@Resource
private DevLogApi devLogApi;
@Resource
private DevSseApi devSseApi;
@Override
public void addSchedule(SysIndexScheduleAddParam sysIndexScheduleAddParam) {
SaBaseLoginUser loginUser = StpLoginUserUtil.getLoginUser();
sysIndexScheduleAddParam.setScheduleUserId(loginUser.getId());
sysIndexScheduleAddParam.setScheduleUserName(loginUser.getName());
sysRelationService.saveRelationWithAppend(loginUser.getId(), sysIndexScheduleAddParam.getScheduleDate(),
SysRelationCategoryEnum.SYS_USER_SCHEDULE_DATA.getValue(), JSONUtil.toJsonStr(sysIndexScheduleAddParam));
}
@Override
public void deleteSchedule(CommonValidList<SysIndexScheduleIdParam> sysIndexScheduleIdParamList) {
List<String> scheduleIdList = sysIndexScheduleIdParamList.stream().map(SysIndexScheduleIdParam::getId)
.collect(Collectors.toList());
if(ObjectUtil.isNotEmpty(scheduleIdList)) {
sysRelationService.removeByIds(scheduleIdList);
}
}
@Override
public List<SysIndexScheduleListResult> scheduleList(SysIndexScheduleListParam sysIndexScheduleListParam) {
return sysRelationService.list(new LambdaQueryWrapper<SysRelation>().eq(SysRelation::getObjectId, StpUtil.getLoginIdAsString())
.eq(SysRelation::getTargetId, sysIndexScheduleListParam.getScheduleDate())
.eq(SysRelation::getCategory, SysRelationCategoryEnum.SYS_USER_SCHEDULE_DATA.getValue()))
.stream().map(sysRelation -> {
SysIndexScheduleListResult sysIndexScheduleListResult = JSONUtil.toBean(sysRelation.getExtJson(), SysIndexScheduleListResult.class);
sysIndexScheduleListResult.setId(sysRelation.getId());
return sysIndexScheduleListResult;
}).collect(Collectors.toList());
}
@Override
public List<SysIndexMessageListResult> messageList(SysIndexMessageListParam sysIndexMessageListParam) {
return devMessageApi.list(CollectionUtil.newArrayList(StpUtil.getLoginIdAsString()),
ObjectUtil.isEmpty(sysIndexMessageListParam.getLimit())?10:sysIndexMessageListParam.getLimit()).stream()
.map(jsonObject -> JSONUtil.toBean(jsonObject, SysIndexMessageListResult.class)).collect(Collectors.toList());
}
@Override
public SysIndexMessageDetailResult messageDetail(SysIndexMessageIdParam sysIndexMessageIdParam) {
return JSONUtil.toBean(devMessageApi.detail(sysIndexMessageIdParam.getId()), SysIndexMessageDetailResult.class);
}
@Override
public void allMessageMarkRead(){
devMessageApi.allMessageMarkRead();
}
@Override
public List<SysIndexVisLogListResult> visLogList() {
return devLogApi.currentUserVisLogList().stream()
.map(jsonObject -> JSONUtil.toBean(jsonObject, SysIndexVisLogListResult.class)).collect(Collectors.toList());
}
@Override
public List<SysIndexOpLogListResult> opLogList() {
return devLogApi.currentUserOpLogList().stream()
.map(jsonObject -> JSONUtil.toBean(jsonObject, SysIndexOpLogListResult.class)).collect(Collectors.toList());
}
@Override
public SseEmitter createSseConnect(String clientId){
Consumer<CommonSseParam> consumer = m -> {
//获取用户未读消息
long unreadMessageNum = devMessageApi.unreadCount(m.getLoginId());
//发送消息
devSseApi.sendMessageToOneClient(m.getClientId(), String.valueOf(unreadMessageNum));
};
return devSseApi.createSseConnect(clientId,true,false,consumer);
}
}

View File

@@ -0,0 +1,155 @@
package mjkf.xinke.sys.modular.org.controller;
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.common.annotation.CommonLog;
import mjkf.xinke.common.pojo.CommonResult;
import mjkf.xinke.common.pojo.CommonValidList;
import mjkf.xinke.sys.modular.org.entity.SysOrg;
import mjkf.xinke.sys.modular.org.param.*;
import mjkf.xinke.sys.modular.org.service.SysOrgService;
import mjkf.xinke.sys.modular.user.entity.SysUser;
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 SysOrgController {
@Resource
private SysOrgService sysOrgService;
/**
* 获取组织分页
*
*
* @date 2022/4/24 20:00
*/
@ApiOperationSupport(order = 1)
@ApiOperation("获取组织分页")
@GetMapping("/sys/org/page")
public CommonResult<Page<SysOrg>> page(SysOrgPageParam sysOrgPageParam) {
return CommonResult.data(sysOrgService.page(sysOrgPageParam));
}
/**
* 获取组织树
*
*
* @date 2022/4/24 20:00
*/
@ApiOperationSupport(order = 2)
@ApiOperation("获取组织树")
@GetMapping("/sys/org/tree")
public CommonResult<List<Tree<String>>> tree() {
return CommonResult.data(sysOrgService.tree());
}
/**
* 添加组织
*
*
* @date 2022/4/24 20:47
*/
@ApiOperationSupport(order = 3)
@ApiOperation("添加组织")
@CommonLog("添加组织")
@PostMapping("/sys/org/add")
public CommonResult<String> add(@RequestBody @Valid SysOrgAddParam sysOrgAddParam) {
sysOrgService.add(sysOrgAddParam);
return CommonResult.ok();
}
/**
* 编辑组织
*
*
* @date 2022/4/24 20:47
*/
@ApiOperationSupport(order = 4)
@ApiOperation("编辑组织")
@CommonLog("编辑组织")
@PostMapping("/sys/org/edit")
public CommonResult<String> edit(@RequestBody @Valid SysOrgEditParam sysOrgEditParam) {
sysOrgService.edit(sysOrgEditParam);
return CommonResult.ok();
}
/**
* 删除组织
*
*
* @date 2022/4/24 20:00
*/
@ApiOperationSupport(order = 5)
@ApiOperation("删除组织")
@CommonLog("删除组织")
@PostMapping("/sys/org/delete")
public CommonResult<String> delete(@RequestBody @Valid @NotEmpty(message = "集合不能为空")
CommonValidList<SysOrgIdParam> sysOrgIdParamList) {
sysOrgService.delete(sysOrgIdParamList);
return CommonResult.ok();
}
/**
* 获取组织详情
*
*
* @date 2022/4/24 20:00
*/
@ApiOperationSupport(order = 6)
@ApiOperation("获取组织详情")
@GetMapping("/sys/org/detail")
public CommonResult<SysOrg> detail(@Valid SysOrgIdParam sysOrgIdParam) {
return CommonResult.data(sysOrgService.detail(sysOrgIdParam));
}
/* ====组织部分所需要用到的选择器==== */
/**
* 获取组织树选择器
*
*
* @date 2022/4/24 20:00
*/
@ApiOperationSupport(order = 7)
@ApiOperation("获取组织树选择器")
@GetMapping("/sys/org/orgTreeSelector")
public CommonResult<List<Tree<String>>> orgTreeSelector() {
return CommonResult.data(sysOrgService.orgTreeSelector());
}
/**
* 获取用户选择器
*
*
* @date 2022/4/24 20:00
*/
@ApiOperationSupport(order = 8)
@ApiOperation("获取用户选择器")
@GetMapping("/sys/org/userSelector")
public CommonResult<Page<SysUser>> userSelector(SysOrgSelectorUserParam sysOrgSelectorUserParam) {
return CommonResult.data(sysOrgService.userSelector(sysOrgSelectorUserParam));
}
}

View File

@@ -0,0 +1,65 @@
package mjkf.xinke.sys.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.common.pojo.CommonEntity;
import mjkf.xinke.sys.modular.user.entity.SysUser;
/**
* 组织实体
*
*
* @date 2022/4/21 16:13
**/
@Getter
@Setter
@TableName("SYS_ORG")
public class SysOrg 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 = SysUser.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;
}

View File

@@ -0,0 +1,34 @@
package mjkf.xinke.sys.modular.org.enums;
import lombok.Getter;
import mjkf.xinke.common.exception.CommonException;
/**
* 组织分类枚举
*
*
* @date 2022/4/21 19:56
**/
@Getter
public enum SysOrgCategoryEnum {
/** 公司 */
COMPANY("COMPANY"),
/** 部门 */
DEPT("DEPT");
private final String value;
SysOrgCategoryEnum(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);
}
}
}

View File

@@ -0,0 +1,14 @@
package mjkf.xinke.sys.modular.org.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import mjkf.xinke.sys.modular.org.entity.SysOrg;
/**
* 组织Mapper接口
*
*
* @date 2022/4/21 18:37
**/
public interface SysOrgMapper extends BaseMapper<SysOrg> {
}

View File

@@ -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.sys.modular.org.mapper.SysOrgMapper">
</mapper>

View File

@@ -0,0 +1,48 @@
package mjkf.xinke.sys.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 SysOrgAddParam {
/** 父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;
}

View File

@@ -0,0 +1,53 @@
package mjkf.xinke.sys.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 SysOrgEditParam {
/** 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;
}

View File

@@ -0,0 +1,24 @@
package mjkf.xinke.sys.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 SysOrgIdParam {
/** id */
@ApiModelProperty(value = "id", required = true)
@NotBlank(message = "id不能为空")
private String id;
}

View File

@@ -0,0 +1,41 @@
package mjkf.xinke.sys.modular.org.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
/**
* 组织查询参数
*
*
* @date 2022/4/21 16:13
**/
@Getter
@Setter
public class SysOrgPageParam {
/** 当前页 */
@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;
}

View File

@@ -0,0 +1,33 @@
package mjkf.xinke.sys.modular.org.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
/**
* 组织列表选择器参数
*
*
* @date 2022/4/21 16:13
**/
@Getter
@Setter
public class SysOrgSelectorOrgListParam {
/** 当前页 */
@ApiModelProperty(value = "当前页码")
private Integer current;
/** 每页条数 */
@ApiModelProperty(value = "每页条数")
private Integer size;
/** 父id */
@ApiModelProperty(value = "父id")
private String parentId;
/** 名称关键词 */
@ApiModelProperty(value = "名称关键词")
private String searchKey;
}

View File

@@ -0,0 +1,33 @@
package mjkf.xinke.sys.modular.org.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
/**
* 用户选择器参数
*
*
* @date 2022/4/21 16:13
**/
@Getter
@Setter
public class SysOrgSelectorUserParam {
/** 当前页 */
@ApiModelProperty(value = "当前页码")
private Integer current;
/** 每页条数 */
@ApiModelProperty(value = "每页条数")
private Integer size;
/** 组织id */
@ApiModelProperty(value = "组织id")
private String orgId;
/** 姓名关键词 */
@ApiModelProperty(value = "姓名关键词")
private String searchKey;
}

View File

@@ -0,0 +1,57 @@
package mjkf.xinke.sys.modular.org.provider;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.util.ObjectUtil;
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.sys.api.SysOrgApi;
import mjkf.xinke.sys.modular.org.entity.SysOrg;
import mjkf.xinke.sys.modular.org.param.SysOrgSelectorOrgListParam;
import mjkf.xinke.sys.modular.org.service.SysOrgService;
import javax.annotation.Resource;
import java.util.List;
/**
* 组织API接口提供者
*
*
* @date 2022/7/22 14:56
**/
@Service
public class SysOrgApiProvider implements SysOrgApi {
@Resource
private SysOrgService sysOrgService;
@Override
public String getNameById(String orgId) {
return sysOrgService.queryEntity(orgId).getName();
}
@Override
public String getSupervisorIdByOrgId(String orgId) {
SysOrg sysOrg = sysOrgService.getById(orgId);
if(ObjectUtil.isNotEmpty(sysOrg)) {
return sysOrg.getDirectorId();
}
return null;
}
@Override
public List<Tree<String>> orgTreeSelector() {
return sysOrgService.orgTreeSelector();
}
@SuppressWarnings("ALL")
@Override
public Page<JSONObject> orgListSelector(String parentId) {
SysOrgSelectorOrgListParam sysOrgSelectorOrgListParam = new SysOrgSelectorOrgListParam();
sysOrgSelectorOrgListParam.setParentId(parentId);
return BeanUtil.toBean(sysOrgService.orgListSelector(sysOrgSelectorOrgListParam), Page.class);
}
}

View File

@@ -0,0 +1,164 @@
package mjkf.xinke.sys.modular.org.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.sys.modular.org.entity.SysOrg;
import mjkf.xinke.sys.modular.org.param.*;
import mjkf.xinke.sys.modular.user.entity.SysUser;
import java.util.List;
/**
* 组织Service接口
*
*
* @date 2022/4/21 18:35
**/
public interface SysOrgService extends IService<SysOrg> {
/**
* 获取组织分页
*
*
* @date 2022/4/24 20:08
*/
Page<SysOrg> page(SysOrgPageParam sysOrgPageParam);
/**
* 获取组织树
*
*
* @date 2022/4/24 20:08
*/
List<Tree<String>> tree();
/**
* 添加组织
*
*
* @date 2022/4/24 20:48
*/
void add(SysOrgAddParam sysOrgAddParam);
/**
* 编辑组织
*
*
* @date 2022/4/24 21:13
*/
void edit(SysOrgEditParam sysOrgEditParam);
/**
* 删除组织
*
*
* @date 2022/4/24 21:18
*/
void delete(List<SysOrgIdParam> sysOrgIdParamList);
/**
* 获取组织详情
*
*
* @date 2022/4/24 21:18
*/
SysOrg detail(SysOrgIdParam sysOrgIdParam);
/**
* 获取组织详情
*
*
* @date 2022/7/25 19:42
**/
SysOrg queryEntity(String id);
/**
* 获取所有组织
*
*
* @date 2022/7/25 19:42
**/
List<SysOrg> getAllOrgList();
/**
* 根据组织全名称获取组织id有则返回无则创建
*
*
* @date 2023/3/7 15:44
**/
String getOrgIdByOrgFullNameWithCreate(String orgFullName);
/**
* 根据id获取父子数据列表
*
*
* @date 2022/8/15 14:55
**/
List<SysOrg> getParentAndChildListById(List<SysOrg> originDataList, String id, boolean includeSelf);
/**
* 根据id获取所有的子数据列表
*
*
* @date 2022/8/15 14:55
**/
List<SysOrg> getChildListById(List<SysOrg> originDataList, String id, boolean includeSelf);
/**
* 根据id获取所有的父数据列表
*
*
* @date 2022/8/15 14:55
**/
List<SysOrg> getParentListById(List<SysOrg> originDataList, String id, boolean includeSelf);
/**
* 根据id获取数据
*
*
* @date 2022/8/15 14:55
**/
SysOrg getById(List<SysOrg> originDataList, String id);
/**
* 根据id获取父数据
*
*
* @date 2022/8/15 14:55
**/
SysOrg getParentById(List<SysOrg> originDataList, String id);
/**
* 根据id获取子数据
*
*
* @date 2022/8/15 14:55
**/
SysOrg getChildById(List<SysOrg> originDataList, String id);
/**
* 获取组织树选择器
*
*
* @date 2022/4/24 20:08
*/
List<Tree<String>> orgTreeSelector();
/**
* 获取组织列表选择器
*
*
* @date 2022/7/22 13:34
**/
Page<SysOrg> orgListSelector(SysOrgSelectorOrgListParam sysOrgSelectorOrgListParam);
/**
* 获取用户选择器
*
*
* @date 2022/4/24 20:08
*/
Page<SysUser> userSelector(SysOrgSelectorUserParam sysOrgSelectorUserParam);
}

View File

@@ -0,0 +1,377 @@
package mjkf.xinke.sys.modular.org.service.impl;
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.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.common.enums.CommonSortOrderEnum;
import mjkf.xinke.common.exception.CommonException;
import mjkf.xinke.common.listener.CommonDataChangeEventCenter;
import mjkf.xinke.common.page.CommonPageRequest;
import mjkf.xinke.sys.core.enums.SysDataTypeEnum;
import mjkf.xinke.sys.modular.org.entity.SysOrg;
import mjkf.xinke.sys.modular.org.enums.SysOrgCategoryEnum;
import mjkf.xinke.sys.modular.org.mapper.SysOrgMapper;
import mjkf.xinke.sys.modular.org.param.*;
import mjkf.xinke.sys.modular.org.service.SysOrgService;
import mjkf.xinke.sys.modular.position.entity.SysPosition;
import mjkf.xinke.sys.modular.position.service.SysPositionService;
import mjkf.xinke.sys.modular.role.entity.SysRole;
import mjkf.xinke.sys.modular.role.service.SysRoleService;
import mjkf.xinke.sys.modular.user.entity.SysUser;
import mjkf.xinke.sys.modular.user.service.SysUserService;
import javax.annotation.Resource;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;
/**
* 组织Service接口实现类
*
*
* @date 2022/2/23 18:43
**/
@Service
public class SysOrgServiceImpl extends ServiceImpl<SysOrgMapper, SysOrg> implements SysOrgService {
@Resource
private SysRoleService sysRoleService;
@Resource
private SysPositionService sysPositionService;
@Resource
private SysUserService sysUserService;
@Override
public Page<SysOrg> page(SysOrgPageParam sysOrgPageParam) {
QueryWrapper<SysOrg> queryWrapper = new QueryWrapper<>();
// 查询部分字段
queryWrapper.lambda().select(SysOrg::getId, SysOrg::getParentId, SysOrg::getName,
SysOrg::getCategory, SysOrg::getSortCode);
if(ObjectUtil.isNotEmpty(sysOrgPageParam.getParentId())) {
queryWrapper.lambda().eq(SysOrg::getParentId, sysOrgPageParam.getParentId());
}
if(ObjectUtil.isNotEmpty(sysOrgPageParam.getSearchKey())) {
queryWrapper.lambda().like(SysOrg::getName, sysOrgPageParam.getSearchKey());
}
if(ObjectUtil.isAllNotEmpty(sysOrgPageParam.getSortField(), sysOrgPageParam.getSortOrder())) {
CommonSortOrderEnum.validate(sysOrgPageParam.getSortOrder());
queryWrapper.orderBy(true, sysOrgPageParam.getSortOrder().equals(CommonSortOrderEnum.ASC.getValue()),
StrUtil.toUnderlineCase(sysOrgPageParam.getSortField()));
} else {
queryWrapper.lambda().orderByAsc(SysOrg::getSortCode);
}
return this.page(CommonPageRequest.defaultPage(), queryWrapper);
}
@Override
public List<Tree<String>> tree() {
List<SysOrg> sysOrgList = this.getAllOrgList();
List<TreeNode<String>> treeNodeList = sysOrgList.stream().map(sysOrg ->
new TreeNode<>(sysOrg.getId(), sysOrg.getParentId(),
sysOrg.getName(), sysOrg.getSortCode()).setExtra(JSONUtil.parseObj(sysOrg)))
.collect(Collectors.toList());
return TreeUtil.build(treeNodeList, "0");
}
@Transactional(rollbackFor = Exception.class)
@Override
public void add(SysOrgAddParam sysOrgAddParam) {
SysOrgCategoryEnum.validate(sysOrgAddParam.getCategory());
SysOrg sysOrg = BeanUtil.toBean(sysOrgAddParam, SysOrg.class);
// 重复名称
boolean repeatName = this.count(new LambdaQueryWrapper<SysOrg>().eq(SysOrg::getParentId, sysOrg.getParentId())
.eq(SysOrg::getName, sysOrg.getName())) > 0;
if(repeatName) {
throw new CommonException("存在重复的同级组织,名称为:{}", sysOrg.getName());
}
sysOrg.setCode(RandomUtil.randomString(10));
this.save(sysOrg);
// 发布增加事件
CommonDataChangeEventCenter.doAddWithData(SysDataTypeEnum.ORG.getValue(), JSONUtil.createArray().put(sysOrg));
}
@Transactional(rollbackFor = Exception.class)
@Override
public void edit(SysOrgEditParam sysOrgEditParam) {
SysOrgCategoryEnum.validate(sysOrgEditParam.getCategory());
SysOrg sysOrg = this.queryEntity(sysOrgEditParam.getId());
BeanUtil.copyProperties(sysOrgEditParam, sysOrg);
boolean repeatName = this.count(new LambdaQueryWrapper<SysOrg>().eq(SysOrg::getParentId, sysOrg.getParentId())
.eq(SysOrg::getName, sysOrg.getName()).ne(SysOrg::getId, sysOrg.getId())) > 0;
if(repeatName) {
throw new CommonException("存在重复的同级组织,名称为:{}", sysOrg.getName());
}
List<SysOrg> originDataList = this.getAllOrgList();
boolean errorLevel = this.getChildListById(originDataList, sysOrg.getId(), true).stream()
.map(SysOrg::getId).collect(Collectors.toList()).contains(sysOrg.getParentId());
if(errorLevel) {
throw new CommonException("不可选择上级组织:{}", this.getById(originDataList, sysOrg.getParentId()).getName());
}
this.updateById(sysOrg);
// 发布更新事件
CommonDataChangeEventCenter.doUpdateWithData(SysDataTypeEnum.ORG.getValue(), JSONUtil.createArray().put(sysOrg));
}
@Transactional(rollbackFor = Exception.class)
@Override
public void delete(List<SysOrgIdParam> sysOrgIdParamList) {
List<String> orgIdList = CollStreamUtil.toList(sysOrgIdParamList, SysOrgIdParam::getId);
if(ObjectUtil.isNotEmpty(orgIdList)) {
List<SysOrg> allOrgList = this.getAllOrgList();
// 获取所有子组织
List<String> toDeleteOrgIdList = CollectionUtil.newArrayList();
orgIdList.forEach(orgId -> toDeleteOrgIdList.addAll(this.getChildListById(allOrgList, orgId, true).stream()
.map(SysOrg::getId).collect(Collectors.toList())));
// 组织下有人不能删除(直属组织)
boolean hasOrgUser = sysUserService.count(new LambdaQueryWrapper<SysUser>().in(SysUser::getOrgId, toDeleteOrgIdList)) > 0;
if(hasOrgUser) {
throw new CommonException("请先删除组织下的用户");
}
// 组织下有人不能删除(兼任组织)
List<String> positionJsonList = sysUserService.list(new LambdaQueryWrapper<SysUser>()
.isNotNull(SysUser::getPositionJson)).stream().map(SysUser::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 = sysRoleService.count(new LambdaQueryWrapper<SysRole>().in(SysRole::getOrgId, toDeleteOrgIdList)) > 0;
if(hasRole) {
throw new CommonException("请先删除组织下的角色");
}
// 组织下有职位不能删除
boolean hasPosition = sysPositionService.count(new LambdaQueryWrapper<SysPosition>().in(SysPosition::getOrgId, toDeleteOrgIdList)) > 0;
if(hasPosition) {
throw new CommonException("请先删除组织下的职位");
}
// 执行删除
this.removeByIds(toDeleteOrgIdList);
// 发布删除事件
CommonDataChangeEventCenter.doDeleteWithDataId(SysDataTypeEnum.ORG.getValue(), toDeleteOrgIdList);
}
}
@Override
public SysOrg detail(SysOrgIdParam sysOrgIdParam) {
return this.queryEntity(sysOrgIdParam.getId());
}
@Override
public SysOrg queryEntity(String id) {
SysOrg sysOrg = this.getById(id);
if(ObjectUtil.isEmpty(sysOrg)) {
throw new CommonException("组织不存在id值为{}", id);
}
return sysOrg;
}
@Override
public List<SysOrg> getAllOrgList() {
return this.list(new LambdaQueryWrapper<SysOrg>().orderByAsc(SysOrg::getSortCode));
}
@Override
public String getOrgIdByOrgFullNameWithCreate(String orgFullName) {
List<SysOrg> allOrgList = this.getAllOrgList();
List<Tree<String>> treeList = TreeUtil.build(allOrgList.stream().map(sysOrg ->
new TreeNode<>(sysOrg.getId(), sysOrg.getParentId(), sysOrg.getName(), sysOrg.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<SysOrg> 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<SysOrg> allOrgList) {
//创建该组织
SysOrg sysOrg = new SysOrg();
sysOrg.setName(orgName);
sysOrg.setCode(RandomUtil.randomString(10));
sysOrg.setParentId(parentId);
sysOrg.setCategory("0".equals(parentId)?SysOrgCategoryEnum.COMPANY.getValue():SysOrgCategoryEnum.DEPT.getValue());
sysOrg.setSortCode(99);
this.save(sysOrg);
// 发布增加事件
CommonDataChangeEventCenter.doAddWithData(SysDataTypeEnum.ORG.getValue(), JSONUtil.createArray().put(sysOrg));
return sysOrg.getId();
}
/* ====组织部分所需要用到的选择器==== */
@Override
public List<Tree<String>> orgTreeSelector() {
List<SysOrg> sysOrgList = this.getAllOrgList();
List<TreeNode<String>> treeNodeList = sysOrgList.stream().map(sysOrg ->
new TreeNode<>(sysOrg.getId(), sysOrg.getParentId(), sysOrg.getName(), sysOrg.getSortCode()))
.collect(Collectors.toList());
return TreeUtil.build(treeNodeList, "0");
}
@Override
public Page<SysOrg> orgListSelector(SysOrgSelectorOrgListParam sysOrgSelectorOrgListParam) {
LambdaQueryWrapper<SysOrg> lambdaQueryWrapper = new LambdaQueryWrapper<>();
// 查询部分字段
lambdaQueryWrapper.select(SysOrg::getId, SysOrg::getParentId, SysOrg::getName,
SysOrg::getCategory, SysOrg::getSortCode);
if(ObjectUtil.isNotEmpty(sysOrgSelectorOrgListParam.getParentId())) {
lambdaQueryWrapper.eq(SysOrg::getParentId, sysOrgSelectorOrgListParam.getParentId());
}
if(ObjectUtil.isNotEmpty(sysOrgSelectorOrgListParam.getSearchKey())) {
lambdaQueryWrapper.like(SysOrg::getName, sysOrgSelectorOrgListParam.getSearchKey());
}
lambdaQueryWrapper.orderByAsc(SysOrg::getSortCode);
return this.page(CommonPageRequest.defaultPage(), lambdaQueryWrapper);
}
@Override
public Page<SysUser> userSelector(SysOrgSelectorUserParam sysOrgSelectorUserParam) {
LambdaQueryWrapper<SysUser> lambdaQueryWrapper = new LambdaQueryWrapper<>();
// 只查询部分字段
lambdaQueryWrapper.select(SysUser::getId, SysUser::getAvatar, SysUser::getOrgId, SysUser::getPositionId, SysUser::getAccount,
SysUser::getName, SysUser::getSortCode, SysUser::getGender, SysUser::getEntryDate);
// 如果查询条件为空,则直接查询
if(ObjectUtil.isAllEmpty(sysOrgSelectorUserParam.getOrgId(), sysOrgSelectorUserParam.getSearchKey())) {
return sysUserService.getAllUserSelectorList();
} else {
if(ObjectUtil.isNotEmpty(sysOrgSelectorUserParam.getOrgId())) {
// 如果组织id不为空则查询该组织及其子组织下的所有人
List<String> childOrgIdList = CollStreamUtil.toList(this.getChildListById(this
.getAllOrgList(), sysOrgSelectorUserParam.getOrgId(), true), SysOrg::getId);
if (ObjectUtil.isNotEmpty(childOrgIdList)) {
lambdaQueryWrapper.in(SysUser::getOrgId, childOrgIdList);
} else {
return new Page<>();
}
}
if(ObjectUtil.isNotEmpty(sysOrgSelectorUserParam.getSearchKey())) {
lambdaQueryWrapper.like(SysUser::getName, sysOrgSelectorUserParam.getSearchKey());
}
lambdaQueryWrapper.orderByAsc(SysUser::getSortCode);
return sysUserService.page(CommonPageRequest.defaultPage(), lambdaQueryWrapper);
}
}
/* ====以下为各种递归方法==== */
@Override
public List<SysOrg> getParentAndChildListById(List<SysOrg> originDataList, String id, boolean includeSelf) {
List<SysOrg> parentListById = this.getParentListById(originDataList, id, false);
List<SysOrg> childListById = this.getChildListById(originDataList, id, true);
parentListById.addAll(childListById);
return parentListById;
}
@Override
public List<SysOrg> getChildListById(List<SysOrg> originDataList, String id, boolean includeSelf) {
List<SysOrg> resultList = CollectionUtil.newArrayList();
execRecursionFindChild(originDataList, id, resultList);
if(includeSelf) {
SysOrg self = this.getById(originDataList, id);
if(ObjectUtil.isNotEmpty(self)) {
resultList.add(self);
}
}
return resultList;
}
@Override
public List<SysOrg> getParentListById(List<SysOrg> originDataList, String id, boolean includeSelf) {
List<SysOrg> resultList = CollectionUtil.newArrayList();
execRecursionFindParent(originDataList, id, resultList);
if(includeSelf) {
SysOrg self = this.getById(originDataList, id);
if(ObjectUtil.isNotEmpty(self)) {
resultList.add(self);
}
}
return resultList;
}
public void execRecursionFindChild(List<SysOrg> originDataList, String id, List<SysOrg> resultList) {
originDataList.forEach(item -> {
if(item.getParentId().equals(id)) {
resultList.add(item);
execRecursionFindChild(originDataList, item.getId(), resultList);
}
});
}
public void execRecursionFindParent(List<SysOrg> originDataList, String id, List<SysOrg> resultList) {
originDataList.forEach(item -> {
if(item.getId().equals(id)) {
SysOrg parent = this.getById(originDataList, item.getParentId());
if(ObjectUtil.isNotEmpty(parent)) {
resultList.add(parent);
}
execRecursionFindParent(originDataList, item.getParentId(), resultList);
}
});
}
@Override
public SysOrg getById(List<SysOrg> originDataList, String id) {
int index = CollStreamUtil.toList(originDataList, SysOrg::getId).indexOf(id);
return index == -1?null:originDataList.get(index);
}
@Override
public SysOrg getParentById(List<SysOrg> originDataList, String id) {
SysOrg self = this.getById(originDataList, id);
return ObjectUtil.isNotEmpty(self)?self:this.getById(originDataList, self.getParentId());
}
@Override
public SysOrg getChildById(List<SysOrg> originDataList, String id) {
int index = CollStreamUtil.toList(originDataList, SysOrg::getParentId).indexOf(id);
return index == -1?null:originDataList.get(index);
}
}

View File

@@ -0,0 +1,141 @@
package mjkf.xinke.sys.modular.position.controller;
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.common.annotation.CommonLog;
import mjkf.xinke.common.pojo.CommonResult;
import mjkf.xinke.common.pojo.CommonValidList;
import mjkf.xinke.sys.modular.position.entity.SysPosition;
import mjkf.xinke.sys.modular.position.param.*;
import mjkf.xinke.sys.modular.position.service.SysPositionService;
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 SysPositionController {
@Resource
private SysPositionService sysPositionService;
/**
* 获取职位分页
*
*
* @date 2022/4/24 20:00
*/
@ApiOperationSupport(order = 1)
@ApiOperation("获取职位分页")
@GetMapping("/sys/position/page")
public CommonResult<Page<SysPosition>> page(SysPositionPageParam sysPositionPageParam) {
return CommonResult.data(sysPositionService.page(sysPositionPageParam));
}
/**
* 添加职位
*
*
* @date 2022/4/24 20:47
*/
@ApiOperationSupport(order = 2)
@ApiOperation("添加职位")
@CommonLog("添加职位")
@PostMapping("/sys/position/add")
public CommonResult<String> add(@RequestBody @Valid SysPositionAddParam sysPositionAddParam) {
sysPositionService.add(sysPositionAddParam);
return CommonResult.ok();
}
/**
* 编辑职位
*
*
* @date 2022/4/24 20:47
*/
@ApiOperationSupport(order = 3)
@ApiOperation("编辑职位")
@CommonLog("编辑职位")
@PostMapping("/sys/position/edit")
public CommonResult<String> edit(@RequestBody @Valid SysPositionEditParam sysPositionEditParam) {
sysPositionService.edit(sysPositionEditParam);
return CommonResult.ok();
}
/**
* 删除职位
*
*
* @date 2022/4/24 20:00
*/
@ApiOperationSupport(order = 4)
@ApiOperation("删除职位")
@CommonLog("删除职位")
@PostMapping("/sys/position/delete")
public CommonResult<String> delete(@RequestBody @Valid @NotEmpty(message = "集合不能为空")
CommonValidList<SysPositionIdParam> sysPositionIdParamList) {
sysPositionService.delete(sysPositionIdParamList);
return CommonResult.ok();
}
/**
* 获取职位详情
*
*
* @date 2022/4/24 20:00
*/
@ApiOperationSupport(order = 5)
@ApiOperation("获取职位详情")
@GetMapping("/sys/position/detail")
public CommonResult<SysPosition> detail(@Valid SysPositionIdParam sysPositionIdParam) {
return CommonResult.data(sysPositionService.detail(sysPositionIdParam));
}
/* ====职位部分所需要用到的选择器==== */
/**
* 获取组织树选择器
*
*
* @date 2022/4/24 20:00
*/
@ApiOperationSupport(order = 6)
@ApiOperation("获取组织树选择器")
@GetMapping("/sys/position/orgTreeSelector")
public CommonResult<List<Tree<String>>> orgTreeSelector() {
return CommonResult.data(sysPositionService.orgTreeSelector());
}
/**
* 获取职位选择器
*
*
* @date 2022/4/24 20:00
*/
@ApiOperationSupport(order = 7)
@ApiOperation("获取职位选择器")
@GetMapping("/sys/position/positionSelector")
public CommonResult<Page<SysPosition>> positionSelector(SysPositionSelectorPositionParam sysPositionSelectorPositionParam) {
return CommonResult.data(sysPositionService.positionSelector(sysPositionSelectorPositionParam));
}
}

View File

@@ -0,0 +1,56 @@
package mjkf.xinke.sys.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 SysPosition 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;
}

View File

@@ -0,0 +1,37 @@
package mjkf.xinke.sys.modular.position.enums;
import lombok.Getter;
import mjkf.xinke.common.exception.CommonException;
/**
* 职位分类枚举
*
*
* @date 2022/4/21 19:56
**/
@Getter
public enum SysPositionCategoryEnum {
/** 高层 */
HIGH("HIGH"),
/** 中层 */
MIDDLE("MIDDLE"),
/** 基层 */
LOW("LOW");
private final String value;
SysPositionCategoryEnum(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);
}
}
}

View File

@@ -0,0 +1,14 @@
package mjkf.xinke.sys.modular.position.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import mjkf.xinke.sys.modular.position.entity.SysPosition;
/**
* 职位Mapper接口
*
*
* @date 2022/4/21 18:37
**/
public interface SysPositionMapper extends BaseMapper<SysPosition> {
}

View File

@@ -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.sys.modular.position.mapper.SysPositionMapper">
</mapper>

View File

@@ -0,0 +1,44 @@
package mjkf.xinke.sys.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 SysPositionAddParam {
/** 组织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;
}

View File

@@ -0,0 +1,49 @@
package mjkf.xinke.sys.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 SysPositionEditParam {
/** 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;
}

View File

@@ -0,0 +1,24 @@
package mjkf.xinke.sys.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 SysPositionIdParam {
/** id */
@ApiModelProperty(value = "id", required = true)
@NotBlank(message = "id不能为空")
private String id;
}

View File

@@ -0,0 +1,45 @@
package mjkf.xinke.sys.modular.position.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
/**
* 职位查询参数
*
*
* @date 2022/4/21 16:13
**/
@Getter
@Setter
public class SysPositionPageParam {
/** 当前页 */
@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;
}

View File

@@ -0,0 +1,33 @@
package mjkf.xinke.sys.modular.position.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
/**
* 职位选择器参数
*
*
* @date 2022/4/21 16:13
**/
@Getter
@Setter
public class SysPositionSelectorPositionParam {
/** 当前页 */
@ApiModelProperty(value = "当前页码")
private Integer current;
/** 每页条数 */
@ApiModelProperty(value = "每页条数")
private Integer size;
/** 组织id */
@ApiModelProperty(value = "组织id")
private String orgId;
/** 名称关键词 */
@ApiModelProperty(value = "名称关键词")
private String searchKey;
}

View File

@@ -0,0 +1,40 @@
package mjkf.xinke.sys.modular.position.provider;
import cn.hutool.core.bean.BeanUtil;
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.sys.api.SysPositionApi;
import mjkf.xinke.sys.modular.position.param.SysPositionSelectorPositionParam;
import mjkf.xinke.sys.modular.position.service.SysPositionService;
import javax.annotation.Resource;
/**
* 职位API接口提供者
*
*
* @date 2022/7/22 14:56
**/
@Service
public class SysPositionApiProvider implements SysPositionApi {
@Resource
private SysPositionService sysPositionService;
@Override
public String getNameById(String positionId) {
return sysPositionService.queryEntity(positionId).getName();
}
@SuppressWarnings("ALL")
@Override
public Page<JSONObject> positionSelector(String orgId, String searchKey) {
SysPositionSelectorPositionParam sysPositionSelectorPositionParam = new SysPositionSelectorPositionParam();
sysPositionSelectorPositionParam.setOrgId(orgId);
sysPositionSelectorPositionParam.setSearchKey(searchKey);
return BeanUtil.toBean(sysPositionService.positionSelector(sysPositionSelectorPositionParam), Page.class);
}
}

View File

@@ -0,0 +1,101 @@
package mjkf.xinke.sys.modular.position.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.sys.modular.position.entity.SysPosition;
import mjkf.xinke.sys.modular.position.param.*;
import java.util.List;
/**
* 职位Service接口
*
*
* @date 2022/4/21 18:35
**/
public interface SysPositionService extends IService<SysPosition> {
/**
* 获取职位分页
*
*
* @date 2022/4/24 20:08
*/
Page<SysPosition> page(SysPositionPageParam sysPositionPageParam);
/**
* 添加职位
*
*
* @date 2022/4/24 20:48
*/
void add(SysPositionAddParam sysPositionAddParam);
/**
* 编辑职位
*
*
* @date 2022/4/24 21:13
*/
void edit(SysPositionEditParam sysPositionEditParam);
/**
* 删除职位
*
*
* @date 2022/4/24 21:18
*/
void delete(List<SysPositionIdParam> sysPositionIdParamList);
/**
* 获取职位详情
*
*
* @date 2022/4/24 21:18
*/
SysPosition detail(SysPositionIdParam sysPositionIdParam);
/**
* 获取职位详情
*
*
* @date 2022/7/25 19:42
**/
SysPosition queryEntity(String id);
/**
* 根据id获取数据
*
*
* @date 2022/8/15 14:55
**/
SysPosition getById(List<SysPosition> originDataList, 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<SysPosition> positionSelector(SysPositionSelectorPositionParam sysPositionSelectorPositionParam);
}

View File

@@ -0,0 +1,209 @@
package mjkf.xinke.sys.modular.position.service.impl;
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.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.common.enums.CommonSortOrderEnum;
import mjkf.xinke.common.exception.CommonException;
import mjkf.xinke.common.listener.CommonDataChangeEventCenter;
import mjkf.xinke.common.page.CommonPageRequest;
import mjkf.xinke.sys.core.enums.SysDataTypeEnum;
import mjkf.xinke.sys.modular.org.entity.SysOrg;
import mjkf.xinke.sys.modular.org.service.SysOrgService;
import mjkf.xinke.sys.modular.position.entity.SysPosition;
import mjkf.xinke.sys.modular.position.enums.SysPositionCategoryEnum;
import mjkf.xinke.sys.modular.position.mapper.SysPositionMapper;
import mjkf.xinke.sys.modular.position.param.*;
import mjkf.xinke.sys.modular.position.service.SysPositionService;
import mjkf.xinke.sys.modular.user.entity.SysUser;
import mjkf.xinke.sys.modular.user.service.SysUserService;
import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;
/**
* 职位Service接口实现类
*
*
* @date 2022/2/23 18:43
**/
@Service
public class SysPositionServiceImpl extends ServiceImpl<SysPositionMapper, SysPosition> implements SysPositionService {
@Resource
private SysOrgService sysOrgService;
@Resource
private SysUserService sysUserService;
@Override
public Page<SysPosition> page(SysPositionPageParam sysPositionPageParam) {
QueryWrapper<SysPosition> queryWrapper = new QueryWrapper<>();
// 查询部分字段
queryWrapper.lambda().select(SysPosition::getId, SysPosition::getOrgId, SysPosition::getName,
SysPosition::getCategory, SysPosition::getSortCode);
if(ObjectUtil.isNotEmpty(sysPositionPageParam.getOrgId())) {
queryWrapper.lambda().eq(SysPosition::getOrgId, sysPositionPageParam.getOrgId());
}
if(ObjectUtil.isNotEmpty(sysPositionPageParam.getCategory())) {
queryWrapper.lambda().eq(SysPosition::getCategory, sysPositionPageParam.getCategory());
}
if(ObjectUtil.isNotEmpty(sysPositionPageParam.getSearchKey())) {
queryWrapper.lambda().like(SysPosition::getName, sysPositionPageParam.getSearchKey());
}
if(ObjectUtil.isAllNotEmpty(sysPositionPageParam.getSortField(), sysPositionPageParam.getSortOrder())) {
CommonSortOrderEnum.validate(sysPositionPageParam.getSortOrder());
queryWrapper.orderBy(true, sysPositionPageParam.getSortOrder().equals(CommonSortOrderEnum.ASC.getValue()),
StrUtil.toUnderlineCase(sysPositionPageParam.getSortField()));
} else {
queryWrapper.lambda().orderByAsc(SysPosition::getSortCode);
}
return this.page(CommonPageRequest.defaultPage(), queryWrapper);
}
@Transactional(rollbackFor = Exception.class)
@Override
public void add(SysPositionAddParam sysPositionAddParam) {
SysPositionCategoryEnum.validate(sysPositionAddParam.getCategory());
SysPosition sysPosition = BeanUtil.toBean(sysPositionAddParam, SysPosition.class);
boolean repeatName = this.count(new LambdaQueryWrapper<SysPosition>().eq(SysPosition::getOrgId, sysPosition.getOrgId())
.eq(SysPosition::getName, sysPosition.getName())) > 0;
if(repeatName) {
throw new CommonException("同组织下存在重复的职位,名称为:{}", sysPosition.getName());
}
sysPosition.setCode(RandomUtil.randomString(10));
this.save(sysPosition);
// 发布增加事件
CommonDataChangeEventCenter.doAddWithData(SysDataTypeEnum.POSITION.getValue(), JSONUtil.createArray().put(sysPosition));
}
@Transactional(rollbackFor = Exception.class)
@Override
public void edit(SysPositionEditParam sysPositionEditParam) {
SysPositionCategoryEnum.validate(sysPositionEditParam.getCategory());
SysPosition sysPosition = this.queryEntity(sysPositionEditParam.getId());
BeanUtil.copyProperties(sysPositionEditParam, sysPosition);
boolean repeatName = this.count(new LambdaQueryWrapper<SysPosition>().eq(SysPosition::getOrgId, sysPosition.getOrgId())
.eq(SysPosition::getName, sysPosition.getName()).ne(SysPosition::getId, sysPosition.getId())) > 0;
if(repeatName) {
throw new CommonException("同组织下存在重复的职位,名称为:{}", sysPosition.getName());
}
this.updateById(sysPosition);
// 发布更新事件
CommonDataChangeEventCenter.doUpdateWithData(SysDataTypeEnum.POSITION.getValue(), JSONUtil.createArray().put(sysPosition));
}
@Transactional(rollbackFor = Exception.class)
@Override
public void delete(List<SysPositionIdParam> sysPositionIdParamList) {
List<String> positionIdList = CollStreamUtil.toList(sysPositionIdParamList, SysPositionIdParam::getId);
if(ObjectUtil.isNotEmpty(positionIdList)) {
// 职位下有人不能删除(直属职位)
boolean hasOrgUser = sysUserService.count(new LambdaQueryWrapper<SysUser>().in(SysUser::getPositionId, positionIdList)) > 0;
if(hasOrgUser) {
throw new CommonException("请先删除职位下的用户");
}
// 职位下有人不能删除(兼任职位)
List<String> positionJsonList = sysUserService.list(new LambdaQueryWrapper<SysUser>()
.isNotNull(SysUser::getPositionJson)).stream().map(SysUser::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(SysDataTypeEnum.POSITION.getValue(), positionIdList);
}
}
@Override
public SysPosition detail(SysPositionIdParam sysPositionIdParam) {
return this.queryEntity(sysPositionIdParam.getId());
}
@Override
public SysPosition queryEntity(String id) {
SysPosition sysPosition = this.getById(id);
if(ObjectUtil.isEmpty(sysPosition)) {
throw new CommonException("职位不存在id值为{}", id);
}
return sysPosition;
}
@Override
public SysPosition getById(List<SysPosition> originDataList, String id) {
int index = CollStreamUtil.toList(originDataList, SysPosition::getId).indexOf(id);
return index == -1?null:originDataList.get(index);
}
@Override
public String getPositionIdByPositionNameWithCreate(String orgId, String positionName) {
SysPosition sysPosition = this.getOne(new LambdaQueryWrapper<SysPosition>().eq(SysPosition::getOrgId, orgId).eq(SysPosition::getName, positionName));
if(ObjectUtil.isNotEmpty(sysPosition)) {
return sysPosition.getId();
} else {
sysPosition = new SysPosition();
sysPosition.setOrgId(orgId);
sysPosition.setName(positionName);
sysPosition.setCode(RandomUtil.randomString(10));
sysPosition.setCategory(SysPositionCategoryEnum.LOW.getValue());
sysPosition.setSortCode(99);
this.save(sysPosition);
// 发布增加事件
CommonDataChangeEventCenter.doAddWithData(SysDataTypeEnum.POSITION.getValue(), JSONUtil.createArray().put(sysPosition));
return sysPosition.getId();
}
}
/* ====职位部分所需要用到的选择器==== */
@Override
public List<Tree<String>> orgTreeSelector() {
List<SysOrg> sysOrgList = sysOrgService.getAllOrgList();
List<TreeNode<String>> treeNodeList = sysOrgList.stream().map(sysOrg ->
new TreeNode<>(sysOrg.getId(), sysOrg.getParentId(), sysOrg.getName(), sysOrg.getSortCode()))
.collect(Collectors.toList());
return TreeUtil.build(treeNodeList, "0");
}
@Override
public Page<SysPosition> positionSelector(SysPositionSelectorPositionParam sysPositionSelectorPositionParam) {
LambdaQueryWrapper<SysPosition> lambdaQueryWrapper = new LambdaQueryWrapper<>();
// 查询部分字段
lambdaQueryWrapper.select(SysPosition::getId, SysPosition::getOrgId, SysPosition::getName,
SysPosition::getCategory, SysPosition::getSortCode);
if(ObjectUtil.isNotEmpty(sysPositionSelectorPositionParam.getOrgId())) {
lambdaQueryWrapper.eq(SysPosition::getOrgId, sysPositionSelectorPositionParam.getOrgId());
}
if(ObjectUtil.isNotEmpty(sysPositionSelectorPositionParam.getSearchKey())) {
lambdaQueryWrapper.like(SysPosition::getName, sysPositionSelectorPositionParam.getSearchKey());
}
lambdaQueryWrapper.orderByAsc(SysPosition::getSortCode);
return this.page(CommonPageRequest.defaultPage(), lambdaQueryWrapper);
}
}

View File

@@ -0,0 +1,46 @@
package mjkf.xinke.sys.modular.relation.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;
/**
* 关系实体
*
*
* @date 2022/4/21 16:13
**/
@Getter
@Setter
@TableName("SYS_RELATION")
public class SysRelation{
/** 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 objectId;
/** 目标id */
@ApiModelProperty(value = "目标id", position = 4)
private String targetId;
/** 分类 */
@ApiModelProperty(value = "分类", position = 5)
private String category;
/** 扩展信息 */
@ApiModelProperty(value = "扩展信息", position = 6)
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
private String extJson;
}

View File

@@ -0,0 +1,44 @@
package mjkf.xinke.sys.modular.relation.enums;
import lombok.Getter;
/**
* 关系分类枚举
*
*
* @date 2022/4/21 19:56
**/
@Getter
public enum SysRelationCategoryEnum {
/** 用户工作台数据 */
SYS_USER_WORKBENCH_DATA("SYS_USER_WORKBENCH_DATA"),
/** 用户日程数据 */
SYS_USER_SCHEDULE_DATA("SYS_USER_SCHEDULE_DATA"),
/** 用户拥有资源 */
SYS_USER_HAS_RESOURCE("SYS_USER_HAS_RESOURCE"),
/** 用户拥有权限 */
SYS_USER_HAS_PERMISSION("SYS_USER_HAS_PERMISSION"),
/** 用户拥有角色 */
SYS_USER_HAS_ROLE("SYS_USER_HAS_ROLE"),
/** 角色拥有资源 */
SYS_ROLE_HAS_RESOURCE("SYS_ROLE_HAS_RESOURCE"),
/** 角色拥有移动端菜单 */
SYS_ROLE_HAS_MOBILE_MENU("SYS_ROLE_HAS_MOBILE_MENU"),
/** 角色拥有权限 */
SYS_ROLE_HAS_PERMISSION("SYS_ROLE_HAS_PERMISSION");
private final String value;
SysRelationCategoryEnum(String value) {
this.value = value;
}
}

View File

@@ -0,0 +1,14 @@
package mjkf.xinke.sys.modular.relation.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import mjkf.xinke.sys.modular.relation.entity.SysRelation;
/**
* 关系Mapper接口
*
*
* @date 2022/4/21 18:37
**/
public interface SysRelationMapper extends BaseMapper<SysRelation> {
}

View File

@@ -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.sys.modular.relation.mapper.SysRelationMapper">
</mapper>

View File

@@ -0,0 +1,64 @@
package mjkf.xinke.sys.modular.relation.provider;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.springframework.stereotype.Service;
import mjkf.xinke.sys.api.SysRelationApi;
import mjkf.xinke.sys.modular.relation.entity.SysRelation;
import mjkf.xinke.sys.modular.relation.enums.SysRelationCategoryEnum;
import mjkf.xinke.sys.modular.relation.service.SysRelationService;
import javax.annotation.Resource;
import java.util.Collection;
import java.util.List;
import java.util.Set;
/**
* 关系API接口实现类
*
*
* @date 2022/6/6 15:33
**/
@Service
public class SysRelationApiProvider implements SysRelationApi {
@Resource
private SysRelationService sysRelationService;
@Override
public List<String> getUserIdListByRoleIdList(List<String> roleIdList) {
return sysRelationService.getRelationObjectIdListByTargetIdListAndCategory(roleIdList,
SysRelationCategoryEnum.SYS_USER_HAS_ROLE.getValue());
}
@Override
public void removeRoleHasMobileMenuRelation(List<String> targetIdList) {
sysRelationService.remove(new LambdaQueryWrapper<SysRelation>().in(SysRelation::getTargetId, targetIdList)
.eq(SysRelation::getCategory, SysRelationCategoryEnum.SYS_ROLE_HAS_MOBILE_MENU.getValue()));
}
@Override
public void removeRoleHasMobileButtonRelation(List<String> targetIdList, List<String> buttonIdList) {
sysRelationService.list(new LambdaQueryWrapper<SysRelation>().in(SysRelation::getTargetId, targetIdList)
.eq(SysRelation::getCategory, SysRelationCategoryEnum.SYS_ROLE_HAS_MOBILE_MENU.getValue())
.isNotNull(SysRelation::getExtJson)).forEach(mobileRelation -> {
JSONObject extJsonObject = JSONUtil.parseObj(mobileRelation.getExtJson());
List<String> buttonInfoList = extJsonObject.getBeanList("buttonInfo", String.class);
if (ObjectUtil.isNotEmpty(buttonInfoList)) {
Set<String> intersectionDistinct = CollectionUtil.intersectionDistinct(buttonIdList, buttonInfoList);
if(ObjectUtil.isNotEmpty(intersectionDistinct)) {
Collection<String> disjunction = CollectionUtil.disjunction(buttonInfoList, intersectionDistinct);
extJsonObject.set("buttonInfo", disjunction);
}
}
// 清除对应的角色与移动端菜单信息中的【授权的移动端按钮信息】
sysRelationService.update(new LambdaUpdateWrapper<SysRelation>().eq(SysRelation::getId, mobileRelation.getId())
.set(SysRelation::getExtJson, JSONUtil.toJsonStr(extJsonObject)));
});
}
}

View File

@@ -0,0 +1,208 @@
package mjkf.xinke.sys.modular.relation.service;
import com.baomidou.mybatisplus.extension.service.IService;
import mjkf.xinke.sys.modular.relation.entity.SysRelation;
import java.util.List;
/**
* 关系Service接口
*
*
* @date 2022/4/21 18:35
**/
public interface SysRelationService extends IService<SysRelation> {
/**
* 追加关系
*
*
* @date 2022/4/24 22:29
*/
void saveRelationWithAppend(String objectId, String targetId, String category);
/**
* 追加关系
*
*
* @date 2022/4/24 22:29
*/
void saveRelationWithAppend(String objectId, String targetId, String category, String extJson);
/**
* 批量追加关系
*
*
* @date 2022/4/24 22:29
*/
void saveRelationBatchWithAppend(String objectId, List<String> targetIdList, String category);
/**
* 批量追加关系
*
*
* @date 2022/4/24 22:29
*/
void saveRelationBatchWithAppend(String objectId, List<String> targetIdList, String category, List<String> extJsonList);
/**
* 清空原关系并保存关系
*
*
* @date 2022/4/24 22:29
*/
void saveRelationWithClear(String objectId, String targetId, String category);
/**
* 清空原关系并保存关系
*
*
* @date 2022/4/24 22:29
*/
void saveRelationWithClear(String objectId, String targetId, String category, String extJson);
/**
* 清空原关系并批量保存关系
*
*
* @date 2022/4/24 22:29
*/
void saveRelationBatchWithClear(String objectId, List<String> targetIdList, String category);
/**
* 清空原关系并批量保存关系
*
*
* @date 2022/4/24 22:29
*/
void saveRelationBatchWithClear(String objectId, List<String> targetIdList, String category, List<String> extJsonList);
/**
* 根据对象id获取关系列表
*
*
* @date 2022/4/27 22:06
*/
List<SysRelation> getRelationListByObjectId(String objectId);
/**
* 根据对象id集合获取关系列表
*
*
* @date 2022/4/27 22:06
*/
List<SysRelation> getRelationListByObjectIdList(List<String> objectIdList);
/**
* 根据对象id和关系分类获取关系列表
*
*
* @date 2022/4/27 22:06
*/
List<SysRelation> getRelationListByObjectIdAndCategory(String objectId, String category);
/**
* 根据对象id集合和关系分类获取关系列表
*
*
* @date 2022/4/27 22:06
*/
List<SysRelation> getRelationListByObjectIdListAndCategory(List<String> objectIdList, String category);
/**
* 根据目标id获取关系列表
*
*
* @date 2022/4/27 22:06
*/
List<SysRelation> getRelationListByTargetId(String targetId);
/**
* 根据目标id集合获取关系列表
*
*
* @date 2022/4/27 22:06
*/
List<SysRelation> getRelationListByTargetIdList(List<String> targetIdList);
/**
* 根据目标id和关系分类获取关系列表
*
*
* @date 2022/4/27 22:06
*/
List<SysRelation> getRelationListByTargetIdAndCategory(String targetId, String category);
/**
* 根据目标id集合和关系分类获取关系列表
*
*
* @date 2022/4/27 22:06
*/
List<SysRelation> getRelationListByTargetIdListAndCategory(List<String> targetIdList, String category);
/**
* 根据对象id获取目标id列表
*
*
* @date 2022/4/27 22:07
*/
List<String> getRelationTargetIdListByObjectId(String objectId);
/**
* 根据对象id集合获取目标id列表
*
*
* @date 2022/4/27 22:07
*/
List<String> getRelationTargetIdListByObjectIdList(List<String> objectIdList);
/**
* 根据对象id和关系分类获取目标id列表
*
*
* @date 2022/4/27 22:07
*/
List<String> getRelationTargetIdListByObjectIdAndCategory(String objectId, String category);
/**
* 根据对象id集合和关系分类获取目标id列表
*
*
* @date 2022/4/27 22:07
*/
List<String> getRelationTargetIdListByObjectIdListAndCategory(List<String> objectIdList, String category);
/**
* 根据目标id获取对象id列表
*
*
* @date 2022/4/27 22:07
*/
List<String> getRelationObjectIdListByTargetId(String targetId);
/**
* 根据目标id集合获取对象id列表
*
*
* @date 2022/4/27 22:07
*/
List<String> getRelationObjectIdListByTargetIdList(List<String> targetIdList);
/**
* 根据目标id和关系分类获取对象id列表
*
*
* @date 2022/4/27 22:08
*/
List<String> getRelationObjectIdListByTargetIdAndCategory(String targetId, String category);
/**
* 根据目标id集合和关系分类获取对象id列表
*
*
* @date 2022/4/27 22:08
*/
List<String> getRelationObjectIdListByTargetIdListAndCategory(List<String> targetIdList, String category);
}

View File

@@ -0,0 +1,207 @@
package mjkf.xinke.sys.modular.relation.service.impl;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import mjkf.xinke.sys.modular.relation.entity.SysRelation;
import mjkf.xinke.sys.modular.relation.mapper.SysRelationMapper;
import mjkf.xinke.sys.modular.relation.service.SysRelationService;
import java.util.List;
import java.util.stream.Collectors;
/**
* 关系Service接口实现类
*
*
* @date 2022/2/23 18:43
**/
@Service
public class SysRelationServiceImpl extends ServiceImpl<SysRelationMapper, SysRelation> implements SysRelationService {
@Transactional(rollbackFor = Exception.class)
public void saveRelation(String objectId, String targetId, String category, String extJson, boolean clear) {
// 是否需要先删除关系
if(clear) {
this.remove(new LambdaQueryWrapper<SysRelation>().eq(SysRelation::getObjectId, objectId)
.eq(SysRelation::getCategory, category));
}
SysRelation sysRelation = new SysRelation();
sysRelation.setObjectId(objectId);
sysRelation.setTargetId(targetId);
sysRelation.setCategory(category);
sysRelation.setExtJson(extJson);
this.save(sysRelation);
}
@Transactional(rollbackFor = Exception.class)
public void saveRelationBatch(String objectId, List<String> targetIdList, String category, List<String> extJsonList, boolean clear) {
// 是否需要先删除关系
if(clear) {
this.remove(new LambdaQueryWrapper<SysRelation>().eq(SysRelation::getObjectId, objectId)
.eq(SysRelation::getCategory, category));
}
List<SysRelation> sysRelationList = CollectionUtil.newArrayList();
for(int i = 0; i < targetIdList.size(); i++) {
SysRelation sysRelation = new SysRelation();
sysRelation.setObjectId(objectId);
sysRelation.setTargetId(targetIdList.get(i));
sysRelation.setCategory(category);
if(ObjectUtil.isNotEmpty(extJsonList)) {
sysRelation.setExtJson(extJsonList.get(i));
}
sysRelationList.add(sysRelation);
}
if(ObjectUtil.isNotEmpty(sysRelationList)) {
this.saveBatch(sysRelationList);
}
}
@Override
public void saveRelationWithAppend(String objectId, String targetId, String category) {
this.saveRelation(objectId, targetId, category, null, false);
}
@Override
public void saveRelationWithAppend(String objectId, String targetId, String category, String extJson) {
this.saveRelation(objectId, targetId, category, extJson, false);
}
@Override
public void saveRelationBatchWithAppend(String objectId, List<String> targetIdList, String category) {
this.saveRelationBatch(objectId, targetIdList, category, null, false);
}
@Override
public void saveRelationBatchWithAppend(String objectId, List<String> targetIdList, String category, List<String> extJsonList) {
this.saveRelationBatch(objectId, targetIdList, category, extJsonList, false);
}
@Override
public void saveRelationWithClear(String objectId, String targetId, String category) {
this.saveRelation(objectId, targetId, category, null, true);
}
@Override
public void saveRelationWithClear(String objectId, String targetId, String category, String extJson) {
this.saveRelation(objectId, targetId, category, extJson, true);
}
@Override
public void saveRelationBatchWithClear(String objectId, List<String> targetIdList, String category) {
this.saveRelationBatch(objectId, targetIdList, category, null, true);
}
@Override
public void saveRelationBatchWithClear(String objectId, List<String> targetIdList, String category, List<String> extJsonList) {
this.saveRelationBatch(objectId, targetIdList, category, extJsonList, true);
}
@Override
public List<SysRelation> getRelationListByObjectId(String objectId) {
return this.getRelationListByObjectIdAndCategory(objectId, null);
}
@Override
public List<SysRelation> getRelationListByObjectIdList(List<String> objectIdList) {
return this.getRelationListByObjectIdListAndCategory(objectIdList, null);
}
@Override
public List<SysRelation> getRelationListByObjectIdAndCategory(String objectId, String category) {
LambdaQueryWrapper<SysRelation> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(SysRelation::getObjectId, objectId);
if(ObjectUtil.isNotEmpty(category)) {
lambdaQueryWrapper.eq(SysRelation::getCategory, category);
}
return this.list(lambdaQueryWrapper);
}
@Override
public List<SysRelation> getRelationListByObjectIdListAndCategory(List<String> objectIdList, String category) {
LambdaQueryWrapper<SysRelation> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.in(SysRelation::getObjectId, objectIdList);
if(ObjectUtil.isNotEmpty(category)) {
lambdaQueryWrapper.eq(SysRelation::getCategory, category);
}
return this.list(lambdaQueryWrapper);
}
@Override
public List<SysRelation> getRelationListByTargetId(String targetId) {
return this.getRelationListByTargetIdAndCategory(targetId, null);
}
@Override
public List<SysRelation> getRelationListByTargetIdList(List<String> targetIdList) {
return this.getRelationListByTargetIdListAndCategory(targetIdList, null);
}
@Override
public List<SysRelation> getRelationListByTargetIdAndCategory(String targetId, String category) {
LambdaQueryWrapper<SysRelation> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(SysRelation::getTargetId, targetId);
if(ObjectUtil.isNotEmpty(category)) {
lambdaQueryWrapper.eq(SysRelation::getCategory, category);
}
return this.list(lambdaQueryWrapper);
}
@Override
public List<SysRelation> getRelationListByTargetIdListAndCategory(List<String> targetIdList, String category) {
LambdaQueryWrapper<SysRelation> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.in(SysRelation::getTargetId, targetIdList);
if(ObjectUtil.isNotEmpty(category)) {
lambdaQueryWrapper.eq(SysRelation::getCategory, category);
}
return this.list(lambdaQueryWrapper);
}
@Override
public List<String> getRelationTargetIdListByObjectId(String objectId) {
return this.getRelationTargetIdListByObjectIdAndCategory(objectId, null);
}
@Override
public List<String> getRelationTargetIdListByObjectIdList(List<String> objectIdList) {
return this.getRelationTargetIdListByObjectIdListAndCategory(objectIdList, null);
}
@Override
public List<String> getRelationTargetIdListByObjectIdAndCategory(String objectId, String category) {
return this.getRelationListByObjectIdAndCategory(objectId, category).stream()
.map(SysRelation::getTargetId).collect(Collectors.toList());
}
@Override
public List<String> getRelationTargetIdListByObjectIdListAndCategory(List<String> objectIdList, String category) {
return this.getRelationListByObjectIdListAndCategory(objectIdList, category).stream()
.map(SysRelation::getTargetId).collect(Collectors.toList());
}
@Override
public List<String> getRelationObjectIdListByTargetId(String targetId) {
return this.getRelationObjectIdListByTargetIdAndCategory(targetId, null);
}
@Override
public List<String> getRelationObjectIdListByTargetIdList(List<String> targetIdList) {
return this.getRelationObjectIdListByTargetIdListAndCategory(targetIdList, null);
}
@Override
public List<String> getRelationObjectIdListByTargetIdAndCategory(String targetId, String category) {
return this.getRelationListByTargetIdAndCategory(targetId, category).stream()
.map(SysRelation::getObjectId).collect(Collectors.toList());
}
@Override
public List<String> getRelationObjectIdListByTargetIdListAndCategory(List<String> targetIdList, String category) {
return this.getRelationListByTargetIdListAndCategory(targetIdList, category).stream()
.map(SysRelation::getObjectId).collect(Collectors.toList());
}
}

View File

@@ -0,0 +1,112 @@
package mjkf.xinke.sys.modular.resource.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.common.annotation.CommonLog;
import mjkf.xinke.common.pojo.CommonResult;
import mjkf.xinke.sys.modular.resource.entity.SysButton;
import mjkf.xinke.sys.modular.resource.param.button.SysButtonAddParam;
import mjkf.xinke.sys.modular.resource.param.button.SysButtonEditParam;
import mjkf.xinke.sys.modular.resource.param.button.SysButtonIdParam;
import mjkf.xinke.sys.modular.resource.param.button.SysButtonPageParam;
import mjkf.xinke.sys.modular.resource.service.SysButtonService;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.List;
/**
* 按钮控制器
*
*
* @date 2022/6/27 13:56
**/
@Api(tags = "按钮控制器")
@ApiSupport(author = "SNOWY_TEAM", order = 3)
@RestController
@Validated
public class SysButtonController {
@Resource
private SysButtonService sysButtonService;
/**
* 获取按钮分页
*
*
* @date 2022/4/24 20:00
*/
@ApiOperationSupport(order = 1)
@ApiOperation("获取按钮分页")
@GetMapping("/sys/button/page")
public CommonResult<Page<SysButton>> page(SysButtonPageParam sysButtonPageParam) {
return CommonResult.data(sysButtonService.page(sysButtonPageParam));
}
/**
* 添加按钮
*
*
* @date 2022/4/24 20:47
*/
@ApiOperationSupport(order = 2)
@ApiOperation("添加按钮")
@CommonLog("添加按钮")
@PostMapping("/sys/button/add")
public CommonResult<String> add(@RequestBody @Valid SysButtonAddParam sysButtonAddParam) {
sysButtonService.add(sysButtonAddParam);
return CommonResult.ok();
}
/**
* 编辑按钮
*
*
* @date 2022/4/24 20:47
*/
@ApiOperationSupport(order = 3)
@ApiOperation("编辑按钮")
@CommonLog("编辑按钮")
@PostMapping("/sys/button/edit")
public CommonResult<String> edit(@RequestBody @Valid SysButtonEditParam sysButtonEditParam) {
sysButtonService.edit(sysButtonEditParam);
return CommonResult.ok();
}
/**
* 删除按钮
*
*
* @date 2022/4/24 20:00
*/
@ApiOperationSupport(order = 4)
@ApiOperation("删除按钮")
@CommonLog("删除按钮")
@PostMapping("/sys/button/delete")
public CommonResult<String> delete(@RequestBody @Valid List<SysButtonIdParam> sysButtonIdParamList) {
sysButtonService.delete(sysButtonIdParamList);
return CommonResult.ok();
}
/**
* 获取按钮详情
*
*
* @date 2022/4/24 20:00
*/
@ApiOperationSupport(order = 5)
@ApiOperation("获取按钮详情")
@GetMapping("/sys/button/detail")
public CommonResult<SysButton> detail(@Valid SysButtonIdParam sysButtonIdParam) {
return CommonResult.data(sysButtonService.detail(sysButtonIdParam));
}
}

View File

@@ -0,0 +1,170 @@
package mjkf.xinke.sys.modular.resource.controller;
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.common.annotation.CommonLog;
import mjkf.xinke.common.pojo.CommonResult;
import mjkf.xinke.common.pojo.CommonValidList;
import mjkf.xinke.sys.modular.resource.entity.SysMenu;
import mjkf.xinke.sys.modular.resource.entity.SysModule;
import mjkf.xinke.sys.modular.resource.param.menu.*;
import mjkf.xinke.sys.modular.resource.service.SysMenuService;
import javax.annotation.Resource;
import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import java.util.List;
/**
* 菜单控制器
*
*
* @date 2022/6/27 14:09
**/
@Api(tags = "菜单控制器")
@ApiSupport(author = "SNOWY_TEAM", order = 5)
@RestController
@Validated
public class SysMenuController {
@Resource
private SysMenuService sysMenuService;
/**
* 获取菜单分页
*
*
* @date 2022/4/24 20:00
*/
@ApiOperationSupport(order = 1)
@ApiOperation("获取菜单分页")
@GetMapping("/sys/menu/page")
public CommonResult<Page<SysMenu>> page(SysMenuPageParam sysMenuPageParam) {
return CommonResult.data(sysMenuService.page(sysMenuPageParam));
}
/**
* 获取菜单树
*
*
* @date 2022/4/24 20:00
*/
@ApiOperationSupport(order = 2)
@ApiOperation("获取菜单树")
@GetMapping("/sys/menu/tree")
public CommonResult<List<Tree<String>>> tree(SysMenuTreeParam sysMenuTreeParam) {
return CommonResult.data(sysMenuService.tree(sysMenuTreeParam));
}
/**
* 添加菜单
*
*
* @date 2022/4/24 20:47
*/
@ApiOperationSupport(order = 3)
@ApiOperation("添加菜单")
@CommonLog("添加菜单")
@PostMapping("/sys/menu/add")
public CommonResult<String> add(@RequestBody @Valid SysMenuAddParam sysMenuAddParam) {
sysMenuService.add(sysMenuAddParam);
return CommonResult.ok();
}
/**
* 编辑菜单
*
*
* @date 2022/4/24 20:47
*/
@ApiOperationSupport(order = 4)
@ApiOperation("编辑菜单")
@CommonLog("编辑菜单")
@PostMapping("/sys/menu/edit")
public CommonResult<String> edit(@RequestBody @Valid SysMenuEditParam sysMenuEditParam) {
sysMenuService.edit(sysMenuEditParam);
return CommonResult.ok();
}
/**
* 更改菜单所属模块
*
*
* @date 2022/4/24 20:47
*/
@ApiOperationSupport(order = 5)
@ApiOperation("更改菜单所属模块")
@CommonLog("更改菜单所属模块")
@PostMapping("/sys/menu/changeModule")
public CommonResult<String> changeModule(@RequestBody @Valid SysMenuChangeModuleParam sysMenuChangeModuleParam) {
sysMenuService.changeModule(sysMenuChangeModuleParam);
return CommonResult.ok();
}
/**
* 删除菜单
*
*
* @date 2022/4/24 20:00
*/
@ApiOperationSupport(order = 6)
@ApiOperation("删除菜单")
@CommonLog("删除菜单")
@PostMapping("/sys/menu/delete")
public CommonResult<String> delete(@RequestBody @Valid @NotEmpty(message = "集合不能为空")
CommonValidList<SysMenuIdParam> sysMenuIdParamList) {
sysMenuService.delete(sysMenuIdParamList);
return CommonResult.ok();
}
/**
* 获取菜单详情
*
*
* @date 2022/4/24 20:00
*/
@ApiOperationSupport(order = 7)
@ApiOperation("获取菜单详情")
@GetMapping("/sys/menu/detail")
public CommonResult<SysMenu> detail(@Valid SysMenuIdParam sysMenuIdParam) {
return CommonResult.data(sysMenuService.detail(sysMenuIdParam));
}
/* ====菜单部分所需要用到的选择器==== */
/**
* 获取模块选择器
*
*
* @date 2022/4/24 20:00
*/
@ApiOperationSupport(order = 8)
@ApiOperation("获取模块选择器")
@GetMapping("/sys/menu/moduleSelector")
public CommonResult<List<SysModule>> moduleSelector(SysMenuSelectorModuleParam sysMenuSelectorModuleParam) {
return CommonResult.data(sysMenuService.moduleSelector(sysMenuSelectorModuleParam));
}
/**
* 获取菜单树选择器
*
*
* @date 2022/4/24 20:00
*/
@ApiOperationSupport(order = 9)
@ApiOperation("获取菜单树选择器")
@GetMapping("/sys/menu/menuTreeSelector")
public CommonResult<List<Tree<String>>> menuTreeSelector(SysMenuSelectorMenuParam sysMenuSelectorMenuParam) {
return CommonResult.data(sysMenuService.menuTreeSelector(sysMenuSelectorMenuParam));
}
}

View File

@@ -0,0 +1,114 @@
package mjkf.xinke.sys.modular.resource.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.common.annotation.CommonLog;
import mjkf.xinke.common.pojo.CommonResult;
import mjkf.xinke.common.pojo.CommonValidList;
import mjkf.xinke.sys.modular.resource.entity.SysModule;
import mjkf.xinke.sys.modular.resource.param.module.SysModuleAddParam;
import mjkf.xinke.sys.modular.resource.param.module.SysModuleEditParam;
import mjkf.xinke.sys.modular.resource.param.module.SysModuleIdParam;
import mjkf.xinke.sys.modular.resource.param.module.SysModulePageParam;
import mjkf.xinke.sys.modular.resource.service.SysModuleService;
import javax.annotation.Resource;
import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
/**
* 模块控制器
*
*
* @date 2022/6/27 14:12
**/
@Api(tags = "模块控制器")
@ApiSupport(author = "SNOWY_TEAM", order = 6)
@RestController
@Validated
public class SysModuleController {
@Resource
private SysModuleService sysModuleService;
/**
* 获取模块分页
*
*
* @date 2022/4/24 20:00
*/
@ApiOperationSupport(order = 1)
@ApiOperation("获取模块分页")
@GetMapping("/sys/module/page")
public CommonResult<Page<SysModule>> page(SysModulePageParam sysModulePageParam) {
return CommonResult.data(sysModuleService.page(sysModulePageParam));
}
/**
* 添加模块
*
*
* @date 2022/4/24 20:47
*/
@ApiOperationSupport(order = 2)
@ApiOperation("添加模块")
@CommonLog("添加模块")
@PostMapping("/sys/module/add")
public CommonResult<String> add(@RequestBody @Valid SysModuleAddParam sysModuleAddParam) {
sysModuleService.add(sysModuleAddParam);
return CommonResult.ok();
}
/**
* 编辑模块
*
*
* @date 2022/4/24 20:47
*/
@ApiOperationSupport(order = 3)
@ApiOperation("编辑模块")
@CommonLog("编辑模块")
@PostMapping("/sys/module/edit")
public CommonResult<String> edit(@RequestBody @Valid SysModuleEditParam sysModuleEditParam) {
sysModuleService.edit(sysModuleEditParam);
return CommonResult.ok();
}
/**
* 删除模块
*
*
* @date 2022/4/24 20:00
*/
@ApiOperationSupport(order = 4)
@ApiOperation("删除模块")
@CommonLog("删除模块")
@PostMapping("/sys/module/delete")
public CommonResult<String> delete(@RequestBody @Valid @NotEmpty(message = "集合不能为空")
CommonValidList<SysModuleIdParam> sysModuleIdParamList) {
sysModuleService.delete(sysModuleIdParamList);
return CommonResult.ok();
}
/**
* 获取模块详情
*
*
* @date 2022/4/24 20:00
*/
@ApiOperationSupport(order = 5)
@ApiOperation("获取模块详情")
@GetMapping("/sys/module/detail")
public CommonResult<SysModule> detail(@Valid SysModuleIdParam sysModuleIdParam) {
return CommonResult.data(sysModuleService.detail(sysModuleIdParam));
}
}

View File

@@ -0,0 +1,114 @@
package mjkf.xinke.sys.modular.resource.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.common.annotation.CommonLog;
import mjkf.xinke.common.pojo.CommonResult;
import mjkf.xinke.common.pojo.CommonValidList;
import mjkf.xinke.sys.modular.resource.entity.SysSpa;
import mjkf.xinke.sys.modular.resource.param.spa.SysSpaAddParam;
import mjkf.xinke.sys.modular.resource.param.spa.SysSpaEditParam;
import mjkf.xinke.sys.modular.resource.param.spa.SysSpaIdParam;
import mjkf.xinke.sys.modular.resource.param.spa.SysSpaPageParam;
import mjkf.xinke.sys.modular.resource.service.SysSpaService;
import javax.annotation.Resource;
import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
/**
* 单页面控制器
*
*
* @date 2022/6/27 14:14
**/
@Api(tags = "单页面控制器")
@ApiSupport(author = "SNOWY_TEAM", order = 7)
@RestController
@Validated
public class SysSpaController {
@Resource
private SysSpaService sysSpaService;
/**
* 获取单页面分页
*
*
* @date 2022/4/24 20:00
*/
@ApiOperationSupport(order = 1)
@ApiOperation("获取单页面分页")
@GetMapping("/sys/spa/page")
public CommonResult<Page<SysSpa>> page(SysSpaPageParam sysSpaPageParam) {
return CommonResult.data(sysSpaService.page(sysSpaPageParam));
}
/**
* 添加单页面
*
*
* @date 2022/4/24 20:47
*/
@ApiOperationSupport(order = 2)
@ApiOperation("添加单页面")
@CommonLog("添加单页面")
@PostMapping("/sys/spa/add")
public CommonResult<String> add(@RequestBody @Valid SysSpaAddParam sysSpaAddParam) {
sysSpaService.add(sysSpaAddParam);
return CommonResult.ok();
}
/**
* 编辑单页面
*
*
* @date 2022/4/24 20:47
*/
@ApiOperationSupport(order = 3)
@ApiOperation("编辑单页面")
@CommonLog("编辑单页面")
@PostMapping("/sys/spa/edit")
public CommonResult<String> edit(@RequestBody @Valid SysSpaEditParam sysSpaEditParam) {
sysSpaService.edit(sysSpaEditParam);
return CommonResult.ok();
}
/**
* 删除单页面
*
*
* @date 2022/4/24 20:00
*/
@ApiOperationSupport(order = 4)
@ApiOperation("删除单页面")
@CommonLog("删除单页面")
@PostMapping("/sys/spa/delete")
public CommonResult<String> delete(@RequestBody @Valid @NotEmpty(message = "集合不能为空")
CommonValidList<SysSpaIdParam> sysSpaIdParamList) {
sysSpaService.delete(sysSpaIdParamList);
return CommonResult.ok();
}
/**
* 获取单页面详情
*
*
* @date 2022/4/24 20:00
*/
@ApiOperationSupport(order = 5)
@ApiOperation("获取单页面详情")
@GetMapping("/sys/spa/detail")
public CommonResult<SysSpa> detail(@Valid SysSpaIdParam sysSpaIdParam) {
return CommonResult.data(sysSpaService.detail(sysSpaIdParam));
}
}

View File

@@ -0,0 +1,55 @@
package mjkf.xinke.sys.modular.resource.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/27 18:25
**/
@Getter
@Setter
@TableName("SYS_RESOURCE")
public class SysButton 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 title;
/** 编码 */
@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;
}

View File

@@ -0,0 +1,86 @@
package mjkf.xinke.sys.modular.resource.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/27 18:20
**/
@Getter
@Setter
@TableName("SYS_RESOURCE")
public class SysMenu 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 title;
/** 别名 */
@ApiModelProperty(value = "别名", position = 5)
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
private String name;
/** 编码 */
@ApiModelProperty(value = "编码", position = 6)
private String code;
/** 分类 */
@ApiModelProperty(value = "分类", position = 7)
private String category;
/** 模块 */
@ApiModelProperty(value = "模块", position = 8)
private String module;
/** 菜单类型 */
@ApiModelProperty(value = "菜单类型", position = 9)
private String menuType;
/** 路径 */
@ApiModelProperty(value = "路径", position = 10)
private String path;
/** 组件 */
@ApiModelProperty(value = "组件", position = 11)
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
private String component;
/** 图标 */
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
@ApiModelProperty(value = "图标", position = 12)
private String icon;
/** 颜色 */
@ApiModelProperty(value = "颜色", position = 13)
private String color;
/** 排序码 */
@ApiModelProperty(value = "排序码", position = 14)
private Integer sortCode;
/** 扩展信息 */
@ApiModelProperty(value = "扩展信息", position = 15)
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
private String extJson;
}

View File

@@ -0,0 +1,59 @@
package mjkf.xinke.sys.modular.resource.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/27 18:20
**/
@Getter
@Setter
@TableName("SYS_RESOURCE")
public class SysModule extends CommonEntity {
/** id */
@ApiModelProperty(value = "id", position = 1)
private String id;
/** 租户id */
@ApiModelProperty(value = "租户id", position = 2)
private String tenantId;
/** 标题 */
@ApiModelProperty(value = "标题", position = 3)
private String title;
/** 编码 */
@ApiModelProperty(value = "编码", position = 4)
private String code;
/** 分类 */
@ApiModelProperty(value = "分类", position = 5)
private String category;
/** 图标 */
@ApiModelProperty(value = "图标", position = 6)
private String icon;
/** 颜色 */
@ApiModelProperty(value = "颜色", position = 7)
private String color;
/** 排序码 */
@ApiModelProperty(value = "排序码", position = 8)
private Integer sortCode;
/** 扩展信息 */
@ApiModelProperty(value = "扩展信息", position = 9)
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
private String extJson;
}

View File

@@ -0,0 +1,71 @@
package mjkf.xinke.sys.modular.resource.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/27 18:27
**/
@Getter
@Setter
@TableName("SYS_RESOURCE")
public class SysSpa extends CommonEntity {
/** id */
@ApiModelProperty(value = "id", position = 1)
private String id;
/** 租户id */
@ApiModelProperty(value = "租户id", position = 2)
private String tenantId;
/** 标题 */
@ApiModelProperty(value = "标题", position = 3)
private String title;
/** 别名 */
@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 String menuType;
/** 路径 */
@ApiModelProperty(value = "路径", position = 8)
private String path;
/** 组件 */
@ApiModelProperty(value = "组件", position = 9)
private String component;
/** 图标 */
@ApiModelProperty(value = "图标", position = 10)
private String icon;
/** 排序码 */
@ApiModelProperty(value = "排序码", position = 11)
private Integer sortCode;
/** 扩展信息 */
@ApiModelProperty(value = "扩展信息", position = 12)
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
private String extJson;
}

View File

@@ -0,0 +1,41 @@
package mjkf.xinke.sys.modular.resource.enums;
import lombok.Getter;
import mjkf.xinke.common.exception.CommonException;
/**
* 资源分类枚举
*
*
* @date 2022/4/21 19:56
**/
@Getter
public enum SysResourceCategoryEnum {
/** 模块 */
MODULE("MODULE"),
/** 单页面 */
SPA("SPA"),
/** 菜单 */
MENU("MENU"),
/** 按钮 */
BUTTON("BUTTON");
private final String value;
SysResourceCategoryEnum(String value) {
this.value = value;
}
public static void validate(String value) {
boolean flag = MODULE.getValue().equals(value) || SPA.getValue().equals(value) || MENU.getValue().equals(value)
|| BUTTON.getValue().equals(value);
if(!flag) {
throw new CommonException("不支持的资源分类:{}", value);
}
}
}

View File

@@ -0,0 +1,41 @@
package mjkf.xinke.sys.modular.resource.enums;
import lombok.Getter;
import mjkf.xinke.common.exception.CommonException;
/**
* 菜单类型枚举
*
*
* @date 2022/4/21 19:56
**/
@Getter
public enum SysResourceMenuTypeEnum {
/** 目录 */
CATALOG("CATALOG"),
/** 组件 */
MENU("MENU"),
/** 内链 */
IFRAME("IFRAME"),
/** 外链 */
LINK("LINK");
private final String value;
SysResourceMenuTypeEnum(String value) {
this.value = value;
}
public static void validate(String value) {
boolean flag = CATALOG.getValue().equals(value) || MENU.getValue().equals(value) || IFRAME.getValue().equals(value) ||
LINK.getValue().equals(value);
if(!flag) {
throw new CommonException("不支持的菜单类型:{}", value);
}
}
}

View File

@@ -0,0 +1,14 @@
package mjkf.xinke.sys.modular.resource.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import mjkf.xinke.sys.modular.resource.entity.SysButton;
/**
* 按钮Mapper接口
*
*
* @date 2022/4/21 18:37
**/
public interface SysButtonMapper extends BaseMapper<SysButton> {
}

View File

@@ -0,0 +1,14 @@
package mjkf.xinke.sys.modular.resource.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import mjkf.xinke.sys.modular.resource.entity.SysMenu;
/**
* 菜单Mapper接口
*
*
* @date 2022/4/21 18:37
**/
public interface SysMenuMapper extends BaseMapper<SysMenu> {
}

View File

@@ -0,0 +1,14 @@
package mjkf.xinke.sys.modular.resource.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import mjkf.xinke.sys.modular.resource.entity.SysModule;
/**
* 模块Mapper接口
*
*
* @date 2022/4/21 18:37
**/
public interface SysModuleMapper extends BaseMapper<SysModule> {
}

View File

@@ -0,0 +1,14 @@
package mjkf.xinke.sys.modular.resource.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import mjkf.xinke.sys.modular.resource.entity.SysSpa;
/**
* 单页面Mapper接口
*
*
* @date 2022/4/21 18:37
**/
public interface SysSpaMapper extends BaseMapper<SysSpa> {
}

View File

@@ -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.sys.modular.resource.mapper.SysButtonMapper">
</mapper>

View File

@@ -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.sys.modular.resource.mapper.SysMenuMapper">
</mapper>

View File

@@ -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.sys.modular.resource.mapper.SysModuleMapper">
</mapper>

View File

@@ -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.sys.modular.resource.mapper.SysSpaMapper">
</mapper>

View File

@@ -0,0 +1,44 @@
package mjkf.xinke.sys.modular.resource.param.button;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
/**
* 按钮添加参数
*
*
* @date 2022/7/27 18:40
**/
@Getter
@Setter
public class SysButtonAddParam {
/** 父id */
@ApiModelProperty(value = "父id", required = true, position = 1)
@NotBlank(message = "parentId不能为空")
private String parentId;
/** 标题 */
@ApiModelProperty(value = "标题", required = true, position = 2)
@NotBlank(message = "title不能为空")
private String title;
/** 编码 */
@ApiModelProperty(value = "编码", required = true, position = 3)
@NotBlank(message = "code不能为空")
private String code;
/** 排序码 */
@ApiModelProperty(value = "排序码", required = true, position = 4)
@NotNull(message = "sortCode不能为空")
private Integer sortCode;
/** 扩展JSON */
@ApiModelProperty(value = "扩展JSON", position = 5)
private String extJson;
}

View File

@@ -0,0 +1,49 @@
package mjkf.xinke.sys.modular.resource.param.button;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
/**
* 按钮编辑参数
*
*
* @date 2022/7/27 18:40
**/
@Getter
@Setter
public class SysButtonEditParam {
/** 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 = "title不能为空")
private String title;
/** 编码 */
@ApiModelProperty(value = "编码", required = true, position = 4)
@NotBlank(message = "code不能为空")
private String code;
/** 排序码 */
@ApiModelProperty(value = "排序码", required = true, position = 5)
@NotNull(message = "sortCode不能为空")
private Integer sortCode;
/** 扩展JSON */
@ApiModelProperty(value = "扩展JSON", position = 6)
private String extJson;
}

View File

@@ -0,0 +1,24 @@
package mjkf.xinke.sys.modular.resource.param.button;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import javax.validation.constraints.NotBlank;
/**
* 按钮Id参数
*
*
* @date 2022/7/27 18:40
**/
@Getter
@Setter
public class SysButtonIdParam {
/** id */
@ApiModelProperty(value = "id", required = true)
@NotBlank(message = "id不能为空")
private String id;
}

View File

@@ -0,0 +1,41 @@
package mjkf.xinke.sys.modular.resource.param.button;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
/**
* 按钮查询参数
*
*
* @date 2022/7/27 18:40
**/
@Getter
@Setter
public class SysButtonPageParam {
/** 当前页 */
@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;
}

View File

@@ -0,0 +1,66 @@
package mjkf.xinke.sys.modular.resource.param.menu;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
/**
* 菜单添加参数
*
*
* @date 2022/7/27 18:40
**/
@Getter
@Setter
public class SysMenuAddParam {
/** 父id */
@ApiModelProperty(value = "父id", required = true, position = 1)
@NotBlank(message = "parentId不能为空")
private String parentId;
/** 标题 */
@ApiModelProperty(value = "标题", required = true, position = 2)
@NotBlank(message = "title不能为空")
private String title;
/** 菜单类型 */
@ApiModelProperty(value = "菜单类型", required = true, position = 3)
@NotBlank(message = "menuType不能为空")
private String menuType;
/** 模块 */
@ApiModelProperty(value = "模块", required = true, position = 4)
@NotBlank(message = "module不能为空")
private String module;
/** 路径 */
@ApiModelProperty(value = "路径", required = true, position = 5)
@NotBlank(message = "path不能为空")
private String path;
/** 排序码 */
@ApiModelProperty(value = "排序码", required = true, position = 6)
@NotNull(message = "sortCode不能为空")
private Integer sortCode;
/** 别名 */
@ApiModelProperty(value = "别名", position = 7)
private String name;
/** 组件 */
@ApiModelProperty(value = "组件", position = 8)
private String component;
/** 图标 */
@ApiModelProperty(value = "图标", position = 9)
private String icon;
/** 扩展信息 */
@ApiModelProperty(value = "扩展信息", position = 10)
private String extJson;
}

View File

@@ -0,0 +1,29 @@
package mjkf.xinke.sys.modular.resource.param.menu;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import javax.validation.constraints.NotBlank;
/**
* 菜单更改所属模块参数
*
*
* @date 2022/7/27 18:40
**/
@Getter
@Setter
public class SysMenuChangeModuleParam {
/** id */
@ApiModelProperty(value = "id", required = true)
@NotBlank(message = "id不能为空")
private String id;
/** 模块 */
@ApiModelProperty(value = "module", required = true)
@NotBlank(message = "module不能为空")
private String module;
}

View File

@@ -0,0 +1,71 @@
package mjkf.xinke.sys.modular.resource.param.menu;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
/**
* 菜单编辑参数
*
*
* @date 2022/7/27 18:40
**/
@Getter
@Setter
public class SysMenuEditParam {
/** 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 = "title不能为空")
private String title;
/** 菜单类型 */
@ApiModelProperty(value = "菜单类型", required = true, position = 4)
@NotBlank(message = "menuType不能为空")
private String menuType;
/** 模块 */
@ApiModelProperty(value = "模块", required = true, position = 5)
@NotBlank(message = "module不能为空")
private String module;
/** 路径 */
@ApiModelProperty(value = "路径", required = true, position = 6)
@NotBlank(message = "path不能为空")
private String path;
/** 排序码 */
@ApiModelProperty(value = "排序码", required = true, position = 7)
@NotNull(message = "sortCode不能为空")
private Integer sortCode;
/** 别名 */
@ApiModelProperty(value = "别名", position = 8)
private String name;
/** 组件 */
@ApiModelProperty(value = "组件", position = 9)
private String component;
/** 图标 */
@ApiModelProperty(value = "图标", position = 10)
private String icon;
/** 扩展信息 */
@ApiModelProperty(value = "扩展信息", position = 11)
private String extJson;
}

View File

@@ -0,0 +1,24 @@
package mjkf.xinke.sys.modular.resource.param.menu;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import javax.validation.constraints.NotBlank;
/**
* 菜单Id参数
*
*
* @date 2022/7/27 18:40
**/
@Getter
@Setter
public class SysMenuIdParam {
/** id */
@ApiModelProperty(value = "id", required = true)
@NotBlank(message = "id不能为空")
private String id;
}

View File

@@ -0,0 +1,41 @@
package mjkf.xinke.sys.modular.resource.param.menu;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
/**
* 菜单查询参数
*
*
* @date 2022/7/27 18:40
**/
@Getter
@Setter
public class SysMenuPageParam {
/** 当前页 */
@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 module;
}

View File

@@ -0,0 +1,21 @@
package mjkf.xinke.sys.modular.resource.param.menu;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
/**
* 菜单选择器参数
*
*
* @date 2022/7/27 18:40
**/
@Getter
@Setter
public class SysMenuSelectorMenuParam {
/** 模块 */
@ApiModelProperty(value = "模块")
private String module;
}

View File

@@ -0,0 +1,21 @@
package mjkf.xinke.sys.modular.resource.param.menu;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
/**
* 模块选择器参数
*
*
* @date 2022/7/27 18:40
**/
@Getter
@Setter
public class SysMenuSelectorModuleParam {
/** 名称关键词 */
@ApiModelProperty(value = "名称关键词")
private String searchKey;
}

View File

@@ -0,0 +1,25 @@
package mjkf.xinke.sys.modular.resource.param.menu;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
/**
* 菜单树查询参数
*
*
* @date 2022/7/27 18:40
**/
@Getter
@Setter
public class SysMenuTreeParam {
/** 模块 */
@ApiModelProperty(value = "模块")
private String module;
/** 名称关键词 */
@ApiModelProperty(value = "名称关键词")
private String searchKey;
}

View File

@@ -0,0 +1,44 @@
package mjkf.xinke.sys.modular.resource.param.module;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
/**
* 模块添加参数
*
*
* @date 2022/7/27 18:40
**/
@Getter
@Setter
public class SysModuleAddParam {
/** 标题 */
@ApiModelProperty(value = "标题", required = true, position = 1)
@NotBlank(message = "title不能为空")
private String title;
/** 图标 */
@ApiModelProperty(value = "图标", required = true, position = 2)
@NotBlank(message = "icon不能为空")
private String icon;
/** 颜色 */
@ApiModelProperty(value = "颜色", required = true, position = 3)
@NotBlank(message = "color不能为空")
private String color;
/** 排序码 */
@ApiModelProperty(value = "排序码", required = true, position = 4)
@NotNull(message = "sortCode不能为空")
private Integer sortCode;
/** 扩展信息 */
@ApiModelProperty(value = "扩展信息", position = 5)
private String extJson;
}

View File

@@ -0,0 +1,49 @@
package mjkf.xinke.sys.modular.resource.param.module;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
/**
* 模块编辑参数
*
*
* @date 2022/7/27 18:40
**/
@Getter
@Setter
public class SysModuleEditParam {
/** id */
@ApiModelProperty(value = "id", required = true, position = 1)
@NotBlank(message = "id不能为空")
private String id;
/** 标题 */
@ApiModelProperty(value = "标题", required = true, position = 2)
@NotBlank(message = "title不能为空")
private String title;
/** 图标 */
@ApiModelProperty(value = "图标", required = true, position = 3)
@NotBlank(message = "icon不能为空")
private String icon;
/** 颜色 */
@ApiModelProperty(value = "颜色", required = true, position = 4)
@NotBlank(message = "color不能为空")
private String color;
/** 排序码 */
@ApiModelProperty(value = "排序码", required = true, position = 5)
@NotNull(message = "sortCode不能为空")
private Integer sortCode;
/** 扩展信息 */
@ApiModelProperty(value = "扩展信息", position = 6)
private String extJson;
}

View File

@@ -0,0 +1,24 @@
package mjkf.xinke.sys.modular.resource.param.module;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import javax.validation.constraints.NotBlank;
/**
* 模块Id参数
*
*
* @date 2022/7/27 18:40
**/
@Getter
@Setter
public class SysModuleIdParam {
/** id */
@ApiModelProperty(value = "id", required = true)
@NotBlank(message = "id不能为空")
private String id;
}

View File

@@ -0,0 +1,37 @@
package mjkf.xinke.sys.modular.resource.param.module;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
/**
* 模块查询参数
*
*
* @date 2022/7/27 18:40
**/
@Getter
@Setter
public class SysModulePageParam {
/** 当前页 */
@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;
}

View File

@@ -0,0 +1,56 @@
package mjkf.xinke.sys.modular.resource.param.spa;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
/**
* 单页面添加参数
*
*
* @date 2022/7/27 18:40
**/
@Getter
@Setter
public class SysSpaAddParam {
/** 标题 */
@ApiModelProperty(value = "标题", required = true, position = 1)
@NotBlank(message = "title不能为空")
private String title;
/** 菜单类型 */
@ApiModelProperty(value = "菜单类型", required = true, position = 2)
@NotBlank(message = "menuType不能为空")
private String menuType;
/** 别名 */
@ApiModelProperty(value = "别名", required = true, position = 3)
private String name;
/** 路径 */
@ApiModelProperty(value = "路径", required = true, position = 4)
@NotBlank(message = "path不能为空")
private String path;
/** 组件 */
@ApiModelProperty(value = "组件", required = true, position = 5)
private String component;
/** 图标 */
@ApiModelProperty(value = "图标", required = true, position = 6)
private String icon;
/** 排序码 */
@ApiModelProperty(value = "排序码", required = true, position = 7)
@NotNull(message = "sortCode不能为空")
private Integer sortCode;
/** 扩展信息 */
@ApiModelProperty(value = "扩展信息", position = 8)
private String extJson;
}

View File

@@ -0,0 +1,61 @@
package mjkf.xinke.sys.modular.resource.param.spa;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
/**
* 单页面编辑参数
*
*
* @date 2022/7/27 18:40
**/
@Getter
@Setter
public class SysSpaEditParam {
/** id */
@ApiModelProperty(value = "id", required = true, position = 1)
@NotBlank(message = "id不能为空")
private String id;
/** 标题 */
@ApiModelProperty(value = "标题", required = true, position = 2)
@NotBlank(message = "title不能为空")
private String title;
/** 菜单类型 */
@ApiModelProperty(value = "菜单类型", required = true, position = 3)
@NotBlank(message = "menuType不能为空")
private String menuType;
/** 别名 */
@ApiModelProperty(value = "别名", required = true, position = 4)
private String name;
/** 路径 */
@ApiModelProperty(value = "路径", required = true, position = 5)
@NotBlank(message = "path不能为空")
private String path;
/** 组件 */
@ApiModelProperty(value = "组件", required = true, position = 6)
private String component;
/** 图标 */
@ApiModelProperty(value = "图标", required = true, position = 7)
private String icon;
/** 排序码 */
@ApiModelProperty(value = "排序码", required = true, position = 8)
@NotNull(message = "sortCode不能为空")
private Integer sortCode;
/** 扩展信息 */
@ApiModelProperty(value = "扩展信息", position = 9)
private String extJson;
}

View File

@@ -0,0 +1,24 @@
package mjkf.xinke.sys.modular.resource.param.spa;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import javax.validation.constraints.NotBlank;
/**
* 单页面Id参数
*
*
* @date 2022/7/27 18:40
**/
@Getter
@Setter
public class SysSpaIdParam {
/** id */
@ApiModelProperty(value = "id", required = true)
@NotBlank(message = "id不能为空")
private String id;
}

View File

@@ -0,0 +1,37 @@
package mjkf.xinke.sys.modular.resource.param.spa;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
/**
* 单页面查询参数
*
*
* @date 2022/7/27 18:40
**/
@Getter
@Setter
public class SysSpaPageParam {
/** 当前页 */
@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;
}

View File

@@ -0,0 +1,26 @@
package mjkf.xinke.sys.modular.resource.provider;
import org.springframework.stereotype.Service;
import mjkf.xinke.sys.api.SysButtonApi;
import mjkf.xinke.sys.modular.resource.service.SysButtonService;
import javax.annotation.Resource;
/**
* 按钮API接口实现类
*
*
* @date 2022/11/1 13:50
**/
@Service
public class SysButtonApiProvider implements SysButtonApi {
@Resource
private SysButtonService sysButtonService;
@Override
public void addForGenButton(String menuId, String className, String functionName) {
sysButtonService.addForGenButton(menuId, className, functionName);
}
}

View File

@@ -0,0 +1,26 @@
package mjkf.xinke.sys.modular.resource.provider;
import org.springframework.stereotype.Service;
import mjkf.xinke.sys.api.SysMenuApi;
import mjkf.xinke.sys.modular.resource.service.SysMenuService;
import javax.annotation.Resource;
/**
* 菜单API接口实现类
*
*
* @date 2022/11/1 13:50
**/
@Service
public class SysMenuApiProvider implements SysMenuApi {
@Resource
private SysMenuService sysMenuService;
@Override
public String addForGenMenu(String parentId, String busName, String module, String title, String path) {
return sysMenuService.addForGenMenu(parentId, busName, title, module, path);
}
}

View File

@@ -0,0 +1,78 @@
package mjkf.xinke.sys.modular.resource.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import mjkf.xinke.sys.modular.resource.entity.SysButton;
import mjkf.xinke.sys.modular.resource.param.button.SysButtonAddParam;
import mjkf.xinke.sys.modular.resource.param.button.SysButtonEditParam;
import mjkf.xinke.sys.modular.resource.param.button.SysButtonIdParam;
import mjkf.xinke.sys.modular.resource.param.button.SysButtonPageParam;
import java.util.List;
/**
* 按钮Service接口
*
*
* @date 2022/6/27 14:01
**/
public interface SysButtonService extends IService<SysButton> {
/**
* 获取按钮分页
*
*
* @date 2022/4/24 20:08
*/
Page<SysButton> page(SysButtonPageParam sysButtonPageParam);
/**
* 添加按钮
*
*
* @date 2022/4/24 20:48
*/
void add(SysButtonAddParam sysButtonAddParam);
/**
* 代码生成按钮插入
*
*
* @date 2022/11/1 15:34
* @return java.lang.String
**/
void addForGenButton(String menuId, String className, String functionName);
/**
* 编辑按钮
*
*
* @date 2022/4/24 21:13
*/
void edit(SysButtonEditParam sysButtonEditParam);
/**
* 删除按钮
*
*
* @date 2022/4/24 21:18
*/
void delete(List<SysButtonIdParam> sysButtonIdParamList);
/**
* 获取按钮详情
*
*
* @date 2022/4/24 21:18
*/
SysButton detail(SysButtonIdParam sysButtonIdParam);
/**
* 获取按钮详情
*
*
* @date 2022/4/24 21:18
*/
SysButton queryEntity(String id);
}

View File

@@ -0,0 +1,129 @@
package mjkf.xinke.sys.modular.resource.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.sys.modular.resource.entity.SysMenu;
import mjkf.xinke.sys.modular.resource.entity.SysModule;
import mjkf.xinke.sys.modular.resource.param.menu.*;
import java.util.List;
/**
* 菜单Service接口
*
*
* @date 2022/6/27 14:02
**/
public interface SysMenuService extends IService<SysMenu> {
/**
* 获取菜单分页
*
*
* @date 2022/4/24 20:08
*/
Page<SysMenu> page(SysMenuPageParam sysMenuPageParam);
/**
* 获取菜单树
*
*
* @date 2022/4/24 20:08
*/
List<Tree<String>> tree(SysMenuTreeParam sysMenuTreeParam);
/**
* 添加菜单
*
*
* @date 2022/4/24 20:48
*/
void add(SysMenuAddParam sysMenuAddParam);
/**
* 代码生成菜单插入
*
*
* @date 2022/11/1 14:06
**/
String addForGenMenu(String parentId, String busName, String title, String module, String path);
/**
* 编辑菜单
*
*
* @date 2022/4/24 21:13
*/
void edit(SysMenuEditParam sysMenuEditParam);
/**
* 更改菜单所属模块
*
*
* @date 2022/9/26 13:09
**/
void changeModule(SysMenuChangeModuleParam sysMenuChangeModuleParam);
/**
* 删除菜单
*
*
* @date 2022/4/24 21:18
*/
void delete(List<SysMenuIdParam> sysMenuIdParamList);
/**
* 获取菜单详情
*
*
* @date 2022/4/24 21:18
*/
SysMenu detail(SysMenuIdParam sysMenuIdParam);
/**
* 获取菜单详情
*
*
* @date 2022/4/24 21:18
*/
SysMenu queryEntity(String id);
/* ====以下为各种递归方法==== */
/**
* 根据id获取所有的子数据列表
*
*
* @date 2022/8/2 14:52
*/
List<SysMenu> getChildListById(List<SysMenu> originDataList, String id, boolean includeSelf);
/**
* 根据id获取所有的父数据列表
*
*
* @date 2022/8/2 14:52
*/
List<SysMenu> getParentListById(List<SysMenu> originDataList, String id, boolean includeSelf);
/* ====菜单部分所需要用到的选择器==== */
/**
* 获取模块选择器
*
*
* @date 2022/8/2 14:53
*/
List<SysModule> moduleSelector(SysMenuSelectorModuleParam sysMenuSelectorModuleParam);
/**
* 获取菜单树选择器
*
*
* @date 2022/4/24 20:08
*/
List<Tree<String>> menuTreeSelector(SysMenuSelectorMenuParam sysMenuSelectorMenuParam);
}

View File

@@ -0,0 +1,69 @@
package mjkf.xinke.sys.modular.resource.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import mjkf.xinke.sys.modular.resource.entity.SysModule;
import mjkf.xinke.sys.modular.resource.param.module.SysModuleAddParam;
import mjkf.xinke.sys.modular.resource.param.module.SysModuleEditParam;
import mjkf.xinke.sys.modular.resource.param.module.SysModuleIdParam;
import mjkf.xinke.sys.modular.resource.param.module.SysModulePageParam;
import java.util.List;
/**
* 模块Service接口
*
*
* @date 2022/6/27 14:03
**/
public interface SysModuleService extends IService<SysModule> {
/**
* 获取模块分页
*
*
* @date 2022/4/24 20:08
*/
Page<SysModule> page(SysModulePageParam sysModulePageParam);
/**
* 添加模块
*
*
* @date 2022/4/24 20:48
*/
void add(SysModuleAddParam sysModuleAddParam);
/**
* 编辑模块
*
*
* @date 2022/4/24 21:13
*/
void edit(SysModuleEditParam sysModuleEditParam);
/**
* 删除模块
*
*
* @date 2022/4/24 21:18
*/
void delete(List<SysModuleIdParam> sysModuleIdParamList);
/**
* 获取模块详情
*
*
* @date 2022/4/24 21:18
*/
SysModule detail(SysModuleIdParam sysModuleIdParam);
/**
* 获取模块详情
*
*
* @date 2022/4/24 21:18
*/
SysModule queryEntity(String id);
}

View File

@@ -0,0 +1,69 @@
package mjkf.xinke.sys.modular.resource.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import mjkf.xinke.sys.modular.resource.entity.SysSpa;
import mjkf.xinke.sys.modular.resource.param.spa.SysSpaAddParam;
import mjkf.xinke.sys.modular.resource.param.spa.SysSpaEditParam;
import mjkf.xinke.sys.modular.resource.param.spa.SysSpaIdParam;
import mjkf.xinke.sys.modular.resource.param.spa.SysSpaPageParam;
import java.util.List;
/**
* 单页面Service接口
*
*
* @date 2022/6/27 14:03
**/
public interface SysSpaService extends IService<SysSpa> {
/**
* 获取单页面分页
*
*
* @date 2022/4/24 20:08
*/
Page<SysSpa> page(SysSpaPageParam sysSpaPageParam);
/**
* 添加单页面
*
*
* @date 2022/4/24 20:48
*/
void add(SysSpaAddParam sysSpaAddParam);
/**
* 编辑单页面
*
*
* @date 2022/4/24 21:13
*/
void edit(SysSpaEditParam sysSpaEditParam);
/**
* 删除单页面
*
*
* @date 2022/4/24 21:18
*/
void delete(List<SysSpaIdParam> sysSpaIdParamList);
/**
* 获取单页面详情
*
*
* @date 2022/4/24 21:18
*/
SysSpa detail(SysSpaIdParam sysSpaIdParam);
/**
* 获取单页面详情
*
*
* @date 2022/4/24 21:18
*/
SysSpa queryEntity(String id);
}

View File

@@ -0,0 +1,175 @@
package mjkf.xinke.sys.modular.resource.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.collection.CollectionUtil;
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.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 org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
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.sys.core.enums.SysDataTypeEnum;
import mjkf.xinke.sys.modular.relation.entity.SysRelation;
import mjkf.xinke.sys.modular.relation.enums.SysRelationCategoryEnum;
import mjkf.xinke.sys.modular.relation.service.SysRelationService;
import mjkf.xinke.sys.modular.resource.entity.SysButton;
import mjkf.xinke.sys.modular.resource.entity.SysMenu;
import mjkf.xinke.sys.modular.resource.enums.SysResourceCategoryEnum;
import mjkf.xinke.sys.modular.resource.mapper.SysButtonMapper;
import mjkf.xinke.sys.modular.resource.param.button.SysButtonAddParam;
import mjkf.xinke.sys.modular.resource.param.button.SysButtonEditParam;
import mjkf.xinke.sys.modular.resource.param.button.SysButtonIdParam;
import mjkf.xinke.sys.modular.resource.param.button.SysButtonPageParam;
import mjkf.xinke.sys.modular.resource.service.SysButtonService;
import mjkf.xinke.sys.modular.resource.service.SysMenuService;
import javax.annotation.Resource;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/**
* 按钮Service接口实现类
*
*
* @date 2022/6/27 14:25
**/
@Service
public class SysButtonServiceImpl extends ServiceImpl<SysButtonMapper, SysButton> implements SysButtonService {
@Resource
private SysRelationService sysRelationService;
@Resource
private SysMenuService sysMenuService;
@Override
public Page<SysButton> page(SysButtonPageParam sysButtonPageParam) {
QueryWrapper<SysButton> queryWrapper = new QueryWrapper<>();
queryWrapper.lambda().eq(SysButton::getCategory, SysResourceCategoryEnum.BUTTON.getValue());
if(ObjectUtil.isNotEmpty(sysButtonPageParam.getParentId())) {
queryWrapper.lambda().eq(SysButton::getParentId, sysButtonPageParam.getParentId());
}
if(ObjectUtil.isNotEmpty(sysButtonPageParam.getSearchKey())) {
queryWrapper.lambda().like(SysButton::getTitle, sysButtonPageParam.getSearchKey());
}
if(ObjectUtil.isAllNotEmpty(sysButtonPageParam.getSortField(), sysButtonPageParam.getSortOrder())) {
CommonSortOrderEnum.validate(sysButtonPageParam.getSortOrder());
queryWrapper.orderBy(true, sysButtonPageParam.getSortOrder().equals(CommonSortOrderEnum.ASC.getValue()),
StrUtil.toUnderlineCase(sysButtonPageParam.getSortField()));
} else {
queryWrapper.lambda().orderByAsc(SysButton::getSortCode);
}
return this.page(CommonPageRequest.defaultPage(), queryWrapper);
}
@Transactional(rollbackFor = Exception.class)
@Override
public void add(SysButtonAddParam sysButtonAddParam) {
SysButton sysButton = BeanUtil.toBean(sysButtonAddParam, SysButton.class);
boolean repeatCode = this.count(new LambdaQueryWrapper<SysButton>()
.eq(SysButton::getCategory, SysResourceCategoryEnum.BUTTON.getValue())
.eq(SysButton::getCode, sysButton.getCode())) > 0;
if(repeatCode) {
throw new CommonException("存在重复的按钮,编码为:{}", sysButton.getCode());
}
sysButton.setCategory(SysResourceCategoryEnum.BUTTON.getValue());
this.save(sysButton);
// 发布增加事件
CommonDataChangeEventCenter.doAddWithData(SysDataTypeEnum.RESOURCE.getValue(), JSONUtil.createArray().put(sysButton));
}
@Override
public void addForGenButton(String menuId, String className, String functionName) {
SysMenu sysMenu = sysMenuService.queryEntity(menuId);
String classNameFirstLower = StrUtil.lowerFirst(className);
CollectionUtil.newArrayList(JSONUtil.createObj().set("title", "新增" + functionName).set("code", classNameFirstLower + "Add").set("sortCode", 1),
JSONUtil.createObj().set("title", "编辑" + functionName).set("code", classNameFirstLower + "Edit").set("sortCode", 2),
JSONUtil.createObj().set("title", "删除" + functionName).set("code", classNameFirstLower + "Delete").set("sortCode", 3),
JSONUtil.createObj().set("title", "批量删除").set("code", classNameFirstLower + "BatchDelete").set("sortCode", 4)).forEach(jsonObject -> {
SysButtonAddParam sysButtonAddParam = new SysButtonAddParam();
BeanUtil.copyProperties(jsonObject, sysButtonAddParam);
sysButtonAddParam.setParentId(sysMenu.getId());
this.add(sysButtonAddParam);
});
}
@Transactional(rollbackFor = Exception.class)
@Override
public void edit(SysButtonEditParam sysButtonEditParam) {
SysButton sysButton = this.queryEntity(sysButtonEditParam.getId());
BeanUtil.copyProperties(sysButtonEditParam, sysButton);
boolean repeatCode = this.count(new LambdaQueryWrapper<SysButton>()
.eq(SysButton::getCategory, SysResourceCategoryEnum.BUTTON.getValue())
.eq(SysButton::getCode, sysButton.getCode())
.ne(SysButton::getId, sysButtonEditParam.getId())) > 0;
if(repeatCode) {
throw new CommonException("存在重复的按钮,编码为:{}", sysButton.getCode());
}
this.updateById(sysButton);
// 发布更新事件
CommonDataChangeEventCenter.doUpdateWithData(SysDataTypeEnum.RESOURCE.getValue(), JSONUtil.createArray().put(sysButton));
}
@Override
public void delete(List<SysButtonIdParam> sysButtonIdParamList) {
List<String> buttonIdList = CollStreamUtil.toList(sysButtonIdParamList, SysButtonIdParam::getId);
if(ObjectUtil.isNotEmpty(buttonIdList)) {
// 获取按钮的父菜单id集合
List<String> parentMenuIdList = sysMenuService.list(new LambdaQueryWrapper<SysMenu>().in(SysMenu::getId, buttonIdList)
.eq(SysMenu::getCategory, SysResourceCategoryEnum.BUTTON.getValue())).stream().map(SysMenu::getParentId)
.collect(Collectors.toList());
if(ObjectUtil.isNotEmpty(parentMenuIdList)) {
sysRelationService.list(new LambdaQueryWrapper<SysRelation>().in(SysRelation::getTargetId, parentMenuIdList)
.eq(SysRelation::getCategory, SysRelationCategoryEnum.SYS_ROLE_HAS_RESOURCE.getValue())
.isNotNull(SysRelation::getExtJson)).forEach(sysRelation -> {
JSONObject extJsonObject = JSONUtil.parseObj(sysRelation.getExtJson());
List<String> buttonInfoList = extJsonObject.getBeanList("buttonInfo", String.class);
if (ObjectUtil.isNotEmpty(buttonInfoList)) {
Set<String> intersectionDistinct = CollectionUtil.intersectionDistinct(buttonIdList, buttonInfoList);
if(ObjectUtil.isNotEmpty(intersectionDistinct)) {
Collection<String> disjunction = CollectionUtil.disjunction(buttonInfoList, intersectionDistinct);
extJsonObject.set("buttonInfo", disjunction);
}
}
// 清除对应的角色与资源信息中的【授权的按钮信息】
sysRelationService.update(new LambdaUpdateWrapper<SysRelation>().eq(SysRelation::getId, sysRelation.getId())
.set(SysRelation::getExtJson, JSONUtil.toJsonStr(extJsonObject)));
});
// 执行删除
this.removeByIds(buttonIdList);
// 发布删除事件
CommonDataChangeEventCenter.doDeleteWithDataId(SysDataTypeEnum.RESOURCE.getValue(), buttonIdList);
}
}
}
@Override
public SysButton detail(SysButtonIdParam sysButtonIdParam) {
return this.queryEntity(sysButtonIdParam.getId());
}
@Override
public SysButton queryEntity(String id) {
SysButton sysButton = this.getById(id);
if(ObjectUtil.isEmpty(sysButton)) {
throw new CommonException("按钮不存在id值为{}", id);
}
return sysButton;
}
}

View File

@@ -0,0 +1,417 @@
package mjkf.xinke.sys.modular.resource.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.collection.CollUtil;
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.JSONUtil;
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 org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
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.sys.core.enums.SysDataTypeEnum;
import mjkf.xinke.sys.modular.relation.entity.SysRelation;
import mjkf.xinke.sys.modular.relation.enums.SysRelationCategoryEnum;
import mjkf.xinke.sys.modular.relation.service.SysRelationService;
import mjkf.xinke.sys.modular.resource.entity.SysMenu;
import mjkf.xinke.sys.modular.resource.entity.SysModule;
import mjkf.xinke.sys.modular.resource.enums.SysResourceCategoryEnum;
import mjkf.xinke.sys.modular.resource.enums.SysResourceMenuTypeEnum;
import mjkf.xinke.sys.modular.resource.mapper.SysMenuMapper;
import mjkf.xinke.sys.modular.resource.param.menu.*;
import mjkf.xinke.sys.modular.resource.service.SysMenuService;
import mjkf.xinke.sys.modular.resource.service.SysModuleService;
import javax.annotation.Resource;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
/**
* 菜单Service接口实现类
*
*
* @date 2022/6/27 14:25
**/
@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService {
@Resource
private SysRelationService sysRelationService;
@Resource
private SysModuleService sysModuleService;
@Override
public Page<SysMenu> page(SysMenuPageParam sysMenuPageParam) {
QueryWrapper<SysMenu> queryWrapper = new QueryWrapper<>();
queryWrapper.lambda().eq(SysMenu::getCategory, SysResourceCategoryEnum.MENU.getValue());
if(ObjectUtil.isNotEmpty(sysMenuPageParam.getSearchKey())) {
queryWrapper.lambda().like(SysMenu::getTitle, sysMenuPageParam.getSearchKey());
}
if(ObjectUtil.isNotEmpty(sysMenuPageParam.getModule())) {
queryWrapper.lambda().like(SysMenu::getModule, sysMenuPageParam.getModule());
}
if(ObjectUtil.isAllNotEmpty(sysMenuPageParam.getSortField(), sysMenuPageParam.getSortOrder())) {
CommonSortOrderEnum.validate(sysMenuPageParam.getSortOrder());
queryWrapper.orderBy(true, sysMenuPageParam.getSortOrder().equals(CommonSortOrderEnum.ASC.getValue()),
StrUtil.toUnderlineCase(sysMenuPageParam.getSortField()));
} else {
queryWrapper.lambda().orderByAsc(SysMenu::getSortCode);
}
return this.page(CommonPageRequest.defaultPage(), queryWrapper);
}
@Override
public List<Tree<String>> tree(SysMenuTreeParam sysMenuTreeParam) {
LambdaQueryWrapper<SysMenu> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(SysMenu::getCategory, SysResourceCategoryEnum.MENU.getValue())
.orderByAsc(SysMenu::getSortCode);
if(ObjectUtil.isNotEmpty(sysMenuTreeParam.getModule())) {
lambdaQueryWrapper.eq(SysMenu::getModule, sysMenuTreeParam.getModule());
}
if(ObjectUtil.isNotEmpty(sysMenuTreeParam.getSearchKey())) {
lambdaQueryWrapper.like(SysMenu::getTitle, sysMenuTreeParam.getSearchKey());
}
List<SysMenu> resourceList = this.list(lambdaQueryWrapper);
// 填充上层的父级菜单
this.fillParentSysMenuInfo(resourceList);
List<TreeNode<String>> treeNodeList = resourceList.stream().map(sysMenu ->
new TreeNode<>(sysMenu.getId(), sysMenu.getParentId(),
sysMenu.getTitle(), sysMenu.getSortCode()).setExtra(JSONUtil.parseObj(sysMenu)))
.collect(Collectors.toList());
return TreeUtil.build(treeNodeList, "0");
}
private void fillParentSysMenuInfo(List<SysMenu> resourceList) {
if(CollUtil.isNotEmpty(resourceList)){
List<SysMenu> parentRelationSysMenus = resourceList.stream().filter(distinctByKey(SysMenu::getParentId)).collect(Collectors.toList());
List<String> parentIds = null;
if(CollUtil.isNotEmpty(parentRelationSysMenus)){
parentIds = CollUtil.newArrayList();
for(SysMenu parentRelationSysMenu : parentRelationSysMenus){
if(!StrUtil.equals(parentRelationSysMenu.getParentId(),"0")){
parentIds.add(parentRelationSysMenu.getParentId());
}
}
}
if(CollUtil.isNotEmpty(parentIds)){
LambdaQueryWrapper<SysMenu> parentSysMenuLambdaQueryWrapper = new LambdaQueryWrapper<>();
parentSysMenuLambdaQueryWrapper.in(SysMenu::getId,parentIds);
List<SysMenu> parentSysMenus = this.list(parentSysMenuLambdaQueryWrapper);
if(CollUtil.isNotEmpty(parentSysMenus)){
this.fillParentSysMenuInfo(parentSysMenus);
resourceList.addAll(parentSysMenus);
}
}
}
}
private static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
Set<Object> seen = ConcurrentHashMap.newKeySet();
return t -> seen.add(keyExtractor.apply(t));
}
@Transactional(rollbackFor = Exception.class)
@Override
public void add(SysMenuAddParam sysMenuAddParam) {
checkParam(sysMenuAddParam);
SysMenu sysMenu = BeanUtil.toBean(sysMenuAddParam, SysMenu.class);
boolean repeatTitle = this.count(new LambdaQueryWrapper<SysMenu>().eq(SysMenu::getParentId, sysMenu.getParentId())
.eq(SysMenu::getCategory, SysResourceCategoryEnum.MENU.getValue()).eq(SysMenu::getTitle, sysMenu.getTitle())) > 0;
if(repeatTitle) {
throw new CommonException("存在重复的菜单,名称为:{}", sysMenu.getTitle());
}
List<SysMenu> originDataList = this.list(new LambdaQueryWrapper<SysMenu>().eq(SysMenu::getCategory,
SysResourceCategoryEnum.MENU.getValue()));
if(!"0".equals(sysMenuAddParam.getParentId())) {
SysMenu parentMenu = this.getById(originDataList, sysMenuAddParam.getParentId());
if(ObjectUtil.isEmpty(parentMenu)) {
throw new CommonException("上级菜单不存在id值为{}", sysMenuAddParam.getParentId());
}
if(!parentMenu.getModule().equals(sysMenuAddParam.getModule())) {
throw new CommonException("module与上级菜单不一致");
}
}
sysMenu.setCategory(SysResourceCategoryEnum.MENU.getValue());
this.save(sysMenu);
// 发布增加事件
CommonDataChangeEventCenter.doAddWithData(SysDataTypeEnum.RESOURCE.getValue(), JSONUtil.createArray().put(sysMenu));
}
@Transactional(rollbackFor = Exception.class)
@Override
public String addForGenMenu(String parentId, String busName, String title, String module, String path) {
// 参数校验
if(!"0".equals(parentId)) {
SysMenu parentMenu = this.queryEntity(parentId);
if(ObjectUtil.isEmpty(parentMenu)) {
throw new CommonException("上级菜单不存在id值为{}", parentId);
}
if(!parentMenu.getModule().equals(module)) {
throw new CommonException("module与上级菜单不一致");
}
}
// 删除老菜单(同时删除其下面的菜单、按钮,清除对应的角色与资源信息
SysMenu sysOldMenu = this.getOne(new LambdaQueryWrapper<SysMenu>().eq(SysMenu::getTitle, title)
.eq(SysMenu::getCategory, SysResourceCategoryEnum.MENU.getValue())
.eq(SysMenu::getMenuType, SysResourceMenuTypeEnum.MENU.getValue()).eq(SysMenu::getPath, path));
if(ObjectUtil.isNotEmpty(sysOldMenu)) {
SysMenuIdParam sysMenuIdParam = new SysMenuIdParam();
sysMenuIdParam.setId(sysOldMenu.getId());
this.delete(CollectionUtil.newArrayList(sysMenuIdParam));
}
// 插入新菜单
SysMenu sysMenu = new SysMenu();
sysMenu.setParentId(parentId);
sysMenu.setTitle(title);
sysMenu.setName(busName);
sysMenu.setCode(RandomUtil.randomString(10));
sysMenu.setCategory(SysResourceCategoryEnum.MENU.getValue());
sysMenu.setModule(module);
sysMenu.setMenuType(SysResourceMenuTypeEnum.MENU.getValue());
sysMenu.setPath(path);
sysMenu.setComponent(StrUtil.removePrefix(path, StrUtil.SLASH) + StrUtil.SLASH + "index");
sysMenu.setIcon("appstore-outlined");
sysMenu.setSortCode(99);
this.save(sysMenu);
return sysMenu.getId();
}
private void checkParam(SysMenuAddParam sysMenuAddParam) {
SysResourceMenuTypeEnum.validate(sysMenuAddParam.getMenuType());
if(SysResourceMenuTypeEnum.MENU.getValue().equals(sysMenuAddParam.getMenuType())) {
if(ObjectUtil.isEmpty(sysMenuAddParam.getName())) {
throw new CommonException("name不能为空");
}
if(ObjectUtil.isEmpty(sysMenuAddParam.getComponent())) {
throw new CommonException("component不能为空");
}
} else if(SysResourceMenuTypeEnum.IFRAME.getValue().equals(sysMenuAddParam.getMenuType()) ||
SysResourceMenuTypeEnum.LINK.getValue().equals(sysMenuAddParam.getMenuType())) {
sysMenuAddParam.setName(RandomUtil.randomNumbers(10));
sysMenuAddParam.setComponent(null);
} else {
sysMenuAddParam.setName(null);
sysMenuAddParam.setComponent(null);
}
}
@Transactional(rollbackFor = Exception.class)
@Override
public void edit(SysMenuEditParam sysMenuEditParam) {
SysMenu sysMenu = this.queryEntity(sysMenuEditParam.getId());
checkParam(sysMenuEditParam);
BeanUtil.copyProperties(sysMenuEditParam, sysMenu);
boolean repeatTitle = this.count(new LambdaQueryWrapper<SysMenu>().eq(SysMenu::getParentId, sysMenu.getParentId())
.eq(SysMenu::getCategory, SysResourceCategoryEnum.MENU.getValue()).eq(SysMenu::getTitle, sysMenu.getTitle())
.ne(SysMenu::getId, sysMenu.getId())) > 0;
if(repeatTitle) {
throw new CommonException("存在重复的菜单,名称为:{}", sysMenu.getTitle());
}
List<SysMenu> originDataList = this.list(new LambdaQueryWrapper<SysMenu>().eq(SysMenu::getCategory,
SysResourceCategoryEnum.MENU.getValue()));
boolean errorLevel = this.getChildListById(originDataList, sysMenu.getId(), true).stream()
.map(SysMenu::getId).collect(Collectors.toList()).contains(sysMenu.getParentId());
if(errorLevel) {
throw new CommonException("不可选择上级菜单:{}", this.getById(originDataList, sysMenu.getParentId()).getName());
}
if(!"0".equals(sysMenuEditParam.getParentId())) {
SysMenu parentMenu = this.getById(originDataList, sysMenuEditParam.getParentId());
if(ObjectUtil.isEmpty(parentMenu)) {
throw new CommonException("上级菜单不存在id值为{}", sysMenuEditParam.getParentId());
}
if(!parentMenu.getModule().equals(sysMenuEditParam.getModule())) {
throw new CommonException("module与上级菜单不一致");
}
}
this.updateById(sysMenu);
// 发布更新事件
CommonDataChangeEventCenter.doUpdateWithData(SysDataTypeEnum.RESOURCE.getValue(), JSONUtil.createArray().put(sysMenu));
}
@Override
public void changeModule(SysMenuChangeModuleParam sysMenuChangeModuleParam) {
SysMenu sysMenu = this.queryEntity(sysMenuChangeModuleParam.getId());
if(!"0".equals(sysMenu.getParentId())) {
throw new CommonException("非顶级菜单不可修改所属模块");
}
List<SysMenu> sysMenuList = this.list(new LambdaQueryWrapper<SysMenu>().eq(SysMenu::getCategory,
SysResourceCategoryEnum.MENU.getValue()));
List<SysMenu> sysMenuChildList = this.getChildListById(sysMenuList, sysMenu.getId(), true).stream()
.peek(sysMenuTemp -> sysMenuTemp.setModule(sysMenuChangeModuleParam.getModule())).collect(Collectors.toList());
this.updateBatchById(sysMenuChildList);
}
private void checkParam(SysMenuEditParam sysMenuEditParam) {
SysResourceMenuTypeEnum.validate(sysMenuEditParam.getMenuType());
if(SysResourceMenuTypeEnum.MENU.getValue().equals(sysMenuEditParam.getMenuType())) {
if(ObjectUtil.isEmpty(sysMenuEditParam.getName())) {
throw new CommonException("name不能为空");
}
if(ObjectUtil.isEmpty(sysMenuEditParam.getComponent())) {
throw new CommonException("component不能为空");
}
} else if(SysResourceMenuTypeEnum.IFRAME.getValue().equals(sysMenuEditParam.getMenuType()) ||
SysResourceMenuTypeEnum.LINK.getValue().equals(sysMenuEditParam.getMenuType())) {
if(ObjectUtil.isEmpty(sysMenuEditParam.getName())) {
sysMenuEditParam.setName(RandomUtil.randomNumbers(10));
}
sysMenuEditParam.setComponent(null);
} else {
sysMenuEditParam.setName(null);
sysMenuEditParam.setComponent(null);
}
}
@Override
public void delete(List<SysMenuIdParam> sysMenuIdParamList) {
List<String> sysMenuIdList = CollStreamUtil.toList(sysMenuIdParamList, SysMenuIdParam::getId);
if(ObjectUtil.isNotEmpty(sysMenuIdList)) {
// 获取菜单下的菜单、按钮
List<SysMenu> allMenuList = this.list(new LambdaQueryWrapper<SysMenu>()
.in(SysMenu::getCategory, CollectionUtil.newArrayList(SysResourceCategoryEnum.MENU.getValue(),
SysResourceCategoryEnum.BUTTON.getValue())));
List<String> toDeleteMenuIdList = CollectionUtil.newArrayList();
sysMenuIdList.forEach(menuId -> toDeleteMenuIdList.addAll(this.getChildListById(allMenuList, menuId, true).stream()
.map(SysMenu::getId).collect(Collectors.toList())));
if(ObjectUtil.isNotEmpty(toDeleteMenuIdList)) {
// 清除对应的角色与资源信息
sysRelationService.remove(new LambdaUpdateWrapper<SysRelation>().in(SysRelation::getTargetId, toDeleteMenuIdList)
.eq(SysRelation::getCategory, SysRelationCategoryEnum.SYS_ROLE_HAS_RESOURCE.getValue()));
// 执行删除
this.removeByIds(toDeleteMenuIdList);
// 发布删除事件
CommonDataChangeEventCenter.doDeleteWithDataId(SysDataTypeEnum.RESOURCE.getValue(), toDeleteMenuIdList);
}
}
}
@Override
public SysMenu detail(SysMenuIdParam sysMenuIdParam) {
return this.queryEntity(sysMenuIdParam.getId());
}
@Override
public SysMenu queryEntity(String id) {
SysMenu sysMenu = this.getById(id);
if(ObjectUtil.isEmpty(sysMenu)) {
throw new CommonException("菜单不存在id值为{}", id);
}
return sysMenu;
}
@Override
public List<SysModule> moduleSelector(SysMenuSelectorModuleParam sysMenuSelectorModuleParam) {
LambdaQueryWrapper<SysModule> lambdaQueryWrapper = new LambdaQueryWrapper<>();
if(ObjectUtil.isNotEmpty(sysMenuSelectorModuleParam.getSearchKey())) {
lambdaQueryWrapper.like(SysModule::getTitle, sysMenuSelectorModuleParam.getSearchKey());
}
lambdaQueryWrapper.eq(SysModule::getCategory, SysResourceCategoryEnum.MODULE.getValue());
return sysModuleService.list(lambdaQueryWrapper);
}
@Override
public List<Tree<String>> menuTreeSelector(SysMenuSelectorMenuParam sysMenuSelectorMenuParam) {
LambdaQueryWrapper<SysMenu> lambdaQueryWrapper = new LambdaQueryWrapper<>();
// 查询类型为菜单的
lambdaQueryWrapper.eq(SysMenu::getCategory, SysResourceCategoryEnum.MENU.getValue());
if(ObjectUtil.isNotEmpty(sysMenuSelectorMenuParam.getModule())) {
lambdaQueryWrapper.eq(SysMenu::getModule, sysMenuSelectorMenuParam.getModule());
}
List<SysMenu> resourceList = this.list(lambdaQueryWrapper);
List<TreeNode<String>> treeNodeList = resourceList.stream().map(sysMenu ->
new TreeNode<>(sysMenu.getId(), sysMenu.getParentId(),
sysMenu.getTitle(), sysMenu.getSortCode()).setExtra(JSONUtil.parseObj(sysMenu)))
.collect(Collectors.toList());
return TreeUtil.build(treeNodeList, "0");
}
/* ====以下为各种递归方法==== */
@Override
public List<SysMenu> getChildListById(List<SysMenu> originDataList, String id, boolean includeSelf) {
List<SysMenu> resultList = CollectionUtil.newArrayList();
execRecursionFindChild(originDataList, id, resultList);
if(includeSelf) {
SysMenu self = this.getById(originDataList, id);
if(ObjectUtil.isNotEmpty(self)) {
resultList.add(self);
}
}
return resultList;
}
@Override
public List<SysMenu> getParentListById(List<SysMenu> originDataList, String id, boolean includeSelf) {
List<SysMenu> resultList = CollectionUtil.newArrayList();
execRecursionFindParent(originDataList, id, resultList);
if(includeSelf) {
SysMenu self = this.getById(originDataList, id);
if(ObjectUtil.isNotEmpty(self)) {
resultList.add(self);
}
}
return resultList;
}
public void execRecursionFindChild(List<SysMenu> originDataList, String id, List<SysMenu> resultList) {
originDataList.forEach(item -> {
if(item.getParentId().equals(id)) {
resultList.add(item);
execRecursionFindChild(originDataList, item.getId(), resultList);
}
});
}
public void execRecursionFindParent(List<SysMenu> originDataList, String id, List<SysMenu> resultList) {
originDataList.forEach(item -> {
if(item.getId().equals(id)) {
SysMenu parent = this.getById(originDataList, item.getParentId());
if(ObjectUtil.isNotEmpty(parent)) {
resultList.add(parent);
}
execRecursionFindParent(originDataList, item.getParentId(), resultList);
}
});
}
public SysMenu getById(List<SysMenu> originDataList, String id) {
int index = CollStreamUtil.toList(originDataList, SysMenu::getId).indexOf(id);
return index == -1?null:originDataList.get(index);
}
public SysMenu getParentById(List<SysMenu> originDataList, String id) {
SysMenu self = this.getById(originDataList, id);
return ObjectUtil.isNotEmpty(self)?self:this.getById(originDataList, self.getParentId());
}
public SysMenu getChildById(List<SysMenu> originDataList, String id) {
int index = CollStreamUtil.toList(originDataList, SysMenu::getParentId).indexOf(id);
return index == -1?null:originDataList.get(index);
}
}

View File

@@ -0,0 +1,155 @@
package mjkf.xinke.sys.modular.resource.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
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.core.conditions.update.LambdaUpdateWrapper;
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.common.enums.CommonSortOrderEnum;
import mjkf.xinke.common.exception.CommonException;
import mjkf.xinke.common.listener.CommonDataChangeEventCenter;
import mjkf.xinke.common.page.CommonPageRequest;
import mjkf.xinke.sys.core.enums.SysBuildInEnum;
import mjkf.xinke.sys.core.enums.SysDataTypeEnum;
import mjkf.xinke.sys.modular.relation.entity.SysRelation;
import mjkf.xinke.sys.modular.relation.enums.SysRelationCategoryEnum;
import mjkf.xinke.sys.modular.relation.service.SysRelationService;
import mjkf.xinke.sys.modular.resource.entity.SysMenu;
import mjkf.xinke.sys.modular.resource.entity.SysModule;
import mjkf.xinke.sys.modular.resource.enums.SysResourceCategoryEnum;
import mjkf.xinke.sys.modular.resource.mapper.SysModuleMapper;
import mjkf.xinke.sys.modular.resource.param.module.SysModuleAddParam;
import mjkf.xinke.sys.modular.resource.param.module.SysModuleEditParam;
import mjkf.xinke.sys.modular.resource.param.module.SysModuleIdParam;
import mjkf.xinke.sys.modular.resource.param.module.SysModulePageParam;
import mjkf.xinke.sys.modular.resource.service.SysMenuService;
import mjkf.xinke.sys.modular.resource.service.SysModuleService;
import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;
/**
* 模块Service接口实现类
*
*
* @date 2022/6/27 14:25
**/
@Service
public class SysModuleServiceImpl extends ServiceImpl<SysModuleMapper, SysModule> implements SysModuleService {
@Resource
private SysMenuService sysMenuService;
@Resource
private SysRelationService sysRelationService;
@Override
public Page<SysModule> page(SysModulePageParam sysModulePageParam) {
QueryWrapper<SysModule> queryWrapper = new QueryWrapper<>();
queryWrapper.lambda().eq(SysModule::getCategory, SysResourceCategoryEnum.MODULE.getValue());
if(ObjectUtil.isNotEmpty(sysModulePageParam.getSearchKey())) {
queryWrapper.lambda().like(SysModule::getTitle, sysModulePageParam.getSearchKey());
}
if(ObjectUtil.isAllNotEmpty(sysModulePageParam.getSortField(), sysModulePageParam.getSortOrder())) {
CommonSortOrderEnum.validate(sysModulePageParam.getSortOrder());
queryWrapper.orderBy(true, sysModulePageParam.getSortOrder().equals(CommonSortOrderEnum.ASC.getValue()),
StrUtil.toUnderlineCase(sysModulePageParam.getSortField()));
} else {
queryWrapper.lambda().orderByAsc(SysModule::getSortCode);
}
return this.page(CommonPageRequest.defaultPage(), queryWrapper);
}
@Transactional(rollbackFor = Exception.class)
@Override
public void add(SysModuleAddParam sysModuleAddParam) {
SysModule sysModule = BeanUtil.toBean(sysModuleAddParam, SysModule.class);
boolean repeatTitle = this.count(new LambdaQueryWrapper<SysModule>().eq(SysModule::getCategory,
SysResourceCategoryEnum.MODULE.getValue()).eq(SysModule::getTitle, sysModule.getTitle())) > 0;
if(repeatTitle) {
throw new CommonException("存在重复的模块,名称为:{}", sysModule.getTitle());
}
sysModule.setCode(RandomUtil.randomString(10));
sysModule.setCategory(SysResourceCategoryEnum.MODULE.getValue());
this.save(sysModule);
// 发布增加事件
CommonDataChangeEventCenter.doAddWithData(SysDataTypeEnum.RESOURCE.getValue(), JSONUtil.createArray().put(sysModule));
}
@Transactional(rollbackFor = Exception.class)
@Override
public void edit(SysModuleEditParam sysModuleEditParam) {
SysModule sysModule = this.queryEntity(sysModuleEditParam.getId());
BeanUtil.copyProperties(sysModuleEditParam, sysModule);
boolean repeatTitle = this.count(new LambdaQueryWrapper<SysModule>().eq(SysModule::getCategory,
SysResourceCategoryEnum.MODULE.getValue()).eq(SysModule::getTitle, sysModule.getTitle())
.ne(SysModule::getId, sysModule.getId())) > 0;
if(repeatTitle) {
throw new CommonException("存在重复的模块,名称为:{}", sysModule.getTitle());
}
this.updateById(sysModule);
// 发布更新事件
CommonDataChangeEventCenter.doUpdateWithData(SysDataTypeEnum.RESOURCE.getValue(), JSONUtil.createArray().put(sysModule));
}
@Override
public void delete(List<SysModuleIdParam> sysModuleIdParamList) {
List<String> sysModuleIdList = CollStreamUtil.toList(sysModuleIdParamList, SysModuleIdParam::getId);
if(ObjectUtil.isNotEmpty(sysModuleIdList)) {
boolean containsSystemModule = this.listByIds(sysModuleIdList).stream().map(SysModule::getCode)
.collect(Collectors.toSet()).contains(SysBuildInEnum.BUILD_IN_MODULE_CODE.getValue());
if(containsSystemModule) {
throw new CommonException("不可删除系统内置模块");
}
// 获取模块下的菜单、按钮
List<SysMenu> allMenuList = sysMenuService.list(new LambdaQueryWrapper<SysMenu>()
.in(SysMenu::getCategory, CollectionUtil.newArrayList(SysResourceCategoryEnum.MENU.getValue(),
SysResourceCategoryEnum.BUTTON.getValue())));
if(ObjectUtil.isNotEmpty(allMenuList)) {
List<String> toDeleteMenuIdList = CollectionUtil.newArrayList(sysModuleIdList);
allMenuList.stream().filter(sysMenu -> sysModuleIdList.contains(sysMenu.getModule()))
.collect(Collectors.toList()).forEach(sysMenu -> toDeleteMenuIdList
.addAll(sysMenuService.getChildListById(allMenuList, sysMenu.getId(), true).stream()
.map(SysMenu::getId).collect(Collectors.toList())));
if(ObjectUtil.isNotEmpty(toDeleteMenuIdList)) {
// 清除对应的角色与资源信息
sysRelationService.remove(new LambdaUpdateWrapper<SysRelation>().in(SysRelation::getTargetId, toDeleteMenuIdList)
.eq(SysRelation::getCategory, SysRelationCategoryEnum.SYS_ROLE_HAS_RESOURCE.getValue()));
// 执行删除
this.removeByIds(toDeleteMenuIdList);
// 发布删除事件
CommonDataChangeEventCenter.doDeleteWithDataId(SysDataTypeEnum.RESOURCE.getValue(), toDeleteMenuIdList);
}
}
}
}
@Override
public SysModule detail(SysModuleIdParam sysModuleIdParam) {
return this.queryEntity(sysModuleIdParam.getId());
}
@Override
public SysModule queryEntity(String id) {
SysModule sysModule = this.getById(id);
if(ObjectUtil.isEmpty(sysModule)) {
throw new CommonException("模块不存在id值为{}", id);
}
return sysModule;
}
}

View File

@@ -0,0 +1,167 @@
package mjkf.xinke.sys.modular.resource.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
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 org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
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.sys.core.enums.SysBuildInEnum;
import mjkf.xinke.sys.core.enums.SysDataTypeEnum;
import mjkf.xinke.sys.modular.resource.entity.SysSpa;
import mjkf.xinke.sys.modular.resource.enums.SysResourceCategoryEnum;
import mjkf.xinke.sys.modular.resource.enums.SysResourceMenuTypeEnum;
import mjkf.xinke.sys.modular.resource.mapper.SysSpaMapper;
import mjkf.xinke.sys.modular.resource.param.spa.SysSpaAddParam;
import mjkf.xinke.sys.modular.resource.param.spa.SysSpaEditParam;
import mjkf.xinke.sys.modular.resource.param.spa.SysSpaIdParam;
import mjkf.xinke.sys.modular.resource.param.spa.SysSpaPageParam;
import mjkf.xinke.sys.modular.resource.service.SysSpaService;
import java.util.List;
import java.util.stream.Collectors;
/**
* 单页面Service接口实现类
*
*
* @date 2022/6/27 14:25
**/
@Service
public class SysSpaServiceImpl extends ServiceImpl<SysSpaMapper, SysSpa> implements SysSpaService {
@Override
public Page<SysSpa> page(SysSpaPageParam sysSpaPageParam) {
QueryWrapper<SysSpa> queryWrapper = new QueryWrapper<>();
queryWrapper.lambda().eq(SysSpa::getCategory, SysResourceCategoryEnum.SPA.getValue());
if(ObjectUtil.isNotEmpty(sysSpaPageParam.getSearchKey())) {
queryWrapper.lambda().like(SysSpa::getTitle, sysSpaPageParam.getSearchKey());
}
if(ObjectUtil.isAllNotEmpty(sysSpaPageParam.getSortField(), sysSpaPageParam.getSortOrder())) {
CommonSortOrderEnum.validate(sysSpaPageParam.getSortOrder());
queryWrapper.orderBy(true, sysSpaPageParam.getSortOrder().equals(CommonSortOrderEnum.ASC.getValue()),
StrUtil.toUnderlineCase(sysSpaPageParam.getSortField()));
} else {
queryWrapper.lambda().orderByAsc(SysSpa::getSortCode);
}
return this.page(CommonPageRequest.defaultPage(), queryWrapper);
}
@Transactional(rollbackFor = Exception.class)
@Override
public void add(SysSpaAddParam sysSpaAddParam) {
checkParam(sysSpaAddParam);
SysSpa sysSpa = BeanUtil.toBean(sysSpaAddParam, SysSpa.class);
boolean repeatTitle = this.count(new LambdaQueryWrapper<SysSpa>().eq(SysSpa::getCategory,
SysResourceCategoryEnum.SPA.getValue()).eq(SysSpa::getTitle, sysSpa.getTitle())) > 0;
if(repeatTitle) {
throw new CommonException("存在重复的单页面,名称为:{}", sysSpa.getTitle());
}
sysSpa.setCode(RandomUtil.randomString(10));
sysSpa.setCategory(SysResourceCategoryEnum.SPA.getValue());
this.save(sysSpa);
// 发布增加事件
CommonDataChangeEventCenter.doAddWithData(SysDataTypeEnum.RESOURCE.getValue(), JSONUtil.createArray().put(sysSpa));
}
@SuppressWarnings("all")
private void checkParam(SysSpaAddParam sysSpaAddParam) {
SysResourceMenuTypeEnum.validate(sysSpaAddParam.getMenuType());
if(SysResourceMenuTypeEnum.MENU.getValue().equals(sysSpaAddParam.getMenuType())) {
if(ObjectUtil.isEmpty(sysSpaAddParam.getName())) {
throw new CommonException("name不能为空");
}
if(ObjectUtil.isEmpty(sysSpaAddParam.getComponent())) {
throw new CommonException("component不能为空");
}
} else if(SysResourceMenuTypeEnum.IFRAME.getValue().equals(sysSpaAddParam.getMenuType()) ||
SysResourceMenuTypeEnum.LINK.getValue().equals(sysSpaAddParam.getMenuType())) {
sysSpaAddParam.setName(RandomUtil.randomNumbers(10));
sysSpaAddParam.setComponent(null);
} else {
sysSpaAddParam.setName(null);
sysSpaAddParam.setComponent(null);
}
}
@Transactional(rollbackFor = Exception.class)
@Override
public void edit(SysSpaEditParam sysSpaEditParam) {
SysSpa sysSpa = this.queryEntity(sysSpaEditParam.getId());
checkParam(sysSpaEditParam);
BeanUtil.copyProperties(sysSpaEditParam, sysSpa);
boolean repeatTitle = this.count(new LambdaQueryWrapper<SysSpa>().eq(SysSpa::getCategory,
SysResourceCategoryEnum.SPA.getValue()).eq(SysSpa::getTitle, sysSpa.getTitle())
.ne(SysSpa::getId, sysSpa.getId())) > 0;
if(repeatTitle) {
throw new CommonException("存在重复的单页面,名称为:{}", sysSpa.getTitle());
}
this.updateById(sysSpa);
// 发布更新事件
CommonDataChangeEventCenter.doUpdateWithData(SysDataTypeEnum.RESOURCE.getValue(), JSONUtil.createArray().put(sysSpa));
}
@SuppressWarnings("all")
private void checkParam(SysSpaEditParam sysSpaEditParam) {
SysResourceMenuTypeEnum.validate(sysSpaEditParam.getMenuType());
if(SysResourceMenuTypeEnum.MENU.getValue().equals(sysSpaEditParam.getMenuType())) {
if(ObjectUtil.isEmpty(sysSpaEditParam.getName())) {
throw new CommonException("name不能为空");
}
if(ObjectUtil.isEmpty(sysSpaEditParam.getComponent())) {
throw new CommonException("component不能为空");
}
} else if(SysResourceMenuTypeEnum.IFRAME.getValue().equals(sysSpaEditParam.getMenuType()) ||
SysResourceMenuTypeEnum.LINK.getValue().equals(sysSpaEditParam.getMenuType())) {
sysSpaEditParam.setName(RandomUtil.randomNumbers(10));
sysSpaEditParam.setComponent(null);
} else {
sysSpaEditParam.setName(null);
sysSpaEditParam.setComponent(null);
}
}
@Override
public void delete(List<SysSpaIdParam> sysSpaIdParamList) {
List<String> sysSpaIdList = CollStreamUtil.toList(sysSpaIdParamList, SysSpaIdParam::getId);
if(ObjectUtil.isNotEmpty(sysSpaIdList)) {
boolean containsSystemSpa = this.listByIds(sysSpaIdList).stream().map(SysSpa::getCode)
.collect(Collectors.toSet()).contains(SysBuildInEnum.BUILD_IN_SPA_CODE.getValue());
if(containsSystemSpa) {
throw new CommonException("不可删除系统内置单页面");
}
// 删除
this.removeByIds(sysSpaIdList);
// 发布删除事件
CommonDataChangeEventCenter.doDeleteWithDataId(SysDataTypeEnum.RESOURCE.getValue(), sysSpaIdList);
}
}
@Override
public SysSpa detail(SysSpaIdParam sysSpaIdParam) {
return this.queryEntity(sysSpaIdParam.getId());
}
@Override
public SysSpa queryEntity(String id) {
SysSpa sysSpa = this.getById(id);
if(ObjectUtil.isEmpty(sysSpa)) {
throw new CommonException("单页面不存在id值为{}", id);
}
return sysSpa;
}
}

Some files were not shown because too many files have changed in this diff Show More