JeecgBoot 3.6.0大版本发布

This commit is contained in:
zhangdaiscott
2023-10-18 15:04:41 +08:00
parent 669c060cb3
commit 8f67aa8ae1
267 changed files with 12894 additions and 49368 deletions

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>jeecg-system-api</artifactId>
<groupId>org.jeecgframework.boot</groupId>
<version>3.5.5</version>
<version>3.6.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -6,6 +6,8 @@ import org.jeecg.common.api.dto.DataLogDTO;
import org.jeecg.common.api.dto.OnlineAuthDTO;
import org.jeecg.common.api.dto.message.*;
import org.jeecg.common.constant.ServiceNameConstants;
import org.jeecg.common.constant.enums.EmailTemplateEnum;
import org.jeecg.common.desensitization.annotation.SensitiveDecode;
import org.jeecg.common.system.api.factory.SysBaseAPIFallbackFactory;
import org.jeecg.common.system.vo.*;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
@ -72,6 +74,7 @@ public interface ISysBaseAPI extends CommonAPI {
* @param id
* @return
*/
@SensitiveDecode
@GetMapping("/sys/api/getUserById")
LoginUser getUserById(@RequestParam("id") String id);
@ -132,14 +135,14 @@ public interface ISysBaseAPI extends CommonAPI {
/**
* 13获取表数据字典
* @param table
* @param tableFilterSql
* @param text
* @param code
* @return
*/
@Override
@GetMapping("/sys/api/queryTableDictItemsByCode")
List<DictModel> queryTableDictItemsByCode(@RequestParam("table") String table, @RequestParam("text") String text, @RequestParam("code") String code);
List<DictModel> queryTableDictItemsByCode(@RequestParam("tableFilterSql") String tableFilterSql, @RequestParam("text") String text, @RequestParam("code") String code);
/**
* 14查询所有部门 作为字典信息 id -->value,departName -->text
@ -258,7 +261,7 @@ public interface ISysBaseAPI extends CommonAPI {
* @return
*/
@GetMapping("/sys/api/queryAllUserByIds")
public List<LoginUser> queryAllUserByIds(@RequestParam("userIds") String[] userIds);
public List<UserAccountInfo> queryAllUserByIds(@RequestParam("userIds") String[] userIds);
/**
* 28将会议签到信息推动到预览
@ -275,7 +278,7 @@ public interface ISysBaseAPI extends CommonAPI {
* @return
*/
@GetMapping("/sys/api/queryUserByNames")
List<LoginUser> queryUserByNames(@RequestParam("userNames")String[] userNames);
List<UserAccountInfo> queryUserByNames(@RequestParam("userNames")String[] userNames);
/**
@ -365,6 +368,7 @@ public interface ISysBaseAPI extends CommonAPI {
* @return LoginUser 用户信息
*/
@Override
@SensitiveDecode
@GetMapping("/sys/api/getUserByName")
LoginUser getUserByName(@RequestParam("username") String username);
@ -450,6 +454,17 @@ public interface ISysBaseAPI extends CommonAPI {
*/
@GetMapping("/sys/api/sendEmailMsg")
void sendEmailMsg(@RequestParam("email")String email,@RequestParam("title")String title,@RequestParam("content")String content);
/**
* 发送html模版邮件消息
*
* @param email
* @param title
* @param emailTemplateEnum 邮件模版枚举
* @param params 模版参数
*/
@GetMapping("/sys/api/sendHtmlTemplateEmail")
void sendHtmlTemplateEmail(@RequestParam("email") String email, @RequestParam("title") String title, @RequestParam("emailEnum") EmailTemplateEnum emailTemplateEnum, @RequestParam("params") JSONObject params);
/**
* 41 获取公司下级部门和公司下所有用户id
* @param orgCode 部门编号
@ -476,6 +491,17 @@ public interface ISysBaseAPI extends CommonAPI {
@GetMapping("/sys/api/loadDictItem")
List<String> loadDictItem(@RequestParam("dictCode") String dictCode, @RequestParam("keys") String keys);
/**
* 复制应用下的所有字典配置到新的租户下
*
* @param originalAppId 原始低代码应用ID
* @param appId 新的低代码应用ID
* @param tenantId 新的租户ID
* @return Map<String, String> Map<原字典编码, 新字典编码>
*/
@GetMapping("/sys/api/copyLowAppDict")
Map<String, String> copyLowAppDict(@RequestParam("originalAppId") String originalAppId, @RequestParam("appId") String appId, @RequestParam("tenantId") String tenantId);
/**
* 44 根据字典code查询字典项
*
@ -577,9 +603,138 @@ public interface ISysBaseAPI extends CommonAPI {
* @param loginUser
* @return
*/
@PutMapping("/updateAvatar")
@PutMapping("/sys/api/updateAvatar")
void updateAvatar(@RequestBody LoginUser loginUser);
@GetMapping("/sendAppChatSocket")
@GetMapping("/sys/api/sendAppChatSocket")
void sendAppChatSocket(@RequestParam(name="userId") String userId);
/**
* 根据角色id查询角色code
* @param id
* @return
*/
@GetMapping("/sys/api/getRoleCode")
String getRoleCodeById(String id);
/**
* 根据roleCode查询角色信息可逗号分隔多个
*
* @param roleCodes
* @return
*/
@GetMapping("/sys/api/queryRoleDictByCode")
List<DictModel> queryRoleDictByCode(@RequestParam(name = "roleCodes") String roleCodes);
/**
* 根据高级查询条件查询用户
* @param superQuery
* @param matchType
* @return
*/
@GetMapping("/sys/api/queryUserBySuperQuery")
List<JSONObject> queryUserBySuperQuery(@RequestParam(name="superQuery")String superQuery,@RequestParam(name="matchType")String matchType);
/**
* 根据ID条件查询用户
* @param id
* @return JSONObject
*/
@GetMapping("/sys/api/queryUserById")
JSONObject queryUserById(String id);
/**
* 根据高级查询条件查询部门
* @param superQuery
* @param matchType
* @return
*/
@GetMapping("/sys/api/queryDeptBySuperQuery")
List<JSONObject> queryDeptBySuperQuery(@RequestParam(name="superQuery")String superQuery,@RequestParam(name="matchType")String matchType);
/**
* 根据高级查询条件查询角色
* @param superQuery
* @param matchType
* @return
*/
@GetMapping("/sys/api/queryRoleBySuperQuery")
List<JSONObject> queryRoleBySuperQuery(@RequestParam(name="superQuery")String superQuery,@RequestParam(name="matchType")String matchType);
/**
* 根据租户ID查询用户ID
* @param tenantId 租户ID
* @return List<String>
*/
@GetMapping("/sys/api/selectUserIdByTenantId")
List<String> selectUserIdByTenantId(@RequestParam("tenantId")String tenantId);
/**
* 根据部门ID查询用户ID
* @param deptIds
* @return
*/
@GetMapping("/sys/api/queryUserIdsByDeptIds")
List<String> queryUserIdsByDeptIds(List<String> deptIds);
/**
* 根据部门ID查询用户账号
* @param deptIds
* @return
*/
@GetMapping("/sys/api/queryUserAccountsByDeptIds")
List<String> queryUserAccountsByDeptIds(List<String> deptIds);
/**
* 根据角色编码 查询用户ID
* @param roleCodes
* @return
*/
@GetMapping("/sys/api/queryUserIdsByRoleds")
List<String> queryUserIdsByRoleds(List<String> roleCodes);
/**
* 根据职务ID查询用户ID
* @param positionIds
* @return
*/
@GetMapping("/sys/api/queryUserIdsByPositionIds")
List<String> queryUserIdsByPositionIds(List<String> positionIds);
/**
* 根据部门和子部门下的所有用户账号
*
* @param orgCode 部门编码
* @return
*/
@GetMapping("/sys/api/getUserAccountsByDepCode")
public List<String> getUserAccountsByDepCode(@RequestParam("orgCode")String orgCode);
/**
* 检查查询sql的表和字段是否在白名单中
*
* @param selectSql
* @return
*/
@GetMapping("/sys/api/dictTableWhiteListCheckBySql")
boolean dictTableWhiteListCheckBySql(@RequestParam("selectSql") String selectSql);
/**
* 根据字典表或者字典编码,校验是否在白名单中
*
* @param tableOrDictCode 表名或dictCode
* @param fields 如果传的是dictCode则该参数必须传null
* @return
*/
@GetMapping("/sys/api/dictTableWhiteListCheckByDict")
boolean dictTableWhiteListCheckByDict(
@RequestParam("tableOrDictCode") String tableOrDictCode,
@RequestParam(value = "fields", required = false) String[] fields
);
}

View File

@ -6,6 +6,7 @@ import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.dto.DataLogDTO;
import org.jeecg.common.api.dto.OnlineAuthDTO;
import org.jeecg.common.api.dto.message.*;
import org.jeecg.common.constant.enums.EmailTemplateEnum;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.vo.*;
@ -91,7 +92,7 @@ public class SysBaseAPIFallback implements ISysBaseAPI {
}
@Override
public List<DictModel> queryTableDictItemsByCode(String table, String text, String code) {
public List<DictModel> queryTableDictItemsByCode(String tableFilterSql, String text, String code) {
return null;
}
@ -163,7 +164,7 @@ public class SysBaseAPIFallback implements ISysBaseAPI {
}
@Override
public List<LoginUser> queryAllUserByIds(String[] userIds) {
public List<UserAccountInfo> queryAllUserByIds(String[] userIds) {
return null;
}
@ -173,7 +174,7 @@ public class SysBaseAPIFallback implements ISysBaseAPI {
}
@Override
public List<LoginUser> queryUserByNames(String[] userNames) {
public List<UserAccountInfo> queryUserByNames(String[] userNames) {
return null;
}
@ -298,6 +299,11 @@ public class SysBaseAPIFallback implements ISysBaseAPI {
}
@Override
public void sendHtmlTemplateEmail(String email, String title, EmailTemplateEnum emailTemplateEnum, JSONObject params) {
}
@Override
public List<Map> getDeptUserByOrgCode(String orgCode) {
return null;
@ -318,6 +324,11 @@ public class SysBaseAPIFallback implements ISysBaseAPI {
return null;
}
@Override
public Map<String, String> copyLowAppDict(String originalAppId, String appId, String tenantId) {
return null;
}
@Override
public List<DictModel> getDictItems(String dictCode) {
return null;
@ -351,4 +362,75 @@ public class SysBaseAPIFallback implements ISysBaseAPI {
public void sendAppChatSocket(String userId) {
}
@Override
public String getRoleCodeById(String id) {
return null;
}
@Override
public List<DictModel> queryRoleDictByCode(String roleCodes) {
return null;
}
@Override
public List<JSONObject> queryUserBySuperQuery(String superQuery, String matchType) {
return null;
}
@Override
public JSONObject queryUserById(String id) {
return null;
}
@Override
public List<JSONObject> queryDeptBySuperQuery(String superQuery, String matchType) {
return null;
}
@Override
public List<JSONObject> queryRoleBySuperQuery(String superQuery, String matchType) {
return null;
}
@Override
public List<String> selectUserIdByTenantId(String tenantId) {
return null;
}
@Override
public List<String> queryUserIdsByDeptIds(List<String> deptIds) {
return null;
}
@Override
public List<String> queryUserAccountsByDeptIds(List<String> deptIds) {
return null;
}
@Override
public List<String> queryUserIdsByRoleds(List<String> roleCodes) {
return null;
}
@Override
public List<String> queryUserIdsByPositionIds(List<String> positionIds) {
return null;
}
@Override
public List<String> getUserAccountsByDepCode(String orgCode) {
return null;
}
@Override
public boolean dictTableWhiteListCheckBySql(String selectSql) {
return false;
}
@Override
public boolean dictTableWhiteListCheckByDict(String tableOrDictCode, String[] fields) {
return false;
}
}

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>jeecg-system-api</artifactId>
<groupId>org.jeecgframework.boot</groupId>
<version>3.5.5</version>
<version>3.6.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,6 +5,7 @@ import org.jeecg.common.api.CommonAPI;
import org.jeecg.common.api.dto.DataLogDTO;
import org.jeecg.common.api.dto.OnlineAuthDTO;
import org.jeecg.common.api.dto.message.*;
import org.jeecg.common.constant.enums.EmailTemplateEnum;
import org.jeecg.common.system.vo.*;
import java.util.List;
@ -19,7 +20,7 @@ import java.util.Set;
*/
public interface ISysBaseAPI extends CommonAPI {
//=======OLD 系统消息推送接口============================
/**
* 1发送系统消息
* @param message 使用构造器赋值参数 如果不设置category(消息类型)则默认为2 发送系统消息
@ -43,28 +44,29 @@ public interface ISysBaseAPI extends CommonAPI {
* @param message 使用构造器赋值参数
*/
void sendBusTemplateAnnouncement(BusTemplateMessageDTO message);
/**
* 5通过消息中心模板生成推送内容
* @param templateDTO 使用构造器赋值参数
* @return
*/
String parseTemplateByCode(TemplateDTO templateDTO);
//=======OLD 系统消息推送接口============================
//update-begin---author:taoyan ---date:20220705 for支持自定义推送类型邮件、钉钉、企业微信、系统消息-----------
//=======TY NEW 自定义消息推送接口,邮件、钉钉、企业微信、系统消息============================
/**
* 发送模板消息【新,支持自定义推送类型】
* NEW发送模板消息【新,支持自定义推送类型: 邮件、钉钉、企业微信、系统消息
* @param message
*/
void sendTemplateMessage(MessageDTO message);
/**
* 根据模板编码获取模板内容【新,支持自定义推送类型】
* NEW根据模板编码获取模板内容【新,支持自定义推送类型】
* @param templateCode
* @return
*/
String getTemplateContent(String templateCode);
//update-begin---author:taoyan ---date:20220705 for支持自定义推送类型邮件、钉钉、企业微信、系统消息-----------
//=======TY NEW 自定义消息推送接口,邮件、钉钉、企业微信、系统消息============================
/**
* 6根据用户id查询用户信息
@ -216,7 +218,7 @@ public interface ISysBaseAPI extends CommonAPI {
* @param userIds 多个用户id
* @return
*/
public List<LoginUser> queryAllUserByIds(String[] userIds);
public List<UserAccountInfo> queryAllUserByIds(String[] userIds);
/**
* 29将会议签到信息推动到预览
@ -231,7 +233,50 @@ public interface ISysBaseAPI extends CommonAPI {
* @param userNames 多个用户账户
* @return
*/
List<LoginUser> queryUserByNames(String[] userNames);
List<UserAccountInfo> queryUserByNames(String[] userNames);
/**
* 根据高级查询条件查询用户
* @param superQuery
* @param matchType
* @return
*/
List<JSONObject> queryUserBySuperQuery(String superQuery,String matchType);
/**
* 根据ID查询用户
* @param id
* @return
*/
JSONObject queryUserById(String id);
/**
* 根据高级查询条件查询部门
* @param superQuery
* @param matchType
* @return
*/
List<JSONObject> queryDeptBySuperQuery(String superQuery,String matchType);
/**
* 根据高级查询条件查询角色
* @param superQuery
* @param matchType
* @return
*/
List<JSONObject> queryRoleBySuperQuery(String superQuery,String matchType);
/**
* 根据租户ID查询用户ID
* @param tenantId 租户ID
* @return List<String>
*/
List<String> selectUserIdByTenantId(String tenantId);
/**
@ -304,6 +349,16 @@ public interface ISysBaseAPI extends CommonAPI {
* @param content
*/
void sendEmailMsg(String email,String title,String content);
/**
* 40发送模版邮件消息
*
* @param email 接收邮箱
* @param title 邮件标题
* @param emailTemplateEnum 邮件模版枚举
* @param params 模版参数
*/
void sendHtmlTemplateEmail(String email, String title, EmailTemplateEnum emailTemplateEnum, JSONObject params);
/**
* 41 获取公司下级部门和公司下所有用户信息
* @param orgCode
@ -327,6 +382,16 @@ public interface ISysBaseAPI extends CommonAPI {
*/
List<String> loadDictItem(String dictCode, String keys);
/**
* 复制应用下的所有字典配置到新的租户下
*
* @param originalAppId 原始低代码应用ID
* @param appId 新的低代码应用ID
* @param tenantId 新的租户ID
* @return Map<String, String> Map<原字典编码, 新字典编码>
*/
Map<String, String> copyLowAppDict(String originalAppId, String appId, String tenantId);
/**
* 根据字典code查询字典项
*
@ -383,4 +448,73 @@ public interface ISysBaseAPI extends CommonAPI {
* @param userId
*/
void sendAppChatSocket(String userId);
/**
* 根据角色id查询角色code
* @param id
* @return
*/
String getRoleCodeById(String id);
/**
* 根据roleCode查询角色信息可逗号分隔多个
*
* @param roleCodes
* @return
*/
List<DictModel> queryRoleDictByCode(String roleCodes);
/**
* 根据部门ID查询用户ID
* @param deptIds
* @return
*/
List<String> queryUserIdsByDeptIds(List<String> deptIds);
/**
* 根据部门ID查询用户账号
* @param deptIds
* @return
*/
List<String> queryUserAccountsByDeptIds(List<String> deptIds);
/**
* 根据角色编码 查询用户ID
* @param roleCodes
* @return
*/
List<String> queryUserIdsByRoleds(List<String> roleCodes);
/**
* 根据职务ID查询用户ID
* @param positionIds
* @return
*/
List<String> queryUserIdsByPositionIds(List<String> positionIds);
/**
* 根据部门和子部门下的所有用户账号
*
* @param orgCode 部门编码
* @return
*/
public List<String> getUserAccountsByDepCode(String orgCode);
/**
* 检查查询sql的表和字段是否在白名单中
*
* @param selectSql
* @return
*/
boolean dictTableWhiteListCheckBySql(String selectSql);
/**
* 根据字典表或者字典编码,校验是否在白名单中
*
* @param tableOrDictCode 表名或dictCode
* @param fields 如果传的是dictCode则该参数必须传null
* @return
*/
boolean dictTableWhiteListCheckByDict(String tableOrDictCode, String... fields);
}

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>jeecg-module-system</artifactId>
<groupId>org.jeecgframework.boot</groupId>
<version>3.5.5</version>
<version>3.6.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -4,7 +4,7 @@
<parent>
<groupId>org.jeecgframework.boot</groupId>
<artifactId>jeecg-module-system</artifactId>
<version>3.5.5</version>
<version>3.6.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -0,0 +1,279 @@
package org.jeecg.config.firewall.SqlInjection.impl;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.constant.SymbolConstant;
import org.jeecg.common.exception.JeecgSqlInjectionException;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.common.util.sqlparse.JSqlParserUtils;
import org.jeecg.common.util.sqlparse.vo.SelectSqlInfo;
import org.jeecg.config.JeecgBaseConfig;
import org.jeecg.config.firewall.SqlInjection.IDictTableWhiteListHandler;
import org.jeecg.config.firewall.interceptor.LowCodeModeInterceptor;
import org.jeecg.modules.system.entity.SysTableWhiteList;
import org.jeecg.modules.system.security.DictQueryBlackListHandler;
import org.jeecg.modules.system.service.ISysTableWhiteListService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.net.URLDecoder;
import java.util.*;
/**
* 通用情况的白名单处理,若有无法处理的情况,可以单独写实现类
*/
@Slf4j
@Component("dictTableWhiteListHandlerImpl")
public class DictTableWhiteListHandlerImpl implements IDictTableWhiteListHandler {
/**
* key-表名
* value-字段名,多个逗号隔开
* 两种配置方式-- 全部配置成小写
* whiteTablesRuleMap.put("sys_user", "*") sys_user所有的字段都支持查询
* whiteTablesRuleMap.put("sys_user", "username,password") sys_user中的username和password支持查询
*/
private static final Map<String, String> whiteTablesRuleMap = new HashMap<>();
/**
* LowCode 是否为 dev 模式
*/
private static Boolean LOW_CODE_IS_DEV = null;
@Autowired
private ISysTableWhiteListService sysTableWhiteListService;
@Autowired
private JeecgBaseConfig jeecgBaseConfig;
/**
* 初始化 whiteTablesRuleMap 方法
*/
private void init() {
// 如果当前为dev模式则每次都查询数据库防止缓存
if (this.isDev()) {
DictTableWhiteListHandlerImpl.whiteTablesRuleMap.clear();
}
// 如果map为空则从数据库中查询
if (DictTableWhiteListHandlerImpl.whiteTablesRuleMap.isEmpty()) {
Map<String, String> ruleMap = sysTableWhiteListService.getAllConfigMap();
log.info("表字典白名单初始化完成:{}", ruleMap);
DictTableWhiteListHandlerImpl.whiteTablesRuleMap.putAll(ruleMap);
}
}
@Override
public boolean isPassBySql(String sql) {
Map<String, SelectSqlInfo> parsedMap = null;
try {
parsedMap = JSqlParserUtils.parseAllSelectTable(sql);
} catch (Exception e) {
log.warn("校验sql语句解析报错{}", e.getMessage());
}
// 如果sql有问题则肯定执行不了所以直接返回true
if (parsedMap == null) {
return true;
}
log.info("获取select sql信息 {} ", parsedMap);
// 遍历当前sql中的所有表名如果有其中一个表或表的字段不在白名单中则不通过
for (Map.Entry<String, SelectSqlInfo> entry : parsedMap.entrySet()) {
SelectSqlInfo sqlInfo = entry.getValue();
if (sqlInfo.isSelectAll()) {
log.warn("查询语句中包含 * 字段,暂时先通过");
continue;
}
Set<String> queryFields = sqlInfo.getAllRealSelectFields();
// 校验表名和字段是否允许查询
String tableName = entry.getKey();
if (!this.checkWhiteList(tableName, queryFields)) {
return false;
}
}
return true;
}
@Override
public boolean isPassByDict(String dictCodeString) {
if (oConvertUtils.isEmpty(dictCodeString)) {
return true;
}
try {
// 针对转义字符进行解码
dictCodeString = URLDecoder.decode(dictCodeString, "UTF-8");
} catch (Exception e) {
log.error(e.getMessage(), e);
this.throwException("字典code解码失败可能是使用了非法字符请检查");
}
dictCodeString = dictCodeString.trim();
String[] arr = dictCodeString.split(SymbolConstant.COMMA);
// 获取表名
String tableName = this.getTableName(arr[0]);
// 获取查询字段
arr = Arrays.copyOfRange(arr, 1, arr.length);
// distinct的作用是去重相当于 Set<String>
String[] fields = Arrays.stream(arr).map(String::trim).distinct().toArray(String[]::new);
// 校验表名和字段是否允许查询
return this.isPassByDict(tableName, fields);
}
@Override
public boolean isPassByDict(String tableName, String... fields) {
if (oConvertUtils.isEmpty(tableName)) {
return true;
}
if (fields == null || fields.length == 0) {
fields = new String[]{"*"};
}
String sql = "select " + String.join(",", fields) + " from " + tableName;
log.info("字典拼接的查询SQL{}", sql);
try {
// 进行SQL解析
JSqlParserUtils.parseSelectSqlInfo(sql);
} catch (Exception e) {
// 如果SQL解析失败则通过字段名和表名进行校验
return checkWhiteList(tableName, new HashSet<>(Arrays.asList(fields)));
}
// 通过SQL解析进行校验可防止SQL注入
return this.isPassBySql(sql);
}
/**
* 校验表名和字段是否在白名单内
*
* @param tableName
* @param queryFields
* @return
*/
public boolean checkWhiteList(String tableName, Set<String> queryFields) {
this.init();
// 1、判断“表名”是否通过校验如果为空则未通过校验
if (oConvertUtils.isEmpty(tableName)) {
log.error("白名单校验:表名为空");
this.throwException();
}
// 统一转成小写
tableName = tableName.toLowerCase();
String allowFieldStr = DictTableWhiteListHandlerImpl.whiteTablesRuleMap.get(tableName);
log.info("checkWhiteList tableName: {}", tableName);
if (oConvertUtils.isEmpty(allowFieldStr)) {
// 如果是dev模式自动向数据库里添加数据
if (this.isDev()) {
this.autoAddWhiteList(tableName, String.join(",", queryFields));
allowFieldStr = DictTableWhiteListHandlerImpl.whiteTablesRuleMap.get(tableName);
} else {
// prod模式下直接抛出异常
log.error("白名单校验:表\"{}\"未通过校验", tableName);
this.throwException();
}
}
// 2、判断“字段名”是否通过校验
// 统一转成小写
allowFieldStr = allowFieldStr.toLowerCase();
Set<String> allowFields = new HashSet<>(Arrays.asList(allowFieldStr.split(",")));
// 需要合并的字段
Set<String> waitMergerFields = new HashSet<>();
for (String field : queryFields) {
if(oConvertUtils.isEmpty(field)){
continue;
}
// 统一转成小写
field = field.toLowerCase();
// 如果允许的字段里不包含查询的字段,则直接抛出异常
if (!allowFields.contains(field)) {
// 如果是dev模式记录需要合并的字段
if (this.isDev()) {
waitMergerFields.add(field);
} else {
log.error("白名单校验:字段 {} 不在 {} 范围内,拒绝访问!", field, allowFields);
this.throwException();
}
}
}
// 自动向数据库中合并未通过的字段
if (!waitMergerFields.isEmpty()) {
this.autoAddWhiteList(tableName, String.join(",", waitMergerFields));
}
log.info("白名单校验:查询表\"{}\",查询字段 {} 通过校验", tableName, queryFields);
return true;
}
/**
* 自动添加白名单,如果数据库已有,则字段会自动合并
*
* @param tableName
* @param allowFieldStr
*/
private void autoAddWhiteList(String tableName, String allowFieldStr) {
try {
SysTableWhiteList entity = sysTableWhiteListService.autoAdd(tableName, allowFieldStr);
DictTableWhiteListHandlerImpl.whiteTablesRuleMap.put(tableName, entity.getFieldName());
log.warn("\"{}\"未通过校验,且当前为 dev 模式,已自动向数据库中增加白名单数据。查询字段:{}", tableName, allowFieldStr);
} catch (Exception e) {
log.error("\"{}\"未通过校验,且当前为 dev 模式,但自动向数据库中增加白名单数据失败,请排查后重试。错误原因:{}", tableName, e.getMessage(), e);
this.throwException();
}
}
/**
* 判断当前 LowCode 是否为 dev 模式
*/
private boolean isDev() {
if (DictTableWhiteListHandlerImpl.LOW_CODE_IS_DEV == null) {
if (this.jeecgBaseConfig.getFirewall() != null) {
String lowCodeMode = this.jeecgBaseConfig.getFirewall().getLowCodeMode();
DictTableWhiteListHandlerImpl.LOW_CODE_IS_DEV = LowCodeModeInterceptor.LOW_CODE_MODE_DEV.equals(lowCodeMode);
} else {
// 如果没有 firewall 配置,则默认为 false
DictTableWhiteListHandlerImpl.LOW_CODE_IS_DEV = false;
}
}
return DictTableWhiteListHandlerImpl.LOW_CODE_IS_DEV;
}
@Override
public boolean clear() {
DictTableWhiteListHandlerImpl.whiteTablesRuleMap.clear();
return true;
}
/**
* 取where前面的为table name
*
* @param str
* @see DictQueryBlackListHandler#getTableName(String)
*/
@SuppressWarnings("JavadocReference")
private String getTableName(String str) {
String[] arr = str.split("\\s+(?i)where\\s+");
String tableName = arr[0].trim();
//【20230814】解决使用参数tableName=sys_user t&复测,漏洞仍然存在
if (tableName.contains(".")) {
tableName = tableName.substring(tableName.indexOf(".") + 1, tableName.length()).trim();
}
if (tableName.contains(" ")) {
tableName = tableName.substring(0, tableName.indexOf(" ")).trim();
}
//【issues/4393】 sys_user , (sys_user), sys_user%20, %60sys_user%60
String reg = "\\s+|\\(|\\)|`";
return tableName.replaceAll(reg, "");
}
private void throwException() throws JeecgSqlInjectionException {
this.throwException(this.getErrorMsg());
}
private void throwException(String message) throws JeecgSqlInjectionException {
if (oConvertUtils.isEmpty(message)) {
message = this.getErrorMsg();
}
log.error(message);
throw new JeecgSqlInjectionException(message);
}
@Override
public String getErrorMsg() {
return "白名单校验未通过!";
}
}

View File

@ -6,9 +6,8 @@ import org.jeecg.common.api.dto.DataLogDTO;
import org.jeecg.common.api.dto.OnlineAuthDTO;
import org.jeecg.common.api.dto.message.*;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.desensitization.util.SensitiveInfoUtil;
import org.jeecg.common.system.vo.*;
import org.jeecg.common.util.SqlInjectionUtil;
import org.jeecg.modules.system.security.DictQueryBlackListHandler;
import org.jeecg.modules.system.service.ISysUserService;
import org.jeecg.modules.system.service.impl.SysBaseApiImpl;
import org.springframework.beans.factory.annotation.Autowired;
@ -33,10 +32,6 @@ public class SystemApiController {
@Autowired
private ISysUserService sysUserService;
@Autowired
private DictQueryBlackListHandler dictQueryBlackListHandler;
/**
* 发送系统消息
* @param message 使用构造器赋值参数 如果不设置category(消息类型)则默认为2 发送系统消息
@ -98,7 +93,14 @@ public class SystemApiController {
*/
@GetMapping("/getUserByName")
public LoginUser getUserByName(@RequestParam("username") String username){
return sysBaseApi.getUserByName(username);
LoginUser loginUser = sysBaseApi.getUserByName(username);
//用户信息加密
try {
SensitiveInfoUtil.handlerObject(loginUser, true);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return loginUser;
}
/**
@ -108,7 +110,14 @@ public class SystemApiController {
*/
@GetMapping("/getUserById")
LoginUser getUserById(@RequestParam("id") String id){
return sysBaseApi.getUserById(id);
LoginUser loginUser = sysBaseApi.getUserById(id);
//用户信息加密
try {
SensitiveInfoUtil.handlerObject(loginUser, true);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return loginUser;
}
/**
@ -300,7 +309,7 @@ public class SystemApiController {
* @return
*/
@GetMapping("/queryAllUserByIds")
public List<LoginUser> queryAllUserByIds(@RequestParam("userIds") String[] userIds){
public List<UserAccountInfo> queryAllUserByIds(@RequestParam("userIds") String[] userIds){
return sysBaseApi.queryAllUserByIds(userIds);
}
@ -341,7 +350,7 @@ public class SystemApiController {
* @return
*/
@GetMapping("/queryUserByNames")
public List<LoginUser> queryUserByNames(@RequestParam("userNames")String[] userNames){
public List<UserAccountInfo> queryUserByNames(@RequestParam("userNames")String[] userNames){
return sysBaseApi.queryUserByNames(userNames);
}
@ -527,13 +536,22 @@ public class SystemApiController {
*/
@GetMapping("/loadDictItem")
public List<String> loadDictItem(@RequestParam("dictCode") String dictCode, @RequestParam("keys") String keys) {
if(!dictQueryBlackListHandler.isPass(dictCode)){
log.error(dictQueryBlackListHandler.getError());
return null;
}
return sysBaseApi.loadDictItem(dictCode, keys);
}
/**
* 复制应用下的所有字典配置到新的租户下
*
* @param originalAppId 原始低代码应用ID
* @param appId 新的低代码应用ID
* @param tenantId 新的租户ID
* @return Map<String, String> Map<原字典编码, 新字典编码>
*/
@GetMapping("/sys/api/copyLowAppDict")
Map<String, String> copyLowAppDict(@RequestParam("originalAppId") String originalAppId, @RequestParam("appId") String appId, @RequestParam("tenantId") String tenantId) {
return sysBaseApi.copyLowAppDict(originalAppId, appId, tenantId);
}
/**
* 根据字典code查询字典项
*
@ -543,10 +561,6 @@ public class SystemApiController {
*/
@GetMapping("/getDictItems")
public List<DictModel> getDictItems(@RequestParam("dictCode") String dictCode) {
if(!dictQueryBlackListHandler.isPass(dictCode)){
log.error(dictQueryBlackListHandler.getError());
return null;
}
return sysBaseApi.getDictItems(dictCode);
}
@ -571,10 +585,6 @@ public class SystemApiController {
*/
@GetMapping("/loadDictItemByKeyword")
public List<DictModel> loadDictItemByKeyword(@RequestParam("dictCode") String dictCode, @RequestParam("keyword") String keyword, @RequestParam(value = "pageSize", required = false) Integer pageSize) {
if(!dictQueryBlackListHandler.isPass(dictCode)){
log.error(dictQueryBlackListHandler.getError());
return null;
}
return sysBaseApi.loadDictItemByKeyword(dictCode, keyword, pageSize);
}
@ -592,19 +602,14 @@ public class SystemApiController {
/**
* 获取表数据字典 【接口签名验证】
* @param table
* @param tableFilterSql 表名可以带where条件
* @param text
* @param code
* @return
*/
@GetMapping("/queryTableDictItemsByCode")
List<DictModel> queryTableDictItemsByCode(@RequestParam("table") String table, @RequestParam("text") String text, @RequestParam("code") String code){
String str = table+","+text+","+code;
if(!dictQueryBlackListHandler.isPass(str)){
log.error(dictQueryBlackListHandler.getError());
return null;
}
return sysBaseApi.queryTableDictItemsByCode(table, text, code);
List<DictModel> queryTableDictItemsByCode(@RequestParam("tableFilterSql") String tableFilterSql, @RequestParam("text") String text, @RequestParam("code") String code){
return sysBaseApi.queryTableDictItemsByCode(tableFilterSql, text, code);
}
/**
@ -617,14 +622,6 @@ public class SystemApiController {
*/
@GetMapping("/queryFilterTableDictInfo")
List<DictModel> queryFilterTableDictInfo(@RequestParam("table") String table, @RequestParam("text") String text, @RequestParam("code") String code, @RequestParam("filterSql") String filterSql){
String str = table+","+text+","+code;
if(!dictQueryBlackListHandler.isPass(str)){
log.error(dictQueryBlackListHandler.getError());
return null;
}
String[] arr = new String[]{table, text, code};
SqlInjectionUtil.filterContent(arr);
SqlInjectionUtil.specialFilterContentForDictSql(filterSql);
return sysBaseApi.queryFilterTableDictInfo(table, text, code, filterSql);
}
@ -640,11 +637,6 @@ public class SystemApiController {
@Deprecated
@GetMapping("/queryTableDictByKeys")
public List<String> queryTableDictByKeys(@RequestParam("table") String table, @RequestParam("text") String text, @RequestParam("code") String code, @RequestParam("keyArray") String[] keyArray){
String str = table+","+text+","+code;
if(!dictQueryBlackListHandler.isPass(str)){
log.error(dictQueryBlackListHandler.getError());
return null;
}
return sysBaseApi.queryTableDictByKeys(table, text, code, keyArray);
}
@ -659,13 +651,6 @@ public class SystemApiController {
*/
@GetMapping("/translateDictFromTable")
public String translateDictFromTable(@RequestParam("table") String table, @RequestParam("text") String text, @RequestParam("code") String code, @RequestParam("key") String key){
String str = table+","+text+","+code;
if(!dictQueryBlackListHandler.isPass(str)){
log.error(dictQueryBlackListHandler.getError());
return null;
}
String[] arr = new String[]{table, text, code, key};
SqlInjectionUtil.filterContent(arr);
return sysBaseApi.translateDictFromTable(table, text, code, key);
}
@ -682,11 +667,6 @@ public class SystemApiController {
*/
@GetMapping("/translateDictFromTableByKeys")
public List<DictModel> translateDictFromTableByKeys(@RequestParam("table") String table, @RequestParam("text") String text, @RequestParam("code") String code, @RequestParam("keys") String keys) {
String str = table+","+text+","+code;
if(!dictQueryBlackListHandler.isPass(str)){
log.error(dictQueryBlackListHandler.getError());
return null;
}
return this.sysBaseApi.translateDictFromTableByKeys(table, text, code, keys);
}
@ -746,7 +726,27 @@ public class SystemApiController {
this.sysBaseApi.sendAppChatSocket(userId);
}
/**
* 根据roleCode查询角色信息可逗号分隔多个
*
* @param roleCodes
* @return
*/
@GetMapping("/queryRoleDictByCode")
public List<DictModel> queryRoleDictByCode(@RequestParam(name = "roleCodes") String roleCodes) {
return this.sysBaseApi.queryRoleDictByCode(roleCodes);
}
/**
* 获取消息模板内容
* @param id
* @return
*/
@GetMapping("/getRoleCode")
public String getRoleCode(@RequestParam("id") String id){
return this.sysBaseApi.getRoleCodeById(id);
}
/**
* VUEN-2584【issue】平台sql注入漏洞几个问题
* 部分特殊函数 可以将查询结果混夹在错误信息中,导致数据库的信息暴露
@ -763,5 +763,138 @@ public class SystemApiController {
}
return Result.error("校验失败sql解析异常" + msg);
}
/**
* 根据高级查询条件查询用户
* @param superQuery
* @param matchType
* @return
*/
@GetMapping("/queryUserBySuperQuery")
public List<JSONObject> queryUserBySuperQuery(@RequestParam("superQuery") String superQuery, @RequestParam("matchType") String matchType) {
return sysBaseApi.queryUserBySuperQuery(superQuery,matchType);
}
/**
* 根据id条件查询用户
* @param id
* @return
*/
@GetMapping("/queryUserById")
public JSONObject queryUserById(@RequestParam("id") String id) {
return sysBaseApi.queryUserById(id);
}
/**
* 根据高级查询条件查询部门
* @param superQuery
* @param matchType
* @return
*/
@GetMapping("/queryDeptBySuperQuery")
public List<JSONObject> queryDeptBySuperQuery(@RequestParam("superQuery") String superQuery, @RequestParam("matchType") String matchType) {
return sysBaseApi.queryDeptBySuperQuery(superQuery,matchType);
}
/**
* 根据高级查询条件查询角色
* @param superQuery
* @param matchType
* @return
*/
@GetMapping("/queryRoleBySuperQuery")
public List<JSONObject> queryRoleBySuperQuery(@RequestParam("superQuery") String superQuery, @RequestParam("matchType") String matchType) {
return sysBaseApi.queryRoleBySuperQuery(superQuery,matchType);
}
/**
* 根据租户ID查询用户ID
* @param tenantId 租户ID
* @return List<String>
*/
@GetMapping("/selectUserIdByTenantId")
public List<String> selectUserIdByTenantId(@RequestParam("tenantId") String tenantId) {
return sysBaseApi.selectUserIdByTenantId(tenantId);
}
/**
* 根据部门ID查询用户ID
* @param deptIds
* @return
*/
@GetMapping("/sys/api/queryUserIdsByDeptIds")
public List<String> queryUserIdsByDeptIds(@RequestParam("deptIds") List<String> deptIds){
return sysBaseApi.queryUserIdsByDeptIds(deptIds);
}
/**
* 根据部门ID查询用户ID
* @param deptIds
* @return
*/
@GetMapping("/sys/api/queryUserAccountsByDeptIds")
public List<String> queryUserAccountsByDeptIds(@RequestParam("deptIds") List<String> deptIds){
return sysBaseApi.queryUserAccountsByDeptIds(deptIds);
}
/**
* 根据角色编码 查询用户ID
* @param roleCodes
* @return
*/
@GetMapping("/sys/api/queryUserIdsByRoleds")
public List<String> queryUserIdsByRoleds(@RequestParam("roleCodes") List<String> roleCodes){
return sysBaseApi.queryUserIdsByRoleds(roleCodes);
}
/**
* 根据职务ID查询用户ID
* @param positionIds
* @return
*/
@GetMapping("/sys/api/queryUserIdsByPositionIds")
public List<String> queryUserIdsByPositionIds(@RequestParam("positionIds") List<String> positionIds){
return sysBaseApi.queryUserIdsByPositionIds(positionIds);
}
/**
* 根据部门和子部门下的所有用户账号
*
* @param orgCode 部门编码
* @return
*/
@GetMapping("/sys/api/getUserAccountsByDepCode")
public List<String> getUserAccountsByDepCode(String orgCode){
return sysBaseApi.getUserAccountsByDepCode(orgCode);
}
/**
* 检查查询sql的表和字段是否在白名单中
*
* @param selectSql
* @return
*/
@GetMapping("/sys/api/dictTableWhiteListCheckBySql")
public boolean dictTableWhiteListCheckBySql(@RequestParam("selectSql") String selectSql) {
return sysBaseApi.dictTableWhiteListCheckBySql(selectSql);
}
/**
* 根据字典表或者字典编码,校验是否在白名单中
*
* @param tableOrDictCode 表名或dictCode
* @param fields 如果传的是dictCode则该参数必须传null
* @return
*/
@GetMapping("/sys/api/dictTableWhiteListCheckByDict")
public boolean dictTableWhiteListCheckByDict(
@RequestParam("tableOrDictCode") String tableOrDictCode,
@RequestParam(value = "fields", required = false) String[] fields
) {
return sysBaseApi.dictTableWhiteListCheckByDict(tableOrDictCode, fields);
}
}

View File

@ -1,5 +1,6 @@
package org.jeecg.modules.message.enums;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.constant.enums.MessageTypeEnum;
import org.jeecg.common.system.annotation.EnumDict;
import org.jeecg.common.system.vo.DictModel;
@ -15,6 +16,7 @@ import java.util.List;
* @Author taoYan
* @Date 2022/8/19 20:41
**/
@Slf4j
@EnumDict("rangeDate")
public enum RangeDateEnum {
@ -25,6 +27,7 @@ public enum RangeDateEnum {
SZ("sz", "上周"),
BY("by", "本月"),
SY("sy", "上月"),
SEVENDAYS("7day", "7日"),
ZDY("zdy", "自定义日期");
String key;
@ -101,6 +104,10 @@ public enum RangeDateEnum {
//本月第一天减一天
calendar2.set(Calendar.DAY_OF_MONTH, 1);
calendar2.add(Calendar.DAY_OF_MONTH, -1);
} else if (SEVENDAYS.key.equals(key)){
//七日第一天
calendar1.setTime(new Date());
calendar1.add(Calendar.DATE, -7);
}else{
flag = true;
}

View File

@ -1,65 +0,0 @@
package org.jeecg.modules.message.enums;
import org.jeecg.common.system.annotation.EnumDict;
import org.jeecg.common.system.vo.DictModel;
import java.util.ArrayList;
import java.util.List;
/**
* 消息跳转【vue3】
* @Author taoYan
* @Date 2022/8/19 20:41
**/
@EnumDict("messageHref")
public enum Vue3MessageHrefEnum {
/**
* 流程催办
*/
BPM("bpm", "/task/myHandleTaskInfo"),
/**
* 节点通知
*/
BPM_TASK("bpm_task", "/task/myHandleTaskInfo"),
/**
* 邮件消息
*/
EMAIL("email", "/eoa/email");
String busType;
String path;
Vue3MessageHrefEnum(String busType, String path) {
this.busType = busType;
this.path = path;
}
public String getBusType() {
return busType;
}
public String getPath() {
return path;
}
/**
* 获取字典数据
* @return
*/
public static List<DictModel> getDictList(){
List<DictModel> list = new ArrayList<>();
DictModel dictModel = null;
for(Vue3MessageHrefEnum e: Vue3MessageHrefEnum.values()){
dictModel = new DictModel();
dictModel.setValue(e.getBusType());
dictModel.setText(e.getPath());
list.add(dictModel);
}
return list;
}
}

View File

@ -23,6 +23,7 @@ import javax.mail.internet.MimeMessage;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.List;
import java.util.Set;
/**
* @Description: 邮箱发送信息
@ -58,7 +59,6 @@ public class EmailSendMsgHandle implements ISendMsgHandle {
//update-begin-authortaoyan date:20200811 for:配置类数据获取
if(oConvertUtils.isEmpty(emailFrom)){
StaticConfig staticConfig = SpringContextUtils.getBean(StaticConfig.class);
log.info("邮件配置 emailFrom" + emailFrom);
setEmailFrom(staticConfig.getEmailFrom());
}
//update-end-authortaoyan date:20200811 for:配置类数据获取
@ -92,6 +92,20 @@ public class EmailSendMsgHandle implements ISendMsgHandle {
log.info("邮件内容:"+ content);
sendMsg(email, title, content);
}
//update-begin-author:taoyan date:2023-6-20 for: QQYUN-5557【简流】通知节点 发送邮箱 表单上有一个邮箱字段,流程中,邮件发送节点,邮件接收人 不可选择邮箱
Set<String> toEmailList = messageDTO.getToEmailList();
if(toEmailList!=null && toEmailList.size()>0){
for(String email: toEmailList){
if (ObjectUtils.isEmpty(email)) {
continue;
}
log.info("邮件内容:"+ content);
sendMsg(email, title, content);
}
}
//update-end-author:taoyan date:2023-6-20 for: QQYUN-5557【简流】通知节点 发送邮箱 表单上有一个邮箱字段,流程中,邮件发送节点,邮件接收人 不可选择邮箱
//发送给抄送人
sendMessageToCopyUser(messageDTO);
}
@ -115,30 +129,56 @@ public class EmailSendMsgHandle implements ISendMsgHandle {
}
content=replaceContent(user,content);
log.info("邮件内容:" + content);
JavaMailSender mailSender = (JavaMailSender) SpringContextUtils.getBean("mailSender");
MimeMessage message = mailSender.createMimeMessage();
MimeMessageHelper helper = null;
if (oConvertUtils.isEmpty(emailFrom)) {
StaticConfig staticConfig = SpringContextUtils.getBean(StaticConfig.class);
setEmailFrom(staticConfig.getEmailFrom());
}
try {
helper = new MimeMessageHelper(message, true);
// 设置发送方邮箱地址
helper.setFrom(emailFrom);
helper.setTo(email);
//设置抄送人
helper.setCc(email);
helper.setSubject(title);
helper.setText(content, true);
mailSender.send(message);
} catch (MessagingException e) {
e.printStackTrace();
//update-begin-author:taoyan date:2023-6-20 for: QQYUN-5557【简流】通知节点 发送邮箱 表单上有一个邮箱字段,流程中,邮件发送节点,邮件接收人 不可选择邮箱
sendEmail(email, content, title);
}
Set<String> ccEmailList = messageDTO.getCcEmailList();
if(ccEmailList!=null && ccEmailList.size()>0){
for(String email: ccEmailList){
if (ObjectUtils.isEmpty(email)) {
continue;
}
log.info("邮件内容:"+ content);
sendEmail(email, content, title);
}
}
}
}
/**
* 发送邮件给抄送人调用
* @param email
* @param content
* @param title
*/
private void sendEmail(String email, String content, String title){
JavaMailSender mailSender = (JavaMailSender) SpringContextUtils.getBean("mailSender");
MimeMessage message = mailSender.createMimeMessage();
MimeMessageHelper helper = null;
if (oConvertUtils.isEmpty(emailFrom)) {
StaticConfig staticConfig = SpringContextUtils.getBean(StaticConfig.class);
setEmailFrom(staticConfig.getEmailFrom());
}
try {
helper = new MimeMessageHelper(message, true);
// 设置发送方邮箱地址
helper.setFrom(emailFrom);
helper.setTo(email);
//设置抄送人
helper.setCc(email);
helper.setSubject(title);
helper.setText(content, true);
mailSender.send(message);
} catch (MessagingException e) {
e.printStackTrace();
}
}
//update-end-author:taoyan date:2023-6-20 for: QQYUN-5557【简流】通知节点 发送邮箱 表单上有一个邮箱字段,流程中,邮件发送节点,邮件接收人 不可选择邮箱
/**
* 替换邮件内容变量
* @param user

View File

@ -8,7 +8,7 @@ import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.util.SpringContextUtils;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.message.enums.Vue3MessageHrefEnum;
import org.jeecg.common.constant.enums.Vue3MessageHrefEnum;
import org.jeecg.modules.message.handle.ISendMsgHandle;
import org.jeecg.modules.message.websocket.WebSocket;
import org.jeecg.modules.system.entity.SysAnnouncement;
@ -92,6 +92,12 @@ public class SystemSendMsgHandle implements ISendMsgHandle {
announcement.setBusId(taskId.toString());
announcement.setBusType(Vue3MessageHrefEnum.BPM_TASK.getBusType());
}
// 流程内消息节点 发消息会传一个busType
Object busType = data.get(CommonConstant.NOTICE_MSG_BUS_TYPE);
if(busType!=null){
announcement.setBusType(busType.toString());
}
}
announcement.setTitile(title);
announcement.setMsgContent(msgContent);

View File

@ -22,7 +22,7 @@ public class SocketHandler implements JeecgRedisListener {
@Override
public void onMessage(BaseMap map) {
log.info("【Redis发布订阅模式】redis Listener: {},参数:{}",WebSocket.REDIS_TOPIC_NAME, map.toString());
log.debug("【Redis发布订阅模式】redis Listener: {},参数:{}",WebSocket.REDIS_TOPIC_NAME, map.toString());
String userId = map.get("userId");
String message = map.get("message");

View File

@ -40,7 +40,7 @@ public class WebSocket {
public void onOpen(Session session, @PathParam(value = "userId") String userId) {
try {
sessionPool.put(userId, session);
log.info("【系统 WebSocket】有新的连接总数为:" + sessionPool.size());
log.debug("【系统 WebSocket】有新的连接总数为:" + sessionPool.size());
} catch (Exception e) {
}
}
@ -49,7 +49,7 @@ public class WebSocket {
public void onClose(@PathParam("userId") String userId) {
try {
sessionPool.remove(userId);
log.info("【系统 WebSocket】连接断开总数为:" + sessionPool.size());
log.debug("【系统 WebSocket】连接断开总数为:" + sessionPool.size());
} catch (Exception e) {
e.printStackTrace();
}
@ -70,7 +70,7 @@ public class WebSocket {
try {
//update-begin-author:taoyan date:20211012 for: websocket报错 https://gitee.com/jeecg/jeecg-boot/issues/I4C0MU
synchronized (session){
log.info("【系统 WebSocket】推送单人消息:" + message);
log.debug("【系统 WebSocket】推送单人消息:" + message);
session.getBasicRemote().sendText(message);
}
//update-end-author:taoyan date:20211012 for: websocket报错 https://gitee.com/jeecg/jeecg-boot/issues/I4C0MU
@ -93,7 +93,7 @@ public class WebSocket {
log.error(e.getMessage(), e);
}
}
log.info("【系统 WebSocket】群发消息:" + message);
log.debug("【系统 WebSocket】群发消息:" + message);
} catch (Exception e) {
log.error(e.getMessage(), e);
}
@ -106,7 +106,7 @@ public class WebSocket {
@OnMessage
public void onMessage(String message, @PathParam(value = "userId") String userId) {
if(!"ping".equals(message) && !WebsocketConst.CMD_CHECK.equals(message)){
log.info("【系统 WebSocket】收到客户端消息:" + message);
log.debug("【系统 WebSocket】收到客户端消息:" + message);
}else{
log.debug("【系统 WebSocket】收到客户端消息:" + message);
}
@ -142,11 +142,11 @@ public class WebSocket {
* @param message
*/
public void sendMessage(String message) {
//log.info("【系统 WebSocket】广播消息:" + message);
//log.debug("【系统 WebSocket】广播消息:" + message);
BaseMap baseMap = new BaseMap();
baseMap.put("userId", "");
baseMap.put("message", message);
jeecgRedisClient.sendMessage(REDIS_TOPIC_NAME, baseMap);
jeecgRedisClient.sendMessage(WebSocket.REDIS_TOPIC_NAME, baseMap);
}
/**
@ -159,7 +159,7 @@ public class WebSocket {
BaseMap baseMap = new BaseMap();
baseMap.put("userId", userId);
baseMap.put("message", message);
jeecgRedisClient.sendMessage(REDIS_TOPIC_NAME, baseMap);
jeecgRedisClient.sendMessage(WebSocket.REDIS_TOPIC_NAME, baseMap);
}
/**

View File

@ -1,37 +1,37 @@
package org.jeecg.modules.ngalain.service;
import com.alibaba.fastjson.JSONArray;
import java.util.List;
import java.util.Map;
/**
* @Description: NgAlainService接口
* @author: jeecg-boot
*/
public interface NgAlainService {
/**
* 菜单
* @param id
* @return JSONArray
* @throws Exception
*/
public JSONArray getMenu(String id) throws Exception;
/**
* jeecg菜单
* @param id
* @return JSONArray
* @throws Exception
*/
public JSONArray getJeecgMenu(String id) throws Exception;
/**
* 获取字典值
* @param table
* @param key
* @param value
* @return List<Map<String, String>>
*/
public List<Map<String, String>> getDictByTable(String table, String key, String value);
}
//package org.jeecg.modules.ngalain.service;
//
//import com.alibaba.fastjson.JSONArray;
//
//import java.util.List;
//import java.util.Map;
//
///**
// * @Description: NgAlainService接口
// * @author: jeecg-boot
// */
//public interface NgAlainService {
// /**
// * 菜单
// * @param id
// * @return JSONArray
// * @throws Exception
// */
// public JSONArray getMenu(String id) throws Exception;
//
// /**
// * jeecg菜单
// * @param id
// * @return JSONArray
// * @throws Exception
// */
// public JSONArray getJeecgMenu(String id) throws Exception;
//
// /**
// * 获取字典值
// * @param table
// * @param key
// * @param value
// * @return List<Map<String, String>>
// */
// public List<Map<String, String>> getDictByTable(String table, String key, String value);
//}

View File

@ -1,187 +1,187 @@
package org.jeecg.modules.ngalain.service.impl;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.constant.SymbolConstant;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.ngalain.service.NgAlainService;
import org.jeecg.modules.system.entity.SysPermission;
import org.jeecg.modules.system.mapper.SysDictMapper;
import org.jeecg.modules.system.service.ISysPermissionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Base64;
import java.util.List;
import java.util.Map;
/**
* @Description: NgAlainServiceImpl 实现类
* @author: jeecg-boot
*/
@Service("ngAlainService")
public class NgAlainServiceImpl implements NgAlainService {
@Autowired
private ISysPermissionService sysPermissionService;
@Autowired
private SysDictMapper mapper;
@Override
public JSONArray getMenu(String id) throws Exception {
return getJeecgMenu(id);
}
@Override
public JSONArray getJeecgMenu(String id) throws Exception {
List<SysPermission> metaList = sysPermissionService.queryByUser(id);
JSONArray jsonArray = new JSONArray();
getPermissionJsonArray(jsonArray, metaList, null);
JSONArray menulist= parseNgAlain(jsonArray);
JSONObject jeecgMenu = new JSONObject();
jeecgMenu.put("text", "jeecg菜单");
jeecgMenu.put("group",true);
jeecgMenu.put("children", menulist);
JSONArray jeecgMenuList=new JSONArray();
jeecgMenuList.add(jeecgMenu);
return jeecgMenuList;
}
@Override
public List<Map<String, String>> getDictByTable(String table, String key, String value) {
return this.mapper.getDictByTableNgAlain(table,key,value);
}
private JSONArray parseNgAlain(JSONArray jsonArray) {
JSONArray menulist=new JSONArray();
for (Object object : jsonArray) {
JSONObject jsonObject= (JSONObject) object;
String path= (String) jsonObject.get("path");
JSONObject meta= (JSONObject) jsonObject.get("meta");
JSONObject menu=new JSONObject();
menu.put("text",meta.get("title"));
menu.put("reuse",true);
if (jsonObject.get("children")!=null){
JSONArray child= parseNgAlain((JSONArray) jsonObject.get("children"));
menu.put("children",child);
JSONObject icon=new JSONObject();
icon.put("type", "icon");
icon.put("value", meta.get("icon"));
menu.put("icon",icon);
}else {
menu.put("link",path);
}
menulist.add(menu);
}
return menulist;
}
/**
* 获取菜单JSON数组
* @param jsonArray
* @param metaList
* @param parentJson
*/
private void getPermissionJsonArray(JSONArray jsonArray,List<SysPermission> metaList,JSONObject parentJson) {
for (SysPermission permission : metaList) {
if(permission.getMenuType()==null) {
continue;
}
String tempPid = permission.getParentId();
JSONObject json = getPermissionJsonObject(permission);
if(parentJson==null && oConvertUtils.isEmpty(tempPid)) {
jsonArray.add(json);
if(!permission.isLeaf()) {
getPermissionJsonArray(jsonArray, metaList, json);
}
}else if(parentJson!=null && oConvertUtils.isNotEmpty(tempPid) && tempPid.equals(parentJson.getString("id"))){
if(permission.getMenuType()==0) {
JSONObject metaJson = parentJson.getJSONObject("meta");
if(metaJson.containsKey("permissionList")) {
metaJson.getJSONArray("permissionList").add(json);
}else {
JSONArray permissionList = new JSONArray();
permissionList.add(json);
metaJson.put("permissionList", permissionList);
}
}else if(permission.getMenuType()==1) {
if(parentJson.containsKey("children")) {
parentJson.getJSONArray("children").add(json);
}else {
JSONArray children = new JSONArray();
children.add(json);
parentJson.put("children", children);
}
if(!permission.isLeaf()) {
getPermissionJsonArray(jsonArray, metaList, json);
}
}
}
}
}
private JSONObject getPermissionJsonObject(SysPermission permission) {
JSONObject json = new JSONObject();
//类型(0一级菜单 1子菜单 2按钮)
if(CommonConstant.MENU_TYPE_2.equals(permission.getMenuType())) {
json.put("action", permission.getPerms());
json.put("describe", permission.getName());
}else if(CommonConstant.MENU_TYPE_0.equals(permission.getMenuType()) || CommonConstant.MENU_TYPE_1.equals(permission.getMenuType())) {
json.put("id", permission.getId());
boolean flag = permission.getUrl()!=null&&(permission.getUrl().startsWith(CommonConstant.HTTP_PROTOCOL)||permission.getUrl().startsWith(CommonConstant.HTTPS_PROTOCOL));
if(flag) {
String url= new String(Base64.getUrlEncoder().encode(permission.getUrl().getBytes()));
json.put("path", "/sys/link/" +url.replaceAll("=",""));
}else {
json.put("path", permission.getUrl());
}
//重要规则路由name (通过URL生成路由name,路由name供前端开发页面跳转使用)
json.put("name", urlToRouteName(permission.getUrl()));
//是否隐藏路由,默认都是显示的
if(permission.isHidden()) {
json.put("hidden",true);
}
//聚合路由
if(permission.isAlwaysShow()) {
json.put("alwaysShow",true);
}
json.put("component", permission.getComponent());
JSONObject meta = new JSONObject();
meta.put("title", permission.getName());
if(oConvertUtils.isEmpty(permission.getParentId())) {
//一级菜单跳转地址
json.put("redirect",permission.getRedirect());
meta.put("icon", oConvertUtils.getString(permission.getIcon(), ""));
}else {
meta.put("icon", oConvertUtils.getString(permission.getIcon(), ""));
}
if(flag) {
meta.put("url", permission.getUrl());
}
json.put("meta", meta);
}
return json;
}
/**
* 通过URL生成路由name去掉URL前缀斜杠替换内容中的斜杠/’为-
* 举例: URL = /isystem/role
* RouteName = isystem-role
* @return
*/
private String urlToRouteName(String url) {
if(oConvertUtils.isNotEmpty(url)) {
if(url.startsWith(SymbolConstant.SINGLE_SLASH)) {
url = url.substring(1);
}
url = url.replace("/", "-");
return url;
}else {
return null;
}
}
}
//package org.jeecg.modules.ngalain.service.impl;
//
//import com.alibaba.fastjson.JSONArray;
//import com.alibaba.fastjson.JSONObject;
//import org.jeecg.common.constant.CommonConstant;
//import org.jeecg.common.constant.SymbolConstant;
//import org.jeecg.common.util.oConvertUtils;
//import org.jeecg.modules.ngalain.service.NgAlainService;
//import org.jeecg.modules.system.entity.SysPermission;
//import org.jeecg.modules.system.mapper.SysDictMapper;
//import org.jeecg.modules.system.service.ISysPermissionService;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.stereotype.Service;
//import org.springframework.transaction.annotation.Transactional;
//
//import java.util.Base64;
//import java.util.List;
//import java.util.Map;
//
///**
// * @Description: NgAlainServiceImpl 实现类
// * @author: jeecg-boot
// */
//@Service("ngAlainService")
//public class NgAlainServiceImpl implements NgAlainService {
// @Autowired
// private ISysPermissionService sysPermissionService;
// @Autowired
// private SysDictMapper mapper;
// @Override
// public JSONArray getMenu(String id) throws Exception {
// return getJeecgMenu(id);
// }
// @Override
// public JSONArray getJeecgMenu(String id) throws Exception {
// List<SysPermission> metaList = sysPermissionService.queryByUser(id);
// JSONArray jsonArray = new JSONArray();
// getPermissionJsonArray(jsonArray, metaList, null);
// JSONArray menulist= parseNgAlain(jsonArray);
// JSONObject jeecgMenu = new JSONObject();
// jeecgMenu.put("text", "jeecg菜单");
// jeecgMenu.put("group",true);
// jeecgMenu.put("children", menulist);
// JSONArray jeecgMenuList=new JSONArray();
// jeecgMenuList.add(jeecgMenu);
// return jeecgMenuList;
// }
//
// @Override
// public List<Map<String, String>> getDictByTable(String table, String key, String value) {
// return this.mapper.getDictByTableNgAlain(table,key,value);
// }
//
// private JSONArray parseNgAlain(JSONArray jsonArray) {
// JSONArray menulist=new JSONArray();
// for (Object object : jsonArray) {
// JSONObject jsonObject= (JSONObject) object;
// String path= (String) jsonObject.get("path");
// JSONObject meta= (JSONObject) jsonObject.get("meta");
// JSONObject menu=new JSONObject();
// menu.put("text",meta.get("title"));
// menu.put("reuse",true);
// if (jsonObject.get("children")!=null){
// JSONArray child= parseNgAlain((JSONArray) jsonObject.get("children"));
// menu.put("children",child);
// JSONObject icon=new JSONObject();
// icon.put("type", "icon");
// icon.put("value", meta.get("icon"));
// menu.put("icon",icon);
// }else {
// menu.put("link",path);
// }
// menulist.add(menu);
// }
// return menulist;
// }
//
// /**
// * 获取菜单JSON数组
// * @param jsonArray
// * @param metaList
// * @param parentJson
// */
// private void getPermissionJsonArray(JSONArray jsonArray,List<SysPermission> metaList,JSONObject parentJson) {
// for (SysPermission permission : metaList) {
// if(permission.getMenuType()==null) {
// continue;
// }
// String tempPid = permission.getParentId();
// JSONObject json = getPermissionJsonObject(permission);
// if(parentJson==null && oConvertUtils.isEmpty(tempPid)) {
// jsonArray.add(json);
// if(!permission.isLeaf()) {
// getPermissionJsonArray(jsonArray, metaList, json);
// }
// }else if(parentJson!=null && oConvertUtils.isNotEmpty(tempPid) && tempPid.equals(parentJson.getString("id"))){
// if(permission.getMenuType()==0) {
// JSONObject metaJson = parentJson.getJSONObject("meta");
// if(metaJson.containsKey("permissionList")) {
// metaJson.getJSONArray("permissionList").add(json);
// }else {
// JSONArray permissionList = new JSONArray();
// permissionList.add(json);
// metaJson.put("permissionList", permissionList);
// }
//
// }else if(permission.getMenuType()==1) {
// if(parentJson.containsKey("children")) {
// parentJson.getJSONArray("children").add(json);
// }else {
// JSONArray children = new JSONArray();
// children.add(json);
// parentJson.put("children", children);
// }
//
// if(!permission.isLeaf()) {
// getPermissionJsonArray(jsonArray, metaList, json);
// }
// }
// }
//
//
// }
// }
// private JSONObject getPermissionJsonObject(SysPermission permission) {
// JSONObject json = new JSONObject();
// //类型(0一级菜单 1子菜单 2按钮)
// if(CommonConstant.MENU_TYPE_2.equals(permission.getMenuType())) {
// json.put("action", permission.getPerms());
// json.put("describe", permission.getName());
// }else if(CommonConstant.MENU_TYPE_0.equals(permission.getMenuType()) || CommonConstant.MENU_TYPE_1.equals(permission.getMenuType())) {
// json.put("id", permission.getId());
// boolean flag = permission.getUrl()!=null&&(permission.getUrl().startsWith(CommonConstant.HTTP_PROTOCOL)||permission.getUrl().startsWith(CommonConstant.HTTPS_PROTOCOL));
// if(flag) {
// String url= new String(Base64.getUrlEncoder().encode(permission.getUrl().getBytes()));
// json.put("path", "/sys/link/" +url.replaceAll("=",""));
// }else {
// json.put("path", permission.getUrl());
// }
//
// //重要规则路由name (通过URL生成路由name,路由name供前端开发页面跳转使用)
// json.put("name", urlToRouteName(permission.getUrl()));
//
// //是否隐藏路由,默认都是显示的
// if(permission.isHidden()) {
// json.put("hidden",true);
// }
// //聚合路由
// if(permission.isAlwaysShow()) {
// json.put("alwaysShow",true);
// }
// json.put("component", permission.getComponent());
// JSONObject meta = new JSONObject();
// meta.put("title", permission.getName());
// if(oConvertUtils.isEmpty(permission.getParentId())) {
// //一级菜单跳转地址
// json.put("redirect",permission.getRedirect());
// meta.put("icon", oConvertUtils.getString(permission.getIcon(), ""));
// }else {
// meta.put("icon", oConvertUtils.getString(permission.getIcon(), ""));
// }
// if(flag) {
// meta.put("url", permission.getUrl());
// }
// json.put("meta", meta);
// }
//
// return json;
// }
// /**
// * 通过URL生成路由name去掉URL前缀斜杠替换内容中的斜杠/’为-
// * 举例: URL = /isystem/role
// * RouteName = isystem-role
// * @return
// */
// private String urlToRouteName(String url) {
// if(oConvertUtils.isNotEmpty(url)) {
// if(url.startsWith(SymbolConstant.SINGLE_SLASH)) {
// url = url.substring(1);
// }
// url = url.replace("/", "-");
// return url;
// }else {
// return null;
// }
// }
//}

View File

@ -1,22 +1,17 @@
package org.jeecg.modules.system.controller;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.constant.SymbolConstant;
import org.jeecg.common.constant.enums.FileTypeEnum;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.util.CommonUtils;
import org.jeecg.common.util.RestUtil;
import org.jeecg.common.util.TokenUtils;
import org.jeecg.common.util.filter.FileTypeFilter;
import org.jeecg.common.util.filter.SsrfFileTypeFilter;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.system.service.ISysFilesService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.*;
@ -28,7 +23,7 @@ import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLDecoder;
/**
* <p>
* 用户表 前端控制器
@ -95,7 +90,7 @@ public class CommonController {
}
if(CommonConstant.UPLOAD_TYPE_LOCAL.equals(uploadType)){
//update-begin-author:liusq date:20221102 for: 过滤上传文件类型
FileTypeFilter.fileTypeFilter(file);
SsrfFileTypeFilter.checkUploadFileType(file);
//update-end-author:liusq date:20221102 for: 过滤上传文件类型
//update-begin-author:lvdandan date:20200928 for:修改JEditor编辑器本地上传
savePath = this.uploadLocal(file,bizPath);
@ -227,11 +222,17 @@ public class CommonController {
if (imgPath.endsWith(SymbolConstant.COMMA)) {
imgPath = imgPath.substring(0, imgPath.length() - 1);
}
//update-begin---author:liusq ---date:20230912 for检查下载文件类型--------------
SsrfFileTypeFilter.checkDownloadFileType(imgPath);
//update-end---author:liusq ---date:20230912 for检查下载文件类型--------------
String filePath = uploadpath + File.separator + imgPath;
File file = new File(filePath);
if(!file.exists()){
response.setStatus(404);
throw new RuntimeException("文件["+imgPath+"]不存在..");
log.error("文件["+imgPath+"]不存在..");
return;
//throw new RuntimeException();
}
// 设置强制下载不打开
response.setContentType("application/force-download");

View File

@ -28,7 +28,7 @@ import javax.servlet.http.HttpServletRequest;
public class DuplicateCheckController {
@Autowired
ISysDictService sysDictService;
ISysDictService sysDictService;
/**
* 校验数据是否在系统中是否存在
@ -59,5 +59,6 @@ public class DuplicateCheckController {
return Result.error("该值不可用,系统中已存在!");
}
}
}

View File

@ -14,6 +14,7 @@ import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.CacheConstant;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.constant.SymbolConstant;
import org.jeecg.common.constant.enums.DySmsEnum;
import org.jeecg.common.system.util.JwtUtil;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.*;
@ -37,6 +38,7 @@ import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;
/**
* @Author scott
@ -60,12 +62,9 @@ public class LoginController {
@Autowired
private ISysDepartService sysDepartService;
@Autowired
private ISysTenantService sysTenantService;
@Autowired
private ISysDictService sysDictService;
@Resource
private BaseCommonService baseCommonService;
@Autowired
private JeecgBaseConfig jeecgBaseConfig;

View File

@ -41,6 +41,7 @@ import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.http.HttpStatus;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
@ -51,6 +52,10 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import static org.jeecg.common.constant.CommonConstant.ANNOUNCEMENT_SEND_STATUS_1;
@ -82,6 +87,12 @@ public class SysAnnouncementController {
@Lazy
private RedisUtil redisUtil;
/**
* QQYUN-5072【性能优化】线上通知消息打开有点慢
*/
public static ExecutorService cachedThreadPool = new ThreadPoolExecutor(0, 1024,60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>());
public static ExecutorService completeNoteThreadPool = new ThreadPoolExecutor(0, 1024,60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>());
/**
* 分页列表查询
* @param sysAnnouncement
@ -105,19 +116,6 @@ public class SysAnnouncementController {
sysAnnouncement.setDelFlag(CommonConstant.DEL_FLAG_0.toString());
QueryWrapper<SysAnnouncement> queryWrapper = QueryGenerator.initQueryWrapper(sysAnnouncement, req.getParameterMap());
Page<SysAnnouncement> page = new Page<SysAnnouncement>(pageNo,pageSize);
//update-begin-author:lvdandan date:20211229 for: sqlserver mssql-jdbc 8.2.2.jre8版本下系统公告列表查询报错 查询SQL中生成了两个create_time DESC故注释此段代码
//排序逻辑 处理
// String column = req.getParameter("column");
// String order = req.getParameter("order");
// if(oConvertUtils.isNotEmpty(column) && oConvertUtils.isNotEmpty(order)) {
// if("asc".equals(order)) {
// queryWrapper.orderByAsc(oConvertUtils.camelToUnderline(column));
// }else {
// queryWrapper.orderByDesc(oConvertUtils.camelToUnderline(column));
// }
// }
//update-end-author:lvdandan date:20211229 for: sqlserver mssql-jdbc 8.2.2.jre8版本下系统公告列表查询报错 查询SQL中生成了两个create_time DESC故注释此段代码
IPage<SysAnnouncement> pageList = sysAnnouncementService.page(page, queryWrapper);
result.setSuccess(true);
result.setResult(pageList);
@ -256,8 +254,12 @@ public class SysAnnouncementController {
sysAnnouncement.setSender(currentUserName);
boolean ok = sysAnnouncementService.updateById(sysAnnouncement);
if(ok) {
result.success("系统通知发布成功");
result.success("系统通知推送成功");
if(sysAnnouncement.getMsgType().equals(CommonConstant.MSG_TYPE_ALL)) {
// 补全公告和用户之前的关系
sysAnnouncementService.batchInsertSysAnnouncementSend(sysAnnouncement.getId(), sysAnnouncement.getTenantId());
// 推送websocket通知
JSONObject obj = new JSONObject();
obj.put(WebsocketConst.MSG_CMD, WebsocketConst.CMD_TOPIC);
obj.put(WebsocketConst.MSG_ID, sysAnnouncement.getId());
@ -277,7 +279,7 @@ public class SysAnnouncementController {
}
try {
// 同步企业微信、钉钉的消息通知
Response<String> dtResponse = dingtalkService.sendActionCardMessage(sysAnnouncement, true);
Response<String> dtResponse = dingtalkService.sendActionCardMessage(sysAnnouncement, null, true);
wechatEnterpriseService.sendTextCardMessage(sysAnnouncement, true);
if (dtResponse != null && dtResponse.isSuccess()) {
@ -332,54 +334,28 @@ public class SysAnnouncementController {
@RequestMapping(value = "/listByUser", method = RequestMethod.GET)
public Result<Map<String, Object>> listByUser(@RequestParam(required = false, defaultValue = "5") Integer pageSize) {
Result<Map<String,Object>> result = new Result<Map<String,Object>>();
Map<String,Object> sysMsgMap = new HashMap(5);
LoginUser sysUser = (LoginUser)SecurityUtils.getSubject().getPrincipal();
String userId = sysUser.getId();
// 1.将系统消息补充到用户通告阅读标记表中
LambdaQueryWrapper<SysAnnouncement> querySaWrapper = new LambdaQueryWrapper<SysAnnouncement>();
//全部人员
querySaWrapper.eq(SysAnnouncement::getMsgType,CommonConstant.MSG_TYPE_ALL);
//未删除
querySaWrapper.eq(SysAnnouncement::getDelFlag,CommonConstant.DEL_FLAG_0.toString());
//已发布
querySaWrapper.eq(SysAnnouncement::getSendStatus, CommonConstant.HAS_SEND);
//新注册用户不看结束通知
querySaWrapper.ge(SysAnnouncement::getEndTime, sysUser.getCreateTime());
//update-begin--Author:liusq Date:20210108 for[JT-424] 【开源issue】bug处理--------------------
querySaWrapper.notInSql(SysAnnouncement::getId,"select annt_id from sys_announcement_send where user_id='"+userId+"'");
//update-begin--Author:liusq Date:20210108 for [JT-424] 【开源issue】bug处理--------------------
List<SysAnnouncement> announcements = sysAnnouncementService.list(querySaWrapper);
if(announcements.size()>0) {
for(int i=0;i<announcements.size();i++) {
//update-begin--Author:wangshuai Date:20200803 for 通知公告消息重复LOWCOD-759--------------------
//因为websocket没有判断是否存在这个用户要是判断会出现问题故在此判断逻辑
LambdaQueryWrapper<SysAnnouncementSend> query = new LambdaQueryWrapper<>();
query.eq(SysAnnouncementSend::getAnntId,announcements.get(i).getId());
query.eq(SysAnnouncementSend::getUserId,userId);
SysAnnouncementSend one = sysAnnouncementSendService.getOne(query);
if(null==one){
log.info("listByUser接口新增了SysAnnouncementSendpageSize{}"+pageSize);
SysAnnouncementSend announcementSend = new SysAnnouncementSend();
announcementSend.setAnntId(announcements.get(i).getId());
announcementSend.setUserId(userId);
announcementSend.setReadFlag(CommonConstant.NO_READ_FLAG);
sysAnnouncementSendService.save(announcementSend);
log.info("announcementSend.toString()",announcementSend.toString());
}
//update-end--Author:wangshuai Date:20200803 for 通知公告消息重复LOWCOD-759------------
}
}
// //补推送数据(用户和通知的关系表)
// completeNoteThreadPool.execute(()->{
// sysAnnouncementService.completeAnnouncementSendInfo();
// });
// 2.查询用户未读的系统消息
Page<SysAnnouncement> anntMsgList = new Page<SysAnnouncement>(0, pageSize);
//通知公告消息
anntMsgList = sysAnnouncementService.querySysCementPageByUserId(anntMsgList,userId,"1");
Page<SysAnnouncement> sysMsgList = new Page<SysAnnouncement>(0, pageSize);
//系统消息
sysMsgList = sysAnnouncementService.querySysCementPageByUserId(sysMsgList,userId,"2");
Map<String,Object> sysMsgMap = new HashMap(5);
sysMsgMap.put("sysMsgList", sysMsgList.getRecords());
sysMsgMap.put("sysMsgTotal", sysMsgList.getTotal());
sysMsgMap.put("anntMsgList", anntMsgList.getRecords());
sysMsgMap.put("anntMsgTotal", anntMsgList.getTotal());
//系统消息
Page<SysAnnouncement> sysMsgList = new Page<SysAnnouncement>(0, pageSize);
sysMsgList = sysAnnouncementService.querySysCementPageByUserId(sysMsgList,userId,"2");
sysMsgMap.put("sysMsgList", sysMsgList.getRecords());
sysMsgMap.put("sysMsgTotal", sysMsgList.getTotal());
result.setSuccess(true);
result.setResult(sysMsgMap);
return result;
@ -528,39 +504,56 @@ public class SysAnnouncementController {
public Result<List<SysAnnouncement>> vue3List(@RequestParam(name="fromUser", required = false) String fromUser,
@RequestParam(name="starFlag", required = false) String starFlag,
@RequestParam(name="rangeDateKey", required = false) String rangeDateKey,
@RequestParam(name="beginDate", required = false) String beginDate, @RequestParam(name="endDate", required = false) String endDate,
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo, @RequestParam(name="pageSize", defaultValue="10") Integer pageSize) {
// 后台获取开始时间/结束时间
Date bd=null, ed=null;
if(RangeDateEnum.ZDY.getKey().equals(rangeDateKey)){
if(oConvertUtils.isNotEmpty(beginDate)){
bd = DateUtils.parseDatetime(beginDate);
@RequestParam(name="beginDate", required = false) String beginDate,
@RequestParam(name="endDate", required = false) String endDate,
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize) {
long calStartTime = System.currentTimeMillis(); // 记录开始时间
// 1、获取日期查询条件开始时间和结束时间
Date beginTime = null, endTime = null;
if (RangeDateEnum.ZDY.getKey().equals(rangeDateKey)) {
// 自定义日期范围查询
if (oConvertUtils.isNotEmpty(beginDate)) {
beginTime = DateUtils.parseDatetime(beginDate);
}
if(oConvertUtils.isNotEmpty(endDate)){
ed = DateUtils.parseDatetime(endDate);
if (oConvertUtils.isNotEmpty(endDate)) {
endTime = DateUtils.parseDatetime(endDate);
}
}else{
} else {
// 日期段落查询
Date[] arr = RangeDateEnum.getRangeArray(rangeDateKey);
if(arr!=null){
bd = arr[0];
ed = arr[1];
if (arr != null) {
beginTime = arr[0];
endTime = arr[1];
}
}
List<SysAnnouncement> ls = this.sysAnnouncementService.querySysMessageList(pageSize, pageNo, fromUser, starFlag, bd, ed);
//查询出来的消息全部设置为已读
if(ls!=null && ls.size()>0){
// 2、根据条件查询用户的通知消息
List<SysAnnouncement> ls = this.sysAnnouncementService.querySysMessageList(pageSize, pageNo, fromUser, starFlag, beginTime, endTime);
// 3、设置当前页的消息为已读
if (!CollectionUtils.isEmpty(ls)) {
// 设置已读
String readed = "1";
List<String> annoceIdList = ls.stream().filter(item->!readed.equals(item.getReadFlag())).map(item->item.getId()).collect(Collectors.toList());
if(annoceIdList!=null && annoceIdList.size()>0){
sysAnnouncementService.updateReaded(annoceIdList);
List<String> annoceIdList = ls.stream().filter(item -> !readed.equals(item.getReadFlag())).map(item -> item.getId()).collect(Collectors.toList());
if (!CollectionUtils.isEmpty(annoceIdList)) {
cachedThreadPool.execute(() -> {
sysAnnouncementService.updateReaded(annoceIdList);
});
}
}
//update-begin-author:taoyan date:2022-9-25 for: VUEN-2261【移动端 系统消息】通知公告显示7条消息点进去查看后仍然显示7条其他地方已读后未读条数减少
JSONObject obj = new JSONObject();
obj.put(WebsocketConst.MSG_CMD, WebsocketConst.CMD_USER);
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
webSocket.sendMessage(sysUser.getId(), obj.toJSONString());
//update-end-author:taoyan date:2022-9-25 for: VUEN-2261【移动端 系统消息】通知公告显示7条消息点进去查看后仍然显示7条其他地方已读后未读条数减少
// 4、性能统计耗时
long calEndTime = System.currentTimeMillis(); // 记录结束时间
long duration = calEndTime - calStartTime; // 计算耗时
System.out.println("耗时:" + duration + " 毫秒");
return Result.ok(ls);
}
@ -583,4 +576,14 @@ public class SysAnnouncementController {
result.setResult(pageList);
return result;
}
/**
* 清除当前用户所有未读消息
* @return
*/
@PostMapping("/clearAllUnReadMessage")
public Result<String> clearAllUnReadMessage(){
sysAnnouncementService.clearAllUnReadMessage();
return Result.ok("清除未读消息成功");
}
}

View File

@ -72,15 +72,11 @@ public class SysAnnouncementSendController {
String column = req.getParameter("column");
String order = req.getParameter("order");
//issues/3331 SQL injection vulnerability
SqlInjectionUtil.filterContent(column);
SqlInjectionUtil.filterContent(order);
if(oConvertUtils.isNotEmpty(column) && oConvertUtils.isNotEmpty(order)) {
if(DataBaseConstant.SQL_ASC.equals(order)) {
queryWrapper.orderByAsc(oConvertUtils.camelToUnderline(column));
queryWrapper.orderByAsc(SqlInjectionUtil.getSqlInjectSortField(column));
}else {
queryWrapper.orderByDesc(oConvertUtils.camelToUnderline(column));
queryWrapper.orderByDesc(SqlInjectionUtil.getSqlInjectSortField(column));
}
}
IPage<SysAnnouncementSend> pageList = sysAnnouncementSendService.page(page, queryWrapper);
@ -203,7 +199,11 @@ public class SysAnnouncementSendController {
LambdaUpdateWrapper<SysAnnouncementSend> updateWrapper = new UpdateWrapper().lambda();
updateWrapper.set(SysAnnouncementSend::getReadFlag, CommonConstant.HAS_READ_FLAG);
updateWrapper.set(SysAnnouncementSend::getReadTime, new Date());
updateWrapper.last("where annt_id ='"+anntId+"' and user_id ='"+userId+"'");
//update-begin-author:liusq date:2023-09-04 for:系统模块存在的sql漏洞写法
updateWrapper.eq(SysAnnouncementSend::getAnntId,anntId);
updateWrapper.eq(SysAnnouncementSend::getUserId,userId);
//update-end-author:liusq date:2023-09-04 for: 系统模块存在的sql漏洞写法
//updateWrapper.last("where annt_id ='"+anntId+"' and user_id ='"+userId+"'");
SysAnnouncementSend announcementSend = new SysAnnouncementSend();
sysAnnouncementSendService.update(announcementSend, updateWrapper);
result.setSuccess(true);
@ -243,7 +243,8 @@ public class SysAnnouncementSendController {
LambdaUpdateWrapper<SysAnnouncementSend> updateWrapper = new UpdateWrapper().lambda();
updateWrapper.set(SysAnnouncementSend::getReadFlag, CommonConstant.HAS_READ_FLAG);
updateWrapper.set(SysAnnouncementSend::getReadTime, new Date());
updateWrapper.last("where user_id ='"+userId+"'");
updateWrapper.eq(SysAnnouncementSend::getUserId,userId);
//updateWrapper.last("where user_id ='"+userId+"'");
SysAnnouncementSend announcementSend = new SysAnnouncementSend();
sysAnnouncementSendService.update(announcementSend, updateWrapper);
JSONObject socketParams = new JSONObject();

View File

@ -15,7 +15,7 @@ import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.vo.DictModel;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.ImportExcelUtil;
import org.jeecg.common.util.SqlInjectionUtil;
import org.jeecg.common.util.ReflectHelper;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.config.mybatis.MybatisPlusSaasConfig;
import org.jeecg.modules.system.entity.SysCategory;
@ -322,7 +322,7 @@ public class SysCategoryController {
Result<SysCategory> result = new Result<SysCategory>();
try {
//update-begin-author:taoyan date:2022-5-6 for: issues/3663 sql注入问题
boolean isClassField = SqlInjectionUtil.isClassField(field, SysCategory.class);
boolean isClassField = ReflectHelper.isClassField(field, SysCategory.class);
if (!isClassField) {
return Result.error("字段无效,请检查!");
}

View File

@ -102,6 +102,23 @@ public class SysCommentController extends JeecgController<SysComment, ISysCommen
}
}
/**
* app端添加评论表
* @param request
* @return
*/
@ApiOperation(value = "系统评论表-添加文件", notes = "系统评论表-添加文件")
@PostMapping(value = "/appAddFile")
public Result<String> appAddFile(HttpServletRequest request) {
try {
sysCommentService.appSaveOneFileComment(request);
return Result.OK("success");
} catch (Exception e) {
log.error("评论文件上传失败:{}", e.getMessage());
return Result.error("操作失败," + e.getMessage());
}
}
@ApiOperation(value = "系统评论回复表-通过id删除", notes = "系统评论回复表-通过id删除")
@DeleteMapping(value = "/deleteOne")
public Result<String> deleteOne(@RequestParam(name = "id", required = true) String id) {

View File

@ -3,6 +3,7 @@ package org.jeecg.modules.system.controller;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@ -11,6 +12,7 @@ import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.config.TenantContext;
@ -225,4 +227,6 @@ public class SysDataSourceController extends JeecgController<SysDataSource, ISys
return super.importExcel(request, response, SysDataSource.class);
}
}

View File

@ -25,6 +25,7 @@ import org.jeecg.modules.system.model.SysDepartTreeModel;
import org.jeecg.modules.system.service.ISysDepartService;
import org.jeecg.modules.system.service.ISysUserDepartService;
import org.jeecg.modules.system.service.ISysUserService;
import org.jeecg.modules.system.vo.lowapp.ExportDepartVo;
import org.jeecgframework.poi.excel.ExcelImportUtil;
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
import org.jeecgframework.poi.excel.entity.ExportParams;
@ -137,6 +138,8 @@ public class SysDepartController {
result.setSuccess(true);
} catch (Exception e) {
log.error(e.getMessage(),e);
result.setSuccess(false);
result.setMessage("查询失败");
}
return result;
}
@ -415,6 +418,8 @@ public class SysDepartController {
SysDepart parentDept = sysDepartService.getOne(queryWrapper);
if(!parentDept.equals(null)) {
sysDepart.setParentId(parentDept.getId());
//更新父级部门不是叶子结点
sysDepartService.updateIzLeaf(parentDept.getId(),CommonConstant.NOT_LEAF);
} else {
sysDepart.setParentId("");
}
@ -574,4 +579,80 @@ public class SysDepartController {
}
return result;
}
/**
* 通过部门id和租户id获取用户 【低代码应用: 用于选择部门负责人】
* @param departId
* @return
*/
@GetMapping("/getUsersByDepartTenantId")
public Result<List<SysUser>> getUsersByDepartTenantId(@RequestParam("departId") String departId){
int tenantId = oConvertUtils.getInt(TenantContext.getTenant(), 0);
List<SysUser> sysUserList = sysUserDepartService.getUsersByDepartTenantId(departId,tenantId);
return Result.ok(sysUserList);
}
/**
* 导出excel【低代码应用: 用于导出部门】
*
* @param request
*/
@RequestMapping(value = "/appExportXls")
public ModelAndView appExportXls(SysDepart sysDepart,HttpServletRequest request) {
// Step.1 组装查询条件
int tenantId = oConvertUtils.getInt(TenantContext.getTenant(), 0);
ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
List<ExportDepartVo> pageList = sysDepartService.getExcelDepart(tenantId);
//Step.2 AutoPoi 导出Excel
//导出文件名称
mv.addObject(NormalExcelConstants.FILE_NAME, "部门列表");
mv.addObject(NormalExcelConstants.CLASS, ExportDepartVo.class);
LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("部门列表数据", "导出人:"+user.getRealname(), "导出信息"));
mv.addObject(NormalExcelConstants.DATA_LIST, pageList);
return mv;
}
/**
* 导入excel【低代码应用: 用于导出部门】
*
* @param request
*/
@RequestMapping(value = "/appImportExcel", method = RequestMethod.POST)
@CacheEvict(value= {CacheConstant.SYS_DEPARTS_CACHE,CacheConstant.SYS_DEPART_IDS_CACHE}, allEntries=true)
public Result<?> appImportExcel(HttpServletRequest request, HttpServletResponse response) {
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
List<String> errorMessageList = new ArrayList<>();
List<ExportDepartVo> listSysDeparts = null;
Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
// 获取上传文件对象
MultipartFile file = entity.getValue();
ImportParams params = new ImportParams();
params.setTitleRows(2);
params.setHeadRows(1);
params.setNeedSave(true);
try {
listSysDeparts = ExcelImportUtil.importExcel(file.getInputStream(), ExportDepartVo.class, params);
sysDepartService.importExcel(listSysDeparts,errorMessageList);
//清空部门缓存
Set keys3 = redisTemplate.keys(CacheConstant.SYS_DEPARTS_CACHE + "*");
Set keys4 = redisTemplate.keys(CacheConstant.SYS_DEPART_IDS_CACHE + "*");
redisTemplate.delete(keys3);
redisTemplate.delete(keys4);
return ImportExcelUtil.imporReturnRes(errorMessageList.size(), listSysDeparts.size() - errorMessageList.size(), errorMessageList);
} catch (Exception e) {
log.error(e.getMessage(),e);
return Result.error("文件导入失败:"+e.getMessage());
} finally {
try {
file.getInputStream().close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return Result.error("文件导入失败!");
}
}

View File

@ -24,7 +24,6 @@ import org.jeecg.modules.system.entity.SysDict;
import org.jeecg.modules.system.entity.SysDictItem;
import org.jeecg.modules.system.model.SysDictTree;
import org.jeecg.modules.system.model.TreeSelectModel;
import org.jeecg.modules.system.security.DictQueryBlackListHandler;
import org.jeecg.modules.system.service.ISysDictItemService;
import org.jeecg.modules.system.service.ISysDictService;
import org.jeecg.modules.system.vo.SysDictPage;
@ -43,7 +42,6 @@ import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
@ -70,8 +68,6 @@ public class SysDictController {
@Autowired
public RedisTemplate<String, Object> redisTemplate;
@Autowired
private DictQueryBlackListHandler dictQueryBlackListHandler;
@Autowired
private RedisUtil redisUtil;
@RequestMapping(value = "/list", method = RequestMethod.GET)
@ -171,11 +167,6 @@ public class SysDictController {
public Result<List<DictModel>> getDictItems(@PathVariable("dictCode") String dictCode, @RequestParam(value = "sign",required = false) String sign,HttpServletRequest request) {
log.info(" dictCode : "+ dictCode);
Result<List<DictModel>> result = new Result<List<DictModel>>();
//update-begin-author:taoyan date:20220317 for: VUEN-222【安全机制】字典接口、online报表、online图表等接口加一些安全机制
if(!dictQueryBlackListHandler.isPass(dictCode)){
return result.error500(dictQueryBlackListHandler.getError());
}
//update-end-author:taoyan date:20220317 for: VUEN-222【安全机制】字典接口、online报表、online图表等接口加一些安全机制
try {
List<DictModel> ls = sysDictService.getDictItems(dictCode);
if (ls == null) {
@ -202,9 +193,9 @@ public class SysDictController {
*/
@RequestMapping(value = "/loadDict/{dictCode}", method = RequestMethod.GET)
public Result<List<DictModel>> loadDict(@PathVariable("dictCode") String dictCode,
@RequestParam(name="keyword",required = false) String keyword,
@RequestParam(value = "sign",required = false) String sign,
@RequestParam(value = "pageSize", required = false) Integer pageSize) {
@RequestParam(name="keyword",required = false) String keyword,
@RequestParam(value = "sign",required = false) String sign,
@RequestParam(value = "pageSize", required = false) Integer pageSize) {
//update-begin-author:taoyan date:2023-5-22 for: /issues/4905 因为中括号(%5)的问题导致的 表单生成器字段配置时,选择关联字段,在进行高级配置时,无法加载数据库列表,提示 Sgin签名校验错误 #4905 RouteToRequestUrlFilter
if(keyword!=null && keyword.indexOf("%5")>=0){
@ -218,11 +209,6 @@ public class SysDictController {
log.info(" 加载字典表数据,加载关键字: "+ keyword);
Result<List<DictModel>> result = new Result<List<DictModel>>();
//update-begin-author:taoyan date:20220317 for: VUEN-222【安全机制】字典接口、online报表、online图表等接口加一些安全机制
if(!dictQueryBlackListHandler.isPass(dictCode)){
return result.error500(dictQueryBlackListHandler.getError());
}
//update-end-author:taoyan date:20220317 for: VUEN-222【安全机制】字典接口、online报表、online图表等接口加一些安全机制
try {
List<DictModel> ls = sysDictService.loadDict(dictCode, keyword, pageSize);
if (ls == null) {
@ -235,7 +221,7 @@ public class SysDictController {
return result;
} catch (Exception e) {
log.error(e.getMessage(),e);
result.error500("操作失败");
result.error500("操作失败" + e.getMessage());
return result;
}
}
@ -294,11 +280,6 @@ public class SysDictController {
@RequestMapping(value = "/loadDictItem/{dictCode}", method = RequestMethod.GET)
public Result<List<String>> loadDictItem(@PathVariable("dictCode") String dictCode,@RequestParam(name="key") String keys, @RequestParam(value = "sign",required = false) String sign,@RequestParam(value = "delNotExist",required = false,defaultValue = "true") boolean delNotExist,HttpServletRequest request) {
Result<List<String>> result = new Result<>();
//update-begin-author:taoyan date:20220317 for: VUEN-222【安全机制】字典接口、online报表、online图表等接口加一些安全机制
if(!dictQueryBlackListHandler.isPass(dictCode)){
return result.error500(dictQueryBlackListHandler.getError());
}
//update-end-author:taoyan date:20220317 for: VUEN-222【安全机制】字典接口、online报表、online图表等接口加一些安全机制
try {
if(dictCode.indexOf(SymbolConstant.COMMA)!=-1) {
String[] params = dictCode.split(SymbolConstant.COMMA);
@ -328,11 +309,16 @@ public class SysDictController {
* 根据表名——显示字段-存储字段 pid 加载树形数据
* @param hasChildField 是否叶子节点字段
* @param converIsLeafVal 是否需要系统转换 是否叶子节点的值 (0标识不转换、1标准系统自动转换)
* @param tableName 表名
* @param text label字段
* @param code value 字段
* @param condition 查询条件
*
*/
@SuppressWarnings("unchecked")
@RequestMapping(value = "/loadTreeData", method = RequestMethod.GET)
public Result<List<TreeSelectModel>> loadTreeData(@RequestParam(name="pid",required = false) String pid,@RequestParam(name="pidField") String pidField,
@RequestParam(name="tableName") String tbname,
@RequestParam(name="tableName") String tableName,
@RequestParam(name="text") String text,
@RequestParam(name="code") String code,
@RequestParam(name="hasChildField") String hasChildField,
@ -340,19 +326,14 @@ public class SysDictController {
@RequestParam(name="condition") String condition,
@RequestParam(value = "sign",required = false) String sign,HttpServletRequest request) {
Result<List<TreeSelectModel>> result = new Result<List<TreeSelectModel>>();
// 1.获取查询条件参数
Map<String, String> query = null;
if(oConvertUtils.isNotEmpty(condition)) {
query = JSON.parseObject(condition, Map.class);
}
// SQL注入漏洞 sign签名校验(表名,label字段,val字段,条件)
String dictCode = tbname+","+text+","+code+","+condition;
SqlInjectionUtil.filterContent(dictCode);
//update-begin-author:scott date:20230723 for:【issues/5173】SQL注入
if(!dictQueryBlackListHandler.isPass(dictCode)){
return result.error500(dictQueryBlackListHandler.getError());
}
//update-end-author:scott date:20230723 for:【issues/5173】SQL注入
List<TreeSelectModel> ls = sysDictService.queryTreeList(query,tbname, text, code, pidField, pid,hasChildField,converIsLeafVal);
// 2.返回查询结果
List<TreeSelectModel> ls = sysDictService.queryTreeList(query,tableName, text, code, pidField, pid,hasChildField,converIsLeafVal);
result.setSuccess(true);
result.setResult(ls);
return result;
@ -372,14 +353,6 @@ public class SysDictController {
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
@RequestParam(value = "sign",required = false) String sign,HttpServletRequest request){
Result<List<DictModel>> res = new Result<List<DictModel>>();
// SQL注入漏洞 sign签名校验
String dictCode = query.getTable()+","+query.getText()+","+query.getCode();
SqlInjectionUtil.filterContent(dictCode);
//update-begin-author:taoyan date:2022-11-4 for: issues/4128 sql injection
if(!dictQueryBlackListHandler.isPass(dictCode)){
return res.error500(dictQueryBlackListHandler.getError());
}
//update-end-author:taoyan date:2022-11-4 for: issues/4128 sql injection
List<DictModel> ls = this.sysDictService.queryDictTablePageList(query,pageSize,pageNo);
res.setResult(ls);
res.setSuccess(true);
@ -690,7 +663,7 @@ public class SysDictController {
*/
@GetMapping("/getDictListByLowAppId")
public Result<List<SysDictVo>> getDictListByLowAppId(HttpServletRequest request){
String lowAppId = oConvertUtils.getString(TokenUtils.getLowAppIdByRequest(request),"0");
String lowAppId = oConvertUtils.getString(TokenUtils.getLowAppIdByRequest(request));
List<SysDictVo> list = sysDictService.getDictListByLowAppId(lowAppId);
return Result.ok(list);
}
@ -703,15 +676,17 @@ public class SysDictController {
*/
@PostMapping("/addDictByLowAppId")
public Result<String> addDictByLowAppId(@RequestBody SysDictVo sysDictVo,HttpServletRequest request){
String lowAppId = oConvertUtils.getString(TokenUtils.getLowAppIdByRequest(request),"0");
String lowAppId = oConvertUtils.getString(TokenUtils.getLowAppIdByRequest(request));
String tenantId = oConvertUtils.getString(TokenUtils.getTenantIdByRequest(request));
sysDictVo.setLowAppId(lowAppId);
sysDictVo.setTenantId(oConvertUtils.getInteger(tenantId, null));
sysDictService.addDictByLowAppId(sysDictVo);
return Result.ok("添加成功");
}
@PutMapping("/editDictByLowAppId")
public Result<String> editDictByLowAppId(@RequestBody SysDictVo sysDictVo,HttpServletRequest request){
String lowAppId = oConvertUtils.getString(TokenUtils.getLowAppIdByRequest(request),"0");
String lowAppId = oConvertUtils.getString(TokenUtils.getLowAppIdByRequest(request));
sysDictVo.setLowAppId(lowAppId);
sysDictService.editDictByLowAppId(sysDictVo);
return Result.ok("编辑成功");

View File

@ -300,7 +300,8 @@ public class SysPermissionController {
json.put("auth", authjsonArray);
//全部权限配置集合(按钮权限,访问权限)
json.put("allAuth", allauthjsonArray);
json.put("sysSafeMode", jeecgBaseConfig.getSafeMode());
//数据源安全模式
json.put("sysSafeMode", jeecgBaseConfig.getFirewall()!=null? jeecgBaseConfig.getFirewall().getDataSourceSafe(): false);
result.setResult(json);
} catch (Exception e) {
result.error500("查询失败:" + e.getMessage());
@ -346,8 +347,8 @@ public class SysPermissionController {
result.put("auth", authArray);
//全部权限配置集合(按钮权限,访问权限)
result.put("allAuth", allAuthArray);
// 系统安全模式
result.put("sysSafeMode", jeecgBaseConfig.getSafeMode());
//数据源安全模式
result.put("sysSafeMode", jeecgBaseConfig.getFirewall()!=null? jeecgBaseConfig.getFirewall().getDataSourceSafe(): null);
return Result.OK(result);
} catch (Exception e) {
log.error(e.getMessage(), e);
@ -548,8 +549,8 @@ public class SysPermissionController {
*
* @return
*/
@RequiresPermissions("system:permission:saveRole")
@RequestMapping(value = "/saveRolePermission", method = RequestMethod.POST)
@RequiresPermissions("system:permission:saveRole")
public Result<String> saveRolePermission(@RequestBody JSONObject json) {
long start = System.currentTimeMillis();
Result<String> result = new Result<>();

View File

@ -19,7 +19,9 @@ import org.jeecg.common.util.ImportExcelUtil;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.config.mybatis.MybatisPlusSaasConfig;
import org.jeecg.modules.system.entity.SysPosition;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.service.ISysPositionService;
import org.jeecg.modules.system.service.ISysUserPositionService;
import org.jeecg.modules.system.service.ISysUserService;
import org.jeecgframework.poi.excel.ExcelImportUtil;
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
@ -58,6 +60,9 @@ public class SysPositionController {
@Autowired
private ISysPositionService sysPositionService;
@Autowired
private ISysUserPositionService userPositionService;
@Autowired
private ISysUserService userService;
@ -157,6 +162,8 @@ public class SysPositionController {
public Result<?> delete(@RequestParam(name = "id", required = true) String id) {
try {
sysPositionService.removeById(id);
//删除用户职位关系表
userPositionService.removeByPositionId(id);
} catch (Exception e) {
log.error("删除失败", e.getMessage());
return Result.error("删除失败!");
@ -306,4 +313,83 @@ public class SysPositionController {
}
return result;
}
/**
* 通过多个ID查询
*
* @param ids
* @return
*/
@AutoLog(value = "职务表-通过多个查询")
@ApiOperation(value = "职务表-通过多个id查询", notes = "职务表-通过多个id查询")
@GetMapping(value = "/queryByIds")
public Result<List<SysPosition>> queryByIds(@RequestParam(name = "ids") String ids) {
Result<List<SysPosition>> result = new Result<>();
QueryWrapper<SysPosition> queryWrapper = new QueryWrapper<>();
queryWrapper.in(true,"id",ids.split(","));
List<SysPosition> list = sysPositionService.list(queryWrapper);
if (list == null) {
result.error500("未找到对应实体");
} else {
result.setResult(list);
result.setSuccess(true);
}
return result;
}
/**
* 获取职位用户列表
*
* @param pageNo
* @param pageSize
* @param positionId
* @return
*/
@GetMapping("/getPositionUserList")
public Result<IPage<SysUser>> getPositionUserList(@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
@RequestParam(name = "positionId") String positionId) {
Page<SysUser> page = new Page<>(pageNo, pageSize);
IPage<SysUser> pageList = userPositionService.getPositionUserList(page, positionId);
List<String> userIds = pageList.getRecords().stream().map(SysUser::getId).collect(Collectors.toList());
if (null != userIds && userIds.size() > 0) {
Map<String, String> useDepNames = userService.getDepNamesByUserIds(userIds);
pageList.getRecords().forEach(item -> {
item.setOrgCodeTxt(useDepNames.get(item.getId()));
});
}
return Result.ok(pageList);
}
/**
* 添加成员到用户职位关系表
*
* @param userIds
* @param positionId
* @return
*/
@PostMapping("/savePositionUser")
public Result<String> saveUserPosition(@RequestParam(name = "userIds") String userIds,
@RequestParam(name = "positionId") String positionId) {
userPositionService.saveUserPosition(userIds, positionId);
return Result.ok("添加成功");
}
/**
* 职位列表移除成员
*
* @param userIds
* @param positionId
* @return
*/
@DeleteMapping("/removePositionUser")
public Result<String> removeUserPosition(@RequestParam(name = "userIds") String userIds,
@RequestParam(name = "positionId") String positionId) {
userPositionService.removePositionUser(userIds, positionId);
return Result.OK("移除成员成功");
}
}

View File

@ -13,14 +13,17 @@ import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.PageDTO;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.config.TenantContext;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.constant.SymbolConstant;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.config.mybatis.MybatisPlusSaasConfig;
import org.jeecg.modules.base.service.BaseCommonService;
import org.jeecg.modules.system.entity.*;
import org.jeecg.modules.system.model.TreeModel;
import org.jeecg.modules.system.service.*;
@ -78,7 +81,9 @@ public class SysRoleController {
@Autowired
private ISysUserRoleService sysUserRoleService;
@Autowired
private BaseCommonService baseCommonService;
/**
* 分页列表查询 【系统角色,不做租户隔离】
* @param role
@ -87,16 +92,18 @@ public class SysRoleController {
* @param req
* @return
*/
//@RequiresPermissions("system:role:list")
@RequiresPermissions("system:role:list")
@RequestMapping(value = "/list", method = RequestMethod.GET)
public Result<IPage<SysRole>> queryPageList(SysRole role,
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
HttpServletRequest req) {
Result<IPage<SysRole>> result = new Result<IPage<SysRole>>();
QueryWrapper<SysRole> queryWrapper = QueryGenerator.initQueryWrapper(role, req.getParameterMap());
//QueryWrapper<SysRole> queryWrapper = QueryGenerator.initQueryWrapper(role, req.getParameterMap());
//IPage<SysRole> pageList = sysRoleService.page(page, queryWrapper);
Page<SysRole> page = new Page<SysRole>(pageNo, pageSize);
IPage<SysRole> pageList = sysRoleService.page(page, queryWrapper);
//换成不做租户隔离的方法,实际上还是存在缺陷(缺陷:如果开启租户隔离,虽然能看到其他租户下的角色,编辑会提示报错)
IPage<SysRole> pageList = sysRoleService.listAllSysRole(page, role);
result.setSuccess(true);
result.setResult(pageList);
return result;
@ -117,11 +124,9 @@ public class SysRoleController {
HttpServletRequest req) {
Result<IPage<SysRole>> result = new Result<IPage<SysRole>>();
//------------------------------------------------------------------------------------------------
//是否开启系统管理模块的多租户数据隔离【SAAS多租户模式】
if(MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL){
role.setTenantId(oConvertUtils.getInt(TenantContext.getTenant(),0));
}
//------------------------------------------------------------------------------------------------
//此接口必须通过租户来隔离查询
role.setTenantId(oConvertUtils.getInt(!"0".equals(TenantContext.getTenant()) ? TenantContext.getTenant() : "", -1));
QueryWrapper<SysRole> queryWrapper = QueryGenerator.initQueryWrapper(role, req.getParameterMap());
Page<SysRole> page = new Page<SysRole>(pageNo, pageSize);
IPage<SysRole> pageList = sysRoleService.page(page, queryWrapper);
@ -140,6 +145,10 @@ public class SysRoleController {
public Result<SysRole> add(@RequestBody SysRole role) {
Result<SysRole> result = new Result<SysRole>();
try {
//开启多租户隔离,角色id自动生成10位
if(MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL){
role.setRoleCode(RandomUtil.randomString(10));
}
role.setCreateTime(new Date());
sysRoleService.save(role);
result.success("添加成功!");
@ -161,16 +170,29 @@ public class SysRoleController {
Result<SysRole> result = new Result<SysRole>();
SysRole sysrole = sysRoleService.getById(role.getId());
if(sysrole==null) {
result.error500("未找到对应实体");
result.error500("未找到对应角色!");
}else {
role.setUpdateTime(new Date());
//------------------------------------------------------------------
//如果是saas隔离的情况下判断当前租户id是否是当前租户下的
if (MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL) {
//获取当前用户
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
Integer tenantId = oConvertUtils.getInt(TenantContext.getTenant(), 0);
String username = "admin";
if (!tenantId.equals(role.getTenantId()) && !username.equals(sysUser.getUsername())) {
baseCommonService.addLog("未经授权修改非本租户下的角色ID" + role.getId() + ",操作人:" + sysUser.getUsername(), CommonConstant.LOG_TYPE_2, CommonConstant.OPERATE_TYPE_3);
return Result.error("修改角色失败,当前角色不在此租户中。");
}
}
//------------------------------------------------------------------
boolean ok = sysRoleService.updateById(role);
//TODO 返回false说明什么
if(ok) {
result.success("修改成功!");
}
}
return result;
}
@ -182,6 +204,18 @@ public class SysRoleController {
@RequiresPermissions("system:role:delete")
@RequestMapping(value = "/delete", method = RequestMethod.DELETE)
public Result<?> delete(@RequestParam(name="id",required=true) String id) {
//如果是saas隔离的情况下判断当前租户id是否是当前租户下的
if(MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL){
//获取当前用户
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
int tenantId = oConvertUtils.getInt(TenantContext.getTenant(), 0);
Long getRoleCount = sysRoleService.getRoleCountByTenantId(id, tenantId);
String username = "admin";
if(getRoleCount == 0 && !username.equals(sysUser.getUsername())){
baseCommonService.addLog("未经授权删除非本租户下的角色ID" + id + ",操作人:" + sysUser.getUsername(), CommonConstant.LOG_TYPE_2, CommonConstant.OPERATE_TYPE_4);
return Result.error("删除角色失败,当前角色不在此租户中。");
}
}
sysRoleService.deleteRole(id);
return Result.ok("删除角色成功");
}
@ -194,10 +228,26 @@ public class SysRoleController {
@RequiresPermissions("system:role:deleteBatch")
@RequestMapping(value = "/deleteBatch", method = RequestMethod.DELETE)
public Result<SysRole> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
baseCommonService.addLog("删除角色操作角色ids" + ids, CommonConstant.LOG_TYPE_2, CommonConstant.OPERATE_TYPE_4);
Result<SysRole> result = new Result<SysRole>();
if(oConvertUtils.isEmpty(ids)) {
result.error500("未选中角色!");
}else {
//如果是saas隔离的情况下判断当前租户id是否是当前租户下的
if(MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL){
int tenantId = oConvertUtils.getInt(TenantContext.getTenant(), 0);
String[] roleIds = ids.split(SymbolConstant.COMMA);
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
String username = "admin";
for (String id:roleIds) {
Long getRoleCount = sysRoleService.getRoleCountByTenantId(id, tenantId);
//如果存在角色id为0即不存在则删除角色
if(getRoleCount == 0 && !username.equals(sysUser.getUsername()) ){
baseCommonService.addLog("未经授权删除非本租户下的角色ID" + id + ",操作人:" + sysUser.getUsername(), CommonConstant.LOG_TYPE_2, CommonConstant.OPERATE_TYPE_4);
return Result.error("批量删除角色失败,存在角色不在此租户中,禁止批量删除");
}
}
}
sysRoleService.deleteBatchRole(ids.split(","));
result.success("删除角色成功!");
}
@ -281,7 +331,8 @@ public class SysRoleController {
if(oConvertUtils.isNotEmpty(id)) {
role = sysRoleService.getById(id);
}
SysRole newRole = sysRoleService.getOne(new QueryWrapper<SysRole>().lambda().eq(SysRole::getRoleCode, roleCode));
//SysRole newRole = sysRoleService.getOne(new QueryWrapper<SysRole>().lambda().eq(SysRole::getRoleCode, roleCode));
SysRole newRole = sysRoleService.getRoleNoTenant(roleCode);
if(newRole!=null) {
//如果根据传入的roleCode查询到信息了那么就需要做校验了。
if(role==null) {
@ -475,4 +526,42 @@ public class SysRoleController {
}
}
/**
* TODO 权限未完成(敲敲云接口,租户应用)
* 分页获取全部角色列表(包含每个角色的数量)
* @return
*/
@RequestMapping(value = "/queryPageRoleCount", method = RequestMethod.GET)
public Result<IPage<SysUserRoleCountVo>> queryPageRoleCount(@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize) {
Result<IPage<SysUserRoleCountVo>> result = new Result<>();
LambdaQueryWrapper<SysRole> query = new LambdaQueryWrapper<SysRole>();
//------------------------------------------------------------------------------------------------
//是否开启系统管理模块的多租户数据隔离【SAAS多租户模式】
if(MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL){
query.eq(SysRole::getTenantId, oConvertUtils.getInt(TenantContext.getTenant(), 0));
}
//------------------------------------------------------------------------------------------------
Page<SysRole> page = new Page<>(pageNo, pageSize);
IPage<SysRole> pageList = sysRoleService.page(page, query);
List<SysRole> records = pageList.getRecords();
IPage<SysUserRoleCountVo> sysRoleCountPage = new PageDTO<>();
List<SysUserRoleCountVo> sysCountVoList = new ArrayList<>();
//循环角色数据获取每个角色下面对应的角色数量
for (SysRole role:records) {
LambdaQueryWrapper<SysUserRole> countQuery = new LambdaQueryWrapper<>();
countQuery.eq(SysUserRole::getRoleId,role.getId());
long count = sysUserRoleService.count(countQuery);
SysUserRoleCountVo countVo = new SysUserRoleCountVo();
BeanUtils.copyProperties(role,countVo);
countVo.setCount(count);
sysCountVoList.add(countVo);
}
sysRoleCountPage.setRecords(sysCountVoList);
sysRoleCountPage.setTotal(pageList.getTotal());
sysRoleCountPage.setSize(pageList.getSize());
result.setSuccess(true);
result.setResult(sysRoleCountPage);
return result;
}
}

View File

@ -0,0 +1,146 @@
package org.jeecg.modules.system.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.modules.system.entity.SysTableWhiteList;
import org.jeecg.modules.system.service.ISysTableWhiteListService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
/**
* @Description: 系统表白名单
* @Author: jeecg-boot
* @Date: 2023-09-12
* @Version: V1.0
*/
@Slf4j
@Api(tags = "系统表白名单")
@RestController
@RequestMapping("/sys/tableWhiteList")
public class SysTableWhiteListController extends JeecgController<SysTableWhiteList, ISysTableWhiteListService> {
@Autowired
private ISysTableWhiteListService sysTableWhiteListService;
/**
* 分页列表查询
*
* @param sysTableWhiteList
* @param pageNo
* @param pageSize
* @param req
* @return
*/
//@RequiresRoles("admin")
@GetMapping(value = "/list")
public Result<?> queryPageList(
SysTableWhiteList sysTableWhiteList,
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
HttpServletRequest req
) {
QueryWrapper<SysTableWhiteList> queryWrapper = QueryGenerator.initQueryWrapper(sysTableWhiteList, req.getParameterMap());
Page<SysTableWhiteList> page = new Page<>(pageNo, pageSize);
IPage<SysTableWhiteList> pageList = sysTableWhiteListService.page(page, queryWrapper);
return Result.OK(pageList);
}
/**
* 添加
*
* @param sysTableWhiteList
* @return
*/
@AutoLog(value = "系统表白名单-添加")
@ApiOperation(value = "系统表白名单-添加", notes = "系统表白名单-添加")
//@RequiresRoles("admin")
@PostMapping(value = "/add")
public Result<?> add(@RequestBody SysTableWhiteList sysTableWhiteList) {
if (sysTableWhiteListService.add(sysTableWhiteList)) {
return Result.OK("添加成功!");
} else {
return Result.error("添加失败!");
}
}
/**
* 编辑
*
* @param sysTableWhiteList
* @return
*/
@AutoLog(value = "系统表白名单-编辑")
@ApiOperation(value = "系统表白名单-编辑", notes = "系统表白名单-编辑")
//@RequiresRoles("admin")
@RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST})
public Result<?> edit(@RequestBody SysTableWhiteList sysTableWhiteList) {
if (sysTableWhiteListService.edit(sysTableWhiteList)) {
return Result.OK("编辑成功!");
} else {
return Result.error("编辑失败!");
}
}
/**
* 通过id删除
*
* @param id
* @return
*/
@AutoLog(value = "系统表白名单-通过id删除")
@ApiOperation(value = "系统表白名单-通过id删除", notes = "系统表白名单-通过id删除")
//@RequiresRoles("admin")
@DeleteMapping(value = "/delete")
public Result<?> delete(@RequestParam(name = "id") String id) {
if (sysTableWhiteListService.deleteByIds(id)) {
return Result.OK("删除成功!");
} else {
return Result.error("删除失败!");
}
}
/**
* 批量删除
*
* @param ids
* @return
*/
@AutoLog(value = "系统表白名单-批量删除")
@ApiOperation(value = "系统表白名单-批量删除", notes = "系统表白名单-批量删除")
//@RequiresRoles("admin")
@DeleteMapping(value = "/deleteBatch")
public Result<?> deleteBatch(@RequestParam(name = "ids") String ids) {
if (sysTableWhiteListService.deleteByIds(ids)) {
return Result.OK("批量删除成功!");
} else {
return Result.error("批量删除失败!");
}
}
/**
* 通过id查询
*
* @param id
* @return
*/
@AutoLog(value = "系统表白名单-通过id查询")
@ApiOperation(value = "系统表白名单-通过id查询", notes = "系统表白名单-通过id查询")
//@RequiresRoles("admin")
@GetMapping(value = "/queryById")
public Result<?> queryById(@RequestParam(name = "id", required = true) String id) {
SysTableWhiteList sysTableWhiteList = sysTableWhiteListService.getById(id);
return Result.OK(sysTableWhiteList);
}
}

View File

@ -26,6 +26,7 @@ import org.jeecg.modules.system.service.ISysTenantPackService;
import org.jeecg.modules.system.service.ISysTenantService;
import org.jeecg.modules.system.service.ISysUserService;
import org.jeecg.modules.system.service.ISysUserTenantService;
import org.jeecg.modules.system.service.ISysDepartService;
import org.jeecg.modules.system.vo.SysUserTenantVo;
import org.jeecg.modules.system.vo.tenant.TenantDepartAuthInfo;
import org.jeecg.modules.system.vo.tenant.TenantPackModel;
@ -61,6 +62,9 @@ public class SysTenantController {
@Autowired
private BaseCommonService baseCommonService;
@Autowired
private ISysDepartService sysDepartService;
/**
* 获取列表数据
* @param sysTenant
@ -72,8 +76,8 @@ public class SysTenantController {
@RequiresPermissions("system:tenant:list")
@PermissionData(pageComponent = "system/TenantList")
@RequestMapping(value = "/list", method = RequestMethod.GET)
public Result<IPage<SysTenant>> queryPageList(SysTenant sysTenant, @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize, HttpServletRequest req) {
public Result<IPage<SysTenant>> queryPageList(SysTenant sysTenant,@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,HttpServletRequest req) {
Result<IPage<SysTenant>> result = new Result<IPage<SysTenant>>();
//---author:zhangyafei---date:20210916-----for: 租户管理添加日期范围查询---
Date beginDate=null;
@ -109,8 +113,8 @@ public class SysTenantController {
*/
@GetMapping("/recycleBinPageList")
@RequiresPermissions("system:tenant:recycleBinPageList")
public Result<IPage<SysTenant>> recycleBinPageList(SysTenant sysTenant, @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize, HttpServletRequest req){
public Result<IPage<SysTenant>> recycleBinPageList(SysTenant sysTenant,@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,HttpServletRequest req){
Result<IPage<SysTenant>> result = new Result<IPage<SysTenant>>();
Page<SysTenant> page = new Page<SysTenant>(pageNo, pageSize);
IPage<SysTenant> pageList = sysTenantService.getRecycleBinPageList(page, sysTenant);
@ -133,6 +137,8 @@ public class SysTenantController {
}
try {
sysTenantService.saveTenant(sysTenant);
//添加默认产品包
sysTenantPackService.addTenantDefaultPack(sysTenant.getId());
result.success("添加成功!");
} catch (Exception e) {
log.error(e.getMessage(), e);
@ -224,21 +230,12 @@ public class SysTenantController {
}
//------------------------------------------------------------------
Long userCount = sysTenantService.countUserLinkTenant(id);
if (userCount == 0) {
idList.add(Integer.parseInt(id));
}
}
if (idList.size() > 0) {
sysTenantService.removeByIds(idList);
if (ls.length == idList.size()) {
result.success("删除成功!");
} else {
result.success("部分删除成功!(被引用的租户无法删除)");
}
}else {
result.error500("选择的租户都已被引用,无法删除!");
idList.add(Integer.parseInt(id));
}
//update-begin---author:wangshuai ---date:20230710 for【QQYUN-5723】3、租户删除直接删除不删除中间表------------
sysTenantService.removeByIds(idList);
result.success("删除成功!");
//update-end---author:wangshuai ---date:20220523 for【QQYUN-5723】3、租户删除直接删除不删除中间表------------
}
return result;
}
@ -399,7 +396,7 @@ public class SysTenantController {
*/
@PutMapping("/invitationUserJoin")
@RequiresPermissions("system:tenant:invitation:user")
public Result<String> invitationUserJoin(@RequestParam("ids") String ids, @RequestParam("phone") String phone){
public Result<String> invitationUserJoin(@RequestParam("ids") String ids,@RequestParam("phone") String phone){
sysTenantService.invitationUserJoin(ids,phone);
return Result.ok("邀请用户成功");
}
@ -457,7 +454,7 @@ public class SysTenantController {
* @return
*/
@RequestMapping(value = "/editOwnTenant", method ={RequestMethod.PUT, RequestMethod.POST})
public Result<SysTenant> editOwnTenant(@RequestBody SysTenant tenant, HttpServletRequest req) {
public Result<SysTenant> editOwnTenant(@RequestBody SysTenant tenant,HttpServletRequest req) {
Result<SysTenant> result = new Result();
String tenantId = TokenUtils.getTenantIdByRequest(req);
if(!tenantId.equals(tenant.getId().toString())){
@ -486,21 +483,6 @@ public class SysTenantController {
public Result<Integer> saveTenantJoinUser(@RequestBody SysTenant sysTenant){
Result<Integer> result = new Result<>();
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
//------------------------------------------------------------------------------------------------
//是否开启系统管理模块的多租户数据隔离【SAAS多租户模式】
if(MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL){
//---author:scott---date:20220111-----for: 限制免费用户只能创建两个租户--
Integer count = sysTenantService.countCreateTenantNum(sysUser.getUsername());
if (count > 2) {
Set<String> roles = sysUserService.getUserRolesSet(sysUser.getUsername());
//创建一个付费角色 paymember
if (roles==null || (!roles.contains("paymember") && !roles.contains("admin"))) {
return result.error500("免费用户最多创建两个租户!");
}
}
//---author:scott---date:20220111-----for: 限制免费用户只能创建两个租户--
}
//------------------------------------------------------------------------------------------------
Integer tenantId = sysTenantService.saveTenantJoinUser(sysTenant, sysUser.getId());
result.setSuccess(true);
result.setMessage("创建成功");
@ -541,7 +523,7 @@ public class SysTenantController {
* @return
*/
@GetMapping("/getUserTenantPageList")
@RequiresPermissions("system:tenant:tenantPageList")
//@RequiresPermissions("system:tenant:tenantPageList")
public Result<IPage<SysUserTenantVo>> getUserTenantPageList(@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
@RequestParam(name = "userTenantStatus") String userTenantStatus,
@ -596,7 +578,7 @@ public class SysTenantController {
*/
@PutMapping("/cancelTenant")
//@RequiresPermissions("system:tenant:cancelTenant")
public Result<String> cancelTenant(@RequestBody SysTenant sysTenant, HttpServletRequest request) {
public Result<String> cancelTenant(@RequestBody SysTenant sysTenant,HttpServletRequest request) {
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
SysTenant tenant = sysTenantService.getById(sysTenant.getId());
if (null == tenant) {
@ -678,7 +660,7 @@ public class SysTenantController {
* @return
*/
@DeleteMapping("/exitUserTenant")
public Result<String> exitUserTenant(@RequestBody SysTenant sysTenant, HttpServletRequest request){
public Result<String> exitUserTenant(@RequestBody SysTenant sysTenant,HttpServletRequest request){
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
//验证用户是否已存在
Integer count = relationService.userTenantIzExist(sysUser.getId(),sysTenant.getId());
@ -703,19 +685,22 @@ public class SysTenantController {
* @return
*/
@PostMapping("/changeOwenUserTenant")
public Result<String> changeOwenUserTenant(@RequestParam("userId") String userId){
sysTenantService.changeOwenUserTenant(userId);
public Result<String> changeOwenUserTenant(@RequestParam("userId") String userId,
@RequestParam("tenantId") String tenantId){
sysTenantService.changeOwenUserTenant(userId,tenantId);
return Result.ok("退出租户成功");
}
/**
* 邀请用户到租户,通过手机号匹配 【低代码应用专用接口】
* @param phone
* @param departId
* @return
*/
@PostMapping("/invitationUser")
public Result<String> invitationUser(@RequestParam(name="phone") String phone){
return sysTenantService.invitationUser(phone);
public Result<String> invitationUser(@RequestParam(name="phone") String phone,
@RequestParam(name="departId",defaultValue = "") String departId){
return sysTenantService.invitationUser(phone,departId);
}
@ -826,6 +811,15 @@ public class SysTenantController {
return Result.ok("");
}
/**
* 查看是否已经申请过了超级管理员
* @return
*/
@GetMapping("/getApplySuperAdminCount")
public Result<Long> getApplySuperAdminCount(){
Long count = sysTenantService.getApplySuperAdminCount();
return Result.ok(count);
}
/**
* 进入应用组织页面 查询租户信息及当前用户是否有 管理员的权限--
@ -857,4 +851,85 @@ public class SysTenantController {
IPage<TenantPackUser> pageList = sysTenantService.queryTenantPackUserList(tenantId,packId,status,page);
return Result.ok(pageList);
}
/**
* 获取当前租户下的部门和成员数量
*/
@GetMapping("/getTenantCount")
public Result<Map<String,Long>> getTenantCount(HttpServletRequest request){
Map<String,Long> map = new HashMap<>();
Integer tenantId = oConvertUtils.getInt(TokenUtils.getTenantIdByRequest(request),0);
LambdaQueryWrapper<SysUserTenant> userTenantQuery = new LambdaQueryWrapper<>();
userTenantQuery.eq(SysUserTenant::getTenantId,tenantId);
userTenantQuery.eq(SysUserTenant::getStatus,CommonConstant.USER_TENANT_NORMAL);
long userCount = relationService.count(userTenantQuery);
map.put("userCount",userCount);
LambdaQueryWrapper<SysDepart> departQuery = new LambdaQueryWrapper<>();
departQuery.eq(SysDepart::getDelFlag,String.valueOf(CommonConstant.DEL_FLAG_0));
departQuery.eq(SysDepart::getTenantId,tenantId);
departQuery.eq(SysDepart::getStatus,CommonConstant.STATUS_1);
long departCount = sysDepartService.count(departQuery);
map.put("departCount",departCount);
return Result.ok(map);
}
/**
* 通过用户id获取租户列表分页
*
* @param sysUserTenantVo
* @return
*/
@GetMapping("/getTenantPageListByUserId")
public Result<IPage<SysTenant>> getTenantPageListByUserId(SysUserTenantVo sysUserTenantVo,
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize) {
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
List<String> list = null;
String userTenantStatus = sysUserTenantVo.getUserTenantStatus();
if (oConvertUtils.isNotEmpty(userTenantStatus)) {
list = Arrays.asList(userTenantStatus.split(SymbolConstant.COMMA));
}
Page<SysTenant> page = new Page<>(pageNo,pageSize);
IPage<SysTenant> pageList = relationService.getTenantPageListByUserId(page,sysUser.getId(),list,sysUserTenantVo);
return Result.ok(pageList);
}
/**
* 同意或拒绝加入租户
*/
@PutMapping("/agreeOrRefuseJoinTenant")
public Result<String> agreeOrRefuseJoinTenant(@RequestParam("tenantId") Integer tenantId,
@RequestParam("status") String status){
//是否开启系统管理模块的多租户数据隔离【SAAS多租户模式】
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
String userId = sysUser.getId();
SysTenant tenant = sysTenantService.getById(tenantId);
if(null == tenant){
return Result.error("不存在该组织");
}
SysUserTenant sysUserTenant = relationService.getUserTenantByTenantId(userId, tenantId);
if (null == sysUserTenant) {
return Result.error("该用户不存在该组织中,无权修改");
}
String content = "";
SysUser user = new SysUser();
user.setUsername(sysUserTenant.getCreateBy());
String realname = oConvertUtils.getString(sysUser.getRealname(),sysUser.getUsername());
//成功加入
if(CommonConstant.USER_TENANT_NORMAL.equals(status)){
//修改租户状态
relationService.agreeJoinTenant(userId,tenantId);
content = content + realname + "已同意您发送的加入 " + tenant.getName() + " 的邀请";
sysTenantService.sendMsgForAgreeAndRefuseJoin(user, content);
return Result.OK("您已同意该组织的邀请");
}else if(CommonConstant.USER_TENANT_REFUSE.equals(status)){
//直接删除关系表即可
relationService.refuseJoinTenant(userId,tenantId);
content = content + realname + "拒绝了您发送的加入 " + tenant.getName() + " 的邀请";
sysTenantService.sendMsgForAgreeAndRefuseJoin(user, content);
return Result.OK("您已成功拒绝该组织的邀请");
}
return Result.error("类型不匹配,禁止修改数据");
}
}

View File

@ -117,15 +117,13 @@ public class SysUserController {
//------------------------------------------------------------------------------------------------
//是否开启系统管理模块的多租户数据隔离【SAAS多租户模式】
if (MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL) {
String tenantId = oConvertUtils.getString(TenantContext.getTenant(), "0");
//update-begin---author:wangshuai ---date:20221223 for[QQYUN-3371]租户逻辑改造,改成关系表------------
String tenantId = oConvertUtils.getString(TenantContext.getTenant(), "-1");
List<String> userIds = userTenantService.getUserIdsByTenantId(Integer.valueOf(tenantId));
if (oConvertUtils.listIsNotEmpty(userIds)) {
queryWrapper.in("id", userIds);
}else{
queryWrapper.eq("id", "通过租户查询不到任何用户");
}
//update-end---author:wangshuai ---date:20221223 for[QQYUN-3371]租户逻辑改造,改成关系表------------
}
//------------------------------------------------------------------------------------------------
return sysUserService.queryPageList(req, queryWrapper, pageSize, pageNo);
@ -248,11 +246,12 @@ public class SysUserController {
String ids = jsonObject.getString("ids");
String status = jsonObject.getString("status");
String[] arr = ids.split(",");
for (String id : arr) {
for (String id : arr) {
if(oConvertUtils.isNotEmpty(id)) {
this.sysUserService.update(new SysUser().setStatus(Integer.parseInt(status)),
new UpdateWrapper<SysUser>().lambda().eq(SysUser::getId,id));
}
//update-begin---author:liusq ---date:20230620 for[QQYUN-5577]用户列表-冻结用户,再解冻之后,用户还是无法登陆,有缓存问题 #5066------------
sysUserService.updateStatus(id,status);
//update-end---author:liusq ---date:20230620 for[QQYUN-5577]用户列表-冻结用户,再解冻之后,用户还是无法登陆,有缓存问题 #5066------------
}
}
} catch (Exception e) {
log.error(e.getMessage(), e);
@ -645,6 +644,7 @@ public class SysUserController {
@RequestMapping(value = "/addSysUserRole", method = RequestMethod.POST)
public Result<String> addSysUserRole(@RequestBody SysUserRoleVO sysUserRoleVO) {
Result<String> result = new Result<String>();
//TODO 判断当前操作的角色是当前登录租户下的
try {
String sysRoleId = sysUserRoleVO.getRoleId();
for(String sysUserId:sysUserRoleVO.getUserIdList()) {
@ -1012,8 +1012,8 @@ public class SysUserController {
user.setPhone(phone);
user.setStatus(CommonConstant.USER_UNFREEZE);
user.setDelFlag(CommonConstant.DEL_FLAG_0);
user.setActivitiSync(CommonConstant.ACT_SYNC_0);
sysUserService.addUserWithRole(user,null);
user.setActivitiSync(CommonConstant.ACT_SYNC_1);
sysUserService.addUserWithRole(user,"");//默认临时角色 test
result.success("注册成功");
} catch (Exception e) {
result.error500("注册失败");
@ -1407,15 +1407,35 @@ public class SysUserController {
*/
@GetMapping("/appQueryUser")
public Result<List<SysUser>> appQueryUser(@RequestParam(name = "keyword", required = false) String keyword,
@RequestParam(name = "username", required = false) String username,
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize) {
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,HttpServletRequest request) {
Result<List<SysUser>> result = new Result<List<SysUser>>();
LambdaQueryWrapper<SysUser> queryWrapper =new LambdaQueryWrapper<SysUser>();
//TODO 外部模拟登陆临时账号,列表不显示
queryWrapper.ne(SysUser::getUsername,"_reserve_user_external");
if(StringUtils.isNotBlank(keyword)){
//增加 username传参
if(oConvertUtils.isNotEmpty(username)){
if(username.contains(",")){
queryWrapper.in(SysUser::getUsername,username.split(","));
}else{
queryWrapper.eq(SysUser::getUsername,username);
}
}else if(StringUtils.isNotBlank(keyword)){
queryWrapper.and(i -> i.like(SysUser::getUsername, keyword).or().like(SysUser::getRealname, keyword));
}
//------------------------------------------------------------------------------------------------
//是否开启系统管理模块的多租户数据隔离【SAAS多租户模式】
if (MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL) {
String tenantId = TokenUtils.getTenantIdByRequest(request);
//update-begin---author:wangshuai ---date:20221223 for[QQYUN-3371]租户逻辑改造,改成关系表------------
List<String> userIds = userTenantService.getUserIdsByTenantId(Integer.valueOf(tenantId));
if (oConvertUtils.listIsNotEmpty(userIds)) {
queryWrapper.in(SysUser::getId, userIds);
}
//update-end---author:wangshuai ---date:20221223 for[QQYUN-3371]租户逻辑改造,改成关系表------------
}
//------------------------------------------------------------------------------------------------
Page<SysUser> page = new Page<>(pageNo, pageSize);
IPage<SysUser> pageList = this.sysUserService.page(page, queryWrapper);
//批量查询用户的所属部门
@ -1614,22 +1634,30 @@ public class SysUserController {
if(user==null) {
return Result.error("未找到该用户数据");
}
if(oConvertUtils.isNotEmpty(user.getPost())){
String post = user.getPost();
LambdaQueryWrapper<SysPosition> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.in(SysPosition::getCode,Arrays.asList(post.split(SymbolConstant.COMMA)));
queryWrapper.select(SysPosition::getName);
List<SysPosition> sysPositionList = sysPositionService.list(queryWrapper);
//update-begin---author:wangshuai ---date:20230220 for[QQYUN-3980]组织管理中 职位功能 职位表加租户id 加职位-用户关联表------------
//获取用户id通过职位数据
List<SysPosition> sysPositionList = sysPositionService.getPositionList(user.getId());
if(null != sysPositionList && sysPositionList.size()>0){
//update-end---author:wangshuai ---date:20230220 for[QQYUN-3980]组织管理中 职位功能 职位表加租户id 加职位-用户关联表------------
StringBuilder nameBuilder = new StringBuilder();
StringBuilder idBuilder = new StringBuilder();
String verticalBar = " | ";
for (SysPosition sysPosition:sysPositionList){
nameBuilder.append(sysPosition.getName()).append(verticalBar);
idBuilder.append(sysPosition.getId()).append(SymbolConstant.COMMA);
}
String names = nameBuilder.toString();
if(oConvertUtils.isNotEmpty(names)){
names = names.substring(0,names.lastIndexOf(verticalBar));
user.setPostText(names);
}
//拼接职位id
String ids = idBuilder.toString();
if(oConvertUtils.isNotEmpty(ids)){
ids = ids.substring(0,ids.lastIndexOf(SymbolConstant.COMMA));
user.setPost(ids);
}
}
return Result.ok(user);
}
@ -1738,8 +1766,58 @@ public class SysUserController {
return result.error500("非当前租户下的用户,不允许修改!");
}
String departs = req.getParameter("selecteddeparts");
String roles = req.getParameter("selectedroles");
sysUserService.editTenantUser(sysUser,tenantId,departs,roles);
sysUserService.editTenantUser(sysUser,tenantId,departs,null);
return Result.ok("修改成功");
}
/**
* 切换租户时 需要修改 loginTenantId
* QQYUN-4491 【应用】一些小问题 1、上次选中登录的租户下次登录未记忆
* @param sysUser
* @return
*/
@PutMapping("/changeLoginTenantId")
public Result<?> changeLoginTenantId(@RequestBody SysUser sysUser){
Result<String> result = new Result<>();
Integer tenantId = sysUser.getLoginTenantId();
LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
String userId = loginUser.getId();
// 判断 指定的租户ID是不是当前登录用户的租户
LambdaQueryWrapper<SysUserTenant> query = new LambdaQueryWrapper<>();
query.eq(SysUserTenant::getTenantId, tenantId);
query.eq(SysUserTenant::getUserId, userId);
SysUserTenant one = userTenantService.getOne(query);
if(null == one){
return result.error500("非租户下的用户,不允许修改!");
}
// 修改 loginTenantId
LambdaQueryWrapper<SysUser> update = new LambdaQueryWrapper<SysUser>()
.eq(SysUser::getId, userId);
SysUser updateUser = new SysUser();
updateUser.setLoginTenantId(tenantId);
sysUserService.update(updateUser, update);
return Result.ok();
}
/**
* 应用用户导出
* @param request
* @return
*/
@RequestMapping(value = "/exportAppUser")
public ModelAndView exportAppUser(HttpServletRequest request) {
return sysUserService.exportAppUser(request);
}
/**
* 应用用户导入
* @param request
* @return
*/
@RequestMapping(value = "/importAppUser", method = RequestMethod.POST)
public Result<?> importAppUser(HttpServletRequest request, HttpServletResponse response)throws IOException {
return sysUserService.importAppUser(request);
}
}

View File

@ -1,12 +1,25 @@
package org.jeecg.modules.system.controller;
import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.jeecg.dingtalk.api.core.response.Response;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.dto.message.MessageDTO;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.config.TenantContext;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.constant.SymbolConstant;
import org.jeecg.common.constant.enums.MessageTypeEnum;
import org.jeecg.common.system.util.JwtUtil;
import org.jeecg.config.thirdapp.ThirdAppConfig;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.config.mybatis.MybatisPlusSaasConfig;
import org.jeecg.modules.system.entity.SysThirdAccount;
import org.jeecg.modules.system.entity.SysThirdAppConfig;
import org.jeecg.modules.system.service.ISysThirdAccountService;
import org.jeecg.modules.system.service.ISysThirdAppConfigService;
import org.jeecg.modules.system.service.impl.ThirdAppDingtalkServiceImpl;
import org.jeecg.modules.system.service.impl.ThirdAppWechatEnterpriseServiceImpl;
import org.jeecg.modules.system.vo.thirdapp.SyncInfoVo;
@ -14,7 +27,9 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
@ -26,22 +41,46 @@ import java.util.Map;
@RequestMapping("/sys/thirdApp")
public class ThirdAppController {
@Autowired
ThirdAppConfig thirdAppConfig;
@Autowired
ThirdAppWechatEnterpriseServiceImpl wechatEnterpriseService;
@Autowired
ThirdAppDingtalkServiceImpl dingtalkService;
@Autowired
private ISysThirdAppConfigService appConfigService;
@Autowired
private ISysThirdAccountService sysThirdAccountService;
/**
* 获取启用的系统
*/
@GetMapping("/getEnabledType")
public Result getEnabledType() {
Map<String, Boolean> enabledMap = new HashMap(5);
enabledMap.put("wechatEnterprise", thirdAppConfig.isWechatEnterpriseEnabled());
enabledMap.put("dingtalk", thirdAppConfig.isDingtalkEnabled());
//update-begin---author:wangshuai ---date:20230224 for[QQYUN-3440]通过租户模式隔离 ------------
int tenantId = oConvertUtils.getInt(TenantContext.getTenant(), 0);
//查询当前租户下的第三方配置
List<SysThirdAppConfig> list = appConfigService.getThirdConfigListByThirdType(tenantId);
//钉钉是否已配置
boolean dingConfig = false;
//企业微信是否已配置
boolean qywxConfig = false;
if(null != list && list.size()>0){
for (SysThirdAppConfig config:list) {
if(MessageTypeEnum.DD.getType().equals(config.getThirdType())){
dingConfig = true;
continue;
}
if(MessageTypeEnum.QYWX.getType().equals(config.getThirdType())){
qywxConfig = true;
continue;
}
}
}
enabledMap.put("wechatEnterprise", qywxConfig);
enabledMap.put("dingtalk", dingConfig);
//update-end---author:wangshuai ---date:20230224 for[QQYUN-3440]通过租户模式隔离------------
return Result.OK(enabledMap);
}
@ -53,7 +92,12 @@ public class ThirdAppController {
*/
@GetMapping("/sync/wechatEnterprise/user/toApp")
public Result syncWechatEnterpriseUserToApp(@RequestParam(value = "ids", required = false) String ids) {
if (thirdAppConfig.isWechatEnterpriseEnabled()) {
//update-begin---author:wangshuai ---date:20230224 for[QQYUN-3440]通过租户模式隔离 ------------
//获取企业微信配置
Integer tenantId = oConvertUtils.getInt(TenantContext.getTenant(),0);
SysThirdAppConfig config = appConfigService.getThirdConfigByThirdType(tenantId, MessageTypeEnum.QYWX.getType());
if (null != config) {
//update-begin---author:wangshuai ---date:20230224 for[QQYUN-3440]通过租户模式隔离 ------------
SyncInfoVo syncInfo = wechatEnterpriseService.syncLocalUserToThirdApp(ids);
if (syncInfo.getFailInfo().size() == 0) {
return Result.OK("同步成功", syncInfo);
@ -61,7 +105,7 @@ public class ThirdAppController {
return Result.error("同步失败", syncInfo);
}
}
return Result.error("企业微信同步功能已禁用");
return Result.error("企业微信尚未配置,请配置企业微信");
}
/**
@ -93,7 +137,10 @@ public class ThirdAppController {
*/
@GetMapping("/sync/wechatEnterprise/depart/toApp")
public Result syncWechatEnterpriseDepartToApp(@RequestParam(value = "ids", required = false) String ids) {
if (thirdAppConfig.isWechatEnterpriseEnabled()) {
//获取企业微信配置
Integer tenantId = oConvertUtils.getInt(TenantContext.getTenant(),0);
SysThirdAppConfig config = appConfigService.getThirdConfigByThirdType(tenantId, MessageTypeEnum.QYWX.getType());
if (null != config) {
SyncInfoVo syncInfo = wechatEnterpriseService.syncLocalDepartmentToThirdApp(ids);
if (syncInfo.getFailInfo().size() == 0) {
return Result.OK("同步成功", null);
@ -101,7 +148,7 @@ public class ThirdAppController {
return Result.error("同步失败", syncInfo);
}
}
return Result.error("企业微信同步功能已禁用");
return Result.error("企业微信尚未配置,请配置企业微信");
}
/**
@ -112,15 +159,19 @@ public class ThirdAppController {
*/
@GetMapping("/sync/wechatEnterprise/depart/toLocal")
public Result syncWechatEnterpriseDepartToLocal(@RequestParam(value = "ids", required = false) String ids) {
if (thirdAppConfig.isWechatEnterpriseEnabled()) {
SyncInfoVo syncInfo = wechatEnterpriseService.syncThirdAppDepartmentToLocal(ids);
if (syncInfo.getFailInfo().size() == 0) {
return Result.OK("同步成功", syncInfo);
} else {
return Result.error("同步失败", syncInfo);
}
}
return Result.error("企业微信同步功能已禁用");
return Result.error("由于企业微信接口调整,企业微信同步本地部门失效");
// //获取企业微信配置
// Integer tenantId = oConvertUtils.getInt(TenantContext.getTenant(),0);
// SysThirdAppConfig config = appConfigService.getThirdConfigByThirdType(tenantId, MessageTypeEnum.QYWX.getType());
// if (null != config) {
// SyncInfoVo syncInfo = wechatEnterpriseService.syncThirdAppDepartmentToLocal(ids);
// if (syncInfo.getFailInfo().size() == 0) {
// return Result.OK("同步成功", syncInfo);
// } else {
// return Result.error("同步失败", syncInfo);
// }
// }
// return Result.error("企业微信尚未配置,请配置企业微信");
}
/**
@ -131,7 +182,10 @@ public class ThirdAppController {
*/
@GetMapping("/sync/dingtalk/depart/toApp")
public Result syncDingtalkDepartToApp(@RequestParam(value = "ids", required = false) String ids) {
if (thirdAppConfig.isDingtalkEnabled()) {
//获取钉钉配置
Integer tenantId = oConvertUtils.getInt(TenantContext.getTenant(),0);
SysThirdAppConfig config = appConfigService.getThirdConfigByThirdType(tenantId, MessageTypeEnum.DD.getType());
if (null != config) {
SyncInfoVo syncInfo = dingtalkService.syncLocalDepartmentToThirdApp(ids);
if (syncInfo.getFailInfo().size() == 0) {
return Result.OK("同步成功", null);
@ -139,27 +193,30 @@ public class ThirdAppController {
return Result.error("同步失败", syncInfo);
}
}
return Result.error("钉钉同步功能已禁用");
return Result.error("钉钉尚未配置,请配置钉钉");
}
/**
* 同步【钉钉】[部门]到本地
*
* @param ids
* @return
*/
@GetMapping("/sync/dingtalk/depart/toLocal")
public Result syncDingtalkDepartToLocal(@RequestParam(value = "ids", required = false) String ids) {
if (thirdAppConfig.isDingtalkEnabled()) {
SyncInfoVo syncInfo = dingtalkService.syncThirdAppDepartmentToLocal(ids);
if (syncInfo.getFailInfo().size() == 0) {
return Result.OK("同步成功", syncInfo);
} else {
return Result.error("同步失败", syncInfo);
}
}
return Result.error("钉钉同步功能已禁用");
}
// /**
// * 同步【钉钉】[部门]到本地
// *
// * @param ids
// * @return
// */
// @GetMapping("/sync/dingtalk/depart/toLocal")
// public Result syncDingtalkDepartToLocal(@RequestParam(value = "ids", required = false) String ids) {
// //获取钉钉配置
// Integer tenantId = oConvertUtils.getInt(TenantContext.getTenant(),0);
// SysThirdAppConfig config = appConfigService.getThirdConfigByThirdType(tenantId, MessageTypeEnum.DD.getType());
// if (null!= config) {
// SyncInfoVo syncInfo = dingtalkService.syncThirdAppDepartmentToLocal(ids);
// if (syncInfo.getFailInfo().size() == 0) {
// return Result.OK("同步成功", syncInfo);
// } else {
// return Result.error("同步失败", syncInfo);
// }
// }
// return Result.error("钉钉尚未配置,请配置钉钉");
// }
/**
* 同步本地[用户]到【钉钉】
@ -169,7 +226,11 @@ public class ThirdAppController {
*/
@GetMapping("/sync/dingtalk/user/toApp")
public Result syncDingtalkUserToApp(@RequestParam(value = "ids", required = false) String ids) {
if (thirdAppConfig.isDingtalkEnabled()) {
//获取钉钉配置
int tenantId = oConvertUtils.getInt(TenantContext.getTenant(), 0);
//根据租户id和第三方类别获取租户数据
SysThirdAppConfig appConfig = appConfigService.getThirdConfigByThirdType(tenantId,MessageTypeEnum.DD.getType());
if(null != appConfig){
SyncInfoVo syncInfo = dingtalkService.syncLocalUserToThirdApp(ids);
if (syncInfo.getFailInfo().size() == 0) {
return Result.OK("同步成功", syncInfo);
@ -177,27 +238,30 @@ public class ThirdAppController {
return Result.error("同步失败", syncInfo);
}
}
return Result.error("钉钉同步功能已禁用");
return Result.error("钉钉尚未配置,请配置钉钉");
}
/**
* 同步【钉钉】[用户]到本地
*
* @param ids 作废
* @return
*/
@GetMapping("/sync/dingtalk/user/toLocal")
public Result syncDingtalkUserToLocal(@RequestParam(value = "ids", required = false) String ids) {
if (thirdAppConfig.isDingtalkEnabled()) {
SyncInfoVo syncInfo = dingtalkService.syncThirdAppUserToLocal();
if (syncInfo.getFailInfo().size() == 0) {
return Result.OK("同步成功", syncInfo);
} else {
return Result.error("同步失败", syncInfo);
}
}
return Result.error("钉钉同步功能已禁用");
}
// /**
// * 同步【钉钉】[用户]到本地
// *
// * @param ids 作废
// * @return
// */
// @GetMapping("/sync/dingtalk/user/toLocal")
// public Result syncDingtalkUserToLocal(@RequestParam(value = "ids", required = false) String ids) {
// //获取钉钉配置
// Integer tenantId = oConvertUtils.getInt(TenantContext.getTenant(),0);
// SysThirdAppConfig config = appConfigService.getThirdConfigByThirdType(tenantId, MessageTypeEnum.DD.getType());
// if (null != config) {
// SyncInfoVo syncInfo = dingtalkService.syncThirdAppUserToLocal();
// if (syncInfo.getFailInfo().size() == 0) {
// return Result.OK("同步成功", syncInfo);
// } else {
// return Result.error("同步失败", syncInfo);
// }
// }
// return Result.error("钉钉尚未配置,请配置钉钉");
// }
/**
* 发送消息测试
@ -215,24 +279,33 @@ public class ThirdAppController {
String receiver = params.getString("receiver");
// 消息内容
String content = params.getString("content");
// 租户id
int tenantId = oConvertUtils.getInt(TenantContext.getTenant(),0);
String fromUser = JwtUtil.getUserNameByToken(request);
String title = "第三方APP消息测试";
MessageDTO message = new MessageDTO(fromUser, receiver, title, content);
message.setToAll(sendAll);
if (ThirdAppConfig.WECHAT_ENTERPRISE.equals(app)) {
if (thirdAppConfig.isWechatEnterpriseEnabled()) {
//update-begin---author:wangshuai ---date:20230224 for[QQYUN-3440]钉钉、企业微信通过租户模式隔离 ------------
String weChatType = MessageTypeEnum.QYWX.getType();
String dingType = MessageTypeEnum.DD.getType();
if (weChatType.toUpperCase().equals(app)) {
SysThirdAppConfig config = appConfigService.getThirdConfigByThirdType(tenantId, weChatType);
if (null != config) {
//update-end---author:wangshuai ---date:20230224 for[QQYUN-3440]钉钉、企业微信通过租户模式隔离 ------------
JSONObject response = wechatEnterpriseService.sendMessageResponse(message, false);
return Result.OK(response);
}
return Result.error("企业微信已被禁用");
} else if (ThirdAppConfig.DINGTALK.equals(app)) {
if (thirdAppConfig.isDingtalkEnabled()) {
return Result.error("企业微信尚未配置,请配置企业微信");
//update-begin---author:wangshuai ---date:20230224 for[QQYUN-3440]钉钉、企业微信通过租户模式隔离 ------------
} else if (dingType.toUpperCase().equals(app)) {
SysThirdAppConfig config = appConfigService.getThirdConfigByThirdType(tenantId, dingType);
if (null != config) {
//update-end---author:wangshuai ---date:20230224 for[QQYUN-3440]钉钉、企业微信通过租户模式隔离 ------------
Response<String> response = dingtalkService.sendMessageResponse(message, false);
return Result.OK(response);
}
return Result.error("钉钉已被禁用");
return Result.error("钉钉尚未配置,请配置钉钉");
}
return Result.error("不识别的第三方APP");
}
@ -249,14 +322,17 @@ public class ThirdAppController {
String app = params.getString("app");
// 消息id
String msgTaskId = params.getString("msg_task_id");
if (ThirdAppConfig.WECHAT_ENTERPRISE.equals(app)) {
if (thirdAppConfig.isWechatEnterpriseEnabled()) {
//租户id
int tenantId = oConvertUtils.getInt(TenantContext.getTenant(),0);
if (CommonConstant.WECHAT_ENTERPRISE.equals(app)) {
SysThirdAppConfig config = appConfigService.getThirdConfigByThirdType(tenantId, MessageTypeEnum.QYWX.getType());
if (null != config) {
return Result.error("企业微信不支持撤回消息");
}
return Result.error("企业微信已被禁用");
} else if (ThirdAppConfig.DINGTALK.equals(app)) {
if (thirdAppConfig.isDingtalkEnabled()) {
return Result.error("企业微信尚未配置,请配置企业微信");
} else if (CommonConstant.DINGTALK.equals(app)) {
SysThirdAppConfig config = appConfigService.getThirdConfigByThirdType(tenantId, MessageTypeEnum.DD.getType());
if (null != config) {
Response<JSONObject> response = dingtalkService.recallMessageResponse(msgTaskId);
if (response.isSuccess()) {
return Result.OK("撤回成功", response);
@ -264,9 +340,184 @@ public class ThirdAppController {
return Result.error("撤回失败:" + response.getErrcode() + "——" + response.getErrmsg(), response);
}
}
return Result.error("钉钉已被禁用");
return Result.error("钉钉尚未配置,请配置钉钉");
}
return Result.error("不识别的第三方APP");
}
//========================begin 应用低代码钉钉/企业微信同步用户部门专用 =============================
/**
* 添加第三方app配置
*
* @param appConfig
* @return
*/
@RequestMapping(value = "/addThirdAppConfig", method = RequestMethod.POST)
public Result<String> addThirdAppConfig(@RequestBody SysThirdAppConfig appConfig) {
Result<String> result = new Result<>();
//根据当前登录租户id和第三方类别判断是否已经创建
Integer tenantId = oConvertUtils.isNotEmpty(appConfig.getTenantId()) ? appConfig.getTenantId() : oConvertUtils.getInt(TenantContext.getTenant(), 0);
SysThirdAppConfig config = appConfigService.getThirdConfigByThirdType(tenantId, appConfig.getThirdType());
if (null != config) {
result.error500("操作失败,同一个租户下只允许绑定一个钉钉或者企业微信");
return result;
}
String clientId = appConfig.getClientId();
//通过应用key获取第三方配置
List<SysThirdAppConfig> thirdAppConfigByClientId = appConfigService.getThirdAppConfigByClientId(clientId);
if(CollectionUtil.isNotEmpty(thirdAppConfigByClientId)){
result.error500("AppKey已存在请勿重复添加");
return result;
}
try {
appConfig.setTenantId(oConvertUtils.getInt(TenantContext.getTenant(),0));
appConfigService.save(appConfig);
result.success("添加成功!");
} catch (Exception e) {
log.error(e.getMessage(), e);
result.error500("操作失败");
}
return result;
}
/**
* 编辑第三方app配置
*
* @param appConfig
* @return
*/
@RequestMapping(value = "/editThirdAppConfig", method = {RequestMethod.PUT, RequestMethod.POST})
public Result<String> editThirdAppConfig(@RequestBody SysThirdAppConfig appConfig) {
Result<String> result = new Result<>();
SysThirdAppConfig config = appConfigService.getById(appConfig.getId());
if (null == config) {
result.error500("数据不存在");
return result;
}
String clientId = appConfig.getClientId();
//如果编辑的应用key,和数据库中的不一致需要判断应用key是否已存在
if(!clientId.equals(config.getClientId())){
//通过应用key获取第三方配置
List<SysThirdAppConfig> thirdAppConfigByClientId = appConfigService.getThirdAppConfigByClientId(clientId);
if(CollectionUtil.isNotEmpty(thirdAppConfigByClientId)){
result.error500("AppKey已存在请勿重复添加");
return result;
}
}
try {
appConfigService.updateById(appConfig);
result.success("修改成功!");
} catch (Exception e) {
log.error(e.getMessage(), e);
result.error500("操作失败");
}
return result;
}
/**
* 根据租户id和第三方类型获取第三方app配置信息
*
* @param tenantId
* @param thirdType
* @return
*/
@GetMapping("/getThirdConfigByTenantId")
public Result<SysThirdAppConfig> getThirdAppByTenantId(@RequestParam(name = "tenantId", required = false) Integer tenantId,
@RequestParam(name = "thirdType") String thirdType) {
Result<SysThirdAppConfig> result = new Result<>();
LambdaQueryWrapper<SysThirdAppConfig> query = new LambdaQueryWrapper<>();
query.eq(SysThirdAppConfig::getThirdType,thirdType);
if (MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL) {
if (tenantId == null) {
return Result.error("开启多租户模式租户ID参数不允许为空");
}
} else {
//租户未传递,则采用平台的
if (tenantId == null) {
tenantId = oConvertUtils.getInt(TenantContext.getTenant(), 0);
}
}
query.eq(SysThirdAppConfig::getTenantId,tenantId);
SysThirdAppConfig sysThirdAppConfig = appConfigService.getOne(query);
result.setSuccess(true);
result.setResult(sysThirdAppConfig);
return result;
}
/**
* 同步【钉钉】[部门和用户]到本地
*
* @param ids
* @return
*/
@GetMapping("/sync/dingtalk/departAndUser/toLocal")
public Result syncDingTalkDepartAndUserToLocal(@RequestParam(value = "ids", required = false) String ids) {
Integer tenantId = oConvertUtils.getInt(TenantContext.getTenant(), 0);
SysThirdAppConfig config = appConfigService.getThirdConfigByThirdType(tenantId, MessageTypeEnum.DD.getType());
if (null != config) {
SyncInfoVo syncInfo = dingtalkService.syncThirdAppDepartmentUserToLocal();
if (syncInfo.getFailInfo().size() == 0) {
return Result.OK("同步成功", syncInfo);
} else {
return Result.error("同步失败", syncInfo);
}
}
return Result.error("钉钉尚未配置,请配置钉钉");
}
//========================end 应用低代码钉钉/企业微信同步用户部门专用 ========================
//========================begin 应用低代码账号设置第三方账号绑定 ================================
/**
* 获取第三方账号
* @param thirdType
* @return
*/
@GetMapping("/getThirdAccountByUserId")
public Result<List<SysThirdAccount>> getThirdAccountByUserId(@RequestParam(name="thirdType") String thirdType){
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
LambdaQueryWrapper<SysThirdAccount> query = new LambdaQueryWrapper<>();
//根据id查询
query.eq(SysThirdAccount::getSysUserId,sysUser.getId());
//扫码登录只有租户为0
query.eq(SysThirdAccount::getTenantId,CommonConstant.TENANT_ID_DEFAULT_VALUE);
//根据第三方类别查询
if(oConvertUtils.isNotEmpty(thirdType)){
query.in(SysThirdAccount::getThirdType, Arrays.asList(thirdType.split(SymbolConstant.COMMA)));
}
List<SysThirdAccount> list = sysThirdAccountService.list(query);
return Result.ok(list);
}
/**
* 绑定第三方账号
* @return
*/
@PostMapping("/bindThirdAppAccount")
public Result<SysThirdAccount> bindThirdAppAccount(@RequestBody SysThirdAccount sysThirdAccount){
SysThirdAccount thirdAccount = sysThirdAccountService.bindThirdAppAccountByUserId(sysThirdAccount);
return Result.ok(thirdAccount);
}
/**
* 删除第三方用户信息
* @param sysThirdAccount
* @return
*/
@DeleteMapping("/deleteThirdAccount")
public Result<String> deleteThirdAccountById(@RequestBody SysThirdAccount sysThirdAccount){
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
if(!sysUser.getId().equals(sysThirdAccount.getSysUserId())){
return Result.error("无权修改他人信息");
}
SysThirdAccount thirdAccount = sysThirdAccountService.getById(sysThirdAccount.getId());
if(null == thirdAccount){
return Result.error("未找到改第三方账户信息");
}
sysThirdAccountService.removeById(thirdAccount.getId());
return Result.ok("解绑成功");
}
//========================end 应用低代码账号设置第三方账号绑定 ================================
}

View File

@ -1,5 +1,6 @@
package org.jeecg.modules.system.controller;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@ -12,16 +13,17 @@ import me.zhyd.oauth.request.AuthRequest;
import me.zhyd.oauth.utils.AuthStateUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.constant.enums.MessageTypeEnum;
import org.jeecg.common.system.util.JwtUtil;
import org.jeecg.common.util.*;
import org.jeecg.config.thirdapp.ThirdAppConfig;
import org.jeecg.config.thirdapp.ThirdAppTypeItemVo;
import org.jeecg.modules.base.service.BaseCommonService;
import org.jeecg.modules.system.entity.SysThirdAccount;
import org.jeecg.modules.system.entity.SysThirdAppConfig;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.model.ThirdLoginModel;
import org.jeecg.modules.system.service.ISysDictService;
import org.jeecg.modules.system.service.ISysThirdAccountService;
import org.jeecg.modules.system.service.ISysThirdAppConfigService;
import org.jeecg.modules.system.service.ISysUserService;
import org.jeecg.modules.system.service.impl.ThirdAppDingtalkServiceImpl;
import org.jeecg.modules.system.service.impl.ThirdAppWechatEnterpriseServiceImpl;
@ -59,13 +61,14 @@ public class ThirdLoginController {
@Autowired
private AuthRequestFactory factory;
@Autowired
ThirdAppConfig thirdAppConfig;
@Autowired
private ThirdAppWechatEnterpriseServiceImpl thirdAppWechatEnterpriseService;
@Autowired
private ThirdAppDingtalkServiceImpl thirdAppDingtalkService;
@Autowired
private ISysThirdAppConfigService appConfigService;
@RequestMapping("/render/{source}")
public void render(@PathVariable("source") String source, HttpServletResponse response) throws IOException {
log.info("第三方登录进入render" + source);
@ -94,12 +97,15 @@ public class ThirdLoginController {
//update-begin-author:wangshuai date:20201118 for:修改成查询第三方账户表
LambdaQueryWrapper<SysThirdAccount> query = new LambdaQueryWrapper<SysThirdAccount>();
query.eq(SysThirdAccount::getThirdType, source);
//update-begin---author:wangshuai---date:2023-10-07---for:【QQYUN-6667】敲敲云线上解绑重新绑定一直提示这个---
query.eq(SysThirdAccount::getTenantId, CommonConstant.TENANT_ID_DEFAULT_VALUE);
//update-end---author:wangshuai---date:2023-10-07---for:【QQYUN-6667】敲敲云线上解绑重新绑定一直提示这个---
query.and(q -> q.eq(SysThirdAccount::getThirdUserUuid, uuid).or().eq(SysThirdAccount::getThirdUserId, uuid));
List<SysThirdAccount> thridList = sysThirdAccountService.list(query);
SysThirdAccount user = null;
if(thridList==null || thridList.size()==0) {
//否则直接创建新账号
user = sysThirdAccountService.saveThirdUser(tlm);
user = sysThirdAccountService.saveThirdUser(tlm,CommonConstant.TENANT_ID_DEFAULT_VALUE);
}else {
//已存在 只设置用户名 不设置头像
user = thridList.get(0);
@ -143,7 +149,7 @@ public class ThirdLoginController {
}
//创建新账号
//update-begin-author:wangshuai date:20201118 for:修改成从第三方登录查出来的user_id在查询用户表尽行token
SysThirdAccount user = sysThirdAccountService.saveThirdUser(model);
SysThirdAccount user = sysThirdAccountService.saveThirdUser(model,CommonConstant.TENANT_ID_DEFAULT_VALUE);
if(oConvertUtils.isNotEmpty(user.getSysUserId())){
String sysUserId = user.getSysUserId();
SysUser sysUser = sysUserService.getById(sysUserId);
@ -212,9 +218,9 @@ public class ThirdLoginController {
* @throws Exception
*/
@SuppressWarnings("unchecked")
@RequestMapping(value = "/getLoginUser/{token}/{thirdType}", method = RequestMethod.GET)
@RequestMapping(value = "/getLoginUser/{token}/{thirdType}/{tenantId}", method = RequestMethod.GET)
@ResponseBody
public Result<JSONObject> getThirdLoginUser(@PathVariable("token") String token,@PathVariable("thirdType") String thirdType) throws Exception {
public Result<JSONObject> getThirdLoginUser(@PathVariable("token") String token,@PathVariable("thirdType") String thirdType,@PathVariable("tenantId") String tenantId) throws Exception {
Result<JSONObject> result = new Result<JSONObject>();
String username = JwtUtil.getUsername(token);
@ -228,7 +234,14 @@ public class ThirdLoginController {
LambdaQueryWrapper<SysThirdAccount> query = new LambdaQueryWrapper<>();
query.eq(SysThirdAccount::getSysUserId,sysUser.getId());
query.eq(SysThirdAccount::getThirdType,thirdType);
SysThirdAccount account = sysThirdAccountService.getOne(query);
query.eq(SysThirdAccount::getTenantId,oConvertUtils.getInt(tenantId,CommonConstant.TENANT_ID_DEFAULT_VALUE));
//update-begin---author:wangshuai ---date:20230328 for[QQYUN-4883]钉钉auth登录同一个租户下有同一个用户id------------
List<SysThirdAccount> accountList = sysThirdAccountService.list(query);
SysThirdAccount account = new SysThirdAccount();
if(CollectionUtil.isNotEmpty(accountList)){
account = accountList.get(0);
}
//update-end---author:wangshuai ---date:20230328 for[QQYUN-4883]钉钉auth登录同一个租户下有同一个用户id------------
if(oConvertUtils.isEmpty(sysUser.getRealname())){
sysUser.setRealname(account.getRealname());
}
@ -238,7 +251,7 @@ public class ThirdLoginController {
//update-end-author:wangshuai date:20201118 for:如果真实姓名和头像不存在就取第三方登录的
JSONObject obj = new JSONObject();
//TODO 第三方登确定登录租户和部门逻辑
//用户登录信息
obj.put("userInfo", sysUser);
//获取字典缓存【解决 #jeecg-boot/issues/3998】
@ -282,7 +295,7 @@ public class ThirdLoginController {
sysThirdAccountService.updateThirdUserId(sysUser,thirdUserUuid);
}else{
// 不存在手机号,创建用户
sysUser = sysThirdAccountService.createUser(phone,thirdUserUuid);
sysUser = sysThirdAccountService.createUser(phone,thirdUserUuid,CommonConstant.TENANT_ID_DEFAULT_VALUE);
}
String token = saveToken(sysUser);
result.setSuccess(true);
@ -299,17 +312,26 @@ public class ThirdLoginController {
*/
@ResponseBody
@GetMapping("/oauth2/{source}/login")
public String oauth2LoginCallback(@PathVariable("source") String source, @RequestParam("state") String state, HttpServletRequest request, HttpServletResponse response) throws Exception {
public String oauth2LoginCallback(@PathVariable("source") String source, @RequestParam("state") String state, HttpServletRequest request, HttpServletResponse response,
@RequestParam(value = "tenantId",required = false,defaultValue = "0") String tenantId) throws Exception {
String url;
if (ThirdAppConfig.WECHAT_ENTERPRISE.equalsIgnoreCase(source)) {
ThirdAppTypeItemVo config = thirdAppConfig.getWechatEnterprise();
//应用id为空说明没有配置lowAppId
if(oConvertUtils.isEmpty(tenantId)){
return "租户编码未配置";
}
if (CommonConstant.WECHAT_ENTERPRISE.equalsIgnoreCase(source)) {
//换成第三方app配置表
SysThirdAppConfig config = appConfigService.getThirdConfigByThirdType(Integer.valueOf(tenantId), MessageTypeEnum.QYWX.getType());
if(null == config){
return "还未配置企业微信应用,请配置企业微信应用";
}
StringBuilder builder = new StringBuilder();
// 构造企业微信OAuth2登录授权地址
builder.append("https://open.weixin.qq.com/connect/oauth2/authorize");
// 企业的CorpID
builder.append("?appid=").append(config.getClientId());
// 授权后重定向的回调链接地址请使用urlencode对链接进行处理
String redirectUri = CommonUtils.getBaseUrl(request) + "/sys/thirdLogin/oauth2/wechat_enterprise/callback";
String redirectUri = CommonUtils.getBaseUrl(request) + "/sys/thirdLogin/oauth2/wechat_enterprise/callback?tenantId="+tenantId;;
builder.append("&redirect_uri=").append(URLEncoder.encode(redirectUri, "UTF-8"));
// 返回类型此时固定为code
builder.append("&response_type=code");
@ -321,21 +343,27 @@ public class ThirdLoginController {
// 终端使用此参数判断是否需要带上身份信息
builder.append("#wechat_redirect");
url = builder.toString();
} else if (ThirdAppConfig.DINGTALK.equalsIgnoreCase(source)) {
ThirdAppTypeItemVo config = thirdAppConfig.getDingtalk();
} else if (CommonConstant.DINGTALK.equalsIgnoreCase(source)) {
//update-begin---author:wangshuai ---date:20230224 for[QQYUN-3440]新建企业微信和钉钉配置表,通过租户模式隔离------------
//换成第三方app配置表
SysThirdAppConfig appConfig = appConfigService.getThirdConfigByThirdType(Integer.valueOf(tenantId), MessageTypeEnum.DD.getType());
if(null == appConfig){
return "还未配置钉钉应用,请配置钉钉应用";
}
//update-end---author:wangshuai ---date:20230224 for[QQYUN-3440]新建企业微信和钉钉配置表,通过租户模式隔离------------
StringBuilder builder = new StringBuilder();
// 构造钉钉OAuth2登录授权地址
builder.append("https://login.dingtalk.com/oauth2/auth");
// 授权通过/拒绝后回调地址。
// 注意 需要与注册应用时登记的域名保持一致。
String redirectUri = CommonUtils.getBaseUrl(request) + "/sys/thirdLogin/oauth2/dingtalk/callback";
String redirectUri = CommonUtils.getBaseUrl(request) + "/sys/thirdLogin/oauth2/dingtalk/callback?tenantId="+tenantId;
builder.append("?redirect_uri=").append(URLEncoder.encode(redirectUri, "UTF-8"));
// 固定值为code。
// 授权通过后返回authCode。
builder.append("&response_type=code");
// 步骤一中创建的应用详情中获取。
// 企业内部应用client_id为应用的AppKey。
builder.append("&client_id=").append(config.getClientId());
builder.append("&client_id=").append(appConfig.getClientId());
// 授权范围,授权页面显示的授权信息以应用注册时配置的为准。
// openid授权后可获得用户userid
builder.append("&scope=openid");
@ -370,17 +398,18 @@ public class ThirdLoginController {
// 钉钉返回的code
@RequestParam(value = "authCode", required = false) String authCode,
@RequestParam("state") String state,
@RequestParam(name = "tenantId",defaultValue = "0") String tenantId,
HttpServletResponse response) {
SysUser loginUser;
if (ThirdAppConfig.WECHAT_ENTERPRISE.equalsIgnoreCase(source)) {
if (CommonConstant.WECHAT_ENTERPRISE.equalsIgnoreCase(source)) {
log.info("【企业微信】OAuth2登录进入callbackcode=" + code + ", state=" + state);
loginUser = thirdAppWechatEnterpriseService.oauth2Login(code);
loginUser = thirdAppWechatEnterpriseService.oauth2Login(code,Integer.valueOf(tenantId));
if (loginUser == null) {
return "登录失败";
}
} else if (ThirdAppConfig.DINGTALK.equalsIgnoreCase(source)) {
} else if (CommonConstant.DINGTALK.equalsIgnoreCase(source)) {
log.info("【钉钉】OAuth2登录进入callbackauthCode=" + authCode + ", state=" + state);
loginUser = thirdAppDingtalkService.oauth2Login(authCode);
loginUser = thirdAppDingtalkService.oauth2Login(authCode,Integer.valueOf(tenantId));
if (loginUser == null) {
return "登录失败";
}
@ -400,7 +429,7 @@ public class ThirdLoginController {
}
String token = saveToken(loginUser);
state += "/oauth2-app/login?oauth2LoginToken=" + URLEncoder.encode(token, "UTF-8");
state += "/oauth2-app/login?oauth2LoginToken=" + URLEncoder.encode(token, "UTF-8") + "&tenantId=" + URLEncoder.encode(tenantId, "UTF-8");
//update-begin---author:wangshuai ---date:20220613 for[issues/I5BOUF]oauth2 钉钉无法登录------------
state += "&thirdType=" + source;
//state += "&thirdType=" + "wechat_enterprise";
@ -424,4 +453,79 @@ public class ThirdLoginController {
}
}
/**
* 注册账号并绑定第三方账号 【低代码应用专用接口】
* @param jsonObject
* @param user
* @return
*/
@ResponseBody
@PutMapping("/registerBindThirdAccount")
public Result<String> registerBindThirdAccount(@RequestBody JSONObject jsonObject, SysUser user) {
//手机号
String phone = jsonObject.getString("phone");
//验证码
String smscode = jsonObject.getString("smscode");
String redisKey = CommonConstant.PHONE_REDIS_KEY_PRE + phone;
Object code = redisUtil.get(redisKey);
//第三方uuid
String thirdUserUuid = jsonObject.getString("thirdUserUuid");
String username = jsonObject.getString("username");
//未设置用户名,则用手机号作为用户名
if (oConvertUtils.isEmpty(username)) {
username = phone;
}
//未设置密码,则随机生成一个密码
String password = jsonObject.getString("password");
if (oConvertUtils.isEmpty(password)) {
password = RandomUtil.randomString(8);
}
String email = jsonObject.getString("email");
SysUser sysUser1 = sysUserService.getUserByName(username);
if (sysUser1 != null) {
return Result.error("用户名已注册");
}
SysUser sysUser2 = sysUserService.getUserByPhone(phone);
if (sysUser2 != null) {
return Result.error("该手机号已注册");
}
if (oConvertUtils.isNotEmpty(email)) {
SysUser sysUser3 = sysUserService.getUserByEmail(email);
if (sysUser3 != null) {
return Result.error("邮箱已被注册");
}
}
if (null == code) {
return Result.error("手机验证码失效,请重新获取");
}
if (!smscode.equals(code.toString())) {
return Result.error("手机验证码错误");
}
String realname = jsonObject.getString("realname");
if (oConvertUtils.isEmpty(realname)) {
realname = username;
}
try {
//保存用户表
user.setCreateTime(new Date());
String salt = oConvertUtils.randomGen(8);
String passwordEncode = PasswordUtil.encrypt(username, password, salt);
user.setSalt(salt);
user.setUsername(username);
user.setRealname(realname);
user.setPassword(passwordEncode);
user.setEmail(email);
user.setPhone(phone);
user.setStatus(CommonConstant.USER_UNFREEZE);
user.setDelFlag(CommonConstant.DEL_FLAG_0);
user.setActivitiSync(CommonConstant.ACT_SYNC_1);
sysUserService.addUserWithRole(user, "");
//保存第三方用户表
sysThirdAccountService.updateThirdUserId(user, thirdUserUuid);
String token = saveToken(user);
return Result.ok(token);
} catch (Exception e) {
return Result.error("注册失败");
}
}
}

View File

@ -124,7 +124,7 @@ public class SysAnnouncement implements Serializable {
**/
private java.lang.String userIds;
/**
* 业务类型(email:邮件 bpm:流程)
* 业务类型(email:邮件 bpm:流程 tenant_invite:租户邀请)
*/
private java.lang.String busType;
/**
@ -140,7 +140,13 @@ public class SysAnnouncement implements Serializable {
*/
private java.lang.String openPage;
/**
* 摘要
* 摘要/扩展业务参数
*
* 示例:
* 1 摘要值
* 放假安排
* 2 跳转流程的参数值
* {"taskDetail":true,"procInsId":"1706547306004377602","taskId":"task630958764530507776"}
*/
private java.lang.String msgAbstract;
/**

View File

@ -28,7 +28,7 @@ public class SysAnnouncementSend implements Serializable {
/**用户id*/
private java.lang.String userId;
/**阅读状态0未读1已读*/
private java.lang.String readFlag;
private java.lang.Integer readFlag;
/**阅读时间*/
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")

View File

@ -1,17 +1,18 @@
package org.jeecg.modules.system.entity;
import java.io.Serializable;
import java.util.Date;
import org.springframework.format.annotation.DateTimeFormat;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.system.vo.LoginUser;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.util.Date;
/**
* @Description: 系统数据日志
@ -20,6 +21,7 @@ import lombok.experimental.Accessors;
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@Slf4j
public class SysDataLog implements Serializable {
private static final long serialVersionUID = 1L;
@ -34,6 +36,11 @@ public class SysDataLog implements Serializable {
*/
private String createBy;
/**
* 创建人真实名称
*/
private String createName;
/**
* 创建日期
*/
@ -80,4 +87,17 @@ public class SysDataLog implements Serializable {
*/
private String type;
//update-end-author:taoyan date:2022-7-26 for: 用于表单评论记录日志 区分数据
/**
* 通过 loginUser 设置 createName
*/
public void autoSetCreateName() {
try {
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
this.setCreateName(sysUser.getRealname());
} catch (Exception e) {
log.warn("SecurityUtils.getSubject() 获取用户信息异常:" + e.getMessage());
}
}
}

View File

@ -78,5 +78,9 @@ public class SysDictItem implements Serializable {
private Date updateTime;
/**
* 字典项颜色
*/
private String itemColor;
}

View File

@ -65,8 +65,8 @@ public class SysFiles {
@Excel(name = "文档类型folder:文件夹 excel:excel doc:word pp:ppt image:图片 archive:其他文档 video:视频)", width = 15)
@ApiModelProperty(value = "文档类型folder:文件夹 excel:excel doc:word pp:ppt image:图片 archive:其他文档 video:视频)")
private String fileType;
/**文件上传类型(temp/本地上传(临时文件) manage/知识库)*/
@Excel(name = "文件上传类型(temp/本地上传(临时文件) manage/知识库)", width = 15)
/**文件上传类型(temp/本地上传(临时文件) manage/知识库 comment)*/
@Excel(name = "文件上传类型(temp/本地上传(临时文件) manage/知识库 common(通用上传))", width = 15)
@ApiModelProperty(value = "文件上传类型(temp/本地上传(临时文件) manage/知识库)")
private String storeType;
/**父级id*/

View File

@ -0,0 +1,80 @@
package org.jeecg.modules.system.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.jeecgframework.poi.excel.annotation.Excel;
import org.springframework.format.annotation.DateTimeFormat;
/**
* @Description: 系统表白名单
* @Author: jeecg-boot
* @Date: 2023-09-12
* @Version: V1.0
*/
@Data
@TableName("sys_table_white_list")
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value = "sys_table_white_list对象", description = "系统表白名单")
public class SysTableWhiteList {
/**
* 主键id
*/
@TableId(type = IdType.ASSIGN_ID)
@ApiModelProperty(value = "主键id")
private java.lang.String id;
/**
* 允许的表名
*/
@Excel(name = "允许的表名", width = 15)
@ApiModelProperty(value = "允许的表名")
private java.lang.String tableName;
/**
* 允许的字段名,多个用逗号分割
*/
@Excel(name = "允许的字段名", width = 15)
@ApiModelProperty(value = "允许的字段名")
private java.lang.String fieldName;
/**
* 状态1=启用0=禁用
*/
@Excel(name = "状态", width = 15)
@ApiModelProperty(value = "状态")
private java.lang.String status;
/**
* 创建人
*/
@Excel(name = "创建人", width = 15)
@ApiModelProperty(value = "创建人")
private java.lang.String createBy;
/**
* 创建时间
*/
@Excel(name = "创建时间", width = 20, format = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value = "创建时间")
private java.util.Date createTime;
/**
* 更新人
*/
@Excel(name = "更新人", width = 15)
@ApiModelProperty(value = "更新人")
private java.lang.String updateBy;
/**
* 更新时间
*/
@Excel(name = "更新时间", width = 20, format = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value = "更新时间")
private java.util.Date updateTime;
}

View File

@ -34,6 +34,7 @@ public class SysTenant implements Serializable {
/**
* 创建人
*/
@Dict(dictTable ="sys_user",dicText = "realname",dicCode = "username")
private String createBy;
/**

View File

@ -63,6 +63,10 @@ public class SysTenantPack implements Serializable {
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(value = "更新时间")
private Date updateTime;
/**产品包类型(default 默认产品包 custom 自定义产品包)*/
@Excel(name = "产品包类型", width = 15)
@ApiModelProperty(value = "产品包类型")
private String packType;
/**菜单id 临时字段用于新增编辑菜单id传递*/
@TableField(exist = false)

View File

@ -68,7 +68,7 @@ public class SysTenantPackUser implements Serializable {
private transient String packCode;
/**
* 状态 正常状态1 申请状态0
* 状态(1 正常 2 离职 3 待审核 4 拒绝 5 邀请加入)
*/
private Integer status;

View File

@ -77,4 +77,7 @@ public class SysThirdAccount {
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private java.util.Date updateTime;
/**租户id*/
private java.lang.Integer tenantId;
}

View File

@ -0,0 +1,80 @@
package org.jeecg.modules.system.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.jeecgframework.poi.excel.annotation.Excel;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
/**
* @Description: 第三方配置表
* @Author: jeecg-boot
* @Date: 2023-02-03
* @Version: V1.0
*/
@Data
@TableName("sys_third_app_config")
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value="sys_third_app_config对象", description="第三方配置表")
public class SysThirdAppConfig {
/**编号*/
@TableId(type = IdType.ASSIGN_ID)
@ApiModelProperty(value = "编号")
private String id;
/**租户id*/
@Excel(name = "租户id", width = 15)
@ApiModelProperty(value = "租户id")
private Integer tenantId;
/**钉钉/企业微信第三方企业应用标识*/
@Excel(name = "钉钉/企业微信第三方企业应用标识", width = 15)
@ApiModelProperty(value = "钉钉/企业微信第三方企业应用标识")
private String agentId;
/**钉钉/企业微信 应用id*/
@Excel(name = "钉钉/企业微信 应用id", width = 15)
@ApiModelProperty(value = "钉钉/企业微信 应用id")
private String clientId;
/**钉钉/企业微信应用id对应的秘钥*/
@Excel(name = "钉钉/企业微信应用id对应的秘钥", width = 15)
@ApiModelProperty(value = "钉钉/企业微信应用id对应的秘钥")
private String clientSecret;
/**企业微信自建应用Secret*/
@Excel(name = "企业微信自建应用Secret", width = 15)
@ApiModelProperty(value = "企业微信自建应用Secret")
private String agentAppSecret;
/**第三方类别(dingtalk 钉钉 wechat_enterprise 企业微信)*/
@Excel(name = "第三方类别(dingtalk 钉钉 wechat_enterprise 企业微信)", width = 15)
@ApiModelProperty(value = "第三方类别(dingtalk 钉钉 wechat_enterprise 企业微信)")
private String thirdType;
/**是否启用(0-否,1-是)*/
@Excel(name = "是否启用(0-否,1-是)", width = 15)
@ApiModelProperty(value = "是否启用(0-否,1-是)")
private Integer status;
/**创建日期*/
@Excel(name = "创建日期", width = 20, format = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private Date createTime;
/**修改日期*/
@Excel(name = "修改日期", width = 20, format = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private Date updateTime;
}

View File

@ -133,7 +133,8 @@ public class SysUser implements Serializable {
* 职务,关联职务表
*/
@Excel(name = "职务", width = 15)
@Dict(dictTable ="sys_position",dicText = "name",dicCode = "code")
@Dict(dictTable ="sys_position",dicText = "name",dicCode = "id")
@TableField(exist = false)
private String post;
/**
@ -204,4 +205,10 @@ public class SysUser implements Serializable {
* 流程状态
*/
private String bpmStatus;
/**
* 是否已经绑定第三方
*/
@TableField(exist = false)
private boolean izBindThird;
}

View File

@ -0,0 +1,54 @@
package org.jeecg.modules.system.entity;
import java.io.Serializable;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.format.annotation.DateTimeFormat;
import org.jeecgframework.poi.excel.annotation.Excel;
import java.util.Date;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
/**
* @Description: 用户职位关系表
* @Author: jeecg-boot
* @Date: 2023-02-14
* @Version: V1.0
*/
@ApiModel(value="sys_user_position对象", description="用户职位关系表")
@Data
@TableName("sys_user_position")
public class SysUserPosition implements Serializable {
private static final long serialVersionUID = 1L;
/**主键*/
@TableId(type = IdType.ASSIGN_ID)
@ApiModelProperty(value = "主键")
private String id;
/**用户id*/
@Excel(name = "用户id", width = 15)
@ApiModelProperty(value = "用户id")
private String userId;
/**职位id*/
@ApiModelProperty(value = "职位id")
private String positionId;
/**创建人*/
@ApiModelProperty(value = "创建人")
private String createBy;
/**创建时间*/
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(value = "创建时间")
private Date createTime;
/**修改人*/
@ApiModelProperty(value = "修改人")
private String updateBy;
/**修改时间*/
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
@ApiModelProperty(value = "修改时间")
private Date updateTime;
}

View File

@ -3,6 +3,8 @@ package org.jeecg.modules.system.mapper;
import java.util.Date;
import java.util.List;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import org.apache.ibatis.annotations.Param;
import org.jeecg.modules.system.entity.SysAnnouncement;
@ -27,7 +29,7 @@ public interface SysAnnouncementMapper extends BaseMapper<SysAnnouncement> {
List<SysAnnouncement> querySysCementListByUserId(Page<SysAnnouncement> page, @Param("userId")String userId,@Param("msgCategory")String msgCategory);
/**
* 分页查询消息列表
* 分页查询全部消息列表
* @param page
* @param userId
* @param fromUser
@ -35,5 +37,13 @@ public interface SysAnnouncementMapper extends BaseMapper<SysAnnouncement> {
* @param endDate
* @return
*/
List<SysAnnouncement> queryMessageList(Page<SysAnnouncement> page, @Param("userId")String userId, @Param("fromUser")String fromUser, @Param("starFlag")String starFlag, @Param("beginDate")Date beginDate, @Param("endDate")Date endDate);
List<SysAnnouncement> queryAllMessageList(Page<SysAnnouncement> page, @Param("userId")String userId, @Param("fromUser")String fromUser, @Param("starFlag")String starFlag, @Param("beginDate")Date beginDate, @Param("endDate")Date endDate);
/**
* 查询用户未阅读的通知公告
* @param currDate
* @param userId
* @return
*/
List<String> getNotSendedAnnouncementlist(@Param("currDate") Date currDate, @Param("userId")String userId);
}

View File

@ -17,13 +17,6 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
*/
public interface SysAnnouncementSendMapper extends BaseMapper<SysAnnouncementSend> {
/**
* 通过用户id查询 用户通告阅读标记表
* @param userId 用户id
* @return
*/
public List<String> queryByUserId(@Param("userId") String userId);
/**
* 获取我的消息
* @param announcementSendModel
@ -44,4 +37,10 @@ public interface SysAnnouncementSendMapper extends BaseMapper<SysAnnouncementSen
* 修改为已读消息
*/
void updateReaded(@Param("userId") String userId, @Param("annoceIdList") List<String> annoceIdList);
/**
* 清除所有未读消息
* @param userId
*/
void clearAllUnReadMessage(@Param("userId") String userId);
}

View File

@ -1,15 +1,16 @@
package org.jeecg.modules.system.mapper;
import java.util.List;
import java.util.Map;
import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.jeecg.modules.system.entity.SysCategory;
import org.jeecg.modules.system.model.TreeSelectModel;
import java.util.List;
import java.util.Map;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @Description: 分类字典
@ -42,9 +43,9 @@ public interface SysCategoryMapper extends BaseMapper<SysCategory> {
*/
@InterceptorIgnore(tenantLine = "true")
@Select("SELECT code FROM sys_category WHERE code IS NOT NULL AND pid=#{categoryPid} ORDER BY code DESC")
List<SysCategory> getMaxCategoryCodeByPage(@Param("page") Page<SysCategory> page, @Param("categoryPid") String categoryPid);
List<SysCategory> getMaxCategoryCodeByPage(@Param("page") Page<SysCategory> page,@Param("categoryPid") String categoryPid);
@InterceptorIgnore(tenantLine = "true")
@Select("SELECT code FROM sys_category WHERE ID = #{id}")
SysCategory selectSysCategoryById(@Param("id") String id);
SysCategory selectSysCategoryById(@Param("id") String id);
}

View File

@ -6,8 +6,11 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import org.jeecg.modules.system.entity.SysDepart;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.model.SysDepartTreeModel;
import org.jeecg.modules.system.model.TreeModel;
import org.jeecg.modules.system.vo.SysUserDepVo;
import org.jeecg.modules.system.vo.lowapp.ExportDepartVo;
import org.springframework.data.repository.query.Param;
import java.util.List;
@ -44,6 +47,13 @@ public interface SysDepartMapper extends BaseMapper<SysDepart> {
*/
@Select("select id from sys_depart where org_code=#{orgCode}")
public String queryDepartIdByOrgCode(@Param("orgCode") String orgCode);
/**
* 通过部门id查询部门下的用户的账号
* @param departIds 部门ID集合
* @return String
*/
public List<String> queryUserAccountByDepartIds(@Param("departIds") List<String> departIds);
/**
* 通过部门id 查询部门id,父id
@ -118,4 +128,37 @@ public interface SysDepartMapper extends BaseMapper<SysDepart> {
*/
@Update("UPDATE sys_depart SET iz_leaf=#{leaf} WHERE id = #{id}")
int setMainLeaf(@Param("id") String id, @Param("leaf") Integer leaf);
/**
* 获取租户id和部门父id获取的部门数据
* @param tenantId
* @param parentId
* @return
*/
List<ExportDepartVo> getDepartList(@Param("parentId") String parentId, @Param("tenantId") Integer tenantId);
/**
* 根据部门名称和租户id获取部门数据
* @param departName
* @param tenantId
* @return
*/
List<SysDepart> getDepartByName(@Param("departName")String departName, @Param("tenantId")Integer tenantId,@Param("parentId") String parentId);
/**
* 根据部门id获取用户id和部门名称
* @param userList
* @return
*/
List<SysUserDepVo> getUserDepartByTenantUserId(@Param("userList") List<SysUser> userList, @Param("tenantId") Integer tenantId);
/**
* 根据部门名称和租户id获取分页部门数据
* @param page
* @param departName
* @param tenantId
* @param parentId
* @return
*/
List<SysDepart> getDepartPageByName(@Param("page") Page<SysDepart> page, @Param("departName") String departName, @Param("tenantId") Integer tenantId, @Param("parentId") String parentId);
}

View File

@ -66,17 +66,6 @@ public interface SysDictMapper extends BaseMapper<SysDict> {
*/
public List<DictModelMany> queryDictItemsByCodeList(@Param("dictCodeList") List<String> dictCodeList);
/**
* 通过查询指定table的 text code 获取字典
* @param table
* @param key
* @param value
* @return List<Map<String,String>>
*/
@Deprecated
@Select("select ${key} as \"label\",${value} as \"value\" from ${table}")
public List<Map<String,String>> getDictByTableNgAlain(@Param("table") String table, @Param("key") String key, @Param("value") String value);
/**
* 通过字典code获取字典数据
* @param code
@ -117,7 +106,9 @@ public interface SysDictMapper extends BaseMapper<SysDict> {
* @return
*/
@Deprecated
List<TreeSelectModel> queryTreeList(@Param("query") Map<String, String> query, @Param("table") String table, @Param("text") String text, @Param("code") String code, @Param("pidField") String pidField, @Param("pid") String pid, @Param("hasChildField") String hasChildField, @Param("converIsLeafVal") int converIsLeafVal);
List<TreeSelectModel> queryTreeList(@Param("query") Map<String, String> query, @Param("table") String table, @Param("text") String text, @Param("code") String code,
@Param("pidField") String pidField, @Param("pid") String pid, @Param("hasChildField") String hasChildField,
@Param("converIsLeafVal") int converIsLeafVal);
/**
* 删除
@ -185,8 +176,8 @@ public interface SysDictMapper extends BaseMapper<SysDict> {
* @return
*/
@Deprecated
List<DictModel> queryTableDictByKeysAndFilterSql(@Param("table") String table, @Param("text") String text, @Param("code") String code, @Param("filterSql") String filterSql,
@Param("codeValues") List<String> codeValues);
List<DictModel> queryTableDictByKeysAndFilterSql(@Param("table") String table, @Param("text") String text, @Param("code") String code, @Param("filterSql") String filterSql,
@Param("codeValues") List<String> codeValues);
/**
* 根据应用id获取字典列表和详情

View File

@ -2,6 +2,7 @@ package org.jeecg.modules.system.mapper;
import java.util.List;
import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
@ -73,4 +74,11 @@ public interface SysPermissionMapper extends BaseMapper<SysPermission> {
* @return
*/
List<SysPermission> queryDepartPermissionList(@Param("departId") String departId);
/**
* 根据用户名称和test角色id查询权限
* @return
*/
@InterceptorIgnore(tenantLine = "true")
List<SysPermission> queryPermissionByTestRoleId();
}

View File

@ -1,7 +1,12 @@
package org.jeecg.modules.system.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Select;
import org.jeecg.modules.system.entity.SysPosition;
import org.springframework.data.repository.query.Param;
import java.util.List;
/**
* @Description: 职务表
@ -11,4 +16,25 @@ import org.jeecg.modules.system.entity.SysPosition;
*/
public interface SysPositionMapper extends BaseMapper<SysPosition> {
/**
* 通过用户id获取职位名称
* @param userId
* @return
*/
List<SysPosition> getPositionList(@Param("userId") String userId);
/**
* 通过职位id获取职位名称
* @param postList
* @return
*/
List<SysPosition> getPositionName(@Param("postList") List<String> postList);
/**
* 根据职位名称获取职位id
* @param name
* @return
*/
@Select("SELECT id FROM sys_position WHERE name = #{name} AND tenant_id = #{tenantId} ORDER BY create_time DESC")
List<String> getPositionIdByName(@Param("name") String name, @Param("tenantId") Integer tenantId, @Param("page") Page<SysPosition> page);
}

View File

@ -1,12 +1,16 @@
package org.jeecg.modules.system.mapper;
import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Update;
import org.apache.ibatis.annotations.Select;
import org.jeecg.modules.system.entity.SysRole;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import java.util.List;
/**
* <p>
* 角色表 Mapper 接口
@ -16,7 +20,24 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
* @since 2018-12-19
*/
public interface SysRoleMapper extends BaseMapper<SysRole> {
/**
* 查询全部的角色(不做租户隔离)
* @param page
* @param role
* @return
*/
@InterceptorIgnore(tenantLine = "true")
List<SysRole> listAllSysRole(@Param("page") Page<SysRole> page, @Param("role") SysRole role);
/**
* 查询角色是否存在不做租户隔离
*
* @param roleCode
* @return
*/
@InterceptorIgnore(tenantLine = "true")
SysRole getRoleNoTenant(@Param("roleCode") String roleCode);
/**
* 删除角色与用户关系
* @Author scott
@ -36,4 +57,11 @@ public interface SysRoleMapper extends BaseMapper<SysRole> {
@Delete("delete from sys_role_permission where role_id = #{roleId}")
void deleteRolePermissionRelation(@Param("roleId") String roleId);
/**
* 根据角色id和当前租户判断当前角色是否存在这个租户中
* @param id
* @return
*/
@Select("select count(*) from sys_role where id=#{id} and tenant_id=#{tenantId}")
Long getRoleCountByTenantId(@Param("id") String id, @Param("tenantId") Integer tenantId);
}

View File

@ -0,0 +1,14 @@
package org.jeecg.modules.system.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.jeecg.modules.system.entity.SysTableWhiteList;
/**
* @Description: 系统表白名单
* @Author: jeecg-boot
* @Date: 2023-09-12
* @Version: V1.0
*/
public interface SysTableWhiteListMapper extends BaseMapper<SysTableWhiteList> {
}

View File

@ -1,5 +1,6 @@
package org.jeecg.modules.system.mapper;
import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Param;
@ -22,7 +23,7 @@ public interface SysTenantMapper extends BaseMapper<SysTenant> {
* 获取最大值id
*/
@Select("select MAX(id) id FROM sys_tenant")
int getMaxTenantId();
Integer getMaxTenantId();
/**
* 获取租户回收站的数据假删除
@ -101,4 +102,22 @@ public interface SysTenantMapper extends BaseMapper<SysTenant> {
* @return
*/
List<TenantPackUser> queryTenantPackUserList(@Param("page") Page<TenantPackUser> page, @Param("tenantId") String tenantId, @Param("packId") String packId, @Param("status") Integer status);
/**
* 根据租户ID 查询租户
* @param id
* @return
*/
@Select("select * from sys_tenant where id = #{id}")
SysTenant querySysTenant(@Param("id") Integer id);
/**
* 查看是否已经申请过了超级管理员
* @param userId
* @param tenantId
* @return
*/
Long getApplySuperAdminCount(@Param("userId") String userId, @Param("tenantId") Integer tenantId);
}

View File

@ -1,7 +1,10 @@
package org.jeecg.modules.system.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.jeecg.modules.system.entity.SysTenantPack;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @Description: 租户产品包

View File

@ -1,8 +1,12 @@
package org.jeecg.modules.system.mapper;
import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
import org.jeecg.modules.system.entity.SysTenantPackUser;
import java.util.List;
/**
* @Description: 租户产品包用户关系
* @Author: jeecg-boot
@ -11,4 +15,14 @@ import org.jeecg.modules.system.entity.SysTenantPackUser;
*/
public interface SysTenantPackUserMapper extends BaseMapper<SysTenantPackUser> {
/**
* 查询租户下 特定角色的人员列表
* @param tenantId
* @param packCodeList
* @return
*/
@InterceptorIgnore(tenantLine = "true")
List<String> queryTenantPackUserNameList(@Param("tenantId") Integer tenantId, @Param("packCodeList") List<String> packCodeList);
}

View File

@ -21,6 +21,6 @@ public interface SysThirdAccountMapper extends BaseMapper<SysThirdAccount> {
* @param thirdType 第三方类型
* @return
*/
List<SysThirdAccount> selectThirdIdsByUsername(@Param("sysUsernameArr") String[] sysUsernameArr, @Param("thirdType") String thirdType);
List<SysThirdAccount> selectThirdIdsByUsername(@Param("sysUsernameArr") String[] sysUsernameArr, @Param("thirdType") String thirdType, @Param("tenantId") Integer tenantId);
}

View File

@ -0,0 +1,31 @@
package org.jeecg.modules.system.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.jeecg.modules.system.entity.SysThirdAppConfig;
import org.springframework.data.repository.query.Param;
import java.util.List;
/**
* @Description: 第三方配置表
* @Author: jeecg-boot
* @Date: 2023-02-03
* @Version: V1.0
*/
public interface SysThirdAppConfigMapper extends BaseMapper<SysThirdAppConfig> {
/**
* 根据租户id获取钉钉/企业微信配置
* @param tenantId
* @return
*/
List<SysThirdAppConfig> getThirdConfigListByThirdType(@Param("tenantId") int tenantId);
/**
* 根据租户id和第三方类别获取第三方配置
* @param tenantId
* @param thirdType
* @return
*/
SysThirdAppConfig getThirdConfigByThirdType(@Param("tenantId") int tenantId, @Param("thirdType") String thirdType);
}

View File

@ -4,6 +4,7 @@ import java.util.List;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.entity.SysUserDepart;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
@ -80,4 +81,21 @@ public interface SysUserDepartMapper extends BaseMapper<SysUserDepart>{
* @param tenantId
*/
void deleteUserDepart(@Param("userId") String userId, @Param("tenantId") String tenantId);
/**
* 通过部门id和租户id获取用户
* @param departId
* @param tenantId
* @return
*/
List<SysUser> getUsersByDepartTenantId(@Param("departId") String departId, @Param("tenantId") Integer tenantId);
/**
* 根据用户id和部门id获取数量,用于查看用户是否存在用户部门关系表中
* @param userId
* @param departId
* @return
*/
@Select("SELECT COUNT(*) FROM sys_user_depart WHERE user_id = #{userId} AND dep_id = #{departId}")
Long getCountByDepartIdAndUserId(String userId, String departId);
}

View File

@ -37,6 +37,14 @@ public interface SysUserMapper extends BaseMapper<SysUser> {
*/
IPage<SysUser> getUserByDepId(Page page, @Param("departId") String departId, @Param("username") String username);
/**
* 根据部门和子部门下的所有用户账号
*
* @param orgCode 部门编码
* @return
*/
List<String> getUserAccountsByDepCode(@Param("orgCode") String orgCode);
/**
* 根据用户Ids,查询用户所属部门名称信息
* @param userIds
@ -181,4 +189,19 @@ public interface SysUserMapper extends BaseMapper<SysUser> {
* @return
*/
List<SysUser> getTenantQuitList(@Param("tenantId") Integer tenantId);
/**
* 获取租户下的有效用户ids
* @param tenantId
* @return
*/
List<String> getTenantUserIdList(@Param("tenantId") Integer tenantId);
/**
* 根据部门id和租户id获取用户数据
* @param departIds
* @param tenantId
* @return
*/
List<SysUser> getUserByDepartsTenantId(@Param("departIds") List<String> departIds,@Param("tenantId") Integer tenantId);
}

View File

@ -0,0 +1,84 @@
package org.jeecg.modules.system.mapper;
import java.util.List;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Select;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.entity.SysUserPosition;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
import org.jeecg.modules.system.vo.SysUserPositionVo;
/**
* @Description: 用户职位关系表
* @Author: jeecg-boot
* @Date: 2023-02-14
* @Version: V1.0
*/
public interface SysUserPositionMapper extends BaseMapper<SysUserPosition> {
/**
* 获取职位用户列表
* @param page
* @param positionId
* @return
*/
List<SysUser> getPositionUserList(@Param("page") Page<SysUser> page, @Param("positionId") String positionId);
/**
* 获取成员是否存在职位中
* @param userId
* @param positionId
* @return
*/
@Select("SELECT count(*) FROM sys_user_position WHERE user_id = #{userId} and position_id = #{positionId}")
Long getUserPositionCount(@Param("userId") String userId, @Param("positionId") String positionId);
/**
* 通过职位id删除用户职位关系表
* @param positionId
*/
@Delete("DELETE FROM sys_user_position WHERE position_id = #{positionId} ")
void removeByPositionId(@Param("positionId") String positionId);
/**
* 职位列表移除成员
* @param userIdList
* @param positionId
*/
void removePositionUser(@Param("userIdList") List<String> userIdList, @Param("positionId") String positionId);
/**
* 根据用户id查询职位id
* @param userId
* @return
*/
List<String> getPositionIdByUserId(@Param("userId") String userId);
/**
* 根据用户ID和租户ID获取职位id
* @param userId
* @param tenantId
* @return
*/
List<String> getPositionIdByUserTenantId(@Param("userId")String userId, @Param("tenantId")Integer tenantId);
/**
* 根据用户id获取用户职位
* @param userIdList
* @param tenantId
* @return
*/
List<SysUserPositionVo> getPositionIdByUsersTenantId(@Param("userIdList") List<SysUser> userIdList, @Param("tenantId") Integer tenantId);
/**
* 根据职位名称和租户id删除用户职位关系表
* @param positionNames
* @param tenantId
* @param userId
*/
void deleteUserPosByNameAndTenantId(@Param("positionNames") List<String> positionNames, @Param("tenantId") Integer tenantId, @Param("userId") String userId);
}

View File

@ -3,7 +3,11 @@ package org.jeecg.modules.system.mapper;
import java.util.List;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import org.jeecg.modules.system.entity.SysTenant;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.entity.SysUserTenant;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
@ -96,4 +100,53 @@ public interface SysUserTenantMapper extends BaseMapper<SysUserTenant> {
* @param tenantId
*/
Integer userTenantIzExist(@Param("userId") String userId, @Param("tenantId") int tenantId);
/**
* 查询未被注销的租户
* @param userId
* @return
*/
List<SysTenant> getTenantNoCancel(@Param("userId") String userId);
/**
* 根据用户id获取我的租户
* @param page
* @param userId
* @param userTenantStatus
* @return
*/
List<SysTenant> getTenantPageListByUserId(@Param("page") Page<SysTenant> page, @Param("userId") String userId, @Param("userTenantStatus") List<String> userTenantStatus,@Param("sysUserTenantVo") SysUserTenantVo sysUserTenantVo);
/**
* 同意加入租户
* @param userId
* @param tenantId
*/
@Update("update sys_user_tenant set status = '1' where user_id = #{userId} and tenant_id = #{tenantId}")
void agreeJoinTenant(@Param("userId") String userId, @Param("tenantId") Integer tenantId);
/**
* 拒绝加入租户
* @param userId
* @param tenantId
*/
@Delete("delete from sys_user_tenant where user_id = #{userId} and tenant_id = #{tenantId}")
void refuseJoinTenant(@Param("userId") String userId, @Param("tenantId") Integer tenantId);
/**
* 根据用户id和租户id获取用户租户中间表信息
*
* @param userId
* @param tenantId
* @return
*/
@Select("select id,user_id,tenant_id,create_by,status from sys_user_tenant where user_id = #{userId} and tenant_id = #{tenantId}")
SysUserTenant getUserTenantByTenantId(@Param("userId") String userId, @Param("tenantId") Integer tenantId);
/**
* 删除租户下的用户
*
* @param tenantIds
*/
void deleteUserByTenantId(@Param("tenantIds") List<Integer> tenantIds);
}

View File

@ -26,7 +26,7 @@
<result column="open_type" property="openType" jdbcType="VARCHAR"/>
<result column="open_page" property="openPage" jdbcType="VARCHAR"/>
<result column="read_flag" property="readFlag" jdbcType="VARCHAR"/>
<result column="read_flag" property="readFlag" jdbcType="INTEGER"/>
<result column="star_flag" property="starFlag" jdbcType="VARCHAR"/>
<result column="send_id" property="sendId" jdbcType="VARCHAR"/>
</resultMap>
@ -37,14 +37,29 @@
where send_status = '1'
and del_flag = '0'
and msg_category = #{msgCategory}
and id IN ( select annt_id from sys_announcement_send where user_id = #{userId} and read_flag = '0')
and id IN ( select annt_id from sys_announcement_send where user_id = #{userId} and read_flag = 0)
order by create_time DESC
</select>
<!-- 查询消息记录 -->
<select id="queryMessageList" resultMap="SysAnnouncement">
select a.*,
<select id="queryAllMessageList" resultMap="SysAnnouncement">
select
a.id,
a.titile,
a.msg_content,
a.sender,
a.priority,
a.msg_category,
a.msg_type,
a.send_status,
a.send_time,
a.bus_type,
a.bus_id,
a.open_type,
a.open_page,
a.msg_abstract,
a.dt_task_id,
b.read_flag,
b.star_flag,
b.id as send_id
@ -65,7 +80,27 @@
<if test="starFlag!=null and starFlag!=''">
and b.star_flag = #{starFlag}
</if>
order by b.read_flag ASC,a.create_time DESC
order by b.read_flag ASC, a.create_time DESC
</select>
<!-- 查询用户未阅读的通知公告 -->
<select id="getNotSendedAnnouncementlist" resultType="java.lang.String" parameterType="object">
SELECT
a.id
FROM
sys_announcement a
WHERE
a.del_flag = '0'
AND a.send_status = '1'
AND a.msg_type = 'ALL'
AND a.end_time >= #{currDate}
AND a.id NOT IN (
SELECT
annt_id
FROM
sys_announcement_send
WHERE
user_id = #{userId}
)
</select>
</mapper>

View File

@ -18,11 +18,6 @@
<result column="open_page" property="openPage" jdbcType="VARCHAR"/>
</resultMap>
<select id="queryByUserId" parameterType="String" resultType="String">
select sas.annt_id from sys_announcement_send sas
where sas.user_id = #{userId}
</select>
<select id="getMyAnnouncementSendList" parameterType="Object" resultMap="AnnouncementSendModel">
select
sas.id,
@ -51,7 +46,7 @@
<if test="announcementSendModel.sender !=null and announcementSendModel.sender != ''">
and sa.sender LIKE concat(concat('%',#{announcementSendModel.sender}),'%')
</if>
<if test="announcementSendModel.readFlag !=null and announcementSendModel.readFlag != ''">
<if test="announcementSendModel.readFlag !=null">
and sas.read_flag = #{announcementSendModel.readFlag}
</if>
<if test="announcementSendModel.busType !=null and announcementSendModel.busType != ''">
@ -95,7 +90,7 @@
<!-- 修改为已读消息 -->
<update id="updateReaded">
update sys_announcement_send set read_flag = '1'
update sys_announcement_send set read_flag = 1
where user_id = #{userId}
and annt_id in
<foreach collection="annoceIdList" index="index" item="id" open="(" separator="," close=")">
@ -103,5 +98,11 @@
</foreach>
</update>
<!--清除所有未读消息-->
<update id="clearAllUnReadMessage">
update sys_announcement_send set read_flag = 1
where user_id = #{userId} and read_flag = 0
</update>
</mapper>

View File

@ -91,4 +91,67 @@
</choose>
ORDER BY org_code DESC
</select>
<!--获取父级部门的数据-->
<select id="getDepartList" resultType="org.jeecg.modules.system.vo.lowapp.ExportDepartVo">
SELECT id,depart_name,parent_id FROM sys_depart
WHERE
tenant_id = #{tenantId}
AND
<choose>
<when test="parentId != null and parentId != ''">
parent_id = #{parentId}
</when>
<otherwise>
parent_id IS NULL OR parent_id=''
</otherwise>
</choose>
ORDER BY depart_order DESC
</select>
<!--根据部门名称和租户id获取部门数据-->
<select id="getDepartByName" resultType="org.jeecg.modules.system.entity.SysDepart">
SELECT id,depart_name,org_code,parent_id FROM sys_depart
where
depart_name = #{departName}
and tenant_id = #{tenantId}
<if test="parentId != null and parentId != ''">
and parent_id = #{parentId}
</if>
order by create_time desc
</select>
<!--根据用户id获取用户id和部门名称-->
<select id="getUserDepartByTenantUserId" resultType="org.jeecg.modules.system.vo.SysUserDepVo">
SELECT sd.depart_name, sud.user_id
FROM sys_depart sd
RIGHT JOIN sys_user_depart sud on sd.id = sud.dep_id and sd.del_flag = 0
WHERE sud.user_id IN
<foreach collection="userList" index="index" item="item" open="(" separator="," close=")">
#{item.id}
</foreach>
AND sd.tenant_id = #{tenantId}
order by sd.org_code;
</select>
<!--根据部门名称和租户id获取分页部门数据-->
<select id="getDepartPageByName" resultType="org.jeecg.modules.system.entity.SysDepart">
SELECT id,depart_name,org_code,parent_id FROM sys_depart
where
depart_name = #{departName}
and tenant_id = #{tenantId}
<if test="parentId != null and parentId != ''">
and parent_id = #{parentId}
</if>
ORDER BY create_time DESC
</select>
<!--通过部门id查询部门下的用户的账号 -->
<select id="queryUserAccountByDepartIds" resultType="java.lang.String">
select username from sys_user where id in (select user_id from sys_user_depart where dep_id in
<foreach item="item" index="index" collection="departIds" open="(" separator="," close=" )">
#{item}
</foreach>
)
</select>
</mapper>

View File

@ -4,25 +4,26 @@
<!-- 通过字典code获取字典数据 -->
<select id="queryDictItemsByCode" parameterType="String" resultType="org.jeecg.common.system.vo.DictModel">
select s.item_value as "value",s.item_text as "text" from sys_dict_item s
select s.item_value as "value",s.item_text as "text",s.item_color as color from sys_dict_item s
where dict_id = (select id from sys_dict where dict_code = #{code})
order by s.sort_order asc, s.create_time DESC;
</select>
<!-- 通过字典code获取有效的字典数据项 -->
<select id="queryEnableDictItemsByCode" parameterType="String" resultType="org.jeecg.common.system.vo.DictModel">
select s.item_value as "value",s.item_text as "text" from sys_dict_item s
select s.item_value as "value",s.item_text as "text", s.item_color as "color" from sys_dict_item s
where dict_id = (select id from sys_dict where dict_code = #{code})
and s.status = 1
order by s.sort_order asc, s.create_time DESC;
</select>
<!-- 通过多个字典code获取字典数据 -->
<select id="queryDictItemsByCodeList" parameterType="String" resultType="org.jeecg.common.system.vo.DictModelMany">
<select id="queryDictItemsByCodeList" parameterType="java.util.List" resultType="org.jeecg.common.system.vo.DictModelMany">
SELECT
dict.dict_code,
item.item_text AS "text",
item.item_value AS "value"
item.item_value AS "value",
item.item_color AS "color"
FROM
sys_dict_item item
INNER JOIN sys_dict dict ON dict.id = item.dict_id
@ -46,7 +47,8 @@
SELECT
dict.dict_code,
item.item_text AS "text",
item.item_value AS "value"
item.item_value AS "value",
item.item_color AS "color"
FROM
sys_dict_item item
INNER JOIN sys_dict dict ON dict.id = item.dict_id

View File

@ -129,5 +129,17 @@
)
order by sort_no ASC
</select>
<!--根据用户名称和test角色id查询权限-->
<select id="queryPermissionByTestRoleId" resultType="org.jeecg.modules.system.entity.SysPermission">
SELECT p.*
FROM sys_permission p
WHERE exists(
select a.id from sys_role_permission a
join sys_role b on a.role_id = b.id
where p.id = a.permission_id AND b.id= 'ee8626f80f7c2619917b6236f3a7f02b'
)
and p.del_flag = 0
</select>
</mapper>

View File

@ -2,4 +2,21 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.jeecg.modules.system.mapper.SysPositionMapper">
<!--通过用户id获取职位数据-->
<select id="getPositionList" resultType="org.jeecg.modules.system.entity.SysPosition">
SELECT sp.name,sp.id FROM sys_position sp
INNER JOIN sys_user_position sup on sp.id = sup.position_id
WHERE
sup.user_id = #{userId}
</select>
<!--通过职位id获取职位名称-->
<select id="getPositionName" resultType="org.jeecg.modules.system.entity.SysPosition">
SELECT name FROM sys_position
WHERE
id IN
<foreach collection="postList" index="index" item="positionId" open="(" separator="," close=")">
#{positionId}
</foreach>
</select>
</mapper>

View File

@ -0,0 +1,24 @@
<?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="org.jeecg.modules.system.mapper.SysRoleMapper">
<select id="listAllSysRole" resultType="org.jeecg.modules.system.entity.SysRole">
SELECT * from sys_role
WHERE 1=1
<if test="role.roleName!='' and role.roleName!=null">
<bind name="bindKeyword" value="'%'+role.roleName+'%'"/>
AND role_name like #{bindKeyword}
</if>
<if test="role.roleCode!='' and role.roleCode!=null">
<bind name="bindRoleCode" value="'%'+role.roleCode+'%'"/>
AND role_code like #{bindRoleCode}
</if>
</select>
<select id="getRoleNoTenant" resultType="org.jeecg.modules.system.entity.SysRole">
SELECT * from sys_role
WHERE role_code = #{roleCode}
</select>
</mapper>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.jeecg.modules.system.mapper.SysTableWhiteListMapper">
</mapper>

View File

@ -121,5 +121,14 @@
and a.id = #{packId}
</if>
</select>
<!--查看是否已经申请过了超级管理员-->
<select id="getApplySuperAdminCount" resultType="java.lang.Long">
SELECT count(*) FROM sys_tenant_pack a
join sys_tenant_pack_user b on a.id = b.pack_id
where a.pack_code = 'superAdmin'
and a.tenant_id = #{tenantId}
and b.user_id = #{userId}
</select>
</mapper>

View File

@ -2,4 +2,17 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.jeecg.modules.system.mapper.SysTenantPackUserMapper">
<!-- 查询租户下 特定套餐角色的人员列表 -->
<select id="queryTenantPackUserNameList" resultType="java.lang.String">
select a.username from sys_user a
join sys_tenant_pack_user b on b.user_id = a.id
join sys_tenant_pack c on c.id = b.pack_id
where b.status = 1 and c.tenant_id = #{tenantId}
and c.pack_code IN (
<foreach item="packCode" collection="packCodeList" separator=",">
#{packCode}
</foreach>
)
</select>
</mapper>

View File

@ -6,7 +6,11 @@
<select id="selectThirdIdsByUsername" resultType="org.jeecg.modules.system.entity.SysThirdAccount">
SELECT third_user_id FROM sys_third_account
INNER JOIN sys_user ON sys_user.id = sys_third_account.sys_user_id
WHERE sys_third_account.third_type = #{thirdType} AND
WHERE sys_third_account.third_type = #{thirdType}
<if test="null != tenantId and tenantId != 0">
AND sys_third_account.tenant_id = #{tenantId}
</if>
AND
<!-- TODO in 查询数据量大的时候可能会报错 -->
<foreach collection="sysUsernameArr" item="item" open=" sys_user.username IN (" close=")" separator=",">#{item}</foreach>
</select>

View File

@ -0,0 +1,19 @@
<?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="org.jeecg.modules.system.mapper.SysThirdAppConfigMapper">
<!--根据租户id获取钉钉/企业微信配置-->
<select id="getThirdConfigListByThirdType" resultType="org.jeecg.modules.system.entity.SysThirdAppConfig">
select * from sys_third_app_config
where tenant_id = #{tenantId}
and status = 1
</select>
<!--根据租户id和第三方类别获取第三方配置-->
<select id="getThirdConfigByThirdType" resultType="org.jeecg.modules.system.entity.SysThirdAppConfig">
select * from sys_third_app_config
where tenant_id = #{tenantId}
and third_type = #{thirdType}
and status = 1
</select>
</mapper>

View File

@ -96,7 +96,18 @@
select id from sys_depart where tenant_id = #{tenantId}
)
</select>
<!--通过部门id和租户id获取用户-->
<select id="getUsersByDepartTenantId" resultType="org.jeecg.modules.system.entity.SysUser">
select su.id,su.realname from sys_user_depart sud
INNER JOIN sys_user su ON sud.user_id = su.id
INNER JOIN sys_user_tenant sut ON su.id = sut.user_id
where
sud.dep_id = #{departId}
AND sut.tenant_id = #{tenantId}
AND sut.status = '1'
</select>
<!--根据用户id和租户id,删除用户部门数据-->
<delete id="deleteUserDepart">
delete from sys_user_depart

View File

@ -15,6 +15,14 @@
</if>
</select>
<!-- 查询部门和子部门下的所有用户账号 -->
<select id="getUserAccountsByDepCode" resultType="String">
<if test="orgCode != null">
<bind name="bindOrgCode" value="orgCode+'%'"/>
</if>
select username from sys_user where del_flag = 0 and id in (select user_id from sys_user_depart where dep_id in (select id from sys_depart where org_code LIKE #{bindOrgCode}))
</select>
<!-- 查询用户的所属部门名称信息 -->
<select id="getDepNamesByUserIds" resultType="org.jeecg.modules.system.vo.SysUserDepVo">
select d.depart_name,ud.user_id from sys_user_depart ud,sys_depart d where d.id = ud.dep_id and ud.user_id in
@ -106,7 +114,6 @@
sys_user.sex AS sex,
sys_user.birthday AS birthday,
sys_user.work_no AS workNo,
sys_user.post AS post,
sys_user.telephone AS telephone,
sys_user.email AS email,
sys_user.phone AS phone,
@ -197,11 +204,11 @@
<!--根据角色查询用户-->
<select id="selectUserListByRoleId" resultType="org.jeecg.modules.system.entity.SysUser">
select DISTINCT a.* from sys_user a
left join sys_user_role ur on ur.user_id = a.id
left join sys_user_role sur on sur.user_id = a.id
where
a.del_flag = 0 and a.status = 1
and a.username!='_reserve_user_external'
and ur.role_id=#{roleId}
and sur.role_id=#{roleId}
<if test="keyword!=null and keyword!=''">
<bind name="bindKeyword" value="'%'+keyword+'%'"/>
and (a.username like #{bindKeyword} or a.realname like #{bindKeyword})
@ -216,7 +223,7 @@
<!--获取租户下的用户离职列表信息-->
<select id="getTenantQuitList" resultType="org.jeecg.modules.system.entity.SysUser">
select su.id,su.username,su.realname,su.sex from sys_user su
select su.id,su.username,su.realname,su.sex,su.avatar from sys_user su
join sys_user_tenant sut on sut.user_id = su.id and sut.status = '2'
where
su.status = 1
@ -225,6 +232,25 @@
and sut.tenant_id = #{tenantId}
</if>
</select>
<!--获取租户下的有效用户ids信息-->
<select id="getTenantUserIdList" resultType="java.lang.String" parameterType="java.lang.Integer">
SELECT DISTINCT( su.id ) id
FROM sys_user su
<choose>
<when test="tenantId!=null and tenantId != 0">
JOIN sys_user_tenant sut ON sut.user_id = su.id
AND sut.STATUS = '1'
AND sut.tenant_id = #{tenantId}
AND su.STATUS = 1
AND su.del_flag = 0
</when>
<otherwise>
WHERE su.STATUS = 1
AND su.del_flag = 0
</otherwise>
</choose>
</select>
<!--更新刪除状态和离职状态-->
<update id="updateStatusAndFlag">
@ -242,4 +268,21 @@
#{userId}
</foreach>
</update>
<!--根据部门id获取用户数据-->
<select id="getUserByDepartsTenantId" resultType="org.jeecg.modules.system.entity.SysUser">
select su.* from sys_user su
join sys_user_tenant sut on su.id = sut.user_id
where su.del_flag = 0
<if test="departIds!=null and departIds.size()>0">
and su.id in (select user_id from sys_user_depart
where dep_id in
<foreach collection="departIds" index="index" item="id" open="(" separator="," close=")">
#{id}
</foreach>
)
</if>
and sut.tenant_id=#{tenantId}
and sut.status = '1'
</select>
</mapper>

View File

@ -0,0 +1,66 @@
<?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="org.jeecg.modules.system.mapper.SysUserPositionMapper">
<!--获取职位用户列表-->
<select id="getPositionUserList" resultType="org.jeecg.modules.system.entity.SysUser">
SELECT su.realname,su.id,su.username,su.email,su.phone,su.work_no
FROM sys_user_position sup
INNER JOIN sys_user su on sup.user_id = su.id and su.del_flag = 0
WHERE
sup.position_id = #{positionId}
ORDER BY sup.create_time DESC
</select>
<!--根据用户id查询职位id-->
<select id="getPositionIdByUserId" resultType="java.lang.String">
SELECT position_id FROM sys_user_position
WHERE
user_id = #{userId}
ORDER BY create_time DESC
</select>
<!--根据用户ID和租户ID获取职位id-->
<select id="getPositionIdByUserTenantId" resultType="java.lang.String">
SELECT sp.id FROM sys_user_position sup
LEFT JOIN sys_position sp ON sup.position_id = sp.id
WHERE
sup.user_id = #{userId}
AND sp.tenant_id = #{tenantId}
</select>
<!--职位列表移除成员-->
<update id="removePositionUser">
DELETE FROM sys_user_position
WHERE
position_id = #{positionId}
AND user_id IN
<foreach collection="userIdList" index="index" item="userId" open="(" separator="," close=")">
#{userId}
</foreach>
</update>
<!--根据用户id获取用户职位-->
<select id="getPositionIdByUsersTenantId" resultType="org.jeecg.modules.system.vo.SysUserPositionVo">
SELECT sp.name,sup.user_id FROM sys_position sp
RIGHT JOIN sys_user_position sup on sup.position_id = sp.id
WHERE sup.user_id IN
<foreach collection="userIdList" index="index" item="userIds" open="(" separator="," close=")">
#{userIds.id}
</foreach>
AND sp.tenant_id = #{tenantId}
</select>
<!--根据职位名称和租户id删除用户职位关系表-->
<delete id="deleteUserPosByNameAndTenantId">
DELETE FROM sys_user_position
WHERE user_id = #{userId}
AND position_id in (
SELECT id FROM sys_position where name in
<foreach collection="positionNames" index="index" item="name" open="(" separator="," close=")">
#{name}
</foreach>
AND tenant_id = #{tenantId}
)
</delete>
</mapper>

View File

@ -18,6 +18,7 @@
<bind name="bindRealName" value="'%'+user.realname+'%'"/>
AND su.realname like #{bindRealName}
</if>
ORDER BY su.create_time DESC
</select>
<!--根据租户id获取用户ids-->
@ -69,9 +70,9 @@
<!--联查用户和租户审核状态-->
<select id="getUserTenantPageList" resultType="org.jeecg.modules.system.vo.SysUserTenantVo">
SELECT su.id,su.realname,su.username,su.email,su.phone,su.avatar,su.work_no,su.post,su.org_code,sut.status,st.create_by
SELECT su.id,su.realname,su.username,su.email,su.phone,su.avatar,su.work_no,su.org_code,sut.status,st.create_by
FROM sys_user_tenant sut
LEFT JOIN sys_user su on sut.user_id = su.id
RIGHT JOIN sys_user su on sut.user_id = su.id and su.del_flag = 0
JOIN sys_tenant st ON sut.tenant_id = st.id
WHERE sut.tenant_id = #{tenantId}
AND st.del_flag = 0
@ -114,6 +115,14 @@
user_id = #{userId}
and tenant_id = #{tenantId}
</select>
<!--查询未被注销的租户-->
<select id="getTenantNoCancel" resultType="org.jeecg.modules.system.entity.SysTenant">
SELECT st.id,st.name FROM sys_user_tenant sut
JOIN sys_tenant st ON sut.tenant_id = st.id AND st.del_flag = 0 AND st.status = 1
WHERE
user_id = #{userId}
</select>
<!--用户租户取消离职-->
<update id="putCancelQuit">
@ -125,4 +134,34 @@
#{userId}
</foreach>
</update>
<!--根据用户id获取我的租户-->
<select id="getTenantPageListByUserId" resultType="org.jeecg.modules.system.entity.SysTenant">
SELECT st.id,st.name,st.status,st.trade,st.company_size,st.company_address,st.company_logo,st.house_number,st.work_place,st.position,st.department,st.create_by FROM sys_user_tenant sut
JOIN sys_tenant st ON sut.tenant_id = st.id AND st.del_flag = 0 AND st.status = 1
WHERE sut.user_id = #{userId}
<if test="sysUserTenantVo.name != null and sysUserTenantVo.name != ''">
<bind name="bindName" value="'%'+sysUserTenantVo.name+'%'"/>
AND st.name like #{bindName}
</if>
<if test="sysUserTenantVo.status != null and sysUserTenantVo.status!= ''">
AND st.status = #{sysUserTenantVo.status}
</if>
AND sut.status in
<foreach collection="userTenantStatus" index="index" item="status" open="(" separator="," close=")">
#{status}
</foreach>
order by st.create_time desc
</select>
<!-- 删除租户下的用户 -->
<delete id="deleteUserByTenantId">
DELETE FROM sys_user_tenant
WHERE
tenant_id in
<foreach collection="tenantIds" index="index" item="tenantId" open="(" separator="," close=")">
#{tenantId}
</foreach>
</delete>
</mapper>

View File

@ -34,7 +34,7 @@ public class AnnouncementSendModel implements Serializable {
/**优先级L低M中H高*/
private java.lang.String priority;
/**阅读状态*/
private java.lang.String readFlag;
private java.lang.Integer readFlag;
/**发布时间*/
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")

View File

@ -1,11 +1,10 @@
package org.jeecg.modules.system.model;
import org.jeecg.modules.system.entity.SysPermission;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.jeecg.modules.system.entity.SysPermission;
/**
* @Description: 菜单树,封装树结构
@ -130,7 +129,7 @@ public class SysPermissionTree implements Serializable {
private boolean hidden;
/**按钮权限状态(0无效1有效)*/
private String status;
private java.lang.String status;
/*update_begin author:wuxianquan date:20190908 for:model增加字段 */
/** 外链菜单打开方式 0/内部打开 1/外部打开 */
@ -402,11 +401,11 @@ public class SysPermissionTree implements Serializable {
this.permsType = permsType;
}
public String getStatus() {
public java.lang.String getStatus() {
return status;
}
public void setStatus(String status) {
public void setStatus(java.lang.String status) {
this.status = status;
}

View File

@ -1,6 +1,7 @@
package org.jeecg.modules.system.rule;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.handler.IFillRuleHandler;

View File

@ -5,7 +5,6 @@ import org.jeecg.common.util.oConvertUtils;
import org.jeecg.common.util.security.AbstractQueryBlackListHandler;
import org.springframework.stereotype.Component;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.List;
@ -30,7 +29,7 @@ public class DictQueryBlackListHandler extends AbstractQueryBlackListHandler {
if (dictCodeString.contains("%")) {
dictCodeString = URLDecoder.decode(dictCodeString, "UTF-8");
}
} catch (UnsupportedEncodingException e) {
} catch (Exception e) {
//e.printStackTrace();
}
dictCodeString = dictCodeString.trim();
@ -41,10 +40,14 @@ public class DictQueryBlackListHandler extends AbstractQueryBlackListHandler {
if (arr.length != 3 && arr.length != 4) {
return null;
}
//获取表名
String tableName = getTableName(arr[0]);
QueryTable table = new QueryTable(tableName, "");
// 无论什么场景 第二、三个元素一定是表的字段直接add
//参数字段1
table.addField(arr[1].trim());
//参数字段2
String filed = arr[2].trim();
if (oConvertUtils.isNotEmpty(filed)) {
table.addField(filed);

View File

@ -16,13 +16,6 @@ import com.baomidou.mybatisplus.extension.service.IService;
*/
public interface ISysAnnouncementSendService extends IService<SysAnnouncementSend> {
/**
* 通过用户id查询用户通告阅读标记
* @param userId 用户id
* @return
*/
public List<String> queryByUserId(String userId);
/**
* 获取我的消息
* @param announcementSendModel

View File

@ -1,5 +1,6 @@
package org.jeecg.modules.system.service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.modules.system.entity.SysAnnouncement;
@ -47,10 +48,19 @@ public interface ISysAnnouncementService extends IService<SysAnnouncement> {
/**
* 补全当前登录用户的消息阅读记录
* @作废无用 2023-09-19
*/
@Deprecated
void completeAnnouncementSendInfo();
/**
* 补全所有用户的推送公告关系数据
*
* @param commentId
* @param tenantId
*/
void batchInsertSysAnnouncementSend(String commentId, Integer tenantId);
/**
* 分页查询当前登录用户的消息, 并且标记哪些是未读消息
*/
@ -62,4 +72,15 @@ public interface ISysAnnouncementService extends IService<SysAnnouncement> {
void updateReaded(List<String> annoceIdList);
/**
* 清除所有未读消息
*/
void clearAllUnReadMessage();
/**
* 查询用户未阅读的通知公告
* @param userId
* @return
*/
public List<String> getNotSendedAnnouncementlist(String userId);
}

View File

@ -56,5 +56,10 @@ public interface ISysCommentService extends IService<SysComment> {
* @return
*/
List<SysCommentFileVo> queryFormFileList(String tableName, String formDataId);
/**
* app端 保存文件+评论
*
* @param request
*/
void appSaveOneFileComment(HttpServletRequest request);
}

View File

@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.modules.system.entity.SysDepart;
import org.jeecg.modules.system.model.DepartIdModel;
import org.jeecg.modules.system.model.SysDepartTreeModel;
import org.jeecg.modules.system.vo.lowapp.ExportDepartVo;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
@ -198,4 +199,21 @@ public interface ISysDepartService extends IService<SysDepart>{
* @return
*/
IPage<SysDepart> getMaxCodeDepart(Page<SysDepart> page, String parentId);
/**
* 更新叶子节点
* @param id
* @param izLeaf
*/
void updateIzLeaf(String id, Integer izLeaf);
/**
* 获取导出部门的数据
* @param tenantId
* @return
*/
List<ExportDepartVo> getExcelDepart(int tenantId);
void importExcel(List<ExportDepartVo> listSysDeparts, List<String> errorMessageList);
}

View File

@ -216,7 +216,7 @@ public interface ISysDictService extends IService<SysDict> {
* @return
*/
@Deprecated
List<TreeSelectModel> queryTreeList(Map<String, String> query, String table, String text, String code, String pidField, String pid, String hasChildField, int converIsLeafVal);
List<TreeSelectModel> queryTreeList(Map<String, String> query,String table, String text, String code, String pidField,String pid,String hasChildField,int converIsLeafVal);
/**
* 真实删除
@ -245,7 +245,7 @@ public interface ISysDictService extends IService<SysDict> {
* @return
*/
@Deprecated
public List<DictModel> queryDictTablePageList(DictQuery query, int pageSize, int pageNo);
public List<DictModel> queryDictTablePageList(DictQuery query,int pageSize, int pageNo);
/**
* 获取字典数据
@ -277,7 +277,7 @@ public interface ISysDictService extends IService<SysDict> {
* 创建字典
* @param sysDictVo
*/
void addDictByLowAppId(SysDictVo sysDictVo);
String addDictByLowAppId(SysDictVo sysDictVo);
/**
* 编辑字典

View File

@ -3,6 +3,8 @@ package org.jeecg.modules.system.service;
import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.modules.system.entity.SysPosition;
import java.util.List;
/**
* @Description: 职务表
* @Author: jeecg-boot
@ -18,4 +20,17 @@ public interface ISysPositionService extends IService<SysPosition> {
*/
SysPosition getByCode(String code);
/**
* 通过用户id获取职位名称列表
* @param userId
* @return
*/
List<SysPosition> getPositionList(String userId);
/**
* 获取职位名称
* @param postList
* @return
*/
String getPositionName(List<String> postList);
}

View File

@ -1,11 +1,17 @@
package org.jeecg.modules.system.service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import org.apache.ibatis.annotations.Param;
import org.jeecg.common.api.vo.Result;
import org.jeecg.modules.system.entity.SysRole;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecgframework.poi.excel.entity.ImportParams;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
/**
* <p>
* 角色表 服务类
@ -15,7 +21,22 @@ import org.springframework.web.multipart.MultipartFile;
* @since 2018-12-19
*/
public interface ISysRoleService extends IService<SysRole> {
/**
* 查询全部的角色(不做租户隔离)
* @param page
* @param role
* @return
*/
Page<SysRole> listAllSysRole(@Param("page") Page<SysRole> page, SysRole role);
/**
* 查询角色是否存在不做租户隔离
*
* @param roleCode
* @return
*/
SysRole getRoleNoTenant(@Param("roleCode") String roleCode);
/**
* 导入 excel ,检查 roleCode 的唯一性
*
@ -40,4 +61,10 @@ public interface ISysRoleService extends IService<SysRole> {
*/
public boolean deleteBatchRole(String[] roleids);
/**
* 根据角色id和当前租户判断当前角色是否存在这个租户中
* @param id
* @return
*/
Long getRoleCountByTenantId(String id, Integer tenantId);
}

View File

@ -0,0 +1,57 @@
package org.jeecg.modules.system.service;
import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.modules.system.entity.SysTableWhiteList;
import java.util.Map;
/**
* @Description: 系统表白名单
* @Author: jeecg-boot
* @Date: 2023-09-12
* @Version: V1.0
*/
public interface ISysTableWhiteListService extends IService<SysTableWhiteList> {
/**
* 新增
*
* @param sysTableWhiteList
* @return
*/
boolean add(SysTableWhiteList sysTableWhiteList);
/**
* 编辑
*
* @param sysTableWhiteList
* @return
*/
boolean edit(SysTableWhiteList sysTableWhiteList);
/**
* 通过id删除可批量删除
*
* @param ids 多个使用逗号分割
* @return
*/
boolean deleteByIds(String ids);
/**
* 自动添加到数据库中
*
* @param tableName
* @param fieldName
* @return
*/
SysTableWhiteList autoAdd(String tableName, String fieldName);
/**
* 以map的方式获取所有数据
* key=tableNamevalue=fieldName
*
* @return
*/
Map<String, String> getAllConfigMap();
}

View File

@ -1,7 +1,7 @@
package org.jeecg.modules.system.service;
import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.modules.system.entity.SysTenantPack;
import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.modules.system.entity.SysTenantPackUser;
import java.util.List;
@ -71,5 +71,11 @@ public interface ISysTenantPackService extends IService<SysTenantPack> {
* @param packCode
* @return
*/
SysTenantPack getSysTenantPack(Integer tenantId , String packCode);
SysTenantPack getSysTenantPack(Integer tenantId ,String packCode);
/**
* 添加由管理员创建的默认产品包
* @param id
*/
void addTenantDefaultPack(Integer id);
}

View File

@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.common.api.vo.Result;
import org.jeecg.modules.system.entity.SysTenant;
import org.jeecg.modules.system.entity.SysTenantPackUser;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.vo.tenant.TenantDepartAuthInfo;
import org.jeecg.modules.system.vo.tenant.TenantPackModel;
import org.jeecg.modules.system.vo.tenant.TenantPackUser;
@ -117,15 +118,17 @@ public interface ISysTenantService extends IService<SysTenant> {
/**
* 变更租户拥有者
* @param userId
* @param tenantId
*/
void changeOwenUserTenant(String userId);
void changeOwenUserTenant(String userId, String tenantId);
/**
* 邀请用户到租户。通过手机号匹配
* @param phone
* @param departId
* @return
*/
Result<String> invitationUser(String phone);
Result<String> invitationUser(String phone, String departId);
/**
* 进入应用组织页面 查询用户是否有 超级管理员的权限
@ -200,4 +203,18 @@ public interface ISysTenantService extends IService<SysTenant> {
* @return
*/
IPage<TenantPackUser> queryTenantPackUserList(String tenantId, String packId, Integer status, Page<TenantPackUser> page);
/**
* 查看是否已经申请过了管理员
* @return
*/
Long getApplySuperAdminCount();
/**
* 发送同意或者拒绝消息
*
* @param user
* @param content
*/
void sendMsgForAgreeAndRefuseJoin(SysUser user, String content);
}

View File

@ -27,7 +27,7 @@ public interface ISysThirdAccountService extends IService<SysThirdAccount> {
* @param thirdUserUuid 第三方id
* @return SysUser
*/
SysUser createUser(String phone, String thirdUserUuid);
SysUser createUser(String phone, String thirdUserUuid, Integer tenantId);
/**
* 根据本地userId查询数据
@ -52,14 +52,30 @@ public interface ISysThirdAccountService extends IService<SysThirdAccount> {
* @param thirdType 第三方类型
* @return
*/
List<SysThirdAccount> listThirdUserIdByUsername(String[] sysUsernameArr, String thirdType);
List<SysThirdAccount> listThirdUserIdByUsername(String[] sysUsernameArr, String thirdType, Integer tenantId);
/**
* 创建新用户
*
* @param tlm 第三方登录信息
* @return SysThirdAccount
* @return tenantId 租户id
*/
SysThirdAccount saveThirdUser(ThirdLoginModel tlm);
SysThirdAccount saveThirdUser(ThirdLoginModel tlm, Integer tenantId);
/**
* 绑定第三方账号(登录后根据用户id绑定第三方账号)
* @param sysThirdAccount
*/
SysThirdAccount bindThirdAppAccountByUserId(SysThirdAccount sysThirdAccount);
/**
* 根据第三方 UUID和第三方类别获取第三方用户数据
* @param unionid
* @param thirdType
* @param tenantId
* @return
*/
SysThirdAccount getOneByUuidAndThirdType(String unionid, String thirdType,Integer tenantId);
}

View File

@ -0,0 +1,37 @@
package org.jeecg.modules.system.service;
import com.baomidou.mybatisplus.extension.service.IService;
import io.swagger.models.auth.In;
import org.jeecg.modules.system.entity.SysThirdAppConfig;
import java.util.List;
/**
* @Description: 第三方配置表
* @Author: jeecg-boot
* @Date: 2023-02-03
* @Version: V1.0
*/
public interface ISysThirdAppConfigService extends IService<SysThirdAppConfig>{
/**
* 根据租户id获取钉钉/企业微信配置
* @param tenantId
* @return
*/
List<SysThirdAppConfig> getThirdConfigListByThirdType(int tenantId);
/**
* 根据租户id和第三方类别获取第三方配置
* @param tenantId
* @param thirdType
* @return
*/
SysThirdAppConfig getThirdConfigByThirdType(Integer tenantId, String thirdType);
/**
* 根据应用key获取第三方表配置
* @param clientId
*/
List<SysThirdAppConfig> getThirdAppConfigByClientId(String clientId);
}

View File

@ -77,4 +77,12 @@ public interface ISysUserDepartService extends IService<SysUserDepart> {
* @return
*/
IPage<SysUser> getUserInformation(Integer tenantId,String departId,String roleId, String keyword, Integer pageSize, Integer pageNo);
/**
* 通过部门id和租户id获取多个用户
* @param departId
* @param tenantId
* @return
*/
List<SysUser> getUsersByDepartTenantId(String departId,Integer tenantId);
}

View File

@ -0,0 +1,43 @@
package org.jeecg.modules.system.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.entity.SysUserPosition;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* @Description: 用户职位关系表
* @Author: jeecg-boot
* @Date: 2023-02-14
* @Version: V1.0
*/
public interface ISysUserPositionService extends IService<SysUserPosition> {
/**
* 获取职位用户列表
* @param page
* @param positionId
* @return
*/
IPage<SysUser> getPositionUserList(Page<SysUser> page, String positionId);
/**
* 添加成员到用户职位关系表
* @param userIds
* @param positionId
*/
void saveUserPosition(String userIds, String positionId);
/**
* 通过职位id删除用户职位关系表
* @param positionId
*/
void removeByPositionId(String positionId);
/**
* 移除成员
* @param userIds
* @param positionId
*/
void removePositionUser(String userIds, String positionId);
}

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