mirror of
https://gitee.com/orangeform/orange-admin.git
synced 2026-01-17 18:46:36 +08:00
commit:升级到vue3,更新最近工作流技术栈,支持sa-token
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
package com.orangeforms.webadmin;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.scheduling.annotation.EnableAsync;
|
||||
|
||||
/**
|
||||
* 应用服务启动类。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
@EnableAsync
|
||||
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
|
||||
@ComponentScan("com.orangeforms")
|
||||
public class WebAdminApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(WebAdminApplication.class, args);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,244 @@
|
||||
package com.orangeforms.webadmin.app.util;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import com.orangeforms.common.flow.util.BaseFlowIdentityExtHelper;
|
||||
import com.orangeforms.common.flow.util.FlowCustomExtFactory;
|
||||
import com.orangeforms.common.flow.vo.FlowUserInfoVo;
|
||||
import com.orangeforms.webadmin.upms.model.SysDept;
|
||||
import com.orangeforms.webadmin.upms.model.SysUser;
|
||||
import com.orangeforms.webadmin.upms.model.constant.SysUserStatus;
|
||||
import com.orangeforms.webadmin.upms.model.SysDeptPost;
|
||||
import com.orangeforms.webadmin.upms.service.SysDeptService;
|
||||
import com.orangeforms.webadmin.upms.service.SysUserService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 为流程提供所需的用户身份相关的等扩展信息的帮助类。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class FlowIdentityExtHelper implements BaseFlowIdentityExtHelper {
|
||||
|
||||
@Autowired
|
||||
private SysDeptService sysDeptService;
|
||||
@Autowired
|
||||
private SysUserService sysUserService;
|
||||
@Autowired
|
||||
private FlowCustomExtFactory flowCustomExtFactory;
|
||||
|
||||
@PostConstruct
|
||||
public void doRegister() {
|
||||
flowCustomExtFactory.registerFlowIdentityExtHelper(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getLeaderDeptPostId(Long deptId) {
|
||||
List<Long> deptPostIdList = sysDeptService.getLeaderDeptPostIdList(deptId);
|
||||
return CollUtil.isEmpty(deptPostIdList) ? null : deptPostIdList.get(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getUpLeaderDeptPostId(Long deptId) {
|
||||
List<Long> deptPostIdList = sysDeptService.getUpLeaderDeptPostIdList(deptId);
|
||||
return CollUtil.isEmpty(deptPostIdList) ? null : deptPostIdList.get(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getDeptPostIdMap(Long deptId, Set<String> postIdSet) {
|
||||
Set<Long> postIdSet2 = postIdSet.stream().map(Long::valueOf).collect(Collectors.toSet());
|
||||
List<SysDeptPost> deptPostList = sysDeptService.getSysDeptPostList(deptId, postIdSet2);
|
||||
if (CollUtil.isEmpty(deptPostList)) {
|
||||
return null;
|
||||
}
|
||||
Map<String, String> resultMap = new HashMap<>(deptPostList.size());
|
||||
deptPostList.forEach(sysDeptPost ->
|
||||
resultMap.put(sysDeptPost.getPostId().toString(), sysDeptPost.getDeptPostId().toString()));
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getSiblingDeptPostIdMap(Long deptId, Set<String> postIdSet) {
|
||||
Set<Long> postIdSet2 = postIdSet.stream().map(Long::valueOf).collect(Collectors.toSet());
|
||||
List<SysDeptPost> deptPostList = sysDeptService.getSiblingSysDeptPostList(deptId, postIdSet2);
|
||||
if (CollUtil.isEmpty(deptPostList)) {
|
||||
return null;
|
||||
}
|
||||
Map<String, String> resultMap = new HashMap<>(deptPostList.size());
|
||||
for (SysDeptPost deptPost : deptPostList) {
|
||||
String deptPostId = resultMap.get(deptPost.getPostId().toString());
|
||||
if (deptPostId != null) {
|
||||
deptPostId = deptPostId + "," + deptPost.getDeptPostId();
|
||||
} else {
|
||||
deptPostId = deptPost.getDeptPostId().toString();
|
||||
}
|
||||
resultMap.put(deptPost.getPostId().toString(), deptPostId);
|
||||
}
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getUpDeptPostIdMap(Long deptId, Set<String> postIdSet) {
|
||||
SysDept sysDept = sysDeptService.getById(deptId);
|
||||
if (sysDept == null || sysDept.getParentId() == null) {
|
||||
return null;
|
||||
}
|
||||
return getDeptPostIdMap(sysDept.getParentId(), postIdSet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getUsernameListByRoleIds(Set<String> roleIdSet) {
|
||||
Set<String> usernameSet = new HashSet<>();
|
||||
Set<Long> roleIdSet2 = roleIdSet.stream().map(Long::valueOf).collect(Collectors.toSet());
|
||||
SysUser filter = new SysUser();
|
||||
filter.setUserStatus(SysUserStatus.STATUS_NORMAL);
|
||||
for (Long roleId : roleIdSet2) {
|
||||
List<SysUser> userList = sysUserService.getSysUserListByRoleId(roleId, filter, null);
|
||||
this.extractAndAppendUsernameList(usernameSet, userList);
|
||||
}
|
||||
return usernameSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FlowUserInfoVo> getUserInfoListByRoleIds(Set<String> roleIdSet) {
|
||||
List<FlowUserInfoVo> resultList = new LinkedList<>();
|
||||
Set<Long> roleIdSet2 = roleIdSet.stream().map(Long::valueOf).collect(Collectors.toSet());
|
||||
SysUser filter = new SysUser();
|
||||
filter.setUserStatus(SysUserStatus.STATUS_NORMAL);
|
||||
for (Long roleId : roleIdSet2) {
|
||||
List<SysUser> userList = sysUserService.getSysUserListByRoleId(roleId, filter, null);
|
||||
if (CollUtil.isNotEmpty(userList)) {
|
||||
resultList.addAll(BeanUtil.copyToList(userList, FlowUserInfoVo.class));
|
||||
}
|
||||
}
|
||||
return resultList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getUsernameListByDeptIds(Set<String> deptIdSet) {
|
||||
Set<String> usernameSet = new HashSet<>();
|
||||
Set<Long> deptIdSet2 = deptIdSet.stream().map(Long::valueOf).collect(Collectors.toSet());
|
||||
for (Long deptId : deptIdSet2) {
|
||||
SysUser filter = new SysUser();
|
||||
filter.setDeptId(deptId);
|
||||
filter.setUserStatus(SysUserStatus.STATUS_NORMAL);
|
||||
List<SysUser> userList = sysUserService.getSysUserList(filter, null);
|
||||
this.extractAndAppendUsernameList(usernameSet, userList);
|
||||
}
|
||||
return usernameSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FlowUserInfoVo> getUserInfoListByDeptIds(Set<String> deptIdSet) {
|
||||
List<FlowUserInfoVo> resultList = new LinkedList<>();
|
||||
Set<Long> deptIdSet2 = deptIdSet.stream().map(Long::valueOf).collect(Collectors.toSet());
|
||||
for (Long deptId : deptIdSet2) {
|
||||
SysUser filter = new SysUser();
|
||||
filter.setDeptId(deptId);
|
||||
filter.setUserStatus(SysUserStatus.STATUS_NORMAL);
|
||||
List<SysUser> userList = sysUserService.getSysUserList(filter, null);
|
||||
if (CollUtil.isNotEmpty(userList)) {
|
||||
resultList.addAll(BeanUtil.copyToList(userList, FlowUserInfoVo.class));
|
||||
}
|
||||
}
|
||||
return resultList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getUsernameListByPostIds(Set<String> postIdSet) {
|
||||
Set<String> usernameSet = new HashSet<>();
|
||||
Set<Long> postIdSet2 = postIdSet.stream().map(Long::valueOf).collect(Collectors.toSet());
|
||||
SysUser filter = new SysUser();
|
||||
filter.setUserStatus(SysUserStatus.STATUS_NORMAL);
|
||||
for (Long postId : postIdSet2) {
|
||||
List<SysUser> userList = sysUserService.getSysUserListByPostId(postId, filter, null);
|
||||
this.extractAndAppendUsernameList(usernameSet, userList);
|
||||
}
|
||||
return usernameSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FlowUserInfoVo> getUserInfoListByPostIds(Set<String> postIdSet) {
|
||||
List<FlowUserInfoVo> resultList = new LinkedList<>();
|
||||
Set<Long> postIdSet2 = postIdSet.stream().map(Long::valueOf).collect(Collectors.toSet());
|
||||
SysUser filter = new SysUser();
|
||||
filter.setUserStatus(SysUserStatus.STATUS_NORMAL);
|
||||
for (Long postId : postIdSet2) {
|
||||
List<SysUser> userList = sysUserService.getSysUserListByPostId(postId, filter, null);
|
||||
if (CollUtil.isNotEmpty(userList)) {
|
||||
resultList.addAll(BeanUtil.copyToList(userList, FlowUserInfoVo.class));
|
||||
}
|
||||
}
|
||||
return resultList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getUsernameListByDeptPostIds(Set<String> deptPostIdSet) {
|
||||
Set<String> usernameSet = new HashSet<>();
|
||||
Set<Long> deptPostIdSet2 = deptPostIdSet.stream().map(Long::valueOf).collect(Collectors.toSet());
|
||||
SysUser filter = new SysUser();
|
||||
filter.setUserStatus(SysUserStatus.STATUS_NORMAL);
|
||||
for (Long deptPostId : deptPostIdSet2) {
|
||||
List<SysUser> userList = sysUserService.getSysUserListByDeptPostId(deptPostId, filter, null);
|
||||
this.extractAndAppendUsernameList(usernameSet, userList);
|
||||
}
|
||||
return usernameSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FlowUserInfoVo> getUserInfoListByDeptPostIds(Set<String> deptPostIdSet) {
|
||||
List<FlowUserInfoVo> resultList = new LinkedList<>();
|
||||
Set<Long> deptPostIdSet2 = deptPostIdSet.stream().map(Long::valueOf).collect(Collectors.toSet());
|
||||
SysUser filter = new SysUser();
|
||||
filter.setUserStatus(SysUserStatus.STATUS_NORMAL);
|
||||
for (Long deptPostId : deptPostIdSet2) {
|
||||
List<SysUser> userList = sysUserService.getSysUserListByDeptPostId(deptPostId, filter, null);
|
||||
if (CollUtil.isNotEmpty(userList)) {
|
||||
resultList.addAll(BeanUtil.copyToList(userList, FlowUserInfoVo.class));
|
||||
}
|
||||
}
|
||||
return resultList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FlowUserInfoVo> getUserInfoListByUsernameSet(Set<String> usernameSet) {
|
||||
List<FlowUserInfoVo> resultList = null;
|
||||
List<SysUser> userList = sysUserService.getInList("loginName", usernameSet);
|
||||
if (CollUtil.isNotEmpty(userList)) {
|
||||
resultList = BeanUtil.copyToList(userList, FlowUserInfoVo.class);
|
||||
}
|
||||
return resultList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean supprtDataPerm() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> mapUserShowNameByLoginName(Set<String> loginNameSet) {
|
||||
if (CollUtil.isEmpty(loginNameSet)) {
|
||||
return new HashMap<>(1);
|
||||
}
|
||||
Map<String, String> resultMap = new HashMap<>(loginNameSet.size());
|
||||
List<SysUser> userList = sysUserService.getInList("loginName", loginNameSet);
|
||||
userList.forEach(user -> resultMap.put(user.getLoginName(), user.getShowName()));
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
private void extractAndAppendUsernameList(Set<String> resultUsernameList, List<SysUser> userList) {
|
||||
List<String> usernameList = userList.stream().map(SysUser::getLoginName).collect(Collectors.toList());
|
||||
if (CollUtil.isNotEmpty(usernameList)) {
|
||||
resultUsernameList.addAll(usernameList);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.orangeforms.webadmin.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* 应用程序自定义的程序属性配置文件。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
@Data
|
||||
@Configuration
|
||||
@ConfigurationProperties(prefix = "application")
|
||||
public class ApplicationConfig {
|
||||
/**
|
||||
* 用户密码被重置之后的缺省密码
|
||||
*/
|
||||
private String defaultUserPassword;
|
||||
/**
|
||||
* 上传文件的基础目录
|
||||
*/
|
||||
private String uploadFileBaseDir;
|
||||
/**
|
||||
* 授信ip列表,没有填写表示全部信任。多个ip之间逗号分隔,如: http://10.10.10.1:8080,http://10.10.10.2:8080
|
||||
*/
|
||||
private String credentialIpList;
|
||||
/**
|
||||
* Session的用户权限在Redis中的过期时间(秒)。一定要和sa-token.timeout
|
||||
* 缺省值是 one day
|
||||
*/
|
||||
private int sessionExpiredSeconds = 86400;
|
||||
/**
|
||||
* 是否排他登录。
|
||||
*/
|
||||
private Boolean excludeLogin = false;
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.orangeforms.webadmin.config;
|
||||
|
||||
import com.orangeforms.common.core.constant.ApplicationConstant;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 表示数据源类型的常量对象。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
public final class DataSourceType {
|
||||
|
||||
public static final int MAIN = 0;
|
||||
/**
|
||||
* 以下所有数据源的类都型是固定值。如果有冲突,请修改上面定义的业务服务的数据源类型值。
|
||||
*/
|
||||
public static final int OPERATION_LOG = ApplicationConstant.OPERATION_LOG_DATASOURCE_TYPE;
|
||||
public static final int GLOBAL_DICT = ApplicationConstant.COMMON_GLOBAL_DICT_TYPE;
|
||||
public static final int COMMON_FLOW_AND_ONLINE = ApplicationConstant.COMMON_FLOW_AND_ONLINE_DATASOURCE_TYPE;
|
||||
|
||||
private static final Map<String, Integer> TYPE_MAP = new HashMap<>(8);
|
||||
static {
|
||||
TYPE_MAP.put("main", MAIN);
|
||||
TYPE_MAP.put("operation-log", OPERATION_LOG);
|
||||
TYPE_MAP.put("global-dict", GLOBAL_DICT);
|
||||
TYPE_MAP.put("common-flow-online", COMMON_FLOW_AND_ONLINE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据名称获取字典类型。
|
||||
*
|
||||
* @param name 数据源在配置中的名称。
|
||||
* @return 返回可用于多数据源切换的数据源类型。
|
||||
*/
|
||||
public static Integer getDataSourceTypeByName(String name) {
|
||||
return TYPE_MAP.get(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* 私有构造函数,明确标识该常量类的作用。
|
||||
*/
|
||||
private DataSourceType() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package com.orangeforms.webadmin.config;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.cors.CorsConfiguration;
|
||||
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
|
||||
import org.springframework.web.filter.CorsFilter;
|
||||
|
||||
import jakarta.servlet.Filter;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/**
|
||||
* 这里主要配置Web的各种过滤器和监听器等Servlet容器组件。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
@Configuration
|
||||
public class FilterConfig {
|
||||
|
||||
/**
|
||||
* 配置Ajax跨域过滤器。
|
||||
*/
|
||||
@Bean
|
||||
public CorsFilter corsFilterRegistration(ApplicationConfig applicationConfig) {
|
||||
UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
|
||||
CorsConfiguration corsConfiguration = new CorsConfiguration();
|
||||
if (StringUtils.isNotBlank(applicationConfig.getCredentialIpList())) {
|
||||
if ("*".equals(applicationConfig.getCredentialIpList())) {
|
||||
corsConfiguration.addAllowedOriginPattern("*");
|
||||
} else {
|
||||
String[] credentialIpList = StringUtils.split(applicationConfig.getCredentialIpList(), ",");
|
||||
if (credentialIpList.length > 0) {
|
||||
for (String ip : credentialIpList) {
|
||||
corsConfiguration.addAllowedOrigin(ip);
|
||||
}
|
||||
}
|
||||
}
|
||||
corsConfiguration.addAllowedHeader("*");
|
||||
corsConfiguration.addAllowedMethod("*");
|
||||
corsConfiguration.setAllowCredentials(true);
|
||||
configSource.registerCorsConfiguration("/**", corsConfiguration);
|
||||
}
|
||||
return new CorsFilter(configSource);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public FilterRegistrationBean<Filter> characterEncodingFilterRegistration() {
|
||||
FilterRegistrationBean<Filter> filterRegistrationBean = new FilterRegistrationBean<>(
|
||||
new org.springframework.web.filter.CharacterEncodingFilter());
|
||||
filterRegistrationBean.addUrlPatterns("/*");
|
||||
filterRegistrationBean.addInitParameter("encoding", StandardCharsets.UTF_8.name());
|
||||
// forceEncoding强制response也被编码,另外即使request中已经设置encoding,forceEncoding也会重新设置
|
||||
filterRegistrationBean.addInitParameter("forceEncoding", "true");
|
||||
filterRegistrationBean.setAsyncSupported(true);
|
||||
return filterRegistrationBean;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.orangeforms.webadmin.config;
|
||||
|
||||
import com.orangeforms.webadmin.interceptor.AuthenticationInterceptor;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
/**
|
||||
* 所有的项目拦截器都在这里集中配置
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
@Configuration
|
||||
public class InterceptorConfig implements WebMvcConfigurer {
|
||||
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
registry.addInterceptor(new AuthenticationInterceptor()).addPathPatterns("/admin/**");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package com.orangeforms.webadmin.config;
|
||||
|
||||
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
|
||||
import com.orangeforms.common.core.config.BaseMultiDataSourceConfig;
|
||||
import com.orangeforms.common.core.config.DynamicDataSource;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 多数据源配置对象。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
@Configuration
|
||||
@EnableTransactionManagement
|
||||
@MapperScan(value = {"com.orangeforms.webadmin.*.dao", "com.orangeforms.common.*.dao"})
|
||||
public class MultiDataSourceConfig extends BaseMultiDataSourceConfig {
|
||||
|
||||
@Bean(initMethod = "init", destroyMethod = "close")
|
||||
@ConfigurationProperties(prefix = "spring.datasource.druid.main")
|
||||
public DataSource mainDataSource() {
|
||||
return super.applyCommonProps(DruidDataSourceBuilder.create().build());
|
||||
}
|
||||
|
||||
/**
|
||||
* 默认生成的用于保存操作日志的数据源,可根据需求修改。
|
||||
* 这里我们还是非常推荐给操作日志使用独立的数据源,这样便于今后的数据迁移。
|
||||
*/
|
||||
@Bean(initMethod = "init", destroyMethod = "close")
|
||||
@ConfigurationProperties(prefix = "spring.datasource.druid.operation-log")
|
||||
public DataSource operationLogDataSource() {
|
||||
return super.applyCommonProps(DruidDataSourceBuilder.create().build());
|
||||
}
|
||||
|
||||
/**
|
||||
* 默认生成的用于全局编码字典的数据源,可根据需求修改。
|
||||
*/
|
||||
@Bean(initMethod = "init", destroyMethod = "close")
|
||||
@ConfigurationProperties(prefix = "spring.datasource.druid.global-dict")
|
||||
public DataSource globalDictDataSource() {
|
||||
return super.applyCommonProps(DruidDataSourceBuilder.create().build());
|
||||
}
|
||||
|
||||
/**
|
||||
* 默认生成的用于在线表单内部表的数据源,可根据需求修改。
|
||||
* 这里我们还是非常推荐使用独立数据源,这样便于今后的服务拆分。
|
||||
*/
|
||||
@Bean(initMethod = "init", destroyMethod = "close")
|
||||
@ConfigurationProperties(prefix = "spring.datasource.druid.common-flow-online")
|
||||
public DataSource commonFlowAndOnlineDataSource() {
|
||||
return super.applyCommonProps(DruidDataSourceBuilder.create().build());
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Primary
|
||||
public DynamicDataSource dataSource() {
|
||||
Map<Object, Object> targetDataSources = new HashMap<>(1);
|
||||
targetDataSources.put(DataSourceType.MAIN, mainDataSource());
|
||||
targetDataSources.put(DataSourceType.OPERATION_LOG, operationLogDataSource());
|
||||
targetDataSources.put(DataSourceType.GLOBAL_DICT, globalDictDataSource());
|
||||
targetDataSources.put(DataSourceType.COMMON_FLOW_AND_ONLINE, commonFlowAndOnlineDataSource());
|
||||
// 如果当前工程支持在线表单,这里请务必保证upms数据表所在数据库为缺省数据源。
|
||||
DynamicDataSource dynamicDataSource = new DynamicDataSource();
|
||||
dynamicDataSource.setTargetDataSources(targetDataSources);
|
||||
dynamicDataSource.setDefaultTargetDataSource(mainDataSource());
|
||||
return dynamicDataSource;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package com.orangeforms.webadmin.config;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import lombok.Data;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 第三方应用鉴权配置。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
@Data
|
||||
@Configuration
|
||||
@ConfigurationProperties(prefix = "third-party")
|
||||
public class ThirdPartyAuthConfig implements InitializingBean {
|
||||
|
||||
private List<AuthProperties> auth;
|
||||
|
||||
private Map<String, AuthProperties> applicationMap;
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
if (CollUtil.isEmpty(auth)) {
|
||||
applicationMap = new HashMap<>(1);
|
||||
} else {
|
||||
applicationMap = auth.stream().collect(Collectors.toMap(AuthProperties::getAppCode, c -> c));
|
||||
}
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class AuthProperties {
|
||||
/**
|
||||
* 应用Id。
|
||||
*/
|
||||
private String appCode;
|
||||
/**
|
||||
* 身份验证相关url的base地址。
|
||||
*/
|
||||
private String baseUrl;
|
||||
/**
|
||||
* 是否为橙单框架。
|
||||
*/
|
||||
private Boolean orangeFramework = true;
|
||||
/**
|
||||
* token的Http Request Header的key
|
||||
*/
|
||||
private String tokenHeaderKey;
|
||||
/**
|
||||
* 数据权限和用户操作权限缓存过期时间,单位秒。
|
||||
*/
|
||||
private Integer permExpiredSeconds = 86400;
|
||||
/**
|
||||
* 用户Token缓存过期时间,单位秒。
|
||||
* 如果为0,则每次都要去第三方服务进行验证。
|
||||
*/
|
||||
private Integer tokenExpiredSeconds = 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,281 @@
|
||||
package com.orangeforms.webadmin.interceptor;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.text.StrFormatter;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.http.HttpResponse;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.TypeReference;
|
||||
import com.orangeforms.common.core.cache.CacheConfig;
|
||||
import com.orangeforms.common.core.constant.ApplicationConstant;
|
||||
import com.orangeforms.common.core.constant.DataPermRuleType;
|
||||
import com.orangeforms.common.core.constant.ErrorCodeEnum;
|
||||
import com.orangeforms.common.core.exception.MyRuntimeException;
|
||||
import com.orangeforms.common.core.object.ResponseResult;
|
||||
import com.orangeforms.common.core.object.TokenData;
|
||||
import com.orangeforms.common.core.util.ApplicationContextHolder;
|
||||
import com.orangeforms.common.core.util.RedisKeyUtil;
|
||||
import com.orangeforms.common.satoken.util.SaTokenUtil;
|
||||
import com.orangeforms.webadmin.config.ThirdPartyAuthConfig;
|
||||
import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.redisson.api.RBucket;
|
||||
import org.redisson.api.RSet;
|
||||
import org.redisson.api.RedissonClient;
|
||||
import org.springframework.cache.Cache;
|
||||
import org.springframework.cache.CacheManager;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.servlet.HandlerInterceptor;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 登录用户Token验证、生成和权限验证的拦截器。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
@Slf4j
|
||||
public class AuthenticationInterceptor implements HandlerInterceptor {
|
||||
|
||||
private final ThirdPartyAuthConfig thirdPartyAuthConfig =
|
||||
ApplicationContextHolder.getBean("thirdPartyAuthConfig");
|
||||
|
||||
private final RedissonClient redissonClient = ApplicationContextHolder.getBean(RedissonClient.class);
|
||||
private final CacheManager cacheManager = ApplicationContextHolder.getBean("caffeineCacheManager");
|
||||
|
||||
private final SaTokenUtil saTokenUtil =
|
||||
ApplicationContextHolder.getBean("saTokenUtil");
|
||||
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
|
||||
throws Exception {
|
||||
String appCode = this.getAppCodeFromRequest(request);
|
||||
if (StrUtil.isNotBlank(appCode)) {
|
||||
return this.handleThirdPartyRequest(appCode, request);
|
||||
}
|
||||
ResponseResult<Void> result = saTokenUtil.handleAuthIntercept(request, handler);
|
||||
if (!result.isSuccess()) {
|
||||
ResponseResult.output(result.getHttpStatus(), result);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
|
||||
ModelAndView modelAndView) throws Exception {
|
||||
// 这里需要空注解,否则sonar会不happy。
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
|
||||
throws Exception {
|
||||
// 这里需要空注解,否则sonar会不happy。
|
||||
}
|
||||
|
||||
private String getTokenFromRequest(HttpServletRequest request, String appCode) {
|
||||
ThirdPartyAuthConfig.AuthProperties prop = thirdPartyAuthConfig.getApplicationMap().get(appCode);
|
||||
String token = request.getHeader(prop.getTokenHeaderKey());
|
||||
if (StrUtil.isBlank(token)) {
|
||||
token = request.getParameter(prop.getTokenHeaderKey());
|
||||
}
|
||||
if (StrUtil.isBlank(token)) {
|
||||
token = request.getHeader(ApplicationConstant.HTTP_HEADER_INTERNAL_TOKEN);
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
private String getAppCodeFromRequest(HttpServletRequest request) {
|
||||
String appCode = request.getHeader("AppCode");
|
||||
if (StrUtil.isBlank(appCode)) {
|
||||
appCode = request.getParameter("AppCode");
|
||||
}
|
||||
return appCode;
|
||||
}
|
||||
|
||||
private boolean handleThirdPartyRequest(String appCode, HttpServletRequest request) throws IOException {
|
||||
String token = this.getTokenFromRequest(request, appCode);
|
||||
ThirdPartyAuthConfig.AuthProperties authProps = thirdPartyAuthConfig.getApplicationMap().get(appCode);
|
||||
if (authProps == null) {
|
||||
String msg = StrFormatter.format("请求的 appCode[{}] 信息,在当前服务中尚未配置!", appCode);
|
||||
ResponseResult.output(ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, msg));
|
||||
return false;
|
||||
}
|
||||
ResponseResult<TokenData> result = this.getAndCacheThirdPartyTokenData(authProps, token);
|
||||
if (!result.isSuccess()) {
|
||||
ResponseResult.output(result.getHttpStatus(),
|
||||
ResponseResult.error(ErrorCodeEnum.UNAUTHORIZED_LOGIN, result.getErrorMessage()));
|
||||
return false;
|
||||
}
|
||||
TokenData tokenData = result.getData();
|
||||
tokenData.setAppCode(appCode);
|
||||
tokenData.setSessionId(this.prependAppCode(authProps.getAppCode(), tokenData.getSessionId()));
|
||||
TokenData.addToRequest(tokenData);
|
||||
String url = request.getRequestURI();
|
||||
if (Boolean.FALSE.equals(tokenData.getIsAdmin())
|
||||
&& !this.hasThirdPartyPermission(authProps, tokenData, url)) {
|
||||
ResponseResult.output(HttpServletResponse.SC_FORBIDDEN, ResponseResult.error(ErrorCodeEnum.NO_OPERATION_PERMISSION));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private ResponseResult<TokenData> getAndCacheThirdPartyTokenData(
|
||||
ThirdPartyAuthConfig.AuthProperties authProps, String token) {
|
||||
if (authProps.getTokenExpiredSeconds() == 0) {
|
||||
return this.getThirdPartyTokenData(authProps, token);
|
||||
}
|
||||
String tokeKey = this.prependAppCode(authProps.getAppCode(), RedisKeyUtil.makeSessionIdKey(token));
|
||||
RBucket<String> sessionData = redissonClient.getBucket(tokeKey);
|
||||
if (sessionData.isExists()) {
|
||||
return ResponseResult.success(JSON.parseObject(sessionData.get(), TokenData.class));
|
||||
}
|
||||
ResponseResult<TokenData> responseResult = this.getThirdPartyTokenData(authProps, token);
|
||||
if (responseResult.isSuccess()) {
|
||||
sessionData.set(JSON.toJSONString(responseResult.getData()), authProps.getTokenExpiredSeconds(), TimeUnit.SECONDS);
|
||||
}
|
||||
return responseResult;
|
||||
}
|
||||
|
||||
private String prependAppCode(String appCode, String key) {
|
||||
return appCode.toUpperCase() + ":" + key;
|
||||
}
|
||||
|
||||
private ResponseResult<TokenData> getThirdPartyTokenData(
|
||||
ThirdPartyAuthConfig.AuthProperties authProps, String token) {
|
||||
try {
|
||||
String resultData = this.invokeThirdPartyUrl(authProps.getBaseUrl() + "/getTokenData", token);
|
||||
return JSON.parseObject(resultData, new TypeReference<ResponseResult<TokenData>>() {});
|
||||
} catch (MyRuntimeException ex) {
|
||||
return ResponseResult.error(ErrorCodeEnum.FAILED_TO_INVOKE_THIRDPARTY_URL, ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private ResponseResult<ThirdPartyAppPermData> getThirdPartyPermData(
|
||||
ThirdPartyAuthConfig.AuthProperties authProps, String token) {
|
||||
try {
|
||||
String resultData = this.invokeThirdPartyUrl(authProps.getBaseUrl() + "/getPermData", token);
|
||||
return JSON.parseObject(resultData, new TypeReference<ResponseResult<ThirdPartyAppPermData>>() {});
|
||||
} catch (MyRuntimeException ex) {
|
||||
return ResponseResult.error(ErrorCodeEnum.FAILED_TO_INVOKE_THIRDPARTY_URL, ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private String invokeThirdPartyUrl(String url, String token) {
|
||||
Map<String, String> headerMap = new HashMap<>(1);
|
||||
headerMap.put("Authorization", token);
|
||||
StringBuilder fullUrl = new StringBuilder(128);
|
||||
fullUrl.append(url).append("?token=").append(token);
|
||||
HttpResponse httpResponse = HttpUtil.createGet(fullUrl.toString()).addHeaders(headerMap).execute();
|
||||
if (!httpResponse.isOk()) {
|
||||
String msg = StrFormatter.format(
|
||||
"Failed to call [{}] with ERROR HTTP Status [{}] and [{}].",
|
||||
url, httpResponse.getStatus(), httpResponse.body());
|
||||
log.error(msg);
|
||||
throw new MyRuntimeException(msg);
|
||||
}
|
||||
return httpResponse.body();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private boolean hasThirdPartyPermission(
|
||||
ThirdPartyAuthConfig.AuthProperties authProps, TokenData tokenData, String url) {
|
||||
// 为了提升效率,先检索Caffeine的一级缓存,如果不存在,再检索Redis的二级缓存,并将结果存入一级缓存。
|
||||
String permKey = RedisKeyUtil.makeSessionPermIdKey(tokenData.getSessionId());
|
||||
Cache cache = cacheManager.getCache(CacheConfig.CacheEnum.USER_PERMISSION_CACHE.name());
|
||||
Assert.notNull(cache, "Cache USER_PERMISSION_CACHE can't be NULL");
|
||||
Cache.ValueWrapper wrapper = cache.get(permKey);
|
||||
if (wrapper != null) {
|
||||
Object cachedData = wrapper.get();
|
||||
if (cachedData != null) {
|
||||
return ((Set<String>) cachedData).contains(url);
|
||||
}
|
||||
}
|
||||
Set<String> localPermSet;
|
||||
RSet<String> permSet = redissonClient.getSet(permKey);
|
||||
if (permSet.isExists()) {
|
||||
localPermSet = permSet.readAll();
|
||||
cache.put(permKey, localPermSet);
|
||||
return localPermSet.contains(url);
|
||||
}
|
||||
ResponseResult<ThirdPartyAppPermData> responseResult = this.getThirdPartyPermData(authProps, tokenData.getToken());
|
||||
this.cacheThirdPartyDataPermData(authProps, tokenData, responseResult.getData().getDataPerms());
|
||||
if (CollUtil.isEmpty(responseResult.getData().urlPerms)) {
|
||||
return false;
|
||||
}
|
||||
permSet.addAll(responseResult.getData().urlPerms);
|
||||
permSet.expire(authProps.getPermExpiredSeconds(), TimeUnit.SECONDS);
|
||||
localPermSet = new HashSet<>(responseResult.getData().urlPerms);
|
||||
cache.put(permKey, localPermSet);
|
||||
return localPermSet.contains(url);
|
||||
}
|
||||
|
||||
private void cacheThirdPartyDataPermData(
|
||||
ThirdPartyAuthConfig.AuthProperties authProps, TokenData tokenData, List<ThirdPartyAppDataPermData> dataPerms) {
|
||||
if (CollUtil.isEmpty(dataPerms)) {
|
||||
return;
|
||||
}
|
||||
Map<Integer, List<ThirdPartyAppDataPermData>> dataPermMap =
|
||||
dataPerms.stream().collect(Collectors.groupingBy(ThirdPartyAppDataPermData::getRuleType));
|
||||
Map<Integer, List<ThirdPartyAppDataPermData>> normalizedDataPermMap = new HashMap<>(dataPermMap.size());
|
||||
for (Map.Entry<Integer, List<ThirdPartyAppDataPermData>> entry : dataPermMap.entrySet()) {
|
||||
List<ThirdPartyAppDataPermData> ruleTypeDataPermDataList;
|
||||
if (entry.getKey().equals(DataPermRuleType.TYPE_DEPT_AND_CHILD_DEPT)) {
|
||||
ruleTypeDataPermDataList =
|
||||
normalizedDataPermMap.computeIfAbsent(DataPermRuleType.TYPE_CUSTOM_DEPT_LIST, k -> new LinkedList<>());
|
||||
} else {
|
||||
ruleTypeDataPermDataList =
|
||||
normalizedDataPermMap.computeIfAbsent(entry.getKey(), k -> new LinkedList<>());
|
||||
}
|
||||
ruleTypeDataPermDataList.addAll(entry.getValue());
|
||||
}
|
||||
Map<Integer, String> resultDataPermMap = new HashMap<>(normalizedDataPermMap.size());
|
||||
for (Map.Entry<Integer, List<ThirdPartyAppDataPermData>> entry : normalizedDataPermMap.entrySet()) {
|
||||
if (entry.getKey().equals(DataPermRuleType.TYPE_CUSTOM_DEPT_LIST)) {
|
||||
String deptIds = entry.getValue().stream()
|
||||
.map(ThirdPartyAppDataPermData::getDeptIds).collect(Collectors.joining(","));
|
||||
resultDataPermMap.put(entry.getKey(), deptIds);
|
||||
} else {
|
||||
resultDataPermMap.put(entry.getKey(), "null");
|
||||
}
|
||||
}
|
||||
Map<String, Map<Integer, String>> menuDataPermMap = new HashMap<>(1);
|
||||
menuDataPermMap.put(ApplicationConstant.DATA_PERM_ALL_MENU_ID, resultDataPermMap);
|
||||
String dataPermSessionKey = RedisKeyUtil.makeSessionDataPermIdKey(tokenData.getSessionId());
|
||||
RBucket<String> bucket = redissonClient.getBucket(dataPermSessionKey);
|
||||
bucket.set(JSON.toJSONString(menuDataPermMap), authProps.getPermExpiredSeconds(), TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class ThirdPartyAppPermData {
|
||||
/**
|
||||
* 当前用户会话可访问的url接口地址列表。
|
||||
*/
|
||||
private List<String> urlPerms;
|
||||
/**
|
||||
* 当前用户会话的数据权限列表。
|
||||
*/
|
||||
private List<ThirdPartyAppDataPermData> dataPerms;
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class ThirdPartyAppDataPermData {
|
||||
/**
|
||||
* 数据权限的规则类型。需要按照橙单的约定返回。具体值可参考DataPermRuleType常量类。
|
||||
*/
|
||||
private Integer ruleType;
|
||||
/**
|
||||
* 部门Id集合,多个部门Id之间逗号分隔。
|
||||
* 注意:仅当ruleType为3、4、5时需要包含该字段值。
|
||||
*/
|
||||
private String deptIds;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package com.orangeforms.webadmin.upms.bo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 菜单扩展数据对象。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
@Data
|
||||
public class SysMenuExtraData {
|
||||
|
||||
/**
|
||||
* 路由名称。
|
||||
*/
|
||||
private String formRouterName;
|
||||
|
||||
/**
|
||||
* 在线表单。
|
||||
*/
|
||||
private Long onlineFormId;
|
||||
|
||||
/**
|
||||
* 报表页面。
|
||||
*/
|
||||
private Long reportPageId;
|
||||
|
||||
/**
|
||||
* 流程。
|
||||
*/
|
||||
private Long onlineFlowEntryId;
|
||||
|
||||
/**
|
||||
* 目标url。
|
||||
*/
|
||||
private String targetUrl;
|
||||
|
||||
/**
|
||||
* 绑定类型。
|
||||
*/
|
||||
private Integer bindType;
|
||||
|
||||
/**
|
||||
* 前端使用的菜单编码。仅当选择satoken权限框架时使用。
|
||||
*/
|
||||
private String menuCode;
|
||||
|
||||
/**
|
||||
* 菜单关联的后台使用的权限字列表。仅当选择satoken权限框架时使用。
|
||||
*/
|
||||
private List<String> permCodeList;
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package com.orangeforms.webadmin.upms.bo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 菜单相关的业务对象。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
@Data
|
||||
public class SysMenuPerm {
|
||||
|
||||
/**
|
||||
* 菜单Id。
|
||||
*/
|
||||
private Long menuId;
|
||||
|
||||
/**
|
||||
* 父菜单Id,目录菜单的父菜单为null
|
||||
*/
|
||||
private Long parentId;
|
||||
|
||||
/**
|
||||
* 菜单显示名称。
|
||||
*/
|
||||
private String menuName;
|
||||
|
||||
/**
|
||||
* 菜单类型 (0: 目录 1: 菜单 2: 按钮 3: UI片段)。
|
||||
*/
|
||||
private Integer menuType;
|
||||
|
||||
/**
|
||||
* 在线表单主键Id,仅用于在线表单绑定的菜单。
|
||||
*/
|
||||
private Long onlineFormId;
|
||||
|
||||
/**
|
||||
* 在线表单菜单的权限控制类型,具体值可参考SysOnlineMenuPermType常量对象。
|
||||
*/
|
||||
private Integer onlineMenuPermType;
|
||||
|
||||
/**
|
||||
* 统计页面主键Id,仅用于统计页面绑定的菜单。
|
||||
*/
|
||||
private Long reportPageId;
|
||||
|
||||
/**
|
||||
* 仅用于在线表单的流程Id。
|
||||
*/
|
||||
private Long onlineFlowEntryId;
|
||||
|
||||
/**
|
||||
* 关联权限URL集合。
|
||||
*/
|
||||
Set<String> permUrlSet = new HashSet<>();
|
||||
|
||||
/**
|
||||
* 关联的某一个url。
|
||||
*/
|
||||
String url;
|
||||
}
|
||||
@@ -0,0 +1,340 @@
|
||||
package com.orangeforms.webadmin.upms.controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.orangeforms.common.core.annotation.MyRequestBody;
|
||||
import com.orangeforms.common.core.constant.ErrorCodeEnum;
|
||||
import com.orangeforms.common.core.object.MyOrderParam;
|
||||
import com.orangeforms.common.core.object.MyPageData;
|
||||
import com.orangeforms.common.core.object.MyPageParam;
|
||||
import com.orangeforms.common.core.object.ResponseResult;
|
||||
import com.orangeforms.common.core.util.MyCommonUtil;
|
||||
import com.orangeforms.common.core.util.MyModelUtil;
|
||||
import com.orangeforms.common.core.util.MyPageUtil;
|
||||
import com.orangeforms.common.core.validator.UpdateGroup;
|
||||
import com.orangeforms.common.dict.dto.GlobalDictDto;
|
||||
import com.orangeforms.common.dict.dto.GlobalDictItemDto;
|
||||
import com.orangeforms.common.dict.model.GlobalDict;
|
||||
import com.orangeforms.common.dict.model.GlobalDictItem;
|
||||
import com.orangeforms.common.dict.service.GlobalDictItemService;
|
||||
import com.orangeforms.common.dict.service.GlobalDictService;
|
||||
import com.orangeforms.common.dict.util.GlobalDictOperationHelper;
|
||||
import com.orangeforms.common.dict.vo.GlobalDictVo;
|
||||
import com.orangeforms.common.log.annotation.OperationLog;
|
||||
import com.orangeforms.common.log.model.constant.SysOperationLogType;
|
||||
import com.github.pagehelper.Page;
|
||||
import com.github.pagehelper.page.PageMethod;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import jakarta.validation.groups.Default;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 全局通用字典操作接口。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
@Tag(name = "全局字典管理接口")
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/admin/upms/globalDict")
|
||||
public class GlobalDictController {
|
||||
|
||||
@Autowired
|
||||
private GlobalDictService globalDictService;
|
||||
@Autowired
|
||||
private GlobalDictItemService globalDictItemService;
|
||||
@Autowired
|
||||
private GlobalDictOperationHelper globalDictOperationHelper;
|
||||
|
||||
/**
|
||||
* 新增全局字典接口。
|
||||
*
|
||||
* @param globalDictDto 新增字典对象。
|
||||
* @return 保存后的字典对象。
|
||||
*/
|
||||
@ApiOperationSupport(ignoreParameters = {"globalDictDto.dictId"})
|
||||
@SaCheckPermission("globalDict.update")
|
||||
@OperationLog(type = SysOperationLogType.ADD)
|
||||
@PostMapping("/add")
|
||||
public ResponseResult<Long> add(@MyRequestBody GlobalDictDto globalDictDto) {
|
||||
String errorMessage = MyCommonUtil.getModelValidationError(globalDictDto);
|
||||
if (errorMessage != null) {
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
|
||||
}
|
||||
// 这里必须手动校验字典编码是否存在,因为我们缺省的实现是逻辑删除,所以字典编码字段没有设置为唯一索引。
|
||||
if (globalDictService.existDictCode(globalDictDto.getDictCode())) {
|
||||
errorMessage = "数据验证失败,字典编码已经存在!";
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
|
||||
}
|
||||
GlobalDict globalDict = MyModelUtil.copyTo(globalDictDto, GlobalDict.class);
|
||||
globalDictService.saveNew(globalDict);
|
||||
return ResponseResult.success(globalDict.getDictId());
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新全局字典操作。
|
||||
*
|
||||
* @param globalDictDto 更新全局字典对象。
|
||||
* @return 应答结果对象。
|
||||
*/
|
||||
@SaCheckPermission("globalDict.update")
|
||||
@OperationLog(type = SysOperationLogType.UPDATE)
|
||||
@PostMapping("/update")
|
||||
public ResponseResult<Void> update(@MyRequestBody GlobalDictDto globalDictDto) {
|
||||
String errorMessage = MyCommonUtil.getModelValidationError(globalDictDto, Default.class, UpdateGroup.class);
|
||||
if (errorMessage != null) {
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
|
||||
}
|
||||
GlobalDict originalGlobalDict = globalDictService.getById(globalDictDto.getDictId());
|
||||
if (originalGlobalDict == null) {
|
||||
errorMessage = "数据验证失败,当前全局字典并不存在,请刷新后重试!";
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
|
||||
}
|
||||
GlobalDict globalDict = MyModelUtil.copyTo(globalDictDto, GlobalDict.class);
|
||||
if (ObjectUtil.notEqual(globalDict.getDictCode(), originalGlobalDict.getDictCode())
|
||||
&& globalDictService.existDictCode(globalDict.getDictCode())) {
|
||||
errorMessage = "数据验证失败,字典编码已经存在!";
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
|
||||
}
|
||||
if (!globalDictService.update(globalDict, originalGlobalDict)) {
|
||||
errorMessage = "更新失败,数据不存在,请刷新后重试!";
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
|
||||
}
|
||||
return ResponseResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除指定的全局字典。
|
||||
*
|
||||
* @param dictId 指定全局字典主键Id。
|
||||
* @return 应答结果对象。
|
||||
*/
|
||||
@SaCheckPermission("globalDict.update")
|
||||
@OperationLog(type = SysOperationLogType.DELETE)
|
||||
@PostMapping("/delete")
|
||||
public ResponseResult<Void> delete(@MyRequestBody(required = true) Long dictId) {
|
||||
if (!globalDictService.remove(dictId)) {
|
||||
String errorMessage = "数据操作失败,全局字典Id不存在,请刷新后重试!";
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
|
||||
}
|
||||
return ResponseResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看全局字典列表。
|
||||
*
|
||||
* @param globalDictDtoFilter 过滤对象。
|
||||
* @param orderParam 排序参数。
|
||||
* @param pageParam 分页参数。
|
||||
* @return 应答结果对象,包含角色列表。
|
||||
*/
|
||||
@SaCheckPermission("globalDict.view")
|
||||
@PostMapping("/list")
|
||||
public ResponseResult<MyPageData<GlobalDictVo>> list(
|
||||
@MyRequestBody GlobalDictDto globalDictDtoFilter,
|
||||
@MyRequestBody MyOrderParam orderParam,
|
||||
@MyRequestBody MyPageParam pageParam) {
|
||||
if (pageParam != null) {
|
||||
PageMethod.startPage(pageParam.getPageNum(), pageParam.getPageSize());
|
||||
}
|
||||
GlobalDict filter = MyModelUtil.copyTo(globalDictDtoFilter, GlobalDict.class);
|
||||
List<GlobalDict> globalDictList =
|
||||
globalDictService.getGlobalDictList(filter, MyOrderParam.buildOrderBy(orderParam, GlobalDict.class));
|
||||
List<GlobalDictVo> globalDictVoList =
|
||||
MyModelUtil.copyCollectionTo(globalDictList, GlobalDictVo.class);
|
||||
long totalCount = 0L;
|
||||
if (globalDictList instanceof Page) {
|
||||
totalCount = ((Page<GlobalDict>) globalDictList).getTotal();
|
||||
}
|
||||
return ResponseResult.success(MyPageUtil.makeResponseData(globalDictVoList, totalCount));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增全局字典项目接口。
|
||||
*
|
||||
* @param globalDictItemDto 新增字典项目对象。
|
||||
* @return 保存后的字典对象。
|
||||
*/
|
||||
@SaCheckPermission("globalDict.update")
|
||||
@ApiOperationSupport(ignoreParameters = {"globalDictItemDto.id"})
|
||||
@OperationLog(type = SysOperationLogType.ADD)
|
||||
@PostMapping("/addItem")
|
||||
public ResponseResult<Long> addItem(@MyRequestBody GlobalDictItemDto globalDictItemDto) {
|
||||
String errorMessage = MyCommonUtil.getModelValidationError(globalDictItemDto);
|
||||
if (errorMessage != null) {
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
|
||||
}
|
||||
if (!globalDictService.existDictCode(globalDictItemDto.getDictCode())) {
|
||||
errorMessage = "数据验证失败,字典编码不存在!";
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
|
||||
}
|
||||
if (globalDictItemService.existDictCodeAndItemId(
|
||||
globalDictItemDto.getDictCode(), globalDictItemDto.getItemId())) {
|
||||
errorMessage = "数据验证失败,该字典编码的项目Id已存在!";
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
|
||||
}
|
||||
GlobalDictItem globalDictItem = MyModelUtil.copyTo(globalDictItemDto, GlobalDictItem.class);
|
||||
globalDictItemService.saveNew(globalDictItem);
|
||||
return ResponseResult.success(globalDictItem.getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新全局字典项目。
|
||||
*
|
||||
* @param globalDictItemDto 更新全局字典项目对象。
|
||||
* @return 应答结果对象。
|
||||
*/
|
||||
@SaCheckPermission("globalDict.update")
|
||||
@OperationLog(type = SysOperationLogType.UPDATE)
|
||||
@PostMapping("/updateItem")
|
||||
public ResponseResult<Void> updateItem(@MyRequestBody GlobalDictItemDto globalDictItemDto) {
|
||||
String errorMessage = MyCommonUtil.getModelValidationError(globalDictItemDto, Default.class, UpdateGroup.class);
|
||||
if (errorMessage != null) {
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
|
||||
}
|
||||
GlobalDictItem originalGlobalDictItem = globalDictItemService.getById(globalDictItemDto.getId());
|
||||
if (originalGlobalDictItem == null) {
|
||||
errorMessage = "数据验证失败,当前全局字典项目并不存在,请刷新后重试!";
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
|
||||
}
|
||||
GlobalDictItem globalDictItem = MyModelUtil.copyTo(globalDictItemDto, GlobalDictItem.class);
|
||||
if (ObjectUtil.notEqual(globalDictItem.getDictCode(), originalGlobalDictItem.getDictCode())) {
|
||||
errorMessage = "数据验证失败,字典项目的字典编码不能修改!";
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
|
||||
}
|
||||
if (ObjectUtil.notEqual(globalDictItem.getItemId(), originalGlobalDictItem.getItemId())
|
||||
&& globalDictItemService.existDictCodeAndItemId(globalDictItem.getDictCode(), globalDictItem.getItemId())) {
|
||||
errorMessage = "数据验证失败,该字典编码已经包含了该项目Id!";
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
|
||||
}
|
||||
if (!globalDictItemService.update(globalDictItem, originalGlobalDictItem)) {
|
||||
errorMessage = "更新失败,数据不存在,请刷新后重试!";
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
|
||||
}
|
||||
return ResponseResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新全局字典项目的状态。
|
||||
*
|
||||
* @param id 更新全局字典项目主键Id。
|
||||
* @return 应答结果对象。
|
||||
*/
|
||||
@SaCheckPermission("globalDict.update")
|
||||
@OperationLog(type = SysOperationLogType.UPDATE)
|
||||
@PostMapping("/updateItemStatus")
|
||||
public ResponseResult<Void> updateItemStatus(
|
||||
@MyRequestBody(required = true) Long id, @MyRequestBody(required = true) Integer status) {
|
||||
String errorMessage;
|
||||
GlobalDictItem dictItem = globalDictItemService.getById(id);
|
||||
if (dictItem == null) {
|
||||
errorMessage = "数据操作失败,全局字典项目Id不存在,请刷新后重试!";
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
|
||||
}
|
||||
if (ObjectUtil.notEqual(dictItem.getStatus(), status)) {
|
||||
globalDictItemService.updateStatus(dictItem, status);
|
||||
}
|
||||
return ResponseResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除指定编码的全局字典项目。
|
||||
*
|
||||
* @param id 主键Id。
|
||||
* @return 应答结果对象。
|
||||
*/
|
||||
@SaCheckPermission("globalDict.update")
|
||||
@OperationLog(type = SysOperationLogType.DELETE)
|
||||
@PostMapping("/deleteItem")
|
||||
public ResponseResult<Void> deleteItem(@MyRequestBody(required = true) Long id) {
|
||||
String errorMessage;
|
||||
GlobalDictItem dictItem = globalDictItemService.getById(id);
|
||||
if (dictItem == null) {
|
||||
errorMessage = "数据操作失败,全局字典项目Id不存在,请刷新后重试!";
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
|
||||
}
|
||||
if (!globalDictItemService.remove(dictItem)) {
|
||||
errorMessage = "数据操作失败,全局字典项目Id不存在,请刷新后重试!";
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
|
||||
}
|
||||
return ResponseResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 将当前字典表的数据重新加载到缓存中。
|
||||
* 由于缓存的数据更新,在add/update/delete等接口均有同步处理。因此该接口仅当同步过程中出现问题时,
|
||||
* 可手工调用,或者每天晚上定时同步一次。
|
||||
*/
|
||||
@SaCheckPermission("globalDict.view")
|
||||
@OperationLog(type = SysOperationLogType.RELOAD_CACHE)
|
||||
@GetMapping("/reloadCachedData")
|
||||
public ResponseResult<Boolean> reloadCachedData(@RequestParam String dictCode) {
|
||||
globalDictService.reloadCachedData(dictCode);
|
||||
return ResponseResult.success(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定字典编码的全局字典项目。字典的键值为[itemId, itemName]。
|
||||
* NOTE: 白名单接口。
|
||||
*
|
||||
* @param dictCode 字典编码。
|
||||
* @param itemIdType 字典项目的ItemId值转换到的目标类型。可能值为Integer或Long。
|
||||
* @return 应答结果对象。
|
||||
*/
|
||||
@GetMapping("/listDict")
|
||||
public ResponseResult<List<Map<String, Object>>> listDict(
|
||||
@RequestParam String dictCode, @RequestParam(required = false) String itemIdType) {
|
||||
List<GlobalDictItem> resultList =
|
||||
globalDictService.getGlobalDictItemListFromCache(dictCode, null);
|
||||
resultList = resultList.stream()
|
||||
.sorted(Comparator.comparing(GlobalDictItem::getStatus))
|
||||
.sorted(Comparator.comparing(GlobalDictItem::getShowOrder))
|
||||
.collect(Collectors.toList());
|
||||
return ResponseResult.success(globalDictOperationHelper.toDictDataList(resultList, itemIdType));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据字典Id集合,获取查询后的字典数据。
|
||||
* NOTE: 白名单接口。
|
||||
*
|
||||
* @param dictCode 字典编码。
|
||||
* @param itemIds 字典项目Id集合。
|
||||
* @param itemIdType 字典项目的ItemId值转换到的目标类型。可能值为Integer或Long。
|
||||
* @return 应答结果对象,包含字典形式的数据集合。
|
||||
*/
|
||||
@GetMapping("/listDictByIds")
|
||||
public ResponseResult<List<Map<String, Object>>> listDictByIds(
|
||||
@RequestParam String dictCode,
|
||||
@RequestParam List<String> itemIds,
|
||||
@RequestParam(required = false) String itemIdType) {
|
||||
List<GlobalDictItem> resultList =
|
||||
globalDictService.getGlobalDictItemListFromCache(dictCode, new HashSet<>(itemIds));
|
||||
return ResponseResult.success(globalDictOperationHelper.toDictDataList(resultList, itemIdType));
|
||||
}
|
||||
|
||||
/**
|
||||
* 白名单接口,登录用户均可访问。以字典形式返回全部字典数据集合。
|
||||
* fullResultList中的字典列表全部取自于数据库,而cachedResultList全部取自于缓存,前端负责比对。
|
||||
*
|
||||
* @return 应答结果对象,包含字典形式的数据集合。
|
||||
*/
|
||||
@GetMapping("/listAll")
|
||||
public ResponseResult<JSONObject> listAll(@RequestParam String dictCode) {
|
||||
List<GlobalDictItem> fullResultList =
|
||||
globalDictItemService.getGlobalDictItemListByDictCode(dictCode);
|
||||
List<GlobalDictItem> cachedList =
|
||||
globalDictService.getGlobalDictItemListFromCache(dictCode, null);
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("fullResultList", globalDictOperationHelper.toDictDataList2(fullResultList));
|
||||
jsonObject.put("cachedResultList", globalDictOperationHelper.toDictDataList2(cachedList));
|
||||
return ResponseResult.success(jsonObject);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,475 @@
|
||||
package com.orangeforms.webadmin.upms.controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaIgnore;
|
||||
import cn.dev33.satoken.session.SaSession;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.BooleanUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import com.orangeforms.webadmin.config.ApplicationConfig;
|
||||
import com.orangeforms.webadmin.upms.bo.SysMenuExtraData;
|
||||
import com.orangeforms.webadmin.upms.service.*;
|
||||
import com.orangeforms.webadmin.upms.model.*;
|
||||
import com.orangeforms.webadmin.upms.model.constant.SysUserStatus;
|
||||
import com.orangeforms.webadmin.upms.model.constant.SysUserType;
|
||||
import com.orangeforms.webadmin.upms.model.constant.SysMenuType;
|
||||
import com.orangeforms.webadmin.upms.model.constant.SysOnlineMenuPermType;
|
||||
import com.orangeforms.common.flow.online.service.FlowOnlineOperationService;
|
||||
import com.orangeforms.common.online.service.OnlineOperationService;
|
||||
import com.orangeforms.common.core.annotation.MyRequestBody;
|
||||
import com.orangeforms.common.core.annotation.DisableDataFilter;
|
||||
import com.orangeforms.common.core.constant.ErrorCodeEnum;
|
||||
import com.orangeforms.common.core.constant.ApplicationConstant;
|
||||
import com.orangeforms.common.core.object.*;
|
||||
import com.orangeforms.common.core.util.*;
|
||||
import com.orangeforms.common.core.upload.*;
|
||||
import com.orangeforms.common.redis.cache.SessionCacheHelper;
|
||||
import com.orangeforms.common.log.annotation.OperationLog;
|
||||
import com.orangeforms.common.log.model.constant.SysOperationLogType;
|
||||
import com.orangeforms.common.satoken.util.SaTokenUtil;
|
||||
import org.redisson.api.RSet;
|
||||
import org.redisson.api.RedissonClient;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 登录接口控制器类。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
@ApiSupport(order = 1)
|
||||
@Tag(name = "用户登录接口")
|
||||
@DisableDataFilter
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/admin/upms/login")
|
||||
public class LoginController {
|
||||
|
||||
@Autowired
|
||||
private SysUserService sysUserService;
|
||||
@Autowired
|
||||
private SysDeptService sysDeptService;
|
||||
@Autowired
|
||||
private SysMenuService sysMenuService;
|
||||
@Autowired
|
||||
private SysPostService sysPostService;
|
||||
@Autowired
|
||||
private SysRoleService sysRoleService;
|
||||
@Autowired
|
||||
private SysDataPermService sysDataPermService;
|
||||
@Autowired
|
||||
private SysPermWhitelistService sysPermWhitelistService;
|
||||
@Autowired
|
||||
private OnlineOperationService onlineOperationService;
|
||||
@Autowired
|
||||
private FlowOnlineOperationService flowOnlineOperationService;
|
||||
@Autowired
|
||||
private ApplicationConfig appConfig;
|
||||
@Autowired
|
||||
private RedissonClient redissonClient;
|
||||
@Autowired
|
||||
private SessionCacheHelper cacheHelper;
|
||||
@Autowired
|
||||
private PasswordEncoder passwordEncoder;
|
||||
@Autowired
|
||||
private UpDownloaderFactory upDownloaderFactory;
|
||||
@Autowired
|
||||
private SaTokenUtil saTokenUtil;
|
||||
|
||||
private static final String IS_ADMIN = "isAdmin";
|
||||
private static final String SHOW_NAME_FIELD = "showName";
|
||||
private static final String SHOW_ORDER_FIELD = "showOrder";
|
||||
private static final String HEAD_IMAGE_URL_FIELD = "headImageUrl";
|
||||
|
||||
/**
|
||||
* 登录接口。
|
||||
*
|
||||
* @param loginName 登录名。
|
||||
* @param password 密码。
|
||||
* @return 应答结果对象,其中包括Token数据,以及菜单列表。
|
||||
*/
|
||||
@Parameter(name = "loginName", example = "admin")
|
||||
@Parameter(name = "password", example = "IP3ccke3GhH45iGHB5qP9p7iZw6xUyj28Ju10rnBiPKOI35sc%2BjI7%2FdsjOkHWMfUwGYGfz8ik31HC2Ruk%2Fhkd9f6RPULTHj7VpFdNdde2P9M4mQQnFBAiPM7VT9iW3RyCtPlJexQ3nAiA09OqG%2F0sIf1kcyveSrulxembARDbDo%3D")
|
||||
@SaIgnore
|
||||
@OperationLog(type = SysOperationLogType.LOGIN, saveResponse = false)
|
||||
@PostMapping("/doLogin")
|
||||
public ResponseResult<JSONObject> doLogin(
|
||||
@MyRequestBody String loginName,
|
||||
@MyRequestBody String password) throws UnsupportedEncodingException {
|
||||
if (MyCommonUtil.existBlankArgument(loginName, password)) {
|
||||
return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
|
||||
}
|
||||
ResponseResult<SysUser> verifyResult = this.verifyAndHandleLoginUser(loginName, password);
|
||||
if (!verifyResult.isSuccess()) {
|
||||
return ResponseResult.errorFrom(verifyResult);
|
||||
}
|
||||
JSONObject jsonData = this.buildLoginDataAndLogin(verifyResult.getData());
|
||||
return ResponseResult.success(jsonData);
|
||||
}
|
||||
|
||||
/**
|
||||
* 登出操作。同时将Session相关的信息从缓存中删除。
|
||||
*
|
||||
* @return 应答结果对象。
|
||||
*/
|
||||
@OperationLog(type = SysOperationLogType.LOGOUT)
|
||||
@PostMapping("/doLogout")
|
||||
public ResponseResult<Void> doLogout() {
|
||||
String sessionId = TokenData.takeFromRequest().getSessionId();
|
||||
redissonClient.getBucket(TokenData.takeFromRequest().getMySessionId()).deleteAsync();
|
||||
redissonClient.getBucket(RedisKeyUtil.makeSessionPermCodeKey(sessionId)).deleteAsync();
|
||||
redissonClient.getBucket(RedisKeyUtil.makeSessionPermIdKey(sessionId)).deleteAsync();
|
||||
sysDataPermService.removeDataPermCache(sessionId);
|
||||
cacheHelper.removeAllSessionCache(sessionId);
|
||||
StpUtil.logout();
|
||||
return ResponseResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 在登录之后,通过token再次获取登录信息。
|
||||
* 用于在当前浏览器登录系统后,在新tab页中可以免密登录。
|
||||
*
|
||||
* @return 应答结果对象,其中包括JWT的Token数据,以及菜单列表。
|
||||
*/
|
||||
@GetMapping("/getLoginInfo")
|
||||
public ResponseResult<JSONObject> getLoginInfo() {
|
||||
TokenData tokenData = TokenData.takeFromRequest();
|
||||
JSONObject jsonData = new JSONObject();
|
||||
jsonData.put(SHOW_NAME_FIELD, tokenData.getShowName());
|
||||
jsonData.put(IS_ADMIN, tokenData.getIsAdmin());
|
||||
if (StrUtil.isNotBlank(tokenData.getHeadImageUrl())) {
|
||||
jsonData.put(HEAD_IMAGE_URL_FIELD, tokenData.getHeadImageUrl());
|
||||
}
|
||||
Collection<SysMenu> allMenuList;
|
||||
if (BooleanUtil.isTrue(tokenData.getIsAdmin())) {
|
||||
allMenuList = sysMenuService.getAllListByOrder(SHOW_ORDER_FIELD);
|
||||
} else {
|
||||
allMenuList = sysMenuService.getMenuListByRoleIds(tokenData.getRoleIds());
|
||||
}
|
||||
List<String> menuCodeList = new LinkedList<>();
|
||||
OnlinePermData onlinePermData = this.getOnlineMenuPermData(allMenuList);
|
||||
CollUtil.addAll(menuCodeList, onlinePermData.permCodeSet);
|
||||
OnlinePermData onlineFlowPermData = this.getFlowOnlineMenuPermData(allMenuList);
|
||||
CollUtil.addAll(menuCodeList, onlineFlowPermData.permCodeSet);
|
||||
allMenuList.stream().filter(m -> m.getExtraData() != null)
|
||||
.forEach(m -> m.setExtraObject(JSON.parseObject(m.getExtraData(), SysMenuExtraData.class)));
|
||||
this.appendResponseMenuAndPermCodeData(jsonData, allMenuList, menuCodeList);
|
||||
return ResponseResult.success(jsonData);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回所有可用的权限字列表。
|
||||
*
|
||||
* @return 整个系统所有可用的权限字列表。
|
||||
*/
|
||||
@GetMapping("/getAllPermCodes")
|
||||
public ResponseResult<List<String>> getAllPermCodes() {
|
||||
List<String> permCodes = saTokenUtil.getAllPermCodes();
|
||||
return ResponseResult.success(permCodes);
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户修改自己的密码。
|
||||
*
|
||||
* @param oldPass 原有密码。
|
||||
* @param newPass 新密码。
|
||||
* @return 应答结果对象。
|
||||
*/
|
||||
@PostMapping("/changePassword")
|
||||
public ResponseResult<Void> changePassword(
|
||||
@MyRequestBody String oldPass, @MyRequestBody String newPass) throws UnsupportedEncodingException {
|
||||
if (MyCommonUtil.existBlankArgument(newPass, oldPass)) {
|
||||
return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
|
||||
}
|
||||
TokenData tokenData = TokenData.takeFromRequest();
|
||||
SysUser user = sysUserService.getById(tokenData.getUserId());
|
||||
oldPass = URLDecoder.decode(oldPass, StandardCharsets.UTF_8.name());
|
||||
// NOTE: 第一次使用时,请务必阅读ApplicationConstant.PRIVATE_KEY的代码注释。
|
||||
// 执行RsaUtil工具类中的main函数,可以生成新的公钥和私钥。
|
||||
oldPass = RsaUtil.decrypt(oldPass, ApplicationConstant.PRIVATE_KEY);
|
||||
if (user == null || !passwordEncoder.matches(oldPass, user.getPassword())) {
|
||||
return ResponseResult.error(ErrorCodeEnum.INVALID_USERNAME_PASSWORD);
|
||||
}
|
||||
newPass = URLDecoder.decode(newPass, StandardCharsets.UTF_8.name());
|
||||
newPass = RsaUtil.decrypt(newPass, ApplicationConstant.PRIVATE_KEY);
|
||||
if (!sysUserService.changePassword(tokenData.getUserId(), newPass)) {
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
|
||||
}
|
||||
return ResponseResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传并修改用户头像。
|
||||
*
|
||||
* @param uploadFile 上传的头像文件。
|
||||
*/
|
||||
@PostMapping("/changeHeadImage")
|
||||
public void changeHeadImage(@RequestParam("uploadFile") MultipartFile uploadFile) throws IOException {
|
||||
UploadStoreInfo storeInfo = MyModelUtil.getUploadStoreInfo(SysUser.class, HEAD_IMAGE_URL_FIELD);
|
||||
BaseUpDownloader upDownloader = upDownloaderFactory.get(storeInfo.getStoreType());
|
||||
UploadResponseInfo responseInfo = upDownloader.doUpload(null,
|
||||
appConfig.getUploadFileBaseDir(), SysUser.class.getSimpleName(), HEAD_IMAGE_URL_FIELD, true, uploadFile);
|
||||
if (BooleanUtil.isTrue(responseInfo.getUploadFailed())) {
|
||||
ResponseResult.output(HttpServletResponse.SC_FORBIDDEN,
|
||||
ResponseResult.error(ErrorCodeEnum.UPLOAD_FAILED, responseInfo.getErrorMessage()));
|
||||
return;
|
||||
}
|
||||
responseInfo.setDownloadUri("/admin/upms/login/downloadHeadImage");
|
||||
String newHeadImage = JSONArray.toJSONString(CollUtil.newArrayList(responseInfo));
|
||||
if (!sysUserService.changeHeadImage(TokenData.takeFromRequest().getUserId(), newHeadImage)) {
|
||||
ResponseResult.output(HttpServletResponse.SC_FORBIDDEN, ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST));
|
||||
return;
|
||||
}
|
||||
ResponseResult.output(ResponseResult.success(responseInfo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载用户头像。
|
||||
*
|
||||
* @param filename 文件名。如果没有提供该参数,就从当前记录的指定字段中读取。
|
||||
* @param response Http 应答对象。
|
||||
*/
|
||||
@GetMapping("/downloadHeadImage")
|
||||
public void downloadHeadImage(String filename, HttpServletResponse response) {
|
||||
try {
|
||||
UploadStoreInfo storeInfo = MyModelUtil.getUploadStoreInfo(SysUser.class, HEAD_IMAGE_URL_FIELD);
|
||||
BaseUpDownloader upDownloader = upDownloaderFactory.get(storeInfo.getStoreType());
|
||||
upDownloader.doDownload(appConfig.getUploadFileBaseDir(),
|
||||
SysUser.class.getSimpleName(), HEAD_IMAGE_URL_FIELD, filename, true, response);
|
||||
} catch (Exception e) {
|
||||
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private ResponseResult<SysUser> verifyAndHandleLoginUser(
|
||||
String loginName, String password) throws UnsupportedEncodingException {
|
||||
String errorMessage;
|
||||
SysUser user = sysUserService.getSysUserByLoginName(loginName);
|
||||
password = URLDecoder.decode(password, StandardCharsets.UTF_8.name());
|
||||
// NOTE: 第一次使用时,请务必阅读ApplicationConstant.PRIVATE_KEY的代码注释。
|
||||
// 执行RsaUtil工具类中的main函数,可以生成新的公钥和私钥。
|
||||
password = RsaUtil.decrypt(password, ApplicationConstant.PRIVATE_KEY);
|
||||
if (user == null || !passwordEncoder.matches(password, user.getPassword())) {
|
||||
return ResponseResult.error(ErrorCodeEnum.INVALID_USERNAME_PASSWORD);
|
||||
}
|
||||
if (user.getUserStatus() == SysUserStatus.STATUS_LOCKED) {
|
||||
errorMessage = "登录失败,用户账号被锁定!";
|
||||
return ResponseResult.error(ErrorCodeEnum.INVALID_USER_STATUS, errorMessage);
|
||||
}
|
||||
if (BooleanUtil.isTrue(appConfig.getExcludeLogin())) {
|
||||
String deviceType = MyCommonUtil.getDeviceTypeWithString();
|
||||
LoginUserInfo userInfo = BeanUtil.copyProperties(user, LoginUserInfo.class);
|
||||
String loginId = SaTokenUtil.makeLoginId(userInfo);
|
||||
StpUtil.kickout(loginId, deviceType);
|
||||
}
|
||||
return ResponseResult.success(user);
|
||||
}
|
||||
|
||||
private JSONObject buildLoginDataAndLogin(SysUser user) {
|
||||
TokenData tokenData = this.loginAndCreateToken(user);
|
||||
// 这里手动将TokenData存入request,便于OperationLogAspect统一处理操作日志。
|
||||
TokenData.addToRequest(tokenData);
|
||||
JSONObject jsonData = this.createResponseData(user);
|
||||
Collection<SysMenu> allMenuList;
|
||||
boolean isAdmin = user.getUserType() == SysUserType.TYPE_ADMIN;
|
||||
if (isAdmin) {
|
||||
allMenuList = sysMenuService.getAllListByOrder(SHOW_ORDER_FIELD);
|
||||
} else {
|
||||
allMenuList = sysMenuService.getMenuListByRoleIds(tokenData.getRoleIds());
|
||||
}
|
||||
allMenuList.stream().filter(m -> m.getExtraData() != null)
|
||||
.forEach(m -> m.setExtraObject(JSON.parseObject(m.getExtraData(), SysMenuExtraData.class)));
|
||||
Collection<String> permCodeList = new LinkedList<>();
|
||||
allMenuList.stream().filter(m -> m.getExtraObject() != null)
|
||||
.forEach(m -> CollUtil.addAll(permCodeList, m.getExtraObject().getPermCodeList()));
|
||||
Set<String> permSet = new HashSet<>();
|
||||
if (!isAdmin) {
|
||||
// 所有登录用户都有白名单接口的访问权限。
|
||||
CollUtil.addAll(permSet, sysPermWhitelistService.getWhitelistPermList());
|
||||
}
|
||||
List<String> menuCodeList = new LinkedList<>();
|
||||
OnlinePermData onlinePermData = this.getOnlineMenuPermData(allMenuList);
|
||||
CollUtil.addAll(menuCodeList, onlinePermData.permCodeSet);
|
||||
OnlinePermData onlineFlowPermData = this.getFlowOnlineMenuPermData(allMenuList);
|
||||
CollUtil.addAll(menuCodeList, onlineFlowPermData.permCodeSet);
|
||||
if (!isAdmin) {
|
||||
permSet.addAll(onlinePermData.permUrlSet);
|
||||
permSet.addAll(onlineFlowPermData.permUrlSet);
|
||||
String sessionId = tokenData.getSessionId();
|
||||
// 缓存用户的权限资源,这里缓存的是基于URL验证的权限资源,比如在线表单、工作流和数据表中的白名单资源。
|
||||
this.putUserSysPermCache(sessionId, permSet);
|
||||
// 缓存权限字字段,StpInterfaceImpl中会从缓存中读取,并交给satoken进行接口权限的验证。
|
||||
this.putUserSysPermCodeCache(sessionId, permCodeList);
|
||||
sysDataPermService.putDataPermCache(sessionId, user.getUserId(), user.getDeptId());
|
||||
}
|
||||
this.appendResponseMenuAndPermCodeData(jsonData, allMenuList, menuCodeList);
|
||||
return jsonData;
|
||||
}
|
||||
|
||||
private TokenData loginAndCreateToken(SysUser user) {
|
||||
String deviceType = MyCommonUtil.getDeviceTypeWithString();
|
||||
LoginUserInfo userInfo = BeanUtil.copyProperties(user, LoginUserInfo.class);
|
||||
String loginId = SaTokenUtil.makeLoginId(userInfo);
|
||||
StpUtil.login(loginId, deviceType);
|
||||
SaSession session = StpUtil.getTokenSession();
|
||||
TokenData tokenData = this.buildTokenData(user, session.getId(), StpUtil.getLoginDevice());
|
||||
String mySessionId = RedisKeyUtil.getSessionIdPrefix(tokenData, user.getLoginName()) + MyCommonUtil.generateUuid();
|
||||
tokenData.setMySessionId(mySessionId);
|
||||
tokenData.setToken(session.getToken());
|
||||
redissonClient.getBucket(mySessionId)
|
||||
.set(JSON.toJSONString(tokenData), appConfig.getSessionExpiredSeconds(), TimeUnit.SECONDS);
|
||||
session.set(TokenData.REQUEST_ATTRIBUTE_NAME, tokenData);
|
||||
return tokenData;
|
||||
}
|
||||
|
||||
private JSONObject createResponseData(SysUser user) {
|
||||
JSONObject jsonData = new JSONObject();
|
||||
jsonData.put(TokenData.REQUEST_ATTRIBUTE_NAME, StpUtil.getTokenValue());
|
||||
jsonData.put(SHOW_NAME_FIELD, user.getShowName());
|
||||
jsonData.put(IS_ADMIN, user.getUserType() == SysUserType.TYPE_ADMIN);
|
||||
if (user.getDeptId() != null) {
|
||||
SysDept dept = sysDeptService.getById(user.getDeptId());
|
||||
jsonData.put("deptName", dept.getDeptName());
|
||||
}
|
||||
if (StrUtil.isNotBlank(user.getHeadImageUrl())) {
|
||||
jsonData.put(HEAD_IMAGE_URL_FIELD, user.getHeadImageUrl());
|
||||
}
|
||||
return jsonData;
|
||||
}
|
||||
|
||||
private void appendResponseMenuAndPermCodeData(
|
||||
JSONObject responseData, Collection<SysMenu> allMenuList, Collection<String> menuCodeList) {
|
||||
allMenuList.stream()
|
||||
.filter(m -> m.getExtraObject() != null && StrUtil.isNotBlank(m.getExtraObject().getMenuCode()))
|
||||
.forEach(m -> CollUtil.addAll(menuCodeList, m.getExtraObject().getMenuCode()));
|
||||
List<SysMenu> menuList = allMenuList.stream()
|
||||
.filter(m -> m.getMenuType() <= SysMenuType.TYPE_MENU).collect(Collectors.toList());
|
||||
responseData.put("menuList", menuList);
|
||||
responseData.put("permCodeList", menuCodeList);
|
||||
}
|
||||
|
||||
private TokenData buildTokenData(SysUser user, String sessionId, String deviceType) {
|
||||
TokenData tokenData = new TokenData();
|
||||
tokenData.setSessionId(sessionId);
|
||||
tokenData.setUserId(user.getUserId());
|
||||
tokenData.setDeptId(user.getDeptId());
|
||||
tokenData.setLoginName(user.getLoginName());
|
||||
tokenData.setShowName(user.getShowName());
|
||||
tokenData.setIsAdmin(user.getUserType().equals(SysUserType.TYPE_ADMIN));
|
||||
tokenData.setLoginIp(IpUtil.getRemoteIpAddress(ContextUtil.getHttpRequest()));
|
||||
tokenData.setLoginTime(new Date());
|
||||
tokenData.setDeviceType(deviceType);
|
||||
tokenData.setHeadImageUrl(user.getHeadImageUrl());
|
||||
List<SysUserPost> userPostList = sysPostService.getSysUserPostListByUserId(user.getUserId());
|
||||
if (CollUtil.isNotEmpty(userPostList)) {
|
||||
Set<Long> deptPostIdSet = userPostList.stream().map(SysUserPost::getDeptPostId).collect(Collectors.toSet());
|
||||
tokenData.setDeptPostIds(StrUtil.join(",", deptPostIdSet));
|
||||
Set<Long> postIdSet = userPostList.stream().map(SysUserPost::getPostId).collect(Collectors.toSet());
|
||||
tokenData.setPostIds(StrUtil.join(",", postIdSet));
|
||||
}
|
||||
List<SysUserRole> userRoleList = sysRoleService.getSysUserRoleListByUserId(user.getUserId());
|
||||
if (CollUtil.isNotEmpty(userRoleList)) {
|
||||
Set<Long> userRoleIdSet = userRoleList.stream().map(SysUserRole::getRoleId).collect(Collectors.toSet());
|
||||
tokenData.setRoleIds(StrUtil.join(",", userRoleIdSet));
|
||||
}
|
||||
return tokenData;
|
||||
}
|
||||
|
||||
private void putUserSysPermCache(String sessionId, Collection<String> permUrlSet) {
|
||||
if (CollUtil.isEmpty(permUrlSet)) {
|
||||
return;
|
||||
}
|
||||
String sessionPermKey = RedisKeyUtil.makeSessionPermIdKey(sessionId);
|
||||
RSet<String> redisPermSet = redissonClient.getSet(sessionPermKey);
|
||||
redisPermSet.addAll(permUrlSet);
|
||||
redisPermSet.expire(appConfig.getSessionExpiredSeconds(), TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
private void putUserSysPermCodeCache(String sessionId, Collection<String> permCodeSet) {
|
||||
if (CollUtil.isEmpty(permCodeSet)) {
|
||||
return;
|
||||
}
|
||||
String sessionPermCodeKey = RedisKeyUtil.makeSessionPermCodeKey(sessionId);
|
||||
RSet<String> redisPermSet = redissonClient.getSet(sessionPermCodeKey);
|
||||
redisPermSet.addAll(permCodeSet);
|
||||
redisPermSet.expire(appConfig.getSessionExpiredSeconds(), TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
private OnlinePermData getOnlineMenuPermData(Collection<SysMenu> allMenuList) {
|
||||
List<SysMenu> onlineMenuList = allMenuList.stream()
|
||||
.filter(m -> m.getOnlineFormId() != null && m.getMenuType().equals(SysMenuType.TYPE_BUTTON))
|
||||
.collect(Collectors.toList());
|
||||
if (CollUtil.isEmpty(onlineMenuList)) {
|
||||
return new OnlinePermData();
|
||||
}
|
||||
Set<Long> formIds = allMenuList.stream()
|
||||
.filter(m -> m.getOnlineFormId() != null
|
||||
&& m.getOnlineFlowEntryId() == null
|
||||
&& m.getMenuType().equals(SysMenuType.TYPE_MENU))
|
||||
.map(SysMenu::getOnlineFormId)
|
||||
.collect(Collectors.toSet());
|
||||
Set<Long> viewFormIds = onlineMenuList.stream()
|
||||
.filter(m -> m.getOnlineMenuPermType() == SysOnlineMenuPermType.TYPE_VIEW)
|
||||
.map(SysMenu::getOnlineFormId)
|
||||
.collect(Collectors.toSet());
|
||||
Set<Long> editFormIds = onlineMenuList.stream()
|
||||
.filter(m -> m.getOnlineMenuPermType() == SysOnlineMenuPermType.TYPE_EDIT)
|
||||
.map(SysMenu::getOnlineFormId)
|
||||
.collect(Collectors.toSet());
|
||||
Map<String, Object> permDataMap =
|
||||
onlineOperationService.calculatePermData(formIds, viewFormIds, editFormIds);
|
||||
OnlinePermData permData = BeanUtil.mapToBean(permDataMap, OnlinePermData.class, false, null);
|
||||
permData.permUrlSet.addAll(permData.onlineWhitelistUrls);
|
||||
return permData;
|
||||
}
|
||||
|
||||
private OnlinePermData getFlowOnlineMenuPermData(Collection<SysMenu> allMenuList) {
|
||||
List<SysMenu> flowOnlineMenuList = allMenuList.stream()
|
||||
.filter(m -> m.getOnlineFlowEntryId() != null).collect(Collectors.toList());
|
||||
Set<Long> entryIds = flowOnlineMenuList.stream()
|
||||
.map(SysMenu::getOnlineFlowEntryId).collect(Collectors.toSet());
|
||||
List<Map<String, Object>> flowPermDataList = flowOnlineOperationService.calculatePermData(entryIds);
|
||||
List<OnlineFlowPermData> flowOnlinePermDataList =
|
||||
MyModelUtil.mapToBeanList(flowPermDataList, OnlineFlowPermData.class);
|
||||
OnlinePermData permData = new OnlinePermData();
|
||||
flowOnlinePermDataList.forEach(perm -> {
|
||||
permData.permCodeSet.addAll(perm.getPermCodeList());
|
||||
permData.permUrlSet.addAll(perm.getPermList());
|
||||
});
|
||||
return permData;
|
||||
}
|
||||
|
||||
static class OnlinePermData {
|
||||
public final Set<String> permCodeSet = new HashSet<>();
|
||||
public final Set<String> permUrlSet = new HashSet<>();
|
||||
public final List<String> onlineWhitelistUrls = new LinkedList<>();
|
||||
}
|
||||
|
||||
@Data
|
||||
static class OnlineFlowPermData {
|
||||
private List<String> permCodeList;
|
||||
private List<String> permList;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
package com.orangeforms.webadmin.upms.controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.orangeforms.common.core.annotation.MyRequestBody;
|
||||
import com.orangeforms.common.core.object.*;
|
||||
import com.orangeforms.common.core.util.RedisKeyUtil;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.redisson.api.RBucket;
|
||||
import org.redisson.api.RedissonClient;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 在线用户控制器对象。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
@Tag(name = "在线用户接口")
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/admin/upms/loginUser")
|
||||
public class LoginUserController {
|
||||
|
||||
@Autowired
|
||||
private RedissonClient redissonClient;
|
||||
|
||||
/**
|
||||
* 显示在线用户列表。
|
||||
*
|
||||
* @param loginName 登录名过滤。
|
||||
* @param pageParam 分页参数。
|
||||
* @return 登录用户信息列表。
|
||||
*/
|
||||
@SaCheckPermission("loginUser.view")
|
||||
@PostMapping("/list")
|
||||
public ResponseResult<MyPageData<LoginUserInfo>> list(
|
||||
@MyRequestBody String loginName, @MyRequestBody MyPageParam pageParam) {
|
||||
int skipCount = (pageParam.getPageNum() - 1) * pageParam.getPageSize();
|
||||
String patternKey;
|
||||
if (StrUtil.isBlank(loginName)) {
|
||||
patternKey = RedisKeyUtil.getSessionIdPrefix() + "*";
|
||||
} else {
|
||||
patternKey = RedisKeyUtil.getSessionIdPrefix(loginName) + "*";
|
||||
}
|
||||
List<LoginUserInfo> loginUserInfoList = new LinkedList<>();
|
||||
Iterable<String> keys = redissonClient.getKeys().getKeysByPattern(patternKey);
|
||||
for (String key : keys) {
|
||||
loginUserInfoList.add(this.buildTokenDataByRedisKey(key));
|
||||
}
|
||||
loginUserInfoList.sort((o1, o2) -> (int) (o2.getLoginTime().getTime() - o1.getLoginTime().getTime()));
|
||||
int toIndex = Math.min(skipCount + pageParam.getPageSize(), loginUserInfoList.size());
|
||||
List<LoginUserInfo> resultList = loginUserInfoList.subList(skipCount, toIndex);
|
||||
return ResponseResult.success(new MyPageData<>(resultList, (long) loginUserInfoList.size()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 强制下线指定登录会话。
|
||||
*
|
||||
* @param sessionId 待强制下线的SessionId。
|
||||
* @return 应答结果对象。
|
||||
*/
|
||||
@SaCheckPermission("loginUser.delete")
|
||||
@PostMapping("/delete")
|
||||
public ResponseResult<Void> delete(@MyRequestBody String sessionId) {
|
||||
RBucket<String> sessionData = redissonClient.getBucket(sessionId);
|
||||
TokenData tokenData = JSON.parseObject(sessionData.get(), TokenData.class);
|
||||
StpUtil.kickoutByTokenValue(tokenData.getToken());
|
||||
sessionData.delete();
|
||||
return ResponseResult.success();
|
||||
}
|
||||
|
||||
private LoginUserInfo buildTokenDataByRedisKey(String key) {
|
||||
RBucket<String> sessionData = redissonClient.getBucket(key);
|
||||
TokenData tokenData = JSON.parseObject(sessionData.get(), TokenData.class);
|
||||
LoginUserInfo userInfo = BeanUtil.copyProperties(tokenData, LoginUserInfo.class);
|
||||
userInfo.setSessionId(tokenData.getMySessionId());
|
||||
return userInfo;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,337 @@
|
||||
package com.orangeforms.webadmin.upms.controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import com.alibaba.fastjson.TypeReference;
|
||||
import com.github.pagehelper.Page;
|
||||
import com.github.pagehelper.page.PageMethod;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import com.orangeforms.webadmin.upms.dto.SysDataPermDto;
|
||||
import com.orangeforms.webadmin.upms.dto.SysUserDto;
|
||||
import com.orangeforms.webadmin.upms.vo.SysDataPermVo;
|
||||
import com.orangeforms.webadmin.upms.vo.SysUserVo;
|
||||
import com.orangeforms.webadmin.upms.model.SysDataPerm;
|
||||
import com.orangeforms.webadmin.upms.model.SysUser;
|
||||
import com.orangeforms.webadmin.upms.service.SysDataPermService;
|
||||
import com.orangeforms.webadmin.upms.service.SysUserService;
|
||||
import com.orangeforms.common.core.validator.UpdateGroup;
|
||||
import com.orangeforms.common.core.constant.ErrorCodeEnum;
|
||||
import com.orangeforms.common.core.object.*;
|
||||
import com.orangeforms.common.core.util.*;
|
||||
import com.orangeforms.common.core.annotation.MyRequestBody;
|
||||
import com.orangeforms.common.log.annotation.OperationLog;
|
||||
import com.orangeforms.common.log.model.constant.SysOperationLogType;
|
||||
import org.springdoc.core.annotations.ParameterObject;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import jakarta.validation.groups.Default;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 数据权限接口控制器对象。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
@Tag(name = "数据权限管理接口")
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/admin/upms/sysDataPerm")
|
||||
public class SysDataPermController {
|
||||
|
||||
@Autowired
|
||||
private SysDataPermService sysDataPermService;
|
||||
@Autowired
|
||||
private SysUserService sysUserService;
|
||||
|
||||
/**
|
||||
* 添加新数据权限操作。
|
||||
*
|
||||
* @param sysDataPermDto 新增对象。
|
||||
* @param deptIdListString 数据权限关联的部门Id列表,多个之间逗号分隔。
|
||||
* @param menuIdListString 数据权限关联的菜单Id列表,多个之间逗号分隔。
|
||||
* @return 应答结果对象。包含新增数据权限对象的主键Id。
|
||||
*/
|
||||
@ApiOperationSupport(ignoreParameters = {
|
||||
"sysDataPermDto.dataPermId",
|
||||
"sysDataPermDto.createTimeStart",
|
||||
"sysDataPermDto.createTimeEnd",
|
||||
"sysDataPermDto.searchString"})
|
||||
@SaCheckPermission("sysDataPerm.add")
|
||||
@OperationLog(type = SysOperationLogType.ADD)
|
||||
@PostMapping("/add")
|
||||
public ResponseResult<Long> add(
|
||||
@MyRequestBody SysDataPermDto sysDataPermDto,
|
||||
@MyRequestBody String deptIdListString,
|
||||
@MyRequestBody String menuIdListString) {
|
||||
String errorMessage = MyCommonUtil.getModelValidationError(sysDataPermDto);
|
||||
if (errorMessage != null) {
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
|
||||
}
|
||||
SysDataPerm sysDataPerm = MyModelUtil.copyTo(sysDataPermDto, SysDataPerm.class);
|
||||
CallResult result = sysDataPermService.verifyRelatedData(sysDataPerm, deptIdListString, menuIdListString);
|
||||
if (!result.isSuccess()) {
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, result.getErrorMessage());
|
||||
}
|
||||
Set<Long> menuIdSet = null;
|
||||
if (result.getData() != null) {
|
||||
menuIdSet = result.getData().getObject("menuIdSet", new TypeReference<Set<Long>>(){});
|
||||
}
|
||||
Set<Long> deptIdSet = null;
|
||||
if (result.getData() != null) {
|
||||
deptIdSet = result.getData().getObject("deptIdSet", new TypeReference<Set<Long>>(){});
|
||||
}
|
||||
sysDataPermService.saveNew(sysDataPerm, deptIdSet, menuIdSet);
|
||||
return ResponseResult.success(sysDataPerm.getDataPermId());
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新数据权限操作。
|
||||
*
|
||||
* @param sysDataPermDto 更新的数据权限对象。
|
||||
* @param deptIdListString 数据权限关联的部门Id列表,多个之间逗号分隔。
|
||||
* @param menuIdListString 数据权限关联的菜单Id列表,多个之间逗号分隔。
|
||||
* @return 应答结果对象。
|
||||
*/
|
||||
@ApiOperationSupport(ignoreParameters = {
|
||||
"sysDataPermDto.createTimeStart",
|
||||
"sysDataPermDto.createTimeEnd",
|
||||
"sysDataPermDto.searchString"})
|
||||
@SaCheckPermission("sysDataPerm.update")
|
||||
@OperationLog(type = SysOperationLogType.UPDATE)
|
||||
@PostMapping("/update")
|
||||
public ResponseResult<Void> update(
|
||||
@MyRequestBody SysDataPermDto sysDataPermDto,
|
||||
@MyRequestBody String deptIdListString,
|
||||
@MyRequestBody String menuIdListString) {
|
||||
String errorMessage = MyCommonUtil.getModelValidationError(sysDataPermDto, Default.class, UpdateGroup.class);
|
||||
if (errorMessage != null) {
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
|
||||
}
|
||||
SysDataPerm originalSysDataPerm = sysDataPermService.getById(sysDataPermDto.getDataPermId());
|
||||
if (originalSysDataPerm == null) {
|
||||
errorMessage = "数据验证失败,当前数据权限并不存在,请刷新后重试!";
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
|
||||
}
|
||||
SysDataPerm sysDataPerm = MyModelUtil.copyTo(sysDataPermDto, SysDataPerm.class);
|
||||
CallResult result = sysDataPermService.verifyRelatedData(sysDataPerm, deptIdListString, menuIdListString);
|
||||
if (!result.isSuccess()) {
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, result.getErrorMessage());
|
||||
}
|
||||
Set<Long> deptIdSet = null;
|
||||
if (result.getData() != null) {
|
||||
deptIdSet = result.getData().getObject("deptIdSet", new TypeReference<Set<Long>>(){});
|
||||
}
|
||||
Set<Long> menuIdSet = null;
|
||||
if (result.getData() != null) {
|
||||
menuIdSet = result.getData().getObject("menuIdSet", new TypeReference<Set<Long>>(){});
|
||||
}
|
||||
if (!sysDataPermService.update(sysDataPerm, originalSysDataPerm, deptIdSet, menuIdSet)) {
|
||||
errorMessage = "更新失败,数据不存在,请刷新后重试!";
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
|
||||
}
|
||||
return ResponseResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除数据权限操作。
|
||||
*
|
||||
* @param dataPermId 待删除数据权限主键Id。
|
||||
* @return 应答数据结果。
|
||||
*/
|
||||
@SaCheckPermission("sysDataPerm.delete")
|
||||
@OperationLog(type = SysOperationLogType.DELETE)
|
||||
@PostMapping("/delete")
|
||||
public ResponseResult<Void> delete(@MyRequestBody Long dataPermId) {
|
||||
if (MyCommonUtil.existBlankArgument(dataPermId)) {
|
||||
return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
|
||||
}
|
||||
if (!sysDataPermService.remove(dataPermId)) {
|
||||
String errorMessage = "数据操作失败,数据权限不存在,请刷新后重试!";
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
|
||||
}
|
||||
return ResponseResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看数据权限列表。
|
||||
*
|
||||
* @param sysDataPermDtoFilter 数据权限查询过滤对象。
|
||||
* @param orderParam 排序参数。
|
||||
* @param pageParam 分页参数。
|
||||
* @return 应答结果对象。包含数据权限列表。
|
||||
*/
|
||||
@SaCheckPermission("sysDataPerm.view")
|
||||
@PostMapping("/list")
|
||||
public ResponseResult<MyPageData<SysDataPermVo>> list(
|
||||
@MyRequestBody SysDataPermDto sysDataPermDtoFilter,
|
||||
@MyRequestBody MyOrderParam orderParam,
|
||||
@MyRequestBody MyPageParam pageParam) {
|
||||
if (pageParam != null) {
|
||||
PageMethod.startPage(pageParam.getPageNum(), pageParam.getPageSize());
|
||||
}
|
||||
SysDataPerm filter = MyModelUtil.copyTo(sysDataPermDtoFilter, SysDataPerm.class);
|
||||
String orderBy = MyOrderParam.buildOrderBy(orderParam, SysDataPerm.class);
|
||||
List<SysDataPerm> dataPermList = sysDataPermService.getSysDataPermListWithRelation(filter, orderBy);
|
||||
List<SysDataPermVo> dataPermVoList = MyModelUtil.copyCollectionTo(dataPermList, SysDataPermVo.class);
|
||||
long totalCount = 0L;
|
||||
if (dataPermList instanceof Page) {
|
||||
totalCount = ((Page<SysDataPerm>) dataPermList).getTotal();
|
||||
}
|
||||
return ResponseResult.success(MyPageUtil.makeResponseData(dataPermVoList, totalCount));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看单条数据权限详情。
|
||||
*
|
||||
* @param dataPermId 数据权限的主键Id。
|
||||
* @return 应答结果对象,包含数据权限的详情。
|
||||
*/
|
||||
@SaCheckPermission("sysDataPerm.view")
|
||||
@GetMapping("/view")
|
||||
public ResponseResult<SysDataPermVo> view(@RequestParam Long dataPermId) {
|
||||
if (MyCommonUtil.existBlankArgument(dataPermId)) {
|
||||
return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
|
||||
}
|
||||
SysDataPerm dataPerm = sysDataPermService.getByIdWithRelation(dataPermId, MyRelationParam.full());
|
||||
if (dataPerm == null) {
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
|
||||
}
|
||||
SysDataPermVo dataPermVo = MyModelUtil.copyTo(dataPerm, SysDataPermVo.class);
|
||||
return ResponseResult.success(dataPermVo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 拥有指定数据权限的用户列表。
|
||||
*
|
||||
* @param dataPermId 数据权限Id。
|
||||
* @param sysUserDtoFilter 用户过滤对象。
|
||||
* @param orderParam 排序参数。
|
||||
* @param pageParam 分页参数。
|
||||
* @return 应答结果对象,包含用户列表数据。
|
||||
*/
|
||||
@SaCheckPermission("sysDataPerm.view")
|
||||
@PostMapping("/listDataPermUser")
|
||||
public ResponseResult<MyPageData<SysUserVo>> listDataPermUser(
|
||||
@MyRequestBody Long dataPermId,
|
||||
@MyRequestBody SysUserDto sysUserDtoFilter,
|
||||
@MyRequestBody MyOrderParam orderParam,
|
||||
@MyRequestBody MyPageParam pageParam) {
|
||||
ResponseResult<Void> verifyResult = this.doDataPermUserVerify(dataPermId);
|
||||
if (!verifyResult.isSuccess()) {
|
||||
return ResponseResult.errorFrom(verifyResult);
|
||||
}
|
||||
if (pageParam != null) {
|
||||
PageMethod.startPage(pageParam.getPageNum(), pageParam.getPageSize());
|
||||
}
|
||||
SysUser filter = MyModelUtil.copyTo(sysUserDtoFilter, SysUser.class);
|
||||
String orderBy = MyOrderParam.buildOrderBy(orderParam, SysUser.class);
|
||||
List<SysUser> userList = sysUserService.getSysUserListByDataPermId(dataPermId, filter, orderBy);
|
||||
return ResponseResult.success(MyPageUtil.makeResponseData(userList, SysUserVo.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取不包含指定数据权限Id的用户列表。
|
||||
* 用户和数据权限是多对多关系,当前接口将返回没有赋值指定DataPermId的用户列表。可用于给数据权限添加新用户。
|
||||
*
|
||||
* @param dataPermId 数据权限主键Id。
|
||||
* @param sysUserDtoFilter 用户数据的过滤对象。
|
||||
* @param orderParam 排序参数。
|
||||
* @param pageParam 分页参数。
|
||||
* @return 应答结果对象,包含用户列表数据。
|
||||
*/
|
||||
@SaCheckPermission("sysDataPerm.update")
|
||||
@PostMapping("/listNotInDataPermUser")
|
||||
public ResponseResult<MyPageData<SysUserVo>> listNotInDataPermUser(
|
||||
@MyRequestBody Long dataPermId,
|
||||
@MyRequestBody SysUserDto sysUserDtoFilter,
|
||||
@MyRequestBody MyOrderParam orderParam,
|
||||
@MyRequestBody MyPageParam pageParam) {
|
||||
ResponseResult<Void> verifyResult = this.doDataPermUserVerify(dataPermId);
|
||||
if (!verifyResult.isSuccess()) {
|
||||
return ResponseResult.errorFrom(verifyResult);
|
||||
}
|
||||
if (pageParam != null) {
|
||||
PageMethod.startPage(pageParam.getPageNum(), pageParam.getPageSize());
|
||||
}
|
||||
SysUser filter = MyModelUtil.copyTo(sysUserDtoFilter, SysUser.class);
|
||||
String orderBy = MyOrderParam.buildOrderBy(orderParam, SysUser.class);
|
||||
List<SysUser> userList =
|
||||
sysUserService.getNotInSysUserListByDataPermId(dataPermId, filter, orderBy);
|
||||
return ResponseResult.success(MyPageUtil.makeResponseData(userList, SysUserVo.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* 为指定数据权限添加用户列表。该操作可同时给一批用户赋值数据权限,并在同一事务内完成。
|
||||
*
|
||||
* @param dataPermId 数据权限主键Id。
|
||||
* @param userIdListString 逗号分隔的用户Id列表。
|
||||
* @return 应答结果对象。
|
||||
*/
|
||||
@SaCheckPermission("sysDataPerm.update")
|
||||
@OperationLog(type = SysOperationLogType.ADD_M2M)
|
||||
@PostMapping("/addDataPermUser")
|
||||
public ResponseResult<Void> addDataPermUser(
|
||||
@MyRequestBody Long dataPermId, @MyRequestBody String userIdListString) {
|
||||
if (MyCommonUtil.existBlankArgument(dataPermId, userIdListString)) {
|
||||
return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
|
||||
}
|
||||
Set<Long> userIdSet =
|
||||
Arrays.stream(userIdListString.split(",")).map(Long::valueOf).collect(Collectors.toSet());
|
||||
if (!sysDataPermService.existId(dataPermId)
|
||||
|| !sysUserService.existUniqueKeyList("userId", userIdSet)) {
|
||||
return ResponseResult.error(ErrorCodeEnum.INVALID_RELATED_RECORD_ID);
|
||||
}
|
||||
sysDataPermService.addDataPermUserList(dataPermId, userIdSet);
|
||||
return ResponseResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 为指定用户移除指定数据权限。
|
||||
*
|
||||
* @param dataPermId 指定数据权限主键Id。
|
||||
* @param userId 指定用户主键Id。
|
||||
* @return 应答数据结果。
|
||||
*/
|
||||
@SaCheckPermission("sysDataPerm.update")
|
||||
@OperationLog(type = SysOperationLogType.DELETE_M2M)
|
||||
@PostMapping("/deleteDataPermUser")
|
||||
public ResponseResult<Void> deleteDataPermUser(
|
||||
@MyRequestBody Long dataPermId, @MyRequestBody Long userId) {
|
||||
if (MyCommonUtil.existBlankArgument(dataPermId, userId)) {
|
||||
return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
|
||||
}
|
||||
if (!sysDataPermService.removeDataPermUser(dataPermId, userId)) {
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
|
||||
}
|
||||
return ResponseResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 以字典形式返回全部数据权限管理数据集合。字典的键值为[dataPermId, dataPermName]。
|
||||
* 白名单接口,登录用户均可访问。
|
||||
*
|
||||
* @param filter 过滤对象。
|
||||
* @return 应答结果对象,包含的数据为 List<Map<String, String>>,map中包含两条记录,key的值分别是id和name,value对应具体数据。
|
||||
*/
|
||||
@GetMapping("/listDict")
|
||||
public ResponseResult<List<Map<String, Object>>> listDict(@ParameterObject SysDataPermDto filter) {
|
||||
List<SysDataPerm> resultList =
|
||||
sysDataPermService.getListByFilter(MyModelUtil.copyTo(filter, SysDataPerm.class));
|
||||
return ResponseResult.success(
|
||||
MyCommonUtil.toDictDataList(resultList, SysDataPerm::getDataPermId, SysDataPerm::getDataPermName));
|
||||
}
|
||||
|
||||
private ResponseResult<Void> doDataPermUserVerify(Long dataPermId) {
|
||||
if (MyCommonUtil.existBlankArgument(dataPermId)) {
|
||||
return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
|
||||
}
|
||||
if (!sysDataPermService.existId(dataPermId)) {
|
||||
return ResponseResult.error(ErrorCodeEnum.INVALID_RELATED_RECORD_ID);
|
||||
}
|
||||
return ResponseResult.success();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,428 @@
|
||||
package com.orangeforms.webadmin.upms.controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.orangeforms.common.log.annotation.OperationLog;
|
||||
import com.orangeforms.common.log.model.constant.SysOperationLogType;
|
||||
import com.github.pagehelper.page.PageMethod;
|
||||
import com.orangeforms.webadmin.upms.vo.*;
|
||||
import com.orangeforms.webadmin.upms.dto.*;
|
||||
import com.orangeforms.webadmin.upms.model.*;
|
||||
import com.orangeforms.webadmin.upms.service.*;
|
||||
import com.orangeforms.common.core.object.*;
|
||||
import com.orangeforms.common.core.util.*;
|
||||
import com.orangeforms.common.core.constant.*;
|
||||
import com.orangeforms.common.core.annotation.MyRequestBody;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springdoc.core.annotations.ParameterObject;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 部门管理操作控制器类。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
@Tag(name = "部门管理管理接口")
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/admin/upms/sysDept")
|
||||
public class SysDeptController {
|
||||
|
||||
@Autowired
|
||||
private SysPostService sysPostService;
|
||||
@Autowired
|
||||
private SysDeptService sysDeptService;
|
||||
|
||||
/**
|
||||
* 新增部门管理数据。
|
||||
*
|
||||
* @param sysDeptDto 新增对象。
|
||||
* @return 应答结果对象,包含新增对象主键Id。
|
||||
*/
|
||||
@ApiOperationSupport(ignoreParameters = {"sysDeptDto.deptId"})
|
||||
@SaCheckPermission("sysDept.add")
|
||||
@OperationLog(type = SysOperationLogType.ADD)
|
||||
@PostMapping("/add")
|
||||
public ResponseResult<Long> add(@MyRequestBody SysDeptDto sysDeptDto) {
|
||||
String errorMessage = MyCommonUtil.getModelValidationError(sysDeptDto, false);
|
||||
if (errorMessage != null) {
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
|
||||
}
|
||||
SysDept sysDept = MyModelUtil.copyTo(sysDeptDto, SysDept.class);
|
||||
// 验证父Id的数据合法性
|
||||
SysDept parentSysDept = null;
|
||||
if (MyCommonUtil.isNotBlankOrNull(sysDept.getParentId())) {
|
||||
parentSysDept = sysDeptService.getById(sysDept.getParentId());
|
||||
if (parentSysDept == null) {
|
||||
errorMessage = "数据验证失败,关联的父节点并不存在,请刷新后重试!";
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_PARENT_ID_NOT_EXIST, errorMessage);
|
||||
}
|
||||
}
|
||||
sysDept = sysDeptService.saveNew(sysDept, parentSysDept);
|
||||
return ResponseResult.success(sysDept.getDeptId());
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新部门管理数据。
|
||||
*
|
||||
* @param sysDeptDto 更新对象。
|
||||
* @return 应答结果对象。
|
||||
*/
|
||||
@SaCheckPermission("sysDept.update")
|
||||
@OperationLog(type = SysOperationLogType.UPDATE)
|
||||
@PostMapping("/update")
|
||||
public ResponseResult<Void> update(@MyRequestBody SysDeptDto sysDeptDto) {
|
||||
String errorMessage = MyCommonUtil.getModelValidationError(sysDeptDto, true);
|
||||
if (errorMessage != null) {
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
|
||||
}
|
||||
SysDept sysDept = MyModelUtil.copyTo(sysDeptDto, SysDept.class);
|
||||
SysDept originalSysDept = sysDeptService.getById(sysDept.getDeptId());
|
||||
if (originalSysDept == null) {
|
||||
// NOTE: 修改下面方括号中的话述
|
||||
errorMessage = "数据验证失败,当前 [数据] 并不存在,请刷新后重试!";
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
|
||||
}
|
||||
// 验证父Id的数据合法性
|
||||
if (MyCommonUtil.isNotBlankOrNull(sysDept.getParentId())
|
||||
&& ObjectUtil.notEqual(sysDept.getParentId(), originalSysDept.getParentId())) {
|
||||
SysDept parentSysDept = sysDeptService.getById(sysDept.getParentId());
|
||||
if (parentSysDept == null) {
|
||||
// NOTE: 修改下面方括号中的话述
|
||||
errorMessage = "数据验证失败,关联的 [父节点] 并不存在,请刷新后重试!";
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_PARENT_ID_NOT_EXIST, errorMessage);
|
||||
}
|
||||
}
|
||||
if (!sysDeptService.update(sysDept, originalSysDept)) {
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
|
||||
}
|
||||
return ResponseResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除部门管理数据。
|
||||
*
|
||||
* @param deptId 删除对象主键Id。
|
||||
* @return 应答结果对象。
|
||||
*/
|
||||
@SaCheckPermission("sysDept.delete")
|
||||
@OperationLog(type = SysOperationLogType.DELETE)
|
||||
@PostMapping("/delete")
|
||||
public ResponseResult<Void> delete(@MyRequestBody Long deptId) {
|
||||
if (MyCommonUtil.existBlankArgument(deptId)) {
|
||||
return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
|
||||
}
|
||||
return this.doDelete(deptId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除部门管理数据。
|
||||
*
|
||||
* @param deptIdList 待删除对象的主键Id列表。
|
||||
* @return 应答结果对象。
|
||||
*/
|
||||
@SaCheckPermission("sysDept.delete")
|
||||
@OperationLog(type = SysOperationLogType.DELETE_BATCH)
|
||||
@PostMapping("/deleteBatch")
|
||||
public ResponseResult<Void> deleteBatch(@MyRequestBody List<Long> deptIdList) {
|
||||
if (MyCommonUtil.existBlankArgument(deptIdList)) {
|
||||
return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
|
||||
}
|
||||
for (Long deptId : deptIdList) {
|
||||
ResponseResult<Void> responseResult = this.doDelete(deptId);
|
||||
if (!responseResult.isSuccess()) {
|
||||
return responseResult;
|
||||
}
|
||||
}
|
||||
return ResponseResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 列出符合过滤条件的部门管理列表。
|
||||
*
|
||||
* @param sysDeptDtoFilter 过滤对象。
|
||||
* @param orderParam 排序参数。
|
||||
* @param pageParam 分页参数。
|
||||
* @return 应答结果对象,包含查询结果集。
|
||||
*/
|
||||
@SaCheckPermission("sysDept.view")
|
||||
@PostMapping("/list")
|
||||
public ResponseResult<MyPageData<SysDeptVo>> list(
|
||||
@MyRequestBody SysDeptDto sysDeptDtoFilter,
|
||||
@MyRequestBody MyOrderParam orderParam,
|
||||
@MyRequestBody MyPageParam pageParam) {
|
||||
if (pageParam != null) {
|
||||
PageMethod.startPage(pageParam.getPageNum(), pageParam.getPageSize(), pageParam.getCount());
|
||||
}
|
||||
SysDept sysDeptFilter = MyModelUtil.copyTo(sysDeptDtoFilter, SysDept.class);
|
||||
String orderBy = MyOrderParam.buildOrderBy(orderParam, SysDept.class);
|
||||
List<SysDept> sysDeptList = sysDeptService.getSysDeptListWithRelation(sysDeptFilter, orderBy);
|
||||
return ResponseResult.success(MyPageUtil.makeResponseData(sysDeptList, SysDeptVo.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看指定部门管理对象详情。
|
||||
*
|
||||
* @param deptId 指定对象主键Id。
|
||||
* @return 应答结果对象,包含对象详情。
|
||||
*/
|
||||
@SaCheckPermission("sysDept.view")
|
||||
@GetMapping("/view")
|
||||
public ResponseResult<SysDeptVo> view(@RequestParam Long deptId) {
|
||||
SysDept sysDept = sysDeptService.getByIdWithRelation(deptId, MyRelationParam.full());
|
||||
if (sysDept == null) {
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
|
||||
}
|
||||
SysDeptVo sysDeptVo = MyModelUtil.copyTo(sysDept, SysDeptVo.class);
|
||||
return ResponseResult.success(sysDeptVo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 列出不与指定部门管理存在多对多关系的 [岗位管理] 列表数据。通常用于查看添加新 [岗位管理] 对象的候选列表。
|
||||
*
|
||||
* @param deptId 主表关联字段。
|
||||
* @param sysPostDtoFilter [岗位管理] 过滤对象。
|
||||
* @param orderParam 排序参数。
|
||||
* @param pageParam 分页参数。
|
||||
* @return 应答结果对象,返回符合条件的数据列表。
|
||||
*/
|
||||
@SaCheckPermission("sysDept.update")
|
||||
@PostMapping("/listNotInSysDeptPost")
|
||||
public ResponseResult<MyPageData<SysPostVo>> listNotInSysDeptPost(
|
||||
@MyRequestBody Long deptId,
|
||||
@MyRequestBody SysPostDto sysPostDtoFilter,
|
||||
@MyRequestBody MyOrderParam orderParam,
|
||||
@MyRequestBody MyPageParam pageParam) {
|
||||
if (MyCommonUtil.isNotBlankOrNull(deptId) && !sysDeptService.existId(deptId)) {
|
||||
return ResponseResult.error(ErrorCodeEnum.INVALID_RELATED_RECORD_ID);
|
||||
}
|
||||
if (pageParam != null) {
|
||||
PageMethod.startPage(pageParam.getPageNum(), pageParam.getPageSize());
|
||||
}
|
||||
SysPost filter = MyModelUtil.copyTo(sysPostDtoFilter, SysPost.class);
|
||||
String orderBy = MyOrderParam.buildOrderBy(orderParam, SysPost.class);
|
||||
List<SysPost> sysPostList;
|
||||
if (MyCommonUtil.isNotBlankOrNull(deptId)) {
|
||||
sysPostList = sysPostService.getNotInSysPostListByDeptId(deptId, filter, orderBy);
|
||||
} else {
|
||||
sysPostList = sysPostService.getSysPostList(filter, orderBy);
|
||||
sysPostService.buildRelationForDataList(sysPostList, MyRelationParam.dictOnly());
|
||||
}
|
||||
return ResponseResult.success(MyPageUtil.makeResponseData(sysPostList, SysPostVo.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* 列出与指定部门管理存在多对多关系的 [岗位管理] 列表数据。
|
||||
*
|
||||
* @param deptId 主表关联字段。
|
||||
* @param sysPostDtoFilter [岗位管理] 过滤对象。
|
||||
* @param orderParam 排序参数。
|
||||
* @param pageParam 分页参数。
|
||||
* @return 应答结果对象,返回符合条件的数据列表。
|
||||
*/
|
||||
@SaCheckPermission("sysDept.view")
|
||||
@PostMapping("/listSysDeptPost")
|
||||
public ResponseResult<MyPageData<SysPostVo>> listSysDeptPost(
|
||||
@MyRequestBody(required = true) Long deptId,
|
||||
@MyRequestBody SysPostDto sysPostDtoFilter,
|
||||
@MyRequestBody MyOrderParam orderParam,
|
||||
@MyRequestBody MyPageParam pageParam) {
|
||||
if (!sysDeptService.existId(deptId)) {
|
||||
return ResponseResult.error(ErrorCodeEnum.INVALID_RELATED_RECORD_ID);
|
||||
}
|
||||
if (pageParam != null) {
|
||||
PageMethod.startPage(pageParam.getPageNum(), pageParam.getPageSize());
|
||||
}
|
||||
SysPost filter = MyModelUtil.copyTo(sysPostDtoFilter, SysPost.class);
|
||||
String orderBy = MyOrderParam.buildOrderBy(orderParam, SysPost.class);
|
||||
List<SysPost> sysPostList = sysPostService.getSysPostListByDeptId(deptId, filter, orderBy);
|
||||
return ResponseResult.success(MyPageUtil.makeResponseData(sysPostList, SysPostVo.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量添加部门管理和 [岗位管理] 对象的多对多关联关系数据。
|
||||
*
|
||||
* @param deptId 主表主键Id。
|
||||
* @param sysDeptPostDtoList 关联对象列表。
|
||||
* @return 应答结果对象。
|
||||
*/
|
||||
@SaCheckPermission("sysDept.update")
|
||||
@PostMapping("/addSysDeptPost")
|
||||
public ResponseResult<Void> addSysDeptPost(
|
||||
@MyRequestBody Long deptId,
|
||||
@MyRequestBody List<SysDeptPostDto> sysDeptPostDtoList) {
|
||||
if (MyCommonUtil.existBlankArgument(deptId, sysDeptPostDtoList)) {
|
||||
return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
|
||||
}
|
||||
String errorMessage = MyCommonUtil.getModelValidationError(sysDeptPostDtoList);
|
||||
if (errorMessage != null) {
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
|
||||
}
|
||||
Set<Long> postIdSet = sysDeptPostDtoList.stream().map(SysDeptPostDto::getPostId).collect(Collectors.toSet());
|
||||
if (!sysDeptService.existId(deptId) || !sysPostService.existUniqueKeyList("postId", postIdSet)) {
|
||||
return ResponseResult.error(ErrorCodeEnum.INVALID_RELATED_RECORD_ID);
|
||||
}
|
||||
List<SysDeptPost> sysDeptPostList = MyModelUtil.copyCollectionTo(sysDeptPostDtoList, SysDeptPost.class);
|
||||
sysDeptService.addSysDeptPostList(sysDeptPostList, deptId);
|
||||
return ResponseResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新指定部门管理和指定 [岗位管理] 的多对多关联数据。
|
||||
*
|
||||
* @param sysDeptPostDto 对多对中间表对象。
|
||||
* @return 应答结果对象。
|
||||
*/
|
||||
@SaCheckPermission("sysDept.update")
|
||||
@PostMapping("/updateSysDeptPost")
|
||||
public ResponseResult<Void> updateSysDeptPost(@MyRequestBody SysDeptPostDto sysDeptPostDto) {
|
||||
String errorMessage = MyCommonUtil.getModelValidationError(sysDeptPostDto);
|
||||
if (errorMessage != null) {
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
|
||||
}
|
||||
SysDeptPost sysDeptPost = MyModelUtil.copyTo(sysDeptPostDto, SysDeptPost.class);
|
||||
if (!sysDeptService.updateSysDeptPost(sysDeptPost)) {
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
|
||||
}
|
||||
return ResponseResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示部门管理和指定 [岗位管理] 的多对多关联详情数据。
|
||||
*
|
||||
* @param deptId 主表主键Id。
|
||||
* @param postId 从表主键Id。
|
||||
* @return 应答结果对象,包括中间表详情。
|
||||
*/
|
||||
@SaCheckPermission("sysDept.update")
|
||||
@GetMapping("/viewSysDeptPost")
|
||||
public ResponseResult<SysDeptPostVo> viewSysDeptPost(@RequestParam Long deptId, @RequestParam Long postId) {
|
||||
SysDeptPost sysDeptPost = sysDeptService.getSysDeptPost(deptId, postId);
|
||||
if (sysDeptPost == null) {
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
|
||||
}
|
||||
SysDeptPostVo sysDeptPostVo = MyModelUtil.copyTo(sysDeptPost, SysDeptPostVo.class);
|
||||
return ResponseResult.success(sysDeptPostVo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除指定部门管理和指定 [岗位管理] 的多对多关联关系。
|
||||
*
|
||||
* @param deptId 主表主键Id。
|
||||
* @param postId 从表主键Id。
|
||||
* @return 应答结果对象。
|
||||
*/
|
||||
@SaCheckPermission("sysDept.update")
|
||||
@PostMapping("/deleteSysDeptPost")
|
||||
public ResponseResult<Void> deleteSysDeptPost(@MyRequestBody Long deptId, @MyRequestBody Long postId) {
|
||||
if (MyCommonUtil.existBlankArgument(deptId, postId)) {
|
||||
return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
|
||||
}
|
||||
if (!sysDeptService.removeSysDeptPost(deptId, postId)) {
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
|
||||
}
|
||||
return ResponseResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取部门岗位多对多关联数据,及其关联的部门和岗位数据。
|
||||
*
|
||||
* @param deptId 部门Id,如果为空,返回全部数据列表。
|
||||
* @return 部门岗位多对多关联数据,及其关联的部门和岗位数据
|
||||
*/
|
||||
@GetMapping("/listSysDeptPostWithRelation")
|
||||
public ResponseResult<List<Map<String, Object>>> listSysDeptPostWithRelation(
|
||||
@RequestParam(required = false) Long deptId) {
|
||||
return ResponseResult.success(sysDeptService.getSysDeptPostListWithRelationByDeptId(deptId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 以字典形式返回全部部门管理数据集合。字典的键值为[deptId, deptName]。
|
||||
* 白名单接口,登录用户均可访问。
|
||||
*
|
||||
* @param filter 过滤对象。
|
||||
* @return 应答结果对象,包含的数据为 List<Map<String, String>>,map中包含两条记录,key的值分别是id和name,value对应具体数据。
|
||||
*/
|
||||
@GetMapping("/listDict")
|
||||
public ResponseResult<List<Map<String, Object>>> listDict(@ParameterObject SysDeptDto filter) {
|
||||
List<SysDept> resultList =
|
||||
sysDeptService.getListByFilter(MyModelUtil.copyTo(filter, SysDept.class));
|
||||
return ResponseResult.success(MyCommonUtil.toDictDataList(
|
||||
resultList, SysDept::getDeptId, SysDept::getDeptName, SysDept::getParentId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据字典Id集合,获取查询后的字典数据。
|
||||
*
|
||||
* @param dictIds 字典Id集合。
|
||||
* @return 应答结果对象,包含字典形式的数据集合。
|
||||
*/
|
||||
@GetMapping("/listDictByIds")
|
||||
public ResponseResult<List<Map<String, Object>>> listDictByIds(@RequestParam List<Long> dictIds) {
|
||||
List<SysDept> resultList = sysDeptService.getInList(new HashSet<>(dictIds));
|
||||
return ResponseResult.success(MyCommonUtil.toDictDataList(
|
||||
resultList, SysDept::getDeptId, SysDept::getDeptName, SysDept::getParentId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据父主键Id,以字典的形式返回其下级数据列表。
|
||||
* 白名单接口,登录用户均可访问。
|
||||
*
|
||||
* @param parentId 父主键Id。
|
||||
* @return 按照字典的形式返回下级数据列表。
|
||||
*/
|
||||
@GetMapping("/listDictByParentId")
|
||||
public ResponseResult<List<Map<String, Object>>> listDictByParentId(@RequestParam(required = false) Long parentId) {
|
||||
List<SysDept> resultList = sysDeptService.getListByParentId("parentId", parentId);
|
||||
return ResponseResult.success(MyCommonUtil.toDictDataList(
|
||||
resultList, SysDept::getDeptId, SysDept::getDeptName, SysDept::getParentId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据父主键Id列表,获取当前部门Id及其所有下级部门Id列表。
|
||||
* 白名单接口,登录用户均可访问。
|
||||
*
|
||||
* @param parentIds 父主键Id列表,多个Id之间逗号分隔。
|
||||
* @return 获取当前部门Id及其所有下级部门Id列表。
|
||||
*/
|
||||
@GetMapping("/listAllChildDeptIdByParentIds")
|
||||
public ResponseResult<List<Long>> listAllChildDeptIdByParentIds(
|
||||
@RequestParam(required = false) String parentIds) {
|
||||
List<Long> parentIdList = StrUtil.split(parentIds, ',')
|
||||
.stream().map(Long::valueOf).collect(Collectors.toList());
|
||||
return ResponseResult.success(sysDeptService.getAllChildDeptIdByParentIds(parentIdList));
|
||||
}
|
||||
|
||||
private ResponseResult<Void> doDelete(Long deptId) {
|
||||
String errorMessage;
|
||||
// 验证关联Id的数据合法性
|
||||
SysDept originalSysDept = sysDeptService.getById(deptId);
|
||||
if (originalSysDept == null) {
|
||||
// NOTE: 修改下面方括号中的话述
|
||||
errorMessage = "数据验证失败,当前 [对象] 并不存在,请刷新后重试!";
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
|
||||
}
|
||||
if (sysDeptService.hasChildren(deptId)) {
|
||||
// NOTE: 修改下面方括号中的话述
|
||||
errorMessage = "数据验证失败,当前 [对象存在子对象] ,请刷新后重试!";
|
||||
return ResponseResult.error(ErrorCodeEnum.HAS_CHILDREN_DATA, errorMessage);
|
||||
}
|
||||
if (sysDeptService.hasChildrenUser(deptId)) {
|
||||
errorMessage = "数据验证失败,请先移除部门用户数据后,再删除当前部门!";
|
||||
return ResponseResult.error(ErrorCodeEnum.HAS_CHILDREN_DATA, errorMessage);
|
||||
}
|
||||
if (!sysDeptService.remove(deptId)) {
|
||||
errorMessage = "数据操作失败,删除的对象不存在,请刷新后重试!";
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
|
||||
}
|
||||
return ResponseResult.success();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,231 @@
|
||||
package com.orangeforms.webadmin.upms.controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import com.orangeforms.webadmin.upms.dto.SysMenuDto;
|
||||
import com.orangeforms.webadmin.upms.vo.SysMenuVo;
|
||||
import com.orangeforms.webadmin.upms.model.SysMenu;
|
||||
import com.orangeforms.webadmin.upms.model.SysDataPerm;
|
||||
import com.orangeforms.webadmin.upms.model.constant.SysMenuType;
|
||||
import com.orangeforms.webadmin.upms.service.SysMenuService;
|
||||
import com.orangeforms.webadmin.upms.service.SysDataPermService;
|
||||
import com.orangeforms.common.core.constant.ErrorCodeEnum;
|
||||
import com.orangeforms.common.core.object.*;
|
||||
import com.orangeforms.common.core.util.*;
|
||||
import com.orangeforms.common.core.validator.UpdateGroup;
|
||||
import com.orangeforms.common.core.annotation.MyRequestBody;
|
||||
import com.orangeforms.common.log.annotation.OperationLog;
|
||||
import com.orangeforms.common.log.model.constant.SysOperationLogType;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import jakarta.validation.groups.Default;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 菜单管理接口控制器类。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
@Tag(name = "菜单管理接口")
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/admin/upms/sysMenu")
|
||||
public class SysMenuController {
|
||||
|
||||
@Autowired
|
||||
private SysMenuService sysMenuService;
|
||||
@Autowired
|
||||
private SysDataPermService sysDataPermService;
|
||||
|
||||
/**
|
||||
* 添加新菜单操作。
|
||||
*
|
||||
* @param sysMenuDto 新菜单对象。
|
||||
* @return 应答结果对象,包含新增菜单的主键Id。
|
||||
*/
|
||||
@ApiOperationSupport(ignoreParameters = {"sysMenuDto.menuId"})
|
||||
@SaCheckPermission("sysMenu.add")
|
||||
@OperationLog(type = SysOperationLogType.ADD)
|
||||
@PostMapping("/add")
|
||||
public ResponseResult<Long> add(@MyRequestBody SysMenuDto sysMenuDto) {
|
||||
String errorMessage = MyCommonUtil.getModelValidationError(sysMenuDto);
|
||||
if (errorMessage != null) {
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
|
||||
}
|
||||
SysMenu sysMenu = MyModelUtil.copyTo(sysMenuDto, SysMenu.class);
|
||||
if (sysMenu.getParentId() != null) {
|
||||
SysMenu parentSysMenu = sysMenuService.getById(sysMenu.getParentId());
|
||||
if (parentSysMenu == null) {
|
||||
errorMessage = "数据验证失败,关联的父菜单不存在!";
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
|
||||
}
|
||||
if (parentSysMenu.getOnlineFormId() != null) {
|
||||
errorMessage = "数据验证失败,不能为动态表单菜单添加子菜单!";
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
|
||||
}
|
||||
}
|
||||
CallResult result = sysMenuService.verifyRelatedData(sysMenu, null);
|
||||
if (!result.isSuccess()) {
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, result.getErrorMessage());
|
||||
}
|
||||
sysMenuService.saveNew(sysMenu);
|
||||
return ResponseResult.success(sysMenu.getMenuId());
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新菜单数据操作。
|
||||
*
|
||||
* @param sysMenuDto 新菜单对象。
|
||||
* @return 应答结果对象。
|
||||
*/
|
||||
@SaCheckPermission("sysMenu.update")
|
||||
@OperationLog(type = SysOperationLogType.UPDATE)
|
||||
@PostMapping("/update")
|
||||
public ResponseResult<Void> update(@MyRequestBody SysMenuDto sysMenuDto) {
|
||||
String errorMessage = MyCommonUtil.getModelValidationError(sysMenuDto, Default.class, UpdateGroup.class);
|
||||
if (errorMessage != null) {
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
|
||||
}
|
||||
SysMenu originalSysMenu = sysMenuService.getById(sysMenuDto.getMenuId());
|
||||
if (originalSysMenu == null) {
|
||||
errorMessage = "数据验证失败,当前菜单并不存在,请刷新后重试!";
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
|
||||
}
|
||||
SysMenu sysMenu = MyModelUtil.copyTo(sysMenuDto, SysMenu.class);
|
||||
if (ObjectUtil.notEqual(originalSysMenu.getOnlineFormId(), sysMenu.getOnlineFormId())) {
|
||||
if (originalSysMenu.getOnlineFormId() == null) {
|
||||
errorMessage = "数据验证失败,不能为当前菜单添加在线表单Id属性!";
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
|
||||
}
|
||||
if (sysMenu.getOnlineFormId() == null) {
|
||||
errorMessage = "数据验证失败,不能去掉当前菜单的在线表单Id属性!";
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
|
||||
}
|
||||
}
|
||||
if (originalSysMenu.getOnlineFormId() != null
|
||||
&& originalSysMenu.getMenuType().equals(SysMenuType.TYPE_BUTTON)) {
|
||||
errorMessage = "数据验证失败,在线表单的内置菜单不能编辑!";
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
|
||||
}
|
||||
CallResult result = sysMenuService.verifyRelatedData(sysMenu, originalSysMenu);
|
||||
if (!result.isSuccess()) {
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, result.getErrorMessage());
|
||||
}
|
||||
if (!sysMenuService.update(sysMenu, originalSysMenu)) {
|
||||
errorMessage = "数据验证失败,当前权限字并不存在,请刷新后重试!";
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
|
||||
}
|
||||
return ResponseResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除指定菜单操作。
|
||||
*
|
||||
* @param menuId 指定菜单主键Id。
|
||||
* @return 应答结果对象。
|
||||
*/
|
||||
@SaCheckPermission("sysMenu.delete")
|
||||
@OperationLog(type = SysOperationLogType.DELETE)
|
||||
@PostMapping("/delete")
|
||||
public ResponseResult<Void> delete(@MyRequestBody Long menuId) {
|
||||
if (MyCommonUtil.existBlankArgument(menuId)) {
|
||||
return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
|
||||
}
|
||||
String errorMessage;
|
||||
SysMenu menu = sysMenuService.getById(menuId);
|
||||
if (menu == null) {
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
|
||||
}
|
||||
if (menu.getOnlineFormId() != null && menu.getMenuType().equals(SysMenuType.TYPE_BUTTON)) {
|
||||
errorMessage = "数据验证失败,在线表单的内置菜单不能删除!";
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
|
||||
}
|
||||
// 对于在线表单,无需进行子菜单的验证,而是在删除的时候,连同子菜单一起删除。
|
||||
if (menu.getOnlineFormId() == null && sysMenuService.hasChildren(menuId)) {
|
||||
errorMessage = "数据验证失败,当前菜单存在下级菜单!";
|
||||
return ResponseResult.error(ErrorCodeEnum.HAS_CHILDREN_DATA, errorMessage);
|
||||
}
|
||||
List<SysDataPerm> dataPermList = sysDataPermService.getSysDataPermListByMenuId(menuId);
|
||||
if (CollUtil.isNotEmpty(dataPermList)) {
|
||||
SysDataPerm dataPerm = dataPermList.get(0);
|
||||
errorMessage = "数据验证失败,当前菜单正在被数据权限 [" + dataPerm.getDataPermName() + "] 引用,不能直接删除!";
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
|
||||
}
|
||||
if (!sysMenuService.remove(menu)) {
|
||||
errorMessage = "数据操作失败,菜单不存在,请刷新后重试!";
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
|
||||
}
|
||||
return ResponseResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取全部菜单列表。
|
||||
*
|
||||
* @return 应答结果对象,包含全部菜单数据列表。
|
||||
*/
|
||||
@SaCheckPermission("sysMenu.view")
|
||||
@PostMapping("/list")
|
||||
public ResponseResult<List<SysMenuVo>> list() {
|
||||
List<SysMenu> resultList = this.getAllMenuListByShowOrder();
|
||||
return ResponseResult.success(MyModelUtil.copyCollectionTo(resultList, SysMenuVo.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看指定菜单数据详情。
|
||||
*
|
||||
* @param menuId 指定菜单主键Id。
|
||||
* @return 应答结果对象,包含菜单详情。
|
||||
*/
|
||||
@SaCheckPermission("sysMenu.view")
|
||||
@GetMapping("/view")
|
||||
public ResponseResult<SysMenuVo> view(@RequestParam Long menuId) {
|
||||
if (MyCommonUtil.existBlankArgument(menuId)) {
|
||||
return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
|
||||
}
|
||||
SysMenu sysMenu = sysMenuService.getByIdWithRelation(menuId, MyRelationParam.full());
|
||||
if (sysMenu == null) {
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
|
||||
}
|
||||
SysMenuVo sysMenuVo = MyModelUtil.copyTo(sysMenu, SysMenuVo.class);
|
||||
return ResponseResult.success(sysMenuVo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 以字典形式返回目录和菜单类型的菜单管理数据集合。字典的键值为[menuId, menuName]。
|
||||
* 白名单接口,登录用户均可访问。
|
||||
*
|
||||
* @return 应答结果对象,包含的数据为 List<Map<String, String>>,map中包含两条记录,key的值分别是id和name,value对应具体数据。
|
||||
*/
|
||||
@GetMapping("/listMenuDict")
|
||||
public ResponseResult<List<Map<String, Object>>> listMenuDict() {
|
||||
List<SysMenu> resultList = this.getAllMenuListByShowOrder();
|
||||
resultList = resultList.stream()
|
||||
.filter(m -> m.getMenuType() <= SysMenuType.TYPE_MENU).collect(Collectors.toList());
|
||||
return ResponseResult.success(
|
||||
MyCommonUtil.toDictDataList(resultList, SysMenu::getMenuId, SysMenu::getMenuName, SysMenu::getParentId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 以字典形式返回全部的菜单管理数据集合。字典的键值为[menuId, menuName]。
|
||||
* 白名单接口,登录用户均可访问。
|
||||
*
|
||||
* @return 应答结果对象,包含的数据为 List<Map<String, String>>,map中包含两条记录,key的值分别是id和name,value对应具体数据。
|
||||
*/
|
||||
@GetMapping("/listDict")
|
||||
public ResponseResult<List<Map<String, Object>>> listDict() {
|
||||
List<SysMenu> resultList = this.getAllMenuListByShowOrder();
|
||||
return ResponseResult.success(
|
||||
MyCommonUtil.toDictDataList(resultList, SysMenu::getMenuId, SysMenu::getMenuName, SysMenu::getParentId));
|
||||
}
|
||||
|
||||
private List<SysMenu> getAllMenuListByShowOrder() {
|
||||
return sysMenuService.getAllListByOrder("showOrder");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package com.orangeforms.webadmin.upms.controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import com.github.pagehelper.Page;
|
||||
import com.github.pagehelper.page.PageMethod;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import com.orangeforms.common.core.annotation.MyRequestBody;
|
||||
import com.orangeforms.common.core.object.*;
|
||||
import com.orangeforms.common.core.util.MyModelUtil;
|
||||
import com.orangeforms.common.core.util.MyPageUtil;
|
||||
import com.orangeforms.common.log.model.SysOperationLog;
|
||||
import com.orangeforms.common.log.service.SysOperationLogService;
|
||||
import com.orangeforms.common.log.dto.SysOperationLogDto;
|
||||
import com.orangeforms.common.log.vo.SysOperationLogVo;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 操作日志接口控制器对象。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
@Tag(name = "操作日志接口")
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/admin/upms/sysOperationLog")
|
||||
public class SysOperationLogController {
|
||||
|
||||
@Autowired
|
||||
private SysOperationLogService operationLogService;
|
||||
|
||||
/**
|
||||
* 数据权限列表。
|
||||
*
|
||||
* @param sysOperationLogDtoFilter 操作日志查询过滤对象。
|
||||
* @param orderParam 排序参数。
|
||||
* @param pageParam 分页参数。
|
||||
* @return 应答结果对象。包含操作日志列表。
|
||||
*/
|
||||
@SaCheckPermission("sysOperationLog.view")
|
||||
@PostMapping("/list")
|
||||
public ResponseResult<MyPageData<SysOperationLogVo>> list(
|
||||
@MyRequestBody SysOperationLogDto sysOperationLogDtoFilter,
|
||||
@MyRequestBody MyOrderParam orderParam,
|
||||
@MyRequestBody MyPageParam pageParam) {
|
||||
if (pageParam != null) {
|
||||
PageMethod.startPage(pageParam.getPageNum(), pageParam.getPageSize());
|
||||
}
|
||||
SysOperationLog filter = MyModelUtil.copyTo(sysOperationLogDtoFilter, SysOperationLog.class);
|
||||
String orderBy = MyOrderParam.buildOrderBy(orderParam, SysOperationLog.class);
|
||||
List<SysOperationLog> operationLogList = operationLogService.getSysOperationLogList(filter, orderBy);
|
||||
List<SysOperationLogVo> operationLogVoList = MyModelUtil.copyCollectionTo(operationLogList, SysOperationLogVo.class);
|
||||
long totalCount = 0L;
|
||||
if (operationLogList instanceof Page) {
|
||||
totalCount = ((Page<SysOperationLog>) operationLogList).getTotal();
|
||||
}
|
||||
return ResponseResult.success(MyPageUtil.makeResponseData(operationLogVoList, totalCount));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,183 @@
|
||||
package com.orangeforms.webadmin.upms.controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import com.github.pagehelper.page.PageMethod;
|
||||
import com.orangeforms.common.core.object.*;
|
||||
import com.orangeforms.common.core.util.*;
|
||||
import com.orangeforms.common.core.constant.*;
|
||||
import com.orangeforms.common.core.annotation.MyRequestBody;
|
||||
import com.orangeforms.common.core.validator.UpdateGroup;
|
||||
import com.orangeforms.webadmin.upms.dto.SysPostDto;
|
||||
import com.orangeforms.webadmin.upms.model.SysPost;
|
||||
import com.orangeforms.webadmin.upms.service.SysPostService;
|
||||
import com.orangeforms.webadmin.upms.vo.SysPostVo;
|
||||
import com.orangeforms.common.log.annotation.OperationLog;
|
||||
import com.orangeforms.common.log.model.constant.SysOperationLogType;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springdoc.core.annotations.ParameterObject;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.*;
|
||||
import jakarta.validation.groups.Default;
|
||||
|
||||
/**
|
||||
* 岗位管理操作控制器类。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
@Tag(name = "岗位管理操作管理接口")
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/admin/upms/sysPost")
|
||||
public class SysPostController {
|
||||
|
||||
@Autowired
|
||||
private SysPostService sysPostService;
|
||||
|
||||
/**
|
||||
* 新增岗位管理数据。
|
||||
*
|
||||
* @param sysPostDto 新增对象。
|
||||
* @return 应答结果对象,包含新增对象主键Id。
|
||||
*/
|
||||
@ApiOperationSupport(ignoreParameters = {"sysPostDto.postId"})
|
||||
@SaCheckPermission("sysPost.add")
|
||||
@OperationLog(type = SysOperationLogType.ADD)
|
||||
@PostMapping("/add")
|
||||
public ResponseResult<Long> add(@MyRequestBody SysPostDto sysPostDto) {
|
||||
String errorMessage = MyCommonUtil.getModelValidationError(sysPostDto);
|
||||
if (errorMessage != null) {
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
|
||||
}
|
||||
SysPost sysPost = MyModelUtil.copyTo(sysPostDto, SysPost.class);
|
||||
sysPost = sysPostService.saveNew(sysPost);
|
||||
return ResponseResult.success(sysPost.getPostId());
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新岗位管理数据。
|
||||
*
|
||||
* @param sysPostDto 更新对象。
|
||||
* @return 应答结果对象。
|
||||
*/
|
||||
@SaCheckPermission("sysPost.update")
|
||||
@OperationLog(type = SysOperationLogType.UPDATE)
|
||||
@PostMapping("/update")
|
||||
public ResponseResult<Void> update(@MyRequestBody SysPostDto sysPostDto) {
|
||||
String errorMessage = MyCommonUtil.getModelValidationError(sysPostDto, Default.class, UpdateGroup.class);
|
||||
if (errorMessage != null) {
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
|
||||
}
|
||||
SysPost sysPost = MyModelUtil.copyTo(sysPostDto, SysPost.class);
|
||||
SysPost originalSysPost = sysPostService.getById(sysPost.getPostId());
|
||||
if (originalSysPost == null) {
|
||||
// NOTE: 修改下面方括号中的话述
|
||||
errorMessage = "数据验证失败,当前 [数据] 并不存在,请刷新后重试!";
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
|
||||
}
|
||||
if (!sysPostService.update(sysPost, originalSysPost)) {
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
|
||||
}
|
||||
return ResponseResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除岗位管理数据。
|
||||
*
|
||||
* @param postId 删除对象主键Id。
|
||||
* @return 应答结果对象。
|
||||
*/
|
||||
@SaCheckPermission("sysPost.delete")
|
||||
@OperationLog(type = SysOperationLogType.DELETE)
|
||||
@PostMapping("/delete")
|
||||
public ResponseResult<Void> delete(@MyRequestBody Long postId) {
|
||||
String errorMessage;
|
||||
if (MyCommonUtil.existBlankArgument(postId)) {
|
||||
return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
|
||||
}
|
||||
// 验证关联Id的数据合法性
|
||||
SysPost originalSysPost = sysPostService.getById(postId);
|
||||
if (originalSysPost == null) {
|
||||
// NOTE: 修改下面方括号中的话述
|
||||
errorMessage = "数据验证失败,当前 [对象] 并不存在,请刷新后重试!";
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
|
||||
}
|
||||
if (!sysPostService.remove(postId)) {
|
||||
errorMessage = "数据操作失败,删除的对象不存在,请刷新后重试!";
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
|
||||
}
|
||||
return ResponseResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 列出符合过滤条件的岗位管理列表。
|
||||
*
|
||||
* @param sysPostDtoFilter 过滤对象。
|
||||
* @param orderParam 排序参数。
|
||||
* @param pageParam 分页参数。
|
||||
* @return 应答结果对象,包含查询结果集。
|
||||
*/
|
||||
@SaCheckPermission("sysPost.view")
|
||||
@PostMapping("/list")
|
||||
public ResponseResult<MyPageData<SysPostVo>> list(
|
||||
@MyRequestBody SysPostDto sysPostDtoFilter,
|
||||
@MyRequestBody MyOrderParam orderParam,
|
||||
@MyRequestBody MyPageParam pageParam) {
|
||||
if (pageParam != null) {
|
||||
PageMethod.startPage(pageParam.getPageNum(), pageParam.getPageSize());
|
||||
}
|
||||
SysPost sysPostFilter = MyModelUtil.copyTo(sysPostDtoFilter, SysPost.class);
|
||||
String orderBy = MyOrderParam.buildOrderBy(orderParam, SysPost.class);
|
||||
List<SysPost> sysPostList = sysPostService.getSysPostListWithRelation(sysPostFilter, orderBy);
|
||||
return ResponseResult.success(MyPageUtil.makeResponseData(sysPostList, SysPostVo.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看指定岗位管理对象详情。
|
||||
*
|
||||
* @param postId 指定对象主键Id。
|
||||
* @return 应答结果对象,包含对象详情。
|
||||
*/
|
||||
@SaCheckPermission("sysPost.view")
|
||||
@GetMapping("/view")
|
||||
public ResponseResult<SysPostVo> view(@RequestParam Long postId) {
|
||||
if (MyCommonUtil.existBlankArgument(postId)) {
|
||||
return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
|
||||
}
|
||||
SysPost sysPost = sysPostService.getByIdWithRelation(postId, MyRelationParam.full());
|
||||
if (sysPost == null) {
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
|
||||
}
|
||||
SysPostVo sysPostVo = MyModelUtil.copyTo(sysPost, SysPostVo.class);
|
||||
return ResponseResult.success(sysPostVo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 以字典形式返回全部岗位管理数据集合。字典的键值为[postId, postName]。
|
||||
* 白名单接口,登录用户均可访问。
|
||||
*
|
||||
* @param filter 过滤对象。
|
||||
* @return 应答结果对象,包含的数据为 List<Map<String, String>>,map中包含两条记录,key的值分别是id和name,value对应具体数据。
|
||||
*/
|
||||
@GetMapping("/listDict")
|
||||
public ResponseResult<List<Map<String, Object>>> listDict(@ParameterObject SysPostDto filter) {
|
||||
List<SysPost> resultList = sysPostService.getListByFilter(MyModelUtil.copyTo(filter, SysPost.class));
|
||||
return ResponseResult.success(MyCommonUtil.toDictDataList(resultList, SysPost::getPostId, SysPost::getPostName));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据字典Id集合,获取查询后的字典数据。
|
||||
*
|
||||
* @param postIds 字典Id集合。
|
||||
* @return 应答结果对象,包含字典形式的数据集合。
|
||||
*/
|
||||
@GetMapping("/listDictByIds")
|
||||
public ResponseResult<List<Map<String, Object>>> listDictByIds(@RequestParam List<Long> postIds) {
|
||||
List<SysPost> resultList = sysPostService.getInList(new HashSet<>(postIds));
|
||||
return ResponseResult.success(MyCommonUtil.toDictDataList(resultList, SysPost::getPostId, SysPost::getPostName));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,331 @@
|
||||
package com.orangeforms.webadmin.upms.controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import com.alibaba.fastjson.TypeReference;
|
||||
import com.github.pagehelper.Page;
|
||||
import com.github.pagehelper.page.PageMethod;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import com.orangeforms.webadmin.upms.dto.SysRoleDto;
|
||||
import com.orangeforms.webadmin.upms.dto.SysUserDto;
|
||||
import com.orangeforms.webadmin.upms.vo.SysRoleVo;
|
||||
import com.orangeforms.webadmin.upms.vo.SysUserVo;
|
||||
import com.orangeforms.webadmin.upms.model.SysRole;
|
||||
import com.orangeforms.webadmin.upms.model.SysUser;
|
||||
import com.orangeforms.webadmin.upms.model.SysUserRole;
|
||||
import com.orangeforms.webadmin.upms.service.SysRoleService;
|
||||
import com.orangeforms.webadmin.upms.service.SysUserService;
|
||||
import com.orangeforms.common.core.validator.UpdateGroup;
|
||||
import com.orangeforms.common.core.constant.ErrorCodeEnum;
|
||||
import com.orangeforms.common.core.object.*;
|
||||
import com.orangeforms.common.core.util.*;
|
||||
import com.orangeforms.common.core.annotation.MyRequestBody;
|
||||
import com.orangeforms.common.log.annotation.OperationLog;
|
||||
import com.orangeforms.common.log.model.constant.SysOperationLogType;
|
||||
import org.springdoc.core.annotations.ParameterObject;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import jakarta.validation.groups.Default;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 角色管理接口控制器类。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
@Tag(name = "角色管理接口")
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/admin/upms/sysRole")
|
||||
public class SysRoleController {
|
||||
|
||||
@Autowired
|
||||
private SysRoleService sysRoleService;
|
||||
@Autowired
|
||||
private SysUserService sysUserService;
|
||||
|
||||
/**
|
||||
* 新增角色操作。
|
||||
*
|
||||
* @param sysRoleDto 新增角色对象。
|
||||
* @param menuIdListString 与当前角色Id绑定的menuId列表,多个menuId之间逗号分隔。
|
||||
* @return 应答结果对象,包含新增角色的主键Id。
|
||||
*/
|
||||
@ApiOperationSupport(ignoreParameters = {"sysRoleDto.roleId", "sysRoleDto.createTimeStart", "sysRoleDto.createTimeEnd"})
|
||||
@SaCheckPermission("sysRole.add")
|
||||
@OperationLog(type = SysOperationLogType.ADD)
|
||||
@PostMapping("/add")
|
||||
public ResponseResult<Long> add(
|
||||
@MyRequestBody SysRoleDto sysRoleDto, @MyRequestBody String menuIdListString) {
|
||||
String errorMessage = MyCommonUtil.getModelValidationError(sysRoleDto);
|
||||
if (errorMessage != null) {
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
|
||||
}
|
||||
SysRole sysRole = MyModelUtil.copyTo(sysRoleDto, SysRole.class);
|
||||
CallResult result = sysRoleService.verifyRelatedData(sysRole, null, menuIdListString);
|
||||
if (!result.isSuccess()) {
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, result.getErrorMessage());
|
||||
}
|
||||
Set<Long> menuIdSet = null;
|
||||
if (result.getData() != null) {
|
||||
menuIdSet = result.getData().getObject("menuIdSet", new TypeReference<Set<Long>>(){});
|
||||
}
|
||||
sysRoleService.saveNew(sysRole, menuIdSet);
|
||||
return ResponseResult.success(sysRole.getRoleId());
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新角色操作。
|
||||
*
|
||||
* @param sysRoleDto 更新角色对象。
|
||||
* @param menuIdListString 与当前角色Id绑定的menuId列表,多个menuId之间逗号分隔。
|
||||
* @return 应答结果对象。
|
||||
*/
|
||||
@ApiOperationSupport(ignoreParameters = {"sysRoleDto.createTimeStart", "sysRoleDto.createTimeEnd"})
|
||||
@SaCheckPermission("sysRole.update")
|
||||
@OperationLog(type = SysOperationLogType.UPDATE)
|
||||
@PostMapping("/update")
|
||||
public ResponseResult<Void> update(
|
||||
@MyRequestBody SysRoleDto sysRoleDto, @MyRequestBody String menuIdListString) {
|
||||
String errorMessage = MyCommonUtil.getModelValidationError(sysRoleDto, Default.class, UpdateGroup.class);
|
||||
if (errorMessage != null) {
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
|
||||
}
|
||||
SysRole originalSysRole = sysRoleService.getById(sysRoleDto.getRoleId());
|
||||
if (originalSysRole == null) {
|
||||
errorMessage = "数据验证失败,当前角色并不存在,请刷新后重试!";
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
|
||||
}
|
||||
SysRole sysRole = MyModelUtil.copyTo(sysRoleDto, SysRole.class);
|
||||
CallResult result = sysRoleService.verifyRelatedData(sysRole, originalSysRole, menuIdListString);
|
||||
if (!result.isSuccess()) {
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, result.getErrorMessage());
|
||||
}
|
||||
Set<Long> menuIdSet = null;
|
||||
if (result.getData() != null) {
|
||||
menuIdSet = result.getData().getObject("menuIdSet", new TypeReference<Set<Long>>(){});
|
||||
}
|
||||
if (!sysRoleService.update(sysRole, originalSysRole, menuIdSet)) {
|
||||
errorMessage = "更新失败,数据不存在,请刷新后重试!";
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
|
||||
}
|
||||
return ResponseResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除指定角色操作。
|
||||
*
|
||||
* @param roleId 指定角色主键Id。
|
||||
* @return 应答结果对象。
|
||||
*/
|
||||
@SaCheckPermission("sysRole.delete")
|
||||
@OperationLog(type = SysOperationLogType.DELETE)
|
||||
@PostMapping("/delete")
|
||||
public ResponseResult<Void> delete(@MyRequestBody Long roleId) {
|
||||
if (MyCommonUtil.existBlankArgument(roleId)) {
|
||||
return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
|
||||
}
|
||||
if (!sysRoleService.remove(roleId)) {
|
||||
String errorMessage = "数据操作失败,角色不存在,请刷新后重试!";
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
|
||||
}
|
||||
return ResponseResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看角色列表。
|
||||
*
|
||||
* @param sysRoleDtoFilter 角色过滤对象。
|
||||
* @param orderParam 排序参数。
|
||||
* @param pageParam 分页参数。
|
||||
* @return 应答结果对象,包含角色列表。
|
||||
*/
|
||||
@SaCheckPermission("sysRole.view")
|
||||
@PostMapping("/list")
|
||||
public ResponseResult<MyPageData<SysRoleVo>> list(
|
||||
@MyRequestBody SysRoleDto sysRoleDtoFilter,
|
||||
@MyRequestBody MyOrderParam orderParam,
|
||||
@MyRequestBody MyPageParam pageParam) {
|
||||
if (pageParam != null) {
|
||||
PageMethod.startPage(pageParam.getPageNum(), pageParam.getPageSize());
|
||||
}
|
||||
SysRole filter = MyModelUtil.copyTo(sysRoleDtoFilter, SysRole.class);
|
||||
List<SysRole> roleList = sysRoleService.getSysRoleList(
|
||||
filter, MyOrderParam.buildOrderBy(orderParam, SysRole.class));
|
||||
List<SysRoleVo> roleVoList = MyModelUtil.copyCollectionTo(roleList, SysRoleVo.class);
|
||||
long totalCount = 0L;
|
||||
if (roleList instanceof Page) {
|
||||
totalCount = ((Page<SysRole>) roleList).getTotal();
|
||||
}
|
||||
return ResponseResult.success(MyPageUtil.makeResponseData(roleVoList, totalCount));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看角色详情。
|
||||
*
|
||||
* @param roleId 指定角色主键Id。
|
||||
* @return 应答结果对象,包含角色详情对象。
|
||||
*/
|
||||
@SaCheckPermission("sysRole.view")
|
||||
@GetMapping("/view")
|
||||
public ResponseResult<SysRoleVo> view(@RequestParam Long roleId) {
|
||||
if (MyCommonUtil.existBlankArgument(roleId)) {
|
||||
return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
|
||||
}
|
||||
SysRole sysRole = sysRoleService.getByIdWithRelation(roleId, MyRelationParam.full());
|
||||
if (sysRole == null) {
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
|
||||
}
|
||||
SysRoleVo sysRoleVo = MyModelUtil.copyTo(sysRole, SysRoleVo.class);
|
||||
return ResponseResult.success(sysRoleVo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 拥有指定角色的用户列表。
|
||||
*
|
||||
* @param roleId 角色主键Id。
|
||||
* @param sysUserDtoFilter 用户过滤对象。
|
||||
* @param orderParam 排序参数。
|
||||
* @param pageParam 分页参数。
|
||||
* @return 应答结果对象,包含用户列表数据。
|
||||
*/
|
||||
@SaCheckPermission("sysRole.view")
|
||||
@PostMapping("/listUserRole")
|
||||
public ResponseResult<MyPageData<SysUserVo>> listUserRole(
|
||||
@MyRequestBody Long roleId,
|
||||
@MyRequestBody SysUserDto sysUserDtoFilter,
|
||||
@MyRequestBody MyOrderParam orderParam,
|
||||
@MyRequestBody MyPageParam pageParam) {
|
||||
ResponseResult<Void> verifyResult = this.doRoleUserVerify(roleId);
|
||||
if (!verifyResult.isSuccess()) {
|
||||
return ResponseResult.errorFrom(verifyResult);
|
||||
}
|
||||
if (pageParam != null) {
|
||||
PageMethod.startPage(pageParam.getPageNum(), pageParam.getPageSize());
|
||||
}
|
||||
SysUser filter = MyModelUtil.copyTo(sysUserDtoFilter, SysUser.class);
|
||||
String orderBy = MyOrderParam.buildOrderBy(orderParam, SysUser.class);
|
||||
List<SysUser> userList = sysUserService.getSysUserListByRoleId(roleId, filter, orderBy);
|
||||
return ResponseResult.success(MyPageUtil.makeResponseData(userList, SysUserVo.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取不包含指定角色Id的用户列表。
|
||||
* 用户和角色是多对多关系,当前接口将返回没有赋值指定RoleId的用户列表。可用于给角色添加新用户。
|
||||
*
|
||||
* @param roleId 角色主键Id。
|
||||
* @param sysUserDtoFilter 用户过滤对象。
|
||||
* @param orderParam 排序参数。
|
||||
* @param pageParam 分页参数。
|
||||
* @return 应答结果对象,包含用户列表数据。
|
||||
*/
|
||||
@SaCheckPermission("sysRole.update")
|
||||
@PostMapping("/listNotInUserRole")
|
||||
public ResponseResult<MyPageData<SysUserVo>> listNotInUserRole(
|
||||
@MyRequestBody Long roleId,
|
||||
@MyRequestBody SysUserDto sysUserDtoFilter,
|
||||
@MyRequestBody MyOrderParam orderParam,
|
||||
@MyRequestBody MyPageParam pageParam) {
|
||||
ResponseResult<Void> verifyResult = this.doRoleUserVerify(roleId);
|
||||
if (!verifyResult.isSuccess()) {
|
||||
return ResponseResult.errorFrom(verifyResult);
|
||||
}
|
||||
if (pageParam != null) {
|
||||
PageMethod.startPage(pageParam.getPageNum(), pageParam.getPageSize());
|
||||
}
|
||||
SysUser filter = MyModelUtil.copyTo(sysUserDtoFilter, SysUser.class);
|
||||
String orderBy = MyOrderParam.buildOrderBy(orderParam, SysUser.class);
|
||||
List<SysUser> userList = sysUserService.getNotInSysUserListByRoleId(roleId, filter, orderBy);
|
||||
return ResponseResult.success(MyPageUtil.makeResponseData(userList, SysUserVo.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* 为指定角色添加用户列表。该操作可同时给一批用户赋值角色,并在同一事务内完成。
|
||||
*
|
||||
* @param roleId 角色主键Id。
|
||||
* @param userIdListString 逗号分隔的用户Id列表。
|
||||
* @return 应答结果对象。
|
||||
*/
|
||||
@SaCheckPermission("sysRole.update")
|
||||
@OperationLog(type = SysOperationLogType.ADD_M2M)
|
||||
@PostMapping("/addUserRole")
|
||||
public ResponseResult<Void> addUserRole(@MyRequestBody Long roleId, @MyRequestBody String userIdListString) {
|
||||
if (MyCommonUtil.existBlankArgument(roleId, userIdListString)) {
|
||||
return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
|
||||
}
|
||||
Set<Long> userIdSet = Arrays.stream(
|
||||
userIdListString.split(",")).map(Long::valueOf).collect(Collectors.toSet());
|
||||
if (!sysRoleService.existId(roleId)
|
||||
|| !sysUserService.existUniqueKeyList("userId", userIdSet)) {
|
||||
return ResponseResult.error(ErrorCodeEnum.INVALID_RELATED_RECORD_ID);
|
||||
}
|
||||
List<SysUserRole> userRoleList = new LinkedList<>();
|
||||
for (Long userId : userIdSet) {
|
||||
SysUserRole userRole = new SysUserRole();
|
||||
userRole.setRoleId(roleId);
|
||||
userRole.setUserId(userId);
|
||||
userRoleList.add(userRole);
|
||||
}
|
||||
sysRoleService.addUserRoleList(userRoleList);
|
||||
return ResponseResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 为指定用户移除指定角色。
|
||||
*
|
||||
* @param roleId 指定角色主键Id。
|
||||
* @param userId 指定用户主键Id。
|
||||
* @return 应答数据结果。
|
||||
*/
|
||||
@SaCheckPermission("sysRole.update")
|
||||
@OperationLog(type = SysOperationLogType.DELETE_M2M)
|
||||
@PostMapping("/deleteUserRole")
|
||||
public ResponseResult<Void> deleteUserRole(@MyRequestBody Long roleId, @MyRequestBody Long userId) {
|
||||
if (MyCommonUtil.existBlankArgument(roleId, userId)) {
|
||||
return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
|
||||
}
|
||||
if (!sysRoleService.removeUserRole(roleId, userId)) {
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
|
||||
}
|
||||
return ResponseResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 以字典形式返回全部角色管理数据集合。字典的键值为[roleId, roleName]。
|
||||
* 白名单接口,登录用户均可访问。
|
||||
*
|
||||
* @param filter 过滤对象。
|
||||
* @return 应答结果对象,包含的数据为 List<Map<String, String>>,map中包含两条记录,key的值分别是id和name,value对应具体数据。
|
||||
*/
|
||||
@GetMapping("/listDict")
|
||||
public ResponseResult<List<Map<String, Object>>> listDict(@ParameterObject SysRoleDto filter) {
|
||||
List<SysRole> resultList = sysRoleService.getListByFilter(MyModelUtil.copyTo(filter, SysRole.class));
|
||||
return ResponseResult.success(MyCommonUtil.toDictDataList(resultList, SysRole::getRoleId, SysRole::getRoleName));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据字典Id集合,获取查询后的字典数据。
|
||||
*
|
||||
* @param dictIds 字典Id集合。
|
||||
* @return 应答结果对象,包含字典形式的数据集合。
|
||||
*/
|
||||
@GetMapping("/listDictByIds")
|
||||
public ResponseResult<List<Map<String, Object>>> listDictByIds(@RequestParam List<Long> dictIds) {
|
||||
List<SysRole> resultList = sysRoleService.getInList(new HashSet<>(dictIds));
|
||||
return ResponseResult.success(MyCommonUtil.toDictDataList(resultList, SysRole::getRoleId, SysRole::getRoleName));
|
||||
}
|
||||
|
||||
private ResponseResult<Void> doRoleUserVerify(Long roleId) {
|
||||
if (MyCommonUtil.existBlankArgument(roleId)) {
|
||||
return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
|
||||
}
|
||||
if (!sysRoleService.existId(roleId)) {
|
||||
return ResponseResult.error(ErrorCodeEnum.INVALID_RELATED_RECORD_ID);
|
||||
}
|
||||
return ResponseResult.success();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,378 @@
|
||||
package com.orangeforms.webadmin.upms.controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import com.alibaba.fastjson.TypeReference;
|
||||
import cn.hutool.core.util.ReflectUtil;
|
||||
import com.orangeforms.common.core.upload.BaseUpDownloader;
|
||||
import com.orangeforms.common.core.upload.UpDownloaderFactory;
|
||||
import com.orangeforms.common.core.upload.UploadResponseInfo;
|
||||
import com.orangeforms.common.core.upload.UploadStoreInfo;
|
||||
import com.orangeforms.common.log.annotation.OperationLog;
|
||||
import com.orangeforms.common.log.model.constant.SysOperationLogType;
|
||||
import com.github.pagehelper.page.PageMethod;
|
||||
import com.orangeforms.webadmin.upms.vo.*;
|
||||
import com.orangeforms.webadmin.upms.dto.*;
|
||||
import com.orangeforms.webadmin.upms.model.*;
|
||||
import com.orangeforms.webadmin.upms.service.*;
|
||||
import com.orangeforms.common.core.object.*;
|
||||
import com.orangeforms.common.core.util.*;
|
||||
import com.orangeforms.common.core.constant.*;
|
||||
import com.orangeforms.common.core.annotation.MyRequestBody;
|
||||
import com.orangeforms.common.redis.cache.SessionCacheHelper;
|
||||
import com.orangeforms.webadmin.config.ApplicationConfig;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springdoc.core.annotations.ParameterObject;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 用户管理操作控制器类。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
@Tag(name = "用户管理管理接口")
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/admin/upms/sysUser")
|
||||
public class SysUserController {
|
||||
|
||||
@Autowired
|
||||
private PasswordEncoder passwordEncoder;
|
||||
@Autowired
|
||||
private ApplicationConfig appConfig;
|
||||
@Autowired
|
||||
private SessionCacheHelper cacheHelper;
|
||||
@Autowired
|
||||
private UpDownloaderFactory upDownloaderFactory;
|
||||
@Autowired
|
||||
private SysUserService sysUserService;
|
||||
|
||||
/**
|
||||
* 新增用户操作。
|
||||
*
|
||||
* @param sysUserDto 新增用户对象。
|
||||
* @param deptPostIdListString 逗号分隔的部门岗位Id列表。
|
||||
* @param dataPermIdListString 逗号分隔的数据权限Id列表。
|
||||
* @param roleIdListString 逗号分隔的角色Id列表。
|
||||
* @return 应答结果对象,包含新增用户的主键Id。
|
||||
*/
|
||||
@ApiOperationSupport(ignoreParameters = {
|
||||
"sysUserDto.userId",
|
||||
"sysUserDto.createTimeStart",
|
||||
"sysUserDto.createTimeEnd"})
|
||||
@SaCheckPermission("sysUser.add")
|
||||
@OperationLog(type = SysOperationLogType.ADD)
|
||||
@PostMapping("/add")
|
||||
public ResponseResult<Long> add(
|
||||
@MyRequestBody SysUserDto sysUserDto,
|
||||
@MyRequestBody String deptPostIdListString,
|
||||
@MyRequestBody String dataPermIdListString,
|
||||
@MyRequestBody String roleIdListString) {
|
||||
String errorMessage = MyCommonUtil.getModelValidationError(sysUserDto, false);
|
||||
if (errorMessage != null) {
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
|
||||
}
|
||||
SysUser sysUser = MyModelUtil.copyTo(sysUserDto, SysUser.class);
|
||||
CallResult result = sysUserService.verifyRelatedData(
|
||||
sysUser, null, roleIdListString, deptPostIdListString, dataPermIdListString);
|
||||
if (!result.isSuccess()) {
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, result.getErrorMessage());
|
||||
}
|
||||
Set<Long> deptPostIdSet = result.getData().getObject("deptPostIdSet", new TypeReference<Set<Long>>() {});
|
||||
Set<Long> roleIdSet = result.getData().getObject("roleIdSet", new TypeReference<Set<Long>>() {});
|
||||
Set<Long> dataPermIdSet = result.getData().getObject("dataPermIdSet", new TypeReference<Set<Long>>() {});
|
||||
sysUserService.saveNew(sysUser, roleIdSet, deptPostIdSet, dataPermIdSet);
|
||||
return ResponseResult.success(sysUser.getUserId());
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新用户操作。
|
||||
*
|
||||
* @param sysUserDto 更新用户对象。
|
||||
* @param deptPostIdListString 逗号分隔的部门岗位Id列表。
|
||||
* @param dataPermIdListString 逗号分隔的数据权限Id列表。
|
||||
* @param roleIdListString 逗号分隔的角色Id列表。
|
||||
* @return 应答结果对象。
|
||||
*/
|
||||
@ApiOperationSupport(ignoreParameters = {
|
||||
"sysUserDto.createTimeStart",
|
||||
"sysUserDto.createTimeEnd"})
|
||||
@SaCheckPermission("sysUser.update")
|
||||
@OperationLog(type = SysOperationLogType.UPDATE)
|
||||
@PostMapping("/update")
|
||||
public ResponseResult<Void> update(
|
||||
@MyRequestBody SysUserDto sysUserDto,
|
||||
@MyRequestBody String deptPostIdListString,
|
||||
@MyRequestBody String dataPermIdListString,
|
||||
@MyRequestBody String roleIdListString) {
|
||||
String errorMessage = MyCommonUtil.getModelValidationError(sysUserDto, true);
|
||||
if (errorMessage != null) {
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
|
||||
}
|
||||
SysUser originalUser = sysUserService.getById(sysUserDto.getUserId());
|
||||
if (originalUser == null) {
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
|
||||
}
|
||||
SysUser sysUser = MyModelUtil.copyTo(sysUserDto, SysUser.class);
|
||||
CallResult result = sysUserService.verifyRelatedData(
|
||||
sysUser, originalUser, roleIdListString, deptPostIdListString, dataPermIdListString);
|
||||
if (!result.isSuccess()) {
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, result.getErrorMessage());
|
||||
}
|
||||
Set<Long> roleIdSet = result.getData().getObject("roleIdSet", new TypeReference<Set<Long>>() {});
|
||||
Set<Long> deptPostIdSet = result.getData().getObject("deptPostIdSet", new TypeReference<Set<Long>>() {});
|
||||
Set<Long> dataPermIdSet = result.getData().getObject("dataPermIdSet", new TypeReference<Set<Long>>() {});
|
||||
if (!sysUserService.update(sysUser, originalUser, roleIdSet, deptPostIdSet, dataPermIdSet)) {
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
|
||||
}
|
||||
return ResponseResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置密码操作。
|
||||
*
|
||||
* @param userId 指定用户主键Id。
|
||||
* @return 应答结果对象。
|
||||
*/
|
||||
@SaCheckPermission("sysUser.resetPassword")
|
||||
@PostMapping("/resetPassword")
|
||||
public ResponseResult<Void> resetPassword(@MyRequestBody Long userId) {
|
||||
if (MyCommonUtil.existBlankArgument(userId)) {
|
||||
return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
|
||||
}
|
||||
if (!sysUserService.changePassword(userId, appConfig.getDefaultUserPassword())) {
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
|
||||
}
|
||||
return ResponseResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除用户管理数据。
|
||||
*
|
||||
* @param userId 删除对象主键Id。
|
||||
* @return 应答结果对象。
|
||||
*/
|
||||
@SaCheckPermission("sysUser.delete")
|
||||
@OperationLog(type = SysOperationLogType.DELETE)
|
||||
@PostMapping("/delete")
|
||||
public ResponseResult<Void> delete(@MyRequestBody Long userId) {
|
||||
if (MyCommonUtil.existBlankArgument(userId)) {
|
||||
return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
|
||||
}
|
||||
return this.doDelete(userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除用户管理数据。
|
||||
*
|
||||
* @param userIdList 待删除对象的主键Id列表。
|
||||
* @return 应答结果对象。
|
||||
*/
|
||||
@SaCheckPermission("sysUser.delete")
|
||||
@OperationLog(type = SysOperationLogType.DELETE_BATCH)
|
||||
@PostMapping("/deleteBatch")
|
||||
public ResponseResult<Void> deleteBatch(@MyRequestBody List<Long> userIdList) {
|
||||
if (MyCommonUtil.existBlankArgument(userIdList)) {
|
||||
return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
|
||||
}
|
||||
for (Long userId : userIdList) {
|
||||
ResponseResult<Void> responseResult = this.doDelete(userId);
|
||||
if (!responseResult.isSuccess()) {
|
||||
return responseResult;
|
||||
}
|
||||
}
|
||||
return ResponseResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 列出符合过滤条件的用户管理列表。
|
||||
*
|
||||
* @param sysUserDtoFilter 过滤对象。
|
||||
* @param orderParam 排序参数。
|
||||
* @param pageParam 分页参数。
|
||||
* @return 应答结果对象,包含查询结果集。
|
||||
*/
|
||||
@SaCheckPermission("sysUser.view")
|
||||
@PostMapping("/list")
|
||||
public ResponseResult<MyPageData<SysUserVo>> list(
|
||||
@MyRequestBody SysUserDto sysUserDtoFilter,
|
||||
@MyRequestBody MyOrderParam orderParam,
|
||||
@MyRequestBody MyPageParam pageParam) {
|
||||
if (pageParam != null) {
|
||||
PageMethod.startPage(pageParam.getPageNum(), pageParam.getPageSize(), pageParam.getCount());
|
||||
}
|
||||
SysUser sysUserFilter = MyModelUtil.copyTo(sysUserDtoFilter, SysUser.class);
|
||||
String orderBy = MyOrderParam.buildOrderBy(orderParam, SysUser.class);
|
||||
List<SysUser> sysUserList = sysUserService.getSysUserListWithRelation(sysUserFilter, orderBy);
|
||||
return ResponseResult.success(MyPageUtil.makeResponseData(sysUserList, SysUserVo.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看指定用户管理对象详情。
|
||||
*
|
||||
* @param userId 指定对象主键Id。
|
||||
* @return 应答结果对象,包含对象详情。
|
||||
*/
|
||||
@SaCheckPermission("sysUser.view")
|
||||
@GetMapping("/view")
|
||||
public ResponseResult<SysUserVo> view(@RequestParam Long userId) {
|
||||
// 这里查看用户数据时候,需要把用户多对多关联的角色和数据权限Id一并查出。
|
||||
SysUser sysUser = sysUserService.getByIdWithRelation(userId, MyRelationParam.full());
|
||||
if (sysUser == null) {
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
|
||||
}
|
||||
SysUserVo sysUserVo = MyModelUtil.copyTo(sysUser, SysUserVo.class);
|
||||
return ResponseResult.success(sysUserVo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 附件文件下载。
|
||||
* 这里将图片和其他类型的附件文件放到不同的父目录下,主要为了便于今后图片文件的迁移。
|
||||
*
|
||||
* @param userId 附件所在记录的主键Id。
|
||||
* @param fieldName 附件所属的字段名。
|
||||
* @param filename 文件名。如果没有提供该参数,就从当前记录的指定字段中读取。
|
||||
* @param asImage 下载文件是否为图片。
|
||||
* @param response Http 应答对象。
|
||||
*/
|
||||
@SaCheckPermission("sysUser.view")
|
||||
@OperationLog(type = SysOperationLogType.DOWNLOAD, saveResponse = false)
|
||||
@GetMapping("/download")
|
||||
public void download(
|
||||
@RequestParam(required = false) Long userId,
|
||||
@RequestParam String fieldName,
|
||||
@RequestParam String filename,
|
||||
@RequestParam Boolean asImage,
|
||||
HttpServletResponse response) {
|
||||
if (MyCommonUtil.existBlankArgument(fieldName, filename, asImage)) {
|
||||
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
|
||||
return;
|
||||
}
|
||||
// 使用try来捕获异常,是为了保证一旦出现异常可以返回500的错误状态,便于调试。
|
||||
// 否则有可能给前端返回的是200的错误码。
|
||||
try {
|
||||
// 如果请求参数中没有包含主键Id,就判断该文件是否为当前session上传的。
|
||||
if (userId == null) {
|
||||
if (!cacheHelper.existSessionUploadFile(filename)) {
|
||||
ResponseResult.output(HttpServletResponse.SC_FORBIDDEN);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
SysUser sysUser = sysUserService.getById(userId);
|
||||
if (sysUser == null) {
|
||||
ResponseResult.output(HttpServletResponse.SC_NOT_FOUND);
|
||||
return;
|
||||
}
|
||||
String fieldJsonData = (String) ReflectUtil.getFieldValue(sysUser, fieldName);
|
||||
if (fieldJsonData == null && !cacheHelper.existSessionUploadFile(filename)) {
|
||||
ResponseResult.output(HttpServletResponse.SC_BAD_REQUEST);
|
||||
return;
|
||||
}
|
||||
if (!BaseUpDownloader.containFile(fieldJsonData, filename)
|
||||
&& !cacheHelper.existSessionUploadFile(filename)) {
|
||||
ResponseResult.output(HttpServletResponse.SC_FORBIDDEN);
|
||||
return;
|
||||
}
|
||||
}
|
||||
UploadStoreInfo storeInfo = MyModelUtil.getUploadStoreInfo(SysUser.class, fieldName);
|
||||
if (!storeInfo.isSupportUpload()) {
|
||||
ResponseResult.output(HttpServletResponse.SC_NOT_IMPLEMENTED,
|
||||
ResponseResult.error(ErrorCodeEnum.INVALID_UPLOAD_FIELD));
|
||||
return;
|
||||
}
|
||||
BaseUpDownloader upDownloader = upDownloaderFactory.get(storeInfo.getStoreType());
|
||||
upDownloader.doDownload(appConfig.getUploadFileBaseDir(),
|
||||
SysUser.class.getSimpleName(), fieldName, filename, asImage, response);
|
||||
} catch (Exception e) {
|
||||
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件上传操作。
|
||||
*
|
||||
* @param fieldName 上传文件名。
|
||||
* @param asImage 是否作为图片上传。如果是图片,今后下载的时候无需权限验证。否则就是附件上传,下载时需要权限验证。
|
||||
* @param uploadFile 上传文件对象。
|
||||
*/
|
||||
@SaCheckPermission("sysUser.view")
|
||||
@OperationLog(type = SysOperationLogType.UPLOAD, saveResponse = false)
|
||||
@PostMapping("/upload")
|
||||
public void upload(
|
||||
@RequestParam String fieldName,
|
||||
@RequestParam Boolean asImage,
|
||||
@RequestParam("uploadFile") MultipartFile uploadFile) throws IOException {
|
||||
UploadStoreInfo storeInfo = MyModelUtil.getUploadStoreInfo(SysUser.class, fieldName);
|
||||
// 这里就会判断参数中指定的字段,是否支持上传操作。
|
||||
if (!storeInfo.isSupportUpload()) {
|
||||
ResponseResult.output(HttpServletResponse.SC_FORBIDDEN,
|
||||
ResponseResult.error(ErrorCodeEnum.INVALID_UPLOAD_FIELD));
|
||||
return;
|
||||
}
|
||||
// 根据字段注解中的存储类型,通过工厂方法获取匹配的上传下载实现类,从而解耦。
|
||||
BaseUpDownloader upDownloader = upDownloaderFactory.get(storeInfo.getStoreType());
|
||||
UploadResponseInfo responseInfo = upDownloader.doUpload(null,
|
||||
appConfig.getUploadFileBaseDir(), SysUser.class.getSimpleName(), fieldName, asImage, uploadFile);
|
||||
if (Boolean.TRUE.equals(responseInfo.getUploadFailed())) {
|
||||
ResponseResult.output(HttpServletResponse.SC_FORBIDDEN,
|
||||
ResponseResult.error(ErrorCodeEnum.UPLOAD_FAILED, responseInfo.getErrorMessage()));
|
||||
return;
|
||||
}
|
||||
cacheHelper.putSessionUploadFile(responseInfo.getFilename());
|
||||
ResponseResult.output(ResponseResult.success(responseInfo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 以字典形式返回全部用户管理数据集合。字典的键值为[userId, showName]。
|
||||
* 白名单接口,登录用户均可访问。
|
||||
*
|
||||
* @param filter 过滤对象。
|
||||
* @return 应答结果对象,包含的数据为 List<Map<String, String>>,map中包含两条记录,key的值分别是id和name,value对应具体数据。
|
||||
*/
|
||||
@GetMapping("/listDict")
|
||||
public ResponseResult<List<Map<String, Object>>> listDict(@ParameterObject SysUserDto filter) {
|
||||
List<SysUser> resultList =
|
||||
sysUserService.getListByFilter(MyModelUtil.copyTo(filter, SysUser.class));
|
||||
return ResponseResult.success(
|
||||
MyCommonUtil.toDictDataList(resultList, SysUser::getUserId, SysUser::getShowName));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据字典Id集合,获取查询后的字典数据。
|
||||
*
|
||||
* @param dictIds 字典Id集合。
|
||||
* @return 应答结果对象,包含字典形式的数据集合。
|
||||
*/
|
||||
@GetMapping("/listDictByIds")
|
||||
public ResponseResult<List<Map<String, Object>>> listDictByIds(@RequestParam List<Long> dictIds) {
|
||||
List<SysUser> resultList = sysUserService.getInList(new HashSet<>(dictIds));
|
||||
return ResponseResult.success(
|
||||
MyCommonUtil.toDictDataList(resultList, SysUser::getUserId, SysUser::getShowName));
|
||||
}
|
||||
|
||||
private ResponseResult<Void> doDelete(Long userId) {
|
||||
String errorMessage;
|
||||
// 验证关联Id的数据合法性
|
||||
SysUser originalSysUser = sysUserService.getById(userId);
|
||||
if (originalSysUser == null) {
|
||||
// NOTE: 修改下面方括号中的话述
|
||||
errorMessage = "数据验证失败,当前 [对象] 并不存在,请刷新后重试!";
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
|
||||
}
|
||||
if (!sysUserService.remove(userId)) {
|
||||
errorMessage = "数据操作失败,删除的对象不存在,请刷新后重试!";
|
||||
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
|
||||
}
|
||||
return ResponseResult.success();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.orangeforms.webadmin.upms.dao;
|
||||
|
||||
import com.orangeforms.common.core.base.dao.BaseDaoMapper;
|
||||
import com.orangeforms.webadmin.upms.model.SysDataPermDept;
|
||||
|
||||
/**
|
||||
* 数据权限与部门关系数据访问操作接口。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
public interface SysDataPermDeptMapper extends BaseDaoMapper<SysDataPermDept> {
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.orangeforms.webadmin.upms.dao;
|
||||
|
||||
import com.orangeforms.common.core.base.dao.BaseDaoMapper;
|
||||
import com.orangeforms.webadmin.upms.model.SysDataPerm;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 数据权限数据访问操作接口。
|
||||
* NOTE: 该对象一定不能被 @EnableDataPerm 注解标注,否则会导致无限递归。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
public interface SysDataPermMapper extends BaseDaoMapper<SysDataPerm> {
|
||||
|
||||
/**
|
||||
* 获取数据权限列表。
|
||||
*
|
||||
* @param sysDataPermFilter 过滤对象。
|
||||
* @param orderBy 排序字符串。
|
||||
* @return 过滤后的数据权限列表。
|
||||
*/
|
||||
List<SysDataPerm> getSysDataPermList(
|
||||
@Param("sysDataPermFilter") SysDataPerm sysDataPermFilter, @Param("orderBy") String orderBy);
|
||||
|
||||
/**
|
||||
* 获取指定用户的数据权限列表。
|
||||
*
|
||||
* @param userId 用户Id。
|
||||
* @return 数据权限列表。
|
||||
*/
|
||||
List<SysDataPerm> getSysDataPermListByUserId(@Param("userId") Long userId);
|
||||
|
||||
/**
|
||||
* 查询与指定菜单关联的数据权限列表。
|
||||
*
|
||||
* @param menuId 菜单Id。
|
||||
* @return 与菜单Id关联的数据权限列表。
|
||||
*/
|
||||
List<SysDataPerm> getSysDataPermListByMenuId(@Param("menuId") Long menuId);
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.orangeforms.webadmin.upms.dao;
|
||||
|
||||
import com.orangeforms.common.core.base.dao.BaseDaoMapper;
|
||||
import com.orangeforms.webadmin.upms.model.SysDataPermMenu;
|
||||
|
||||
/**
|
||||
* 数据权限与菜单关系数据访问操作接口。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
public interface SysDataPermMenuMapper extends BaseDaoMapper<SysDataPermMenu> {
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.orangeforms.webadmin.upms.dao;
|
||||
|
||||
import com.orangeforms.common.core.base.dao.BaseDaoMapper;
|
||||
import com.orangeforms.webadmin.upms.model.SysDataPermUser;
|
||||
|
||||
/**
|
||||
* 数据权限与用户关系数据访问操作接口。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
public interface SysDataPermUserMapper extends BaseDaoMapper<SysDataPermUser> {
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.orangeforms.webadmin.upms.dao;
|
||||
|
||||
import com.orangeforms.common.core.base.dao.BaseDaoMapper;
|
||||
import com.orangeforms.webadmin.upms.model.SysDept;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 部门管理数据操作访问接口。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
public interface SysDeptMapper extends BaseDaoMapper<SysDept> {
|
||||
|
||||
/**
|
||||
* 批量插入对象列表。
|
||||
*
|
||||
* @param sysDeptList 新增对象列表。
|
||||
*/
|
||||
void insertList(List<SysDept> sysDeptList);
|
||||
|
||||
/**
|
||||
* 获取过滤后的对象列表。
|
||||
*
|
||||
* @param sysDeptFilter 主表过滤对象。
|
||||
* @param orderBy 排序字符串,order by从句的参数。
|
||||
* @return 对象列表。
|
||||
*/
|
||||
List<SysDept> getSysDeptList(
|
||||
@Param("sysDeptFilter") SysDept sysDeptFilter, @Param("orderBy") String orderBy);
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.orangeforms.webadmin.upms.dao;
|
||||
|
||||
import com.orangeforms.common.core.base.dao.BaseDaoMapper;
|
||||
import com.orangeforms.webadmin.upms.model.SysDeptPost;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 部门岗位数据操作访问接口。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
public interface SysDeptPostMapper extends BaseDaoMapper<SysDeptPost> {
|
||||
|
||||
/**
|
||||
* 获取指定部门Id的部门岗位多对多关联数据列表,以及关联的部门和岗位数据。
|
||||
*
|
||||
* @param deptId 部门Id。如果参数为空则返回全部数据。
|
||||
* @return 部门岗位多对多数据列表。
|
||||
*/
|
||||
List<Map<String, Object>> getSysDeptPostListWithRelationByDeptId(@Param("deptId") Long deptId);
|
||||
|
||||
/**
|
||||
* 获取指定部门Id的领导部门岗位列表。
|
||||
*
|
||||
* @param deptId 部门Id。
|
||||
* @return 指定部门Id的领导部门岗位列表
|
||||
*/
|
||||
List<SysDeptPost> getLeaderDeptPostList(@Param("deptId") Long deptId);
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.orangeforms.webadmin.upms.dao;
|
||||
|
||||
import com.orangeforms.common.core.base.dao.BaseDaoMapper;
|
||||
import com.orangeforms.webadmin.upms.model.SysDeptRelation;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 部门关系树关联关系表访问接口。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
public interface SysDeptRelationMapper extends BaseDaoMapper<SysDeptRelation> {
|
||||
|
||||
/**
|
||||
* 将myDeptId的所有子部门,与其父部门parentDeptId解除关联关系。
|
||||
*
|
||||
* @param parentDeptIds myDeptId的父部门Id列表。
|
||||
* @param myDeptId 当前部门。
|
||||
*/
|
||||
void removeBetweenChildrenAndParents(
|
||||
@Param("parentDeptIds") List<Long> parentDeptIds, @Param("myDeptId") Long myDeptId);
|
||||
|
||||
/**
|
||||
* 批量插入部门关联数据。
|
||||
* 由于目前版本(3.4.1)的Mybatis Plus没有提供真正的批量插入,为了保证效率需要自己实现。
|
||||
* 目前我们仅仅给出MySQL和PostgresSQL的insert list实现作为参考,其他数据库需要自行修改。
|
||||
*
|
||||
* @param deptRelationList 部门关联关系数据列表。
|
||||
*/
|
||||
void insertList(List<SysDeptRelation> deptRelationList);
|
||||
|
||||
/**
|
||||
* 批量插入当前部门的所有父部门列表,包括自己和自己的关系。
|
||||
*
|
||||
* @param parentDeptId myDeptId的父部门Id。
|
||||
* @param myDeptId 当前部门。
|
||||
*/
|
||||
void insertParentList(@Param("parentDeptId") Long parentDeptId, @Param("myDeptId") Long myDeptId);
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.orangeforms.webadmin.upms.dao;
|
||||
|
||||
import com.orangeforms.common.core.base.dao.BaseDaoMapper;
|
||||
import com.orangeforms.webadmin.upms.model.SysMenu;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 菜单数据访问操作接口。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
public interface SysMenuMapper extends BaseDaoMapper<SysMenu> {
|
||||
|
||||
/**
|
||||
* 获取登录用户的菜单列表。
|
||||
*
|
||||
* @param userId 登录用户。
|
||||
* @return 菜单列表。
|
||||
*/
|
||||
List<SysMenu> getMenuListByUserId(@Param("userId") Long userId);
|
||||
|
||||
/**
|
||||
* 获取指定角色Id集合的菜单列表。
|
||||
*
|
||||
* @param roleIds 角色Id集合。
|
||||
* @return 菜单列表。
|
||||
*/
|
||||
List<SysMenu> getMenuListByRoleIds(@Param("roleIds") Set<Long> roleIds);
|
||||
|
||||
/**
|
||||
* 查询包含指定菜单编码的菜单数量,目前仅用于satoken的权限框架。
|
||||
*
|
||||
* @param menuCode 菜单编码。
|
||||
* @return 查询数量
|
||||
*/
|
||||
int countMenuCode(@Param("menuCode") String menuCode);
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.orangeforms.webadmin.upms.dao;
|
||||
|
||||
import com.orangeforms.common.core.base.dao.BaseDaoMapper;
|
||||
import com.orangeforms.webadmin.upms.model.SysPermWhitelist;
|
||||
|
||||
/**
|
||||
* 权限资源白名单数据访问操作接口。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
public interface SysPermWhitelistMapper extends BaseDaoMapper<SysPermWhitelist> {
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package com.orangeforms.webadmin.upms.dao;
|
||||
|
||||
import com.orangeforms.common.core.base.dao.BaseDaoMapper;
|
||||
import com.orangeforms.webadmin.upms.model.SysPost;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 岗位管理数据操作访问接口。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
public interface SysPostMapper extends BaseDaoMapper<SysPost> {
|
||||
|
||||
/**
|
||||
* 获取过滤后的对象列表。
|
||||
*
|
||||
* @param sysPostFilter 主表过滤对象。
|
||||
* @param orderBy 排序字符串,order by从句的参数。
|
||||
* @return 对象列表。
|
||||
*/
|
||||
List<SysPost> getSysPostList(
|
||||
@Param("sysPostFilter") SysPost sysPostFilter, @Param("orderBy") String orderBy);
|
||||
|
||||
/**
|
||||
* 获取指定部门的岗位列表。
|
||||
*
|
||||
* @param deptId 部门Id。
|
||||
* @param sysPostFilter 从表过滤对象。
|
||||
* @param orderBy 排序字符串,order by从句的参数。
|
||||
* @return 岗位数据列表。
|
||||
*/
|
||||
List<SysPost> getSysPostListByDeptId(
|
||||
@Param("deptId") Long deptId,
|
||||
@Param("sysPostFilter") SysPost sysPostFilter,
|
||||
@Param("orderBy") String orderBy);
|
||||
|
||||
/**
|
||||
* 根据关联主表Id,获取关联从表中没有和主表建立关联关系的数据列表。
|
||||
*
|
||||
* @param deptId 关联主表Id。
|
||||
* @param sysPostFilter 过滤对象。
|
||||
* @param orderBy 排序字符串,order by从句的参数。
|
||||
* @return 与主表没有建立关联的从表数据列表。
|
||||
*/
|
||||
List<SysPost> getNotInSysPostListByDeptId(
|
||||
@Param("deptId") Long deptId,
|
||||
@Param("sysPostFilter") SysPost sysPostFilter,
|
||||
@Param("orderBy") String orderBy);
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.orangeforms.webadmin.upms.dao;
|
||||
|
||||
import com.orangeforms.common.core.base.dao.BaseDaoMapper;
|
||||
import com.orangeforms.webadmin.upms.model.SysRole;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 角色数据访问操作接口。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
public interface SysRoleMapper extends BaseDaoMapper<SysRole> {
|
||||
|
||||
/**
|
||||
* 获取对象列表,过滤条件中包含like和between条件。
|
||||
*
|
||||
* @param sysRoleFilter 过滤对象。
|
||||
* @param orderBy 排序字符串,order by从句的参数。
|
||||
* @return 对象列表。
|
||||
*/
|
||||
List<SysRole> getSysRoleList(@Param("sysRoleFilter") SysRole sysRoleFilter, @Param("orderBy") String orderBy);
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.orangeforms.webadmin.upms.dao;
|
||||
|
||||
import com.orangeforms.common.core.base.dao.BaseDaoMapper;
|
||||
import com.orangeforms.webadmin.upms.model.SysRoleMenu;
|
||||
|
||||
/**
|
||||
* 角色与菜单操作关联关系数据访问操作接口。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
public interface SysRoleMenuMapper extends BaseDaoMapper<SysRoleMenu> {
|
||||
}
|
||||
@@ -0,0 +1,188 @@
|
||||
package com.orangeforms.webadmin.upms.dao;
|
||||
|
||||
import com.orangeforms.common.core.base.dao.BaseDaoMapper;
|
||||
import com.orangeforms.webadmin.upms.model.SysUser;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 用户管理数据操作访问接口。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
public interface SysUserMapper extends BaseDaoMapper<SysUser> {
|
||||
|
||||
/**
|
||||
* 批量插入对象列表。
|
||||
*
|
||||
* @param sysUserList 新增对象列表。
|
||||
*/
|
||||
void insertList(List<SysUser> sysUserList);
|
||||
|
||||
/**
|
||||
* 获取过滤后的对象列表。
|
||||
*
|
||||
* @param sysUserFilter 主表过滤对象。
|
||||
* @param orderBy 排序字符串,order by从句的参数。
|
||||
* @return 对象列表。
|
||||
*/
|
||||
List<SysUser> getSysUserList(
|
||||
@Param("sysUserFilter") SysUser sysUserFilter, @Param("orderBy") String orderBy);
|
||||
|
||||
/**
|
||||
* 根据部门Id集合,获取关联的用户列表。
|
||||
*
|
||||
* @param deptIds 关联的部门Id集合。
|
||||
* @param sysUserFilter 用户过滤条件对象。
|
||||
* @param orderBy order by从句的参数。
|
||||
* @return 和部门Id集合关联的用户列表。
|
||||
*/
|
||||
List<SysUser> getSysUserListByDeptIds(
|
||||
@Param("deptIds") Set<Long> deptIds,
|
||||
@Param("sysUserFilter") SysUser sysUserFilter,
|
||||
@Param("orderBy") String orderBy);
|
||||
|
||||
/**
|
||||
* 根据登录名集合,获取关联的用户列表。
|
||||
* @param loginNames 登录名集合。
|
||||
* @param sysUserFilter 用户过滤条件对象。
|
||||
* @param orderBy order by从句的参数。
|
||||
* @return 和登录名集合关联的用户列表。
|
||||
*/
|
||||
List<SysUser> getSysUserListByLoginNames(
|
||||
@Param("loginNames") List<String> loginNames,
|
||||
@Param("sysUserFilter") SysUser sysUserFilter,
|
||||
@Param("orderBy") String orderBy);
|
||||
|
||||
/**
|
||||
* 根据角色Id,获取关联的用户列表。
|
||||
*
|
||||
* @param roleId 关联的角色Id。
|
||||
* @param sysUserFilter 用户过滤条件对象。
|
||||
* @param orderBy order by从句的参数。
|
||||
* @return 和角色Id关联的用户列表。
|
||||
*/
|
||||
List<SysUser> getSysUserListByRoleId(
|
||||
@Param("roleId") Long roleId,
|
||||
@Param("sysUserFilter") SysUser sysUserFilter,
|
||||
@Param("orderBy") String orderBy);
|
||||
|
||||
/**
|
||||
* 根据角色Id集合,获取去重后的用户Id列表。
|
||||
*
|
||||
* @param roleIds 关联的角色Id集合。
|
||||
* @param sysUserFilter 用户过滤条件对象。
|
||||
* @param orderBy order by从句的参数。
|
||||
* @return 和角色Id集合关联的去重后的用户Id列表。
|
||||
*/
|
||||
List<Long> getUserIdListByRoleIds(
|
||||
@Param("roleIds") Set<Long> roleIds,
|
||||
@Param("sysUserFilter") SysUser sysUserFilter,
|
||||
@Param("orderBy") String orderBy);
|
||||
|
||||
/**
|
||||
* 根据角色Id,获取和当前角色Id没有建立多对多关联关系的用户列表。
|
||||
*
|
||||
* @param roleId 关联的角色Id。
|
||||
* @param sysUserFilter 用户过滤条件对象。
|
||||
* @param orderBy order by从句的参数。
|
||||
* @return 和RoleId没有建立关联关系的用户列表。
|
||||
*/
|
||||
List<SysUser> getNotInSysUserListByRoleId(
|
||||
@Param("roleId") Long roleId,
|
||||
@Param("sysUserFilter") SysUser sysUserFilter,
|
||||
@Param("orderBy") String orderBy);
|
||||
|
||||
/**
|
||||
* 根据数据权限Id,获取关联的用户列表。
|
||||
*
|
||||
* @param dataPermId 关联的数据权限Id。
|
||||
* @param sysUserFilter 用户过滤条件对象。
|
||||
* @param orderBy order by从句的参数。
|
||||
* @return 和DataPermId关联的用户列表。
|
||||
*/
|
||||
List<SysUser> getSysUserListByDataPermId(
|
||||
@Param("dataPermId") Long dataPermId,
|
||||
@Param("sysUserFilter") SysUser sysUserFilter,
|
||||
@Param("orderBy") String orderBy);
|
||||
|
||||
/**
|
||||
* 根据数据权限Id,获取和当前数据权限Id没有建立多对多关联关系的用户列表。
|
||||
*
|
||||
* @param dataPermId 关联的数据权限Id。
|
||||
* @param sysUserFilter 用户过滤条件对象。
|
||||
* @param orderBy order by从句的参数。
|
||||
* @return 和DataPermId没有建立关联关系的用户列表。
|
||||
*/
|
||||
List<SysUser> getNotInSysUserListByDataPermId(
|
||||
@Param("dataPermId") Long dataPermId,
|
||||
@Param("sysUserFilter") SysUser sysUserFilter,
|
||||
@Param("orderBy") String orderBy);
|
||||
|
||||
/**
|
||||
* 根据部门岗位Id集合,获取关联的去重后的用户Id列表。
|
||||
*
|
||||
* @param deptPostIds 关联的部门岗位Id集合。
|
||||
* @param sysUserFilter 用户过滤条件对象。
|
||||
* @param orderBy order by从句的参数。
|
||||
* @return 和部门岗位Id集合关联的去重后的用户Id列表。
|
||||
*/
|
||||
List<Long> getUserIdListByDeptPostIds(
|
||||
@Param("deptPostIds") Set<Long> deptPostIds,
|
||||
@Param("sysUserFilter") SysUser sysUserFilter,
|
||||
@Param("orderBy") String orderBy);
|
||||
|
||||
/**
|
||||
* 根据部门岗位Id,获取关联的用户列表。
|
||||
*
|
||||
* @param deptPostId 关联的部门岗位Id。
|
||||
* @param sysUserFilter 用户过滤条件对象。
|
||||
* @param orderBy order by从句的参数。
|
||||
* @return 和部门岗位Id关联的用户列表。
|
||||
*/
|
||||
List<SysUser> getSysUserListByDeptPostId(
|
||||
@Param("deptPostId") Long deptPostId,
|
||||
@Param("sysUserFilter") SysUser sysUserFilter,
|
||||
@Param("orderBy") String orderBy);
|
||||
|
||||
/**
|
||||
* 根据部门岗位Id,获取和当前部门岗位Id没有建立多对多关联关系的用户列表。
|
||||
*
|
||||
* @param deptPostId 关联的部门岗位Id。
|
||||
* @param sysUserFilter 用户过滤条件对象。
|
||||
* @param orderBy order by从句的参数。
|
||||
* @return 和deptPostId没有建立关联关系的用户列表。
|
||||
*/
|
||||
List<SysUser> getNotInSysUserListByDeptPostId(
|
||||
@Param("deptPostId") Long deptPostId,
|
||||
@Param("sysUserFilter") SysUser sysUserFilter,
|
||||
@Param("orderBy") String orderBy);
|
||||
|
||||
/**
|
||||
* 根据岗位Id集合,获取关联的去重后的用户Id列表。
|
||||
*
|
||||
* @param postIds 关联的岗位Id集合。
|
||||
* @param sysUserFilter 用户过滤条件对象。
|
||||
* @param orderBy order by从句的参数。
|
||||
* @return 和岗位Id集合关联的去重后的用户Id列表。
|
||||
*/
|
||||
List<Long> getUserIdListByPostIds(
|
||||
@Param("postIds") Set<Long> postIds,
|
||||
@Param("sysUserFilter") SysUser sysUserFilter,
|
||||
@Param("orderBy") String orderBy);
|
||||
|
||||
/**
|
||||
* 根据岗位Id,获取关联的用户列表。
|
||||
*
|
||||
* @param postId 关联的岗位Id。
|
||||
* @param sysUserFilter 用户过滤条件对象。
|
||||
* @param orderBy order by从句的参数。
|
||||
* @return 和岗位Id关联的用户列表。
|
||||
*/
|
||||
List<SysUser> getSysUserListByPostId(
|
||||
@Param("postId") Long postId,
|
||||
@Param("sysUserFilter") SysUser sysUserFilter,
|
||||
@Param("orderBy") String orderBy);
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.orangeforms.webadmin.upms.dao;
|
||||
|
||||
import com.orangeforms.common.core.base.dao.BaseDaoMapper;
|
||||
import com.orangeforms.webadmin.upms.model.SysUserPost;
|
||||
|
||||
/**
|
||||
* 用户岗位数据操作访问接口。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
public interface SysUserPostMapper extends BaseDaoMapper<SysUserPost> {
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.orangeforms.webadmin.upms.dao;
|
||||
|
||||
import com.orangeforms.common.core.base.dao.BaseDaoMapper;
|
||||
import com.orangeforms.webadmin.upms.model.SysUserRole;
|
||||
|
||||
/**
|
||||
* 用户与角色关联关系数据访问操作接口。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
public interface SysUserRoleMapper extends BaseDaoMapper<SysUserRole> {
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
<?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="com.orangeforms.webadmin.upms.dao.SysDataPermDeptMapper">
|
||||
<resultMap id="BaseResultMap" type="com.orangeforms.webadmin.upms.model.SysDataPermDept">
|
||||
<id column="data_perm_id" jdbcType="BIGINT" property="dataPermId"/>
|
||||
<id column="dept_id" jdbcType="BIGINT" property="deptId"/>
|
||||
</resultMap>
|
||||
</mapper>
|
||||
@@ -0,0 +1,79 @@
|
||||
<?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="com.orangeforms.webadmin.upms.dao.SysDataPermMapper">
|
||||
<resultMap id="BaseResultMap" type="com.orangeforms.webadmin.upms.model.SysDataPerm">
|
||||
<id column="data_perm_id" jdbcType="BIGINT" property="dataPermId"/>
|
||||
<result column="data_perm_name" jdbcType="VARCHAR" property="dataPermName"/>
|
||||
<result column="rule_type" jdbcType="INTEGER" property="ruleType"/>
|
||||
<result column="create_user_id" jdbcType="BIGINT" property="createUserId"/>
|
||||
<result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
|
||||
<result column="update_user_id" jdbcType="BIGINT" property="updateUserId"/>
|
||||
<result column="update_time" jdbcType="TIMESTAMP" property="updateTime"/>
|
||||
</resultMap>
|
||||
|
||||
<resultMap id="BaseResultMapEx" type="com.orangeforms.webadmin.upms.model.SysDataPerm" extends="BaseResultMap">
|
||||
<collection property="dataPermDeptList" column="data_perm_id" javaType="ArrayList"
|
||||
ofType="com.orangeforms.webadmin.upms.model.SysDataPermDept" notNullColumn="dept_id"
|
||||
resultMap="com.orangeforms.webadmin.upms.dao.SysDataPermDeptMapper.BaseResultMap">
|
||||
</collection>
|
||||
<collection property="dataPermMenuList" column="data_perm_id" javaType="ArrayList"
|
||||
ofType="com.orangeforms.webadmin.upms.model.SysDataPermMenu" notNullColumn="menu_id"
|
||||
resultMap="com.orangeforms.webadmin.upms.dao.SysDataPermMenuMapper.BaseResultMap">
|
||||
</collection>
|
||||
</resultMap>
|
||||
|
||||
<sql id="filterRef">
|
||||
<if test="sysDataPermFilter != null">
|
||||
<if test="sysDataPermFilter.ruleType != null">
|
||||
AND zz_sys_data_perm.rule_type = #{sysDataPermFilter.ruleType}
|
||||
</if>
|
||||
<if test="sysDataPermFilter.searchString != null and sysDataPermFilter.searchString != ''">
|
||||
<bind name= "safeSearchString" value= "'%' + sysDataPermFilter.searchString + '%'" />
|
||||
AND IFNULL(zz_sys_data_perm.data_perm_name, '') LIKE #{safeSearchString}
|
||||
</if>
|
||||
</if>
|
||||
</sql>
|
||||
|
||||
<select id="getSysDataPermList" resultMap="BaseResultMap" parameterType="com.orangeforms.webadmin.upms.model.SysDataPerm">
|
||||
SELECT
|
||||
zz_sys_data_perm.*
|
||||
FROM
|
||||
zz_sys_data_perm
|
||||
<where>
|
||||
<include refid="filterRef"/>
|
||||
</where>
|
||||
<if test="orderBy != null and orderBy != ''">
|
||||
ORDER BY ${orderBy}
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<select id="getSysDataPermListByUserId" resultMap="BaseResultMapEx" parameterType="com.orangeforms.webadmin.upms.model.SysDataPerm">
|
||||
SELECT
|
||||
zz_sys_data_perm.*,
|
||||
zz_sys_data_perm_dept.*,
|
||||
zz_sys_data_perm_menu.*
|
||||
FROM
|
||||
zz_sys_data_perm_user
|
||||
INNER JOIN
|
||||
zz_sys_data_perm ON zz_sys_data_perm_user.data_perm_id = zz_sys_data_perm.data_perm_id
|
||||
LEFT JOIN
|
||||
zz_sys_data_perm_dept ON zz_sys_data_perm.data_perm_id = zz_sys_data_perm_dept.data_perm_id
|
||||
LEFT JOIN
|
||||
zz_sys_data_perm_menu ON zz_sys_data_perm.data_perm_id = zz_sys_data_perm_menu.data_perm_id
|
||||
<where>
|
||||
AND zz_sys_data_perm_user.user_id = #{userId}
|
||||
</where>
|
||||
</select>
|
||||
|
||||
<select id="getSysDataPermListByMenuId" resultMap="BaseResultMap" parameterType="com.orangeforms.webadmin.upms.model.SysDataPerm">
|
||||
SELECT
|
||||
zz_sys_data_perm.*
|
||||
FROM
|
||||
zz_sys_data_perm,
|
||||
zz_sys_data_perm_menu
|
||||
<where>
|
||||
zz_sys_data_perm.data_perm_id = zz_sys_data_perm_menu.data_perm_id
|
||||
AND zz_sys_data_perm_menu.menu_id = #{menuId}
|
||||
</where>
|
||||
</select>
|
||||
</mapper>
|
||||
@@ -0,0 +1,8 @@
|
||||
<?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="com.orangeforms.webadmin.upms.dao.SysDataPermMenuMapper">
|
||||
<resultMap id="BaseResultMap" type="com.orangeforms.webadmin.upms.model.SysDataPermMenu">
|
||||
<id column="data_perm_id" jdbcType="BIGINT" property="dataPermId"/>
|
||||
<id column="menu_id" jdbcType="BIGINT" property="menuId"/>
|
||||
</resultMap>
|
||||
</mapper>
|
||||
@@ -0,0 +1,8 @@
|
||||
<?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="com.orangeforms.webadmin.upms.dao.SysDataPermUserMapper">
|
||||
<resultMap id="BaseResultMap" type="com.orangeforms.webadmin.upms.model.SysDataPermUser">
|
||||
<id column="data_perm_id" jdbcType="BIGINT" property="dataPermId"/>
|
||||
<id column="user_id" jdbcType="BIGINT" property="userId"/>
|
||||
</resultMap>
|
||||
</mapper>
|
||||
@@ -0,0 +1,70 @@
|
||||
<?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="com.orangeforms.webadmin.upms.dao.SysDeptMapper">
|
||||
<resultMap id="BaseResultMap" type="com.orangeforms.webadmin.upms.model.SysDept">
|
||||
<id column="dept_id" jdbcType="BIGINT" property="deptId"/>
|
||||
<result column="dept_name" jdbcType="VARCHAR" property="deptName"/>
|
||||
<result column="show_order" jdbcType="INTEGER" property="showOrder"/>
|
||||
<result column="parent_id" jdbcType="BIGINT" property="parentId"/>
|
||||
<result column="deleted_flag" jdbcType="INTEGER" property="deletedFlag"/>
|
||||
<result column="create_user_id" jdbcType="BIGINT" property="createUserId"/>
|
||||
<result column="update_user_id" jdbcType="BIGINT" property="updateUserId"/>
|
||||
<result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
|
||||
<result column="update_time" jdbcType="TIMESTAMP" property="updateTime"/>
|
||||
</resultMap>
|
||||
|
||||
<insert id="insertList">
|
||||
INSERT INTO zz_sys_dept
|
||||
(dept_id,
|
||||
dept_name,
|
||||
show_order,
|
||||
parent_id,
|
||||
deleted_flag,
|
||||
create_user_id,
|
||||
update_user_id,
|
||||
create_time,
|
||||
update_time)
|
||||
VALUES
|
||||
<foreach collection="list" index="index" item="item" separator="," >
|
||||
(#{item.deptId},
|
||||
#{item.deptName},
|
||||
#{item.showOrder},
|
||||
#{item.parentId},
|
||||
#{item.deletedFlag},
|
||||
#{item.createUserId},
|
||||
#{item.updateUserId},
|
||||
#{item.createTime},
|
||||
#{item.updateTime})
|
||||
</foreach>
|
||||
</insert>
|
||||
|
||||
<!-- 如果有逻辑删除字段过滤,请写到这里 -->
|
||||
<sql id="filterRef">
|
||||
<!-- 这里必须加上全包名,否则当filterRef被其他Mapper.xml包含引用的时候,就会调用Mapper.xml中的该SQL片段 -->
|
||||
<include refid="com.orangeforms.webadmin.upms.dao.SysDeptMapper.inputFilterRef"/>
|
||||
AND zz_sys_dept.deleted_flag = ${@com.orangeforms.common.core.constant.GlobalDeletedFlag@NORMAL}
|
||||
</sql>
|
||||
|
||||
<!-- 这里仅包含调用接口输入的主表过滤条件 -->
|
||||
<sql id="inputFilterRef">
|
||||
<if test="sysDeptFilter != null">
|
||||
<if test="sysDeptFilter.deptName != null and sysDeptFilter.deptName != ''">
|
||||
<bind name = "safeSysDeptDeptName" value = "'%' + sysDeptFilter.deptName + '%'" />
|
||||
AND zz_sys_dept.dept_name LIKE #{safeSysDeptDeptName}
|
||||
</if>
|
||||
<if test="sysDeptFilter.parentId != null">
|
||||
AND zz_sys_dept.parent_id = #{sysDeptFilter.parentId}
|
||||
</if>
|
||||
</if>
|
||||
</sql>
|
||||
|
||||
<select id="getSysDeptList" resultMap="BaseResultMap" parameterType="com.orangeforms.webadmin.upms.model.SysDept">
|
||||
SELECT * FROM zz_sys_dept
|
||||
<where>
|
||||
<include refid="filterRef"/>
|
||||
</where>
|
||||
<if test="orderBy != null and orderBy != ''">
|
||||
ORDER BY ${orderBy}
|
||||
</if>
|
||||
</select>
|
||||
</mapper>
|
||||
@@ -0,0 +1,46 @@
|
||||
<?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="com.orangeforms.webadmin.upms.dao.SysDeptPostMapper">
|
||||
<resultMap id="BaseResultMap" type="com.orangeforms.webadmin.upms.model.SysDeptPost">
|
||||
<id column="dept_post_id" jdbcType="BIGINT" property="deptPostId"/>
|
||||
<result column="dept_id" jdbcType="BIGINT" property="deptId"/>
|
||||
<result column="post_id" jdbcType="BIGINT" property="postId"/>
|
||||
<result column="post_show_name" jdbcType="VARCHAR" property="postShowName"/>
|
||||
</resultMap>
|
||||
|
||||
<select id="getSysDeptPostListWithRelationByDeptId" resultType="map">
|
||||
SELECT
|
||||
a.dept_post_id deptPostId,
|
||||
a.dept_id deptId,
|
||||
a.post_id postId,
|
||||
a.post_show_name postShowName,
|
||||
b.dept_name deptName,
|
||||
c.post_level postLevel,
|
||||
c.leader_post leaderPost
|
||||
FROM
|
||||
zz_sys_dept_post a,
|
||||
zz_sys_dept b,
|
||||
zz_sys_post c
|
||||
<where>
|
||||
a.dept_id = b.dept_id
|
||||
AND a.post_id = c.post_id
|
||||
<if test="deptId != null">
|
||||
AND a.dept_id = #{deptId}
|
||||
</if>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
<select id="getLeaderDeptPostList" resultMap="BaseResultMap">
|
||||
SELECT
|
||||
a.*
|
||||
FROM
|
||||
zz_sys_dept_post a,
|
||||
zz_sys_post b
|
||||
WHERE
|
||||
a.post_id = b.post_id
|
||||
AND b.leader_post = 1
|
||||
AND a.dept_id = #{deptId}
|
||||
ORDER BY
|
||||
b.post_level
|
||||
</select>
|
||||
</mapper>
|
||||
@@ -0,0 +1,32 @@
|
||||
<?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="com.orangeforms.webadmin.upms.dao.SysDeptRelationMapper">
|
||||
<resultMap id="BaseResultMap" type="com.orangeforms.webadmin.upms.model.SysDeptRelation">
|
||||
<id column="parent_dept_id" jdbcType="BIGINT" property="parentDeptId"/>
|
||||
<id column="dept_id" jdbcType="BIGINT" property="deptId"/>
|
||||
</resultMap>
|
||||
|
||||
<delete id="removeBetweenChildrenAndParents">
|
||||
DELETE a FROM zz_sys_dept_relation a
|
||||
INNER JOIN zz_sys_dept_relation b ON a.dept_id = b.dept_id
|
||||
WHERE b.parent_dept_id = #{myDeptId} AND a.parent_dept_id IN
|
||||
<foreach collection="parentDeptIds" index="index" item="item" separator="," open="(" close=")">
|
||||
#{item}
|
||||
</foreach>
|
||||
</delete>
|
||||
|
||||
<insert id="insertList">
|
||||
INSERT INTO zz_sys_dept_relation(parent_dept_id, dept_id) VALUES
|
||||
<foreach collection="list" index="index" item="item" separator=",">
|
||||
(#{item.parentDeptId}, #{item.deptId})
|
||||
</foreach>
|
||||
</insert>
|
||||
|
||||
<insert id="insertParentList">
|
||||
INSERT INTO zz_sys_dept_relation(parent_dept_id, dept_id)
|
||||
SELECT t.parent_dept_id, #{myDeptId} FROM zz_sys_dept_relation t
|
||||
WHERE t.dept_id = #{parentDeptId}
|
||||
UNION ALL
|
||||
SELECT #{myDeptId}, #{myDeptId}
|
||||
</insert>
|
||||
</mapper>
|
||||
@@ -0,0 +1,58 @@
|
||||
<?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="com.orangeforms.webadmin.upms.dao.SysMenuMapper">
|
||||
<resultMap id="BaseResultMap" type="com.orangeforms.webadmin.upms.model.SysMenu">
|
||||
<id column="menu_id" jdbcType="BIGINT" property="menuId"/>
|
||||
<result column="parent_id" jdbcType="BIGINT" property="parentId"/>
|
||||
<result column="menu_name" jdbcType="VARCHAR" property="menuName"/>
|
||||
<result column="menu_type" jdbcType="INTEGER" property="menuType"/>
|
||||
<result column="form_router_name" jdbcType="VARCHAR" property="formRouterName"/>
|
||||
<result column="online_form_id" jdbcType="BIGINT" property="onlineFormId"/>
|
||||
<result column="online_menu_perm_type" jdbcType="INTEGER" property="onlineMenuPermType"/>
|
||||
<result column="report_page_id" jdbcType="BIGINT" property="reportPageId"/>
|
||||
<result column="online_flow_entry_id" jdbcType="BIGINT" property="onlineFlowEntryId"/>
|
||||
<result column="show_order" jdbcType="INTEGER" property="showOrder"/>
|
||||
<result column="icon" jdbcType="VARCHAR" property="icon"/>
|
||||
<result column="extra_data" jdbcType="VARCHAR" property="extraData"/>
|
||||
<result column="create_user_id" jdbcType="BIGINT" property="createUserId"/>
|
||||
<result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
|
||||
<result column="update_user_id" jdbcType="BIGINT" property="updateUserId"/>
|
||||
<result column="update_time" jdbcType="TIMESTAMP" property="updateTime"/>
|
||||
</resultMap>
|
||||
|
||||
<select id="getMenuListByUserId" resultMap="BaseResultMap">
|
||||
SELECT
|
||||
m.*
|
||||
FROM
|
||||
zz_sys_user_role ur,
|
||||
zz_sys_role_menu rm,
|
||||
zz_sys_menu m
|
||||
<where>
|
||||
AND ur.user_id = #{userId}
|
||||
AND ur.role_id = rm.role_id
|
||||
AND rm.menu_id = m.menu_id
|
||||
</where>
|
||||
ORDER BY m.show_order
|
||||
</select>
|
||||
|
||||
<select id="getMenuListByRoleIds" resultMap="BaseResultMap">
|
||||
SELECT
|
||||
m.*
|
||||
FROM
|
||||
zz_sys_role_menu rm,
|
||||
zz_sys_menu m
|
||||
<where>
|
||||
rm.role_id IN
|
||||
<foreach collection="roleIds" item="item" separator="," open="(" close=")">
|
||||
#{item}
|
||||
</foreach>
|
||||
AND rm.menu_id = m.menu_id
|
||||
</where>
|
||||
ORDER BY m.show_order
|
||||
</select>
|
||||
|
||||
<select id="countMenuCode" resultType="java.lang.Integer">
|
||||
<bind name= "safeMenuCode" value= "'%' + menuCode + '%'"/>
|
||||
SELECT COUNT(*) FROM zz_sys_menu WHERE extra_data LIKE #{safeMenuCode}
|
||||
</select>
|
||||
</mapper>
|
||||
@@ -0,0 +1,9 @@
|
||||
<?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="com.orangeforms.webadmin.upms.dao.SysPermWhitelistMapper">
|
||||
<resultMap id="BaseResultMap" type="com.orangeforms.webadmin.upms.model.SysPermWhitelist">
|
||||
<id column="perm_url" jdbcType="VARCHAR" property="permUrl"/>
|
||||
<result column="module_name" jdbcType="VARCHAR" property="moduleName"/>
|
||||
<result column="perm_name" jdbcType="VARCHAR" property="permName"/>
|
||||
</resultMap>
|
||||
</mapper>
|
||||
@@ -0,0 +1,80 @@
|
||||
<?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="com.orangeforms.webadmin.upms.dao.SysPostMapper">
|
||||
<resultMap id="BaseResultMap" type="com.orangeforms.webadmin.upms.model.SysPost">
|
||||
<id column="post_id" jdbcType="BIGINT" property="postId"/>
|
||||
<result column="post_name" jdbcType="VARCHAR" property="postName"/>
|
||||
<result column="post_level" jdbcType="INTEGER" property="postLevel"/>
|
||||
<result column="leader_post" jdbcType="BOOLEAN" property="leaderPost"/>
|
||||
<result column="create_user_id" jdbcType="BIGINT" property="createUserId"/>
|
||||
<result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
|
||||
<result column="update_user_id" jdbcType="BIGINT" property="updateUserId"/>
|
||||
<result column="update_time" jdbcType="TIMESTAMP" property="updateTime"/>
|
||||
</resultMap>
|
||||
|
||||
<resultMap id="BaseResultMapWithSysDeptPost" type="com.orangeforms.webadmin.upms.model.SysPost" extends="BaseResultMap">
|
||||
<association property="sysDeptPost" column="post_id" foreignColumn="post_id"
|
||||
notNullColumn="post_id" resultMap="com.orangeforms.webadmin.upms.dao.SysDeptPostMapper.BaseResultMap" />
|
||||
</resultMap>
|
||||
|
||||
<!-- 如果有逻辑删除字段过滤,请写到这里 -->
|
||||
<sql id="filterRef">
|
||||
<!-- 这里必须加上全包名,否则当filterRef被其他Mapper.xml包含引用的时候,就会调用Mapper.xml中的该SQL片段 -->
|
||||
<include refid="com.orangeforms.webadmin.upms.dao.SysPostMapper.inputFilterRef"/>
|
||||
</sql>
|
||||
|
||||
<!-- 这里仅包含调用接口输入的主表过滤条件 -->
|
||||
<sql id="inputFilterRef">
|
||||
<if test="sysPostFilter != null">
|
||||
<if test="sysPostFilter.postName != null and sysPostFilter.postName != ''">
|
||||
<bind name = "safeSysPostPostName" value = "'%' + sysPostFilter.postName + '%'" />
|
||||
AND zz_sys_post.post_name LIKE #{safeSysPostPostName}
|
||||
</if>
|
||||
<if test="sysPostFilter.leaderPost != null">
|
||||
AND zz_sys_post.leader_post = #{sysPostFilter.leaderPost}
|
||||
</if>
|
||||
</if>
|
||||
</sql>
|
||||
|
||||
<select id="getSysPostList" resultMap="BaseResultMap" parameterType="com.orangeforms.webadmin.upms.model.SysPost">
|
||||
SELECT * FROM zz_sys_post
|
||||
<where>
|
||||
<include refid="filterRef"/>
|
||||
</where>
|
||||
<if test="orderBy != null and orderBy != ''">
|
||||
ORDER BY ${orderBy}
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<select id="getSysPostListByDeptId" resultMap="BaseResultMapWithSysDeptPost">
|
||||
SELECT
|
||||
zz_sys_post.*,
|
||||
zz_sys_dept_post.*
|
||||
FROM
|
||||
zz_sys_post,
|
||||
zz_sys_dept_post
|
||||
<where>
|
||||
AND zz_sys_dept_post.dept_id = #{deptId}
|
||||
AND zz_sys_dept_post.post_id = zz_sys_post.post_id
|
||||
<include refid="filterRef"/>
|
||||
</where>
|
||||
<if test="orderBy != null and orderBy != ''">
|
||||
ORDER BY ${orderBy}
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<select id="getNotInSysPostListByDeptId" resultMap="BaseResultMap">
|
||||
SELECT
|
||||
zz_sys_post.*
|
||||
FROM
|
||||
zz_sys_post
|
||||
<where>
|
||||
AND NOT EXISTS (SELECT * FROM zz_sys_dept_post
|
||||
WHERE zz_sys_dept_post.dept_id = #{deptId} AND zz_sys_dept_post.post_id = zz_sys_post.post_id)
|
||||
<include refid="filterRef"/>
|
||||
</where>
|
||||
<if test="orderBy != null and orderBy != ''">
|
||||
ORDER BY ${orderBy}
|
||||
</if>
|
||||
</select>
|
||||
</mapper>
|
||||
@@ -0,0 +1,31 @@
|
||||
<?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="com.orangeforms.webadmin.upms.dao.SysRoleMapper">
|
||||
<resultMap id="BaseResultMap" type="com.orangeforms.webadmin.upms.model.SysRole">
|
||||
<id column="role_id" jdbcType="BIGINT" property="roleId"/>
|
||||
<result column="role_name" jdbcType="VARCHAR" property="roleName"/>
|
||||
<result column="create_user_id" jdbcType="BIGINT" property="createUserId"/>
|
||||
<result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
|
||||
<result column="update_user_id" jdbcType="BIGINT" property="updateUserId"/>
|
||||
<result column="update_time" jdbcType="TIMESTAMP" property="updateTime"/>
|
||||
</resultMap>
|
||||
|
||||
<sql id="filterRef">
|
||||
<if test="sysRoleFilter != null">
|
||||
<if test="sysRoleFilter.roleName != null and sysRoleFilter.roleName != ''">
|
||||
<bind name= "safeRoleName" value= "'%' + sysRoleFilter.roleName + '%'"/>
|
||||
AND role_name LIKE #{safeRoleName}
|
||||
</if>
|
||||
</if>
|
||||
</sql>
|
||||
|
||||
<select id="getSysRoleList" resultMap="BaseResultMap" parameterType="com.orangeforms.webadmin.upms.model.SysRole">
|
||||
SELECT * FROM zz_sys_role
|
||||
<where>
|
||||
<include refid="filterRef"/>
|
||||
</where>
|
||||
<if test="orderBy != null and orderBy != ''">
|
||||
ORDER BY ${orderBy}
|
||||
</if>
|
||||
</select>
|
||||
</mapper>
|
||||
@@ -0,0 +1,8 @@
|
||||
<?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="com.orangeforms.webadmin.upms.dao.SysRoleMenuMapper">
|
||||
<resultMap id="BaseResultMap" type="com.orangeforms.webadmin.upms.model.SysRoleMenu">
|
||||
<id column="role_id" jdbcType="BIGINT" property="roleId"/>
|
||||
<id column="menu_id" jdbcType="BIGINT" property="menuId"/>
|
||||
</resultMap>
|
||||
</mapper>
|
||||
@@ -0,0 +1,294 @@
|
||||
<?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="com.orangeforms.webadmin.upms.dao.SysUserMapper">
|
||||
<resultMap id="BaseResultMap" type="com.orangeforms.webadmin.upms.model.SysUser">
|
||||
<id column="user_id" jdbcType="BIGINT" property="userId"/>
|
||||
<result column="login_name" jdbcType="VARCHAR" property="loginName"/>
|
||||
<result column="password" jdbcType="VARCHAR" property="password"/>
|
||||
<result column="dept_id" jdbcType="BIGINT" property="deptId"/>
|
||||
<result column="show_name" jdbcType="VARCHAR" property="showName"/>
|
||||
<result column="user_type" jdbcType="INTEGER" property="userType"/>
|
||||
<result column="head_image_url" jdbcType="VARCHAR" property="headImageUrl"/>
|
||||
<result column="user_status" jdbcType="INTEGER" property="userStatus"/>
|
||||
<result column="email" jdbcType="VARCHAR" property="email"/>
|
||||
<result column="mobile" jdbcType="VARCHAR" property="mobile"/>
|
||||
<result column="create_user_id" jdbcType="BIGINT" property="createUserId"/>
|
||||
<result column="update_user_id" jdbcType="BIGINT" property="updateUserId"/>
|
||||
<result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
|
||||
<result column="update_time" jdbcType="TIMESTAMP" property="updateTime"/>
|
||||
<result column="deleted_flag" jdbcType="INTEGER" property="deletedFlag"/>
|
||||
</resultMap>
|
||||
|
||||
<insert id="insertList">
|
||||
INSERT INTO zz_sys_user
|
||||
(user_id,
|
||||
login_name,
|
||||
password,
|
||||
dept_id,
|
||||
show_name,
|
||||
user_type,
|
||||
head_image_url,
|
||||
user_status,
|
||||
email,
|
||||
mobile,
|
||||
create_user_id,
|
||||
update_user_id,
|
||||
create_time,
|
||||
update_time,
|
||||
deleted_flag)
|
||||
VALUES
|
||||
<foreach collection="list" index="index" item="item" separator="," >
|
||||
(#{item.userId},
|
||||
#{item.loginName},
|
||||
#{item.password},
|
||||
#{item.deptId},
|
||||
#{item.showName},
|
||||
#{item.userType},
|
||||
#{item.headImageUrl},
|
||||
#{item.userStatus},
|
||||
#{item.email},
|
||||
#{item.mobile},
|
||||
#{item.createUserId},
|
||||
#{item.updateUserId},
|
||||
#{item.createTime},
|
||||
#{item.updateTime},
|
||||
#{item.deletedFlag})
|
||||
</foreach>
|
||||
</insert>
|
||||
|
||||
<!-- 如果有逻辑删除字段过滤,请写到这里 -->
|
||||
<sql id="filterRef">
|
||||
<!-- 这里必须加上全包名,否则当filterRef被其他Mapper.xml包含引用的时候,就会调用Mapper.xml中的该SQL片段 -->
|
||||
<include refid="com.orangeforms.webadmin.upms.dao.SysUserMapper.inputFilterRef"/>
|
||||
AND zz_sys_user.deleted_flag = ${@com.orangeforms.common.core.constant.GlobalDeletedFlag@NORMAL}
|
||||
</sql>
|
||||
|
||||
<!-- 这里仅包含调用接口输入的主表过滤条件 -->
|
||||
<sql id="inputFilterRef">
|
||||
<if test="sysUserFilter != null">
|
||||
<if test="sysUserFilter.loginName != null and sysUserFilter.loginName != ''">
|
||||
<bind name = "safeSysUserLoginName" value = "'%' + sysUserFilter.loginName + '%'" />
|
||||
AND zz_sys_user.login_name LIKE #{safeSysUserLoginName}
|
||||
</if>
|
||||
<if test="sysUserFilter.deptId != null">
|
||||
AND (EXISTS (SELECT 1 FROM zz_sys_dept_relation WHERE
|
||||
zz_sys_dept_relation.parent_dept_id = #{sysUserFilter.deptId}
|
||||
AND zz_sys_user.dept_id = zz_sys_dept_relation.dept_id))
|
||||
</if>
|
||||
<if test="sysUserFilter.showName != null and sysUserFilter.showName != ''">
|
||||
<bind name = "safeSysUserShowName" value = "'%' + sysUserFilter.showName + '%'" />
|
||||
AND zz_sys_user.show_name LIKE #{safeSysUserShowName}
|
||||
</if>
|
||||
<if test="sysUserFilter.userStatus != null">
|
||||
AND zz_sys_user.user_status = #{sysUserFilter.userStatus}
|
||||
</if>
|
||||
<if test="sysUserFilter.createTimeStart != null and sysUserFilter.createTimeStart != ''">
|
||||
AND zz_sys_user.create_time >= #{sysUserFilter.createTimeStart}
|
||||
</if>
|
||||
<if test="sysUserFilter.createTimeEnd != null and sysUserFilter.createTimeEnd != ''">
|
||||
AND zz_sys_user.create_time <= #{sysUserFilter.createTimeEnd}
|
||||
</if>
|
||||
</if>
|
||||
</sql>
|
||||
|
||||
<select id="getSysUserList" resultMap="BaseResultMap" parameterType="com.orangeforms.webadmin.upms.model.SysUser">
|
||||
SELECT * FROM zz_sys_user
|
||||
<where>
|
||||
<include refid="filterRef"/>
|
||||
</where>
|
||||
<if test="orderBy != null and orderBy != ''">
|
||||
ORDER BY ${orderBy}
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<select id="getSysUserListByDeptIds" resultMap="BaseResultMap">
|
||||
SELECT * FROM zz_sys_user
|
||||
<where>
|
||||
<if test="deptIds != null">
|
||||
AND (EXISTS (SELECT 1 FROM zz_sys_dept_relation WHERE
|
||||
zz_sys_dept_relation.parent_dept_id IN
|
||||
<foreach collection="deptIds" item="item" separator="," open="(" close=")">
|
||||
#{item}
|
||||
</foreach>
|
||||
AND zz_sys_user.dept_id = zz_sys_dept_relation.dept_id))
|
||||
</if>
|
||||
<include refid="filterRef"/>
|
||||
</where>
|
||||
<if test="orderBy != null and orderBy != ''">
|
||||
ORDER BY ${orderBy}
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<select id="getSysUserListByLoginNames" resultMap="BaseResultMap">
|
||||
SELECT * FROM zz_sys_user
|
||||
<where>
|
||||
<if test="loginNames != null">
|
||||
AND zz_sys_user.login_name IN
|
||||
<foreach collection="loginNames" item="item" separator="," open="(" close=")">
|
||||
#{item}
|
||||
</foreach>
|
||||
</if>
|
||||
<include refid="filterRef"/>
|
||||
</where>
|
||||
<if test="orderBy != null and orderBy != ''">
|
||||
ORDER BY ${orderBy}
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<select id="getUserIdListByRoleIds" resultType="java.lang.Long">
|
||||
SELECT
|
||||
DISTINCT zz_sys_user.user_id
|
||||
FROM
|
||||
zz_sys_user_role,
|
||||
zz_sys_user
|
||||
<where>
|
||||
AND zz_sys_user_role.role_id IN
|
||||
<foreach collection="roleIds" item="item" separator="," open="(" close=")">
|
||||
#{item}
|
||||
</foreach>
|
||||
AND zz_sys_user_role.user_id = zz_sys_user.user_id
|
||||
<include refid="filterRef"/>
|
||||
</where>
|
||||
<if test="orderBy != null and orderBy != ''">
|
||||
ORDER BY ${orderBy}
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<select id="getSysUserListByRoleId" resultMap="BaseResultMap">
|
||||
SELECT
|
||||
zz_sys_user.*
|
||||
FROM
|
||||
zz_sys_user_role,
|
||||
zz_sys_user
|
||||
<where>
|
||||
AND zz_sys_user_role.role_id = #{roleId}
|
||||
AND zz_sys_user_role.user_id = zz_sys_user.user_id
|
||||
<include refid="filterRef"/>
|
||||
</where>
|
||||
<if test="orderBy != null and orderBy != ''">
|
||||
ORDER BY ${orderBy}
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<select id="getNotInSysUserListByRoleId" resultMap="BaseResultMap">
|
||||
SELECT * FROM zz_sys_user
|
||||
<where>
|
||||
NOT EXISTS (SELECT * FROM zz_sys_user_role
|
||||
WHERE zz_sys_user_role.role_id = #{roleId} AND zz_sys_user_role.user_id = zz_sys_user.user_id)
|
||||
<include refid="filterRef"/>
|
||||
</where>
|
||||
<if test="orderBy != null and orderBy != ''">
|
||||
ORDER BY ${orderBy}
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<select id="getSysUserListByDataPermId" resultMap="BaseResultMap">
|
||||
SELECT
|
||||
zz_sys_user.*
|
||||
FROM
|
||||
zz_sys_data_perm_user,
|
||||
zz_sys_user
|
||||
<where>
|
||||
AND zz_sys_data_perm_user.data_perm_id = #{dataPermId}
|
||||
AND zz_sys_data_perm_user.user_id = zz_sys_user.user_id
|
||||
<include refid="filterRef"/>
|
||||
</where>
|
||||
<if test="orderBy != null and orderBy != ''">
|
||||
ORDER BY ${orderBy}
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<select id="getNotInSysUserListByDataPermId" resultMap="BaseResultMap">
|
||||
SELECT * FROM zz_sys_user
|
||||
<where>
|
||||
NOT EXISTS (SELECT * FROM zz_sys_data_perm_user
|
||||
WHERE zz_sys_data_perm_user.data_perm_id = #{dataPermId} AND zz_sys_data_perm_user.user_id = zz_sys_user.user_id)
|
||||
<include refid="filterRef"/>
|
||||
</where>
|
||||
<if test="orderBy != null and orderBy != ''">
|
||||
ORDER BY ${orderBy}
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<select id="getUserIdListByDeptPostIds" resultType="java.lang.Long">
|
||||
SELECT
|
||||
DISTINCT zz_sys_user.user_id
|
||||
FROM
|
||||
zz_sys_user_post,
|
||||
zz_sys_user
|
||||
<where>
|
||||
AND zz_sys_user_post.dept_post_id IN
|
||||
<foreach collection="deptPostIds" item="item" separator="," open="(" close=")">
|
||||
#{item}
|
||||
</foreach>
|
||||
AND zz_sys_user_post.user_id = zz_sys_user.user_id
|
||||
<include refid="filterRef"/>
|
||||
</where>
|
||||
<if test="orderBy != null and orderBy != ''">
|
||||
ORDER BY ${orderBy}
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<select id="getSysUserListByDeptPostId" resultMap="BaseResultMap">
|
||||
SELECT
|
||||
zz_sys_user.*
|
||||
FROM
|
||||
zz_sys_user_post,
|
||||
zz_sys_user
|
||||
<where>
|
||||
AND zz_sys_user_post.dept_post_id = #{deptPostId}
|
||||
AND zz_sys_user_post.user_id = zz_sys_user.user_id
|
||||
<include refid="filterRef"/>
|
||||
</where>
|
||||
<if test="orderBy != null and orderBy != ''">
|
||||
ORDER BY ${orderBy}
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<select id="getNotInSysUserListByDeptPostId" resultMap="BaseResultMap">
|
||||
SELECT * FROM zz_sys_user
|
||||
<where>
|
||||
NOT EXISTS (SELECT * FROM zz_sys_user_post
|
||||
WHERE zz_sys_user_post.dept_post_id = #{deptPostId} AND zz_sys_user_post.user_id = zz_sys_user.user_id)
|
||||
<include refid="filterRef"/>
|
||||
</where>
|
||||
<if test="orderBy != null and orderBy != ''">
|
||||
ORDER BY ${orderBy}
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<select id="getUserIdListByPostIds" resultType="java.lang.Long">
|
||||
SELECT
|
||||
DISTINCT zz_sys_user.user_id
|
||||
FROM
|
||||
zz_sys_user_post,
|
||||
zz_sys_user
|
||||
<where>
|
||||
AND zz_sys_user_post.post_id IN
|
||||
<foreach collection="postIds" item="item" separator="," open="(" close=")">
|
||||
#{item}
|
||||
</foreach>
|
||||
AND zz_sys_user_post.user_id = zz_sys_user.user_id
|
||||
<include refid="filterRef"/>
|
||||
</where>
|
||||
<if test="orderBy != null and orderBy != ''">
|
||||
ORDER BY ${orderBy}
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<select id="getSysUserListByPostId" resultMap="BaseResultMap">
|
||||
SELECT
|
||||
zz_sys_user.*
|
||||
FROM
|
||||
zz_sys_user_post,
|
||||
zz_sys_user
|
||||
<where>
|
||||
AND zz_sys_user_post.post_id = #{postId}
|
||||
AND zz_sys_user_post.user_id = zz_sys_user.user_id
|
||||
<include refid="filterRef"/>
|
||||
</where>
|
||||
<if test="orderBy != null and orderBy != ''">
|
||||
ORDER BY ${orderBy}
|
||||
</if>
|
||||
</select>
|
||||
</mapper>
|
||||
@@ -0,0 +1,9 @@
|
||||
<?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="com.orangeforms.webadmin.upms.dao.SysUserPostMapper">
|
||||
<resultMap id="BaseResultMap" type="com.orangeforms.webadmin.upms.model.SysUserPost">
|
||||
<id column="user_id" jdbcType="BIGINT" property="userId"/>
|
||||
<id column="dept_post_id" jdbcType="BIGINT" property="deptPostId"/>
|
||||
<id column="post_id" jdbcType="BIGINT" property="postId"/>
|
||||
</resultMap>
|
||||
</mapper>
|
||||
@@ -0,0 +1,8 @@
|
||||
<?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="com.orangeforms.webadmin.upms.dao.SysUserRoleMapper">
|
||||
<resultMap id="BaseResultMap" type="com.orangeforms.webadmin.upms.model.SysUserRole">
|
||||
<id column="user_id" jdbcType="BIGINT" property="userId"/>
|
||||
<id column="role_id" jdbcType="BIGINT" property="roleId"/>
|
||||
</resultMap>
|
||||
</mapper>
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.orangeforms.webadmin.upms.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 数据权限与部门关联Dto。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
@Schema(description = "数据权限与部门关联Dto")
|
||||
@Data
|
||||
public class SysDataPermDeptDto {
|
||||
|
||||
/**
|
||||
* 数据权限Id。
|
||||
*/
|
||||
@Schema(description = "数据权限Id", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private Long dataPermId;
|
||||
|
||||
/**
|
||||
* 关联部门Id。
|
||||
*/
|
||||
@Schema(description = "关联部门Id", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private Long deptId;
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package com.orangeforms.webadmin.upms.dto;
|
||||
|
||||
import com.orangeforms.common.core.validator.UpdateGroup;
|
||||
import com.orangeforms.common.core.validator.ConstDictRef;
|
||||
import com.orangeforms.common.core.constant.DataPermRuleType;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import jakarta.validation.constraints.*;
|
||||
|
||||
/**
|
||||
* 数据权限Dto。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
@Schema(description = "数据权限Dto")
|
||||
@Data
|
||||
public class SysDataPermDto {
|
||||
|
||||
/**
|
||||
* 数据权限Id。
|
||||
*/
|
||||
@Schema(description = "数据权限Id", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "数据权限Id不能为空!", groups = {UpdateGroup.class})
|
||||
private Long dataPermId;
|
||||
|
||||
/**
|
||||
* 显示名称。
|
||||
*/
|
||||
@Schema(description = "显示名称", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotBlank(message = "数据权限名称不能为空!")
|
||||
private String dataPermName;
|
||||
|
||||
/**
|
||||
* 数据权限规则类型(0: 全部可见 1: 只看自己 2: 只看本部门 3: 本部门及子部门 4: 多部门及子部门 5: 自定义部门列表)。
|
||||
*/
|
||||
@Schema(description = "数据权限规则类型", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "数据权限规则类型不能为空!")
|
||||
@ConstDictRef(constDictClass = DataPermRuleType.class)
|
||||
private Integer ruleType;
|
||||
|
||||
/**
|
||||
* 部门Id列表(逗号分隔)。
|
||||
*/
|
||||
@Schema(hidden = true)
|
||||
private String deptIdListString;
|
||||
|
||||
/**
|
||||
* 搜索字符串。
|
||||
*/
|
||||
@Schema(description = "LIKE 模糊搜索字符串")
|
||||
private String searchString;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.orangeforms.webadmin.upms.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 数据权限与菜单关联Dto。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
@Schema(description = "数据权限与菜单关联Dto")
|
||||
@Data
|
||||
public class SysDataPermMenuDto {
|
||||
|
||||
/**
|
||||
* 数据权限Id。
|
||||
*/
|
||||
@Schema(description = "数据权限Id", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private Long dataPermId;
|
||||
|
||||
/**
|
||||
* 关联菜单Id。
|
||||
*/
|
||||
@Schema(description = "关联菜单Id", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private Long menuId;
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.orangeforms.webadmin.upms.dto;
|
||||
|
||||
import com.orangeforms.common.core.validator.UpdateGroup;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import jakarta.validation.constraints.*;
|
||||
|
||||
/**
|
||||
* 部门管理Dto对象。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
@Schema(description = "SysDeptDto对象")
|
||||
@Data
|
||||
public class SysDeptDto {
|
||||
|
||||
/**
|
||||
* 部门Id。
|
||||
*/
|
||||
@Schema(description = "部门Id。", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "数据验证失败,部门Id不能为空!", groups = {UpdateGroup.class})
|
||||
private Long deptId;
|
||||
|
||||
/**
|
||||
* 部门名称。
|
||||
* NOTE: 可支持等于操作符的列表数据过滤。
|
||||
*/
|
||||
@Schema(description = "部门名称。可支持等于操作符的列表数据过滤。", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotBlank(message = "数据验证失败,部门名称不能为空!")
|
||||
private String deptName;
|
||||
|
||||
/**
|
||||
* 显示顺序。
|
||||
*/
|
||||
@Schema(description = "显示顺序。", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "数据验证失败,显示顺序不能为空!")
|
||||
private Integer showOrder;
|
||||
|
||||
/**
|
||||
* 父部门Id。
|
||||
* NOTE: 可支持等于操作符的列表数据过滤。
|
||||
*/
|
||||
@Schema(description = "父部门Id。可支持等于操作符的列表数据过滤。")
|
||||
private Long parentId;
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.orangeforms.webadmin.upms.dto;
|
||||
|
||||
import com.orangeforms.common.core.validator.UpdateGroup;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import jakarta.validation.constraints.*;
|
||||
|
||||
/**
|
||||
* 部门岗位Dto对象。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
@Schema(description = "部门岗位Dto")
|
||||
@Data
|
||||
public class SysDeptPostDto {
|
||||
|
||||
/**
|
||||
* 部门岗位Id。
|
||||
*/
|
||||
@Schema(description = "部门岗位Id", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "数据验证失败,部门岗位Id不能为空!", groups = {UpdateGroup.class})
|
||||
private Long deptPostId;
|
||||
|
||||
/**
|
||||
* 部门Id。
|
||||
*/
|
||||
@Schema(description = "部门Id", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "数据验证失败,部门Id不能为空!", groups = {UpdateGroup.class})
|
||||
private Long deptId;
|
||||
|
||||
/**
|
||||
* 岗位Id。
|
||||
*/
|
||||
@Schema(description = "岗位Id", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "数据验证失败,岗位Id不能为空!", groups = {UpdateGroup.class})
|
||||
private Long postId;
|
||||
|
||||
/**
|
||||
* 部门岗位显示名称。
|
||||
*/
|
||||
@Schema(description = "部门岗位显示名称", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotBlank(message = "数据验证失败,部门岗位显示名称不能为空!")
|
||||
private String postShowName;
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
package com.orangeforms.webadmin.upms.dto;
|
||||
|
||||
import com.orangeforms.common.core.validator.ConstDictRef;
|
||||
import com.orangeforms.common.core.validator.UpdateGroup;
|
||||
import com.orangeforms.webadmin.upms.model.constant.SysMenuType;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 菜单Dto。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
@Schema(description = "菜单Dto")
|
||||
@Data
|
||||
public class SysMenuDto {
|
||||
|
||||
/**
|
||||
* 菜单Id。
|
||||
*/
|
||||
@Schema(description = "菜单Id", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "菜单Id不能为空!", groups = {UpdateGroup.class})
|
||||
private Long menuId;
|
||||
|
||||
/**
|
||||
* 父菜单Id,目录菜单的父菜单为null
|
||||
*/
|
||||
@Schema(description = "父菜单Id")
|
||||
private Long parentId;
|
||||
|
||||
/**
|
||||
* 菜单显示名称。
|
||||
*/
|
||||
@Schema(description = "菜单显示名称", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotBlank(message = "菜单显示名称不能为空!")
|
||||
private String menuName;
|
||||
|
||||
/**
|
||||
* 菜单类型 (0: 目录 1: 菜单 2: 按钮 3: UI片段)。
|
||||
*/
|
||||
@Schema(description = "菜单类型", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "菜单类型不能为空!")
|
||||
@ConstDictRef(constDictClass = SysMenuType.class, message = "数据验证失败,菜单类型为无效值!")
|
||||
private Integer menuType;
|
||||
|
||||
/**
|
||||
* 前端表单路由名称,仅用于menu_type为1的菜单类型。
|
||||
*/
|
||||
@Schema(description = "前端表单路由名称")
|
||||
private String formRouterName;
|
||||
|
||||
/**
|
||||
* 在线表单主键Id,仅用于在线表单绑定的菜单。
|
||||
*/
|
||||
@Schema(description = "在线表单主键Id")
|
||||
private Long onlineFormId;
|
||||
|
||||
/**
|
||||
* 统计页面主键Id,仅用于统计页面绑定的菜单。
|
||||
*/
|
||||
@Schema(description = "统计页面主键Id")
|
||||
private Long reportPageId;
|
||||
|
||||
/**
|
||||
* 仅用于在线表单的流程Id。
|
||||
*/
|
||||
@Schema(description = "仅用于在线表单的流程Id")
|
||||
private Long onlineFlowEntryId;
|
||||
|
||||
/**
|
||||
* 菜单显示顺序 (值越小,排序越靠前)。
|
||||
*/
|
||||
@Schema(description = "菜单显示顺序", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "菜单显示顺序不能为空!")
|
||||
private Integer showOrder;
|
||||
|
||||
/**
|
||||
* 菜单图标。
|
||||
*/
|
||||
@Schema(description = "菜单显示图标")
|
||||
private String icon;
|
||||
|
||||
/**
|
||||
* 附加信息。
|
||||
*/
|
||||
@Schema(description = "附加信息")
|
||||
private String extraData;
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.orangeforms.webadmin.upms.dto;
|
||||
|
||||
import com.orangeforms.common.core.validator.UpdateGroup;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import jakarta.validation.constraints.*;
|
||||
|
||||
/**
|
||||
* 岗位Dto对象。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
@Schema(description = "岗位Dto")
|
||||
@Data
|
||||
public class SysPostDto {
|
||||
|
||||
/**
|
||||
* 岗位Id。
|
||||
*/
|
||||
@Schema(description = "岗位Id", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "数据验证失败,岗位Id不能为空!", groups = {UpdateGroup.class})
|
||||
private Long postId;
|
||||
|
||||
/**
|
||||
* 岗位名称。
|
||||
*/
|
||||
@Schema(description = "岗位名称", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotBlank(message = "数据验证失败,岗位名称不能为空!")
|
||||
private String postName;
|
||||
|
||||
/**
|
||||
* 岗位层级,数值越小级别越高。
|
||||
*/
|
||||
@Schema(description = "岗位层级", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "数据验证失败,岗位层级不能为空!")
|
||||
private Integer postLevel;
|
||||
|
||||
/**
|
||||
* 是否领导岗位。
|
||||
*/
|
||||
@Schema(description = "是否领导岗位", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "数据验证失败,领导岗位不能为空!", groups = {UpdateGroup.class})
|
||||
private Boolean leaderPost;
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.orangeforms.webadmin.upms.dto;
|
||||
|
||||
import com.orangeforms.common.core.validator.UpdateGroup;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import jakarta.validation.constraints.*;
|
||||
|
||||
/**
|
||||
* 角色Dto。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
@Schema(description = "角色Dto")
|
||||
@Data
|
||||
public class SysRoleDto {
|
||||
|
||||
/**
|
||||
* 角色Id。
|
||||
*/
|
||||
@Schema(description = "角色Id", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "角色Id不能为空!", groups = {UpdateGroup.class})
|
||||
private Long roleId;
|
||||
|
||||
/**
|
||||
* 角色名称。
|
||||
*/
|
||||
@Schema(description = "角色名称", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotBlank(message = "角色名称不能为空!")
|
||||
private String roleName;
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
package com.orangeforms.webadmin.upms.dto;
|
||||
|
||||
import com.orangeforms.common.core.validator.AddGroup;
|
||||
import com.orangeforms.common.core.validator.UpdateGroup;
|
||||
import com.orangeforms.common.core.validator.ConstDictRef;
|
||||
import com.orangeforms.webadmin.upms.model.constant.SysUserType;
|
||||
import com.orangeforms.webadmin.upms.model.constant.SysUserStatus;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import jakarta.validation.constraints.*;
|
||||
|
||||
/**
|
||||
* 用户管理Dto对象。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
@Schema(description = "SysUserDto对象")
|
||||
@Data
|
||||
public class SysUserDto {
|
||||
|
||||
/**
|
||||
* 用户Id。
|
||||
*/
|
||||
@Schema(description = "用户Id。", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "数据验证失败,用户Id不能为空!", groups = {UpdateGroup.class})
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 登录用户名。
|
||||
* NOTE: 可支持等于操作符的列表数据过滤。
|
||||
*/
|
||||
@Schema(description = "登录用户名。可支持等于操作符的列表数据过滤。", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotBlank(message = "数据验证失败,登录用户名不能为空!")
|
||||
private String loginName;
|
||||
|
||||
/**
|
||||
* 用户密码。
|
||||
*/
|
||||
@Schema(description = "用户密码。", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotBlank(message = "数据验证失败,用户密码不能为空!", groups = {AddGroup.class})
|
||||
private String password;
|
||||
|
||||
/**
|
||||
* 用户部门Id。
|
||||
* NOTE: 可支持等于操作符的列表数据过滤。
|
||||
*/
|
||||
@Schema(description = "用户部门Id。可支持等于操作符的列表数据过滤。", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "数据验证失败,用户部门Id不能为空!")
|
||||
private Long deptId;
|
||||
|
||||
/**
|
||||
* 用户显示名称。
|
||||
* NOTE: 可支持等于操作符的列表数据过滤。
|
||||
*/
|
||||
@Schema(description = "用户显示名称。可支持等于操作符的列表数据过滤。", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotBlank(message = "数据验证失败,用户显示名称不能为空!")
|
||||
private String showName;
|
||||
|
||||
/**
|
||||
* 用户类型(0: 管理员 1: 系统管理用户 2: 系统业务用户)。
|
||||
*/
|
||||
@Schema(description = "用户类型(0: 管理员 1: 系统管理用户 2: 系统业务用户)。", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "数据验证失败,用户类型(0: 管理员 1: 系统管理用户 2: 系统业务用户)不能为空!")
|
||||
@ConstDictRef(constDictClass = SysUserType.class, message = "数据验证失败,用户类型(0: 管理员 1: 系统管理用户 2: 系统业务用户)为无效值!")
|
||||
private Integer userType;
|
||||
|
||||
/**
|
||||
* 用户头像的Url。
|
||||
*/
|
||||
@Schema(description = "用户头像的Url。")
|
||||
private String headImageUrl;
|
||||
|
||||
/**
|
||||
* 用户状态(0: 正常 1: 锁定)。
|
||||
* NOTE: 可支持等于操作符的列表数据过滤。
|
||||
*/
|
||||
@Schema(description = "用户状态(0: 正常 1: 锁定)。可支持等于操作符的列表数据过滤。", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "数据验证失败,用户状态(0: 正常 1: 锁定)不能为空!")
|
||||
@ConstDictRef(constDictClass = SysUserStatus.class, message = "数据验证失败,用户状态(0: 正常 1: 锁定)为无效值!")
|
||||
private Integer userStatus;
|
||||
|
||||
/**
|
||||
* 用户邮箱。
|
||||
*/
|
||||
@Schema(description = "用户邮箱。")
|
||||
private String email;
|
||||
|
||||
/**
|
||||
* 用户手机。
|
||||
*/
|
||||
@Schema(description = "用户手机。")
|
||||
private String mobile;
|
||||
|
||||
/**
|
||||
* createTime 范围过滤起始值(>=)。
|
||||
* NOTE: 可支持范围操作符的列表数据过滤。
|
||||
*/
|
||||
@Schema(description = "createTime 范围过滤起始值(>=)。可支持范围操作符的列表数据过滤。")
|
||||
private String createTimeStart;
|
||||
|
||||
/**
|
||||
* createTime 范围过滤结束值(<=)。
|
||||
* NOTE: 可支持范围操作符的列表数据过滤。
|
||||
*/
|
||||
@Schema(description = "createTime 范围过滤结束值(<=)。可支持范围操作符的列表数据过滤。")
|
||||
private String createTimeEnd;
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package com.orangeforms.webadmin.upms.model;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import com.orangeforms.common.core.util.MyCommonUtil;
|
||||
import com.orangeforms.common.core.annotation.RelationManyToMany;
|
||||
import com.orangeforms.common.core.base.model.BaseModel;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 数据权限实体对象。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName(value = "zz_sys_data_perm")
|
||||
public class SysDataPerm extends BaseModel {
|
||||
|
||||
/**
|
||||
* 主键Id。
|
||||
*/
|
||||
@TableId(value = "data_perm_id")
|
||||
private Long dataPermId;
|
||||
|
||||
/**
|
||||
* 显示名称。
|
||||
*/
|
||||
@TableField(value = "data_perm_name")
|
||||
private String dataPermName;
|
||||
|
||||
/**
|
||||
* 数据权限规则类型(0: 全部可见 1: 只看自己 2: 只看本部门 3: 本部门及子部门 4: 多部门及子部门 5: 自定义部门列表)。
|
||||
*/
|
||||
@TableField(value = "rule_type")
|
||||
private Integer ruleType;
|
||||
|
||||
@TableField(exist = false)
|
||||
private String deptIdListString;
|
||||
|
||||
@RelationManyToMany(
|
||||
relationMasterIdField = "dataPermId",
|
||||
relationModelClass = SysDataPermDept.class)
|
||||
@TableField(exist = false)
|
||||
private List<SysDataPermDept> dataPermDeptList;
|
||||
|
||||
@RelationManyToMany(
|
||||
relationMasterIdField = "dataPermId",
|
||||
relationModelClass = SysDataPermMenu.class)
|
||||
@TableField(exist = false)
|
||||
private List<SysDataPermMenu> dataPermMenuList;
|
||||
|
||||
@TableField(exist = false)
|
||||
private String searchString;
|
||||
|
||||
public void setSearchString(String searchString) {
|
||||
this.searchString = MyCommonUtil.replaceSqlWildcard(searchString);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.orangeforms.webadmin.upms.model;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import lombok.Data;
|
||||
import lombok.ToString;
|
||||
|
||||
/**
|
||||
* 数据权限与部门关联实体对象。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
@Data
|
||||
@ToString(of = {"deptId"})
|
||||
@TableName(value = "zz_sys_data_perm_dept")
|
||||
public class SysDataPermDept {
|
||||
|
||||
/**
|
||||
* 数据权限Id。
|
||||
*/
|
||||
@TableField(value = "data_perm_id")
|
||||
private Long dataPermId;
|
||||
|
||||
/**
|
||||
* 关联部门Id。
|
||||
*/
|
||||
@TableField(value = "dept_id")
|
||||
private Long deptId;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.orangeforms.webadmin.upms.model;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import lombok.Data;
|
||||
import lombok.ToString;
|
||||
|
||||
/**
|
||||
* 数据权限与菜单关联实体对象。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
@Data
|
||||
@ToString(of = {"menuId"})
|
||||
@TableName(value = "zz_sys_data_perm_menu")
|
||||
public class SysDataPermMenu {
|
||||
|
||||
/**
|
||||
* 数据权限Id。
|
||||
*/
|
||||
@TableField(value = "data_perm_id")
|
||||
private Long dataPermId;
|
||||
|
||||
/**
|
||||
* 关联菜单Id。
|
||||
*/
|
||||
@TableField(value = "menu_id")
|
||||
private Long menuId;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.orangeforms.webadmin.upms.model;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 数据权限与用户关联实体对象。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
@Data
|
||||
@TableName(value = "zz_sys_data_perm_user")
|
||||
public class SysDataPermUser {
|
||||
|
||||
/**
|
||||
* 数据权限Id。
|
||||
*/
|
||||
@TableField(value = "data_perm_id")
|
||||
private Long dataPermId;
|
||||
|
||||
/**
|
||||
* 用户Id。
|
||||
*/
|
||||
@TableField(value = "user_id")
|
||||
private Long userId;
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package com.orangeforms.webadmin.upms.model;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 部门管理实体对象。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
@Data
|
||||
@TableName(value = "zz_sys_dept")
|
||||
public class SysDept {
|
||||
|
||||
/**
|
||||
* 部门Id。
|
||||
*/
|
||||
@TableId(value = "dept_id")
|
||||
private Long deptId;
|
||||
|
||||
/**
|
||||
* 部门名称。
|
||||
*/
|
||||
@TableField(value = "dept_name")
|
||||
private String deptName;
|
||||
|
||||
/**
|
||||
* 显示顺序。
|
||||
*/
|
||||
@TableField(value = "show_order")
|
||||
private Integer showOrder;
|
||||
|
||||
/**
|
||||
* 父部门Id。
|
||||
*/
|
||||
@TableField(value = "parent_id")
|
||||
private Long parentId;
|
||||
|
||||
/**
|
||||
* 逻辑删除标记字段(1: 正常 -1: 已删除)。
|
||||
*/
|
||||
@TableLogic
|
||||
@TableField(value = "deleted_flag")
|
||||
private Integer deletedFlag;
|
||||
|
||||
/**
|
||||
* 创建者Id。
|
||||
*/
|
||||
@TableField(value = "create_user_id")
|
||||
private Long createUserId;
|
||||
|
||||
/**
|
||||
* 更新者Id。
|
||||
*/
|
||||
@TableField(value = "update_user_id")
|
||||
private Long updateUserId;
|
||||
|
||||
/**
|
||||
* 创建时间。
|
||||
*/
|
||||
@TableField(value = "create_time")
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 更新时间。
|
||||
*/
|
||||
@TableField(value = "update_time")
|
||||
private Date updateTime;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.orangeforms.webadmin.upms.model;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 部门岗位多对多关联实体对象。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
@Data
|
||||
@TableName(value = "zz_sys_dept_post")
|
||||
public class SysDeptPost {
|
||||
|
||||
/**
|
||||
* 部门岗位Id。
|
||||
*/
|
||||
@TableId(value = "dept_post_id")
|
||||
private Long deptPostId;
|
||||
|
||||
/**
|
||||
* 部门Id。
|
||||
*/
|
||||
@TableField(value = "dept_id")
|
||||
private Long deptId;
|
||||
|
||||
/**
|
||||
* 岗位Id。
|
||||
*/
|
||||
@TableField(value = "post_id")
|
||||
private Long postId;
|
||||
|
||||
/**
|
||||
* 部门岗位显示名称。
|
||||
*/
|
||||
@TableField(value = "post_show_name")
|
||||
private String postShowName;
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.orangeforms.webadmin.upms.model;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* 部门关联实体对象。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@TableName(value = "zz_sys_dept_relation")
|
||||
public class SysDeptRelation {
|
||||
|
||||
/**
|
||||
* 上级部门Id。
|
||||
*/
|
||||
@TableField(value = "parent_dept_id")
|
||||
private Long parentDeptId;
|
||||
|
||||
/**
|
||||
* 部门Id。
|
||||
*/
|
||||
@TableField(value = "dept_id")
|
||||
private Long deptId;
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
package com.orangeforms.webadmin.upms.model;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import com.orangeforms.common.core.base.model.BaseModel;
|
||||
import com.orangeforms.webadmin.upms.bo.SysMenuExtraData;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* 菜单实体对象。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName(value = "zz_sys_menu")
|
||||
public class SysMenu extends BaseModel {
|
||||
|
||||
/**
|
||||
* 菜单Id。
|
||||
*/
|
||||
@TableId(value = "menu_id")
|
||||
private Long menuId;
|
||||
|
||||
/**
|
||||
* 父菜单Id,目录菜单的父菜单为null。
|
||||
*/
|
||||
@TableField(value = "parent_id")
|
||||
private Long parentId;
|
||||
|
||||
/**
|
||||
* 菜单显示名称。
|
||||
*/
|
||||
@TableField(value = "menu_name")
|
||||
private String menuName;
|
||||
|
||||
/**
|
||||
* 菜单类型(0: 目录 1: 菜单 2: 按钮 3: UI片段)。
|
||||
*/
|
||||
@TableField(value = "menu_type")
|
||||
private Integer menuType;
|
||||
|
||||
/**
|
||||
* 前端表单路由名称,仅用于menu_type为1的菜单类型。
|
||||
*/
|
||||
@TableField(value = "form_router_name")
|
||||
private String formRouterName;
|
||||
|
||||
/**
|
||||
* 在线表单主键Id,仅用于在线表单绑定的菜单。
|
||||
*/
|
||||
@TableField(value = "online_form_id")
|
||||
private Long onlineFormId;
|
||||
|
||||
/**
|
||||
* 在线表单菜单的权限控制类型,具体值可参考SysOnlineMenuPermType常量对象。
|
||||
*/
|
||||
@TableField(value = "online_menu_perm_type")
|
||||
private Integer onlineMenuPermType;
|
||||
|
||||
/**
|
||||
* 统计页面主键Id,仅用于统计页面绑定的菜单。
|
||||
*/
|
||||
@TableField(value = "report_page_id")
|
||||
private Long reportPageId;
|
||||
|
||||
/**
|
||||
* 仅用于在线表单的流程Id。
|
||||
*/
|
||||
@TableField(value = "online_flow_entry_id")
|
||||
private Long onlineFlowEntryId;
|
||||
|
||||
/**
|
||||
* 菜单显示顺序 (值越小,排序越靠前)。
|
||||
*/
|
||||
@TableField(value = "show_order")
|
||||
private Integer showOrder;
|
||||
|
||||
/**
|
||||
* 菜单图标。
|
||||
*/
|
||||
private String icon;
|
||||
|
||||
/**
|
||||
* 附加信息。
|
||||
*/
|
||||
@TableField(value = "extra_data")
|
||||
private String extraData;
|
||||
|
||||
/**
|
||||
* extraData字段解析后的对象数据。
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private SysMenuExtraData extraObject;
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.orangeforms.webadmin.upms.model;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 白名单实体对象。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
@Data
|
||||
@TableName(value = "zz_sys_perm_whitelist")
|
||||
public class SysPermWhitelist {
|
||||
|
||||
/**
|
||||
* 权限资源的URL。
|
||||
*/
|
||||
@TableId(value = "perm_url")
|
||||
private String permUrl;
|
||||
|
||||
/**
|
||||
* 权限资源所属模块名字(通常是Controller的名字)。
|
||||
*/
|
||||
@TableField(value = "module_name")
|
||||
private String moduleName;
|
||||
|
||||
/**
|
||||
* 权限的名称。
|
||||
*/
|
||||
@TableField(value = "perm_name")
|
||||
private String permName;
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.orangeforms.webadmin.upms.model;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import com.orangeforms.common.core.base.model.BaseModel;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* 岗位实体对象。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName(value = "zz_sys_post")
|
||||
public class SysPost extends BaseModel {
|
||||
|
||||
/**
|
||||
* 岗位Id。
|
||||
*/
|
||||
@TableId(value = "post_id")
|
||||
private Long postId;
|
||||
|
||||
/**
|
||||
* 岗位名称。
|
||||
*/
|
||||
@TableField(value = "post_name")
|
||||
private String postName;
|
||||
|
||||
/**
|
||||
* 岗位层级,数值越小级别越高。
|
||||
*/
|
||||
@TableField(value = "post_level")
|
||||
private Integer postLevel;
|
||||
|
||||
/**
|
||||
* 是否领导岗位。
|
||||
*/
|
||||
@TableField(value = "leader_post")
|
||||
private Boolean leaderPost;
|
||||
|
||||
/**
|
||||
* postId 的多对多关联表数据对象。
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private SysDeptPost sysDeptPost;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.orangeforms.webadmin.upms.model;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import com.orangeforms.common.core.annotation.RelationManyToMany;
|
||||
import com.orangeforms.common.core.base.model.BaseModel;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 角色实体对象。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName(value = "zz_sys_role")
|
||||
public class SysRole extends BaseModel {
|
||||
|
||||
/**
|
||||
* 角色Id。
|
||||
*/
|
||||
@TableId(value = "role_id")
|
||||
private Long roleId;
|
||||
|
||||
/**
|
||||
* 角色名称。
|
||||
*/
|
||||
@TableField(value = "role_name")
|
||||
private String roleName;
|
||||
|
||||
@RelationManyToMany(
|
||||
relationMasterIdField = "roleId",
|
||||
relationModelClass = SysRoleMenu.class)
|
||||
@TableField(exist = false)
|
||||
private List<SysRoleMenu> sysRoleMenuList;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.orangeforms.webadmin.upms.model;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 角色菜单实体对象。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
@Data
|
||||
@TableName(value = "zz_sys_role_menu")
|
||||
public class SysRoleMenu {
|
||||
|
||||
/**
|
||||
* 角色Id。
|
||||
*/
|
||||
@TableField(value = "role_id")
|
||||
private Long roleId;
|
||||
|
||||
/**
|
||||
* 菜单Id。
|
||||
*/
|
||||
@TableField(value = "menu_id")
|
||||
private Long menuId;
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
package com.orangeforms.webadmin.upms.model;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import com.orangeforms.webadmin.upms.model.constant.SysUserType;
|
||||
import com.orangeforms.webadmin.upms.model.constant.SysUserStatus;
|
||||
import com.orangeforms.common.core.upload.UploadStoreTypeEnum;
|
||||
import com.orangeforms.common.core.annotation.*;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 用户管理实体对象。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
@Data
|
||||
@TableName(value = "zz_sys_user")
|
||||
public class SysUser {
|
||||
|
||||
/**
|
||||
* 用户Id。
|
||||
*/
|
||||
@TableId(value = "user_id")
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 登录用户名。
|
||||
*/
|
||||
@TableField(value = "login_name")
|
||||
private String loginName;
|
||||
|
||||
/**
|
||||
* 用户密码。
|
||||
*/
|
||||
private String password;
|
||||
|
||||
/**
|
||||
* 用户部门Id。
|
||||
*/
|
||||
@TableField(value = "dept_id")
|
||||
private Long deptId;
|
||||
|
||||
/**
|
||||
* 用户显示名称。
|
||||
*/
|
||||
@TableField(value = "show_name")
|
||||
private String showName;
|
||||
|
||||
/**
|
||||
* 用户类型(0: 管理员 1: 系统管理用户 2: 系统业务用户)。
|
||||
*/
|
||||
@TableField(value = "user_type")
|
||||
private Integer userType;
|
||||
|
||||
/**
|
||||
* 用户头像的Url。
|
||||
*/
|
||||
@UploadFlagColumn(storeType = UploadStoreTypeEnum.LOCAL_SYSTEM)
|
||||
@TableField(value = "head_image_url")
|
||||
private String headImageUrl;
|
||||
|
||||
/**
|
||||
* 用户状态(0: 正常 1: 锁定)。
|
||||
*/
|
||||
@TableField(value = "user_status")
|
||||
private Integer userStatus;
|
||||
|
||||
/**
|
||||
* 用户邮箱。
|
||||
*/
|
||||
private String email;
|
||||
|
||||
/**
|
||||
* 用户手机。
|
||||
*/
|
||||
private String mobile;
|
||||
|
||||
/**
|
||||
* 创建者Id。
|
||||
*/
|
||||
@TableField(value = "create_user_id")
|
||||
private Long createUserId;
|
||||
|
||||
/**
|
||||
* 更新者Id。
|
||||
*/
|
||||
@TableField(value = "update_user_id")
|
||||
private Long updateUserId;
|
||||
|
||||
/**
|
||||
* 创建时间。
|
||||
*/
|
||||
@TableField(value = "create_time")
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 更新时间。
|
||||
*/
|
||||
@TableField(value = "update_time")
|
||||
private Date updateTime;
|
||||
|
||||
/**
|
||||
* 逻辑删除标记字段(1: 正常 -1: 已删除)。
|
||||
*/
|
||||
@TableLogic
|
||||
@TableField(value = "deleted_flag")
|
||||
private Integer deletedFlag;
|
||||
|
||||
/**
|
||||
* createTime 范围过滤起始值(>=)。
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private String createTimeStart;
|
||||
|
||||
/**
|
||||
* createTime 范围过滤结束值(<=)。
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private String createTimeEnd;
|
||||
|
||||
/**
|
||||
* 多对多用户部门岗位数据集合。
|
||||
*/
|
||||
@RelationManyToMany(
|
||||
relationMasterIdField = "userId",
|
||||
relationModelClass = SysUserPost.class)
|
||||
@TableField(exist = false)
|
||||
private List<SysUserPost> sysUserPostList;
|
||||
|
||||
/**
|
||||
* 多对多用户角色数据集合。
|
||||
*/
|
||||
@RelationManyToMany(
|
||||
relationMasterIdField = "userId",
|
||||
relationModelClass = SysUserRole.class)
|
||||
@TableField(exist = false)
|
||||
private List<SysUserRole> sysUserRoleList;
|
||||
|
||||
/**
|
||||
* 多对多用户数据权限数据集合。
|
||||
*/
|
||||
@RelationManyToMany(
|
||||
relationMasterIdField = "userId",
|
||||
relationModelClass = SysDataPermUser.class)
|
||||
@TableField(exist = false)
|
||||
private List<SysDataPermUser> sysDataPermUserList;
|
||||
|
||||
@RelationDict(
|
||||
masterIdField = "deptId",
|
||||
slaveModelClass = SysDept.class,
|
||||
slaveIdField = "deptId",
|
||||
slaveNameField = "deptName")
|
||||
@TableField(exist = false)
|
||||
private Map<String, Object> deptIdDictMap;
|
||||
|
||||
@RelationConstDict(
|
||||
masterIdField = "userType",
|
||||
constantDictClass = SysUserType.class)
|
||||
@TableField(exist = false)
|
||||
private Map<String, Object> userTypeDictMap;
|
||||
|
||||
@RelationConstDict(
|
||||
masterIdField = "userStatus",
|
||||
constantDictClass = SysUserStatus.class)
|
||||
@TableField(exist = false)
|
||||
private Map<String, Object> userStatusDictMap;
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.orangeforms.webadmin.upms.model;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 用户岗位多对多关系实体对象。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
@Data
|
||||
@TableName(value = "zz_sys_user_post")
|
||||
public class SysUserPost {
|
||||
|
||||
/**
|
||||
* 用户Id。
|
||||
*/
|
||||
@TableField(value = "user_id")
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 部门岗位Id。
|
||||
*/
|
||||
@TableField(value = "dept_post_id")
|
||||
private Long deptPostId;
|
||||
|
||||
/**
|
||||
* 岗位Id。
|
||||
*/
|
||||
@TableField(value = "post_id")
|
||||
private Long postId;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.orangeforms.webadmin.upms.model;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 用户角色实体对象。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
@Data
|
||||
@TableName(value = "zz_sys_user_role")
|
||||
public class SysUserRole {
|
||||
|
||||
/**
|
||||
* 用户Id。
|
||||
*/
|
||||
@TableField(value = "user_id")
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 角色Id。
|
||||
*/
|
||||
@TableField(value = "role_id")
|
||||
private Long roleId;
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.orangeforms.webadmin.upms.model.constant;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 菜单类型常量对象。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
public final class SysMenuType {
|
||||
|
||||
/**
|
||||
* 目录菜单。
|
||||
*/
|
||||
public static final int TYPE_DIRECTORY = 0;
|
||||
/**
|
||||
* 普通菜单。
|
||||
*/
|
||||
public static final int TYPE_MENU = 1;
|
||||
/**
|
||||
* 表单片段类型。
|
||||
*/
|
||||
public static final int TYPE_UI_FRAGMENT = 2;
|
||||
/**
|
||||
* 按钮类型。
|
||||
*/
|
||||
public static final int TYPE_BUTTON = 3;
|
||||
|
||||
private static final Map<Object, String> DICT_MAP = new HashMap<>(4);
|
||||
static {
|
||||
DICT_MAP.put(TYPE_DIRECTORY, "目录菜单");
|
||||
DICT_MAP.put(TYPE_MENU, "普通菜单");
|
||||
DICT_MAP.put(TYPE_UI_FRAGMENT, "表单片段类型");
|
||||
DICT_MAP.put(TYPE_BUTTON, "按钮类型");
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断参数是否为当前常量字典的合法值。
|
||||
*
|
||||
* @param value 待验证的参数值。
|
||||
* @return 合法返回true,否则false。
|
||||
*/
|
||||
public static boolean isValid(Integer value) {
|
||||
return value != null && DICT_MAP.containsKey(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 私有构造函数,明确标识该常量类的作用。
|
||||
*/
|
||||
private SysMenuType() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.orangeforms.webadmin.upms.model.constant;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 菜单关联在线表单的控制权限类型。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
public final class SysOnlineMenuPermType {
|
||||
|
||||
/**
|
||||
* 查看。
|
||||
*/
|
||||
public static final int TYPE_VIEW = 0;
|
||||
/**
|
||||
* 编辑。
|
||||
*/
|
||||
public static final int TYPE_EDIT = 1;
|
||||
|
||||
private static final Map<Object, String> DICT_MAP = new HashMap<>(4);
|
||||
static {
|
||||
DICT_MAP.put(TYPE_VIEW, "查看");
|
||||
DICT_MAP.put(TYPE_EDIT, "编辑");
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断参数是否为当前常量字典的合法值。
|
||||
*
|
||||
* @param value 待验证的参数值。
|
||||
* @return 合法返回true,否则false。
|
||||
*/
|
||||
public static boolean isValid(Integer value) {
|
||||
return value != null && DICT_MAP.containsKey(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 私有构造函数,明确标识该常量类的作用。
|
||||
*/
|
||||
private SysOnlineMenuPermType() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.orangeforms.webadmin.upms.model.constant;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 用户状态常量字典对象。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
public final class SysUserStatus {
|
||||
|
||||
/**
|
||||
* 正常状态。
|
||||
*/
|
||||
public static final int STATUS_NORMAL = 0;
|
||||
/**
|
||||
* 锁定状态。
|
||||
*/
|
||||
public static final int STATUS_LOCKED = 1;
|
||||
|
||||
private static final Map<Object, String> DICT_MAP = new HashMap<>(2);
|
||||
static {
|
||||
DICT_MAP.put(STATUS_NORMAL, "正常状态");
|
||||
DICT_MAP.put(STATUS_LOCKED, "锁定状态");
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断参数是否为当前常量字典的合法值。
|
||||
*
|
||||
* @param value 待验证的参数值。
|
||||
* @return 合法返回true,否则false。
|
||||
*/
|
||||
public static boolean isValid(Integer value) {
|
||||
return value != null && DICT_MAP.containsKey(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 私有构造函数,明确标识该常量类的作用。
|
||||
*/
|
||||
private SysUserStatus() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.orangeforms.webadmin.upms.model.constant;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 用户类型常量字典对象。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
public final class SysUserType {
|
||||
|
||||
/**
|
||||
* 管理员。
|
||||
*/
|
||||
public static final int TYPE_ADMIN = 0;
|
||||
/**
|
||||
* 系统操作员。
|
||||
*/
|
||||
public static final int TYPE_SYSTEM = 1;
|
||||
/**
|
||||
* 普通操作员。
|
||||
*/
|
||||
public static final int TYPE_OPERATOR = 2;
|
||||
|
||||
private static final Map<Object, String> DICT_MAP = new HashMap<>(3);
|
||||
static {
|
||||
DICT_MAP.put(TYPE_ADMIN, "管理员");
|
||||
DICT_MAP.put(TYPE_SYSTEM, "系统操作员");
|
||||
DICT_MAP.put(TYPE_OPERATOR, "普通操作员");
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断参数是否为当前常量字典的合法值。
|
||||
*
|
||||
* @param value 待验证的参数值。
|
||||
* @return 合法返回true,否则false。
|
||||
*/
|
||||
public static boolean isValid(Integer value) {
|
||||
return value != null && DICT_MAP.containsKey(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 私有构造函数,明确标识该常量类的作用。
|
||||
*/
|
||||
private SysUserType() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
package com.orangeforms.webadmin.upms.service;
|
||||
|
||||
import com.orangeforms.common.core.base.service.IBaseService;
|
||||
import com.orangeforms.common.core.object.CallResult;
|
||||
import com.orangeforms.webadmin.upms.model.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 数据权限数据服务接口。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
public interface SysDataPermService extends IBaseService<SysDataPerm, Long> {
|
||||
|
||||
/**
|
||||
* 保存新增的数据权限对象。
|
||||
*
|
||||
* @param dataPerm 新增的数据权限对象。
|
||||
* @param deptIdSet 关联的部门Id列表。
|
||||
* @param menuIdSet 关联的菜单Id列表。
|
||||
* @return 新增后的数据权限对象。
|
||||
*/
|
||||
SysDataPerm saveNew(SysDataPerm dataPerm, Set<Long> deptIdSet, Set<Long> menuIdSet);
|
||||
|
||||
/**
|
||||
* 更新数据权限对象。
|
||||
*
|
||||
* @param dataPerm 更新的数据权限对象。
|
||||
* @param originalDataPerm 原有的数据权限对象。
|
||||
* @param deptIdSet 关联的部门Id列表。
|
||||
* @param menuIdSet 关联的菜单Id列表。
|
||||
* @return 更新成功返回true,否则false。
|
||||
*/
|
||||
boolean update(SysDataPerm dataPerm, SysDataPerm originalDataPerm, Set<Long> deptIdSet, Set<Long> menuIdSet);
|
||||
|
||||
/**
|
||||
* 删除指定数据权限。
|
||||
*
|
||||
* @param dataPermId 数据权限主键Id。
|
||||
* @return 删除成功返回true,否则false。
|
||||
*/
|
||||
boolean remove(Long dataPermId);
|
||||
|
||||
/**
|
||||
* 获取数据权限列表及其关联数据。
|
||||
*
|
||||
* @param filter 数据权限过滤对象。
|
||||
* @param orderBy 排序参数。
|
||||
* @return 数据权限查询列表。
|
||||
*/
|
||||
List<SysDataPerm> getSysDataPermListWithRelation(SysDataPerm filter, String orderBy);
|
||||
|
||||
/**
|
||||
* 将指定用户的指定会话的数据权限集合存入缓存。
|
||||
*
|
||||
* @param sessionId 会话Id。
|
||||
* @param userId 用户主键Id。
|
||||
* @param deptId 用户所属部门主键Id。
|
||||
*/
|
||||
void putDataPermCache(String sessionId, Long userId, Long deptId);
|
||||
|
||||
/**
|
||||
* 将指定会话的数据权限集合从缓存中移除。
|
||||
*
|
||||
* @param sessionId 会话Id。
|
||||
*/
|
||||
void removeDataPermCache(String sessionId);
|
||||
|
||||
/**
|
||||
* 获取指定用户Id的数据权限列表。并基于menuId和权限规则类型进行了一级分组。
|
||||
*
|
||||
* @param userId 指定的用户Id。
|
||||
* @param deptId 用户所属部门主键Id。
|
||||
* @return 合并优化后的数据权限列表。返回格式为,Map<MenuId, Map<RuleType, DeptIdString>>。
|
||||
*/
|
||||
Map<String, Map<Integer, String>> getSysDataPermListByUserId(Long userId, Long deptId);
|
||||
|
||||
/**
|
||||
* 查询与指定菜单关联的数据权限列表。
|
||||
*
|
||||
* @param menuId 菜单Id。
|
||||
* @return 与菜单Id关联的数据权限列表。
|
||||
*/
|
||||
List<SysDataPerm> getSysDataPermListByMenuId(Long menuId);
|
||||
|
||||
/**
|
||||
* 添加用户和数据权限之间的多对多关联关系。
|
||||
*
|
||||
* @param dataPermId 数据权限Id。
|
||||
* @param userIdSet 关联的用户Id列表。
|
||||
*/
|
||||
void addDataPermUserList(Long dataPermId, Set<Long> userIdSet);
|
||||
|
||||
/**
|
||||
* 移除用户和数据权限之间的多对多关联关系。
|
||||
*
|
||||
* @param dataPermId 数据权限主键Id。
|
||||
* @param userId 用户主键Id。
|
||||
* @return true移除成功,否则false。
|
||||
*/
|
||||
boolean removeDataPermUser(Long dataPermId, Long userId);
|
||||
|
||||
/**
|
||||
* 验证数据权限对象关联菜单数据是否都合法。
|
||||
*
|
||||
* @param dataPerm 数据权限关对象。
|
||||
* @param deptIdListString 与数据权限关联的部门Id列表。
|
||||
* @param menuIdListString 与数据权限关联的菜单Id列表。
|
||||
* @return 验证结果。
|
||||
*/
|
||||
CallResult verifyRelatedData(SysDataPerm dataPerm, String deptIdListString, String menuIdListString);
|
||||
}
|
||||
@@ -0,0 +1,170 @@
|
||||
package com.orangeforms.webadmin.upms.service;
|
||||
|
||||
import com.orangeforms.webadmin.upms.model.*;
|
||||
import com.orangeforms.common.core.base.service.IBaseService;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 部门管理数据操作服务接口。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
public interface SysDeptService extends IBaseService<SysDept, Long> {
|
||||
|
||||
/**
|
||||
* 保存新增的部门对象。
|
||||
*
|
||||
* @param sysDept 新增的部门对象。
|
||||
* @param parentSysDept 上级部门对象。
|
||||
* @return 新增后的部门对象。
|
||||
*/
|
||||
SysDept saveNew(SysDept sysDept, SysDept parentSysDept);
|
||||
|
||||
/**
|
||||
* 更新部门对象。
|
||||
*
|
||||
* @param sysDept 更新的部门对象。
|
||||
* @param originalSysDept 原有的部门对象。
|
||||
* @return 更新成功返回true,否则false。
|
||||
*/
|
||||
boolean update(SysDept sysDept, SysDept originalSysDept);
|
||||
|
||||
/**
|
||||
* 删除指定数据。
|
||||
*
|
||||
* @param deptId 主键Id。
|
||||
* @return 成功返回true,否则false。
|
||||
*/
|
||||
boolean remove(Long deptId);
|
||||
|
||||
/**
|
||||
* 获取单表查询结果。由于没有关联数据查询,因此在仅仅获取单表数据的场景下,效率更高。
|
||||
* 如果需要同时获取关联数据,请移步(getSysDeptListWithRelation)方法。
|
||||
*
|
||||
* @param filter 过滤对象。
|
||||
* @param orderBy 排序参数。
|
||||
* @return 查询结果集。
|
||||
*/
|
||||
List<SysDept> getSysDeptList(SysDept filter, String orderBy);
|
||||
|
||||
/**
|
||||
* 获取主表的查询结果,以及主表关联的字典数据和一对一从表数据,以及一对一从表的字典数据。
|
||||
* 该查询会涉及到一对一从表的关联过滤,或一对多从表的嵌套关联过滤,因此性能不如单表过滤。
|
||||
* 如果仅仅需要获取主表数据,请移步(getSysDeptList),以便获取更好的查询性能。
|
||||
*
|
||||
* @param filter 主表过滤对象。
|
||||
* @param orderBy 排序参数。
|
||||
* @return 查询结果集。
|
||||
*/
|
||||
List<SysDept> getSysDeptListWithRelation(SysDept filter, String orderBy);
|
||||
|
||||
/**
|
||||
* 判断指定对象是否包含下级对象。
|
||||
*
|
||||
* @param deptId 主键Id。
|
||||
* @return 存在返回true,否则false。
|
||||
*/
|
||||
boolean hasChildren(Long deptId);
|
||||
|
||||
/**
|
||||
* 判断指定部门Id是否包含用户对象。
|
||||
*
|
||||
* @param deptId 部门主键Id。
|
||||
* @return 存在返回true,否则false。
|
||||
*/
|
||||
boolean hasChildrenUser(Long deptId);
|
||||
|
||||
/**
|
||||
* 批量添加多对多关联关系。
|
||||
*
|
||||
* @param sysDeptPostList 多对多关联表对象集合。
|
||||
* @param deptId 主表Id。
|
||||
*/
|
||||
void addSysDeptPostList(List<SysDeptPost> sysDeptPostList, Long deptId);
|
||||
|
||||
/**
|
||||
* 更新中间表数据。
|
||||
*
|
||||
* @param sysDeptPost 中间表对象。
|
||||
* @return 更新成功与否。
|
||||
*/
|
||||
boolean updateSysDeptPost(SysDeptPost sysDeptPost);
|
||||
|
||||
/**
|
||||
* 移除单条多对多关系。
|
||||
*
|
||||
* @param deptId 主表Id。
|
||||
* @param postId 从表Id。
|
||||
* @return 成功返回true,否则false。
|
||||
*/
|
||||
boolean removeSysDeptPost(Long deptId, Long postId);
|
||||
|
||||
/**
|
||||
* 获取中间表数据。
|
||||
*
|
||||
* @param deptId 主表Id。
|
||||
* @param postId 从表Id。
|
||||
* @return 中间表对象。
|
||||
*/
|
||||
SysDeptPost getSysDeptPost(Long deptId, Long postId);
|
||||
|
||||
/**
|
||||
* 根据部门岗位Id获取部门岗位关联对象。
|
||||
*
|
||||
* @param deptPostId 部门岗位Id。
|
||||
* @return 部门岗位对象。
|
||||
*/
|
||||
SysDeptPost getSysDeptPost(Long deptPostId);
|
||||
|
||||
/**
|
||||
* 获取指定部门Id的部门岗位多对多关联数据列表,以及关联的部门和岗位数据。
|
||||
*
|
||||
* @param deptId 部门Id。如果参数为空则返回全部数据。
|
||||
* @return 部门岗位多对多数据列表。
|
||||
*/
|
||||
List<Map<String, Object>> getSysDeptPostListWithRelationByDeptId(Long deptId);
|
||||
|
||||
/**
|
||||
* 获取指定部门Id和岗位Id集合的部门岗位多对多关联数据列表。
|
||||
*
|
||||
* @param deptId 部门Id。
|
||||
* @param postIdSet 指定的岗位Id集合。
|
||||
* @return 部门岗位多对多数据列表。
|
||||
*/
|
||||
List<SysDeptPost> getSysDeptPostList(Long deptId, Set<Long> postIdSet);
|
||||
|
||||
/**
|
||||
* 获取与指定部门Id同级部门和岗位Id集合的部门岗位多对多关联数据列表。
|
||||
*
|
||||
* @param deptId 部门Id。
|
||||
* @param postIdSet 指定的岗位Id集合。
|
||||
* @return 部门岗位多对多数据列表。
|
||||
*/
|
||||
List<SysDeptPost> getSiblingSysDeptPostList(Long deptId, Set<Long> postIdSet);
|
||||
|
||||
/**
|
||||
* 根据部门Id获取该部门领导岗位的部门岗位Id集合。
|
||||
*
|
||||
* @param deptId 部门Id。
|
||||
* @return 部门领导岗位的部门岗位Id集合。
|
||||
*/
|
||||
List<Long> getLeaderDeptPostIdList(Long deptId);
|
||||
|
||||
/**
|
||||
* 根据部门Id获取上级部门领导岗位的部门岗位Id集合。
|
||||
*
|
||||
* @param deptId 部门Id。
|
||||
* @return 上级部门领导岗位的部门岗位Id集合。
|
||||
*/
|
||||
List<Long> getUpLeaderDeptPostIdList(Long deptId);
|
||||
|
||||
/**
|
||||
* 根据父主键Id列表,获取当前部门Id及其所有下级部门Id列表。
|
||||
*
|
||||
* @param parentIds 父主键Id列表。
|
||||
* @return 获取当前部门Id及其所有下级部门Id列表。
|
||||
*/
|
||||
List<Long> getAllChildDeptIdByParentIds(List<Long> parentIds);
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package com.orangeforms.webadmin.upms.service;
|
||||
|
||||
import com.orangeforms.common.core.base.service.IBaseService;
|
||||
import com.orangeforms.webadmin.upms.model.SysMenu;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 菜单数据服务接口。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
public interface SysMenuService extends IBaseService<SysMenu, Long> {
|
||||
|
||||
/**
|
||||
* 保存新增的菜单对象。
|
||||
*
|
||||
* @param sysMenu 新增的菜单对象。
|
||||
* @return 新增后的菜单对象。
|
||||
*/
|
||||
SysMenu saveNew(SysMenu sysMenu);
|
||||
|
||||
/**
|
||||
* 更新菜单对象。
|
||||
*
|
||||
* @param sysMenu 更新的菜单对象。
|
||||
* @param originalSysMenu 原有的菜单对象。
|
||||
* @return 更新成功返回true,否则false。
|
||||
*/
|
||||
boolean update(SysMenu sysMenu, SysMenu originalSysMenu);
|
||||
|
||||
/**
|
||||
* 删除指定的菜单。
|
||||
*
|
||||
* @param menu 菜单对象。
|
||||
* @return 删除成功返回true,否则false。
|
||||
*/
|
||||
boolean remove(SysMenu menu);
|
||||
|
||||
/**
|
||||
* 获取指定用户Id的菜单列表,已去重。
|
||||
*
|
||||
* @param userId 用户主键Id。
|
||||
* @return 用户关联的菜单列表。
|
||||
*/
|
||||
Collection<SysMenu> getMenuListByUserId(Long userId);
|
||||
|
||||
/**
|
||||
* 根据角色Id集合获取菜单对象列表。
|
||||
*
|
||||
* @param roleIds 逗号分隔的角色Id集合。
|
||||
* @return 菜单对象列表。
|
||||
*/
|
||||
Collection<SysMenu> getMenuListByRoleIds(String roleIds);
|
||||
|
||||
/**
|
||||
* 判断当前菜单是否存在子菜单。
|
||||
*
|
||||
* @param menuId 菜单主键Id。
|
||||
* @return 存在返回true,否则false。
|
||||
*/
|
||||
boolean hasChildren(Long menuId);
|
||||
|
||||
/**
|
||||
* 获取指定类型的所有在线表单的菜单。
|
||||
*
|
||||
* @param menuType 菜单类型,NULL则返回全部类型。
|
||||
* @return 在线表单关联的菜单列表。
|
||||
*/
|
||||
List<SysMenu> getAllOnlineMenuList(Integer menuType);
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.orangeforms.webadmin.upms.service;
|
||||
|
||||
import com.orangeforms.common.core.base.service.IBaseService;
|
||||
import com.orangeforms.webadmin.upms.model.SysPermWhitelist;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 权限资源白名单数据服务接口。
|
||||
* 白名单中的权限资源,可以不受权限控制,任何用户皆可访问,一般用于常用的字典数据列表接口。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
public interface SysPermWhitelistService extends IBaseService<SysPermWhitelist, String> {
|
||||
|
||||
/**
|
||||
* 获取白名单权限资源的列表。
|
||||
*
|
||||
* @return 白名单权限资源地址列表。
|
||||
*/
|
||||
List<String> getWhitelistPermList();
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
package com.orangeforms.webadmin.upms.service;
|
||||
|
||||
import com.orangeforms.common.core.base.service.IBaseService;
|
||||
import com.orangeforms.webadmin.upms.model.SysPost;
|
||||
import com.orangeforms.webadmin.upms.model.SysUserPost;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 岗位管理数据操作服务接口。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
public interface SysPostService extends IBaseService<SysPost, Long> {
|
||||
|
||||
/**
|
||||
* 保存新增对象。
|
||||
*
|
||||
* @param sysPost 新增对象。
|
||||
* @return 返回新增对象。
|
||||
*/
|
||||
SysPost saveNew(SysPost sysPost);
|
||||
|
||||
/**
|
||||
* 更新数据对象。
|
||||
*
|
||||
* @param sysPost 更新的对象。
|
||||
* @param originalSysPost 原有数据对象。
|
||||
* @return 成功返回true,否则false。
|
||||
*/
|
||||
boolean update(SysPost sysPost, SysPost originalSysPost);
|
||||
|
||||
/**
|
||||
* 删除指定数据。
|
||||
*
|
||||
* @param postId 主键Id。
|
||||
* @return 成功返回true,否则false。
|
||||
*/
|
||||
boolean remove(Long postId);
|
||||
|
||||
/**
|
||||
* 获取单表查询结果。由于没有关联数据查询,因此在仅仅获取单表数据的场景下,效率更高。
|
||||
* 如果需要同时获取关联数据,请移步(getSysPostListWithRelation)方法。
|
||||
*
|
||||
* @param filter 过滤对象。
|
||||
* @param orderBy 排序参数。
|
||||
* @return 查询结果集。
|
||||
*/
|
||||
List<SysPost> getSysPostList(SysPost filter, String orderBy);
|
||||
|
||||
/**
|
||||
* 获取主表的查询结果,以及主表关联的字典数据和一对一从表数据,以及一对一从表的字典数据。
|
||||
* 该查询会涉及到一对一从表的关联过滤,或一对多从表的嵌套关联过滤,因此性能不如单表过滤。
|
||||
* 如果仅仅需要获取主表数据,请移步(getSysPostList),以便获取更好的查询性能。
|
||||
*
|
||||
* @param filter 主表过滤对象。
|
||||
* @param orderBy 排序参数。
|
||||
* @return 查询结果集。
|
||||
*/
|
||||
List<SysPost> getSysPostListWithRelation(SysPost filter, String orderBy);
|
||||
|
||||
/**
|
||||
* 在多对多关系中,当前Service的数据表为从表,返回不与指定主表主键Id存在对多对关系的列表。
|
||||
*
|
||||
* @param deptId 主表主键Id。
|
||||
* @param filter 从表的过滤对象。
|
||||
* @param orderBy 排序参数。
|
||||
* @return 查询结果集。
|
||||
*/
|
||||
List<SysPost> getNotInSysPostListByDeptId(Long deptId, SysPost filter, String orderBy);
|
||||
|
||||
/**
|
||||
* 获取指定部门的岗位列表。
|
||||
*
|
||||
* @param deptId 部门Id。
|
||||
* @param filter 从表的过滤对象。
|
||||
* @param orderBy 排序参数。
|
||||
* @return 查询结果集。
|
||||
*/
|
||||
List<SysPost> getSysPostListByDeptId(Long deptId, SysPost filter, String orderBy);
|
||||
|
||||
/**
|
||||
* 获取指定用户的用户岗位多对多关联数据列表。
|
||||
*
|
||||
* @param userId 用户Id。
|
||||
* @return 用户岗位多对多关联数据列表。
|
||||
*/
|
||||
List<SysUserPost> getSysUserPostListByUserId(Long userId);
|
||||
|
||||
/**
|
||||
* 判断指定的部门岗位Id集合是否都属于指定的部门Id。
|
||||
*
|
||||
* @param deptPostIdSet 部门岗位Id集合。
|
||||
* @param deptId 部门Id。
|
||||
* @return 全部是返回true,否则false。
|
||||
*/
|
||||
boolean existAllPrimaryKeys(Set<Long> deptPostIdSet, Long deptId);
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
package com.orangeforms.webadmin.upms.service;
|
||||
|
||||
import com.orangeforms.common.core.base.service.IBaseService;
|
||||
import com.orangeforms.common.core.object.CallResult;
|
||||
import com.orangeforms.webadmin.upms.model.SysRole;
|
||||
import com.orangeforms.webadmin.upms.model.SysUserRole;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 角色数据服务接口。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
public interface SysRoleService extends IBaseService<SysRole, Long> {
|
||||
|
||||
/**
|
||||
* 保存新增的角色对象。
|
||||
*
|
||||
* @param role 新增的角色对象。
|
||||
* @param menuIdSet 菜单Id列表。
|
||||
* @return 新增后的角色对象。
|
||||
*/
|
||||
SysRole saveNew(SysRole role, Set<Long> menuIdSet);
|
||||
|
||||
/**
|
||||
* 更新角色对象。
|
||||
*
|
||||
* @param role 更新的角色对象。
|
||||
* @param originalRole 原有的角色对象。
|
||||
* @param menuIdSet 菜单Id列表。
|
||||
* @return 更新成功返回true,否则false。
|
||||
*/
|
||||
boolean update(SysRole role, SysRole originalRole, Set<Long> menuIdSet);
|
||||
|
||||
/**
|
||||
* 删除指定角色。
|
||||
*
|
||||
* @param roleId 角色主键Id。
|
||||
* @return 删除成功返回true,否则false。
|
||||
*/
|
||||
boolean remove(Long roleId);
|
||||
|
||||
/**
|
||||
* 获取角色列表。
|
||||
*
|
||||
* @param filter 角色过滤对象。
|
||||
* @param orderBy 排序参数。
|
||||
* @return 角色列表。
|
||||
*/
|
||||
List<SysRole> getSysRoleList(SysRole filter, String orderBy);
|
||||
|
||||
/**
|
||||
* 获取用户的用户角色对象列表。
|
||||
*
|
||||
* @param userId 用户Id。
|
||||
* @return 用户角色对象列表。
|
||||
*/
|
||||
List<SysUserRole> getSysUserRoleListByUserId(Long userId);
|
||||
|
||||
/**
|
||||
* 批量新增用户角色关联。
|
||||
*
|
||||
* @param userRoleList 用户角色关系数据列表。
|
||||
*/
|
||||
void addUserRoleList(List<SysUserRole> userRoleList);
|
||||
|
||||
/**
|
||||
* 移除指定用户和指定角色的关联关系。
|
||||
*
|
||||
* @param roleId 角色主键Id。
|
||||
* @param userId 用户主键Id。
|
||||
* @return 移除成功返回true,否则false。
|
||||
*/
|
||||
boolean removeUserRole(Long roleId, Long userId);
|
||||
|
||||
/**
|
||||
* 验证角色对象关联的数据是否都合法。
|
||||
*
|
||||
* @param sysRole 当前操作的对象。
|
||||
* @param originalSysRole 原有对象。
|
||||
* @param menuIdListString 逗号分隔的menuId列表。
|
||||
* @return 验证结果。
|
||||
*/
|
||||
CallResult verifyRelatedData(SysRole sysRole, SysRole originalSysRole, String menuIdListString);
|
||||
}
|
||||
@@ -0,0 +1,176 @@
|
||||
package com.orangeforms.webadmin.upms.service;
|
||||
|
||||
import com.orangeforms.webadmin.upms.model.*;
|
||||
import com.orangeforms.common.core.object.CallResult;
|
||||
import com.orangeforms.common.core.base.service.IBaseService;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 用户管理数据操作服务接口。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
public interface SysUserService extends IBaseService<SysUser, Long> {
|
||||
|
||||
/**
|
||||
* 获取指定登录名的用户对象。
|
||||
*
|
||||
* @param loginName 指定登录用户名。
|
||||
* @return 用户对象。
|
||||
*/
|
||||
SysUser getSysUserByLoginName(String loginName);
|
||||
|
||||
/**
|
||||
* 保存新增的用户对象。
|
||||
*
|
||||
* @param user 新增的用户对象。
|
||||
* @param roleIdSet 用户角色Id集合。
|
||||
* @param deptPostIdSet 部门岗位Id集合。
|
||||
* @param dataPermIdSet 数据权限Id集合。
|
||||
* @return 新增后的用户对象。
|
||||
*/
|
||||
SysUser saveNew(SysUser user, Set<Long> roleIdSet, Set<Long> deptPostIdSet, Set<Long> dataPermIdSet);
|
||||
|
||||
/**
|
||||
* 更新用户对象。
|
||||
*
|
||||
* @param user 更新的用户对象。
|
||||
* @param originalUser 原有的用户对象。
|
||||
* @param roleIdSet 用户角色Id列表。
|
||||
* @param deptPostIdSet 部门岗位Id集合。
|
||||
* @param dataPermIdSet 数据权限Id集合。
|
||||
* @return 更新成功返回true,否则false。
|
||||
*/
|
||||
boolean update(SysUser user, SysUser originalUser, Set<Long> roleIdSet, Set<Long> deptPostIdSet, Set<Long> dataPermIdSet);
|
||||
|
||||
/**
|
||||
* 修改用户密码。
|
||||
* @param userId 用户主键Id。
|
||||
* @param newPass 新密码。
|
||||
* @return 成功返回true,否则false。
|
||||
*/
|
||||
boolean changePassword(Long userId, String newPass);
|
||||
|
||||
/**
|
||||
* 修改用户头像。
|
||||
*
|
||||
* @param userId 用户主键Id。
|
||||
* @param newHeadImage 新的头像信息。
|
||||
* @return 成功返回true,否则false。
|
||||
*/
|
||||
boolean changeHeadImage(Long userId, String newHeadImage);
|
||||
|
||||
/**
|
||||
* 删除指定数据。
|
||||
*
|
||||
* @param userId 主键Id。
|
||||
* @return 成功返回true,否则false。
|
||||
*/
|
||||
boolean remove(Long userId);
|
||||
|
||||
/**
|
||||
* 获取单表查询结果。由于没有关联数据查询,因此在仅仅获取单表数据的场景下,效率更高。
|
||||
* 如果需要同时获取关联数据,请移步(getSysUserListWithRelation)方法。
|
||||
*
|
||||
* @param filter 过滤对象。
|
||||
* @param orderBy 排序参数。
|
||||
* @return 查询结果集。
|
||||
*/
|
||||
List<SysUser> getSysUserList(SysUser filter, String orderBy);
|
||||
|
||||
/**
|
||||
* 获取主表的查询结果,以及主表关联的字典数据和一对一从表数据,以及一对一从表的字典数据。
|
||||
* 该查询会涉及到一对一从表的关联过滤,或一对多从表的嵌套关联过滤,因此性能不如单表过滤。
|
||||
* 如果仅仅需要获取主表数据,请移步(getSysUserList),以便获取更好的查询性能。
|
||||
*
|
||||
* @param filter 主表过滤对象。
|
||||
* @param orderBy 排序参数。
|
||||
* @return 查询结果集。
|
||||
*/
|
||||
List<SysUser> getSysUserListWithRelation(SysUser filter, String orderBy);
|
||||
|
||||
/**
|
||||
* 获取指定角色的用户列表。
|
||||
*
|
||||
* @param roleId 角色主键Id。
|
||||
* @param filter 用户过滤对象。
|
||||
* @param orderBy 排序参数。
|
||||
* @return 用户列表。
|
||||
*/
|
||||
List<SysUser> getSysUserListByRoleId(Long roleId, SysUser filter, String orderBy);
|
||||
|
||||
/**
|
||||
* 获取不属于指定角色的用户列表。
|
||||
*
|
||||
* @param roleId 角色主键Id。
|
||||
* @param filter 用户过滤对象。
|
||||
* @param orderBy 排序参数。
|
||||
* @return 用户列表。
|
||||
*/
|
||||
List<SysUser> getNotInSysUserListByRoleId(Long roleId, SysUser filter, String orderBy);
|
||||
|
||||
/**
|
||||
* 获取指定数据权限的用户列表。
|
||||
*
|
||||
* @param dataPermId 数据权限主键Id。
|
||||
* @param filter 用户过滤对象。
|
||||
* @param orderBy 排序参数。
|
||||
* @return 用户列表。
|
||||
*/
|
||||
List<SysUser> getSysUserListByDataPermId(Long dataPermId, SysUser filter, String orderBy);
|
||||
|
||||
/**
|
||||
* 获取不属于指定数据权限的用户列表。
|
||||
*
|
||||
* @param dataPermId 数据权限主键Id。
|
||||
* @param filter 用户过滤对象。
|
||||
* @param orderBy 排序参数。
|
||||
* @return 用户列表。
|
||||
*/
|
||||
List<SysUser> getNotInSysUserListByDataPermId(Long dataPermId, SysUser filter, String orderBy);
|
||||
|
||||
/**
|
||||
* 获取指定部门岗位的用户列表。
|
||||
*
|
||||
* @param deptPostId 部门岗位主键Id。
|
||||
* @param filter 用户过滤对象。
|
||||
* @param orderBy 排序参数。
|
||||
* @return 用户列表。
|
||||
*/
|
||||
List<SysUser> getSysUserListByDeptPostId(Long deptPostId, SysUser filter, String orderBy);
|
||||
|
||||
/**
|
||||
* 获取不属于指定部门岗位的用户列表。
|
||||
*
|
||||
* @param deptPostId 部门岗位主键Id。
|
||||
* @param filter 用户过滤对象。
|
||||
* @param orderBy 排序参数。
|
||||
* @return 用户列表。
|
||||
*/
|
||||
List<SysUser> getNotInSysUserListByDeptPostId(Long deptPostId, SysUser filter, String orderBy);
|
||||
|
||||
/**
|
||||
* 获取指定岗位的用户列表。
|
||||
*
|
||||
* @param postId 岗位主键Id。
|
||||
* @param filter 用户过滤对象。
|
||||
* @param orderBy 排序参数。
|
||||
* @return 用户列表。
|
||||
*/
|
||||
List<SysUser> getSysUserListByPostId(Long postId, SysUser filter, String orderBy);
|
||||
|
||||
/**
|
||||
* 验证用户对象关联的数据是否都合法。
|
||||
*
|
||||
* @param sysUser 当前操作的对象。
|
||||
* @param originalSysUser 原有对象。
|
||||
* @param roleIds 逗号分隔的角色Id列表字符串。
|
||||
* @param deptPostIds 逗号分隔的部门岗位Id列表字符串。
|
||||
* @param dataPermIds 逗号分隔的数据权限Id列表字符串。
|
||||
* @return 验证结果。
|
||||
*/
|
||||
CallResult verifyRelatedData(
|
||||
SysUser sysUser, SysUser originalSysUser, String roleIds, String deptPostIds, String dataPermIds);
|
||||
}
|
||||
@@ -0,0 +1,345 @@
|
||||
package com.orangeforms.webadmin.upms.service.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
||||
import com.orangeforms.common.sequence.wrapper.IdGeneratorWrapper;
|
||||
import com.orangeforms.common.core.constant.DataPermRuleType;
|
||||
import com.orangeforms.common.core.base.service.BaseService;
|
||||
import com.orangeforms.common.core.base.dao.BaseDaoMapper;
|
||||
import com.orangeforms.common.core.object.MyRelationParam;
|
||||
import com.orangeforms.common.core.object.CallResult;
|
||||
import com.orangeforms.common.core.util.MyModelUtil;
|
||||
import com.orangeforms.common.core.util.RedisKeyUtil;
|
||||
import com.orangeforms.common.core.constant.ApplicationConstant;
|
||||
import com.orangeforms.webadmin.config.ApplicationConfig;
|
||||
import com.orangeforms.webadmin.upms.dao.SysDataPermDeptMapper;
|
||||
import com.orangeforms.webadmin.upms.dao.SysDataPermMapper;
|
||||
import com.orangeforms.webadmin.upms.dao.SysDataPermUserMapper;
|
||||
import com.orangeforms.webadmin.upms.dao.SysDataPermMenuMapper;
|
||||
import com.orangeforms.webadmin.upms.model.*;
|
||||
import com.orangeforms.webadmin.upms.service.SysDataPermService;
|
||||
import com.orangeforms.webadmin.upms.service.SysDeptService;
|
||||
import com.orangeforms.webadmin.upms.service.SysMenuService;
|
||||
import com.orangeforms.webadmin.upms.service.SysUserService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.redisson.api.RBucket;
|
||||
import org.redisson.api.RedissonClient;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 数据权限数据服务类。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
@Slf4j
|
||||
@Service("sysDataPermService")
|
||||
public class SysDataPermServiceImpl extends BaseService<SysDataPerm, Long> implements SysDataPermService {
|
||||
|
||||
@Autowired
|
||||
private SysDataPermMapper sysDataPermMapper;
|
||||
@Autowired
|
||||
private SysDataPermDeptMapper sysDataPermDeptMapper;
|
||||
@Autowired
|
||||
private SysDataPermUserMapper sysDataPermUserMapper;
|
||||
@Autowired
|
||||
private SysDataPermMenuMapper sysDataPermMenuMapper;
|
||||
@Autowired
|
||||
private SysUserService sysUserService;
|
||||
@Autowired
|
||||
private SysDeptService sysDeptService;
|
||||
@Autowired
|
||||
private SysMenuService sysMenuService;
|
||||
@Autowired
|
||||
private RedissonClient redissonClient;
|
||||
@Autowired
|
||||
private ApplicationConfig applicationConfig;
|
||||
@Autowired
|
||||
private IdGeneratorWrapper idGenerator;
|
||||
|
||||
/**
|
||||
* 返回主对象的Mapper对象。
|
||||
*
|
||||
* @return 主对象的Mapper对象。
|
||||
*/
|
||||
@Override
|
||||
protected BaseDaoMapper<SysDataPerm> mapper() {
|
||||
return sysDataPermMapper;
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public SysDataPerm saveNew(SysDataPerm dataPerm, Set<Long> deptIdSet, Set<Long> menuIdSet) {
|
||||
dataPerm.setDataPermId(idGenerator.nextLongId());
|
||||
MyModelUtil.fillCommonsForInsert(dataPerm);
|
||||
sysDataPermMapper.insert(dataPerm);
|
||||
this.insertRelationData(dataPerm, deptIdSet, menuIdSet);
|
||||
return dataPerm;
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public boolean update(
|
||||
SysDataPerm dataPerm, SysDataPerm originalDataPerm, Set<Long> deptIdSet, Set<Long> menuIdSet) {
|
||||
MyModelUtil.fillCommonsForUpdate(dataPerm, originalDataPerm);
|
||||
UpdateWrapper<SysDataPerm> uw = this.createUpdateQueryForNullValue(dataPerm, dataPerm.getDataPermId());
|
||||
if (sysDataPermMapper.update(dataPerm, uw) != 1) {
|
||||
return false;
|
||||
}
|
||||
SysDataPermDept dataPermDept = new SysDataPermDept();
|
||||
dataPermDept.setDataPermId(dataPerm.getDataPermId());
|
||||
sysDataPermDeptMapper.delete(new QueryWrapper<>(dataPermDept));
|
||||
SysDataPermMenu dataPermMenu = new SysDataPermMenu();
|
||||
dataPermMenu.setDataPermId(dataPerm.getDataPermId());
|
||||
sysDataPermMenuMapper.delete(new QueryWrapper<>(dataPermMenu));
|
||||
this.insertRelationData(dataPerm, deptIdSet, menuIdSet);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public boolean remove(Long dataPermId) {
|
||||
if (sysDataPermMapper.deleteById(dataPermId) != 1) {
|
||||
return false;
|
||||
}
|
||||
SysDataPermDept dataPermDept = new SysDataPermDept();
|
||||
dataPermDept.setDataPermId(dataPermId);
|
||||
sysDataPermDeptMapper.delete(new QueryWrapper<>(dataPermDept));
|
||||
SysDataPermUser dataPermUser = new SysDataPermUser();
|
||||
dataPermUser.setDataPermId(dataPermId);
|
||||
sysDataPermUserMapper.delete(new QueryWrapper<>(dataPermUser));
|
||||
SysDataPermMenu dataPermMenu = new SysDataPermMenu();
|
||||
dataPermMenu.setDataPermId(dataPermId);
|
||||
sysDataPermMenuMapper.delete(new QueryWrapper<>(dataPermMenu));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SysDataPerm> getSysDataPermListWithRelation(SysDataPerm filter, String orderBy) {
|
||||
List<SysDataPerm> resultList = sysDataPermMapper.getSysDataPermList(filter, orderBy);
|
||||
buildRelationForDataList(resultList, MyRelationParam.full(), CollUtil.newHashSet("dataPermDeptList"));
|
||||
return resultList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putDataPermCache(String sessionId, Long userId, Long deptId) {
|
||||
Map<String, Map<Integer, String>> menuDataPermMap = getSysDataPermListByUserId(userId, deptId);
|
||||
if (menuDataPermMap.size() > 0) {
|
||||
String dataPermSessionKey = RedisKeyUtil.makeSessionDataPermIdKey(sessionId);
|
||||
RBucket<String> bucket = redissonClient.getBucket(dataPermSessionKey);
|
||||
bucket.set(JSON.toJSONString(menuDataPermMap),
|
||||
applicationConfig.getSessionExpiredSeconds(), TimeUnit.SECONDS);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeDataPermCache(String sessionId) {
|
||||
String sessionPermKey = RedisKeyUtil.makeSessionDataPermIdKey(sessionId);
|
||||
redissonClient.getBucket(sessionPermKey).deleteAsync();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Map<Integer, String>> getSysDataPermListByUserId(Long userId, Long deptId) {
|
||||
List<SysDataPerm> dataPermList = sysDataPermMapper.getSysDataPermListByUserId(userId);
|
||||
dataPermList.forEach(dataPerm -> {
|
||||
if (CollUtil.isNotEmpty(dataPerm.getDataPermDeptList())) {
|
||||
Set<Long> deptIdSet = dataPerm.getDataPermDeptList().stream()
|
||||
.map(SysDataPermDept::getDeptId).collect(Collectors.toSet());
|
||||
dataPerm.setDeptIdListString(StrUtil.join(",", deptIdSet));
|
||||
}
|
||||
});
|
||||
Map<String, List<SysDataPerm>> menuIdMap = new HashMap<>(4);
|
||||
for (SysDataPerm dataPerm : dataPermList) {
|
||||
if (CollUtil.isNotEmpty(dataPerm.getDataPermMenuList())) {
|
||||
for (SysDataPermMenu dataPermMenu : dataPerm.getDataPermMenuList()) {
|
||||
menuIdMap.computeIfAbsent(
|
||||
dataPermMenu.getMenuId().toString(), k -> new LinkedList<>()).add(dataPerm);
|
||||
}
|
||||
} else {
|
||||
menuIdMap.computeIfAbsent(
|
||||
ApplicationConstant.DATA_PERM_ALL_MENU_ID, k -> new LinkedList<>()).add(dataPerm);
|
||||
}
|
||||
}
|
||||
Map<String, Map<Integer, String>> menuResultMap = new HashMap<>(menuIdMap.size());
|
||||
for (Map.Entry<String, List<SysDataPerm>> entry : menuIdMap.entrySet()) {
|
||||
Map<Integer, String> resultMap = this.mergeAndOptimizeDataPermRule(entry.getValue(), deptId);
|
||||
menuResultMap.put(entry.getKey(), resultMap);
|
||||
}
|
||||
return menuResultMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SysDataPerm> getSysDataPermListByMenuId(Long menuId) {
|
||||
return sysDataPermMapper.getSysDataPermListByMenuId(menuId);
|
||||
}
|
||||
|
||||
private Map<Integer, String> mergeAndOptimizeDataPermRule(List<SysDataPerm> dataPermList, Long deptId) {
|
||||
// 为了更方便进行后续的合并优化处理,这里再基于菜单Id和规则类型进行分组。ruleMap的key是规则类型。
|
||||
Map<Integer, List<SysDataPerm>> ruleMap =
|
||||
dataPermList.stream().collect(Collectors.groupingBy(SysDataPerm::getRuleType));
|
||||
Map<Integer, String> resultMap = new HashMap<>(ruleMap.size());
|
||||
// 如有有ALL存在,就可以直接退出了,没有必要在处理后续的规则了。
|
||||
if (ruleMap.containsKey(DataPermRuleType.TYPE_ALL)) {
|
||||
resultMap.put(DataPermRuleType.TYPE_ALL, "null");
|
||||
return resultMap;
|
||||
}
|
||||
// 这里优先合并最复杂的多部门及子部门场景。
|
||||
String deptIds = processMultiDeptAndChildren(ruleMap, deptId);
|
||||
if (deptIds != null) {
|
||||
resultMap.put(DataPermRuleType.TYPE_MULTI_DEPT_AND_CHILD_DEPT, deptIds);
|
||||
}
|
||||
// 合并当前部门及子部门的优化
|
||||
if (ruleMap.get(DataPermRuleType.TYPE_DEPT_AND_CHILD_DEPT) != null) {
|
||||
// 需要与仅仅当前部门规则进行合并。
|
||||
ruleMap.remove(DataPermRuleType.TYPE_DEPT_ONLY);
|
||||
resultMap.put(DataPermRuleType.TYPE_DEPT_AND_CHILD_DEPT, "null");
|
||||
}
|
||||
// 合并自定义部门了。
|
||||
deptIds = processMultiDept(ruleMap, deptId);
|
||||
if (deptIds != null) {
|
||||
resultMap.put(DataPermRuleType.TYPE_CUSTOM_DEPT_LIST, deptIds);
|
||||
}
|
||||
// 最后处理当前部门和当前用户。
|
||||
if (ruleMap.get(DataPermRuleType.TYPE_DEPT_ONLY) != null) {
|
||||
resultMap.put(DataPermRuleType.TYPE_DEPT_ONLY, "null");
|
||||
}
|
||||
if (ruleMap.get(DataPermRuleType.TYPE_DEPT_AND_CHILD_DEPT_USERS) != null) {
|
||||
// 合并当前部门用户和当前用户
|
||||
ruleMap.remove(DataPermRuleType.TYPE_USER_ONLY);
|
||||
ruleMap.remove(DataPermRuleType.TYPE_DEPT_USERS);
|
||||
SysUser filter = new SysUser();
|
||||
filter.setDeptId(deptId);
|
||||
List<SysUser> userList = sysUserService.getSysUserList(filter, null);
|
||||
Set<Long> userIdSet = userList.stream().map(SysUser::getUserId).collect(Collectors.toSet());
|
||||
resultMap.put(DataPermRuleType.TYPE_DEPT_AND_CHILD_DEPT_USERS, CollUtil.join(userIdSet, ","));
|
||||
}
|
||||
if (ruleMap.get(DataPermRuleType.TYPE_DEPT_USERS) != null) {
|
||||
SysUser filter = new SysUser();
|
||||
filter.setDeptId(deptId);
|
||||
List<SysUser> userList = sysUserService.getListByFilter(filter);
|
||||
Set<Long> userIdSet = userList.stream().map(SysUser::getUserId).collect(Collectors.toSet());
|
||||
// 合并仅当前用户
|
||||
ruleMap.remove(DataPermRuleType.TYPE_USER_ONLY);
|
||||
resultMap.put(DataPermRuleType.TYPE_DEPT_USERS, CollUtil.join(userIdSet, ","));
|
||||
}
|
||||
if (ruleMap.get(DataPermRuleType.TYPE_USER_ONLY) != null) {
|
||||
resultMap.put(DataPermRuleType.TYPE_USER_ONLY, "null");
|
||||
}
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
private String processMultiDeptAndChildren(Map<Integer, List<SysDataPerm>> ruleMap, Long deptId) {
|
||||
List<SysDataPerm> parentDeptList = ruleMap.get(DataPermRuleType.TYPE_MULTI_DEPT_AND_CHILD_DEPT);
|
||||
if (parentDeptList == null) {
|
||||
return null;
|
||||
}
|
||||
Set<Long> deptIdSet = new HashSet<>();
|
||||
for (SysDataPerm parentDept : parentDeptList) {
|
||||
deptIdSet.addAll(StrUtil.split(parentDept.getDeptIdListString(), ',')
|
||||
.stream().map(Long::valueOf).collect(Collectors.toSet()));
|
||||
}
|
||||
// 在合并所有的多父部门Id之后,需要判断是否有本部门及子部门的规则。如果有,就继续合并。
|
||||
if (ruleMap.containsKey(DataPermRuleType.TYPE_DEPT_AND_CHILD_DEPT)) {
|
||||
// 如果多父部门列表中包含当前部门,那么可以直接删除该规则了,如果没包含,就加入到多部门的DEPT_ID的IN LIST中。
|
||||
deptIdSet.add(deptId);
|
||||
ruleMap.remove(DataPermRuleType.TYPE_DEPT_AND_CHILD_DEPT);
|
||||
}
|
||||
// 需要与仅仅当前部门规则进行合并。
|
||||
if (ruleMap.containsKey(DataPermRuleType.TYPE_DEPT_ONLY) && deptIdSet.contains(deptId)) {
|
||||
ruleMap.remove(DataPermRuleType.TYPE_DEPT_ONLY);
|
||||
}
|
||||
return StrUtil.join(",", deptIdSet);
|
||||
}
|
||||
|
||||
private String processMultiDept(Map<Integer, List<SysDataPerm>> ruleMap, Long deptId) {
|
||||
List<SysDataPerm> customDeptList = ruleMap.get(DataPermRuleType.TYPE_CUSTOM_DEPT_LIST);
|
||||
if (customDeptList == null) {
|
||||
return null;
|
||||
}
|
||||
Set<Long> deptIdSet = new HashSet<>();
|
||||
for (SysDataPerm customDept : customDeptList) {
|
||||
deptIdSet.addAll(StrUtil.split(customDept.getDeptIdListString(), ',')
|
||||
.stream().map(Long::valueOf).collect(Collectors.toSet()));
|
||||
}
|
||||
if (ruleMap.containsKey(DataPermRuleType.TYPE_DEPT_ONLY)) {
|
||||
deptIdSet.add(deptId);
|
||||
ruleMap.remove(DataPermRuleType.TYPE_DEPT_ONLY);
|
||||
}
|
||||
return StrUtil.join(",", deptIdSet);
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public void addDataPermUserList(Long dataPermId, Set<Long> userIdSet) {
|
||||
for (Long userId : userIdSet) {
|
||||
SysDataPermUser dataPermUser = new SysDataPermUser();
|
||||
dataPermUser.setDataPermId(dataPermId);
|
||||
dataPermUser.setUserId(userId);
|
||||
sysDataPermUserMapper.insert(dataPermUser);
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public boolean removeDataPermUser(Long dataPermId, Long userId) {
|
||||
SysDataPermUser dataPermUser = new SysDataPermUser();
|
||||
dataPermUser.setDataPermId(dataPermId);
|
||||
dataPermUser.setUserId(userId);
|
||||
return sysDataPermUserMapper.delete(new QueryWrapper<>(dataPermUser)) == 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CallResult verifyRelatedData(SysDataPerm dataPerm, String deptIdListString, String menuIdListString) {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
if (dataPerm.getRuleType() == DataPermRuleType.TYPE_MULTI_DEPT_AND_CHILD_DEPT
|
||||
|| dataPerm.getRuleType() == DataPermRuleType.TYPE_CUSTOM_DEPT_LIST) {
|
||||
if (StrUtil.isBlank(deptIdListString)) {
|
||||
return CallResult.error("数据验证失败,部门列表不能为空!");
|
||||
}
|
||||
Set<Long> deptIdSet = StrUtil.split(
|
||||
deptIdListString, ",").stream().map(Long::valueOf).collect(Collectors.toSet());
|
||||
if (!sysDeptService.existAllPrimaryKeys(deptIdSet)) {
|
||||
return CallResult.error("数据验证失败,存在不合法的部门数据,请刷新后重试!");
|
||||
}
|
||||
jsonObject.put("deptIdSet", deptIdSet);
|
||||
}
|
||||
if (StrUtil.isNotBlank(menuIdListString)) {
|
||||
Set<Long> menuIdSet = StrUtil.split(
|
||||
menuIdListString, ",").stream().map(Long::valueOf).collect(Collectors.toSet());
|
||||
if (!sysMenuService.existAllPrimaryKeys(menuIdSet)) {
|
||||
return CallResult.error("数据验证失败,存在不合法的菜单数据,请刷新后重试!");
|
||||
}
|
||||
jsonObject.put("menuIdSet", menuIdSet);
|
||||
}
|
||||
return CallResult.ok(jsonObject);
|
||||
}
|
||||
|
||||
private void insertRelationData(SysDataPerm dataPerm, Set<Long> deptIdSet, Set<Long> menuIdSet) {
|
||||
if (CollUtil.isNotEmpty(deptIdSet)) {
|
||||
for (Long deptId : deptIdSet) {
|
||||
SysDataPermDept dataPermDept = new SysDataPermDept();
|
||||
dataPermDept.setDataPermId(dataPerm.getDataPermId());
|
||||
dataPermDept.setDeptId(deptId);
|
||||
sysDataPermDeptMapper.insert(dataPermDept);
|
||||
}
|
||||
}
|
||||
if (CollUtil.isNotEmpty(menuIdSet)) {
|
||||
for (Long menuId : menuIdSet) {
|
||||
SysDataPermMenu dataPermMenu = new SysDataPermMenu();
|
||||
dataPermMenu.setDataPermId(dataPerm.getDataPermId());
|
||||
dataPermMenu.setMenuId(menuId);
|
||||
sysDataPermMenuMapper.insert(dataPermMenu);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,316 @@
|
||||
package com.orangeforms.webadmin.upms.service.impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.*;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
||||
import com.github.pagehelper.page.PageMethod;
|
||||
import com.orangeforms.webadmin.upms.service.*;
|
||||
import com.orangeforms.webadmin.upms.dao.*;
|
||||
import com.orangeforms.webadmin.upms.model.*;
|
||||
import com.orangeforms.common.ext.util.BizWidgetDatasourceExtHelper;
|
||||
import com.orangeforms.common.ext.base.BizWidgetDatasource;
|
||||
import com.orangeforms.common.ext.constant.BizWidgetDatasourceType;
|
||||
import com.orangeforms.common.core.base.dao.BaseDaoMapper;
|
||||
import com.orangeforms.common.core.constant.GlobalDeletedFlag;
|
||||
import com.orangeforms.common.core.object.*;
|
||||
import com.orangeforms.common.core.base.service.BaseService;
|
||||
import com.orangeforms.common.core.util.MyModelUtil;
|
||||
import com.orangeforms.common.core.util.MyPageUtil;
|
||||
import com.orangeforms.common.sequence.wrapper.IdGeneratorWrapper;
|
||||
import com.github.pagehelper.Page;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 部门管理数据操作服务类。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
@Slf4j
|
||||
@Service("sysDeptService")
|
||||
public class SysDeptServiceImpl extends BaseService<SysDept, Long> implements SysDeptService, BizWidgetDatasource {
|
||||
|
||||
@Autowired
|
||||
private IdGeneratorWrapper idGenerator;
|
||||
@Autowired
|
||||
private SysDeptMapper sysDeptMapper;
|
||||
@Autowired
|
||||
private SysDeptRelationMapper sysDeptRelationMapper;
|
||||
@Autowired
|
||||
private SysUserService sysUserService;
|
||||
@Autowired
|
||||
private SysDeptPostMapper sysDeptPostMapper;
|
||||
@Autowired
|
||||
private SysDataPermDeptMapper sysDataPermDeptMapper;
|
||||
@Autowired
|
||||
private BizWidgetDatasourceExtHelper bizWidgetDatasourceExtHelper;
|
||||
|
||||
/**
|
||||
* 返回当前Service的主表Mapper对象。
|
||||
*
|
||||
* @return 主表Mapper对象。
|
||||
*/
|
||||
@Override
|
||||
protected BaseDaoMapper<SysDept> mapper() {
|
||||
return sysDeptMapper;
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
private void registerBizWidgetDatasource() {
|
||||
bizWidgetDatasourceExtHelper.registerDatasource(BizWidgetDatasourceType.UPMS_DEPT_TYPE, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyPageData<Map<String, Object>> getDataList(
|
||||
String type, Map<String, Object> filter, MyOrderParam orderParam, MyPageParam pageParam) {
|
||||
if (pageParam != null) {
|
||||
PageMethod.startPage(pageParam.getPageNum(), pageParam.getPageSize(), pageParam.getCount());
|
||||
}
|
||||
String orderBy = orderParam == null ? null : MyOrderParam.buildOrderBy(orderParam, SysDept.class);
|
||||
SysDept deptFilter = filter == null ? null : BeanUtil.toBean(filter, SysDept.class);
|
||||
List<SysDept> deptList = this.getSysDeptList(deptFilter, orderBy);
|
||||
this.buildRelationForDataList(deptList, MyRelationParam.dictOnly());
|
||||
return MyPageUtil.makeResponseData(deptList, BeanUtil::beanToMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Map<String, Object>> getDataListWithInList(String type, String fieldName, List<String> fieldValues) {
|
||||
List<SysDept> deptList;
|
||||
if (StrUtil.isBlank(fieldName)) {
|
||||
deptList = this.getInList(fieldValues.stream().map(Long::valueOf).collect(Collectors.toSet()));
|
||||
} else {
|
||||
deptList = this.getInList(fieldName, MyModelUtil.convertToTypeValues(SysDept.class, fieldName, fieldValues));
|
||||
}
|
||||
this.buildRelationForDataList(deptList, MyRelationParam.dictOnly());
|
||||
return MyModelUtil.beanToMapList(deptList);
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public SysDept saveNew(SysDept sysDept, SysDept parentSysDept) {
|
||||
sysDept.setDeptId(idGenerator.nextLongId());
|
||||
sysDept.setDeletedFlag(GlobalDeletedFlag.NORMAL);
|
||||
MyModelUtil.fillCommonsForInsert(sysDept);
|
||||
sysDeptMapper.insert(sysDept);
|
||||
// 同步插入部门关联关系数据
|
||||
if (parentSysDept == null) {
|
||||
sysDeptRelationMapper.insert(new SysDeptRelation(sysDept.getDeptId(), sysDept.getDeptId()));
|
||||
} else {
|
||||
sysDeptRelationMapper.insertParentList(parentSysDept.getDeptId(), sysDept.getDeptId());
|
||||
}
|
||||
return sysDept;
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public boolean update(SysDept sysDept, SysDept originalSysDept) {
|
||||
MyModelUtil.fillCommonsForUpdate(sysDept, originalSysDept);
|
||||
UpdateWrapper<SysDept> uw = this.createUpdateQueryForNullValue(sysDept, sysDept.getDeptId());
|
||||
if (sysDeptMapper.update(sysDept, uw) == 0) {
|
||||
return false;
|
||||
}
|
||||
if (ObjectUtil.notEqual(sysDept.getParentId(), originalSysDept.getParentId())) {
|
||||
this.updateParentRelation(sysDept, originalSysDept);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void updateParentRelation(SysDept sysDept, SysDept originalSysDept) {
|
||||
List<Long> originalParentIdList = null;
|
||||
// 1. 因为层级关系变化了,所以要先遍历出,当前部门的原有父部门Id列表。
|
||||
if (originalSysDept.getParentId() != null) {
|
||||
LambdaQueryWrapper<SysDeptRelation> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(SysDeptRelation::getDeptId, sysDept.getDeptId());
|
||||
List<SysDeptRelation> relationList = sysDeptRelationMapper.selectList(queryWrapper);
|
||||
originalParentIdList = relationList.stream()
|
||||
.filter(c -> !c.getParentDeptId().equals(sysDept.getDeptId()))
|
||||
.map(SysDeptRelation::getParentDeptId).collect(Collectors.toList());
|
||||
}
|
||||
// 2. 毕竟当前部门的上级部门变化了,所以当前部门和他的所有子部门,与当前部门的原有所有上级部门
|
||||
// 之间的关联关系就要被移除。
|
||||
// 这里先移除当前部门的所有子部门,与当前部门的所有原有上级部门之间的关联关系。
|
||||
if (CollUtil.isNotEmpty(originalParentIdList)) {
|
||||
sysDeptRelationMapper.removeBetweenChildrenAndParents(originalParentIdList, sysDept.getDeptId());
|
||||
}
|
||||
// 这里更进一步,将当前部门Id与其原有所有上级部门Id之间的关联关系删除。
|
||||
SysDeptRelation filter = new SysDeptRelation();
|
||||
filter.setDeptId(sysDept.getDeptId());
|
||||
sysDeptRelationMapper.delete(new QueryWrapper<>(filter));
|
||||
// 3. 重新计算当前部门的新上级部门列表。
|
||||
List<Long> newParentIdList = new LinkedList<>();
|
||||
// 这里要重新计算出当前部门所有新的上级部门Id列表。
|
||||
if (sysDept.getParentId() != null) {
|
||||
LambdaQueryWrapper<SysDeptRelation> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(SysDeptRelation::getDeptId, sysDept.getParentId());
|
||||
List<SysDeptRelation> relationList = sysDeptRelationMapper.selectList(queryWrapper);
|
||||
newParentIdList = relationList.stream()
|
||||
.map(SysDeptRelation::getParentDeptId).collect(Collectors.toList());
|
||||
}
|
||||
// 4. 先查询出当前部门的所有下级子部门Id列表。
|
||||
LambdaQueryWrapper<SysDeptRelation> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(SysDeptRelation::getParentDeptId, sysDept.getDeptId());
|
||||
List<SysDeptRelation> childRelationList = sysDeptRelationMapper.selectList(queryWrapper);
|
||||
// 5. 将当前部门及其所有子部门Id与其新的所有上级部门Id之间,建立关联关系。
|
||||
List<SysDeptRelation> deptRelationList = new LinkedList<>();
|
||||
deptRelationList.add(new SysDeptRelation(sysDept.getDeptId(), sysDept.getDeptId()));
|
||||
for (Long newParentId : newParentIdList) {
|
||||
deptRelationList.add(new SysDeptRelation(newParentId, sysDept.getDeptId()));
|
||||
for (SysDeptRelation childDeptRelation : childRelationList) {
|
||||
deptRelationList.add(new SysDeptRelation(newParentId, childDeptRelation.getDeptId()));
|
||||
}
|
||||
}
|
||||
// 6. 执行批量插入SQL语句,插入当前部门Id及其所有下级子部门Id,与所有新上级部门Id之间的关联关系。
|
||||
sysDeptRelationMapper.insertList(deptRelationList);
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public boolean remove(Long deptId) {
|
||||
if (sysDeptMapper.deleteById(deptId) == 0) {
|
||||
return false;
|
||||
}
|
||||
// 这里删除当前部门及其父部门的关联关系。
|
||||
// 当前部门和子部门的关系无需在这里删除,因为包含子部门时不能删除父部门。
|
||||
SysDeptRelation deptRelation = new SysDeptRelation();
|
||||
deptRelation.setDeptId(deptId);
|
||||
sysDeptRelationMapper.delete(new QueryWrapper<>(deptRelation));
|
||||
SysDataPermDept dataPermDept = new SysDataPermDept();
|
||||
dataPermDept.setDeptId(deptId);
|
||||
sysDataPermDeptMapper.delete(new QueryWrapper<>(dataPermDept));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SysDept> getSysDeptList(SysDept filter, String orderBy) {
|
||||
return sysDeptMapper.getSysDeptList(filter, orderBy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SysDept> getSysDeptListWithRelation(SysDept filter, String orderBy) {
|
||||
List<SysDept> resultList = sysDeptMapper.getSysDeptList(filter, orderBy);
|
||||
// 在缺省生成的代码中,如果查询结果resultList不是Page对象,说明没有分页,那么就很可能是数据导出接口调用了当前方法。
|
||||
// 为了避免一次性的大量数据关联,规避因此而造成的系统运行性能冲击,这里手动进行了分批次读取,开发者可按需修改该值。
|
||||
int batchSize = resultList instanceof Page ? 0 : 1000;
|
||||
this.buildRelationForDataList(resultList, MyRelationParam.normal(), batchSize);
|
||||
return resultList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasChildren(Long deptId) {
|
||||
SysDept filter = new SysDept();
|
||||
filter.setParentId(deptId);
|
||||
return getCountByFilter(filter) > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasChildrenUser(Long deptId) {
|
||||
SysUser sysUser = new SysUser();
|
||||
sysUser.setDeptId(deptId);
|
||||
return sysUserService.getCountByFilter(sysUser) > 0;
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public void addSysDeptPostList(List<SysDeptPost> sysDeptPostList, Long deptId) {
|
||||
for (SysDeptPost sysDeptPost : sysDeptPostList) {
|
||||
sysDeptPost.setDeptPostId(idGenerator.nextLongId());
|
||||
sysDeptPost.setDeptId(deptId);
|
||||
sysDeptPostMapper.insert(sysDeptPost);
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public boolean updateSysDeptPost(SysDeptPost sysDeptPost) {
|
||||
SysDeptPost filter = new SysDeptPost();
|
||||
filter.setDeptPostId(sysDeptPost.getDeptPostId());
|
||||
filter.setDeptId(sysDeptPost.getDeptId());
|
||||
filter.setPostId(sysDeptPost.getPostId());
|
||||
UpdateWrapper<SysDeptPost> uw =
|
||||
BaseService.createUpdateQueryForNullValue(sysDeptPost, SysDeptPost.class);
|
||||
uw.setEntity(filter);
|
||||
return sysDeptPostMapper.update(sysDeptPost, uw) > 0;
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public boolean removeSysDeptPost(Long deptId, Long postId) {
|
||||
SysDeptPost filter = new SysDeptPost();
|
||||
filter.setDeptId(deptId);
|
||||
filter.setPostId(postId);
|
||||
return sysDeptPostMapper.delete(new QueryWrapper<>(filter)) > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SysDeptPost getSysDeptPost(Long deptId, Long postId) {
|
||||
SysDeptPost filter = new SysDeptPost();
|
||||
filter.setDeptId(deptId);
|
||||
filter.setPostId(postId);
|
||||
return sysDeptPostMapper.selectOne(new QueryWrapper<>(filter));
|
||||
}
|
||||
|
||||
@Override
|
||||
public SysDeptPost getSysDeptPost(Long deptPostId) {
|
||||
return sysDeptPostMapper.selectById(deptPostId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Map<String, Object>> getSysDeptPostListWithRelationByDeptId(Long deptId) {
|
||||
return sysDeptPostMapper.getSysDeptPostListWithRelationByDeptId(deptId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SysDeptPost> getSysDeptPostList(Long deptId, Set<Long> postIdSet) {
|
||||
LambdaQueryWrapper<SysDeptPost> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(SysDeptPost::getDeptId, deptId);
|
||||
queryWrapper.in(SysDeptPost::getPostId, postIdSet);
|
||||
return sysDeptPostMapper.selectList(queryWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SysDeptPost> getSiblingSysDeptPostList(Long deptId, Set<Long> postIdSet) {
|
||||
SysDept sysDept = this.getById(deptId);
|
||||
if (sysDept == null) {
|
||||
return new LinkedList<>();
|
||||
}
|
||||
List<SysDept> deptList = this.getListByParentId("parentId", sysDept.getParentId());
|
||||
Set<Long> deptIdSet = deptList.stream().map(SysDept::getDeptId).collect(Collectors.toSet());
|
||||
LambdaQueryWrapper<SysDeptPost> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.in(SysDeptPost::getDeptId, deptIdSet);
|
||||
queryWrapper.in(SysDeptPost::getPostId, postIdSet);
|
||||
return sysDeptPostMapper.selectList(queryWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Long> getLeaderDeptPostIdList(Long deptId) {
|
||||
List<SysDeptPost> resultList = sysDeptPostMapper.getLeaderDeptPostList(deptId);
|
||||
return resultList.stream().map(SysDeptPost::getDeptPostId).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Long> getUpLeaderDeptPostIdList(Long deptId) {
|
||||
SysDept sysDept = this.getById(deptId);
|
||||
if (sysDept.getParentId() == null) {
|
||||
return new LinkedList<>();
|
||||
}
|
||||
return this.getLeaderDeptPostIdList(sysDept.getParentId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Long> getAllChildDeptIdByParentIds(List<Long> parentIds) {
|
||||
LambdaQueryWrapper<SysDeptRelation> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.in(SysDeptRelation::getParentDeptId, parentIds);
|
||||
return sysDeptRelationMapper.selectList(queryWrapper)
|
||||
.stream().map(SysDeptRelation::getDeptId).collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,239 @@
|
||||
package com.orangeforms.webadmin.upms.service.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
||||
import com.orangeforms.common.core.base.service.BaseService;
|
||||
import com.orangeforms.common.core.base.dao.BaseDaoMapper;
|
||||
import com.orangeforms.common.core.util.MyModelUtil;
|
||||
import com.orangeforms.common.core.object.CallResult;
|
||||
import com.orangeforms.common.sequence.wrapper.IdGeneratorWrapper;
|
||||
import com.orangeforms.webadmin.upms.bo.SysMenuExtraData;
|
||||
import com.orangeforms.webadmin.upms.dao.SysMenuMapper;
|
||||
import com.orangeforms.webadmin.upms.dao.SysRoleMenuMapper;
|
||||
import com.orangeforms.webadmin.upms.model.SysMenu;
|
||||
import com.orangeforms.webadmin.upms.model.SysRoleMenu;
|
||||
import com.orangeforms.webadmin.upms.model.constant.SysMenuType;
|
||||
import com.orangeforms.webadmin.upms.model.constant.SysOnlineMenuPermType;
|
||||
import com.orangeforms.webadmin.upms.service.SysMenuService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 菜单数据服务类。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
@Slf4j
|
||||
@Service("sysMenuService")
|
||||
public class SysMenuServiceImpl extends BaseService<SysMenu, Long> implements SysMenuService {
|
||||
|
||||
@Autowired
|
||||
private SysMenuMapper sysMenuMapper;
|
||||
@Autowired
|
||||
private SysRoleMenuMapper sysRoleMenuMapper;
|
||||
@Autowired
|
||||
private IdGeneratorWrapper idGenerator;
|
||||
|
||||
/**
|
||||
* 返回主对象的Mapper对象。
|
||||
*
|
||||
* @return 主对象的Mapper对象。
|
||||
*/
|
||||
@Override
|
||||
protected BaseDaoMapper<SysMenu> mapper() {
|
||||
return sysMenuMapper;
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public SysMenu saveNew(SysMenu sysMenu) {
|
||||
sysMenu.setMenuId(idGenerator.nextLongId());
|
||||
MyModelUtil.fillCommonsForInsert(sysMenu);
|
||||
sysMenuMapper.insert(sysMenu);
|
||||
// 判断当前菜单是否为指向在线表单的菜单,并将根据约定,动态插入两个子菜单。
|
||||
if (sysMenu.getOnlineFormId() != null && sysMenu.getOnlineFlowEntryId() == null) {
|
||||
SysMenu viewSubMenu = new SysMenu();
|
||||
viewSubMenu.setMenuId(idGenerator.nextLongId());
|
||||
viewSubMenu.setParentId(sysMenu.getMenuId());
|
||||
viewSubMenu.setMenuType(SysMenuType.TYPE_BUTTON);
|
||||
viewSubMenu.setMenuName("查看");
|
||||
viewSubMenu.setShowOrder(0);
|
||||
viewSubMenu.setOnlineFormId(sysMenu.getOnlineFormId());
|
||||
viewSubMenu.setOnlineMenuPermType(SysOnlineMenuPermType.TYPE_VIEW);
|
||||
MyModelUtil.fillCommonsForInsert(viewSubMenu);
|
||||
sysMenuMapper.insert(viewSubMenu);
|
||||
SysMenu editSubMenu = new SysMenu();
|
||||
editSubMenu.setMenuId(idGenerator.nextLongId());
|
||||
editSubMenu.setParentId(sysMenu.getMenuId());
|
||||
editSubMenu.setMenuType(SysMenuType.TYPE_BUTTON);
|
||||
editSubMenu.setMenuName("编辑");
|
||||
editSubMenu.setShowOrder(1);
|
||||
editSubMenu.setOnlineFormId(sysMenu.getOnlineFormId());
|
||||
editSubMenu.setOnlineMenuPermType(SysOnlineMenuPermType.TYPE_EDIT);
|
||||
MyModelUtil.fillCommonsForInsert(editSubMenu);
|
||||
sysMenuMapper.insert(editSubMenu);
|
||||
}
|
||||
return sysMenu;
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public boolean update(SysMenu sysMenu, SysMenu originalSysMenu) {
|
||||
MyModelUtil.fillCommonsForUpdate(sysMenu, originalSysMenu);
|
||||
sysMenu.setMenuType(originalSysMenu.getMenuType());
|
||||
UpdateWrapper<SysMenu> uw = this.createUpdateQueryForNullValue(sysMenu, sysMenu.getMenuId());
|
||||
if (sysMenuMapper.update(sysMenu, uw) != 1) {
|
||||
return false;
|
||||
}
|
||||
// 如果当前菜单的在线表单Id变化了,就需要同步更新他的内置子菜单也同步更新。
|
||||
if (ObjectUtil.notEqual(originalSysMenu.getOnlineFormId(), sysMenu.getOnlineFormId())) {
|
||||
SysMenu onlineSubMenu = new SysMenu();
|
||||
onlineSubMenu.setOnlineFormId(sysMenu.getOnlineFormId());
|
||||
sysMenuMapper.update(onlineSubMenu,
|
||||
new QueryWrapper<SysMenu>().lambda().eq(SysMenu::getParentId, sysMenu.getMenuId()));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public boolean remove(SysMenu menu) {
|
||||
Long menuId = menu.getMenuId();
|
||||
if (sysMenuMapper.delete(new LambdaQueryWrapper<SysMenu>().eq(SysMenu::getMenuId, menuId)) != 1) {
|
||||
return false;
|
||||
}
|
||||
SysRoleMenu roleMenu = new SysRoleMenu();
|
||||
roleMenu.setMenuId(menuId);
|
||||
sysRoleMenuMapper.delete(new QueryWrapper<>(roleMenu));
|
||||
// 如果为指向在线表单的菜单,则连同删除子菜单
|
||||
if (menu.getOnlineFormId() != null) {
|
||||
SysMenu filter = new SysMenu();
|
||||
filter.setParentId(menuId);
|
||||
List<SysMenu> childMenus = sysMenuMapper.selectList(new QueryWrapper<>(filter));
|
||||
sysMenuMapper.delete(new LambdaQueryWrapper<SysMenu>().eq(SysMenu::getParentId, menuId));
|
||||
if (CollUtil.isNotEmpty(childMenus)) {
|
||||
List<Long> childMenuIds = childMenus.stream().map(SysMenu::getMenuId).collect(Collectors.toList());
|
||||
LambdaQueryWrapper<SysRoleMenu> qw = new LambdaQueryWrapper<>();
|
||||
qw.in(SysRoleMenu::getMenuId, childMenuIds);
|
||||
sysRoleMenuMapper.delete(qw);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<SysMenu> getMenuListByUserId(Long userId) {
|
||||
List<SysMenu> menuList = sysMenuMapper.getMenuListByUserId(userId);
|
||||
return this.distinctMenuList(menuList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<SysMenu> getMenuListByRoleIds(String roleIds) {
|
||||
if (StrUtil.isBlank(roleIds)) {
|
||||
return CollUtil.empty(Long.class);
|
||||
}
|
||||
Set<Long> roleIdSet = StrUtil.split(roleIds, ",").stream().map(Long::valueOf).collect(Collectors.toSet());
|
||||
List<SysMenu> menuList = sysMenuMapper.getMenuListByRoleIds(roleIdSet);
|
||||
return this.distinctMenuList(menuList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasChildren(Long menuId) {
|
||||
SysMenu menu = new SysMenu();
|
||||
menu.setParentId(menuId);
|
||||
return this.getCountByFilter(menu) > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CallResult verifyRelatedData(SysMenu sysMenu, SysMenu originalSysMenu) {
|
||||
// menu、ui fragment和button类型的menu不能没有parentId
|
||||
if (sysMenu.getParentId() == null && sysMenu.getMenuType() != SysMenuType.TYPE_DIRECTORY) {
|
||||
return CallResult.error("数据验证失败,当前类型菜单项的上级菜单不能为空!");
|
||||
}
|
||||
if (this.needToVerify(sysMenu, originalSysMenu, SysMenu::getParentId)) {
|
||||
String errorMessage = checkErrorOfNonDirectoryMenu(sysMenu);
|
||||
if (errorMessage != null) {
|
||||
return CallResult.error(errorMessage);
|
||||
}
|
||||
}
|
||||
if (!this.verifyMenuCode(sysMenu, originalSysMenu)) {
|
||||
return CallResult.error("数据验证失败,菜单编码已存在,不能重复使用!");
|
||||
}
|
||||
return CallResult.ok();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SysMenu> getAllOnlineMenuList(Integer menuType) {
|
||||
LambdaQueryWrapper<SysMenu> queryWrapper =
|
||||
new QueryWrapper<SysMenu>().lambda().isNotNull(SysMenu::getOnlineFormId);
|
||||
if (menuType != null) {
|
||||
queryWrapper.eq(SysMenu::getMenuType, menuType);
|
||||
}
|
||||
return sysMenuMapper.selectList(queryWrapper);
|
||||
}
|
||||
|
||||
private boolean verifyMenuCode(SysMenu sysMenu, SysMenu originalSysMenu) {
|
||||
if (sysMenu.getExtraData() == null) {
|
||||
return true;
|
||||
}
|
||||
String menuCode = JSON.parseObject(sysMenu.getExtraData(), SysMenuExtraData.class).getMenuCode();
|
||||
if (StrUtil.isBlank(menuCode)) {
|
||||
return true;
|
||||
}
|
||||
String originalMenuCode = "";
|
||||
if (originalSysMenu != null && originalSysMenu.getExtraData() != null) {
|
||||
originalMenuCode = JSON.parseObject(originalSysMenu.getExtraData(), SysMenuExtraData.class).getMenuCode();
|
||||
}
|
||||
return StrUtil.equals(menuCode, originalMenuCode)
|
||||
|| sysMenuMapper.countMenuCode("\"menuCode\":\"" + menuCode + "\"") == 0;
|
||||
}
|
||||
|
||||
private String checkErrorOfNonDirectoryMenu(SysMenu sysMenu) {
|
||||
// 判断父节点是否存在
|
||||
SysMenu parentSysMenu = getById(sysMenu.getParentId());
|
||||
if (parentSysMenu == null) {
|
||||
return "数据验证失败,关联的上级菜单并不存在,请刷新后重试!";
|
||||
}
|
||||
// 逐个判断每种类型的菜单,他的父菜单的合法性,先从目录类型和菜单类型开始
|
||||
if (sysMenu.getMenuType() == SysMenuType.TYPE_DIRECTORY
|
||||
|| sysMenu.getMenuType() == SysMenuType.TYPE_MENU) {
|
||||
// 他们的上级只能是目录
|
||||
if (parentSysMenu.getMenuType() != SysMenuType.TYPE_DIRECTORY) {
|
||||
return "数据验证失败,当前类型菜单项的上级菜单只能是目录类型!";
|
||||
}
|
||||
} else if (sysMenu.getMenuType() == SysMenuType.TYPE_UI_FRAGMENT) {
|
||||
// ui fragment的上级只能是menu类型
|
||||
if (parentSysMenu.getMenuType() != SysMenuType.TYPE_MENU) {
|
||||
return "数据验证失败,当前类型菜单项的上级菜单只能是菜单类型和按钮类型!";
|
||||
}
|
||||
} else if (sysMenu.getMenuType() == SysMenuType.TYPE_BUTTON) {
|
||||
// button的上级只能是menu和ui fragment
|
||||
if (parentSysMenu.getMenuType() != SysMenuType.TYPE_MENU
|
||||
&& parentSysMenu.getMenuType() != SysMenuType.TYPE_UI_FRAGMENT) {
|
||||
return "数据验证失败,当前类型菜单项的上级菜单只能是菜单类型和UI片段类型!";
|
||||
}
|
||||
} else {
|
||||
return "数据验证失败,不支持的菜单类型!";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Collection<SysMenu> distinctMenuList(List<SysMenu> menuList) {
|
||||
LinkedHashMap<Long, SysMenu> menuMap = new LinkedHashMap<>();
|
||||
for (SysMenu menu : menuList) {
|
||||
menuMap.put(menu.getMenuId(), menu);
|
||||
}
|
||||
return menuMap.values();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.orangeforms.webadmin.upms.service.impl;
|
||||
|
||||
import com.orangeforms.common.core.base.service.BaseService;
|
||||
import com.orangeforms.common.core.base.dao.BaseDaoMapper;
|
||||
import com.orangeforms.webadmin.upms.dao.SysPermWhitelistMapper;
|
||||
import com.orangeforms.webadmin.upms.model.SysPermWhitelist;
|
||||
import com.orangeforms.webadmin.upms.service.SysPermWhitelistService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 权限资源白名单数据服务类。
|
||||
* 白名单中的权限资源,可以不受权限控制,任何用户皆可访问,一般用于常用的字典数据列表接口。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
@Slf4j
|
||||
@Service("sysPermWhitelistService")
|
||||
public class SysPermWhitelistServiceImpl extends BaseService<SysPermWhitelist, String> implements SysPermWhitelistService {
|
||||
|
||||
@Autowired
|
||||
private SysPermWhitelistMapper sysPermWhitelistMapper;
|
||||
|
||||
/**
|
||||
* 返回主对象的Mapper对象。
|
||||
*
|
||||
* @return 主对象的Mapper对象。
|
||||
*/
|
||||
@Override
|
||||
protected BaseDaoMapper<SysPermWhitelist> mapper() {
|
||||
return sysPermWhitelistMapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getWhitelistPermList() {
|
||||
List<SysPermWhitelist> dataList = this.getAllList();
|
||||
Function<SysPermWhitelist, String> getterFunc = SysPermWhitelist::getPermUrl;
|
||||
return dataList.stream()
|
||||
.filter(x -> getterFunc.apply(x) != null).map(getterFunc).collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,186 @@
|
||||
package com.orangeforms.webadmin.upms.service.impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
||||
import com.github.pagehelper.Page;
|
||||
import com.github.pagehelper.page.PageMethod;
|
||||
import com.orangeforms.common.core.base.dao.BaseDaoMapper;
|
||||
import com.orangeforms.common.core.base.service.BaseService;
|
||||
import com.orangeforms.common.core.object.MyOrderParam;
|
||||
import com.orangeforms.common.core.object.MyPageData;
|
||||
import com.orangeforms.common.core.object.MyPageParam;
|
||||
import com.orangeforms.common.core.object.MyRelationParam;
|
||||
import com.orangeforms.common.core.util.MyModelUtil;
|
||||
import com.orangeforms.common.core.util.MyPageUtil;
|
||||
import com.orangeforms.common.ext.base.BizWidgetDatasource;
|
||||
import com.orangeforms.common.ext.constant.BizWidgetDatasourceType;
|
||||
import com.orangeforms.common.ext.util.BizWidgetDatasourceExtHelper;
|
||||
import com.orangeforms.common.sequence.wrapper.IdGeneratorWrapper;
|
||||
import com.orangeforms.webadmin.upms.dao.SysDeptPostMapper;
|
||||
import com.orangeforms.webadmin.upms.dao.SysPostMapper;
|
||||
import com.orangeforms.webadmin.upms.dao.SysUserPostMapper;
|
||||
import com.orangeforms.webadmin.upms.model.SysDeptPost;
|
||||
import com.orangeforms.webadmin.upms.model.SysPost;
|
||||
import com.orangeforms.webadmin.upms.model.SysUserPost;
|
||||
import com.orangeforms.webadmin.upms.service.SysDeptService;
|
||||
import com.orangeforms.webadmin.upms.service.SysPostService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 岗位管理数据操作服务类。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
@Slf4j
|
||||
@Service("sysPostService")
|
||||
public class SysPostServiceImpl extends BaseService<SysPost, Long> implements SysPostService, BizWidgetDatasource {
|
||||
|
||||
@Autowired
|
||||
private SysPostMapper sysPostMapper;
|
||||
@Autowired
|
||||
private SysUserPostMapper sysUserPostMapper;
|
||||
@Autowired
|
||||
private SysDeptPostMapper sysDeptPostMapper;
|
||||
@Autowired
|
||||
private SysDeptService sysDeptService;
|
||||
@Autowired
|
||||
private IdGeneratorWrapper idGenerator;
|
||||
@Autowired
|
||||
private BizWidgetDatasourceExtHelper bizWidgetDatasourceExtHelper;
|
||||
|
||||
/**
|
||||
* 返回当前Service的主表Mapper对象。
|
||||
*
|
||||
* @return 主表Mapper对象。
|
||||
*/
|
||||
@Override
|
||||
protected BaseDaoMapper<SysPost> mapper() {
|
||||
return sysPostMapper;
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
private void registerBizWidgetDatasource() {
|
||||
bizWidgetDatasourceExtHelper.registerDatasource(BizWidgetDatasourceType.UPMS_POST_TYPE, this);
|
||||
bizWidgetDatasourceExtHelper.registerDatasource(BizWidgetDatasourceType.UPMS_DEPT_POST_TYPE, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyPageData<Map<String, Object>> getDataList(
|
||||
String type, Map<String, Object> filter, MyOrderParam orderParam, MyPageParam pageParam) {
|
||||
if (pageParam != null) {
|
||||
PageMethod.startPage(pageParam.getPageNum(), pageParam.getPageSize(), pageParam.getCount());
|
||||
}
|
||||
String orderBy = orderParam == null ? null : MyOrderParam.buildOrderBy(orderParam, SysPost.class);
|
||||
SysPost postFilter = filter == null ? null : BeanUtil.toBean(filter, SysPost.class);
|
||||
if (StrUtil.equals(type, BizWidgetDatasourceType.UPMS_POST_TYPE)) {
|
||||
List<SysPost> postList = this.getSysPostList(postFilter, orderBy);
|
||||
return MyPageUtil.makeResponseData(postList, BeanUtil::beanToMap);
|
||||
}
|
||||
Assert.notNull(filter, "filter can't be NULL.");
|
||||
Long deptId = (Long) filter.get("deptId");
|
||||
List<Map<String, Object>> dataList = sysDeptService.getSysDeptPostListWithRelationByDeptId(deptId);
|
||||
return MyPageUtil.makeResponseData(dataList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Map<String, Object>> getDataListWithInList(String type, String fieldName, List<String> fieldValues) {
|
||||
List<SysPost> postList;
|
||||
if (StrUtil.isBlank(fieldName)) {
|
||||
postList = this.getInList(fieldValues.stream().map(Long::valueOf).collect(Collectors.toSet()));
|
||||
} else {
|
||||
postList = this.getInList(fieldName, MyModelUtil.convertToTypeValues(SysPost.class, fieldName, fieldValues));
|
||||
}
|
||||
return MyModelUtil.beanToMapList(postList);
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public SysPost saveNew(SysPost sysPost) {
|
||||
sysPost.setPostId(idGenerator.nextLongId());
|
||||
MyModelUtil.fillCommonsForInsert(sysPost);
|
||||
MyModelUtil.setDefaultValue(sysPost, "leaderPost", false);
|
||||
sysPostMapper.insert(sysPost);
|
||||
return sysPost;
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public boolean update(SysPost sysPost, SysPost originalSysPost) {
|
||||
MyModelUtil.fillCommonsForUpdate(sysPost, originalSysPost);
|
||||
// 这里重点提示,在执行主表数据更新之前,如果有哪些字段不支持修改操作,请用原有数据对象字段替换当前数据字段。
|
||||
UpdateWrapper<SysPost> uw = this.createUpdateQueryForNullValue(sysPost, sysPost.getPostId());
|
||||
return sysPostMapper.update(sysPost, uw) == 1;
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public boolean remove(Long postId) {
|
||||
if (sysPostMapper.deleteById(postId) != 1) {
|
||||
return false;
|
||||
}
|
||||
// 开始删除多对多父表的关联
|
||||
SysUserPost sysUserPost = new SysUserPost();
|
||||
sysUserPost.setPostId(postId);
|
||||
sysUserPostMapper.delete(new QueryWrapper<>(sysUserPost));
|
||||
SysDeptPost sysDeptPost = new SysDeptPost();
|
||||
sysDeptPost.setPostId(postId);
|
||||
sysDeptPostMapper.delete(new QueryWrapper<>(sysDeptPost));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SysPost> getSysPostList(SysPost filter, String orderBy) {
|
||||
return sysPostMapper.getSysPostList(filter, orderBy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SysPost> getSysPostListWithRelation(SysPost filter, String orderBy) {
|
||||
List<SysPost> resultList = sysPostMapper.getSysPostList(filter, orderBy);
|
||||
// 在缺省生成的代码中,如果查询结果resultList不是Page对象,说明没有分页,那么就很可能是数据导出接口调用了当前方法。
|
||||
// 为了避免一次性的大量数据关联,规避因此而造成的系统运行性能冲击,这里手动进行了分批次读取,开发者可按需修改该值。
|
||||
int batchSize = resultList instanceof Page ? 0 : 1000;
|
||||
this.buildRelationForDataList(resultList, MyRelationParam.normal(), batchSize);
|
||||
return resultList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SysPost> getNotInSysPostListByDeptId(Long deptId, SysPost filter, String orderBy) {
|
||||
List<SysPost> resultList = sysPostMapper.getNotInSysPostListByDeptId(deptId, filter, orderBy);
|
||||
this.buildRelationForDataList(resultList, MyRelationParam.dictOnly());
|
||||
return resultList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SysPost> getSysPostListByDeptId(Long deptId, SysPost filter, String orderBy) {
|
||||
List<SysPost> resultList = sysPostMapper.getSysPostListByDeptId(deptId, filter, orderBy);
|
||||
this.buildRelationForDataList(resultList, MyRelationParam.dictOnly());
|
||||
return resultList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SysUserPost> getSysUserPostListByUserId(Long userId) {
|
||||
SysUserPost filter = new SysUserPost();
|
||||
filter.setUserId(userId);
|
||||
return sysUserPostMapper.selectList(new QueryWrapper<>(filter));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean existAllPrimaryKeys(Set<Long> deptPostIdSet, Long deptId) {
|
||||
LambdaQueryWrapper<SysDeptPost> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(SysDeptPost::getDeptId, deptId);
|
||||
queryWrapper.in(SysDeptPost::getDeptPostId, deptPostIdSet);
|
||||
return sysDeptPostMapper.selectCount(queryWrapper) == deptPostIdSet.size();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,192 @@
|
||||
package com.orangeforms.webadmin.upms.service.impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.github.pagehelper.page.PageMethod;
|
||||
import com.orangeforms.common.core.base.service.BaseService;
|
||||
import com.orangeforms.common.core.base.dao.BaseDaoMapper;
|
||||
import com.orangeforms.common.core.object.*;
|
||||
import com.orangeforms.common.core.util.MyModelUtil;
|
||||
import com.orangeforms.common.core.util.MyPageUtil;
|
||||
import com.orangeforms.common.ext.base.BizWidgetDatasource;
|
||||
import com.orangeforms.common.ext.constant.BizWidgetDatasourceType;
|
||||
import com.orangeforms.common.ext.util.BizWidgetDatasourceExtHelper;
|
||||
import com.orangeforms.common.sequence.wrapper.IdGeneratorWrapper;
|
||||
import com.orangeforms.webadmin.upms.dao.SysRoleMapper;
|
||||
import com.orangeforms.webadmin.upms.dao.SysRoleMenuMapper;
|
||||
import com.orangeforms.webadmin.upms.dao.SysUserRoleMapper;
|
||||
import com.orangeforms.webadmin.upms.model.SysRole;
|
||||
import com.orangeforms.webadmin.upms.model.SysRoleMenu;
|
||||
import com.orangeforms.webadmin.upms.model.SysUserRole;
|
||||
import com.orangeforms.webadmin.upms.service.SysMenuService;
|
||||
import com.orangeforms.webadmin.upms.service.SysRoleService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 角色数据服务类。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
@Slf4j
|
||||
@Service("sysRoleService")
|
||||
public class SysRoleServiceImpl extends BaseService<SysRole, Long> implements SysRoleService, BizWidgetDatasource {
|
||||
|
||||
@Autowired
|
||||
private SysRoleMapper sysRoleMapper;
|
||||
@Autowired
|
||||
private SysRoleMenuMapper sysRoleMenuMapper;
|
||||
@Autowired
|
||||
private SysUserRoleMapper sysUserRoleMapper;
|
||||
@Autowired
|
||||
private SysMenuService sysMenuService;
|
||||
@Autowired
|
||||
private IdGeneratorWrapper idGenerator;
|
||||
@Autowired
|
||||
private BizWidgetDatasourceExtHelper bizWidgetDatasourceExtHelper;
|
||||
|
||||
/**
|
||||
* 返回主对象的Mapper对象。
|
||||
*
|
||||
* @return 主对象的Mapper对象。
|
||||
*/
|
||||
@Override
|
||||
protected BaseDaoMapper<SysRole> mapper() {
|
||||
return sysRoleMapper;
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
private void registerBizWidgetDatasource() {
|
||||
bizWidgetDatasourceExtHelper.registerDatasource(BizWidgetDatasourceType.UPMS_ROLE_TYPE, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyPageData<Map<String, Object>> getDataList(
|
||||
String type, Map<String, Object> filter, MyOrderParam orderParam, MyPageParam pageParam) {
|
||||
if (pageParam != null) {
|
||||
PageMethod.startPage(pageParam.getPageNum(), pageParam.getPageSize(), pageParam.getCount());
|
||||
}
|
||||
String orderBy = orderParam == null ? null : MyOrderParam.buildOrderBy(orderParam, SysRole.class);
|
||||
SysRole roleFilter = filter == null ? null : BeanUtil.toBean(filter, SysRole.class);
|
||||
List<SysRole> roleList = this.getSysRoleList(roleFilter, orderBy);
|
||||
return MyPageUtil.makeResponseData(roleList, BeanUtil::beanToMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Map<String, Object>> getDataListWithInList(String type, String fieldName, List<String> fieldValues) {
|
||||
List<SysRole> roleList;
|
||||
if (StrUtil.isBlank(fieldName)) {
|
||||
roleList = this.getInList(fieldValues.stream().map(Long::valueOf).collect(Collectors.toSet()));
|
||||
} else {
|
||||
roleList = this.getInList(fieldName, MyModelUtil.convertToTypeValues(SysRole.class, fieldName, fieldValues));
|
||||
}
|
||||
return MyModelUtil.beanToMapList(roleList);
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public SysRole saveNew(SysRole role, Set<Long> menuIdSet) {
|
||||
role.setRoleId(idGenerator.nextLongId());
|
||||
MyModelUtil.fillCommonsForInsert(role);
|
||||
sysRoleMapper.insert(role);
|
||||
if (menuIdSet != null) {
|
||||
for (Long menuId : menuIdSet) {
|
||||
SysRoleMenu roleMenu = new SysRoleMenu();
|
||||
roleMenu.setRoleId(role.getRoleId());
|
||||
roleMenu.setMenuId(menuId);
|
||||
sysRoleMenuMapper.insert(roleMenu);
|
||||
}
|
||||
}
|
||||
return role;
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public boolean update(SysRole role, SysRole originalRole, Set<Long> menuIdSet) {
|
||||
MyModelUtil.fillCommonsForUpdate(role, originalRole);
|
||||
if (sysRoleMapper.updateById(role) != 1) {
|
||||
return false;
|
||||
}
|
||||
SysRoleMenu deletedRoleMenu = new SysRoleMenu();
|
||||
deletedRoleMenu.setRoleId(role.getRoleId());
|
||||
sysRoleMenuMapper.delete(new QueryWrapper<>(deletedRoleMenu));
|
||||
if (menuIdSet != null) {
|
||||
for (Long menuId : menuIdSet) {
|
||||
SysRoleMenu roleMenu = new SysRoleMenu();
|
||||
roleMenu.setRoleId(role.getRoleId());
|
||||
roleMenu.setMenuId(menuId);
|
||||
sysRoleMenuMapper.insert(roleMenu);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public boolean remove(Long roleId) {
|
||||
if (sysRoleMapper.deleteById(roleId) != 1) {
|
||||
return false;
|
||||
}
|
||||
SysRoleMenu roleMenu = new SysRoleMenu();
|
||||
roleMenu.setRoleId(roleId);
|
||||
sysRoleMenuMapper.delete(new QueryWrapper<>(roleMenu));
|
||||
SysUserRole userRole = new SysUserRole();
|
||||
userRole.setRoleId(roleId);
|
||||
sysUserRoleMapper.delete(new QueryWrapper<>(userRole));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SysRole> getSysRoleList(SysRole filter, String orderBy) {
|
||||
return sysRoleMapper.getSysRoleList(filter, orderBy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SysUserRole> getSysUserRoleListByUserId(Long userId) {
|
||||
SysUserRole filter = new SysUserRole();
|
||||
filter.setUserId(userId);
|
||||
return sysUserRoleMapper.selectList(new QueryWrapper<>(filter));
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public void addUserRoleList(List<SysUserRole> userRoleList) {
|
||||
for (SysUserRole userRole : userRoleList) {
|
||||
sysUserRoleMapper.insert(userRole);
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public boolean removeUserRole(Long roleId, Long userId) {
|
||||
SysUserRole userRole = new SysUserRole();
|
||||
userRole.setRoleId(roleId);
|
||||
userRole.setUserId(userId);
|
||||
return sysUserRoleMapper.delete(new QueryWrapper<>(userRole)) == 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CallResult verifyRelatedData(SysRole sysRole, SysRole originalSysRole, String menuIdListString) {
|
||||
JSONObject jsonObject = null;
|
||||
if (StringUtils.isNotBlank(menuIdListString)) {
|
||||
Set<Long> menuIdSet = Arrays.stream(
|
||||
menuIdListString.split(",")).map(Long::valueOf).collect(Collectors.toSet());
|
||||
if (!sysMenuService.existAllPrimaryKeys(menuIdSet)) {
|
||||
return CallResult.error("数据验证失败,存在不合法的菜单权限,请刷新后重试!");
|
||||
}
|
||||
jsonObject = new JSONObject();
|
||||
jsonObject.put("menuIdSet", menuIdSet);
|
||||
}
|
||||
return CallResult.ok(jsonObject);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,384 @@
|
||||
package com.orangeforms.webadmin.upms.service.impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.*;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
||||
import com.github.pagehelper.page.PageMethod;
|
||||
import com.orangeforms.webadmin.upms.service.*;
|
||||
import com.orangeforms.webadmin.upms.dao.*;
|
||||
import com.orangeforms.webadmin.upms.model.*;
|
||||
import com.orangeforms.webadmin.upms.model.constant.SysUserStatus;
|
||||
import com.orangeforms.common.ext.util.BizWidgetDatasourceExtHelper;
|
||||
import com.orangeforms.common.ext.base.BizWidgetDatasource;
|
||||
import com.orangeforms.common.ext.constant.BizWidgetDatasourceType;
|
||||
import com.orangeforms.common.core.base.dao.BaseDaoMapper;
|
||||
import com.orangeforms.common.core.constant.UserFilterGroup;
|
||||
import com.orangeforms.common.core.constant.GlobalDeletedFlag;
|
||||
import com.orangeforms.common.core.object.*;
|
||||
import com.orangeforms.common.core.base.service.BaseService;
|
||||
import com.orangeforms.common.core.util.MyModelUtil;
|
||||
import com.orangeforms.common.core.util.MyPageUtil;
|
||||
import com.orangeforms.common.sequence.wrapper.IdGeneratorWrapper;
|
||||
import com.github.pagehelper.Page;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 用户管理数据操作服务类。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
@Slf4j
|
||||
@Service("sysUserService")
|
||||
public class SysUserServiceImpl extends BaseService<SysUser, Long> implements SysUserService, BizWidgetDatasource {
|
||||
|
||||
@Autowired
|
||||
private IdGeneratorWrapper idGenerator;
|
||||
@Autowired
|
||||
private SysUserMapper sysUserMapper;
|
||||
@Autowired
|
||||
private SysUserRoleMapper sysUserRoleMapper;
|
||||
@Autowired
|
||||
private SysUserPostMapper sysUserPostMapper;
|
||||
@Autowired
|
||||
private SysDataPermUserMapper sysDataPermUserMapper;
|
||||
@Autowired
|
||||
private SysDeptService sysDeptService;
|
||||
@Autowired
|
||||
private SysRoleService sysRoleService;
|
||||
@Autowired
|
||||
private SysDataPermService sysDataPermService;
|
||||
@Autowired
|
||||
private SysPostService sysPostService;
|
||||
@Autowired
|
||||
private PasswordEncoder passwordEncoder;
|
||||
@Autowired
|
||||
private BizWidgetDatasourceExtHelper bizWidgetDatasourceExtHelper;
|
||||
|
||||
/**
|
||||
* 返回当前Service的主表Mapper对象。
|
||||
*
|
||||
* @return 主表Mapper对象。
|
||||
*/
|
||||
@Override
|
||||
protected BaseDaoMapper<SysUser> mapper() {
|
||||
return sysUserMapper;
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
private void registerBizWidgetDatasource() {
|
||||
bizWidgetDatasourceExtHelper.registerDatasource(BizWidgetDatasourceType.UPMS_USER_TYPE, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MyPageData<Map<String, Object>> getDataList(
|
||||
String type, Map<String, Object> filter, MyOrderParam orderParam, MyPageParam pageParam) {
|
||||
if (pageParam != null) {
|
||||
PageMethod.startPage(pageParam.getPageNum(), pageParam.getPageSize(), pageParam.getCount());
|
||||
}
|
||||
List<SysUser> userList = null;
|
||||
String orderBy = MyOrderParam.buildOrderBy(orderParam, SysUser.class, false);
|
||||
SysUser userFilter = BeanUtil.toBean(filter, SysUser.class);
|
||||
if (filter != null) {
|
||||
Object group = filter.get("USER_FILTER_GROUP");
|
||||
if (group != null) {
|
||||
JSONObject filterGroupJson = JSON.parseObject(group.toString());
|
||||
String groupType = filterGroupJson.getString("type");
|
||||
String values = filterGroupJson.getString("values");
|
||||
if (UserFilterGroup.USER.equals(groupType)) {
|
||||
List<String> loginNames = StrUtil.splitTrim(values, ",");
|
||||
userList = sysUserMapper.getSysUserListByLoginNames(loginNames, userFilter, orderBy);
|
||||
} else {
|
||||
Set<Long> groupIds = StrUtil.splitTrim(values, ",")
|
||||
.stream().map(Long::valueOf).collect(Collectors.toSet());
|
||||
userList = this.getUserListByGroupIds(groupType, groupIds, userFilter, orderBy);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (userList == null) {
|
||||
userList = this.getSysUserList(userFilter, orderBy);
|
||||
}
|
||||
this.buildRelationForDataList(userList, MyRelationParam.dictOnly());
|
||||
return MyPageUtil.makeResponseData(userList, BeanUtil::beanToMap);
|
||||
}
|
||||
|
||||
private List<SysUser> getUserListByGroupIds(String groupType, Set<Long> groupIds, SysUser filter, String orderBy) {
|
||||
if (groupType.equals(UserFilterGroup.DEPT)) {
|
||||
return sysUserMapper.getSysUserListByDeptIds(groupIds, filter, orderBy);
|
||||
}
|
||||
List<Long> userIds = null;
|
||||
switch (groupType) {
|
||||
case UserFilterGroup.ROLE:
|
||||
userIds = sysUserMapper.getUserIdListByRoleIds(groupIds, filter, orderBy);
|
||||
break;
|
||||
case UserFilterGroup.POST:
|
||||
userIds = sysUserMapper.getUserIdListByPostIds(groupIds, filter, orderBy);
|
||||
break;
|
||||
case UserFilterGroup.DEPT_POST:
|
||||
userIds = sysUserMapper.getUserIdListByDeptPostIds(groupIds, filter, orderBy);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (CollUtil.isEmpty(userIds)) {
|
||||
return CollUtil.empty(SysUser.class);
|
||||
}
|
||||
LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.in(SysUser::getUserId, userIds);
|
||||
if (StrUtil.isNotBlank(orderBy)) {
|
||||
queryWrapper.last(" ORDER BY " + orderBy);
|
||||
}
|
||||
return sysUserMapper.selectList(queryWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Map<String, Object>> getDataListWithInList(String type, String fieldName, List<String> fieldValues) {
|
||||
List<SysUser> userList;
|
||||
if (StrUtil.isBlank(fieldName)) {
|
||||
userList = this.getInList(fieldValues.stream().map(Long::valueOf).collect(Collectors.toSet()));
|
||||
} else {
|
||||
userList = this.getInList(fieldName, MyModelUtil.convertToTypeValues(SysUser.class, fieldName, fieldValues));
|
||||
}
|
||||
this.buildRelationForDataList(userList, MyRelationParam.dictOnly());
|
||||
return MyModelUtil.beanToMapList(userList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定登录名的用户对象。
|
||||
*
|
||||
* @param loginName 指定登录用户名。
|
||||
* @return 用户对象。
|
||||
*/
|
||||
@Override
|
||||
public SysUser getSysUserByLoginName(String loginName) {
|
||||
SysUser filter = new SysUser();
|
||||
filter.setLoginName(loginName);
|
||||
return sysUserMapper.selectOne(new QueryWrapper<>(filter));
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public SysUser saveNew(SysUser user, Set<Long> roleIdSet, Set<Long> deptPostIdSet, Set<Long> dataPermIdSet) {
|
||||
user.setUserId(idGenerator.nextLongId());
|
||||
user.setPassword(passwordEncoder.encode(user.getPassword()));
|
||||
user.setUserStatus(SysUserStatus.STATUS_NORMAL);
|
||||
user.setDeletedFlag(GlobalDeletedFlag.NORMAL);
|
||||
MyModelUtil.fillCommonsForInsert(user);
|
||||
sysUserMapper.insert(user);
|
||||
if (CollUtil.isNotEmpty(deptPostIdSet)) {
|
||||
for (Long deptPostId : deptPostIdSet) {
|
||||
SysDeptPost deptPost = sysDeptService.getSysDeptPost(deptPostId);
|
||||
SysUserPost userPost = new SysUserPost();
|
||||
userPost.setUserId(user.getUserId());
|
||||
userPost.setDeptPostId(deptPostId);
|
||||
userPost.setPostId(deptPost.getPostId());
|
||||
sysUserPostMapper.insert(userPost);
|
||||
}
|
||||
}
|
||||
if (CollUtil.isNotEmpty(roleIdSet)) {
|
||||
for (Long roleId : roleIdSet) {
|
||||
SysUserRole userRole = new SysUserRole();
|
||||
userRole.setUserId(user.getUserId());
|
||||
userRole.setRoleId(roleId);
|
||||
sysUserRoleMapper.insert(userRole);
|
||||
}
|
||||
}
|
||||
if (CollUtil.isNotEmpty(dataPermIdSet)) {
|
||||
for (Long dataPermId : dataPermIdSet) {
|
||||
SysDataPermUser dataPermUser = new SysDataPermUser();
|
||||
dataPermUser.setDataPermId(dataPermId);
|
||||
dataPermUser.setUserId(user.getUserId());
|
||||
sysDataPermUserMapper.insert(dataPermUser);
|
||||
}
|
||||
}
|
||||
return user;
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public boolean update(SysUser user, SysUser originalUser, Set<Long> roleIdSet, Set<Long> deptPostIdSet, Set<Long> dataPermIdSet) {
|
||||
user.setLoginName(originalUser.getLoginName());
|
||||
user.setPassword(originalUser.getPassword());
|
||||
MyModelUtil.fillCommonsForUpdate(user, originalUser);
|
||||
UpdateWrapper<SysUser> uw = this.createUpdateQueryForNullValue(user, user.getUserId());
|
||||
if (sysUserMapper.update(user, uw) != 1) {
|
||||
return false;
|
||||
}
|
||||
// 先删除原有的User-Post关联关系,再重新插入新的关联关系
|
||||
SysUserPost deletedUserPost = new SysUserPost();
|
||||
deletedUserPost.setUserId(user.getUserId());
|
||||
sysUserPostMapper.delete(new QueryWrapper<>(deletedUserPost));
|
||||
if (CollUtil.isNotEmpty(deptPostIdSet)) {
|
||||
for (Long deptPostId : deptPostIdSet) {
|
||||
SysDeptPost deptPost = sysDeptService.getSysDeptPost(deptPostId);
|
||||
SysUserPost userPost = new SysUserPost();
|
||||
userPost.setUserId(user.getUserId());
|
||||
userPost.setDeptPostId(deptPostId);
|
||||
userPost.setPostId(deptPost.getPostId());
|
||||
sysUserPostMapper.insert(userPost);
|
||||
}
|
||||
}
|
||||
// 先删除原有的User-Role关联关系,再重新插入新的关联关系
|
||||
SysUserRole deletedUserRole = new SysUserRole();
|
||||
deletedUserRole.setUserId(user.getUserId());
|
||||
sysUserRoleMapper.delete(new QueryWrapper<>(deletedUserRole));
|
||||
if (CollUtil.isNotEmpty(roleIdSet)) {
|
||||
for (Long roleId : roleIdSet) {
|
||||
SysUserRole userRole = new SysUserRole();
|
||||
userRole.setUserId(user.getUserId());
|
||||
userRole.setRoleId(roleId);
|
||||
sysUserRoleMapper.insert(userRole);
|
||||
}
|
||||
}
|
||||
// 先删除原有的DataPerm-User关联关系,在重新插入新的关联关系
|
||||
SysDataPermUser deletedDataPermUser = new SysDataPermUser();
|
||||
deletedDataPermUser.setUserId(user.getUserId());
|
||||
sysDataPermUserMapper.delete(new QueryWrapper<>(deletedDataPermUser));
|
||||
if (CollUtil.isNotEmpty(dataPermIdSet)) {
|
||||
for (Long dataPermId : dataPermIdSet) {
|
||||
SysDataPermUser dataPermUser = new SysDataPermUser();
|
||||
dataPermUser.setDataPermId(dataPermId);
|
||||
dataPermUser.setUserId(user.getUserId());
|
||||
sysDataPermUserMapper.insert(dataPermUser);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public boolean changePassword(Long userId, String newPass) {
|
||||
SysUser updatedUser = new SysUser();
|
||||
updatedUser.setUserId(userId);
|
||||
updatedUser.setPassword(passwordEncoder.encode(newPass));
|
||||
return sysUserMapper.updateById(updatedUser) == 1;
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public boolean changeHeadImage(Long userId, String newHeadImage) {
|
||||
SysUser updatedUser = new SysUser();
|
||||
updatedUser.setUserId(userId);
|
||||
updatedUser.setHeadImageUrl(newHeadImage);
|
||||
return sysUserMapper.updateById(updatedUser) == 1;
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public boolean remove(Long userId) {
|
||||
if (sysUserMapper.deleteById(userId) == 0) {
|
||||
return false;
|
||||
}
|
||||
SysUserRole userRole = new SysUserRole();
|
||||
userRole.setUserId(userId);
|
||||
sysUserRoleMapper.delete(new QueryWrapper<>(userRole));
|
||||
SysUserPost userPost = new SysUserPost();
|
||||
userPost.setUserId(userId);
|
||||
sysUserPostMapper.delete(new QueryWrapper<>(userPost));
|
||||
SysDataPermUser dataPermUser = new SysDataPermUser();
|
||||
dataPermUser.setUserId(userId);
|
||||
sysDataPermUserMapper.delete(new QueryWrapper<>(dataPermUser));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SysUser> getSysUserList(SysUser filter, String orderBy) {
|
||||
return sysUserMapper.getSysUserList(filter, orderBy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SysUser> getSysUserListWithRelation(SysUser filter, String orderBy) {
|
||||
List<SysUser> resultList = sysUserMapper.getSysUserList(filter, orderBy);
|
||||
// 在缺省生成的代码中,如果查询结果resultList不是Page对象,说明没有分页,那么就很可能是数据导出接口调用了当前方法。
|
||||
// 为了避免一次性的大量数据关联,规避因此而造成的系统运行性能冲击,这里手动进行了分批次读取,开发者可按需修改该值。
|
||||
int batchSize = resultList instanceof Page ? 0 : 1000;
|
||||
this.buildRelationForDataList(resultList, MyRelationParam.normal(), batchSize);
|
||||
return resultList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SysUser> getSysUserListByRoleId(Long roleId, SysUser filter, String orderBy) {
|
||||
return sysUserMapper.getSysUserListByRoleId(roleId, filter, orderBy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SysUser> getNotInSysUserListByRoleId(Long roleId, SysUser filter, String orderBy) {
|
||||
return sysUserMapper.getNotInSysUserListByRoleId(roleId, filter, orderBy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SysUser> getSysUserListByDataPermId(Long dataPermId, SysUser filter, String orderBy) {
|
||||
return sysUserMapper.getSysUserListByDataPermId(dataPermId, filter, orderBy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SysUser> getNotInSysUserListByDataPermId(Long dataPermId, SysUser filter, String orderBy) {
|
||||
return sysUserMapper.getNotInSysUserListByDataPermId(dataPermId, filter, orderBy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SysUser> getSysUserListByDeptPostId(Long deptPostId, SysUser filter, String orderBy) {
|
||||
return sysUserMapper.getSysUserListByDeptPostId(deptPostId, filter, orderBy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SysUser> getNotInSysUserListByDeptPostId(Long deptPostId, SysUser filter, String orderBy) {
|
||||
return sysUserMapper.getNotInSysUserListByDeptPostId(deptPostId, filter, orderBy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SysUser> getSysUserListByPostId(Long postId, SysUser filter, String orderBy) {
|
||||
return sysUserMapper.getSysUserListByPostId(postId, filter, orderBy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CallResult verifyRelatedData(
|
||||
SysUser sysUser, SysUser originalSysUser, String roleIds, String deptPostIds, String dataPermIds) {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
if (StrUtil.isBlank(deptPostIds)) {
|
||||
return CallResult.error("数据验证失败,用户的部门岗位数据不能为空!");
|
||||
}
|
||||
Set<Long> deptPostIdSet =
|
||||
Arrays.stream(deptPostIds.split(",")).map(Long::valueOf).collect(Collectors.toSet());
|
||||
if (!sysPostService.existAllPrimaryKeys(deptPostIdSet, sysUser.getDeptId())) {
|
||||
return CallResult.error("数据验证失败,存在不合法的用户岗位,请刷新后重试!");
|
||||
}
|
||||
jsonObject.put("deptPostIdSet", deptPostIdSet);
|
||||
if (StrUtil.isBlank(roleIds)) {
|
||||
return CallResult.error("数据验证失败,用户的角色数据不能为空!");
|
||||
}
|
||||
Set<Long> roleIdSet = Arrays.stream(
|
||||
roleIds.split(",")).map(Long::valueOf).collect(Collectors.toSet());
|
||||
if (!sysRoleService.existAllPrimaryKeys(roleIdSet)) {
|
||||
return CallResult.error("数据验证失败,存在不合法的用户角色,请刷新后重试!");
|
||||
}
|
||||
jsonObject.put("roleIdSet", roleIdSet);
|
||||
if (StrUtil.isBlank(dataPermIds)) {
|
||||
return CallResult.error("数据验证失败,用户的数据权限不能为空!");
|
||||
}
|
||||
Set<Long> dataPermIdSet = Arrays.stream(
|
||||
dataPermIds.split(",")).map(Long::valueOf).collect(Collectors.toSet());
|
||||
if (!sysDataPermService.existAllPrimaryKeys(dataPermIdSet)) {
|
||||
return CallResult.error("数据验证失败,存在不合法的数据权限,请刷新后重试!");
|
||||
}
|
||||
jsonObject.put("dataPermIdSet", dataPermIdSet);
|
||||
//这里是基于字典的验证。
|
||||
if (this.needToVerify(sysUser, originalSysUser, SysUser::getDeptId)
|
||||
&& !sysDeptService.existId(sysUser.getDeptId())) {
|
||||
return CallResult.error("数据验证失败,关联的用户部门Id并不存在,请刷新后重试!");
|
||||
}
|
||||
return CallResult.ok(jsonObject);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.orangeforms.webadmin.upms.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 数据权限与部门关联VO。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
@Schema(description = "数据权限与部门关联VO")
|
||||
@Data
|
||||
public class SysDataPermDeptVo {
|
||||
|
||||
/**
|
||||
* 数据权限Id。
|
||||
*/
|
||||
@Schema(description = "数据权限Id")
|
||||
private Long dataPermId;
|
||||
|
||||
/**
|
||||
* 关联部门Id。
|
||||
*/
|
||||
@Schema(description = "关联部门Id")
|
||||
private Long deptId;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.orangeforms.webadmin.upms.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 数据权限与菜单关联VO。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
@Schema(description = "数据权限与菜单关联VO")
|
||||
@Data
|
||||
public class SysDataPermMenuVo {
|
||||
|
||||
/**
|
||||
* 数据权限Id。
|
||||
*/
|
||||
@Schema(description = "数据权限Id")
|
||||
private Long dataPermId;
|
||||
|
||||
/**
|
||||
* 关联菜单Id。
|
||||
*/
|
||||
@Schema(description = "关联菜单Id")
|
||||
private Long menuId;
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.orangeforms.webadmin.upms.vo;
|
||||
|
||||
import com.orangeforms.common.core.base.vo.BaseVo;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 数据权限VO。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
@Schema(description = "数据权限VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class SysDataPermVo extends BaseVo {
|
||||
|
||||
/**
|
||||
* 数据权限Id。
|
||||
*/
|
||||
@Schema(description = "数据权限Id")
|
||||
private Long dataPermId;
|
||||
|
||||
/**
|
||||
* 显示名称。
|
||||
*/
|
||||
@Schema(description = "显示名称")
|
||||
private String dataPermName;
|
||||
|
||||
/**
|
||||
* 数据权限规则类型(0: 全部可见 1: 只看自己 2: 只看本部门 3: 本部门及子部门 4: 多部门及子部门 5: 自定义部门列表)。
|
||||
*/
|
||||
@Schema(description = "数据权限规则类型")
|
||||
private Integer ruleType;
|
||||
|
||||
/**
|
||||
* 部门Id列表(逗号分隔)。
|
||||
*/
|
||||
@Schema(description = "部门Id列表")
|
||||
private String deptIdListString;
|
||||
|
||||
/**
|
||||
* 数据权限与部门关联对象列表。
|
||||
*/
|
||||
@Schema(description = "数据权限与部门关联对象列表")
|
||||
private List<Map<String, Object>> dataPermDeptList;
|
||||
|
||||
/**
|
||||
* 数据权限与菜单关联对象列表。
|
||||
*/
|
||||
@Schema(description = "数据权限与菜单关联对象列表")
|
||||
private List<Map<String, Object>> dataPermMenuList;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.orangeforms.webadmin.upms.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 部门岗位VO对象。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
@Schema(description = "部门岗位VO")
|
||||
@Data
|
||||
public class SysDeptPostVo {
|
||||
|
||||
/**
|
||||
* 部门岗位Id。
|
||||
*/
|
||||
@Schema(description = "部门岗位Id")
|
||||
private Long deptPostId;
|
||||
|
||||
/**
|
||||
* 部门Id。
|
||||
*/
|
||||
@Schema(description = "部门Id")
|
||||
private Long deptId;
|
||||
|
||||
/**
|
||||
* 岗位Id。
|
||||
*/
|
||||
@Schema(description = "岗位Id")
|
||||
private Long postId;
|
||||
|
||||
/**
|
||||
* 部门岗位显示名称。
|
||||
*/
|
||||
@Schema(description = "部门岗位显示名称")
|
||||
private String postShowName;
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package com.orangeforms.webadmin.upms.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 部门管理VO视图对象。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
@Schema(description = "SysDeptVO视图对象")
|
||||
@Data
|
||||
public class SysDeptVo {
|
||||
|
||||
/**
|
||||
* 部门Id。
|
||||
*/
|
||||
@Schema(description = "部门Id")
|
||||
private Long deptId;
|
||||
|
||||
/**
|
||||
* 部门名称。
|
||||
*/
|
||||
@Schema(description = "部门名称")
|
||||
private String deptName;
|
||||
|
||||
/**
|
||||
* 显示顺序。
|
||||
*/
|
||||
@Schema(description = "显示顺序")
|
||||
private Integer showOrder;
|
||||
|
||||
/**
|
||||
* 父部门Id。
|
||||
*/
|
||||
@Schema(description = "父部门Id")
|
||||
private Long parentId;
|
||||
|
||||
/**
|
||||
* 创建者Id。
|
||||
*/
|
||||
@Schema(description = "创建者Id")
|
||||
private Long createUserId;
|
||||
|
||||
/**
|
||||
* 更新者Id。
|
||||
*/
|
||||
@Schema(description = "更新者Id")
|
||||
private Long updateUserId;
|
||||
|
||||
/**
|
||||
* 创建时间。
|
||||
*/
|
||||
@Schema(description = "创建时间")
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 更新时间。
|
||||
*/
|
||||
@Schema(description = "更新时间")
|
||||
private Date updateTime;
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
package com.orangeforms.webadmin.upms.vo;
|
||||
|
||||
import com.orangeforms.common.core.base.vo.BaseVo;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* 菜单VO。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
@Schema(description = "菜单VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class SysMenuVo extends BaseVo {
|
||||
|
||||
/**
|
||||
* 菜单Id。
|
||||
*/
|
||||
@Schema(description = "菜单Id")
|
||||
private Long menuId;
|
||||
|
||||
/**
|
||||
* 父菜单Id,目录菜单的父菜单为null
|
||||
*/
|
||||
@Schema(description = "父菜单Id")
|
||||
private Long parentId;
|
||||
|
||||
/**
|
||||
* 菜单显示名称。
|
||||
*/
|
||||
@Schema(description = "菜单显示名称")
|
||||
private String menuName;
|
||||
|
||||
/**
|
||||
* 菜单类型 (0: 目录 1: 菜单 2: 按钮 3: UI片段)。
|
||||
*/
|
||||
@Schema(description = "菜单类型")
|
||||
private Integer menuType;
|
||||
|
||||
/**
|
||||
* 前端表单路由名称,仅用于menu_type为1的菜单类型。
|
||||
*/
|
||||
@Schema(description = "前端表单路由名称")
|
||||
private String formRouterName;
|
||||
|
||||
/**
|
||||
* 在线表单主键Id,仅用于在线表单绑定的菜单。
|
||||
*/
|
||||
@Schema(description = "在线表单主键Id")
|
||||
private Long onlineFormId;
|
||||
|
||||
/**
|
||||
* 在线表单菜单的权限控制类型,具体值可参考SysOnlineMenuPermType常量对象。
|
||||
*/
|
||||
@Schema(description = "在线表单菜单的权限控制类型")
|
||||
private Integer onlineMenuPermType;
|
||||
|
||||
/**
|
||||
* 统计页面主键Id,仅用于统计页面绑定的菜单。
|
||||
*/
|
||||
@Schema(description = "统计页面主键Id")
|
||||
private Long reportPageId;
|
||||
|
||||
/**
|
||||
* 仅用于在线表单的流程Id。
|
||||
*/
|
||||
@Schema(description = "仅用于在线表单的流程Id")
|
||||
private Long onlineFlowEntryId;
|
||||
|
||||
/**
|
||||
* 菜单显示顺序 (值越小,排序越靠前)。
|
||||
*/
|
||||
@Schema(description = "菜单显示顺序")
|
||||
private Integer showOrder;
|
||||
|
||||
/**
|
||||
* 菜单图标。
|
||||
*/
|
||||
@Schema(description = "菜单显示图标")
|
||||
private String icon;
|
||||
|
||||
/**
|
||||
* 附加信息。
|
||||
*/
|
||||
@Schema(description = "附加信息")
|
||||
private String extraData;
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.orangeforms.webadmin.upms.vo;
|
||||
|
||||
import com.orangeforms.common.core.base.vo.BaseVo;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 岗位VO对象。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2024-07-02
|
||||
*/
|
||||
@Schema(description = "岗位VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class SysPostVo extends BaseVo {
|
||||
|
||||
/**
|
||||
* 岗位Id。
|
||||
*/
|
||||
@Schema(description = "岗位Id")
|
||||
private Long postId;
|
||||
|
||||
/**
|
||||
* 岗位名称。
|
||||
*/
|
||||
@Schema(description = "岗位名称")
|
||||
private String postName;
|
||||
|
||||
/**
|
||||
* 岗位层级,数值越小级别越高。
|
||||
*/
|
||||
@Schema(description = "岗位层级,数值越小级别越高")
|
||||
private Integer postLevel;
|
||||
|
||||
/**
|
||||
* 是否领导岗位。
|
||||
*/
|
||||
@Schema(description = "是否领导岗位")
|
||||
private Boolean leaderPost;
|
||||
|
||||
/**
|
||||
* postId 的多对多关联表数据对象,数据对应类型为SysDeptPostVo。
|
||||
*/
|
||||
@Schema(description = "postId 的多对多关联表数据对象")
|
||||
private Map<String, Object> sysDeptPost;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user