mirror of
https://github.com/jeecgboot/JeecgBoot.git
synced 2026-02-06 02:25:30 +08:00
v3.9.0 里程碑版本发布
This commit is contained in:
@ -56,7 +56,7 @@ public class DictTableWhiteListHandlerImpl implements IDictTableWhiteListHandler
|
||||
// 如果map为空,则从数据库中查询
|
||||
if (DictTableWhiteListHandlerImpl.whiteTablesRuleMap.isEmpty()) {
|
||||
Map<String, String> ruleMap = sysTableWhiteListService.getAllConfigMap();
|
||||
log.info("表字典白名单初始化完成:{}", ruleMap);
|
||||
log.debug("表字典白名单初始化完成:{}", ruleMap);
|
||||
DictTableWhiteListHandlerImpl.whiteTablesRuleMap.putAll(ruleMap);
|
||||
}
|
||||
}
|
||||
@ -73,7 +73,7 @@ public class DictTableWhiteListHandlerImpl implements IDictTableWhiteListHandler
|
||||
if (parsedMap == null) {
|
||||
return true;
|
||||
}
|
||||
log.info("获取select sql信息 :{} ", parsedMap);
|
||||
log.debug("获取select sql信息 :{} ", parsedMap);
|
||||
// 遍历当前sql中的所有表名,如果有其中一个表或表的字段不在白名单中,则不通过
|
||||
for (Map.Entry<String, SelectSqlInfo> entry : parsedMap.entrySet()) {
|
||||
SelectSqlInfo sqlInfo = entry.getValue();
|
||||
@ -124,7 +124,7 @@ public class DictTableWhiteListHandlerImpl implements IDictTableWhiteListHandler
|
||||
fields = new String[]{"*"};
|
||||
}
|
||||
String sql = "select " + String.join(",", fields) + " from " + tableName;
|
||||
log.info("字典拼接的查询SQL:{}", sql);
|
||||
log.debug("字典拼接的查询SQL:{}", sql);
|
||||
try {
|
||||
// 进行SQL解析
|
||||
MiniDaoUtil.parseSelectSqlInfo(sql);
|
||||
@ -153,7 +153,7 @@ public class DictTableWhiteListHandlerImpl implements IDictTableWhiteListHandler
|
||||
// 统一转成小写
|
||||
tableName = tableName.toLowerCase();
|
||||
String allowFieldStr = DictTableWhiteListHandlerImpl.whiteTablesRuleMap.get(tableName);
|
||||
log.info("checkWhiteList tableName: {}", tableName);
|
||||
log.debug("checkWhiteList tableName: {}", tableName);
|
||||
if (oConvertUtils.isEmpty(allowFieldStr)) {
|
||||
// 如果是dev模式,自动向数据库里添加数据
|
||||
if (this.isDev()) {
|
||||
@ -192,7 +192,7 @@ public class DictTableWhiteListHandlerImpl implements IDictTableWhiteListHandler
|
||||
if (!waitMergerFields.isEmpty()) {
|
||||
this.autoAddWhiteList(tableName, String.join(",", waitMergerFields));
|
||||
}
|
||||
log.info("白名单校验:查询表\"{}\",查询字段 {} 通过校验", tableName, queryFields);
|
||||
log.debug("白名单校验:查询表\"{}\",查询字段 {} 通过校验", tableName, queryFields);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -205,10 +205,10 @@ public class JeecgBizToolsProvider implements JeecgToolsProvider {
|
||||
qw.like("role_code", sysRole.getRoleCode());
|
||||
}
|
||||
// 未删除
|
||||
List<SysRole> roles = sysRoleService.list(qw);
|
||||
List<org.jeecg.modules.system.entity.SysRole> roles = sysRoleService.list(qw);
|
||||
// 仅返回核心字段
|
||||
JSONArray arr = new JSONArray();
|
||||
for (SysRole r : roles) {
|
||||
for (org.jeecg.modules.system.entity.SysRole r : roles) {
|
||||
JSONObject o = new JSONObject();
|
||||
o.put("id", r.getId());
|
||||
o.put("roleName", r.getRoleName());
|
||||
@ -242,10 +242,10 @@ public class JeecgBizToolsProvider implements JeecgToolsProvider {
|
||||
JSONObject args = JSONObject.parseObject(toolExecutionRequest.arguments());
|
||||
String userId = args.getString("userId");
|
||||
String roleIdsStr = args.getString("roleIds");
|
||||
if (StringUtils.isAnyBlank(userId, roleIdsStr)) {
|
||||
if (org.apache.commons.lang3.StringUtils.isAnyBlank(userId, roleIdsStr)) {
|
||||
return "参数缺失:userId 或 roleIds";
|
||||
}
|
||||
SysUser user = sysUserService.getById(userId);
|
||||
org.jeecg.modules.system.entity.SysUser user = sysUserService.getById(userId);
|
||||
if (user == null) {
|
||||
return "用户不存在:" + userId;
|
||||
}
|
||||
@ -254,9 +254,9 @@ public class JeecgBizToolsProvider implements JeecgToolsProvider {
|
||||
for (String roleId : roleIds) {
|
||||
roleId = roleId.trim();
|
||||
if (roleId.isEmpty()) continue;
|
||||
SysRole role = sysRoleService.getById(roleId);
|
||||
org.jeecg.modules.system.entity.SysRole role = sysRoleService.getById(roleId);
|
||||
if (role == null) { invalid++; continue; }
|
||||
QueryWrapper<org.jeecg.modules.system.entity.SysUserRole> q = new QueryWrapper<>();
|
||||
com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<org.jeecg.modules.system.entity.SysUserRole> q = new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<>();
|
||||
q.eq("role_id", roleId).eq("user_id", userId);
|
||||
org.jeecg.modules.system.entity.SysUserRole one = sysUserRoleService.getOne(q);
|
||||
if (one == null) {
|
||||
|
||||
@ -5,6 +5,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.api.dto.AiragFlowDTO;
|
||||
import org.jeecg.common.api.dto.DataLogDTO;
|
||||
import org.jeecg.common.api.dto.OnlineAuthDTO;
|
||||
import org.jeecg.common.api.dto.PushMessageDTO;
|
||||
import org.jeecg.common.api.dto.message.*;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.constant.enums.DySmsEnum;
|
||||
@ -764,7 +765,6 @@ public class SystemApiController {
|
||||
}
|
||||
|
||||
|
||||
//update-begin---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
/**
|
||||
* 【接口签名验证】
|
||||
* 49 字典表的 翻译,可批量
|
||||
@ -780,7 +780,6 @@ public class SystemApiController {
|
||||
public List<DictModel> translateDictFromTableByKeys(@RequestParam("table") String table, @RequestParam("text") String text, @RequestParam("code") String code, @RequestParam("keys") String keys, @RequestParam("ds") String ds) {
|
||||
return this.sysBaseApi.translateDictFromTableByKeys(table, text, code, keys, ds);
|
||||
}
|
||||
//update-end---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
|
||||
/**
|
||||
* 发送模板信息
|
||||
@ -933,6 +932,16 @@ public class SystemApiController {
|
||||
return sysBaseApi.queryUserIdsByDeptIds(deptIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据部门岗位ID查询用户ID
|
||||
* @param deptPostIds
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/queryUserIdsByDeptPostIds")
|
||||
public List<String> queryUserIdsByDeptPostIds(@RequestParam("deptPostIds") List<String> deptPostIds){
|
||||
return sysBaseApi.queryUserIdsByDeptPostIds(deptPostIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据部门ID查询用户ID
|
||||
* @param deptIds
|
||||
@ -953,6 +962,26 @@ public class SystemApiController {
|
||||
return sysBaseApi.queryUserIdsByRoleds(roleCodes);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据用户ID查询用户名
|
||||
* @param userIds
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/queryUsernameByIds")
|
||||
public List<String> queryUsernameByIds(@RequestParam("userIds") List<String> userIds){
|
||||
return sysBaseApi.queryUsernameByIds(userIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据岗位的职级ID查询用户ID
|
||||
* @param departPositIds
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/queryUsernameByDepartPositIds")
|
||||
public List<String> queryUsernameByDepartPositIds(@RequestParam("departPositIds") List<String> departPositIds){
|
||||
return sysBaseApi.queryUsernameByDepartPositIds(departPositIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据职务ID查询用户ID
|
||||
* @param positionIds
|
||||
@ -1072,4 +1101,13 @@ public class SystemApiController {
|
||||
public List<String> queryUserIdsByCascadeDeptIds(@RequestParam("deptIds") List<String> deptIds){
|
||||
return sysBaseApi.queryUserIdsByCascadeDeptIds(deptIds);
|
||||
}
|
||||
/**
|
||||
* 推送uniapp 消息
|
||||
* @param pushMessageDTO
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/uniPushMsgToUser")
|
||||
public void uniPushMsgToUser(@RequestBody PushMessageDTO pushMessageDTO){
|
||||
sysBaseApi.uniPushMsgToUser(pushMessageDTO);
|
||||
}
|
||||
}
|
||||
|
||||
@ -78,7 +78,7 @@ public class CasClientController {
|
||||
if(!result.isSuccess()) {
|
||||
return result;
|
||||
}
|
||||
String token = JwtUtil.sign(sysUser.getUsername(), sysUser.getPassword());
|
||||
String token = JwtUtil.sign(sysUser.getUsername(), sysUser.getPassword(), CommonConstant.CLIENT_TYPE_PC);
|
||||
// 设置超时时间
|
||||
redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token);
|
||||
redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME*2 / 1000);
|
||||
|
||||
@ -292,12 +292,12 @@ public final class XmlUtils {
|
||||
"</cas:serviceResponse>";
|
||||
|
||||
String error = XmlUtils.getTextForElement(errorRes, "authenticationFailure");
|
||||
System.out.println("------"+error);
|
||||
//System.out.println("------"+error);
|
||||
|
||||
String error2 = XmlUtils.getTextForElement(result, "authenticationFailure");
|
||||
System.out.println("------"+error2);
|
||||
//System.out.println("------"+error2);
|
||||
String principal = XmlUtils.getTextForElement(result, "user");
|
||||
System.out.println("---principal---"+principal);
|
||||
//System.out.println("---principal---"+principal);
|
||||
Map<String, Object> attributes = XmlUtils.extractCustomAttributes(result);
|
||||
System.out.println("---attributes---"+attributes);
|
||||
}
|
||||
|
||||
@ -68,12 +68,11 @@ public class EmailSendMsgHandle implements ISendMsgHandle {
|
||||
public void sendMsg(String esReceiver, String esTitle, String esContent) {
|
||||
JavaMailSender mailSender = (JavaMailSender) SpringContextUtils.getBean("mailSender");
|
||||
MimeMessage message = mailSender.createMimeMessage();
|
||||
//update-begin-author:taoyan date:20200811 for:配置类数据获取
|
||||
// 代码逻辑说明: 配置类数据获取
|
||||
if(oConvertUtils.isEmpty(emailFrom)){
|
||||
StaticConfig staticConfig = SpringContextUtils.getBean(StaticConfig.class);
|
||||
setEmailFrom(staticConfig.getEmailFrom());
|
||||
}
|
||||
//update-end-author:taoyan date:20200811 for:配置类数据获取
|
||||
cachedThreadPool.execute(()->{
|
||||
try {
|
||||
log.info("============> 开始邮件发送,接收人:"+esReceiver);
|
||||
@ -95,12 +94,11 @@ public class EmailSendMsgHandle implements ISendMsgHandle {
|
||||
public void sendMessage(MessageDTO messageDTO) {
|
||||
String content = messageDTO.getContent();
|
||||
String title = messageDTO.getTitle();
|
||||
//update-begin---author:wangshuai---date:2024-11-20---for:【QQYUN-8523】敲敲云发邮件通知,不稳定---
|
||||
// 代码逻辑说明: 【QQYUN-8523】敲敲云发邮件通知,不稳定---
|
||||
boolean timeJobSendEmail = this.isTimeJobSendEmail(messageDTO.getToUser(), title, content);
|
||||
if(timeJobSendEmail){
|
||||
return;
|
||||
}
|
||||
//update-end---author:wangshuai---date:2024-11-20---for:【QQYUN-8523】敲敲云发邮件通知,不稳定---
|
||||
this.sendEmailMessage(messageDTO);
|
||||
}
|
||||
|
||||
@ -125,7 +123,7 @@ public class EmailSendMsgHandle implements ISendMsgHandle {
|
||||
sendMsg(email, title, content);
|
||||
}
|
||||
|
||||
//update-begin-author:taoyan date:2023-6-20 for: QQYUN-5557【简流】通知节点 发送邮箱 表单上有一个邮箱字段,流程中,邮件发送节点,邮件接收人 不可选择邮箱
|
||||
// 代码逻辑说明: QQYUN-5557【简流】通知节点 发送邮箱 表单上有一个邮箱字段,流程中,邮件发送节点,邮件接收人 不可选择邮箱
|
||||
Set<String> toEmailList = messageDTO.getToEmailList();
|
||||
if(toEmailList!=null && toEmailList.size()>0){
|
||||
for(String email: toEmailList){
|
||||
@ -136,7 +134,6 @@ public class EmailSendMsgHandle implements ISendMsgHandle {
|
||||
sendMsg(email, title, content);
|
||||
}
|
||||
}
|
||||
//update-end-author:taoyan date:2023-6-20 for: QQYUN-5557【简流】通知节点 发送邮箱 表单上有一个邮箱字段,流程中,邮件发送节点,邮件接收人 不可选择邮箱
|
||||
|
||||
//发送给抄送人
|
||||
sendMessageToCopyUser(messageDTO);
|
||||
@ -162,7 +159,7 @@ public class EmailSendMsgHandle implements ISendMsgHandle {
|
||||
content=replaceContent(user,content);
|
||||
log.info("邮件内容:" + content);
|
||||
|
||||
//update-begin-author:taoyan date:2023-6-20 for: QQYUN-5557【简流】通知节点 发送邮箱 表单上有一个邮箱字段,流程中,邮件发送节点,邮件接收人 不可选择邮箱
|
||||
// 代码逻辑说明: QQYUN-5557【简流】通知节点 发送邮箱 表单上有一个邮箱字段,流程中,邮件发送节点,邮件接收人 不可选择邮箱
|
||||
sendEmail(email, content, title);
|
||||
}
|
||||
|
||||
@ -210,7 +207,6 @@ public class EmailSendMsgHandle implements ISendMsgHandle {
|
||||
}
|
||||
});
|
||||
}
|
||||
//update-end-author:taoyan date:2023-6-20 for: QQYUN-5557【简流】通知节点 发送邮箱 表单上有一个邮箱字段,流程中,邮件发送节点,邮件接收人 不可选择邮箱
|
||||
|
||||
|
||||
/**
|
||||
@ -241,7 +237,7 @@ public class EmailSendMsgHandle implements ISendMsgHandle {
|
||||
*/
|
||||
private String getToken(SysUser user) {
|
||||
// 生成token
|
||||
String token = JwtUtil.sign(user.getUsername(), user.getPassword());
|
||||
String token = JwtUtil.sign(user.getUsername(), user.getPassword(), CommonConstant.CLIENT_TYPE_PC);
|
||||
redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token);
|
||||
// 设置超时时间 1个小时
|
||||
redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME * 1 / 1000);
|
||||
|
||||
@ -75,9 +75,8 @@ public class SystemSendMsgHandle implements ISendMsgHandle {
|
||||
Map<String,Object> data = messageDTO.getData();
|
||||
String[] arr = messageDTO.getToUser().split(",");
|
||||
for(String username: arr){
|
||||
//update-begin---author:wangshuai---date:2025-06-26---for:【QQYUN-12162】OA项目改造,系统重消息拆分,目前消息都在一起 需按分类进行拆分---
|
||||
// 代码逻辑说明: 【QQYUN-12162】OA项目改造,系统重消息拆分,目前消息都在一起 需按分类进行拆分---
|
||||
doSend(title, content, fromUser, username, data, messageDTO.getNoticeType());
|
||||
//update-end---author:wangshuai---date:2025-06-26---for:【QQYUN-12162】OA项目改造,系统重消息拆分,目前消息都在一起 需按分类进行拆分---
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -42,7 +42,7 @@ public class SendMsgJob implements Job {
|
||||
System.out.println(sysMessages);
|
||||
// 2.根据不同的类型走不通的发送实现类
|
||||
for (SysMessage sysMessage : sysMessages) {
|
||||
//update-begin-author:taoyan date:2022-7-8 for: 模板消息发送测试调用方法修改
|
||||
// 代码逻辑说明: 模板消息发送测试调用方法修改
|
||||
Integer sendNum = sysMessage.getEsSendNum();
|
||||
try {
|
||||
MessageDTO md = new MessageDTO();
|
||||
@ -51,13 +51,11 @@ public class SendMsgJob implements Job {
|
||||
md.setToUser(sysMessage.getEsReceiver());
|
||||
md.setType(sysMessage.getEsType());
|
||||
md.setToAll(false);
|
||||
//update-begin---author:wangshuai---date:2024-11-12---for:【QQYUN-8523】敲敲云发邮件通知,不稳定---
|
||||
// 代码逻辑说明: 【QQYUN-8523】敲敲云发邮件通知,不稳定---
|
||||
md.setIsTimeJob(true);
|
||||
//update-end---author:wangshuai---date:2024-11-12---for:【QQYUN-8523】敲敲云发邮件通知,不稳定---
|
||||
sysBaseAPI.sendTemplateMessage(md);
|
||||
//发送消息成功
|
||||
sysMessage.setEsSendStatus(SendMsgStatusEnum.SUCCESS.getCode());
|
||||
//update-end-author:taoyan date:2022-7-8 for: 模板消息发送测试调用方法修改
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
// 发送消息出现异常
|
||||
|
||||
@ -73,12 +73,11 @@ public class WebSocket {
|
||||
if (item.getKey().contains(userId)) {
|
||||
Session session = item.getValue();
|
||||
try {
|
||||
//update-begin-author:taoyan date:20211012 for: websocket报错 https://gitee.com/jeecg/jeecg-boot/issues/I4C0MU
|
||||
// 代码逻辑说明: websocket报错 https://gitee.com/jeecg/jeecg-boot/issues/I4C0MU
|
||||
synchronized (session){
|
||||
log.debug("【系统 WebSocket】推送单人消息:" + message);
|
||||
session.getBasicRemote().sendText(message);
|
||||
}
|
||||
//update-end-author:taoyan date:20211012 for: websocket报错 https://gitee.com/jeecg/jeecg-boot/issues/I4C0MU
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
}
|
||||
@ -114,9 +113,8 @@ public class WebSocket {
|
||||
log.debug("【系统 WebSocket】收到客户端消息:" + message);
|
||||
}else{
|
||||
log.debug("【系统 WebSocket】收到客户端消息:" + message);
|
||||
//update-begin---author:wangshuai---date:2024-05-07---for:【issues/1161】前端websocket因心跳导致监听不起作用---
|
||||
// 代码逻辑说明: 【issues/1161】前端websocket因心跳导致监听不起作用---
|
||||
this.sendMessage(userId, "ping");
|
||||
//update-end---author:wangshuai---date:2024-05-07---for:【issues/1161】前端websocket因心跳导致监听不起作用---
|
||||
}
|
||||
|
||||
// //------------------------------------------------------------------------------
|
||||
|
||||
@ -36,7 +36,7 @@ public class ActuatorMemoryController {
|
||||
result.put("memory.runtime.max", runtime.totalMemory() - runtime.freeMemory());
|
||||
result.put("memory.runtime.free", runtime.maxMemory() - runtime.totalMemory() + runtime.freeMemory());
|
||||
result.put("memory.runtime.usage", NumberUtil.div(runtime.totalMemory() - runtime.freeMemory(), runtime.totalMemory()));
|
||||
//update-begin---author:chenrui ---date:20240705 for:[TV360X-1695]内存信息-立即更新 功能报错 #6635------------
|
||||
// 代码逻辑说明: [TV360X-1695]内存信息-立即更新 功能报错 #6635------------
|
||||
OperatingSystemMXBean operatingSystemMXBean = ManagementFactory.getOperatingSystemMXBean();
|
||||
if (operatingSystemMXBean instanceof com.sun.management.OperatingSystemMXBean) {
|
||||
com.sun.management.OperatingSystemMXBean opBean = (com.sun.management.OperatingSystemMXBean) operatingSystemMXBean;
|
||||
@ -49,7 +49,6 @@ public class ActuatorMemoryController {
|
||||
result.put("memory.physical.free", usedPhysicalMemory);
|
||||
result.put("memory.physical.usage", NumberUtil.div(usedPhysicalMemory, totalPhysicalMemory));
|
||||
}
|
||||
//update-end---author:chenrui ---date:20240705 for:[TV360X-1695]内存信息-立即更新 功能报错 #6635------------
|
||||
return Result.ok(result);
|
||||
}
|
||||
|
||||
|
||||
@ -43,7 +43,6 @@ public class ActuatorRedisController {
|
||||
return Result.ok(infoList);
|
||||
}
|
||||
|
||||
//update-begin---author:chenrui ---date:20240514 for:[QQYUN-9247]系统监控功能优化------------
|
||||
/**
|
||||
* Redis历史性能指标查询(过去一小时)
|
||||
* @return
|
||||
@ -56,7 +55,6 @@ public class ActuatorRedisController {
|
||||
Map<String,List<Map<String,Object>>> metricsHistory = this.redisService.getMetricsHistory();
|
||||
return Result.OK(metricsHistory);
|
||||
}
|
||||
//update-end---author:chenrui ---date:20240514 for:[QQYUN-9247]系统监控功能优化------------
|
||||
|
||||
@GetMapping("/keysSize")
|
||||
public Map<String, Object> getKeysSize() throws Exception {
|
||||
@ -97,7 +95,6 @@ public class ActuatorRedisController {
|
||||
return redisService.getMemoryInfo();
|
||||
}
|
||||
|
||||
//update-begin--Author:zhangweijian Date:20190425 for:获取磁盘信息
|
||||
/**
|
||||
* @功能:获取磁盘信息
|
||||
* @param request
|
||||
@ -134,5 +131,4 @@ public class ActuatorRedisController {
|
||||
}
|
||||
return res;
|
||||
}
|
||||
//update-end--Author:zhangweijian Date:20190425 for:获取磁盘信息
|
||||
}
|
||||
|
||||
@ -128,7 +128,6 @@ public class RedisServiceImpl implements RedisService {
|
||||
return mapJson;
|
||||
}
|
||||
|
||||
//update-begin---author:chenrui ---date:20240514 for:[QQYUN-9247]系统监控功能优化------------
|
||||
/**
|
||||
* 获取历史性能指标
|
||||
* @return
|
||||
@ -170,5 +169,4 @@ public class RedisServiceImpl implements RedisService {
|
||||
}
|
||||
list.add(getMemoryInfo());
|
||||
}
|
||||
//update-end---author:chenrui ---date:20240514 for:[QQYUN-9247]系统监控功能优化------------
|
||||
}
|
||||
|
||||
@ -207,7 +207,7 @@ public class OpenApiController extends JeecgController<OpenApi, OpenApiService>
|
||||
* @return
|
||||
*/
|
||||
private String getToken(String USERNAME, String PASSWORD) {
|
||||
String token = JwtUtil.sign(USERNAME, PASSWORD);
|
||||
String token = JwtUtil.sign(USERNAME, PASSWORD, CommonConstant.CLIENT_TYPE_PC);
|
||||
redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token);
|
||||
redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, 60);
|
||||
return token;
|
||||
@ -382,7 +382,7 @@ public class OpenApiController extends JeecgController<OpenApi, OpenApiService>
|
||||
SwaggerInfo info = new SwaggerInfo();
|
||||
|
||||
info.setDescription("OpenAPI 接口列表");
|
||||
info.setVersion("3.8.3");
|
||||
info.setVersion("3.9.0");
|
||||
info.setTitle("OpenAPI 接口列表");
|
||||
info.setTermsOfService("https://jeecg.com");
|
||||
|
||||
|
||||
@ -30,10 +30,8 @@ public class OssFileServiceImpl extends ServiceImpl<OssFileMapper, OssFile> impl
|
||||
if(oConvertUtils.isEmpty(url)){
|
||||
throw new JeecgBootException("上传文件失败! ");
|
||||
}
|
||||
//update-begin--Author:scott Date:20201227 for:JT-361【文件预览】阿里云原生域名可以文件预览,自己映射域名kkfileview提示文件下载失败-------------------
|
||||
// 返回阿里云原生域名前缀URL
|
||||
ossFile.setUrl(OssBootUtil.getOriginalUrl(url));
|
||||
//update-end--Author:scott Date:20201227 for:JT-361【文件预览】阿里云原生域名可以文件预览,自己映射域名kkfileview提示文件下载失败-------------------
|
||||
this.save(ossFile);
|
||||
}
|
||||
|
||||
|
||||
@ -220,10 +220,8 @@ public class QuartzJobController {
|
||||
mv.addObject(NormalExcelConstants.FILE_NAME, "定时任务列表");
|
||||
mv.addObject(NormalExcelConstants.CLASS, QuartzJob.class);
|
||||
//获取当前登录用户
|
||||
//update-begin---author:wangshuai ---date:20211227 for:[JTC-116]导出人写死了------------
|
||||
LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("定时任务列表数据", "导出人:"+user.getRealname(), "导出信息"));
|
||||
//update-end---author:wangshuai ---date:20211227 for:[JTC-116]导出人写死了------------
|
||||
mv.addObject(NormalExcelConstants.DATA_LIST, pageList);
|
||||
return mv;
|
||||
}
|
||||
|
||||
@ -104,9 +104,8 @@ public class QuartzJobServiceImpl extends ServiceImpl<QuartzJobMapper, QuartzJob
|
||||
String ymd = DateUtils.date2Str(startDate,DateUtils.yyyymmddhhmmss.get());
|
||||
String identity = jobName + ymd;
|
||||
//3秒后执行 只执行一次
|
||||
// update-begin--author:sunjianlei ---- date:20210511--- for:定时任务立即执行,延迟3秒改成0.1秒-------
|
||||
// 代码逻辑说明: 定时任务立即执行,延迟3秒改成0.1秒-------
|
||||
startDate.setTime(startDate.getTime() + 100L);
|
||||
// update-end--author:sunjianlei ---- date:20210511--- for:定时任务立即执行,延迟3秒改成0.1秒-------
|
||||
// 定义一个Trigger
|
||||
SimpleTrigger trigger = (SimpleTrigger)TriggerBuilder.newTrigger()
|
||||
.withIdentity(identity, JOB_TEST_GROUP)
|
||||
|
||||
@ -1,26 +1,29 @@
|
||||
package org.jeecg.modules.system.controller;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
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.filter.SsrfFileTypeFilter;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.modules.system.util.HttpFileToMultipartFileUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.util.AntPathMatcher;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||
import org.springframework.web.servlet.HandlerMapping;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
@ -80,6 +83,13 @@ public class CommonController {
|
||||
savePath = CommonUtils.upload(file, bizPath, uploadType);
|
||||
}
|
||||
if(oConvertUtils.isNotEmpty(savePath)){
|
||||
|
||||
//添加到文件表
|
||||
String orgName = file.getOriginalFilename();
|
||||
// 获取文件名
|
||||
orgName = CommonUtils.getFileName(orgName);
|
||||
String type = orgName.substring(orgName.lastIndexOf(SymbolConstant.SPOT));
|
||||
FileTypeEnum fileType = FileTypeEnum.getByType(type);
|
||||
result.setMessage(savePath);
|
||||
result.setSuccess(true);
|
||||
}else {
|
||||
@ -188,9 +198,8 @@ 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);
|
||||
@ -303,4 +312,35 @@ public class CommonController {
|
||||
return new AntPathMatcher().extractPathWithinPattern(bestMatchPattern, path);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据网路图片地址上传到服务器
|
||||
* @param jsonObject
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/uploadImgByHttp")
|
||||
public Result<String> uploadImgByHttp(@RequestBody JSONObject jsonObject, HttpServletRequest request){
|
||||
String fileUrl = oConvertUtils.getString(jsonObject.get("fileUrl"));
|
||||
String filename = oConvertUtils.getString(jsonObject.get("filename"));
|
||||
String bizPath = oConvertUtils.getString(jsonObject.get("bizPath"));
|
||||
try {
|
||||
String savePath = "";
|
||||
MultipartFile file = HttpFileToMultipartFileUtil.httpFileToMultipartFile(fileUrl, filename);
|
||||
// 文件安全校验,防止上传漏洞文件
|
||||
SsrfFileTypeFilter.checkUploadFileType(file, bizPath);
|
||||
if (oConvertUtils.isEmpty(bizPath)) {
|
||||
bizPath = CommonConstant.UPLOAD_TYPE_OSS.equals(uploadType) ? "upload" : "";
|
||||
}
|
||||
if(CommonConstant.UPLOAD_TYPE_LOCAL.equals(uploadType)){
|
||||
savePath = this.uploadLocal(file,bizPath);
|
||||
}else{
|
||||
savePath = CommonUtils.upload(file, bizPath, uploadType);
|
||||
}
|
||||
return Result.OK(savePath);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return Result.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -5,8 +5,11 @@ import com.alibaba.fastjson.JSONObject;
|
||||
import com.aliyuncs.exceptions.ClientException;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.apache.shiro.authz.annotation.RequiresRoles;
|
||||
@ -18,12 +21,13 @@ 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.*;
|
||||
import org.jeecg.common.util.encryption.AesEncryptUtil;
|
||||
import org.jeecg.common.util.encryption.EncryptedString;
|
||||
import org.jeecg.config.JeecgBaseConfig;
|
||||
import org.jeecg.config.shiro.IgnoreAuth;
|
||||
import org.jeecg.modules.base.service.BaseCommonService;
|
||||
import org.jeecg.modules.system.entity.SysDepart;
|
||||
import org.jeecg.modules.system.entity.SysRoleIndex;
|
||||
import org.jeecg.modules.system.entity.SysTenant;
|
||||
import org.jeecg.modules.system.entity.SysUser;
|
||||
import org.jeecg.modules.system.model.SysLoginModel;
|
||||
import org.jeecg.modules.system.service.*;
|
||||
@ -31,18 +35,13 @@ import org.jeecg.modules.system.service.impl.SysBaseApiImpl;
|
||||
import org.jeecg.modules.system.util.RandImageUtil;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.task.AsyncTaskExecutor;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.SynchronousQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @Author scott
|
||||
@ -71,45 +70,36 @@ public class LoginController {
|
||||
private BaseCommonService baseCommonService;
|
||||
@Autowired
|
||||
private JeecgBaseConfig jeecgBaseConfig;
|
||||
|
||||
private final String BASE_CHECK_CODES = "qwertyuiplkjhgfdsazxcvbnmQWERTYUPLKJHGFDSAZXCVBNM1234567890";
|
||||
/**
|
||||
* 线程池用于异步发送纪要
|
||||
*/
|
||||
public static ExecutorService cachedThreadPool = new ShiroThreadPoolExecutor(0, 1024, 60L, TimeUnit.SECONDS, new SynchronousQueue<>());
|
||||
|
||||
|
||||
|
||||
@Operation(summary="登录接口")
|
||||
@RequestMapping(value = "/login", method = RequestMethod.POST)
|
||||
public Result<JSONObject> login(@RequestBody SysLoginModel sysLoginModel, HttpServletRequest request){
|
||||
Result<JSONObject> result = new Result<JSONObject>();
|
||||
Result<JSONObject> result = new Result<>();
|
||||
String username = sysLoginModel.getUsername();
|
||||
String password = sysLoginModel.getPassword();
|
||||
// 密码加密传输(尝试 AES解密,失败视为明文)
|
||||
String password = AesEncryptUtil.resolvePassword(sysLoginModel.getPassword());
|
||||
log.debug("登录密码,原始密码:{},解密密码:{}" , sysLoginModel.getPassword(), password);
|
||||
|
||||
//step.1 登录失败超出次数5次锁定用户10分钟
|
||||
if(isLoginFailOvertimes(username)){
|
||||
return result.error500("该用户登录失败次数过多,请于10分钟后再次登录!");
|
||||
}
|
||||
|
||||
// step.1 验证码check
|
||||
String captcha = sysLoginModel.getCaptcha();
|
||||
if(captcha==null){
|
||||
result.error500("验证码无效");
|
||||
// step.2 验证码check
|
||||
String realKey = validateCaptcha(sysLoginModel, result);
|
||||
if (realKey == null) {
|
||||
return result;
|
||||
}
|
||||
String lowerCaseCaptcha = captcha.toLowerCase();
|
||||
// 加入密钥作为混淆,避免简单的拼接,被外部利用,用户自定义该密钥即可
|
||||
//update-begin---author:chenrui ---date:20250107 for:[QQYUN-10775]验证码可以复用 #7674------------
|
||||
String keyPrefix = Md5Util.md5Encode(sysLoginModel.getCheckKey()+jeecgBaseConfig.getSignatureSecret(), "utf-8");
|
||||
String realKey = keyPrefix + lowerCaseCaptcha;
|
||||
//update-end---author:chenrui ---date:20250107 for:[QQYUN-10775]验证码可以复用 #7674------------
|
||||
Object checkCode = redisUtil.get(realKey);
|
||||
//当进入登录页时,有一定几率出现验证码错误 #1714
|
||||
if(checkCode==null || !checkCode.toString().equals(lowerCaseCaptcha)) {
|
||||
log.warn("验证码错误,key= {} , Ui checkCode= {}, Redis checkCode = {}", sysLoginModel.getCheckKey(), lowerCaseCaptcha, checkCode);
|
||||
result.error500("验证码错误");
|
||||
// 改成特殊的code 便于前端判断
|
||||
result.setCode(HttpStatus.PRECONDITION_FAILED.value());
|
||||
return result;
|
||||
}
|
||||
|
||||
// step.2 校验用户是否存在且有效
|
||||
// step.3 校验用户是否存在且有效
|
||||
LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(SysUser::getUsername,username);
|
||||
SysUser sysUser = sysUserService.getOne(queryWrapper);
|
||||
@ -118,7 +108,7 @@ public class LoginController {
|
||||
return result;
|
||||
}
|
||||
|
||||
// step.3 校验用户名或密码是否正确
|
||||
// step.4 校验用户名或密码是否正确
|
||||
String userpassword = PasswordUtil.encrypt(username, password, sysUser.getSalt());
|
||||
String syspassword = sysUser.getPassword();
|
||||
if (!syspassword.equals(userpassword)) {
|
||||
@ -127,14 +117,16 @@ public class LoginController {
|
||||
return result;
|
||||
}
|
||||
|
||||
// step.4 登录成功获取用户信息
|
||||
userInfo(sysUser, result, request);
|
||||
// step.5 登录成功获取用户信息
|
||||
String loginOrgCode = sysLoginModel.getLoginOrgCode();
|
||||
sysUser.setLoginOrgCode(loginOrgCode);
|
||||
userInfo(sysUser, result, request, CommonConstant.CLIENT_TYPE_PC);
|
||||
|
||||
// step.5 登录成功删除验证码
|
||||
// step.6 登录成功删除验证码
|
||||
redisUtil.del(realKey);
|
||||
redisUtil.del(CommonConstant.LOGIN_FAIL + username);
|
||||
|
||||
// step.6 记录用户登录日志
|
||||
// step.7 记录用户登录日志
|
||||
LoginUser loginUser = new LoginUser();
|
||||
BeanUtils.copyProperties(sysUser, loginUser);
|
||||
baseCommonService.addLog("用户名: " + username + ",登录成功!", CommonConstant.LOG_TYPE_1, null,loginUser);
|
||||
@ -154,11 +146,10 @@ public class LoginController {
|
||||
// 根据用户名查询用户信息
|
||||
SysUser sysUser = sysUserService.getUserByName(username);
|
||||
JSONObject obj=new JSONObject();
|
||||
log.info("1 获取用户信息耗时(用户基础信息)" + (System.currentTimeMillis() - start) + "毫秒");
|
||||
log.debug("1 获取用户信息耗时(用户基础信息)" + (System.currentTimeMillis() - start) + "毫秒");
|
||||
|
||||
//update-begin---author:scott ---date:2022-06-20 for:vue3前端,支持自定义首页-----------
|
||||
// 代码逻辑说明: vue3前端,支持自定义首页-----------
|
||||
String vue3Version = request.getHeader(CommonConstant.VERSION);
|
||||
//update-begin---author:liusq ---date:2022-06-29 for:接口返回值修改,同步修改这里的判断逻辑-----------
|
||||
SysRoleIndex roleIndex = sysUserService.getDynamicIndexByUserRole(username, vue3Version);
|
||||
if (oConvertUtils.isNotEmpty(vue3Version) && roleIndex != null && oConvertUtils.isNotEmpty(roleIndex.getUrl())) {
|
||||
String homePath = roleIndex.getUrl();
|
||||
@ -167,18 +158,16 @@ public class LoginController {
|
||||
}
|
||||
sysUser.setHomePath(homePath);
|
||||
}
|
||||
//update-begin---author:liusq ---date:2022-06-29 for:接口返回值修改,同步修改这里的判断逻辑-----------
|
||||
//update-end---author:scott ---date::2022-06-20 for:vue3前端,支持自定义首页--------------
|
||||
log.info("2 获取用户信息耗时 (首页面配置)" + (System.currentTimeMillis() - start) + "毫秒");
|
||||
log.debug("2 获取用户信息耗时 (首页面配置)" + (System.currentTimeMillis() - start) + "毫秒");
|
||||
|
||||
obj.put("userInfo",sysUser);
|
||||
obj.put("sysAllDictItems", sysDictService.queryAllDictItems());
|
||||
log.info("3 获取用户信息耗时 (字典数据)" + (System.currentTimeMillis() - start) + "毫秒");
|
||||
log.debug("3 获取用户信息耗时 (字典数据)" + (System.currentTimeMillis() - start) + "毫秒");
|
||||
|
||||
result.setResult(obj);
|
||||
result.success("");
|
||||
}
|
||||
log.info("end 获取用户信息耗时 " + (System.currentTimeMillis() - start) + "毫秒");
|
||||
log.debug("end 获取用户信息耗时 " + (System.currentTimeMillis() - start) + "毫秒");
|
||||
return result;
|
||||
|
||||
}
|
||||
@ -209,7 +198,7 @@ public class LoginController {
|
||||
|
||||
/**
|
||||
* 清理用户缓存
|
||||
*
|
||||
*
|
||||
* @param token
|
||||
* @param sysUser
|
||||
*/
|
||||
@ -221,12 +210,15 @@ public class LoginController {
|
||||
redisUtil.del(CommonConstant.PREFIX_USER_SHIRO_CACHE + sysUser.getId());
|
||||
//清空用户的缓存信息(包括部门信息),例如sys:cache:user::<username>
|
||||
redisUtil.del(String.format("%s::%s", CacheConstant.SYS_USERS_CACHE, sysUser.getUsername()));
|
||||
//清空是否允许同一账号多地同时登录缓存(PC端和APP端)
|
||||
redisUtil.del(CommonConstant.PREFIX_USER_TOKEN_PC + sysUser.getUsername());
|
||||
redisUtil.del(CommonConstant.PREFIX_USER_TOKEN_APP + sysUser.getUsername());
|
||||
redisUtil.del(CommonConstant.PREFIX_USER_TOKEN_PHONE + sysUser.getUsername());
|
||||
baseCommonService.addLog("用户名: "+sysUser.getRealname()+",退出成功!", CommonConstant.LOG_TYPE_1, null, sysUser);
|
||||
log.info("【退出成功操作】异步处理,退出后,清理用户缓存: "+sysUser.getRealname());
|
||||
log.debug("【退出成功操作】异步处理,退出后,清理用户缓存: "+sysUser.getRealname());
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取访问量
|
||||
* @return
|
||||
@ -235,7 +227,6 @@ public class LoginController {
|
||||
public Result<JSONObject> loginfo() {
|
||||
Result<JSONObject> result = new Result<JSONObject>();
|
||||
JSONObject obj = new JSONObject();
|
||||
//update-begin--Author:zhangweijian Date:20190428 for:传入开始时间,结束时间参数
|
||||
// 获取一天的开始和结束时间
|
||||
Calendar calendar = new GregorianCalendar();
|
||||
calendar.set(Calendar.HOUR_OF_DAY, 0);
|
||||
@ -251,7 +242,6 @@ public class LoginController {
|
||||
Long todayVisitCount = logService.findTodayVisitCount(dayStart,dayEnd);
|
||||
obj.put("todayVisitCount", todayVisitCount);
|
||||
Long todayIp = logService.findTodayIp(dayStart,dayEnd);
|
||||
//update-end--Author:zhangweijian Date:20190428 for:传入开始时间,结束时间参数
|
||||
obj.put("todayIp", todayIp);
|
||||
result.setResult(obj);
|
||||
result.success("登录成功");
|
||||
@ -328,10 +318,9 @@ public class LoginController {
|
||||
return result;
|
||||
}
|
||||
|
||||
//update-begin-author:taoyan date:2022-9-13 for: VUEN-2245 【漏洞】发现新漏洞待处理20220906
|
||||
// VUEN-2245【漏洞】发现新漏洞待处理20220906
|
||||
String redisKey = CommonConstant.PHONE_REDIS_KEY_PRE+mobile;
|
||||
Object object = redisUtil.get(redisKey);
|
||||
//update-end-author:taoyan date:2022-9-13 for: VUEN-2245 【漏洞】发现新漏洞待处理20220906
|
||||
|
||||
if (object != null) {
|
||||
result.setMessage("验证码10分钟内,仍然有效!");
|
||||
@ -387,7 +376,7 @@ public class LoginController {
|
||||
} else if(CommonConstant.SMS_TPL_TYPE_2.equals(smsmode)) {
|
||||
//忘记密码模板
|
||||
b = DySmsHelper.sendSms(mobile, obj, DySmsEnum.FORGET_PASSWORD_TEMPLATE_CODE);
|
||||
//update-begin---author:wangshuai---date:2025-07-15---for:【issues/8567】严重:修改密码存在水平越权问题。---
|
||||
// 代码逻辑说明: 【issues/8567】严重:修改密码存在水平越权问题。---
|
||||
if(b){
|
||||
String username = sysUser.getUsername();
|
||||
obj.put("username",username);
|
||||
@ -395,7 +384,6 @@ public class LoginController {
|
||||
result.setSuccess(true);
|
||||
return result;
|
||||
}
|
||||
//update-end---author:wangshuai---date:2025-07-15---for:【issues/8567】严重:修改密码存在水平越权问题。---
|
||||
}
|
||||
}
|
||||
|
||||
@ -405,14 +393,8 @@ public class LoginController {
|
||||
return result;
|
||||
}
|
||||
|
||||
//update-begin-author:taoyan date:2022-9-13 for: VUEN-2245 【漏洞】发现新漏洞待处理20220906
|
||||
//验证码10分钟内有效
|
||||
redisUtil.set(redisKey, captcha, 600);
|
||||
//update-end-author:taoyan date:2022-9-13 for: VUEN-2245 【漏洞】发现新漏洞待处理20220906
|
||||
|
||||
//update-begin--Author:scott Date:20190812 for:issues#391
|
||||
//result.setResult(captcha);
|
||||
//update-end--Author:scott Date:20190812 for:issues#391
|
||||
result.setSuccess(true);
|
||||
|
||||
} catch (ClientException e) {
|
||||
@ -435,11 +417,11 @@ public class LoginController {
|
||||
public Result<JSONObject> phoneLogin(@RequestBody JSONObject jsonObject, HttpServletRequest request) {
|
||||
Result<JSONObject> result = new Result<JSONObject>();
|
||||
String phone = jsonObject.getString("mobile");
|
||||
//update-begin-author:taoyan date:2022-11-7 for: issues/4109 平台用户登录失败锁定用户
|
||||
// 平台用户登录失败锁定用户
|
||||
if(isLoginFailOvertimes(phone)){
|
||||
return result.error500("该用户登录失败次数过多,请于10分钟后再次登录!");
|
||||
}
|
||||
//update-end-author:taoyan date:2022-11-7 for: issues/4109 平台用户登录失败锁定用户
|
||||
|
||||
//校验用户有效性
|
||||
SysUser sysUser = sysUserService.getUserByPhone(phone);
|
||||
result = sysUserService.checkUserIsEffective(sysUser);
|
||||
@ -449,19 +431,18 @@ public class LoginController {
|
||||
|
||||
String smscode = jsonObject.getString("captcha");
|
||||
|
||||
//update-begin-author:taoyan date:2022-9-13 for: VUEN-2245 【漏洞】发现新漏洞待处理20220906
|
||||
// 代码逻辑说明: VUEN-2245 【漏洞】发现新漏洞待处理20220906
|
||||
String redisKey = CommonConstant.PHONE_REDIS_KEY_PRE+phone;
|
||||
Object code = redisUtil.get(redisKey);
|
||||
//update-end-author:taoyan date:2022-9-13 for: VUEN-2245 【漏洞】发现新漏洞待处理20220906
|
||||
|
||||
if (!smscode.equals(code)) {
|
||||
//update-begin-author:taoyan date:2022-11-7 for: issues/4109 平台用户登录失败锁定用户
|
||||
addLoginFailOvertimes(phone);
|
||||
//update-end-author:taoyan date:2022-11-7 for: issues/4109 平台用户登录失败锁定用户
|
||||
return Result.error("手机验证码错误");
|
||||
}
|
||||
//用户信息
|
||||
userInfo(sysUser, result, request);
|
||||
String loginOrgCode = jsonObject.getString("loginOrgCode");
|
||||
sysUser.setLoginOrgCode(loginOrgCode);
|
||||
userInfo(sysUser, result, request, CommonConstant.CLIENT_TYPE_PHONE);
|
||||
//添加日志
|
||||
baseCommonService.addLog("用户名: " + sysUser.getUsername() + ",登录成功!", CommonConstant.LOG_TYPE_1, null);
|
||||
redisUtil.removeAll(redisKey);
|
||||
@ -476,19 +457,24 @@ public class LoginController {
|
||||
* @param result
|
||||
* @return
|
||||
*/
|
||||
private Result<JSONObject> userInfo(SysUser sysUser, Result<JSONObject> result, HttpServletRequest request) {
|
||||
private Result<JSONObject> userInfo(SysUser sysUser, Result<JSONObject> result, HttpServletRequest request, String clientType) {
|
||||
String username = sysUser.getUsername();
|
||||
String syspassword = sysUser.getPassword();
|
||||
// 获取用户部门信息
|
||||
JSONObject obj = new JSONObject(new LinkedHashMap<>());
|
||||
|
||||
//1.生成token
|
||||
String token = JwtUtil.sign(username, syspassword);
|
||||
// 设置token缓存有效时间
|
||||
//1.生成token,并设置超时时间
|
||||
String token = JwtUtil.sign(username, syspassword, clientType);
|
||||
redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token);
|
||||
redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME * 2 / 1000);
|
||||
// 根据客户端类型设置对应的过期时间
|
||||
long expireTime = CommonConstant.CLIENT_TYPE_APP.equalsIgnoreCase(clientType)
|
||||
? JwtUtil.APP_EXPIRE_TIME * 2 / 1000
|
||||
: JwtUtil.EXPIRE_TIME * 2 / 1000;
|
||||
redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, expireTime);
|
||||
obj.put("token", token);
|
||||
|
||||
// 是否允许同一账号多地同时登录,踢掉之前的登录
|
||||
handleSingleSignOn(username, token, clientType);
|
||||
|
||||
//2.设置登录租户
|
||||
Result<JSONObject> loginTenantError = sysUserService.setLoginTenant(sysUser, obj, username,result);
|
||||
if (loginTenantError != null) {
|
||||
@ -503,33 +489,95 @@ public class LoginController {
|
||||
obj.put("departs", departs);
|
||||
if (departs == null || departs.size() == 0) {
|
||||
obj.put("multi_depart", 0);
|
||||
sysUserService.updateUserDepart(username, null, null);
|
||||
} else if (departs.size() == 1) {
|
||||
sysUserService.updateUserDepart(username, departs.get(0).getOrgCode(),null);
|
||||
obj.put("multi_depart", 1);
|
||||
} else {
|
||||
//查询当前是否有登录部门
|
||||
// update-begin--Author:wangshuai Date:20200805 for:如果用戶为选择部门,数据库为存在上一次登录部门,则取一条存进去
|
||||
SysUser sysUserById = sysUserService.getById(sysUser.getId());
|
||||
if(oConvertUtils.isEmpty(sysUserById.getOrgCode())){
|
||||
sysUserService.updateUserDepart(username, departs.get(0).getOrgCode(),null);
|
||||
//【部门切换】支持登录页面选择部门
|
||||
String loginOrgCode = sysUser.getLoginOrgCode();
|
||||
|
||||
// 判断上次登录部门orgCode是否在departs中
|
||||
boolean orgCodeInDeparts = departs.stream().anyMatch(d -> sysUserById.getOrgCode() != null && sysUserById.getOrgCode().equalsIgnoreCase(d.getOrgCode()));
|
||||
if (!orgCodeInDeparts) {
|
||||
sysUserById.setOrgCode(null);
|
||||
}
|
||||
|
||||
// 如果未设置登录部门,则将登录部门设置为用户选择的 loginOrgCode(优先),否则设置为默认的第一个部门
|
||||
if(oConvertUtils.isEmpty(sysUserById.getOrgCode())){
|
||||
String orgCode = oConvertUtils.isNotEmpty(loginOrgCode) ? loginOrgCode : departs.get(0).getOrgCode();
|
||||
sysUserService.updateUserDepart(username, orgCode, null);
|
||||
} else {
|
||||
// 已设置登录部门,若用户本次登录选择了不同的部门,则优先使用用户选择的 loginOrgCode 更新登录部门
|
||||
String orgCode = sysUserById.getOrgCode();
|
||||
if(oConvertUtils.isNotEmpty(loginOrgCode) && !orgCode.equalsIgnoreCase(loginOrgCode)){
|
||||
sysUserService.updateUserDepart(username, loginOrgCode, null);
|
||||
}
|
||||
}
|
||||
// update-end--Author:wangshuai Date:20200805 for:如果用戶为选择部门,数据库为存在上一次登录部门,则取一条存进去
|
||||
obj.put("multi_depart", 2);
|
||||
}
|
||||
|
||||
//update-begin---author:scott ---date:2024-01-05 for:【QQYUN-7802】前端在登录时加载了两次数据字典,建议优化下,避免数据字典太多时可能产生的性能问题 #956---
|
||||
// login接口,在vue3前端下不加载字典数据,vue2下加载字典
|
||||
// 5.vue3版本不加载字典数据,vue2下加载字典
|
||||
String vue3Version = request.getHeader(CommonConstant.VERSION);
|
||||
if(oConvertUtils.isEmpty(vue3Version)){
|
||||
obj.put("sysAllDictItems", sysDictService.queryAllDictItems());
|
||||
}
|
||||
//end-begin---author:scott ---date:2024-01-05 for:【QQYUN-7802】前端在登录时加载了两次数据字典,建议优化下,避免数据字典太多时可能产生的性能问题 #956---
|
||||
|
||||
result.setResult(obj);
|
||||
result.success("登录成功");
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 同一账号在同一客户端类型只能登录一次
|
||||
*
|
||||
* @author scott
|
||||
* @date 2025-10-31
|
||||
* PC端、APP端、手机号登录分别独立,互不影响
|
||||
*
|
||||
* @param username 用户名
|
||||
* @param newToken 新生成的token
|
||||
* @param clientType 客户端类型(PC、APP、PHONE)
|
||||
*/
|
||||
private void handleSingleSignOn(String username, String newToken, String clientType) {
|
||||
// 检查是否允许并发登录
|
||||
if (jeecgBaseConfig.getFirewall() == null || jeecgBaseConfig.getFirewall().getIsConcurrent()==null || Boolean.TRUE.equals(jeecgBaseConfig.getFirewall().getIsConcurrent())) {
|
||||
// 允许并发登录,只设置当前用户的token缓存,不踢掉之前的登录
|
||||
log.debug("并发登录已启用:用户[{}]在{}端允许多地同时登录", username, clientType);
|
||||
return;
|
||||
}
|
||||
|
||||
log.info("【并发登录限制已开启】 用户[{}]在{}端不允许多地同时登录", username, clientType);
|
||||
// 根据客户端类型选择对应的Redis key前缀
|
||||
String redisKeyPrefix;
|
||||
if (CommonConstant.CLIENT_TYPE_APP.equalsIgnoreCase(clientType)) {
|
||||
redisKeyPrefix = CommonConstant.PREFIX_USER_TOKEN_APP;
|
||||
} else if (CommonConstant.CLIENT_TYPE_PHONE.equalsIgnoreCase(clientType)) {
|
||||
redisKeyPrefix = CommonConstant.PREFIX_USER_TOKEN_PHONE;
|
||||
} else {
|
||||
redisKeyPrefix = CommonConstant.PREFIX_USER_TOKEN_PC;
|
||||
}
|
||||
|
||||
String userTokenKey = redisKeyPrefix + username;
|
||||
|
||||
// 获取该用户在当前客户端类型下之前的token
|
||||
Object oldTokenObj = redisUtil.get(userTokenKey);
|
||||
if (oldTokenObj != null && !oldTokenObj.equals(newToken)) {
|
||||
String oldToken = oldTokenObj.toString();
|
||||
// 清除旧登录token的缓存(设置 1 小时过期时间)
|
||||
redisUtil.del(CommonConstant.PREFIX_USER_TOKEN + oldToken);
|
||||
redisUtil.set(CommonConstant.PREFIX_USER_TOKEN_ERROR_MSG + oldToken, "不允许同一账号多地同时登录,当前登录被踢掉!", 60 * 1 * 60);
|
||||
log.info("【并发登录限制已开启】用户[{}]在{}端的旧登录已被踢下线!", username, clientType);
|
||||
log.info("【并发登录限制已开启】用户被踢下线,新token: {},旧token:{}", newToken, oldToken);
|
||||
}
|
||||
|
||||
// 保存新的token到单点登录缓存
|
||||
redisUtil.set(userTokenKey, newToken);
|
||||
redisUtil.expire(userTokenKey, JwtUtil.EXPIRE_TIME * 2 / 1000);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取加密字符串
|
||||
* @return
|
||||
@ -554,22 +602,14 @@ public class LoginController {
|
||||
public Result<String> randomImage(HttpServletResponse response,@PathVariable("key") String key){
|
||||
Result<String> res = new Result<String>();
|
||||
try {
|
||||
//生成验证码
|
||||
//生成验证码,存到redis中
|
||||
String code = RandomUtil.randomString(BASE_CHECK_CODES,4);
|
||||
//存到redis中
|
||||
String lowerCaseCode = code.toLowerCase();
|
||||
|
||||
//update-begin-author:taoyan date:2022-9-13 for: VUEN-2245 【漏洞】发现新漏洞待处理20220906
|
||||
// 加入密钥作为混淆,避免简单的拼接,被外部利用,用户自定义该密钥即可
|
||||
//update-begin---author:chenrui ---date:20250107 for:[QQYUN-10775]验证码可以复用 #7674------------
|
||||
String keyPrefix = Md5Util.md5Encode(key+jeecgBaseConfig.getSignatureSecret(), "utf-8");
|
||||
String keyPrefix = Md5Util.md5Encode(key + jeecgBaseConfig.getSignatureSecret(), "utf-8");
|
||||
String realKey = keyPrefix + lowerCaseCode;
|
||||
//update-end-author:taoyan date:2022-9-13 for: VUEN-2245 【漏洞】发现新漏洞待处理20220906
|
||||
redisUtil.removeAll(keyPrefix);
|
||||
//update-end---author:chenrui ---date:20250107 for:[QQYUN-10775]验证码可以复用 #7674------------
|
||||
redisUtil.set(realKey, lowerCaseCode, 60);
|
||||
log.info("获取验证码,Redis key = {},checkCode = {}", realKey, code);
|
||||
//返回前端
|
||||
log.debug("获取验证码,Redis key = {},checkCode = {}", realKey, code);
|
||||
String base64 = RandImageUtil.generate(code);
|
||||
res.setSuccess(true);
|
||||
res.setResult(base64);
|
||||
@ -581,16 +621,16 @@ public class LoginController {
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 切换菜单表为vue3的表
|
||||
*/
|
||||
@RequiresRoles({"admin"})
|
||||
@GetMapping(value = "/switchVue3Menu")
|
||||
public Result<String> switchVue3Menu(HttpServletResponse response) {
|
||||
Result<String> res = new Result<String>();
|
||||
sysPermissionService.switchVue3Menu();
|
||||
return res;
|
||||
}
|
||||
// /**
|
||||
// * 切换菜单表为vue3的表
|
||||
// */
|
||||
// @RequiresRoles({"admin"})
|
||||
// @GetMapping(value = "/switchVue3Menu")
|
||||
// public Result<String> switchVue3Menu(HttpServletResponse response) {
|
||||
// Result<String> res = new Result<String>();
|
||||
// sysPermissionService.switchVue3Menu();
|
||||
// return res;
|
||||
// }
|
||||
|
||||
/**
|
||||
* app登录
|
||||
@ -599,74 +639,80 @@ public class LoginController {
|
||||
* @throws Exception
|
||||
*/
|
||||
@RequestMapping(value = "/mLogin", method = RequestMethod.POST)
|
||||
public Result<JSONObject> mLogin(@RequestBody SysLoginModel sysLoginModel) throws Exception {
|
||||
public Result<JSONObject> mLogin(@RequestBody SysLoginModel sysLoginModel, HttpServletRequest request) throws Exception {
|
||||
Result<JSONObject> result = new Result<JSONObject>();
|
||||
String username = sysLoginModel.getUsername();
|
||||
String password = sysLoginModel.getPassword();
|
||||
// 密码加密传输(尝试 AES解密,失败视为明文)
|
||||
String password = AesEncryptUtil.resolvePassword(sysLoginModel.getPassword());
|
||||
log.debug("登录密码,原始密码:{},解密密码:{}" , sysLoginModel.getPassword(), password);
|
||||
|
||||
JSONObject obj = new JSONObject();
|
||||
|
||||
//update-begin-author:taoyan date:2022-11-7 for: issues/4109 平台用户登录失败锁定用户
|
||||
// 1.平台用户登录失败锁定用户
|
||||
if(isLoginFailOvertimes(username)){
|
||||
return result.error500("该用户登录失败次数过多,请于10分钟后再次登录!");
|
||||
}
|
||||
//update-end-author:taoyan date:2022-11-7 for: issues/4109 平台用户登录失败锁定用户
|
||||
//1. 校验用户是否有效
|
||||
// 2.校验用户是否有效
|
||||
SysUser sysUser = sysUserService.getUserByName(username);
|
||||
result = sysUserService.checkUserIsEffective(sysUser);
|
||||
if(!result.isSuccess()) {
|
||||
return result;
|
||||
}
|
||||
|
||||
//2. 校验用户名或密码是否正确
|
||||
// 3.校验用户名或密码是否正确
|
||||
String userpassword = PasswordUtil.encrypt(username, password, sysUser.getSalt());
|
||||
String syspassword = sysUser.getPassword();
|
||||
if (!syspassword.equals(userpassword)) {
|
||||
//update-begin-author:taoyan date:2022-11-7 for: issues/4109 平台用户登录失败锁定用户
|
||||
addLoginFailOvertimes(username);
|
||||
//update-end-author:taoyan date:2022-11-7 for: issues/4109 平台用户登录失败锁定用户
|
||||
result.error500("用户名或密码错误");
|
||||
return result;
|
||||
}
|
||||
|
||||
//3.设置登录部门
|
||||
//4.设置登录部门
|
||||
String orgCode = sysUser.getOrgCode();
|
||||
//登录设置的组织
|
||||
String loginOrgCode = sysLoginModel.getLoginOrgCode();
|
||||
if(oConvertUtils.isEmpty(orgCode)) {
|
||||
//如果当前用户无选择部门 查看部门关联信息
|
||||
|
||||
List<SysDepart> departs = sysDepartService.queryUserDeparts(sysUser.getId());
|
||||
//update-begin-author:taoyan date:20220117 for: JTC-1068【app】新建用户,没有设置部门及角色,点击登录提示暂未归属部,一直在登录页面 使用手机号登录 可正常
|
||||
if (departs == null || departs.size() == 0) {
|
||||
/*result.error500("用户暂未归属部门,不可登录!");
|
||||
|
||||
return result;*/
|
||||
if(oConvertUtils.isNotEmpty(loginOrgCode)){
|
||||
sysUser.setOrgCode(loginOrgCode);
|
||||
this.sysUserService.updateUserDepart(username, loginOrgCode,null);
|
||||
}else{
|
||||
orgCode = departs.get(0).getOrgCode();
|
||||
sysUser.setOrgCode(orgCode);
|
||||
this.sysUserService.updateUserDepart(username, orgCode,null);
|
||||
List<SysDepart> departs = sysDepartService.queryUserDeparts(sysUser.getId());
|
||||
if (departs != null && !departs.isEmpty()) {
|
||||
orgCode = departs.get(0).getOrgCode();
|
||||
sysUser.setOrgCode(orgCode);
|
||||
this.sysUserService.updateUserDepart(username, orgCode,null);
|
||||
}
|
||||
}
|
||||
}else{
|
||||
if(oConvertUtils.isNotEmpty(loginOrgCode) && !orgCode.equalsIgnoreCase(loginOrgCode)){
|
||||
sysUser.setOrgCode(loginOrgCode);
|
||||
sysUserService.updateUserDepart(username, loginOrgCode,null);
|
||||
}
|
||||
//update-end-author:taoyan date:20220117 for: JTC-1068【app】新建用户,没有设置部门及角色,点击登录提示暂未归属部,一直在登录页面 使用手机号登录 可正常
|
||||
}
|
||||
|
||||
//4. 设置登录租户
|
||||
//5. 设置登录租户
|
||||
Result<JSONObject> loginTenantError = sysUserService.setLoginTenant(sysUser, obj, username, result);
|
||||
if (loginTenantError != null) {
|
||||
return loginTenantError;
|
||||
}
|
||||
|
||||
//5. 设置登录用户信息
|
||||
// 设置登录用户信息
|
||||
obj.put("userInfo", sysUser);
|
||||
|
||||
//6. 生成token
|
||||
String token = JwtUtil.sign(username, syspassword);
|
||||
// 设置超时时间
|
||||
redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token);
|
||||
redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME*2 / 1000);
|
||||
|
||||
//token 信息
|
||||
//6. 生成token,并设置超时时间
|
||||
String token = JwtUtil.sign(username, syspassword, CommonConstant.CLIENT_TYPE_APP);
|
||||
redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token);
|
||||
redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.APP_EXPIRE_TIME*2 / 1000);
|
||||
obj.put("token", token);
|
||||
result.setResult(obj);
|
||||
result.setSuccess(true);
|
||||
result.setCode(200);
|
||||
|
||||
// 7.是否允许同一账号多地同时登录(APP端登录,踢掉之前的APP端登录)
|
||||
handleSingleSignOn(username, token, CommonConstant.CLIENT_TYPE_APP);
|
||||
|
||||
// 8.登录成功记录日志
|
||||
baseCommonService.addLog("用户名: " + username + ",登录成功[移动端]!", CommonConstant.LOG_TYPE_1, null);
|
||||
return result;
|
||||
}
|
||||
@ -818,11 +864,9 @@ public class LoginController {
|
||||
result.setSuccess(false);
|
||||
return result;
|
||||
}
|
||||
//验证码5分钟内有效
|
||||
//update-begin---author:wangshuai---date:2025-07-15---for:【issues/8567】严重:修改密码存在水平越权问题。---
|
||||
//【issues/8567】严重:修改密码存在水平越权问题
|
||||
obj.put("username",username);
|
||||
redisUtil.set(redisKey, obj.toJSONString(), 300);
|
||||
//update-end---author:wangshuai---date:2025-07-15---for:【issues/8567】严重:修改密码存在水平越权问题。---
|
||||
result.setSuccess(true);
|
||||
} catch (ClientException e) {
|
||||
e.printStackTrace();
|
||||
@ -857,5 +901,43 @@ public class LoginController {
|
||||
redisUtil.removeAll(realKey);
|
||||
return Result.ok();
|
||||
}
|
||||
/**
|
||||
* 登录获取用户部门信息
|
||||
*
|
||||
* @param jsonObject
|
||||
* @return
|
||||
*/
|
||||
@IgnoreAuth
|
||||
@RequestMapping(value = "/loginGetUserDeparts", method = RequestMethod.POST)
|
||||
public Result<JSONObject> loginGetUserDeparts(@RequestBody JSONObject jsonObject, HttpServletRequest request){
|
||||
return sysUserService.loginGetUserDeparts(jsonObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验验证码工具方法,校验失败直接返回Result,校验通过返回realKey
|
||||
*/
|
||||
private String validateCaptcha(SysLoginModel sysLoginModel, Result<JSONObject> result) {
|
||||
// 判断是否启用登录验证码校验
|
||||
if (jeecgBaseConfig.getFirewall() != null && Boolean.FALSE.equals(jeecgBaseConfig.getFirewall().getEnableLoginCaptcha())) {
|
||||
log.warn("关闭了登录验证码校验,跳过验证码校验!");
|
||||
return "LoginWithoutVerifyCode";
|
||||
}
|
||||
|
||||
String captcha = sysLoginModel.getCaptcha();
|
||||
if (captcha == null) {
|
||||
result.error500("验证码无效");
|
||||
return null;
|
||||
}
|
||||
String lowerCaseCaptcha = captcha.toLowerCase();
|
||||
String keyPrefix = Md5Util.md5Encode(sysLoginModel.getCheckKey() + jeecgBaseConfig.getSignatureSecret(), "utf-8");
|
||||
String realKey = keyPrefix + lowerCaseCaptcha;
|
||||
Object checkCode = redisUtil.get(realKey);
|
||||
if (checkCode == null || !checkCode.toString().equals(lowerCaseCaptcha)) {
|
||||
log.warn("验证码错误,key= {} , Ui checkCode= {}, Redis checkCode = {}", sysLoginModel.getCheckKey(), lowerCaseCaptcha, checkCode);
|
||||
result.error500("验证码错误");
|
||||
result.setCode(HttpStatus.PRECONDITION_FAILED.value());
|
||||
return null;
|
||||
}
|
||||
return realKey;
|
||||
}
|
||||
}
|
||||
@ -9,6 +9,7 @@ import com.jeecg.dingtalk.api.core.response.Response;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.jeecg.common.api.dto.PushMessageDTO;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.config.TenantContext;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
@ -49,10 +50,7 @@ import jakarta.annotation.Resource;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.SynchronousQueue;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
@ -100,8 +98,8 @@ public class SysAnnouncementController {
|
||||
/**
|
||||
* 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>());
|
||||
public static ExecutorService cachedThreadPool = new ShiroThreadPoolExecutor(0, 1024,60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>());
|
||||
public static ExecutorService completeNoteThreadPool = new ShiroThreadPoolExecutor(0, 1024,60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>());
|
||||
|
||||
/**
|
||||
* 分页列表查询
|
||||
@ -141,10 +139,9 @@ public class SysAnnouncementController {
|
||||
public Result<SysAnnouncement> add(@RequestBody SysAnnouncement sysAnnouncement) {
|
||||
Result<SysAnnouncement> result = new Result<SysAnnouncement>();
|
||||
try {
|
||||
// update-begin-author:liusq date:20210804 for:标题处理xss攻击的问题
|
||||
// 代码逻辑说明: 标题处理xss攻击的问题
|
||||
String title = XssUtils.scriptXss(sysAnnouncement.getTitile());
|
||||
sysAnnouncement.setTitile(title);
|
||||
// update-end-author:liusq date:20210804 for:标题处理xss攻击的问题
|
||||
sysAnnouncement.setDelFlag(CommonConstant.DEL_FLAG_0.toString());
|
||||
//未发布
|
||||
sysAnnouncement.setSendStatus(CommonSendStatus.UNPUBLISHED_STATUS_0);
|
||||
@ -173,10 +170,9 @@ public class SysAnnouncementController {
|
||||
if(sysAnnouncementEntity==null) {
|
||||
result.error500("未找到对应实体");
|
||||
}else {
|
||||
// update-begin-author:liusq date:20210804 for:标题处理xss攻击的问题
|
||||
// 代码逻辑说明: 标题处理xss攻击的问题
|
||||
String title = XssUtils.scriptXss(sysAnnouncement.getTitile());
|
||||
sysAnnouncement.setTitile(title);
|
||||
// update-end-author:liusq date:20210804 for:标题处理xss攻击的问题
|
||||
sysAnnouncement.setNoticeType(NoticeTypeEnum.NOTICE_TYPE_SYSTEM.getValue());
|
||||
boolean ok = sysAnnouncementService.upDateAnnouncement(sysAnnouncement);
|
||||
//TODO 返回false说明什么?
|
||||
@ -306,6 +302,13 @@ public class SysAnnouncementController {
|
||||
obj.put(WebsocketConst.MSG_TXT, sysAnnouncement.getTitile());
|
||||
obj.put(CommonConstant.NOTICE_TYPE, sysAnnouncement.getNoticeType());
|
||||
webSocket.sendMessage(obj.toJSONString());
|
||||
//update-begin-author:liusq---date:2025-11-13--for: JHHB-827 【审批消息】移动端需要有推送 -全推送
|
||||
PushMessageDTO pushMessageDTO = new PushMessageDTO();
|
||||
pushMessageDTO.setTitle(sysAnnouncement.getTitile());
|
||||
pushMessageDTO.setPushType(CommonConstant.MSG_TYPE_ALL);
|
||||
pushMessageDTO.setContent(sysAnnouncement.getMsgAbstract());
|
||||
sysBaseApi.uniPushMsgToUser(pushMessageDTO);
|
||||
//update-begin-author:liusq---date:2025-11-13--for: JHHB-827 【审批消息】移动端需要有推送 -全推送
|
||||
}else {
|
||||
// 2.插入用户通告阅读标记表记录
|
||||
String userId = sysAnnouncement.getUserIds();
|
||||
@ -318,6 +321,13 @@ public class SysAnnouncementController {
|
||||
obj.put(WebsocketConst.MSG_TXT, sysAnnouncement.getTitile());
|
||||
obj.put(CommonConstant.NOTICE_TYPE, sysAnnouncement.getNoticeType());
|
||||
webSocket.sendMessage(userIds, obj.toJSONString());
|
||||
//update-begin-author:liusq---date:2025-11-13--for: JHHB-827 【审批消息】移动端需要有推送
|
||||
PushMessageDTO pushMessageDTO = new PushMessageDTO();
|
||||
pushMessageDTO.setTitle(sysAnnouncement.getTitile());
|
||||
pushMessageDTO.setUserIds(Arrays.asList(userIds));
|
||||
pushMessageDTO.setContent(sysAnnouncement.getMsgAbstract());
|
||||
sysBaseApi.uniPushMsgToUser(pushMessageDTO);
|
||||
//update-begin-author:liusq---date:2025-11-13--for: JHHB-827 【审批消息】移动端需要有推送
|
||||
}
|
||||
try {
|
||||
// 同步企业微信、钉钉的消息通知
|
||||
@ -382,11 +392,9 @@ public class SysAnnouncementController {
|
||||
String userId = sysUser.getId();
|
||||
|
||||
|
||||
//update-begin---author:scott ---date:2024-05-11 for:【性能优化】优化系统通知,只查近2个月的通知---
|
||||
// 获取上个月的第一天(只查近两个月的通知)
|
||||
Date lastMonthStartDay = DateRangeUtils.getLastMonthStartDay();
|
||||
log.info("-----查询近两个月收到的未读通知-----,近2月的第一天:{}", lastMonthStartDay);
|
||||
//update-end---author:scott ---date::2024-05-11 for:【性能优化】优化系统通知,只查近2个月的通知---
|
||||
|
||||
// //补推送数据(用户和通知的关系表)
|
||||
// completeNoteThreadPool.execute(()->{
|
||||
@ -428,8 +436,8 @@ public class SysAnnouncementController {
|
||||
|
||||
// 获取上个月的第一天(只查近两个月的通知)
|
||||
Date lastMonthStartDay = DateRangeUtils.getLastMonthStartDay();
|
||||
log.info(" ------查询近两个月收到的未读通知消息数量------,近2月的第一天:{}", lastMonthStartDay);
|
||||
//update-begin---author:wangshuai---date:2025-06-26---for:【QQYUN-12162】OA项目改造,系统重消息拆分,目前消息都在一起 需按分类进行拆分---
|
||||
log.debug(" ------查询近两个月收到的未读通知消息数量------,近2月的第一天:{}", lastMonthStartDay);
|
||||
// 代码逻辑说明: 【QQYUN-12162】OA项目改造,系统重消息拆分,目前消息都在一起 需按分类进行拆分---
|
||||
Map<String,Integer> unreadMessageCount = new HashMap<>();
|
||||
//系统消息数量
|
||||
Integer systemCount = sysAnnouncementService.getUnreadMessageCountByUserId(userId, lastMonthStartDay, NoticeTypeEnum.NOTICE_TYPE_SYSTEM.getValue());
|
||||
@ -445,7 +453,6 @@ public class SysAnnouncementController {
|
||||
unreadMessageCount.put("planCount",planCount);
|
||||
Integer count = systemCount + flowCount + fileCount + planCount;
|
||||
unreadMessageCount.put("count",count);
|
||||
//update-end---author:wangshuai---date:2025-06-26---for:【QQYUN-12162】OA项目改造,系统重消息拆分,目前消息都在一起 需按分类进行拆分---
|
||||
return Result.ok(unreadMessageCount);
|
||||
}
|
||||
|
||||
@ -649,7 +656,7 @@ public class SysAnnouncementController {
|
||||
// 4、性能统计耗时
|
||||
long calEndTime = System.currentTimeMillis(); // 记录结束时间
|
||||
long duration = calEndTime - calStartTime; // 计算耗时
|
||||
log.info("耗时:" + duration + " 毫秒");
|
||||
//System.out.println("耗时:" + duration + " 毫秒");
|
||||
|
||||
return Result.ok(ls);
|
||||
}
|
||||
@ -667,7 +674,7 @@ public class SysAnnouncementController {
|
||||
// step.1 此接口过慢,可以采用缓存一小时方案
|
||||
String keyString = String.format(CommonConstant.CACHE_KEY_USER_LAST_ANNOUNT_TIME_1HOUR + "_" + noticeType, userId);
|
||||
if (redisTemplate.hasKey(keyString)) {
|
||||
log.info("[SysAnnouncementSend Redis] 通过Redis缓存查询用户最后一次收到系统通知时间,userId={}", userId);
|
||||
log.debug("[SysAnnouncementSend Redis] 通过Redis缓存查询用户最后一次收到系统通知时间,userId={}", userId);
|
||||
Page<SysAnnouncementSend> pageList = (Page<SysAnnouncementSend>) redisTemplate.opsForValue().get(keyString);
|
||||
result.setSuccess(true);
|
||||
result.setResult(pageList);
|
||||
|
||||
@ -138,9 +138,10 @@ public class SysAnnouncementSendController {
|
||||
@DeleteMapping(value = "/delete")
|
||||
public Result<SysAnnouncementSend> delete(@RequestParam(name="id",required=true) String id) {
|
||||
Result<SysAnnouncementSend> result = new Result<SysAnnouncementSend>();
|
||||
SysAnnouncementSend sysAnnouncementSend = sysAnnouncementSendService.getById(id);
|
||||
if(sysAnnouncementSend==null) {
|
||||
result.error500("未找到对应实体");
|
||||
//根据用户id和通告阅读表的id获取当前用户已阅读的数量
|
||||
long count = sysAnnouncementSendService.getReadCountByUserId(id);
|
||||
if(0 == count) {
|
||||
result.error500("删除失败,该数据不存在或尚未标记为“已读”");
|
||||
}else {
|
||||
boolean ok = sysAnnouncementSendService.removeById(id);
|
||||
if(ok) {
|
||||
@ -162,8 +163,8 @@ public class SysAnnouncementSendController {
|
||||
if(ids==null || "".equals(ids.trim())) {
|
||||
result.error500("参数不识别!");
|
||||
}else {
|
||||
this.sysAnnouncementSendService.removeByIds(Arrays.asList(ids.split(",")));
|
||||
result.success("删除成功!");
|
||||
this.sysAnnouncementSendService.deleteBatchByIds(ids);
|
||||
result.success("已阅读的消息删除成功!");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -200,10 +201,9 @@ public class SysAnnouncementSendController {
|
||||
LambdaUpdateWrapper<SysAnnouncementSend> updateWrapper = new UpdateWrapper().lambda();
|
||||
updateWrapper.set(SysAnnouncementSend::getReadFlag, CommonConstant.HAS_READ_FLAG);
|
||||
updateWrapper.set(SysAnnouncementSend::getReadTime, new Date());
|
||||
//update-begin-author:liusq date:2023-09-04 for:系统模块存在的sql漏洞写法
|
||||
// 代码逻辑说明: 系统模块存在的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);
|
||||
@ -225,14 +225,13 @@ public class SysAnnouncementSendController {
|
||||
announcementSendModel.setUserId(userId);
|
||||
announcementSendModel.setPageNo((pageNo-1)*pageSize);
|
||||
announcementSendModel.setPageSize(pageSize);
|
||||
//update-begin---author:wangshuai---date:2024-06-11---for:【TV360X-545】我的消息列表不能通过时间范围查询---
|
||||
// 代码逻辑说明: 【TV360X-545】我的消息列表不能通过时间范围查询---
|
||||
if(StringUtils.isNotEmpty(announcementSendModel.getSendTimeBegin())){
|
||||
announcementSendModel.setSendTimeBegin(announcementSendModel.getSendTimeBegin() + " 00:00:00");
|
||||
}
|
||||
if(StringUtils.isNotEmpty(announcementSendModel.getSendTimeBegin())){
|
||||
announcementSendModel.setSendTimeEnd(announcementSendModel.getSendTimeEnd() + " 23:59:59");
|
||||
}
|
||||
//update-end---author:wangshuai---date:2024-06-11---for:【TV360X-545】我的消息列表不能通过时间范围查询---
|
||||
Page<AnnouncementSendModel> pageList = new Page<AnnouncementSendModel>(pageNo,pageSize);
|
||||
pageList = sysAnnouncementSendService.getMyAnnouncementSendPage(pageList, announcementSendModel);
|
||||
result.setResult(pageList);
|
||||
@ -275,4 +274,25 @@ public class SysAnnouncementSendController {
|
||||
AnnouncementSendModel model = sysAnnouncementSendService.getOne(sendId);
|
||||
return Result.ok(model);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据业务类型和ID修改阅读状态
|
||||
* @param busType
|
||||
* @return
|
||||
*/
|
||||
@GetMapping(value = "/updateSysAnnounReadFlag")
|
||||
public Result<AnnouncementSendModel> updateSysAnnounReadFlag(
|
||||
@RequestParam(name="busId",required=true) String busId,
|
||||
@RequestParam(name="busType",required=false) String busType) {
|
||||
//更新阅读状态
|
||||
sysAnnouncementSendService.updateReadFlagByBusId(busId,busType);
|
||||
|
||||
//刷新未读数量
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put(WebsocketConst.MSG_CMD, WebsocketConst.CMD_USER);
|
||||
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
webSocket.sendMessage(sysUser.getId(), obj.toJSONString());
|
||||
|
||||
return Result.ok();
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,6 +25,7 @@ import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||
import org.jeecgframework.poi.excel.entity.enmus.ExcelType;
|
||||
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
@ -238,7 +239,13 @@ public class SysCategoryController {
|
||||
mv.addObject(NormalExcelConstants.FILE_NAME, "分类字典列表");
|
||||
mv.addObject(NormalExcelConstants.CLASS, SysCategory.class);
|
||||
LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("分类字典列表数据", "导出人:"+user.getRealname(), "导出信息"));
|
||||
//导出支持xlsx
|
||||
mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("分类字典列表数据", "导出人:"+user.getRealname(), "导出信息", ExcelType.XSSF));
|
||||
//分类字典导出支持导出字段
|
||||
String exportFields = request.getParameter(NormalExcelConstants.EXPORT_FIELDS);
|
||||
if(oConvertUtils.isNotEmpty(exportFields)){
|
||||
mv.addObject(NormalExcelConstants.EXPORT_FIELDS, exportFields);
|
||||
}
|
||||
return mv;
|
||||
}
|
||||
|
||||
@ -265,9 +272,8 @@ public class SysCategoryController {
|
||||
params.setNeedSave(true);
|
||||
try {
|
||||
List<SysCategory> listSysCategorys = ExcelImportUtil.importExcel(file.getInputStream(), SysCategory.class, params);
|
||||
//update-begin---author:chenrui ---date:20250721 for:[issues/8612]分类字典导入bug #8612 ------------
|
||||
// 代码逻辑说明: [issues/8612]分类字典导入bug #8612 ------------
|
||||
Set<String> parentCategoryIds = new HashSet<>();
|
||||
//update-end---author:chenrui ---date:20250721 for:[issues/8612]分类字典导入bug #8612 ------------
|
||||
//按照编码长度排序
|
||||
Collections.sort(listSysCategorys);
|
||||
log.info("排序后的list====>",listSysCategorys);
|
||||
@ -281,9 +287,7 @@ public class SysCategoryController {
|
||||
log.info("pId====>",pId);
|
||||
if(StringUtils.isNotBlank(pId)){
|
||||
sysCategoryExcel.setPid(pId);
|
||||
//update-begin---author:chenrui ---date:20250721 for:[issues/8612]分类字典导入bug #8612 ------------
|
||||
parentCategoryIds.add(pId);
|
||||
//update-end---author:chenrui ---date:20250721 for:[issues/8612]分类字典导入bug #8612 ------------
|
||||
}
|
||||
}else{
|
||||
sysCategoryExcel.setPid("0");
|
||||
@ -304,7 +308,7 @@ public class SysCategoryController {
|
||||
}
|
||||
}
|
||||
}
|
||||
//update-begin---author:chenrui ---date:20250721 for:[issues/8612]分类字典导入bug #8612 ------------
|
||||
// 代码逻辑说明: [issues/8612]分类字典导入bug #8612 ------------
|
||||
if(oConvertUtils.isObjectNotEmpty(parentCategoryIds)){
|
||||
for (String parentCategoryId : parentCategoryIds) {
|
||||
SysCategory parentCategory = sysCategoryService.getById(parentCategoryId);
|
||||
@ -314,7 +318,6 @@ public class SysCategoryController {
|
||||
}
|
||||
}
|
||||
}
|
||||
//update-end---author:chenrui ---date:20250721 for:[issues/8612]分类字典导入bug #8612 ------------
|
||||
} catch (Exception e) {
|
||||
errorMessage.add("发生异常:" + e.getMessage());
|
||||
log.error(e.getMessage(), e);
|
||||
@ -338,12 +341,11 @@ public class SysCategoryController {
|
||||
public Result<SysCategory> loadOne(@RequestParam(name="field") String field,@RequestParam(name="val") String val) {
|
||||
Result<SysCategory> result = new Result<SysCategory>();
|
||||
try {
|
||||
//update-begin-author:taoyan date:2022-5-6 for: issues/3663 sql注入问题
|
||||
// 代码逻辑说明: issues/3663 sql注入问题
|
||||
boolean isClassField = ReflectHelper.isClassField(field, SysCategory.class);
|
||||
if (!isClassField) {
|
||||
return Result.error("字段无效,请检查!");
|
||||
}
|
||||
//update-end-author:taoyan date:2022-5-6 for: issues/3663 sql注入问题
|
||||
QueryWrapper<SysCategory> query = new QueryWrapper<SysCategory>();
|
||||
query.eq(field, val);
|
||||
List<SysCategory> ls = this.sysCategoryService.list(query);
|
||||
|
||||
@ -87,14 +87,13 @@ public class SysDataLogController {
|
||||
QueryWrapper<SysDataLog> queryWrapper = new QueryWrapper<SysDataLog>();
|
||||
queryWrapper.eq("data_table", dataTable);
|
||||
queryWrapper.eq("data_id", dataId);
|
||||
//update-begin-author:taoyan date:2022-7-26 for: 新增查询条件-type
|
||||
// 代码逻辑说明: 新增查询条件-type
|
||||
String type = req.getParameter("type");
|
||||
if (oConvertUtils.isNotEmpty(type)) {
|
||||
queryWrapper.eq("type", type);
|
||||
}
|
||||
// 按时间倒序排
|
||||
queryWrapper.orderByDesc("create_time");
|
||||
//update-end-author:taoyan date:2022-7-26 for:新增查询条件-type
|
||||
|
||||
List<SysDataLog> list = service.list(queryWrapper);
|
||||
if(list==null||list.size()<=0) {
|
||||
|
||||
@ -114,14 +114,13 @@ public class SysDataSourceController extends JeecgController<SysDataSource, ISys
|
||||
@Operation(summary = "多数据源管理-添加")
|
||||
@PostMapping(value = "/add")
|
||||
public Result<?> add(@RequestBody SysDataSource sysDataSource) {
|
||||
//update-begin-author:taoyan date:2022-8-10 for: jdbc连接地址漏洞问题
|
||||
// 代码逻辑说明: jdbc连接地址漏洞问题
|
||||
try {
|
||||
JdbcSecurityUtil.validate(sysDataSource.getDbUrl());
|
||||
}catch (JeecgBootException e){
|
||||
log.error(e.toString());
|
||||
return Result.error("操作失败:" + e.getMessage());
|
||||
}
|
||||
//update-end-author:taoyan date:2022-8-10 for: jdbc连接地址漏洞问题
|
||||
return sysDataSourceService.saveDataSource(sysDataSource);
|
||||
}
|
||||
|
||||
@ -135,14 +134,13 @@ public class SysDataSourceController extends JeecgController<SysDataSource, ISys
|
||||
@Operation(summary = "多数据源管理-编辑")
|
||||
@RequestMapping(value = "/edit", method ={RequestMethod.PUT, RequestMethod.POST})
|
||||
public Result<?> edit(@RequestBody SysDataSource sysDataSource) {
|
||||
//update-begin-author:taoyan date:2022-8-10 for: jdbc连接地址漏洞问题
|
||||
// 代码逻辑说明: jdbc连接地址漏洞问题
|
||||
try {
|
||||
JdbcSecurityUtil.validate(sysDataSource.getDbUrl());
|
||||
} catch (JeecgBootException e) {
|
||||
log.error(e.toString());
|
||||
return Result.error("操作失败:" + e.getMessage());
|
||||
}
|
||||
//update-end-author:taoyan date:2022-8-10 for: jdbc连接地址漏洞问题
|
||||
return sysDataSourceService.editDataSource(sysDataSource);
|
||||
}
|
||||
|
||||
|
||||
@ -2,10 +2,13 @@ package org.jeecg.modules.system.controller;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
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.config.TenantContext;
|
||||
import org.jeecg.common.constant.CacheConstant;
|
||||
@ -24,6 +27,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.SysChangeDepartVo;
|
||||
import org.jeecg.modules.system.vo.SysDepartExportVo;
|
||||
import org.jeecg.modules.system.vo.SysPositionSelectTreeVo;
|
||||
import org.jeecg.modules.system.vo.lowapp.ExportDepartVo;
|
||||
@ -31,6 +35,7 @@ import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||
import org.jeecgframework.poi.excel.entity.enmus.ExcelType;
|
||||
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
@ -78,13 +83,12 @@ public class SysDepartController {
|
||||
LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
try {
|
||||
if(oConvertUtils.isNotEmpty(user.getUserIdentity()) && user.getUserIdentity().equals( CommonConstant.USER_IDENTITY_2 )){
|
||||
//update-begin--Author:liusq Date:20210624 for:部门查询ids为空后的前端显示问题 issues/I3UD06
|
||||
// 代码逻辑说明: 部门查询ids为空后的前端显示问题 issues/I3UD06
|
||||
String departIds = user.getDepartIds();
|
||||
if(StringUtils.isNotBlank(departIds)){
|
||||
List<SysDepartTreeModel> list = sysDepartService.queryMyDeptTreeList(departIds);
|
||||
result.setResult(list);
|
||||
}
|
||||
//update-end--Author:liusq Date:20210624 for:部门查询ids为空后的前端显示问题 issues/I3UD06
|
||||
result.setMessage(CommonConstant.USER_IDENTITY_2.toString());
|
||||
result.setSuccess(true);
|
||||
}else{
|
||||
@ -382,7 +386,6 @@ public class SysDepartController {
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------
|
||||
|
||||
//update-begin---author:wangshuai---date:2023-10-19---for:【QQYUN-5482】系统的部门导入导出也可以改成敲敲云模式的部门路径---
|
||||
//// Step.1 组装查询条件
|
||||
//QueryWrapper<SysDepart> queryWrapper = QueryGenerator.initQueryWrapper(sysDepart, request.getParameterMap());
|
||||
//Step.1 AutoPoi 导出Excel
|
||||
@ -403,9 +406,8 @@ public class SysDepartController {
|
||||
}
|
||||
//step.2 组装导出数据
|
||||
Integer tenantId = sysDepart == null ? null : sysDepart.getTenantId();
|
||||
//update-begin---author:wangshuai---date:2024-07-05---for:【TV360X-1671】部门管理不支持选中的记录导出---
|
||||
// 代码逻辑说明: 【TV360X-1671】部门管理不支持选中的记录导出---
|
||||
List<SysDepartExportVo> sysDepartExportVos = sysDepartService.getExportDepart(tenantId,idList);
|
||||
//update-end---author:wangshuai---date:2024-07-05---for:【TV360X-1671】部门管理不支持选中的记录导出---
|
||||
//导出文件名称
|
||||
mv.addObject(NormalExcelConstants.FILE_NAME, "部门列表");
|
||||
mv.addObject(NormalExcelConstants.CLASS, SysDepartExportVo.class);
|
||||
@ -414,12 +416,11 @@ public class SysDepartController {
|
||||
"1、标题为第三行,部门路径和部门名称的标题不允许修改,否则会匹配失败;第四行为数据填写范围;\n" +
|
||||
"2、部门路径用英文字符/分割,部门名称为部门路径的最后一位;\n" +
|
||||
"3、部门从一级名称开始创建,如果有同级就需要多添加一行,如研发部/研发一部;研发部/研发二部;\n" +
|
||||
"4、自定义的部门编码需要满足规则才能导入。如一级部门编码为A01,那么子部门为A01A01,同级子部门为A01A02,编码固定为三位,首字母为A-Z,后两位为数字0-99,依次递增;", "导出人:" + user.getRealname(), "导出信息");
|
||||
"4、自定义的部门编码需要满足规则才能导入。如一级部门编码为A01,那么子部门为A01A01,同级子部门为A01A02,编码固定为三位,首字母为A-Z,后两位为数字0-99,依次递增;", "导出人:" + user.getRealname(), "导出信息", ExcelType.XSSF);
|
||||
exportParams.setTitleHeight((short)70);
|
||||
exportParams.setStyle(ExcelExportSysUserStyle.class);
|
||||
mv.addObject(NormalExcelConstants.PARAMS, exportParams);
|
||||
mv.addObject(NormalExcelConstants.DATA_LIST, sysDepartExportVos);
|
||||
//update-end---author:wangshuai---date:2023-10-19---for:【QQYUN-5482】系统的部门导入导出也可以改成敲敲云模式的部门路径---
|
||||
|
||||
return mv;
|
||||
}
|
||||
@ -450,7 +451,6 @@ public class SysDepartController {
|
||||
params.setHeadRows(1);
|
||||
params.setNeedSave(true);
|
||||
try {
|
||||
//update-begin---author:wangshuai---date:2023-10-20---for: 注释掉原来的导入部门的逻辑---
|
||||
// // orgCode编码长度
|
||||
// int codeLength = YouBianCodeUtil.ZHANWEI_LENGTH;
|
||||
// listSysDeparts = ExcelImportUtil.importExcel(file.getInputStream(), SysDepart.class, params);
|
||||
@ -484,24 +484,18 @@ public class SysDepartController {
|
||||
// }else{
|
||||
// sysDepart.setParentId("");
|
||||
// }
|
||||
// //update-begin---author:liusq Date:20210223 for:批量导入部门以后,不能追加下一级部门 #2245------------
|
||||
// sysDepart.setOrgType(sysDepart.getOrgCode().length()/codeLength+"");
|
||||
// //update-end---author:liusq Date:20210223 for:批量导入部门以后,不能追加下一级部门 #2245------------
|
||||
// sysDepart.setDelFlag(CommonConstant.DEL_FLAG_0.toString());
|
||||
// //update-begin---author:wangshuai ---date:20220105 for:[JTC-363]部门导入 机构类别没有时导入失败,赋默认值------------
|
||||
// if(oConvertUtils.isEmpty(sysDepart.getOrgCategory())){
|
||||
// sysDepart.setOrgCategory("1");
|
||||
// }
|
||||
// //update-end---author:wangshuai ---date:20220105 for:[JTC-363]部门导入 机构类别没有时导入失败,赋默认值------------
|
||||
// ImportExcelUtil.importDateSaveOne(sysDepart, ISysDepartService.class, errorMessageList, num, CommonConstant.SQL_INDEX_UNIQ_DEPART_ORG_CODE);
|
||||
// num++;
|
||||
// }
|
||||
//update-end---author:wangshuai---date:2023-10-20---for: 注释掉原来的导入部门的逻辑---
|
||||
|
||||
//update-begin---author:wangshuai---date:2023-10-19---for:【QQYUN-5482】系统的部门导入导出也可以改成敲敲云模式的部门路径---
|
||||
// 代码逻辑说明: 【QQYUN-5482】系统的部门导入导出也可以改成敲敲云模式的部门路径---
|
||||
listSysDeparts = ExcelImportUtil.importExcel(file.getInputStream(), SysDepartExportVo.class, params);
|
||||
sysDepartService.importSysDepart(listSysDeparts,errorMessageList);
|
||||
//update-end---author:wangshuai---date:2023-10-19---for:【QQYUN-5482】系统的部门导入导出也可以改成敲敲云模式的部门路径---
|
||||
|
||||
//清空部门缓存
|
||||
List<String> keys3 = redisUtil.scan(CacheConstant.SYS_DEPARTS_CACHE + "*");
|
||||
@ -757,4 +751,45 @@ public class SysDepartController {
|
||||
String departName = sysDepartService.getDepartPathNameByOrgCode(orgCode, depId);
|
||||
return Result.OK(departName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据部门id获取部门下的岗位id
|
||||
*
|
||||
* @param depIds 当前选择的公司、子公司、部门id
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/getDepPostIdByDepId")
|
||||
public Result<Map<String, String>> getDepPostIdByDepId(@RequestParam(name = "depIds") String depIds) {
|
||||
String departIds = sysDepartService.getDepPostIdByDepId(depIds);
|
||||
return Result.OK(departIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新改变后的部门数据
|
||||
*
|
||||
* @param changeDepartVo
|
||||
* @return
|
||||
*/
|
||||
@PutMapping("/updateChangeDepart")
|
||||
@RequiresPermissions("system:depart:updateChange")
|
||||
@RequiresRoles({"admin"})
|
||||
public Result<String> updateChangeDepart(@RequestBody SysChangeDepartVo changeDepartVo) {
|
||||
sysDepartService.updateChangeDepart(changeDepartVo);
|
||||
return Result.ok("调整部门位置成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取部门负责人
|
||||
*
|
||||
* @param departId
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/getDepartmentHead")
|
||||
public Result<IPage<SysUser>> getDepartmentHead(@RequestParam(name = "departId") String departId,
|
||||
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
||||
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize){
|
||||
Page<SysUser> page = new Page<>(pageNo, pageSize);
|
||||
IPage<SysUser> pageList = sysDepartService.getDepartmentHead(departId,page);
|
||||
return Result.OK(pageList);
|
||||
}
|
||||
}
|
||||
|
||||
@ -259,10 +259,9 @@ public class SysDepartPermissionController extends JeecgController<SysDepartPerm
|
||||
String lastPermissionIds = json.getString("lastpermissionIds");
|
||||
this.sysDepartRolePermissionService.saveDeptRolePermission(roleId, permissionIds, lastPermissionIds);
|
||||
result.success("保存成功!");
|
||||
//update-begin---author:wangshuai ---date:20220316 for:[VUEN-234]部门角色授权添加敏感日志------------
|
||||
// 代码逻辑说明: [VUEN-234]部门角色授权添加敏感日志------------
|
||||
LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
baseCommonService.addLog("修改部门角色ID:"+roleId+"的权限配置,操作人: " +loginUser.getUsername() ,CommonConstant.LOG_TYPE_2, 2);
|
||||
//update-end---author:wangshuai ---date:20220316 for:[VUEN-234]部门角色授权添加敏感日志------------
|
||||
log.info("======部门角色授权成功=====耗时:" + (System.currentTimeMillis() - start) + "毫秒");
|
||||
} catch (Exception e) {
|
||||
result.error500("授权失败!");
|
||||
|
||||
@ -92,7 +92,7 @@ public class SysDepartRoleController extends JeecgController<SysDepartRole, ISys
|
||||
// queryWrapper.in("depart_id",deptIds);
|
||||
|
||||
//我的部门,选中部门只能看当前部门下的角色
|
||||
//update-begin---author:chenrui ---date:20250107 for:[QQYUN-10775]验证码可以复用 #7674------------
|
||||
// 代码逻辑说明: [QQYUN-10775]验证码可以复用 #7674------------
|
||||
if(oConvertUtils.isNotEmpty(deptId)){
|
||||
queryWrapper.eq("depart_id",deptId);
|
||||
IPage<SysDepartRole> pageList = sysDepartRoleService.page(page, queryWrapper);
|
||||
@ -100,7 +100,6 @@ public class SysDepartRoleController extends JeecgController<SysDepartRole, ISys
|
||||
}else{
|
||||
return Result.ok(null);
|
||||
}
|
||||
//update-end---author:chenrui ---date:20250107 for:[QQYUN-10775]验证码可以复用 #7674------------
|
||||
}
|
||||
|
||||
/**
|
||||
@ -202,10 +201,9 @@ public class SysDepartRoleController extends JeecgController<SysDepartRole, ISys
|
||||
String oldRoleId = json.getString("oldRoleId");
|
||||
String userId = json.getString("userId");
|
||||
departRoleUserService.deptRoleUserAdd(userId,newRoleId,oldRoleId);
|
||||
//update-begin---author:wangshuai ---date:20220316 for:[VUEN-234]部门角色分配添加敏感日志------------
|
||||
// 代码逻辑说明: [VUEN-234]部门角色分配添加敏感日志------------
|
||||
LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
baseCommonService.addLog("给部门用户ID:"+userId+"分配角色,操作人: " +loginUser.getUsername() ,CommonConstant.LOG_TYPE_2, 2);
|
||||
//update-end---author:wangshuai ---date:20220316 for:[VUEN-234]部门角色分配添加敏感日志------------
|
||||
return Result.ok("添加成功!");
|
||||
}
|
||||
|
||||
|
||||
@ -24,6 +24,7 @@ import org.jeecg.common.system.vo.LoginUser;
|
||||
import org.jeecg.common.util.*;
|
||||
import org.jeecg.config.mybatis.MybatisPlusSaasConfig;
|
||||
import org.jeecg.config.shiro.ShiroRealm;
|
||||
import org.jeecg.modules.system.constant.DefIndexConst;
|
||||
import org.jeecg.modules.system.entity.SysDict;
|
||||
import org.jeecg.modules.system.entity.SysDictItem;
|
||||
import org.jeecg.modules.system.model.SysDictTree;
|
||||
@ -37,6 +38,7 @@ import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||
import org.jeecgframework.poi.excel.entity.enmus.ExcelType;
|
||||
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -182,7 +184,7 @@ public class SysDictController {
|
||||
*/
|
||||
@RequestMapping(value = "/getDictItems/{dictCode}", method = RequestMethod.GET)
|
||||
public Result<List<DictModel>> getDictItems(@PathVariable("dictCode") String dictCode, @RequestParam(value = "sign",required = false) String sign,HttpServletRequest request) {
|
||||
log.info(" dictCode : "+ dictCode);
|
||||
log.debug(" dictCode : "+ dictCode);
|
||||
Result<List<DictModel>> result = new Result<List<DictModel>>();
|
||||
try {
|
||||
List<DictModel> ls = sysDictService.getDictItems(dictCode);
|
||||
@ -215,7 +217,7 @@ public class SysDictController {
|
||||
@RequestParam(name = "pageNo", defaultValue = "1", required = false) Integer pageNo,
|
||||
@RequestParam(name = "pageSize", defaultValue = "10", required = false) Integer pageSize) {
|
||||
|
||||
//update-begin-author:taoyan date:2023-5-22 for: /issues/4905 因为中括号(%5)的问题导致的 表单生成器字段配置时,选择关联字段,在进行高级配置时,无法加载数据库列表,提示 Sgin签名校验错误! #4905 RouteToRequestUrlFilter
|
||||
// 代码逻辑说明: /issues/4905 因为中括号(%5)的问题导致的 表单生成器字段配置时,选择关联字段,在进行高级配置时,无法加载数据库列表,提示 Sgin签名校验错误! #4905 RouteToRequestUrlFilter
|
||||
if(keyword!=null && keyword.indexOf("%5")>=0){
|
||||
try {
|
||||
keyword = URLDecoder.decode(keyword, "UTF-8");
|
||||
@ -223,7 +225,6 @@ public class SysDictController {
|
||||
log.error("下拉搜索关键字解码失败", e);
|
||||
}
|
||||
}
|
||||
//update-end-author:taoyan date:2023-5-22 for: /issues/4905 因为中括号(%5)的问题导致的 表单生成器字段配置时,选择关联字段,在进行高级配置时,无法加载数据库列表,提示 Sgin签名校验错误! #4905
|
||||
|
||||
log.info(" 加载字典表数据,加载关键字: "+ keyword);
|
||||
Result<List<DictModel>> result = new Result<List<DictModel>>();
|
||||
@ -490,7 +491,7 @@ public class SysDictController {
|
||||
// redisTemplate.delete(keys6);
|
||||
// redisTemplate.delete(keys7);
|
||||
|
||||
//update-begin-author:liusq date:20230404 for: [issue/4358]springCache中的清除缓存的操作使用了“keys”
|
||||
// 代码逻辑说明: [issue/4358]springCache中的清除缓存的操作使用了“keys”
|
||||
redisUtil.removeAll(CacheConstant.SYS_DICT_CACHE);
|
||||
redisUtil.removeAll(CacheConstant.SYS_ENABLE_DICT_CACHE);
|
||||
redisUtil.removeAll(CacheConstant.SYS_DICT_TABLE_CACHE);
|
||||
@ -499,15 +500,15 @@ public class SysDictController {
|
||||
redisUtil.removeAll(CacheConstant.SYS_DEPART_IDS_CACHE);
|
||||
redisUtil.removeAll("jmreport:cache:dict");
|
||||
redisUtil.removeAll("jmreport:cache:dictTable");
|
||||
//update-end-author:liusq date:20230404 for: [issue/4358]springCache中的清除缓存的操作使用了“keys”
|
||||
|
||||
//update-begin---author:scott ---date:2024-06-18 for:【TV360X-1320】分配权限必须退出重新登录才生效,造成很多用户困扰---
|
||||
// 清除当前用户的授权缓存信息
|
||||
Subject currentUser = SecurityUtils.getSubject();
|
||||
if (currentUser.isAuthenticated()) {
|
||||
shiroRealm.clearCache(currentUser.getPrincipals());
|
||||
}
|
||||
//update-end---author:scott ---date::2024-06-18 for:【TV360X-1320】分配权限必须退出重新登录才生效,造成很多用户困扰---
|
||||
|
||||
// 清空默认首页缓存(开源版和商业版会串)
|
||||
redisUtil.del(DefIndexConst.CACHE_KEY + "::" + DefIndexConst.DEF_INDEX_ALL);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -551,7 +552,7 @@ public class SysDictController {
|
||||
mv.addObject(NormalExcelConstants.CLASS, SysDictPage.class);
|
||||
// 自定义表格参数
|
||||
LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("数据字典列表", "导出人:"+user.getRealname(), "数据字典"));
|
||||
mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("数据字典列表", "导出人:"+user.getRealname(), "数据字典", ExcelType.XSSF));
|
||||
// 导出数据列表
|
||||
mv.addObject(NormalExcelConstants.DATA_LIST, pageList);
|
||||
return mv;
|
||||
@ -594,21 +595,19 @@ public class SysDictController {
|
||||
Integer integer = sysDictService.saveMain(po, list.get(i).getSysDictItemList());
|
||||
if(integer>0){
|
||||
successLines++;
|
||||
//update-begin---author:wangshuai ---date:20220211 for:[JTC-1168]如果字典项值为空,则字典项忽略导入------------
|
||||
// 代码逻辑说明: [JTC-1168]如果字典项值为空,则字典项忽略导入------------
|
||||
}else if(integer == -1){
|
||||
errorLines++;
|
||||
errorMessage.add("字典名称:" + po.getDictName() + ",对应字典列表的字典项值不能为空,忽略导入。");
|
||||
}else{
|
||||
//update-end---author:wangshuai ---date:20220211 for:[JTC-1168]如果字典项值为空,则字典项忽略导入------------
|
||||
errorLines++;
|
||||
int lineNumber = i + 1;
|
||||
//update-begin---author:wangshuai ---date:20220209 for:[JTC-1168]字典编号不能为空------------
|
||||
// 代码逻辑说明: [JTC-1168]字典编号不能为空------------
|
||||
if(oConvertUtils.isEmpty(po.getDictCode())){
|
||||
errorMessage.add("第 " + lineNumber + " 行:字典编码不能为空,忽略导入。");
|
||||
}else{
|
||||
errorMessage.add("第 " + lineNumber + " 行:字典编码已经存在,忽略导入。");
|
||||
}
|
||||
//update-end---author:wangshuai ---date:20220209 for:[JTC-1168]字典编号不能为空------------
|
||||
}
|
||||
} catch (Exception e) {
|
||||
errorLines++;
|
||||
|
||||
@ -2,17 +2,26 @@ package org.jeecg.modules.system.controller;
|
||||
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.system.base.controller.JeecgController;
|
||||
import org.jeecg.common.system.query.QueryGenerator;
|
||||
import org.jeecg.common.system.vo.LoginUser;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.config.JeecgBaseConfig;
|
||||
import org.jeecg.modules.system.entity.SysLog;
|
||||
import org.jeecg.modules.system.entity.SysRole;
|
||||
import org.jeecg.modules.system.service.ISysLogService;
|
||||
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||
import org.jeecgframework.poi.handler.inter.IExcelExportServerEnhanced;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
@ -42,6 +51,12 @@ public class SysLogController extends JeecgController<SysLog, ISysLogService> {
|
||||
@Autowired
|
||||
private ISysLogService sysLogService;
|
||||
|
||||
/**
|
||||
* for [issues/8699]AutoPoi在使用@ExcelEntity当设置show=true并且该项为null时报错
|
||||
*/
|
||||
@Resource
|
||||
private JeecgBaseConfig jeecgBaseConfig;
|
||||
|
||||
/**
|
||||
* 全部清除
|
||||
*/
|
||||
@ -72,10 +87,10 @@ public class SysLogController extends JeecgController<SysLog, ISysLogService> {
|
||||
//TODO 一个强大的功能,前端传一个字段字符串,后台只返回这些字符串对应的字段
|
||||
//创建时间/创建人的赋值
|
||||
IPage<SysLog> pageList = sysLogService.page(page, queryWrapper);
|
||||
log.info("查询当前页:"+pageList.getCurrent());
|
||||
log.info("查询当前页数量:"+pageList.getSize());
|
||||
log.info("查询结果数量:"+pageList.getRecords().size());
|
||||
log.info("数据总数:"+pageList.getTotal());
|
||||
// log.info("查询当前页:"+pageList.getCurrent());
|
||||
// log.info("查询当前页数量:"+pageList.getSize());
|
||||
// log.info("查询结果数量:"+pageList.getRecords().size());
|
||||
// log.info("数据总数:"+pageList.getTotal());
|
||||
result.setSuccess(true);
|
||||
result.setResult(pageList);
|
||||
return result;
|
||||
@ -131,9 +146,74 @@ public class SysLogController extends JeecgController<SysLog, ISysLogService> {
|
||||
* @param syslog
|
||||
*/
|
||||
@RequestMapping(value = "/exportXls")
|
||||
public ModelAndView exportXls(HttpServletRequest request, SysLog syslog) {
|
||||
return super.exportXlsForBigData(request, syslog, SysLog.class, "syslog", 10000);
|
||||
}
|
||||
|
||||
|
||||
public ModelAndView exportXls(HttpServletRequest request, SysLog syslog) {
|
||||
// 复制参数,移除排序相关键(column/order 等)防止前端传入排序影响导出顺序
|
||||
java.util.Map<String, String[]> rawMap = request.getParameterMap();
|
||||
java.util.Map<String, String[]> paramMap = new java.util.HashMap<>(rawMap);
|
||||
// 剔除自定义排序参数
|
||||
paramMap.remove("column");
|
||||
paramMap.remove("order");
|
||||
// 组装查询条件(已剔除排序参数)
|
||||
QueryWrapper<SysLog> queryWrapper = QueryGenerator.initQueryWrapper(syslog, paramMap);
|
||||
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
// 过滤选中数据
|
||||
String selections = request.getParameter("selections");
|
||||
if (oConvertUtils.isNotEmpty(selections)) {
|
||||
List<String> selectionList = Arrays.asList(selections.split(","));
|
||||
queryWrapper.in("id", selectionList);
|
||||
}
|
||||
// 定义IExcelExportServer
|
||||
IExcelExportServerEnhanced<SysLog> excelExportServer = new IExcelExportServerEnhanced<>() {
|
||||
|
||||
@Override
|
||||
public List<SysLog> selectListForExcelExport(Object queryParams, SysLog lastRecord, int pageSize) {
|
||||
QueryWrapper<SysLog> originalWrapper = (QueryWrapper<SysLog>) queryParams;
|
||||
// 克隆原始条件,避免多次迭代污染
|
||||
QueryWrapper<SysLog> batchWrapper = null;
|
||||
try {
|
||||
batchWrapper = (QueryWrapper<SysLog>) originalWrapper.clone();
|
||||
} catch (Exception e) {
|
||||
batchWrapper = originalWrapper;
|
||||
}
|
||||
|
||||
String lastId = null;
|
||||
if (lastRecord != null) {
|
||||
lastId = lastRecord.getId();
|
||||
final String cursorLastId = lastId;
|
||||
// 仅基于雪花ID(全局唯一,数值递增)作为游标,提升索引利用与性能
|
||||
// 条件:id < 上一批最后一条的ID,实现“从大到小”倒序分页
|
||||
batchWrapper.lt("id", cursorLastId);
|
||||
}
|
||||
|
||||
// 排序:按 id DESC(雪花ID递增,倒序可获取最新数据)
|
||||
batchWrapper.orderByDesc("id");
|
||||
Page<SysLog> cursorPage = new Page<>(1, pageSize);
|
||||
List<SysLog> list = service.page(cursorPage, batchWrapper).getRecords();
|
||||
|
||||
log.info("系统日志游标导出(ID游标) - lastId: {} batchSize: {} 返回: {}", lastId, pageSize, list.size());
|
||||
if (!list.isEmpty()) {
|
||||
SysLog endRecord = list.get(list.size() - 1);
|
||||
log.debug("本批次最后一条记录游标ID -> id: {}", endRecord.getId());
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPageSize() {
|
||||
return 10000;
|
||||
}
|
||||
};
|
||||
|
||||
String title = "系统日志";
|
||||
// AutoPoi 导出Excel
|
||||
ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
|
||||
//此处设置的filename无效 ,前端会重更新设置一下
|
||||
mv.addObject(NormalExcelConstants.FILE_NAME, title);
|
||||
mv.addObject(NormalExcelConstants.CLASS, SysLog.class);
|
||||
ExportParams exportParams = new ExportParams(title + "报表", "导出人:" + sysUser.getRealname(), title, jeecgBaseConfig.getPath().getUpload());
|
||||
mv.addObject(NormalExcelConstants.PARAMS, exportParams);
|
||||
mv.addObject(NormalExcelConstants.EXPORT_SERVER, excelExportServer);
|
||||
mv.addObject(NormalExcelConstants.QUERY_PARAMS, queryWrapper);
|
||||
return mv;
|
||||
}
|
||||
}
|
||||
|
||||
@ -111,7 +111,7 @@ public class SysPermissionController {
|
||||
}
|
||||
result.setResult(treeList);
|
||||
result.setSuccess(true);
|
||||
log.info("======获取全部菜单数据=====耗时:" + (System.currentTimeMillis() - start) + "毫秒");
|
||||
log.debug("======获取全部菜单数据=====耗时:" + (System.currentTimeMillis() - start) + "毫秒");
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
@ -176,7 +176,6 @@ public class SysPermissionController {
|
||||
}
|
||||
/*update_end author:wuxianquan date:20190908 for:先查询一级菜单,当用户点击展开菜单时加载子菜单 */
|
||||
|
||||
// update_begin author:sunjianlei date:20200108 for: 新增批量根据父ID查询子级菜单的接口 -------------
|
||||
/**
|
||||
* 查询子菜单
|
||||
*
|
||||
@ -210,7 +209,6 @@ public class SysPermissionController {
|
||||
return Result.error("批量查询子菜单失败:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
// update_end author:sunjianlei date:20200108 for: 新增批量根据父ID查询子级菜单的接口 -------------
|
||||
|
||||
// /**
|
||||
// * 查询用户拥有的菜单权限和按钮权限(根据用户账号)
|
||||
@ -251,15 +249,13 @@ public class SysPermissionController {
|
||||
}
|
||||
List<SysPermission> metaList = sysPermissionService.queryByUser(loginUser.getId());
|
||||
//添加首页路由
|
||||
//update-begin-author:taoyan date:20200211 for: TASK #3368 【路由缓存】首页的缓存设置有问题,需要根据后台的路由配置来实现是否缓存
|
||||
|
||||
//update-begin--Author:zyf Date:20220425 for:自定义首页地址 LOWCOD-1578
|
||||
// 代码逻辑说明: 自定义首页地址 LOWCOD-1578
|
||||
String version = request.getHeader(CommonConstant.VERSION);
|
||||
SysRoleIndex defIndexCfg = sysUserService.getDynamicIndexByUserRole(loginUser.getUsername(), version);
|
||||
if (defIndexCfg == null) {
|
||||
defIndexCfg = sysRoleIndexService.initDefaultIndex();
|
||||
}
|
||||
//update-end--Author:zyf Date:20220425 for:自定义首页地址 LOWCOD-1578
|
||||
|
||||
// 如果没有授权角色首页,则自动添加首页路由
|
||||
if (!PermissionDataUtil.hasIndexPage(metaList, defIndexCfg)) {
|
||||
@ -284,7 +280,6 @@ public class SysPermissionController {
|
||||
}
|
||||
metaList.add(0, indexMenu);
|
||||
}
|
||||
//update-end-author:taoyan date:20200211 for: TASK #3368 【路由缓存】首页的缓存设置有问题,需要根据后台的路由配置来实现是否缓存
|
||||
|
||||
/* TODO 注: 这段代码的主要作用是:把首页菜单的组件替换成角色菜单的组件,由于现在的逻辑如果角色菜单不存在则自动插入一条,所以这段代码暂时不需要
|
||||
List<SysPermission> menus = metaList.stream().filter(sysPermission -> {
|
||||
@ -293,7 +288,7 @@ public class SysPermissionController {
|
||||
}
|
||||
return defIndexCfg.getUrl().equals(sysPermission.getUrl());
|
||||
}).collect(Collectors.toList());
|
||||
//update-begin---author:liusq ---date:2022-06-29 for:设置自定义首页地址和组件----------
|
||||
// 代码逻辑说明: 设置自定义首页地址和组件----------
|
||||
if (menus.size() == 1) {
|
||||
String component = defIndexCfg.getComponent();
|
||||
String routeUrl = defIndexCfg.getUrl();
|
||||
@ -306,7 +301,6 @@ public class SysPermissionController {
|
||||
menus.get(0).setComponent(component);
|
||||
}
|
||||
}
|
||||
//update-end---author:liusq ---date:2022-06-29 for:设置自定义首页地址和组件-----------
|
||||
*/
|
||||
|
||||
JSONObject json = new JSONObject();
|
||||
@ -596,20 +590,17 @@ public class SysPermissionController {
|
||||
String permissionIds = json.getString("permissionIds");
|
||||
String lastPermissionIds = json.getString("lastpermissionIds");
|
||||
this.sysRolePermissionService.saveRolePermission(roleId, permissionIds, lastPermissionIds);
|
||||
//update-begin---author:wangshuai ---date:20220316 for:[VUEN-234]用户管理角色授权添加敏感日志------------
|
||||
// 代码逻辑说明: [VUEN-234]用户管理角色授权添加敏感日志------------
|
||||
LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
baseCommonService.addLog("修改角色ID: "+roleId+" 的权限配置,操作人: " +loginUser.getUsername() ,CommonConstant.LOG_TYPE_2, 2);
|
||||
//update-end---author:wangshuai ---date:20220316 for:[VUEN-234]用户管理角色授权添加敏感日志------------
|
||||
result.success("保存成功!");
|
||||
log.info("======角色授权成功=====耗时:" + (System.currentTimeMillis() - start) + "毫秒");
|
||||
|
||||
//update-begin---author:scott ---date:2024-06-18 for:【TV360X-1320】分配权限必须退出重新登录才生效,造成很多用户困扰---
|
||||
// 清除当前用户的授权缓存信息
|
||||
Subject currentUser = SecurityUtils.getSubject();
|
||||
if (currentUser.isAuthenticated()) {
|
||||
shiroRealm.clearCache(currentUser.getPrincipals());
|
||||
}
|
||||
//update-end---author:scott ---date::2024-06-18 for:【TV360X-1320】分配权限必须退出重新登录才生效,造成很多用户困扰---
|
||||
|
||||
} catch (Exception e) {
|
||||
result.error500("授权失败!");
|
||||
@ -836,12 +827,11 @@ public class SysPermissionController {
|
||||
|
||||
meta.put("title", permission.getName());
|
||||
|
||||
//update-begin--Author:scott Date:20201015 for:路由缓存问题,关闭了tab页时再打开就不刷新 #842
|
||||
// 代码逻辑说明: 路由缓存问题,关闭了tab页时再打开就不刷新 #842
|
||||
String component = permission.getComponent();
|
||||
if(oConvertUtils.isNotEmpty(permission.getComponentName()) || oConvertUtils.isNotEmpty(component)){
|
||||
meta.put("componentName", oConvertUtils.getString(permission.getComponentName(),component.substring(component.lastIndexOf("/")+1)));
|
||||
}
|
||||
//update-end--Author:scott Date:20201015 for:路由缓存问题,关闭了tab页时再打开就不刷新 #842
|
||||
|
||||
if (oConvertUtils.isEmpty(permission.getParentId())) {
|
||||
// 一级菜单跳转地址
|
||||
@ -857,11 +847,10 @@ public class SysPermissionController {
|
||||
if (isWwwHttpUrl(permission.getUrl())) {
|
||||
meta.put("url", permission.getUrl());
|
||||
}
|
||||
// update-begin--Author:sunjianlei Date:20210918 for:新增适配vue3项目的隐藏tab功能
|
||||
// 代码逻辑说明: 新增适配vue3项目的隐藏tab功能
|
||||
if (permission.isHideTab()) {
|
||||
meta.put("hideTab", true);
|
||||
}
|
||||
// update-end--Author:sunjianlei Date:20210918 for:新增适配vue3项目的隐藏tab功能
|
||||
json.put("meta", meta);
|
||||
}
|
||||
|
||||
|
||||
@ -27,6 +27,7 @@ import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||
import org.jeecgframework.poi.excel.entity.enmus.ExcelType;
|
||||
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
@ -111,13 +112,11 @@ public class SysPositionController {
|
||||
public Result<SysPosition> add(@RequestBody SysPosition sysPosition) {
|
||||
Result<SysPosition> result = new Result<SysPosition>();
|
||||
try {
|
||||
//update-begin---author:wangshuai ---date:20230313 for:【QQYUN-4558】vue3职位功能调整,去掉编码和级别,可以先隐藏------------
|
||||
//编号是空的,不需要判断多租户隔离了
|
||||
if(oConvertUtils.isEmpty(sysPosition.getCode())){
|
||||
//生成职位编码10位
|
||||
sysPosition.setCode(RandomUtil.randomString(10));
|
||||
}
|
||||
//update-end---author:wangshuai ---date:20230313 for:【QQYUN-4558】vue3职位功能调整,去掉编码和级别,可以先隐藏-------------
|
||||
sysPositionService.save(sysPosition);
|
||||
result.success("添加成功!");
|
||||
} catch (Exception e) {
|
||||
@ -240,12 +239,11 @@ public class SysPositionController {
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
//update-begin--Author:liusq Date:20240715 for:[03]职务导出,如果选择数据则只导出相关数据--------------------
|
||||
// 代码逻辑说明: [03]职务导出,如果选择数据则只导出相关数据--------------------
|
||||
String selections = request.getParameter("selections");
|
||||
if(!oConvertUtils.isEmpty(selections)){
|
||||
queryWrapper.in("id",selections.split(","));
|
||||
}
|
||||
//update-end--Author:liusq Date:20240715 for:[03]职务导出,如果选择数据则只导出相关数据----------------------
|
||||
//Step.2 AutoPoi 导出Excel
|
||||
ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
|
||||
List<SysPosition> pageList = sysPositionService.list(queryWrapper);
|
||||
@ -253,8 +251,14 @@ public class SysPositionController {
|
||||
//导出文件名称
|
||||
mv.addObject(NormalExcelConstants.FILE_NAME, "职务表列表");
|
||||
mv.addObject(NormalExcelConstants.CLASS, SysPosition.class);
|
||||
mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("职务表列表数据", "导出人:"+user.getRealname(),"导出信息"));
|
||||
//支持导出xlsx格式
|
||||
mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("职务表列表数据", "导出人:"+user.getRealname(),"导出信息", ExcelType.XSSF));
|
||||
mv.addObject(NormalExcelConstants.DATA_LIST, pageList);
|
||||
//职级导出支持导出字段
|
||||
String exportFields = request.getParameter(NormalExcelConstants.EXPORT_FIELDS);
|
||||
if(oConvertUtils.isNotEmpty(exportFields)){
|
||||
mv.addObject(NormalExcelConstants.EXPORT_FIELDS, exportFields);
|
||||
}
|
||||
return mv;
|
||||
}
|
||||
|
||||
|
||||
@ -33,6 +33,7 @@ import org.jeecg.modules.system.vo.SysUserRoleCountVo;
|
||||
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||
import org.jeecgframework.poi.excel.entity.ImportParams;
|
||||
import org.jeecgframework.poi.excel.entity.enmus.ExcelType;
|
||||
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -103,11 +104,10 @@ public class SysRoleController {
|
||||
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
|
||||
@RequestParam(name="isMultiTranslate", required = false) Boolean isMultiTranslate,
|
||||
HttpServletRequest req) {
|
||||
//update-begin---author:wangshuai---date:2025-03-26---for:【issues/7948】角色解决根据id查询回显不对---
|
||||
// 代码逻辑说明: 【issues/7948】角色解决根据id查询回显不对---
|
||||
if(null != isMultiTranslate && isMultiTranslate){
|
||||
pageSize = 100;
|
||||
}
|
||||
//update-end---author:wangshuai---date:2025-03-26---for:【issues/7948】角色解决根据id查询回显不对---
|
||||
Result<IPage<SysRole>> result = new Result<IPage<SysRole>>();
|
||||
//QueryWrapper<SysRole> queryWrapper = QueryGenerator.initQueryWrapper(role, req.getParameterMap());
|
||||
//IPage<SysRole> pageList = sysRoleService.page(page, queryWrapper);
|
||||
@ -157,9 +157,8 @@ public class SysRoleController {
|
||||
Result<SysRole> result = new Result<SysRole>();
|
||||
try {
|
||||
//开启多租户隔离,角色id自动生成10位
|
||||
//update-begin---author:wangshuai---date:2024-05-23---for:【TV360X-42】角色新增时设置的编码,保存后不一致---
|
||||
// 代码逻辑说明: 【TV360X-42】角色新增时设置的编码,保存后不一致---
|
||||
if(MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL && oConvertUtils.isEmpty(role.getRoleCode())){
|
||||
//update-end---author:wangshuai---date:2024-05-23---for:【TV360X-42】角色新增时设置的编码,保存后不一致---
|
||||
role.setRoleCode(RandomUtil.randomString(10));
|
||||
}
|
||||
role.setCreateTime(new Date());
|
||||
@ -230,10 +229,8 @@ public class SysRoleController {
|
||||
}
|
||||
}
|
||||
|
||||
//update-begin---author:wangshuai---date:2024-01-16---for:【QQYUN-7974】禁止删除 admin 角色---
|
||||
//是否存在admin角色
|
||||
sysRoleService.checkAdminRoleRejectDel(id);
|
||||
//update-end---author:wangshuai---date:2024-01-16---for:【QQYUN-7974】禁止删除 admin 角色---
|
||||
|
||||
sysRoleService.deleteRole(id);
|
||||
|
||||
@ -401,8 +398,14 @@ public class SysRoleController {
|
||||
mv.addObject(NormalExcelConstants.FILE_NAME,"角色列表");
|
||||
mv.addObject(NormalExcelConstants.CLASS,SysRole.class);
|
||||
LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
mv.addObject(NormalExcelConstants.PARAMS,new ExportParams("角色列表数据","导出人:"+user.getRealname(),"导出信息"));
|
||||
//导出支持xlsx
|
||||
mv.addObject(NormalExcelConstants.PARAMS,new ExportParams("角色列表数据","导出人:"+user.getRealname(),"导出信息", ExcelType.XSSF));
|
||||
mv.addObject(NormalExcelConstants.DATA_LIST,pageList);
|
||||
//角色支持指定字段导出
|
||||
String exportFields = request.getParameter(NormalExcelConstants.EXPORT_FIELDS);
|
||||
if(oConvertUtils.isNotEmpty(exportFields)){
|
||||
mv.addObject(NormalExcelConstants.EXPORT_FIELDS, exportFields);
|
||||
}
|
||||
return mv;
|
||||
}
|
||||
|
||||
|
||||
@ -91,6 +91,8 @@ public class SysRoleIndexController extends JeecgController<SysRoleIndex, ISysRo
|
||||
sysRoleIndex.setRelationType(CommonConstant.HOME_RELATION_ROLE);
|
||||
}
|
||||
sysRoleIndexService.save(sysRoleIndex);
|
||||
//更新其他全局配置的状态
|
||||
sysRoleIndexService.updateOtherDefaultStatus(sysRoleIndex.getRoleCode(),sysRoleIndex.getStatus(),sysRoleIndex.getId());
|
||||
sysRoleIndexService.cleanDefaultIndexCache();
|
||||
return Result.OK("添加成功!");
|
||||
}
|
||||
@ -112,6 +114,8 @@ public class SysRoleIndexController extends JeecgController<SysRoleIndex, ISysRo
|
||||
sysRoleIndex.setRelationType(CommonConstant.HOME_RELATION_ROLE);
|
||||
}
|
||||
sysRoleIndexService.updateById(sysRoleIndex);
|
||||
//更新其他全局配置的状态
|
||||
sysRoleIndexService.updateOtherDefaultStatus(sysRoleIndex.getRoleCode(),sysRoleIndex.getStatus(),sysRoleIndex.getId());
|
||||
sysRoleIndexService.cleanDefaultIndexCache();
|
||||
return Result.OK("编辑成功!");
|
||||
}
|
||||
@ -236,7 +240,7 @@ public class SysRoleIndexController extends JeecgController<SysRoleIndex, ISysRo
|
||||
String username = JwtUtil.getUserNameByToken(request);
|
||||
sysRoleIndex.setRoleCode(username);
|
||||
sysRoleIndexService.changeDefHome(sysRoleIndex);
|
||||
//update-begin-author:liusq---date:2025-07-03--for: 切换完成后的homePath获取
|
||||
// 代码逻辑说明: 切换完成后的homePath获取
|
||||
String version = request.getHeader(CommonConstant.VERSION);
|
||||
String homePath = null;
|
||||
SysRoleIndex defIndexCfg = sysUserService.getDynamicIndexByUserRole(username, version);
|
||||
@ -249,7 +253,6 @@ public class SysRoleIndexController extends JeecgController<SysRoleIndex, ISysRo
|
||||
homePath = SymbolConstant.SINGLE_SLASH + homePath;
|
||||
}
|
||||
}
|
||||
//update-end-author:liusq---date:2025-07-03--for:切换完成后的homePath获取
|
||||
return Result.OK(homePath);
|
||||
}
|
||||
/**
|
||||
@ -261,7 +264,7 @@ public class SysRoleIndexController extends JeecgController<SysRoleIndex, ISysRo
|
||||
public Result<?> getCurrentHome(HttpServletRequest request) {
|
||||
String username = JwtUtil.getUserNameByToken(request);
|
||||
Object homeType = redisUtil.get(DefIndexConst.CACHE_TYPE + username);
|
||||
return Result.OK(oConvertUtils.getString(homeType,DefIndexConst.HOME_TYPE_SYSTEM));
|
||||
return Result.OK(oConvertUtils.getString(homeType,DefIndexConst.HOME_TYPE_MENU));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -248,10 +248,9 @@ public class SysTenantController {
|
||||
|
||||
idList.add(Integer.parseInt(id));
|
||||
}
|
||||
//update-begin---author:wangshuai ---date:20230710 for:【QQYUN-5723】3、租户删除直接删除,不删除中间表------------
|
||||
// 代码逻辑说明: 【QQYUN-5723】3、租户删除直接删除,不删除中间表------------
|
||||
sysTenantService.removeByIds(idList);
|
||||
result.success("删除成功!");
|
||||
//update-end---author:wangshuai ---date:20220523 for:【QQYUN-5723】3、租户删除直接删除,不删除中间表------------
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -386,11 +385,10 @@ public class SysTenantController {
|
||||
Result<Map<String,Object>> result = new Result<Map<String,Object>>();
|
||||
try {
|
||||
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
//update-begin---author:wangshuai ---date:20221223 for:[QQYUN-3371]租户逻辑改造,改成关系表------------
|
||||
// 代码逻辑说明: [QQYUN-3371]租户逻辑改造,改成关系表------------
|
||||
List<Integer> tenantIdList = relationService.getTenantIdsByUserId(sysUser.getId());
|
||||
Map<String,Object> map = new HashMap(5);
|
||||
if (null!=tenantIdList && tenantIdList.size()>0) {
|
||||
//update-end---author:wangshuai ---date:20221223 for:[QQYUN-3371]租户逻辑改造,改成关系表------------
|
||||
// 该方法仅查询有效的租户,如果返回0个就说明所有的租户均无效。
|
||||
List<SysTenant> tenantList = sysTenantService.queryEffectiveTenant(tenantIdList);
|
||||
map.put("list", tenantList);
|
||||
@ -530,7 +528,6 @@ public class SysTenantController {
|
||||
}
|
||||
}
|
||||
|
||||
//update-begin---author:wangshuai ---date:20230107 for:[QQYUN-3725]申请加入租户,审核中状态增加接口------------
|
||||
/**
|
||||
* 分页获取租户用户数据(vue3用户租户页面)【低代码应用专用接口】
|
||||
*
|
||||
@ -615,7 +612,6 @@ public class SysTenantController {
|
||||
sysTenantService.removeById(sysTenant.getId());
|
||||
return Result.ok("注销成功");
|
||||
}
|
||||
//update-end---author:wangshuai ---date:20230107 for:[QQYUN-3725]申请加入租户,审核中状态增加接口------------
|
||||
|
||||
/**
|
||||
* 获取租户用户不同状态下的数量【低代码应用专用接口】
|
||||
@ -877,13 +873,12 @@ public class SysTenantController {
|
||||
@GetMapping("/getTenantCount")
|
||||
public Result<Map<String,Long>> getTenantCount(HttpServletRequest request){
|
||||
Map<String,Long> map = new HashMap<>();
|
||||
//update-begin---author:wangshuai---date:2023-11-24---for:【QQYUN-7177】用户数量显示不正确---
|
||||
// 代码逻辑说明: 【QQYUN-7177】用户数量显示不正确---
|
||||
if(oConvertUtils.isEmpty(TokenUtils.getTenantIdByRequest(request))){
|
||||
return Result.error("当前租户为空,禁止访问!");
|
||||
}
|
||||
Integer tenantId = oConvertUtils.getInt(TokenUtils.getTenantIdByRequest(request));
|
||||
Long userCount = relationService.getUserCount(tenantId,CommonConstant.USER_TENANT_NORMAL);
|
||||
//update-end---author:wangshuai---date:2023-11-24---for:【QQYUN-7177】用户数量显示不正确---
|
||||
map.put("userCount",userCount);
|
||||
LambdaQueryWrapper<SysDepart> departQuery = new LambdaQueryWrapper<>();
|
||||
departQuery.eq(SysDepart::getDelFlag,String.valueOf(CommonConstant.DEL_FLAG_0));
|
||||
|
||||
@ -3,6 +3,7 @@ package org.jeecg.modules.system.controller;
|
||||
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
@ -12,16 +13,21 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
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.PermissionData;
|
||||
import org.jeecg.common.base.BaseMap;
|
||||
import org.jeecg.common.config.TenantContext;
|
||||
import org.jeecg.common.constant.CacheConstant;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.constant.PasswordConstant;
|
||||
import org.jeecg.common.constant.SymbolConstant;
|
||||
import org.jeecg.common.modules.redis.client.JeecgRedisClient;
|
||||
import org.jeecg.common.system.query.QueryGenerator;
|
||||
import org.jeecg.common.system.util.JwtUtil;
|
||||
import org.jeecg.common.system.vo.LoginUser;
|
||||
import org.jeecg.common.util.*;
|
||||
import org.jeecg.config.JeecgBaseConfig;
|
||||
import org.jeecg.config.mybatis.MybatisPlusSaasConfig;
|
||||
import org.jeecg.modules.base.service.BaseCommonService;
|
||||
import org.jeecg.modules.system.entity.*;
|
||||
@ -38,6 +44,7 @@ import org.jeecg.modules.system.vo.lowapp.DepartAndUserInfo;
|
||||
import org.jeecg.modules.system.vo.lowapp.UpdateDepartInfo;
|
||||
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||
import org.jeecgframework.poi.excel.entity.enmus.ExcelType;
|
||||
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
@ -47,6 +54,8 @@ import org.springframework.web.servlet.ModelAndView;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@ -98,6 +107,8 @@ public class SysUserController {
|
||||
|
||||
@Autowired
|
||||
private JeecgRedisClient jeecgRedisClient;
|
||||
@Autowired
|
||||
private JeecgBaseConfig jeecgBaseConfig;
|
||||
|
||||
/**
|
||||
* 获取租户下用户数据(支持租户隔离)
|
||||
@ -161,6 +172,7 @@ public class SysUserController {
|
||||
user.setDelFlag(CommonConstant.DEL_FLAG_0);
|
||||
//用户表字段org_code不能在这里设置他的值
|
||||
user.setOrgCode(null);
|
||||
user.setLastPwdUpdateTime(new Date());
|
||||
// 保存用户走一个service 保证事务
|
||||
//获取租户ids
|
||||
String relTenantIds = jsonObject.getString("relTenantIds");
|
||||
@ -200,7 +212,10 @@ public class SysUserController {
|
||||
//获取租户ids
|
||||
String relTenantIds = jsonObject.getString("relTenantIds");
|
||||
String updateFromPage = jsonObject.getString("updateFromPage");
|
||||
sysUserService.editUser(user, roles, departs, relTenantIds, updateFromPage);
|
||||
//update-begin---author:wangshuai---date:2025-11-12---for:【JHHB-776】用户编辑,应该从数据库查出老数据,页面传递什么字段,把这些字段覆盖数据库查询结果,再更新---
|
||||
oConvertUtils.copyNonNullFields(user, sysUser);
|
||||
sysUserService.editUser(sysUser, roles, departs, relTenantIds, updateFromPage);
|
||||
//update-end---author:wangshuai---date:2025-11-12---for:【JHHB-776】用户编辑,应该从数据库查出老数据,页面传递什么字段,把这些字段覆盖数据库查询结果,再更新---
|
||||
result.success("修改成功!");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
@ -259,9 +274,8 @@ public class SysUserController {
|
||||
String[] arr = ids.split(",");
|
||||
for (String id : arr) {
|
||||
if(oConvertUtils.isNotEmpty(id)) {
|
||||
//update-begin---author:liusq ---date:20230620 for:[QQYUN-5577]用户列表-冻结用户,再解冻之后,用户还是无法登陆,有缓存问题 #5066------------
|
||||
// 代码逻辑说明: [QQYUN-5577]用户列表-冻结用户,再解冻之后,用户还是无法登陆,有缓存问题 #5066------------
|
||||
sysUserService.updateStatus(id,status);
|
||||
//update-end---author:liusq ---date:20230620 for:[QQYUN-5577]用户列表-冻结用户,再解冻之后,用户还是无法登陆,有缓存问题 #5066------------
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
@ -271,6 +285,26 @@ public class SysUserController {
|
||||
result.success("操作成功!");
|
||||
return result;
|
||||
|
||||
}
|
||||
/**
|
||||
* 重置为系统密码接口
|
||||
* @param usernames
|
||||
* @return
|
||||
*/
|
||||
@RequiresRoles({"admin"})
|
||||
@RequiresPermissions("system:user:resetPassword")
|
||||
@RequestMapping(value = "/resetPassword", method = RequestMethod.PUT)
|
||||
public Result<SysUser> resetPassword(@RequestParam(name = "usernames") String usernames) {
|
||||
Result<SysUser> result = new Result<SysUser>();
|
||||
try {
|
||||
sysUserService.resetToSysPassword(usernames);
|
||||
result.success("操作成功!");
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
result.error500(e.getMessage());
|
||||
}
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
@RequiresPermissions("system:user:queryById")
|
||||
@ -342,16 +376,23 @@ public class SysUserController {
|
||||
*/
|
||||
@RequiresPermissions("system:user:changepwd")
|
||||
@RequestMapping(value = "/changePassword", method = RequestMethod.PUT)
|
||||
public Result<?> changePassword(@RequestBody SysUser sysUser) {
|
||||
public Result<?> changePassword(@RequestBody SysUser sysUser, HttpServletRequest request) {
|
||||
//-------------------------------------------------------------------------------------
|
||||
//增加 check防止恶意刷短信接口
|
||||
String clientIp = IpUtils.getIpAddr(request);
|
||||
if(!DySmsLimit.canSendSms(clientIp)){
|
||||
log.warn("-------- IP地址:{}, 短信接口请求太多,有攻击风险!", clientIp);
|
||||
return Result.error("短信接口请求太多,请稍后再试!");
|
||||
}
|
||||
//-------------------------------------------------------------------------------------
|
||||
SysUser u = this.sysUserService.getOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUsername, sysUser.getUsername()));
|
||||
if (u == null) {
|
||||
return Result.error("用户不存在!");
|
||||
}
|
||||
sysUser.setId(u.getId());
|
||||
//update-begin---author:wangshuai ---date:20220316 for:[VUEN-234]修改密码添加敏感日志------------
|
||||
// 代码逻辑说明: [VUEN-234]修改密码添加敏感日志------------
|
||||
LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
baseCommonService.addLog("修改用户 "+sysUser.getUsername()+" 的密码,操作人: " +loginUser.getUsername() ,CommonConstant.LOG_TYPE_2, 2);
|
||||
//update-end---author:wangshuai ---date:20220316 for:[VUEN-234]修改密码添加敏感日志------------
|
||||
return sysUserService.changePassword(sysUser);
|
||||
}
|
||||
|
||||
@ -392,7 +433,7 @@ public class SysUserController {
|
||||
@RequestMapping(value = "/generateUserId", method = RequestMethod.GET)
|
||||
public Result<String> generateUserId() {
|
||||
Result<String> result = new Result<>();
|
||||
System.out.println("我执行了,生成用户ID==============================");
|
||||
//System.out.println("我执行了,生成用户ID==============================");
|
||||
String userId = UUID.randomUUID().toString().replace("-", "");
|
||||
result.setSuccess(true);
|
||||
result.setResult(userId);
|
||||
@ -450,10 +491,9 @@ public class SysUserController {
|
||||
@RequestParam(name="username",required=false) String username,
|
||||
@RequestParam(name="isMultiTranslate",required=false) String isMultiTranslate,
|
||||
@RequestParam(name="id",required = false) String id) {
|
||||
//update-begin-author:taoyan date:2022-7-14 for: VUEN-1702【禁止问题】sql注入漏洞
|
||||
// 代码逻辑说明: VUEN-1702【禁止问题】sql注入漏洞
|
||||
String[] arr = new String[]{departId, realname, username, id};
|
||||
SqlInjectionUtil.filterContent(arr, SymbolConstant.SINGLE_QUOTATION_MARK);
|
||||
//update-end-author:taoyan date:2022-7-14 for: VUEN-1702【禁止问题】sql注入漏洞
|
||||
IPage<SysUser> pageList = sysUserDepartService.queryDepartUserPageList(departId, username, realname, pageSize, pageNo,id,isMultiTranslate);
|
||||
return Result.OK(pageList);
|
||||
}
|
||||
@ -469,17 +509,34 @@ public class SysUserController {
|
||||
public ModelAndView exportXls(SysUser sysUser,HttpServletRequest request) {
|
||||
// Step.1 组装查询条件
|
||||
QueryWrapper<SysUser> queryWrapper = QueryGenerator.initQueryWrapper(sysUser, request.getParameterMap());
|
||||
queryWrapper.ne("username", "_reserve_user_external");
|
||||
//Step.2 AutoPoi 导出Excel
|
||||
ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
|
||||
//update-begin--Author:kangxiaolin Date:20180825 for:[03]用户导出,如果选择数据则只导出相关数据--------------------
|
||||
// 代码逻辑说明: [03]用户导出,如果选择数据则只导出相关数据--------------------
|
||||
String selections = request.getParameter("selections");
|
||||
if(!oConvertUtils.isEmpty(selections)){
|
||||
queryWrapper.in("id",selections.split(","));
|
||||
}
|
||||
//update-end--Author:kangxiaolin Date:20180825 for:[03]用户导出,如果选择数据则只导出相关数据----------------------
|
||||
List<SysUser> pageList = sysUserService.list(queryWrapper);
|
||||
List<SysUserExportVo> list = sysUserService.getDepartAndRoleExportMsg(pageList);
|
||||
|
||||
//是否存在部门id
|
||||
boolean izDepartId = true;
|
||||
String departId = request.getParameter("departId");
|
||||
if (oConvertUtils.isNotEmpty(departId)) {
|
||||
LambdaQueryWrapper<SysUserDepart> query = new LambdaQueryWrapper<>();
|
||||
query.in(SysUserDepart::getDepId, Arrays.asList(departId.split(",")));
|
||||
List<SysUserDepart> list = sysUserDepartService.list(query);
|
||||
List<String> userIds = list.stream().map(SysUserDepart::getUserId).collect(Collectors.toList());
|
||||
if (oConvertUtils.listIsNotEmpty(userIds)) {
|
||||
queryWrapper.in("id", userIds);
|
||||
}else{
|
||||
izDepartId = false;
|
||||
}
|
||||
}
|
||||
List<SysUserExportVo> list = new ArrayList<>();
|
||||
// 代码逻辑说明: 【JHHB-762】【用户管理】需要支持按组织架构查询用户---
|
||||
if(izDepartId){
|
||||
List<SysUser> pageList = sysUserService.list(queryWrapper);
|
||||
list = sysUserService.getDepartAndRoleExportMsg(pageList);
|
||||
}
|
||||
//导出文件名称
|
||||
mv.addObject(NormalExcelConstants.FILE_NAME, "用户列表");
|
||||
mv.addObject(NormalExcelConstants.CLASS, SysUserExportVo.class);
|
||||
@ -495,8 +552,15 @@ public class SysUserController {
|
||||
exportParams.setTitleHeight((short)70);
|
||||
exportParams.setStyle(ExcelExportSysUserStyle.class);
|
||||
exportParams.setImageBasePath(upLoadPath);
|
||||
//导出为xlsx
|
||||
exportParams.setType(ExcelType.XSSF);
|
||||
mv.addObject(NormalExcelConstants.PARAMS, exportParams);
|
||||
mv.addObject(NormalExcelConstants.DATA_LIST, list);
|
||||
//用户导出支持导出字段
|
||||
String exportFields = request.getParameter(NormalExcelConstants.EXPORT_FIELDS);
|
||||
if(oConvertUtils.isNotEmpty(exportFields)){
|
||||
mv.addObject(NormalExcelConstants.EXPORT_FIELDS, exportFields);
|
||||
}
|
||||
return mv;
|
||||
}
|
||||
|
||||
@ -577,10 +641,9 @@ public class SysUserController {
|
||||
if(user==null) {
|
||||
return Result.error("用户不存在!");
|
||||
}
|
||||
//update-begin---author:wangshuai ---date:20220316 for:[VUEN-234]修改密码添加敏感日志------------
|
||||
// 代码逻辑说明: [VUEN-234]修改密码添加敏感日志------------
|
||||
LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
baseCommonService.addLog("修改密码,username: " +loginUser.getUsername() ,CommonConstant.LOG_TYPE_2, 2);
|
||||
//update-end---author:wangshuai ---date:20220316 for:[VUEN-234]修改密码添加敏感日志------------
|
||||
return sysUserService.resetPassword(username,oldpassword,password,confirmpassword);
|
||||
}
|
||||
|
||||
@ -694,10 +757,9 @@ public class SysUserController {
|
||||
if(oConvertUtils.isEmpty(depId)){
|
||||
LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
int userIdentity = user.getUserIdentity() != null?user.getUserIdentity():CommonConstant.USER_IDENTITY_1;
|
||||
//update-begin---author:chenrui ---date:20250107 for:[QQYUN-10775]验证码可以复用 #7674------------
|
||||
// 代码逻辑说明: [QQYUN-10775]验证码可以复用 #7674------------
|
||||
if(oConvertUtils.isNotEmpty(userIdentity) && userIdentity == CommonConstant.USER_IDENTITY_2
|
||||
&& oConvertUtils.isNotEmpty(user.getDepartIds())) {
|
||||
//update-end---author:chenrui ---date:20250107 for:[QQYUN-10775]验证码可以复用 #7674------------
|
||||
subDepids = sysDepartService.getMySubDepIdsByDepId(user.getDepartIds());
|
||||
}
|
||||
}else{
|
||||
@ -716,10 +778,8 @@ public class SysUserController {
|
||||
item.setOrgCode(useDepNames.get(item.getId()));
|
||||
});
|
||||
}
|
||||
//update-begin---author:wangshuai ---date:20221223 for:[QQYUN-3371]租户逻辑改造,改成关系表------------
|
||||
//设置租户id
|
||||
page.setRecords(userTenantService.setUserTenantIds(page.getRecords()));
|
||||
//update-end---author:wangshuai ---date:20221223 for:[QQYUN-3371]租户逻辑改造,改成关系表------------
|
||||
result.setSuccess(true);
|
||||
result.setResult(pageList);
|
||||
}else{
|
||||
@ -746,7 +806,7 @@ public class SysUserController {
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 orgCode 查询用户,包括子部门下的用户
|
||||
* 根据 orgCode 查询用户,包括子部门下的用户 【不包含岗位下的用户】
|
||||
* 针对通讯录模块做的接口,将多个部门的用户合并成一条记录,并转成对前端友好的格式
|
||||
*/
|
||||
@GetMapping("/queryByOrgCodeForAddressList")
|
||||
@ -755,12 +815,91 @@ public class SysUserController {
|
||||
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
|
||||
@RequestParam(name = "orgCode",required = false) String orgCode,
|
||||
SysUser userParams
|
||||
) {
|
||||
IPage page = new Page(pageNo, pageSize);
|
||||
IPage<SysUserSysDepartModel> pageList = sysUserService.queryUserByOrgCode(orgCode, userParams, page);
|
||||
List<SysUserSysDepartModel> list = pageList.getRecords();
|
||||
|
||||
// 记录所有出现过的 user, key = userId
|
||||
Map<String, JSONObject> hasUser = new HashMap<>(list.size());
|
||||
|
||||
JSONArray resultJson = new JSONArray(list.size());
|
||||
|
||||
for (SysUserSysDepartModel item : list) {
|
||||
String userId = item.getId();
|
||||
// userId
|
||||
JSONObject getModel = hasUser.get(userId);
|
||||
// 之前已存在过该用户,直接合并数据
|
||||
if (getModel != null) {
|
||||
String departName = getModel.get("departName").toString();
|
||||
getModel.put("departName", (departName + " | " + item.getDepartName()));
|
||||
} else {
|
||||
// 将用户对象转换为json格式,并将部门信息合并到 json 中
|
||||
JSONObject json = JSON.parseObject(JSON.toJSONString(item));
|
||||
json.remove("id");
|
||||
json.put("userId", userId);
|
||||
json.put("departId", item.getDepartId());
|
||||
json.put("departName", item.getDepartName());
|
||||
// json.put("avatar", item.getSysUser().getAvatar());
|
||||
resultJson.add(json);
|
||||
hasUser.put(userId, json);
|
||||
}
|
||||
}
|
||||
|
||||
IPage<JSONObject> result = new Page<>(pageNo, pageSize, pageList.getTotal());
|
||||
result.setRecords(resultJson.toJavaList(JSONObject.class));
|
||||
return Result.ok(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 orgCode 查询用户,包括公司、子公司、岗位部门下的用户
|
||||
*/
|
||||
@GetMapping("/queryDepartPostByOrgCode")
|
||||
public Result<?> queryDepartPostByOrgCode(@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
|
||||
@RequestParam(name = "orgCode",required = false) String orgCode,
|
||||
SysUser userParams
|
||||
) {
|
||||
IPage page = new Page(pageNo, pageSize);
|
||||
IPage<SysUserSysDepPostModel> pageList = sysUserService.queryDepartPostUserByOrgCode(orgCode, userParams, page);
|
||||
return Result.ok(pageList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 orgCode 查询用户信息(部门全路径,主岗位和兼职岗位的信息),包括公司、子公司、部门
|
||||
*/
|
||||
@GetMapping("/queryDepartUserByOrgCode")
|
||||
public Result<IPage<SysUserSysDepPostModel>> queryDepartUserByOrgCode(@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
|
||||
@RequestParam(name = "orgCode",required = false) String orgCode,
|
||||
SysUser userParams
|
||||
) {
|
||||
IPage page = new Page(pageNo, pageSize);
|
||||
IPage<SysUserSysDepPostModel> pageList = sysUserService.queryDepartUserByOrgCode(orgCode, userParams, page);
|
||||
return Result.ok(pageList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通讯录点击用户获取用户详情(包含用户基本信息、部门全路径、主岗位兼职岗位全路径)
|
||||
*
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/getUserDetailByUserId")
|
||||
public Result<SysUserSysDepPostModel> getUserDetailByUserId(@RequestParam(name = "userId") String userId) {
|
||||
Result<SysUserSysDepPostModel> result = new Result<SysUserSysDepPostModel>();
|
||||
try {
|
||||
SysUserSysDepPostModel sysDepPostModel = sysUserService.getUserDetailByUserId(userId);
|
||||
result.setSuccess(true);
|
||||
result.setResult(sysDepPostModel);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
result.setSuccess(false);
|
||||
result.setMessage("查询失败: " + e.getMessage());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 给指定部门添加对应的用户
|
||||
*/
|
||||
@ -770,15 +909,21 @@ public class SysUserController {
|
||||
Result<String> result = new Result<String>();
|
||||
try {
|
||||
String sysDepId = sysDepartUsersVO.getDepId();
|
||||
boolean updated = false;
|
||||
for(String sysUserId:sysDepartUsersVO.getUserIdList()) {
|
||||
SysUserDepart sysUserDepart = new SysUserDepart(null,sysUserId,sysDepId);
|
||||
QueryWrapper<SysUserDepart> queryWrapper = new QueryWrapper<SysUserDepart>();
|
||||
queryWrapper.eq("dep_id", sysDepId).eq("user_id",sysUserId);
|
||||
SysUserDepart one = sysUserDepartService.getOne(queryWrapper);
|
||||
if(one==null){
|
||||
updated = true;
|
||||
sysUserDepartService.save(sysUserDepart);
|
||||
}
|
||||
}
|
||||
// 【JHHB-737】更新关系后清空用户缓存
|
||||
if (updated) {
|
||||
redisUtil.removeAll(CacheConstant.SYS_USERS_CACHE);
|
||||
}
|
||||
result.setMessage("添加成功!");
|
||||
result.setSuccess(true);
|
||||
return result;
|
||||
@ -887,10 +1032,9 @@ public class SysUserController {
|
||||
String phone = jsonObject.getString("phone");
|
||||
String smscode = jsonObject.getString("smscode");
|
||||
|
||||
//update-begin-author:taoyan date:2022-9-13 for: VUEN-2245 【漏洞】发现新漏洞待处理20220906
|
||||
// 代码逻辑说明: VUEN-2245 【漏洞】发现新漏洞待处理20220906
|
||||
String redisKey = CommonConstant.PHONE_REDIS_KEY_PRE+phone;
|
||||
Object code = redisUtil.get(redisKey);
|
||||
//update-end-author:taoyan date:2022-9-13 for: VUEN-2245 【漏洞】发现新漏洞待处理20220906
|
||||
|
||||
String username = jsonObject.getString("username");
|
||||
//未设置用户名,则用手机号作为用户名
|
||||
@ -953,6 +1097,7 @@ public class SysUserController {
|
||||
user.setStatus(CommonConstant.USER_UNFREEZE);
|
||||
user.setDelFlag(CommonConstant.DEL_FLAG_0);
|
||||
user.setActivitiSync(CommonConstant.ACT_SYNC_1);
|
||||
user.setLastPwdUpdateTime(new Date());
|
||||
sysUserService.addUserWithRole(user,"");//默认临时角色 test
|
||||
result.success("注册成功");
|
||||
} catch (Exception e) {
|
||||
@ -1005,10 +1150,10 @@ public class SysUserController {
|
||||
Result<Map<String,String>> result = new Result<Map<String,String>>();
|
||||
String phone = jsonObject.getString("phone");
|
||||
String smscode = jsonObject.getString("smscode");
|
||||
//update-begin-author:taoyan date:2022-9-13 for: VUEN-2245 【漏洞】发现新漏洞待处理20220906
|
||||
// 代码逻辑说明: VUEN-2245 【漏洞】发现新漏洞待处理20220906
|
||||
String redisKey = CommonConstant.PHONE_REDIS_KEY_PRE+phone;
|
||||
Object code = redisUtil.get(redisKey);
|
||||
//update-begin---author:wangshuai---date:2025-07-15---for:【issues/8567】严重:修改密码存在水平越权问题。---
|
||||
// 代码逻辑说明: 【issues/8567】严重:修改密码存在水平越权问题。---
|
||||
if (null == code) {
|
||||
result.setMessage("短信验证码失效!");
|
||||
result.setSuccess(false);
|
||||
@ -1021,14 +1166,12 @@ public class SysUserController {
|
||||
smsCode = code.toString();
|
||||
}
|
||||
if (!smscode.equals(smsCode)) {
|
||||
//update-end---author:wangshuai---date:2025-07-15---for:【issues/8567】严重:修改密码存在水平越权问题。---
|
||||
result.setMessage("手机验证码错误");
|
||||
result.setSuccess(false);
|
||||
return result;
|
||||
}
|
||||
//设置有效时间
|
||||
redisUtil.set(redisKey, code,600);
|
||||
//update-end-author:taoyan date:2022-9-13 for: VUEN-2245 【漏洞】发现新漏洞待处理20220906
|
||||
|
||||
//新增查询用户名
|
||||
LambdaQueryWrapper<SysUser> query = new LambdaQueryWrapper<>();
|
||||
@ -1064,17 +1207,16 @@ public class SysUserController {
|
||||
}
|
||||
|
||||
SysUser sysUser=new SysUser();
|
||||
//update-begin-author:taoyan date:2022-9-13 for: VUEN-2245 【漏洞】发现新漏洞待处理20220906
|
||||
// 代码逻辑说明: VUEN-2245 【漏洞】发现新漏洞待处理20220906
|
||||
String redisKey = CommonConstant.PHONE_REDIS_KEY_PRE+phone;
|
||||
Object object= redisUtil.get(redisKey);
|
||||
//update-end-author:taoyan date:2022-9-13 for: VUEN-2245 【漏洞】发现新漏洞待处理20220906
|
||||
if(null==object) {
|
||||
result.setMessage("短信验证码失效!");
|
||||
result.setSuccess(false);
|
||||
return result;
|
||||
}
|
||||
|
||||
//update-begin---author:wangshuai---date:2025-07-14---for:【issues/8567】严重:修改密码存在水平越权问题。---
|
||||
// 代码逻辑说明: 【issues/8567】严重:修改密码存在水平越权问题。---
|
||||
String redisUsername = "";
|
||||
if(object.toString().contains("code")){
|
||||
JSONObject jsonObject = JSONObject.parseObject(object.toString());
|
||||
@ -1087,7 +1229,6 @@ public class SysUserController {
|
||||
result.setSuccess(false);
|
||||
return result;
|
||||
}
|
||||
//update-end---author:wangshuai---date:2025-07-14---for:【issues/8567】严重:修改密码存在水平越权问题。---
|
||||
|
||||
if(!smscode.equals(object.toString())) {
|
||||
result.setMessage("短信验证码不匹配!");
|
||||
@ -1104,10 +1245,10 @@ public class SysUserController {
|
||||
sysUser.setSalt(salt);
|
||||
String passwordEncode = PasswordUtil.encrypt(sysUser.getUsername(), password, salt);
|
||||
sysUser.setPassword(passwordEncode);
|
||||
sysUser.setLastPwdUpdateTime(new Date());
|
||||
this.sysUserService.updateById(sysUser);
|
||||
//update-begin---author:wangshuai ---date:20220316 for:[VUEN-234]密码重置添加敏感日志------------
|
||||
// 代码逻辑说明: [VUEN-234]密码重置添加敏感日志------------
|
||||
baseCommonService.addLog("重置 "+username+" 的密码,操作人: " +sysUser.getUsername() ,CommonConstant.LOG_TYPE_2, 2);
|
||||
//update-end---author:wangshuai ---date:20220316 for:[VUEN-234]密码重置添加敏感日志------------
|
||||
result.setSuccess(true);
|
||||
result.setMessage("密码重置完成!");
|
||||
//修改完密码后清空redis
|
||||
@ -1295,7 +1436,7 @@ public class SysUserController {
|
||||
sysUser.setPhone(phone);
|
||||
}
|
||||
if(StringUtils.isNotBlank(email)){
|
||||
//update-begin---author:wangshuai ---date:20220708 for:[VUEN-1528]积木官网邮箱重复,应该提示准确------------
|
||||
// 代码逻辑说明: [VUEN-1528]积木官网邮箱重复,应该提示准确------------
|
||||
LambdaQueryWrapper<SysUser> emailQuery = new LambdaQueryWrapper<>();
|
||||
emailQuery.eq(SysUser::getEmail,email);
|
||||
long count = sysUserService.count(emailQuery);
|
||||
@ -1303,7 +1444,6 @@ public class SysUserController {
|
||||
result.error500("保存失败,邮箱已存在!");
|
||||
return result;
|
||||
}
|
||||
//update-end---author:wangshuai ---date:20220708 for:[VUEN-1528]积木官网邮箱重复,应该提示准确--------------
|
||||
sysUser.setEmail(email);
|
||||
}
|
||||
if(null != birthday){
|
||||
@ -1324,7 +1464,7 @@ public class SysUserController {
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/saveClientId", method = RequestMethod.GET)
|
||||
public Result<SysUser> saveClientId(HttpServletRequest request,@RequestParam("clientId")String clientId) {
|
||||
public Result<SysUser> saveClientId(HttpServletRequest request,@RequestParam(value = "clientId",required = false)String clientId) {
|
||||
Result<SysUser> result = new Result<SysUser>();
|
||||
try {
|
||||
String username = JwtUtil.getUserNameByToken(request);
|
||||
@ -1332,8 +1472,7 @@ public class SysUserController {
|
||||
if(sysUser==null) {
|
||||
result.error500("未找到对应用户!");
|
||||
}else {
|
||||
sysUser.setClientId(clientId);
|
||||
sysUserService.updateById(sysUser);
|
||||
sysUserService.updateClientId(clientId,sysUser.getId());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
@ -1391,7 +1530,7 @@ public class SysUserController {
|
||||
@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");
|
||||
//增加 username传参
|
||||
if(oConvertUtils.isNotEmpty(username)){
|
||||
@ -1407,15 +1546,19 @@ public class SysUserController {
|
||||
//是否开启系统管理模块的多租户数据隔离【SAAS多租户模式】
|
||||
if (MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL) {
|
||||
String tenantId = oConvertUtils.getString(TokenUtils.getTenantIdByRequest(request),"-1");
|
||||
//update-begin---author:wangshuai ---date:20221223 for:[QQYUN-3371]租户逻辑改造,改成关系表------------
|
||||
// 代码逻辑说明: [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);
|
||||
|
||||
// 代码逻辑说明: JHHB-812 【移动端】人员按照排序展示 选择人员,通讯录等 123正序排
|
||||
queryWrapper.orderByAsc(SysUser::getSort);
|
||||
queryWrapper.orderByDesc(SysUser::getCreateTime);
|
||||
|
||||
IPage<SysUser> pageList = this.sysUserService.page(page, queryWrapper);
|
||||
//批量查询用户的所属部门
|
||||
//step.1 先拿到全部的 useids
|
||||
@ -1448,10 +1591,9 @@ public class SysUserController {
|
||||
result.setSuccess(false);
|
||||
return result;
|
||||
}
|
||||
//update-begin-author:taoyan date:2022-9-13 for: VUEN-2245 【漏洞】发现新漏洞待处理20220906
|
||||
// 代码逻辑说明: VUEN-2245 【漏洞】发现新漏洞待处理20220906
|
||||
String redisKey = CommonConstant.PHONE_REDIS_KEY_PRE+phone;
|
||||
Object object= redisUtil.get(redisKey);
|
||||
//update-end-author:taoyan date:2022-9-13 for: VUEN-2245 【漏洞】发现新漏洞待处理20220906
|
||||
if(null==object) {
|
||||
result.setMessage("短信验证码失效!");
|
||||
result.setSuccess(false);
|
||||
@ -1480,9 +1622,8 @@ public class SysUserController {
|
||||
@GetMapping("/getMultiUser")
|
||||
public List<SysUser> getMultiUser(SysUser sysUser){
|
||||
QueryWrapper<SysUser> queryWrapper = QueryGenerator.initQueryWrapper(sysUser, null);
|
||||
//update-begin---author:wangshuai ---date:20220104 for:[JTC-297]已冻结用户仍可设置为代理人------------
|
||||
// 代码逻辑说明: [JTC-297]已冻结用户仍可设置为代理人------------
|
||||
queryWrapper.eq("status",Integer.parseInt(CommonConstant.STATUS_1));
|
||||
//update-end---author:wangshuai ---date:20220104 for:[JTC-297]已冻结用户仍可设置为代理人------------
|
||||
List<SysUser> ls = this.sysUserService.list(queryWrapper);
|
||||
for(SysUser user: ls){
|
||||
user.setPassword(null);
|
||||
@ -1529,6 +1670,7 @@ public class SysUserController {
|
||||
@RequestParam(name = "roleId", required = false) String roleId,
|
||||
@RequestParam(name="keyword",required=false) String keyword,
|
||||
@RequestParam(name="excludeUserIdList",required = false) String excludeUserIdList,
|
||||
@RequestParam(name="includeUsernameList",required = false) String includeUsernameList,
|
||||
HttpServletRequest req) {
|
||||
//------------------------------------------------------------------------------------------------
|
||||
Integer tenantId = null;
|
||||
@ -1539,10 +1681,9 @@ public class SysUserController {
|
||||
log.info("---------简流中选择用户接口,通过租户筛选,租户ID={}", tenantId);
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------
|
||||
IPage<SysUser> pageList = sysUserDepartService.getUserInformation(tenantId, departId,roleId, keyword, pageSize, pageNo,excludeUserIdList);
|
||||
IPage<SysUser> pageList = sysUserDepartService.getUserInformation(tenantId, departId,roleId, keyword, pageSize, pageNo,excludeUserIdList,includeUsernameList);
|
||||
return Result.OK(pageList);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取被逻辑删除的用户列表,无分页【低代码应用专用接口】
|
||||
@ -1564,6 +1705,23 @@ public class SysUserController {
|
||||
return Result.ok(quitList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新刪除状态和离职状态【低代码应用专用接口】
|
||||
* @param jsonObject
|
||||
* @return Result<String>
|
||||
*/
|
||||
@PutMapping("/putCancelQuit")
|
||||
public Result<String> putCancelQuit(@RequestBody JSONObject jsonObject, HttpServletRequest request){
|
||||
String userIds = jsonObject.getString("userIds");
|
||||
String usernames = jsonObject.getString("usernames");
|
||||
Integer tenantId = oConvertUtils.getInt(TokenUtils.getTenantIdByRequest(request),0);
|
||||
//将状态改成未删除
|
||||
if (StringUtils.isNotBlank(userIds)) {
|
||||
userTenantService.putCancelQuit(Arrays.asList(userIds.split(SymbolConstant.COMMA)),tenantId);
|
||||
}
|
||||
return Result.ok("取消离职成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户信息(vue3用户设置专用)【低代码应用专用接口】
|
||||
* @return
|
||||
@ -1576,11 +1734,9 @@ public class SysUserController {
|
||||
return Result.error("未找到该用户数据");
|
||||
}
|
||||
|
||||
//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 = " | ";
|
||||
@ -1686,42 +1842,6 @@ public class SysUserController {
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加用户【后台租户模式专用,敲敲云不要用这个】
|
||||
*
|
||||
* @param jsonObject
|
||||
* @return
|
||||
*/
|
||||
@RequiresPermissions("system:user:addTenantUser")
|
||||
@RequestMapping(value = "/addTenantUser", method = RequestMethod.POST)
|
||||
public Result<SysUser> addTenantUser(@RequestBody JSONObject jsonObject) {
|
||||
Result<SysUser> result = new Result<SysUser>();
|
||||
String selectedRoles = jsonObject.getString("selectedroles");
|
||||
String selectedDeparts = jsonObject.getString("selecteddeparts");
|
||||
try {
|
||||
SysUser user = JSON.parseObject(jsonObject.toJSONString(), SysUser.class);
|
||||
user.setCreateTime(new Date());//设置创建时间
|
||||
String salt = oConvertUtils.randomGen(8);
|
||||
user.setSalt(salt);
|
||||
String passwordEncode = PasswordUtil.encrypt(user.getUsername(), user.getPassword(), salt);
|
||||
user.setPassword(passwordEncode);
|
||||
user.setStatus(1);
|
||||
user.setDelFlag(CommonConstant.DEL_FLAG_0);
|
||||
//用户表字段org_code不能在这里设置他的值
|
||||
user.setOrgCode(null);
|
||||
// 保存用户走一个service 保证事务
|
||||
//获取租户ids
|
||||
String relTenantIds = jsonObject.getString("relTenantIds");
|
||||
sysUserService.saveUser(user, selectedRoles, selectedDeparts, relTenantIds, true);
|
||||
baseCommonService.addLog("添加用户,username: " + user.getUsername(), CommonConstant.LOG_TYPE_2, 2);
|
||||
result.success("添加成功!");
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
result.error500("操作失败");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改租户下的用户【低代码应用专用接口】
|
||||
* @param sysUser
|
||||
@ -1899,4 +2019,27 @@ public class SysUserController {
|
||||
}
|
||||
return Result.ok(progress);
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证当前登录用户是否仍使用系统默认初始密码。
|
||||
* 返回值说明:
|
||||
* yes_{URL编码后的默认密码} -> 用户当前密码为默认初始密码,前端需弹出强制修改提示
|
||||
* no -> 用户密码不是默认密码,或未开启默认密码检测开关
|
||||
*/
|
||||
@GetMapping("/verifyIzDefaultPwd")
|
||||
public Result<String> verifyIzDefaultPwd() throws UnsupportedEncodingException {
|
||||
// 未配置 Firewall 或已关闭默认密码检测开关 (enableDefaultPwdCheck=false) 时,直接返回 "no" 表示无需提示
|
||||
if (jeecgBaseConfig.getFirewall() == null || Boolean.FALSE.equals((jeecgBaseConfig.getFirewall().getEnableDefaultPwdCheck()))) {
|
||||
return Result.OK("no");
|
||||
}
|
||||
|
||||
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
SysUser user = sysUserService.getById(sysUser.getId());
|
||||
String passwordEncode = PasswordUtil.encrypt(user.getUsername(), PasswordConstant.DEFAULT_PASSWORD, user.getSalt());
|
||||
if(passwordEncode.equals(user.getPassword())){
|
||||
String encode = URLEncoder.encode(PasswordConstant.DEFAULT_PASSWORD, "UTF-8");
|
||||
return Result.OK("yes_" + encode);
|
||||
}
|
||||
return Result.OK("no");
|
||||
}
|
||||
}
|
||||
|
||||
@ -61,7 +61,6 @@ public class SysUserOnlineController {
|
||||
//TODO 改成一次性查询
|
||||
LoginUser loginUser = sysBaseApi.getUserByName(JwtUtil.getUsername(token));
|
||||
if (loginUser != null && !"_reserve_user_external".equals(loginUser.getUsername())) {
|
||||
//update-begin---author:wangshuai ---date:20220104 for:[JTC-382]在线用户查询无效------------
|
||||
//验证用户名是否与传过来的用户名相同
|
||||
boolean isMatchUsername=true;
|
||||
//判断用户名是否为空,并且当前循环的用户不包含传过来的用户名,那么就设成false
|
||||
@ -72,7 +71,6 @@ public class SysUserOnlineController {
|
||||
BeanUtils.copyProperties(loginUser, online);
|
||||
onlineList.add(online);
|
||||
}
|
||||
//update-end---author:wangshuai ---date:20220104 for:[JTC-382]在线用户查询无效------------
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -89,7 +89,6 @@ public class ThirdAppController {
|
||||
}
|
||||
enabledMap.put("wechatEnterprise", qywxConfig);
|
||||
enabledMap.put("dingtalk", dingConfig);
|
||||
//update-end---author:wangshuai ---date:20230224 for:[QQYUN-3440]通过租户模式隔离------------
|
||||
return Result.OK(enabledMap);
|
||||
}
|
||||
|
||||
@ -101,12 +100,11 @@ public class ThirdAppController {
|
||||
*/
|
||||
@GetMapping("/sync/wechatEnterprise/user/toApp")
|
||||
public Result syncWechatEnterpriseUserToApp(@RequestParam(value = "ids", required = false) String ids) {
|
||||
//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]通过租户模式隔离 ------------
|
||||
// 代码逻辑说明: [QQYUN-3440]通过租户模式隔离 ------------
|
||||
SyncInfoVo syncInfo = wechatEnterpriseService.syncLocalUserToThirdApp(ids);
|
||||
if (syncInfo.getFailInfo().size() == 0) {
|
||||
return Result.OK("同步成功", syncInfo);
|
||||
@ -295,22 +293,19 @@ public class ThirdAppController {
|
||||
String title = "第三方APP消息测试";
|
||||
MessageDTO message = new MessageDTO(fromUser, receiver, title, content);
|
||||
message.setToAll(sendAll);
|
||||
//update-begin---author:wangshuai ---date:20230224 for:[QQYUN-3440]钉钉、企业微信通过租户模式隔离 ------------
|
||||
// 代码逻辑说明: [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("企业微信尚未配置,请配置企业微信");
|
||||
//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);
|
||||
}
|
||||
|
||||
@ -103,12 +103,11 @@ public class ThirdLoginController {
|
||||
//构造第三方登录信息存储对象
|
||||
ThirdLoginModel tlm = new ThirdLoginModel(source, uuid, username, avatar);
|
||||
//判断有没有这个人
|
||||
//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】敲敲云,线上解绑重新绑定一直提示这个---
|
||||
// 代码逻辑说明: 【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;
|
||||
@ -120,7 +119,7 @@ public class ThirdLoginController {
|
||||
user = thridList.get(0);
|
||||
}
|
||||
// 生成token
|
||||
//update-begin-author:wangshuai date:20201118 for:从第三方登录查询是否存在用户id,不存在绑定手机号
|
||||
// 代码逻辑说明: 从第三方登录查询是否存在用户id,不存在绑定手机号
|
||||
if(oConvertUtils.isNotEmpty(user.getSysUserId())) {
|
||||
String sysUserId = user.getSysUserId();
|
||||
SysUser sysUser = sysUserService.getById(sysUserId);
|
||||
@ -129,12 +128,9 @@ public class ThirdLoginController {
|
||||
}else{
|
||||
modelMap.addAttribute("token", "绑定手机号,"+""+uuid);
|
||||
}
|
||||
//update-end-author:wangshuai date:20201118 for:从第三方登录查询是否存在用户id,不存在绑定手机号
|
||||
//update-begin--Author:wangshuai Date:20200729 for:接口在签名校验失败时返回失败的标识码 issues#1441--------------------
|
||||
}else{
|
||||
modelMap.addAttribute("token", "登录失败");
|
||||
}
|
||||
//update-end--Author:wangshuai Date:20200729 for:接口在签名校验失败时返回失败的标识码 issues#1441--------------------
|
||||
result.setSuccess(false);
|
||||
result.setMessage("第三方登录异常,请联系管理员");
|
||||
return "thirdLogin";
|
||||
@ -157,14 +153,13 @@ public class ThirdLoginController {
|
||||
return res;
|
||||
}
|
||||
//创建新账号
|
||||
//update-begin-author:wangshuai date:20201118 for:修改成从第三方登录查出来的user_id,在查询用户表尽行token
|
||||
// 代码逻辑说明: 修改成从第三方登录查出来的user_id,在查询用户表尽行token
|
||||
SysThirdAccount user = sysThirdAccountService.saveThirdUser(model,CommonConstant.TENANT_ID_DEFAULT_VALUE);
|
||||
if(oConvertUtils.isNotEmpty(user.getSysUserId())){
|
||||
String sysUserId = user.getSysUserId();
|
||||
SysUser sysUser = sysUserService.getById(sysUserId);
|
||||
// 生成token
|
||||
String token = saveToken(sysUser);
|
||||
//update-end-author:wangshuai date:20201118 for:修改成从第三方登录查出来的user_id,在查询用户表尽行token
|
||||
res.setResult(token);
|
||||
res.setSuccess(true);
|
||||
}
|
||||
@ -212,7 +207,7 @@ public class ThirdLoginController {
|
||||
|
||||
private String saveToken(SysUser user) {
|
||||
// 生成token
|
||||
String token = JwtUtil.sign(user.getUsername(), user.getPassword());
|
||||
String token = JwtUtil.sign(user.getUsername(), user.getPassword(), CommonConstant.CLIENT_TYPE_PC);
|
||||
redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token);
|
||||
// 设置超时时间
|
||||
redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME * 2 / 1000);
|
||||
@ -232,36 +227,33 @@ public class ThirdLoginController {
|
||||
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);
|
||||
//update-begin---author:chenrui ---date:20250210 for:[QQYUN-11021]三方登录接口通过token获取用户信息漏洞修复------------
|
||||
// 代码逻辑说明: [QQYUN-11021]三方登录接口通过token获取用户信息漏洞修复------------
|
||||
if (!TokenUtils.verifyToken(token, sysBaseAPI, redisUtil)) {
|
||||
return Result.noauth("token验证失败");
|
||||
}
|
||||
//update-end---author:chenrui ---date:20250210 for:[QQYUN-11021]三方登录接口通过token获取用户信息漏洞修复------------
|
||||
//1. 校验用户是否有效
|
||||
SysUser sysUser = sysUserService.getUserByName(username);
|
||||
result = sysUserService.checkUserIsEffective(sysUser);
|
||||
if(!result.isSuccess()) {
|
||||
return result;
|
||||
}
|
||||
//update-begin-author:wangshuai date:20201118 for:如果真实姓名和头像不存在就取第三方登录的
|
||||
// 代码逻辑说明: 如果真实姓名和头像不存在就取第三方登录的
|
||||
LambdaQueryWrapper<SysThirdAccount> query = new LambdaQueryWrapper<>();
|
||||
query.eq(SysThirdAccount::getSysUserId,sysUser.getId());
|
||||
query.eq(SysThirdAccount::getThirdType,thirdType);
|
||||
query.eq(SysThirdAccount::getTenantId,oConvertUtils.getInt(tenantId,CommonConstant.TENANT_ID_DEFAULT_VALUE));
|
||||
//update-begin---author:wangshuai ---date:20230328 for:[QQYUN-4883]钉钉auth登录同一个租户下有同一个用户id------------
|
||||
// 代码逻辑说明: [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());
|
||||
}
|
||||
if(oConvertUtils.isEmpty(sysUser.getAvatar())){
|
||||
sysUser.setAvatar(account.getAvatar());
|
||||
}
|
||||
//update-end-author:wangshuai date:20201118 for:如果真实姓名和头像不存在就取第三方登录的
|
||||
JSONObject obj = new JSONObject();
|
||||
//第三方登确定登录租户和部门逻辑
|
||||
this.setUserTenantAndDepart(sysUser,obj,result);
|
||||
@ -292,10 +284,9 @@ public class ThirdLoginController {
|
||||
String thirdUserUuid = jsonObject.getString("thirdUserUuid");
|
||||
// 校验验证码
|
||||
String captcha = jsonObject.getString("captcha");
|
||||
//update-begin-author:taoyan date:2022-9-13 for: VUEN-2245 【漏洞】发现新漏洞待处理20220906
|
||||
// 代码逻辑说明: VUEN-2245 【漏洞】发现新漏洞待处理20220906
|
||||
String redisKey = CommonConstant.PHONE_REDIS_KEY_PRE+phone;
|
||||
Object captchaCache = redisUtil.get(redisKey);
|
||||
//update-end-author:taoyan date:2022-9-13 for: VUEN-2245 【漏洞】发现新漏洞待处理20220906
|
||||
if (oConvertUtils.isEmpty(captcha) || !captcha.equals(captchaCache)) {
|
||||
result.setMessage("验证码错误");
|
||||
result.setSuccess(false);
|
||||
@ -357,13 +348,11 @@ public class ThirdLoginController {
|
||||
builder.append("#wechat_redirect");
|
||||
url = builder.toString();
|
||||
} 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");
|
||||
@ -382,9 +371,8 @@ public class ThirdLoginController {
|
||||
builder.append("&scope=openid");
|
||||
// 跟随authCode原样返回。
|
||||
builder.append("&state=").append(state);
|
||||
//update-begin---author:wangshuai ---date:20220613 for:[issues/I5BOUF]oauth2 钉钉无法登录------------
|
||||
// 代码逻辑说明: [issues/I5BOUF]oauth2 钉钉无法登录------------
|
||||
builder.append("&prompt=").append("consent");
|
||||
//update-end---author:wangshuai ---date:20220613 for:[issues/I5BOUF]oauth2 钉钉无法登录--------------
|
||||
url = builder.toString();
|
||||
} else {
|
||||
return "不支持的source";
|
||||
@ -430,8 +418,7 @@ public class ThirdLoginController {
|
||||
return "不支持的source";
|
||||
}
|
||||
try {
|
||||
|
||||
//update-begin-author:taoyan date:2022-6-30 for: 工作流发送消息 点击消息链接跳转办理页面
|
||||
// 代码逻辑说明: 工作流发送消息 点击消息链接跳转办理页面
|
||||
String redirect = "";
|
||||
if (state.indexOf("?") > 0) {
|
||||
String[] arr = state.split("\\?");
|
||||
@ -443,15 +430,13 @@ public class ThirdLoginController {
|
||||
|
||||
String token = saveToken(loginUser);
|
||||
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 钉钉无法登录------------
|
||||
// 代码逻辑说明: [issues/I5BOUF]oauth2 钉钉无法登录------------
|
||||
state += "&thirdType=" + source;
|
||||
//state += "&thirdType=" + "wechat_enterprise";
|
||||
if (redirect != null && redirect.length() > 0) {
|
||||
state += "&" + redirect;
|
||||
}
|
||||
//update-end-author:taoyan date:2022-6-30 for: 工作流发送消息 点击消息链接跳转办理页面
|
||||
|
||||
//update-end---author:wangshuai ---date:20220613 for:[issues/I5BOUF]oauth2 钉钉无法登录------------
|
||||
log.info("OAuth2登录重定向地址: " + state);
|
||||
try {
|
||||
response.sendRedirect(state);
|
||||
|
||||
@ -79,6 +79,9 @@ public class SysAppVersion implements Serializable {
|
||||
/**热更新路径*/
|
||||
@Schema(description = "热更新路径")
|
||||
private String wgtUrl;
|
||||
/**热更新路径*/
|
||||
@Schema(description = "桌面端下载路径")
|
||||
private String webDownloadUrl;
|
||||
/**更新内容*/
|
||||
@Schema(description = "更新内容")
|
||||
private String updateNote;
|
||||
|
||||
@ -84,12 +84,10 @@ public class SysDataLog implements Serializable {
|
||||
private String dataVersion;
|
||||
|
||||
|
||||
//update-begin-author:taoyan date:2022-7-26 for: 用于表单评论记录日志 区分数据
|
||||
/**
|
||||
* 类型
|
||||
* 类型,用于表单评论记录日志 区分数据
|
||||
*/
|
||||
private String type;
|
||||
//update-end-author:taoyan date:2022-7-26 for: 用于表单评论记录日志 区分数据
|
||||
|
||||
/**
|
||||
* 通过 loginUser 设置 createName
|
||||
|
||||
@ -240,7 +240,36 @@ public class SysUser implements Serializable {
|
||||
/**
|
||||
* 职务(字典)
|
||||
*/
|
||||
@Excel(name = "职务", width = 15, dicCode = "position_type")
|
||||
@Dict(dicCode = "position_type")
|
||||
@Excel(name = "职务", width = 15, dicCode = "user_position")
|
||||
@Dict(dicCode = "user_position")
|
||||
private String positionType;
|
||||
|
||||
/**
|
||||
* 上一次修改密码的时间
|
||||
*/
|
||||
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date lastPwdUpdateTime;
|
||||
|
||||
/**
|
||||
* 登录时,选择的部门,临时用,不持久化数据库(数据库字段不存在)
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private String loginOrgCode;
|
||||
|
||||
/**
|
||||
* 排序
|
||||
*/
|
||||
private Integer sort;
|
||||
|
||||
/**
|
||||
* 是否隐藏联系方式 0否1是
|
||||
*/
|
||||
private String izHideContact;
|
||||
|
||||
/**
|
||||
* 所属部门的id
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private String belongDepIds;
|
||||
}
|
||||
|
||||
@ -0,0 +1,68 @@
|
||||
package org.jeecg.modules.system.job;
|
||||
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.api.dto.message.MessageDTO;
|
||||
import org.jeecg.common.constant.enums.NoticeTypeEnum;
|
||||
import org.jeecg.common.system.api.ISysBaseAPI;
|
||||
import org.jeecg.modules.system.entity.SysUser;
|
||||
import org.jeecg.modules.system.service.ISysUserService;
|
||||
import org.quartz.Job;
|
||||
import org.quartz.JobExecutionContext;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Description: 用户更新提醒job
|
||||
*
|
||||
* @author: wangshuai
|
||||
* @date: 2025/9/13 16:20
|
||||
*/
|
||||
@Slf4j
|
||||
public class UserUpadtePwdJob implements Job {
|
||||
|
||||
@Autowired
|
||||
private ISysBaseAPI sysBaseAPI;
|
||||
|
||||
@Autowired
|
||||
private ISysUserService userService;
|
||||
|
||||
@Override
|
||||
public void execute(JobExecutionContext context) {
|
||||
//获取当前时间5个月前的时间
|
||||
// 获取当前日期
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
// 减去5个月
|
||||
calendar.add(Calendar.MONTH, -5);
|
||||
// 格式化输出
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
|
||||
String formattedDate = sdf.format(calendar.getTime());
|
||||
String startTime = formattedDate + " 00:00:00";
|
||||
String endTime = formattedDate + " 23:59:59";
|
||||
LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.between(SysUser::getLastPwdUpdateTime, startTime, endTime);
|
||||
queryWrapper.select(SysUser::getUsername,SysUser::getRealname);
|
||||
List<SysUser> list = userService.list(queryWrapper);
|
||||
if (CollectionUtil.isNotEmpty(list)){
|
||||
for (SysUser sysUser : list) {
|
||||
this.sendSysMessage(sysUser.getUsername(), sysUser.getRealname());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 发送系统消息
|
||||
*/
|
||||
private void sendSysMessage(String username, String realname) {
|
||||
String fromUser = "system";
|
||||
String title = "尊敬的"+realname+"您的密码已经5个月未修改了,请修改密码";
|
||||
MessageDTO messageDTO = new MessageDTO(fromUser, username, title, title);
|
||||
messageDTO.setNoticeType(NoticeTypeEnum.NOTICE_TYPE_PLAN.getValue());
|
||||
sysBaseAPI.sendSysAnnouncement(messageDTO);
|
||||
}
|
||||
}
|
||||
@ -3,6 +3,7 @@ package org.jeecg.modules.system.mapper;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
import org.jeecg.modules.system.entity.SysAnnouncementSend;
|
||||
import org.jeecg.modules.system.model.AnnouncementSendModel;
|
||||
|
||||
@ -43,4 +44,22 @@ public interface SysAnnouncementSendMapper extends BaseMapper<SysAnnouncementSen
|
||||
* @param userId
|
||||
*/
|
||||
void clearAllUnReadMessage(@Param("userId") String userId);
|
||||
|
||||
/**
|
||||
* 根据用户id和通告阅读表的id获取当前用户已阅读的数量
|
||||
*
|
||||
* @param id
|
||||
* @param userId
|
||||
*/
|
||||
@Select("select count(1) from sys_announcement_send where id=#{id} and user_id = #{userId} and read_flag = 1")
|
||||
long getReadCountByUserId(@Param("id") String id, @Param("userId") String userId);
|
||||
|
||||
/**
|
||||
* 根据用户id和阅读表的id获取所有阅读的数据
|
||||
*
|
||||
* @param ids
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
List<String> getReadAnnSendByUserId(@Param("ids") List<String> ids, @Param("userId") String userId);
|
||||
}
|
||||
|
||||
@ -7,6 +7,7 @@ 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.SysUserSysDepPostModel;
|
||||
import org.jeecg.modules.system.vo.SysDepartExportVo;
|
||||
import org.jeecg.modules.system.vo.SysDepartPositionVo;
|
||||
import org.jeecg.modules.system.vo.SysUserDepVo;
|
||||
@ -209,7 +210,7 @@ public interface SysDepartMapper extends BaseMapper<SysDepart> {
|
||||
* @param parentId
|
||||
* @return
|
||||
*/
|
||||
@Select("select id, depart_name, parent_id, iz_leaf, org_category, org_code from sys_depart where parent_id = #{parentId} order by depart_order,create_time desc")
|
||||
@Select("select id, depart_name, parent_id, iz_leaf, org_category, org_code, depart_order from sys_depart where parent_id = #{parentId} order by depart_order,create_time desc")
|
||||
List<SysDepart> getDepartByParentId(@Param("parentId") String parentId);
|
||||
|
||||
/**
|
||||
@ -251,4 +252,63 @@ public interface SysDepartMapper extends BaseMapper<SysDepart> {
|
||||
* @return
|
||||
*/
|
||||
String getPostNameByPostId(@Param("depId") String depId);
|
||||
|
||||
/**
|
||||
* 根据部门code获取部门数据
|
||||
*
|
||||
* @param orgCode
|
||||
* @return
|
||||
*/
|
||||
@Select("select depart_name, id, iz_leaf, org_category, parent_id, org_code from sys_depart where org_code = #{orgCode} order by depart_order,create_time desc")
|
||||
SysDepart queryDepartByOrgCode(@Param("orgCode") String orgCode);
|
||||
|
||||
/**
|
||||
* 根据部门父id获取部门岗位数据
|
||||
*
|
||||
* @param parentIds
|
||||
* @return
|
||||
*/
|
||||
List<SysDepart> getDepartPositionByParentIds(@Param("parentIds") List<String> parentIds);
|
||||
|
||||
/**
|
||||
* 根据用户id集合获取用户的兼职岗位信息
|
||||
*
|
||||
* @param userIdList
|
||||
* @return
|
||||
*/
|
||||
List<SysUserSysDepPostModel> getDepartOtherPostByUserIds(@Param("userIdList") List<String> userIdList);
|
||||
|
||||
/**
|
||||
* 获取没有父级id的部门数据
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Select("select id, org_code, depart_order from sys_depart where parent_id is null or parent_id = '' order by depart_order,create_time desc")
|
||||
List<SysDepart> getDepartNoParent();
|
||||
|
||||
/**
|
||||
* 根据父级id统计子节点数量
|
||||
*
|
||||
* @param parentId
|
||||
* @return
|
||||
*/
|
||||
@Select("select count(1) from sys_depart where parent_id = #{parentId}")
|
||||
long countByParentId(@Param("parentId") String parentId);
|
||||
|
||||
/**
|
||||
* 根据用户名和分类查询
|
||||
* @param username
|
||||
* @param category
|
||||
* @return
|
||||
*/
|
||||
List<SysDepart> queryDeptByUserAndCategory(@Param("username")String username, @Param("category")String category);
|
||||
|
||||
/**
|
||||
* 获取负责部门
|
||||
*
|
||||
* @param page
|
||||
* @param departId
|
||||
* @return
|
||||
*/
|
||||
List<SysUser> getDepartmentHead(@Param("page") Page<SysUser> page, @Param("departId") String departId);
|
||||
}
|
||||
|
||||
@ -31,7 +31,6 @@ public interface SysLogMapper extends BaseMapper<SysLog> {
|
||||
*/
|
||||
Long findTotalVisitCount();
|
||||
|
||||
//update-begin--Author:zhangweijian Date:20190428 for:传入开始时间,结束时间参数
|
||||
/**
|
||||
* 获取系统今日访问次数
|
||||
* @param dayStart 开始时间
|
||||
@ -47,7 +46,6 @@ public interface SysLogMapper extends BaseMapper<SysLog> {
|
||||
* @return Long
|
||||
*/
|
||||
Long findTodayIp(@Param("dayStart") Date dayStart, @Param("dayEnd") Date dayEnd);
|
||||
//update-end--Author:zhangweijian Date:20190428 for:传入开始时间,结束时间参数
|
||||
|
||||
/**
|
||||
* 首页:根据时间统计访问数量/ip数量
|
||||
|
||||
@ -8,6 +8,7 @@ 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;
|
||||
import org.jeecg.modules.system.model.SysUserSysDepPostModel;
|
||||
|
||||
/**
|
||||
* @Description: 用户部门mapper接口
|
||||
@ -98,4 +99,12 @@ public interface SysUserDepartMapper extends BaseMapper<SysUserDepart>{
|
||||
*/
|
||||
@Select("SELECT COUNT(*) FROM sys_user_depart WHERE user_id = #{userId} AND dep_id = #{departId}")
|
||||
Long getCountByDepartIdAndUserId(String userId, String departId);
|
||||
|
||||
/**
|
||||
* 通过用户id集合获取用户id和部门code
|
||||
*
|
||||
* @param userIdList
|
||||
* @return
|
||||
*/
|
||||
List<SysUserSysDepPostModel> getUserDepPostByUserIds(@Param("userIdList") List<String> userIdList);
|
||||
}
|
||||
|
||||
@ -36,6 +36,13 @@ public interface SysUserMapper extends BaseMapper<SysUser> {
|
||||
* @return
|
||||
*/
|
||||
public String getUserIdByName(@Param("username") String username);
|
||||
|
||||
/**
|
||||
* 通过用户账号查询用户Id
|
||||
* @param userIds
|
||||
* @return
|
||||
*/
|
||||
public List<String> getUsernameByIds(@Param("userIds") List<String> userIds);
|
||||
|
||||
/**
|
||||
* 根据部门Id查询用户信息
|
||||
@ -254,4 +261,14 @@ public interface SysUserMapper extends BaseMapper<SysUser> {
|
||||
* @return
|
||||
*/
|
||||
IPage<SysUser> getDepartPostListByIdUserRealName(@Param("page") Page<SysUser> page, @Param("username") String username, @Param("realname") String realname, @Param("orgCode") String orgCode);
|
||||
|
||||
/**
|
||||
* 查询部门下的用户包括子部门下的用户
|
||||
*
|
||||
* @param page
|
||||
* @param orgCode
|
||||
* @param userParams
|
||||
* @return
|
||||
*/
|
||||
List<SysUserSysDepPostModel> queryDepartUserByOrgCode(@Param("page") IPage page, @Param("orgCode") String orgCode, @Param("userParams") SysUser userParams);
|
||||
}
|
||||
|
||||
@ -40,7 +40,8 @@
|
||||
sa.msg_abstract,
|
||||
sa.files,
|
||||
sa.visits_num,
|
||||
sa.iz_top
|
||||
sa.iz_top,
|
||||
sa.notice_type
|
||||
from sys_announcement_send sas
|
||||
left join sys_announcement sa ON sas.annt_id = sa.id
|
||||
where sa.send_status = '1'
|
||||
@ -51,6 +52,15 @@
|
||||
</if>
|
||||
<if test="announcementSendModel.sender !=null and announcementSendModel.sender != ''">
|
||||
and sa.sender LIKE concat(concat('%',#{announcementSendModel.sender}),'%')
|
||||
</if>
|
||||
<if test="announcementSendModel.noticeType !=null and announcementSendModel.noticeType != ''">
|
||||
and sa.notice_type = #{announcementSendModel.noticeType}
|
||||
</if>
|
||||
<if test="announcementSendModel.noticeTypeList !=null and announcementSendModel.noticeTypeList.size() > 0">
|
||||
and sa.notice_type in
|
||||
<foreach collection="announcementSendModel.noticeTypeList" index="index" item="noticeType" open="(" separator="," close=")">
|
||||
#{noticeType}
|
||||
</foreach>
|
||||
</if>
|
||||
<if test="announcementSendModel.readFlag !=null">
|
||||
and sas.read_flag = #{announcementSendModel.readFlag}
|
||||
@ -115,4 +125,13 @@
|
||||
where user_id = #{userId} and read_flag = 0
|
||||
</update>
|
||||
|
||||
<!-- 根据用户id和阅读表的id获取所有阅读的数据 -->
|
||||
<select id="getReadAnnSendByUserId" resultType="java.lang.String">
|
||||
select id from sys_announcement_send
|
||||
where user_id = #{userId} and read_flag = 1
|
||||
and id in
|
||||
<foreach collection="ids" index="index" item="id" open="(" separator="," close=")">
|
||||
#{id}
|
||||
</foreach>
|
||||
</select>
|
||||
</mapper>
|
||||
@ -32,6 +32,24 @@
|
||||
)
|
||||
</select>
|
||||
|
||||
<!-- 根据username和分类查询所拥有的部门/岗位/公司 -->
|
||||
<select id="queryDeptByUserAndCategory" parameterType="String" resultType="org.jeecg.modules.system.entity.SysDepart">
|
||||
SELECT *
|
||||
FROM sys_depart
|
||||
WHERE id IN (
|
||||
SELECT dep_id
|
||||
FROM sys_user_depart
|
||||
WHERE user_id = (
|
||||
SELECT id
|
||||
FROM sys_user
|
||||
WHERE username = #{username}
|
||||
)
|
||||
)
|
||||
<if test="category != null and category != ''">
|
||||
AND org_category = #{category}
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<!-- 根据部门Id查询,当前和下级所有部门IDS -->
|
||||
<select id="getSubDepIdsByDepId" resultType="java.lang.String">
|
||||
select id from sys_depart where del_flag = '0' and org_code like concat((select org_code from sys_depart where id=#{departId}),'%')
|
||||
@ -175,16 +193,13 @@
|
||||
1=1
|
||||
<if test="null != tenantId and 0 != tenantId">
|
||||
AND tenant_id = #{tenantId}
|
||||
</if>
|
||||
AND
|
||||
<choose>
|
||||
<when test="parentId != null and parentId != ''">
|
||||
parent_id = #{parentId}
|
||||
</when>
|
||||
<otherwise>
|
||||
(parent_id IS NULL OR parent_id='')
|
||||
</otherwise>
|
||||
</choose>
|
||||
</if>
|
||||
<if test="parentId != null and parentId != '' and parentId != '-1'">
|
||||
AND parent_id = #{parentId}
|
||||
</if>
|
||||
<if test="parentId == '-1'">
|
||||
AND (parent_id IS NULL OR parent_id='')
|
||||
</if>
|
||||
<if test="idList != null and !idList.isEmpty()">
|
||||
and id in
|
||||
<foreach item="id" index="index" collection="idList" open="(" separator="," close=")">
|
||||
@ -268,4 +283,35 @@
|
||||
select sp.name from sys_depart sd join sys_position sp on sd.position_id = sp.id
|
||||
where sd.id = #{depId}
|
||||
</select>
|
||||
|
||||
<!-- 根据部门父id获取部门岗位数据 -->
|
||||
<select id="getDepartPositionByParentIds" resultType="org.jeecg.modules.system.entity.SysDepart">
|
||||
select sd.depart_name, sd.id, sd.iz_leaf, sd.org_category, sd.parent_id, sd.org_code from sys_depart sd left join sys_position sp on sd.position_id = sp.id
|
||||
where sd.parent_id in
|
||||
<foreach collection="parentIds" index="index" item="item" open="(" separator="," close=")">
|
||||
#{item}
|
||||
</foreach>
|
||||
and sd.org_category = '3'
|
||||
order by sd.depart_order,sd.create_time desc
|
||||
</select>
|
||||
|
||||
<!-- 根据用户id集合获取用户的兼职岗位信息 -->
|
||||
<select id="getDepartOtherPostByUserIds" resultType="org.jeecg.modules.system.model.SysUserSysDepPostModel">
|
||||
select sudp.user_id as id, sudp.dep_id as otherDepPostId, sd.org_code
|
||||
from sys_user_dep_post sudp
|
||||
join sys_depart sd on sudp.dep_id = sd.id
|
||||
where sudp.user_id in
|
||||
<foreach collection="userIdList" index="index" item="item" open="(" separator="," close=")">
|
||||
#{item}
|
||||
</foreach>
|
||||
</select>
|
||||
|
||||
<!-- 获取负责部门 -->
|
||||
<select id="getDepartmentHead" resultType="org.jeecg.modules.system.entity.SysUser">
|
||||
select id, realname, avatar, sex, telephone, phone, main_dep_post_id, iz_hide_contact, sort, create_time from sys_user
|
||||
where status = 1 and del_flag = 0
|
||||
<bind name="bindDepartId" value="departId+'%'"/>
|
||||
and depart_ids like #{bindDepartId}
|
||||
order by sort,create_time desc
|
||||
</select>
|
||||
</mapper>
|
||||
@ -147,6 +147,9 @@
|
||||
<when test="key == 'tenant_id'">
|
||||
and tenant_id = #{value}
|
||||
</when>
|
||||
<when test="key == '_tableFilterSql'">
|
||||
and ${value}
|
||||
</when>
|
||||
<otherwise>
|
||||
and ${key} LIKE #{value}
|
||||
</otherwise>
|
||||
|
||||
@ -37,6 +37,8 @@
|
||||
<bind name="bindRealname" value="'%'+realname+'%'"/>
|
||||
and a.realname like #{bindRealname}
|
||||
</if>
|
||||
ORDER BY
|
||||
a.sort,a.create_time desc
|
||||
</select>
|
||||
|
||||
<!--获取用户信息(聊天专用)-->
|
||||
@ -82,6 +84,7 @@
|
||||
#{userId}
|
||||
</foreach>
|
||||
</if>
|
||||
order by a.sort, a.create_time desc
|
||||
</select>
|
||||
|
||||
<!--获取租户下的部门-通过前台传过来的部门id-->
|
||||
@ -125,4 +128,16 @@
|
||||
select id from sys_depart where tenant_id = #{tenantId}
|
||||
)
|
||||
</delete>
|
||||
|
||||
<!-- 通过用户id集合获取用户id和部门code -->
|
||||
<select id="getUserDepPostByUserIds" resultType="org.jeecg.modules.system.model.SysUserSysDepPostModel">
|
||||
select su.id,sd.org_code from sys_user_depart sud
|
||||
JOIN sys_user su ON sud.user_id = su.id
|
||||
JOIN sys_depart sd ON sud.dep_id = sd.id
|
||||
where
|
||||
sud.user_id in
|
||||
<foreach collection="userIdList" item="userId" open="(" close=")" separator=",">
|
||||
#{userId}
|
||||
</foreach>
|
||||
</select>
|
||||
</mapper>
|
||||
@ -11,6 +11,14 @@
|
||||
<select id="getUserIdByName" resultType="String">
|
||||
select id from sys_user where username = #{username} and del_flag = 0
|
||||
</select>
|
||||
|
||||
<!-- 根据用户ids批量查询用户账号 -->
|
||||
<select id="getUsernameByIds" resultType="String">
|
||||
select username from sys_user where del_flag = 0 and a.status = 1 and id in
|
||||
<foreach collection="userIds" index="index" item="id" open="(" separator="," close=")">
|
||||
#{id}
|
||||
</foreach>
|
||||
</select>
|
||||
|
||||
<!-- 根据部门Id查询 -->
|
||||
<select id="getUserByDepId" resultType="org.jeecg.modules.system.entity.SysUser">
|
||||
@ -75,6 +83,9 @@
|
||||
<if test="orgCode!=null and loginTenantId==null">
|
||||
org_code = #{orgCode}
|
||||
</if>
|
||||
<if test="orgCode==null and loginTenantId==null">
|
||||
org_code = #{orgCode}
|
||||
</if>
|
||||
where username = #{username}
|
||||
</update>
|
||||
|
||||
@ -129,7 +140,7 @@
|
||||
sys_depart.depart_name AS departName
|
||||
<include refid="getUserByOrgCodeFromSql"/>
|
||||
ORDER BY
|
||||
sys_depart.org_code ASC
|
||||
sys_user.sort,sys_user.create_time desc
|
||||
</select>
|
||||
|
||||
<!-- 查询 getUserByOrgCode 的总数-->
|
||||
@ -235,6 +246,7 @@
|
||||
#{userId}
|
||||
</foreach>
|
||||
</if>
|
||||
order by a.sort, a.create_time desc
|
||||
</select>
|
||||
|
||||
<!--获取租户下的用户离职列表信息-->
|
||||
@ -332,14 +344,14 @@
|
||||
<select id="getDepPostListByIdUserName" resultType="org.jeecg.modules.system.entity.SysUser">
|
||||
SELECT su.* from
|
||||
(
|
||||
SELECT su.create_time,su.realname,su.username,su.phone FROM sys_user su
|
||||
SELECT su.create_time,su.realname,su.username,su.phone,su.iz_hide_contact,su.sort FROM sys_user su
|
||||
<include refid="getDepPostListByIdUserNameSql"/>
|
||||
union
|
||||
select DISTINCT su.create_time,su.realname,su.username,su.phone FROM sys_user su
|
||||
select DISTINCT su.create_time,su.realname,su.username,su.phone,su.iz_hide_contact,su.sort FROM sys_user su
|
||||
JOIN sys_user_dep_post sudp ON su.id = sudp.user_id
|
||||
<include refid="getDepPostListByIdUserNameSql"/>
|
||||
) su
|
||||
order by su.create_time desc
|
||||
order by su.sort,su.create_time desc
|
||||
</select>
|
||||
|
||||
<!-- SQL片段:getDepartPostListByIdUserRealName WHERE部分 -->
|
||||
@ -366,16 +378,16 @@
|
||||
<select id="getDepartPostListByIdUserRealName" resultType="org.jeecg.modules.system.entity.SysUser">
|
||||
SELECT su.* from
|
||||
(
|
||||
SELECT su.create_time,su.realname,su.username,su.phone FROM sys_user su
|
||||
SELECT su.create_time,su.realname,su.username,su.phone,su.iz_hide_contact,su.sort FROM sys_user su
|
||||
join sys_depart sd on su.main_dep_post_id = sd.id
|
||||
<include refid="getDepartPostListByIdUserRealNameSql"/>
|
||||
union
|
||||
SELECT DISTINCT su.create_time,su.realname,su.username,su.phone FROM sys_user su
|
||||
SELECT DISTINCT su.create_time,su.realname,su.username,su.phone,su.iz_hide_contact,su.sort FROM sys_user su
|
||||
join sys_depart sd on su.main_dep_post_id = sd.id
|
||||
join sys_user_dep_post sudp on su.id = sudp.user_id
|
||||
<include refid="getDepartPostListByIdUserRealNameSql"/>
|
||||
) su
|
||||
order by su.create_time desc
|
||||
order by su.sort,su.create_time desc
|
||||
</select>
|
||||
|
||||
<!-- SQL片段:queryDepartPostUserByOrgCode WHERE部分 -->
|
||||
@ -404,22 +416,50 @@
|
||||
SELECT su.* from
|
||||
(
|
||||
SELECT su.id, su.create_time, su.realname, su.username, su.phone, su.avatar, su.birthday, su.sex, su.email,
|
||||
su.status, su.del_flag, su.telephone, su.activiti_sync, su.user_identity, su.depart_ids, su.main_dep_post_id
|
||||
su.status, su.del_flag, su.telephone, su.activiti_sync, su.user_identity, su.depart_ids, su.main_dep_post_id,
|
||||
su.sort,su.iz_hide_contact,su.position_type,su.work_no
|
||||
FROM sys_user su join sys_user_depart sud on su.id = sud.user_id
|
||||
join sys_depart sd on sud.dep_id = sd.id
|
||||
<include refid="queryDepartPostUserByOrgCodeSql"/>
|
||||
union
|
||||
SELECT su.id, su.create_time, su.realname, su.username, su.phone, su.avatar, su.birthday, su.sex, su.email,
|
||||
su.status, su.del_flag, su.telephone, su.activiti_sync, su.user_identity, su.depart_ids, su.main_dep_post_id
|
||||
su.status, su.del_flag, su.telephone, su.activiti_sync, su.user_identity, su.depart_ids, su.main_dep_post_id,
|
||||
su.sort,su.iz_hide_contact,su.position_type,su.work_no
|
||||
FROM sys_user su join sys_depart sd on su.main_dep_post_id = sd.id
|
||||
<include refid="queryDepartPostUserByOrgCodeSql"/>
|
||||
union
|
||||
SELECT su.id, su.create_time, su.realname, su.username, su.phone, su.avatar, su.birthday, su.sex, su.email,
|
||||
su.status, su.del_flag, su.telephone, su.activiti_sync, su.user_identity, su.depart_ids, su.main_dep_post_id
|
||||
su.status, su.del_flag, su.telephone, su.activiti_sync, su.user_identity, su.depart_ids, su.main_dep_post_id,
|
||||
su.sort,su.iz_hide_contact,su.position_type,su.work_no
|
||||
FROM sys_user su join sys_user_dep_post sudp on su.id = sudp.user_id
|
||||
join sys_depart sd on sd.id = sudp.dep_id
|
||||
<include refid="queryDepartPostUserByOrgCodeSql"/>
|
||||
) su
|
||||
order by su.create_time desc
|
||||
order by su.sort,su.create_time desc
|
||||
</select>
|
||||
|
||||
<!--查询部门下的用户包括子部门下的用户-->
|
||||
<select id="queryDepartUserByOrgCode" resultType="org.jeecg.modules.system.model.SysUserSysDepPostModel">
|
||||
SELECT DISTINCT su.id, su.realname, su.avatar, su.sex, su.birthday, su.telephone, su.email, su.phone, su.main_dep_post_id, su.iz_hide_contact, su.sort, su.create_time
|
||||
FROM sys_user su join sys_user_depart sud on su.id = sud.user_id
|
||||
join sys_depart sd on sud.dep_id = sd.id
|
||||
where
|
||||
su.status = 1
|
||||
and su.del_flag = 0
|
||||
and su.username <![CDATA[ != ]]> '_reserve_user_external'
|
||||
<if test="orgCode == null">
|
||||
<bind name="bindOrgCode" value="'%'"/>
|
||||
</if>
|
||||
<if test="orgCode != null">
|
||||
<bind name="bindOrgCode" value="orgCode+'%'"/>
|
||||
</if>
|
||||
and sd.del_flag = 0 and sd.org_code LIKE #{bindOrgCode}
|
||||
<if test="userParams != null">
|
||||
<if test="userParams.realname != null and userParams.realname != ''">
|
||||
<bind name="bindRealname" value="'%'+ userParams.realname +'%'"/>
|
||||
and su.realname like #{bindRealname}
|
||||
</if>
|
||||
</if>
|
||||
order by su.sort,su.create_time desc
|
||||
</select>
|
||||
</mapper>
|
||||
@ -7,6 +7,7 @@ import lombok.Data;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Description: 用户通告阅读标记表
|
||||
@ -95,4 +96,12 @@ public class AnnouncementSendModel implements Serializable {
|
||||
* 是否置顶(0否 1是)
|
||||
*/
|
||||
private java.lang.Integer izTop;
|
||||
/**
|
||||
* 通知类型(plan:日程计划 | flow:流程消息 | meeting:会议 | file:知识库 | collab:协同通知 | supe:督办通知 | attendance:考勤)
|
||||
*/
|
||||
private java.lang.String noticeType;
|
||||
/**
|
||||
* 通告类型数组
|
||||
*/
|
||||
private List<String> noticeTypeList;
|
||||
}
|
||||
|
||||
@ -75,10 +75,10 @@ public class SysDepartTreeModel implements Serializable{
|
||||
|
||||
private Date updateTime;
|
||||
|
||||
//update-begin---author:wangshuai ---date:20200308 for:[JTC-119]在部门管理菜单下设置部门负责人,新增字段部门负责人ids
|
||||
/**部门负责人ids*/
|
||||
/**部门负责人ids
|
||||
* [JTC-119]在部门管理菜单下设置部门负责人,新增字段部门负责人ids
|
||||
* */
|
||||
private String directorUserIds;
|
||||
//update-end---author:wangshuai ---date:20200308 for:[JTC-119]在部门管理菜单下设置部门负责人,新增字段部门负责人ids
|
||||
|
||||
/**职务*/
|
||||
private String positionId;
|
||||
|
||||
@ -15,6 +15,8 @@ public class SysLoginModel {
|
||||
private String username;
|
||||
@Schema(description = "密码")
|
||||
private String password;
|
||||
@Schema(description = "登录部门")
|
||||
private String loginOrgCode;
|
||||
@Schema(description = "验证码")
|
||||
private String captcha;
|
||||
@Schema(description = "验证码key")
|
||||
@ -51,5 +53,12 @@ public class SysLoginModel {
|
||||
public void setCheckKey(String checkKey) {
|
||||
this.checkKey = checkKey;
|
||||
}
|
||||
|
||||
|
||||
public String getLoginOrgCode() {
|
||||
return loginOrgCode;
|
||||
}
|
||||
|
||||
public void setLoginOrgCode(String loginOrgCode) {
|
||||
this.loginOrgCode = loginOrgCode;
|
||||
}
|
||||
}
|
||||
@ -21,11 +21,10 @@ public class SysUserSysDepPostModel {
|
||||
* 用户ID
|
||||
*/
|
||||
private String id;
|
||||
|
||||
|
||||
/**
|
||||
* 登录账号
|
||||
* 用户名
|
||||
*/
|
||||
@Excel(name = "登录账号", width = 15)
|
||||
private String username;
|
||||
|
||||
/* 真实姓名 */
|
||||
@ -143,4 +142,29 @@ public class SysUserSysDepPostModel {
|
||||
* 职务
|
||||
*/
|
||||
private String post;
|
||||
|
||||
/**
|
||||
* 部门编码
|
||||
*/
|
||||
private String orgCode;
|
||||
|
||||
/**
|
||||
* 职务(字典)
|
||||
*/
|
||||
private String positionType;
|
||||
|
||||
/**
|
||||
* 排序
|
||||
*/
|
||||
private Integer sort;
|
||||
|
||||
/**
|
||||
* 是否隐藏联系方式 0否1是
|
||||
*/
|
||||
private String izHideContact;
|
||||
|
||||
/**
|
||||
* 工号
|
||||
*/
|
||||
private String workNo;
|
||||
}
|
||||
|
||||
@ -52,19 +52,16 @@ public class CategoryCodeRule implements IFillRuleHandler {
|
||||
* */
|
||||
//找同类 确定上一个最大的code值
|
||||
SysCategoryMapper baseMapper = (SysCategoryMapper) SpringContextUtils.getBean("sysCategoryMapper");
|
||||
//update-begin---author:wangshuai ---date:20230424 for:【issues/4846】开启saas多租户功能后,租户管理员在添加分类字典时,报错------------
|
||||
// 代码逻辑说明: 【issues/4846】开启saas多租户功能后,租户管理员在添加分类字典时,报错------------
|
||||
Page<SysCategory> page = new Page<>(1,1);
|
||||
List<SysCategory> list = baseMapper.getMaxCategoryCodeByPage(page,categoryPid);
|
||||
//update-end---author:wangshuai ---date:20230424 for:【issues/4846】开启saas多租户功能后,租户管理员在添加分类字典时,报错------------
|
||||
if (list == null || list.size() == 0) {
|
||||
if (ROOT_PID_VALUE.equals(categoryPid)) {
|
||||
//情况1
|
||||
categoryCode = YouBianCodeUtil.getNextYouBianCode(null);
|
||||
} else {
|
||||
//情况2
|
||||
//update-begin---author:wangshuai ---date:20230424 for:【issues/4846】开启saas多租户功能后,租户管理员在添加分类字典时,报错------------
|
||||
SysCategory parent = (SysCategory) baseMapper.selectSysCategoryById(categoryPid);
|
||||
//update-end---author:wangshuai ---date:20230424 for:【issues/4846】开启saas多租户功能后,租户管理员在添加分类字典时,报错------------
|
||||
categoryCode = YouBianCodeUtil.getSubYouBianCode(parent.getCode(), null);
|
||||
}
|
||||
} else {
|
||||
|
||||
@ -56,12 +56,11 @@ public class OrgCodeRule implements IFillRuleHandler {
|
||||
if (StringUtil.isNullOrEmpty(parentId)) {
|
||||
// 线判断数据库中的表是否为空,空则直接返回初始编码
|
||||
//获取最大值code的部门信息
|
||||
//update-begin---author:wangshuai ---date:20230211 for:[QQYUN-4209]租户隔离下部门新建不了------------
|
||||
// 代码逻辑说明: [QQYUN-4209]租户隔离下部门新建不了------------
|
||||
Page<SysDepart> page = new Page<>(1,1);
|
||||
IPage<SysDepart> pageList = sysDepartService.getMaxCodeDepart(page,"");
|
||||
List<SysDepart> records = pageList.getRecords();
|
||||
if (null==records || records.size()==0) {
|
||||
//update-end---author:wangshuai ---date:20230211 for:[QQYUN-4209]租户隔离下部门新建不了------------
|
||||
strArray[0] = YouBianCodeUtil.getNextYouBianCode(null);
|
||||
strArray[1] = "1";
|
||||
return strArray;
|
||||
@ -73,13 +72,12 @@ public class OrgCodeRule implements IFillRuleHandler {
|
||||
}
|
||||
} else {//反之则查询出所有同级的部门,获取结果后有两种情况,有同级和没有同级
|
||||
//获取自己部门最大值orgCode部门信息
|
||||
//update-begin---author:wangshuai ---date:20230211 for:[QQYUN-4209]租户隔离下部门新建不了------------
|
||||
// 代码逻辑说明: [QQYUN-4209]租户隔离下部门新建不了------------
|
||||
Page<SysDepart> page = new Page<>(1,1);
|
||||
IPage<SysDepart> pageList = sysDepartService.getMaxCodeDepart(page,parentId);
|
||||
List<SysDepart> records = pageList.getRecords();
|
||||
// 查询出父级部门
|
||||
SysDepart depart = sysDepartService.getDepartById(parentId);
|
||||
//update-end---author:wangshuai ---date:20230211 for:[QQYUN-4209]租户隔离下部门新建不了------------
|
||||
// 获取父级部门的Code
|
||||
String parentCode = depart.getOrgCode();
|
||||
// 根据父级部门类型算出当前部门的类型
|
||||
|
||||
@ -31,4 +31,25 @@ public interface ISysAnnouncementSendService extends IService<SysAnnouncementSen
|
||||
AnnouncementSendModel getOne(String sendId);
|
||||
|
||||
|
||||
/**
|
||||
* 获取当前用户已阅读的内容
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
long getReadCountByUserId(String id);
|
||||
|
||||
/**
|
||||
* 根据多个id批量删除已阅读的数量
|
||||
*
|
||||
* @param ids
|
||||
*/
|
||||
void deleteBatchByIds(String ids);
|
||||
|
||||
/**
|
||||
* 根据id更新阅读状态
|
||||
* @param busId
|
||||
* @param busType
|
||||
*/
|
||||
void updateReadFlagByBusId(String busId, String busType);
|
||||
}
|
||||
|
||||
@ -2,10 +2,10 @@ package org.jeecg.modules.system.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.jeecg.modules.system.entity.SysAnnouncement;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@ -5,13 +5,14 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import org.jeecg.modules.system.entity.SysDepart;
|
||||
import org.jeecg.modules.system.entity.SysUser;
|
||||
import org.jeecg.modules.system.model.DepartIdModel;
|
||||
import org.jeecg.modules.system.model.SysDepartTreeModel;
|
||||
import org.jeecg.modules.system.vo.SysChangeDepartVo;
|
||||
import org.jeecg.modules.system.vo.SysDepartExportVo;
|
||||
import org.jeecg.modules.system.vo.SysPositionSelectTreeVo;
|
||||
import org.jeecg.modules.system.vo.lowapp.ExportDepartVo;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -279,4 +280,29 @@ public interface ISysDepartService extends IService<SysDepart>{
|
||||
* @return
|
||||
*/
|
||||
String getDepartPathNameByOrgCode(String orgCode, String depId);
|
||||
|
||||
/**
|
||||
* 根据部门id获取部门下的岗位id
|
||||
*
|
||||
* @param depIds 当前选择的公司、子公司、部门id
|
||||
* @return
|
||||
*/
|
||||
String getDepPostIdByDepId(String depIds);
|
||||
|
||||
/**
|
||||
* 调整部门位置
|
||||
*
|
||||
* @param changeDepartVo
|
||||
* @return
|
||||
*/
|
||||
void updateChangeDepart(SysChangeDepartVo changeDepartVo);
|
||||
|
||||
/**
|
||||
* 获取部门负责人
|
||||
*
|
||||
* @param departId
|
||||
* @param page
|
||||
* @return
|
||||
*/
|
||||
IPage<SysUser> getDepartmentHead(String departId, Page<SysUser> page);
|
||||
}
|
||||
|
||||
@ -107,7 +107,6 @@ public interface ISysDictService extends IService<SysDict> {
|
||||
@Deprecated
|
||||
String queryTableDictTextByKey(String table, String text, String code, String key);
|
||||
|
||||
//update-begin---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
/**
|
||||
* 通过查询指定table的 text code key 获取字典值,可批量查询
|
||||
*
|
||||
@ -119,7 +118,6 @@ public interface ISysDictService extends IService<SysDict> {
|
||||
* @return
|
||||
*/
|
||||
List<DictModel> queryTableDictTextByKeys(String table, String text, String code, List<String> keys, String dataSource);
|
||||
//update-end---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
|
||||
/**
|
||||
* 通过查询指定table的 text code key 获取字典值,包含value
|
||||
|
||||
@ -30,7 +30,6 @@ public interface ISysLogService extends IService<SysLog> {
|
||||
*/
|
||||
Long findTotalVisitCount();
|
||||
|
||||
//update-begin--Author:zhangweijian Date:20190428 for:传入开始时间,结束时间参数
|
||||
/**
|
||||
* 获取系统今日访问次数
|
||||
* @param dayStart
|
||||
@ -46,7 +45,6 @@ public interface ISysLogService extends IService<SysLog> {
|
||||
* @return Long
|
||||
*/
|
||||
Long findTodayIp(Date dayStart, Date dayEnd);
|
||||
//update-end--Author:zhangweijian Date:20190428 for:传入开始时间,结束时间参数
|
||||
|
||||
/**
|
||||
* 首页:根据时间统计访问数量/ip数量
|
||||
|
||||
@ -45,4 +45,13 @@ public interface ISysRoleIndexService extends IService<SysRoleIndex> {
|
||||
* @param sysRoleIndex
|
||||
*/
|
||||
void changeDefHome(SysRoleIndex sysRoleIndex);
|
||||
|
||||
/**
|
||||
* 更新其他全局默认的状态值
|
||||
*
|
||||
* @param roleCode
|
||||
* @param status
|
||||
* @param id
|
||||
*/
|
||||
void updateOtherDefaultStatus(String roleCode, String status, String id);
|
||||
}
|
||||
|
||||
@ -77,7 +77,7 @@ public interface ISysUserDepartService extends IService<SysUserDepart> {
|
||||
* @param pageNo
|
||||
* @return
|
||||
*/
|
||||
IPage<SysUser> getUserInformation(Integer tenantId,String departId,String roleId, String keyword, Integer pageSize, Integer pageNo, String excludeUserIdList);
|
||||
IPage<SysUser> getUserInformation(Integer tenantId,String departId,String roleId, String keyword, Integer pageSize, Integer pageNo, String excludeUserIdList, String includeUsernameList);
|
||||
|
||||
/**
|
||||
* 通过部门id和租户id获取多个用户
|
||||
|
||||
@ -158,9 +158,7 @@ public interface ISysUserService extends IService<SysUser> {
|
||||
* @param queryWrapper
|
||||
* @return
|
||||
*/
|
||||
//update-begin-author:taoyan date:2022-9-13 for: VUEN-2245【漏洞】发现新漏洞待处理20220906 ----sql注入 方法没有使用,注掉
|
||||
// public IPage<SysUser> getUserByDepartIdAndQueryWrapper(Page<SysUser> page, String departId, QueryWrapper<SysUser> queryWrapper);
|
||||
//update-end-author:taoyan date:2022-9-13 for: VUEN-2245【漏洞】发现新漏洞待处理20220906 ----sql注入 方法没有使用,注掉
|
||||
|
||||
/**
|
||||
* 根据 orgCode 查询用户,包括子部门下的用户
|
||||
@ -503,4 +501,41 @@ public interface ISysUserService extends IService<SysUser> {
|
||||
*/
|
||||
IPage<SysUserSysDepPostModel> queryDepartPostUserByOrgCode(String orgCode, SysUser userParams, IPage page);
|
||||
|
||||
/**
|
||||
* 根据 orgCode 查询用户信息(部门全路径,主岗位和兼职岗位的信息),包括公司、子公司、部门
|
||||
*
|
||||
* @param orgCode
|
||||
* @param userParams
|
||||
* @param page
|
||||
* @return
|
||||
*/
|
||||
IPage<SysUserSysDepPostModel> queryDepartUserByOrgCode(String orgCode, SysUser userParams, IPage page);
|
||||
|
||||
/**
|
||||
* 通讯录点击用户获取用户详情(包含用户基本信息、部门全路径、主岗位兼职岗位全路径)
|
||||
*
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
SysUserSysDepPostModel getUserDetailByUserId(String userId);
|
||||
|
||||
/**
|
||||
* 登录获取用户部门信息
|
||||
* @param jsonObject
|
||||
* @return
|
||||
*/
|
||||
Result loginGetUserDeparts(JSONObject jsonObject);
|
||||
|
||||
/**
|
||||
* 根据用户名查询重置成系统密码
|
||||
* @param usernames
|
||||
*/
|
||||
void resetToSysPassword(String usernames);
|
||||
|
||||
/**
|
||||
* 更新用户设备ID
|
||||
* @param clientId
|
||||
* @param userId
|
||||
*/
|
||||
void updateClientId(String clientId,String userId);
|
||||
}
|
||||
|
||||
@ -27,12 +27,11 @@ public class ImportFileServiceImpl implements ImportFileServiceI {
|
||||
|
||||
@Override
|
||||
public String doUpload(byte[] data, String saveUrl) {
|
||||
//update-begin---author:chenrui ---date:20250114 for:[QQYUN-10902]AutoPoi Excel表格导入有问题,还会报个错。 #7703------------
|
||||
// 代码逻辑说明: [QQYUN-10902]AutoPoi Excel表格导入有问题,还会报个错。 #7703------------
|
||||
String bizPath = "import";
|
||||
if(null != saveUrl && !saveUrl.isEmpty()){
|
||||
bizPath = saveUrl;
|
||||
}
|
||||
return CommonUtils.uploadOnlineImage(data, upLoadPath, bizPath, uploadType);
|
||||
//update-end---author:chenrui ---date:20250114 for:[QQYUN-10902]AutoPoi Excel表格导入有问题,还会报个错。 #7703------------
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,13 +1,27 @@
|
||||
package org.jeecg.modules.system.service.impl;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.constant.SymbolConstant;
|
||||
import org.jeecg.common.system.vo.LoginUser;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.modules.system.entity.SysAnnouncement;
|
||||
import org.jeecg.modules.system.entity.SysAnnouncementSend;
|
||||
import org.jeecg.modules.system.mapper.SysAnnouncementMapper;
|
||||
import org.jeecg.modules.system.mapper.SysAnnouncementSendMapper;
|
||||
import org.jeecg.modules.system.model.AnnouncementSendModel;
|
||||
import org.jeecg.modules.system.service.ISysAnnouncementSendService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
@ -24,7 +38,10 @@ public class SysAnnouncementSendServiceImpl extends ServiceImpl<SysAnnouncementS
|
||||
|
||||
@Resource
|
||||
private SysAnnouncementSendMapper sysAnnouncementSendMapper;
|
||||
|
||||
|
||||
@Autowired
|
||||
private SysAnnouncementMapper sysAnnouncementMapper;
|
||||
|
||||
@Override
|
||||
public Page<AnnouncementSendModel> getMyAnnouncementSendPage(Page<AnnouncementSendModel> page,
|
||||
AnnouncementSendModel announcementSendModel) {
|
||||
@ -36,4 +53,51 @@ public class SysAnnouncementSendServiceImpl extends ServiceImpl<SysAnnouncementS
|
||||
return sysAnnouncementSendMapper.getOne(sendId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前用户已阅读数量
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public long getReadCountByUserId(String id) {
|
||||
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
return sysAnnouncementSendMapper.getReadCountByUserId(id, sysUser.getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据多个id批量删除已阅读的数量
|
||||
*
|
||||
* @param ids
|
||||
*/
|
||||
@Override
|
||||
public void deleteBatchByIds(String ids) {
|
||||
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
//根据用户id和阅读表的id获取所有阅读的数据
|
||||
List<String> sendIds = sysAnnouncementSendMapper.getReadAnnSendByUserId(Arrays.asList(ids.split(SymbolConstant.COMMA)),sysUser.getId());
|
||||
if(CollectionUtil.isNotEmpty(sendIds)){
|
||||
this.removeByIds(sendIds);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据busId更新阅读状态
|
||||
* @param busId
|
||||
* @param busType
|
||||
*/
|
||||
@Override
|
||||
public void updateReadFlagByBusId(String busId, String busType) {
|
||||
SysAnnouncement announcement = sysAnnouncementMapper.selectOne(new QueryWrapper<SysAnnouncement>().eq("bus_type",busType).eq("bus_id",busId));
|
||||
if(oConvertUtils.isNotEmpty(announcement)){
|
||||
LoginUser sysUser = (LoginUser)SecurityUtils.getSubject().getPrincipal();
|
||||
String userId = sysUser.getId();
|
||||
LambdaUpdateWrapper<SysAnnouncementSend> updateWrapper = new UpdateWrapper().lambda();
|
||||
updateWrapper.set(SysAnnouncementSend::getReadFlag, CommonConstant.HAS_READ_FLAG);
|
||||
updateWrapper.set(SysAnnouncementSend::getReadTime, new Date());
|
||||
updateWrapper.eq(SysAnnouncementSend::getAnntId,announcement.getId());
|
||||
updateWrapper.eq(SysAnnouncementSend::getUserId,userId);
|
||||
SysAnnouncementSend announcementSend = new SysAnnouncementSend();
|
||||
sysAnnouncementSendMapper.update(announcementSend, updateWrapper);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,8 +4,6 @@ import cn.hutool.core.io.IoUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.compress.archivers.zip.Zip64Mode;
|
||||
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
|
||||
@ -29,9 +27,11 @@ import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.io.*;
|
||||
import java.net.URLEncoder;
|
||||
import jakarta.annotation.Resource;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.SynchronousQueue;
|
||||
@ -73,12 +73,11 @@ public class SysAnnouncementServiceImpl extends ServiceImpl<SysAnnouncementMappe
|
||||
sysAnnouncementMapper.insert(sysAnnouncement);
|
||||
// 2.插入用户通告阅读标记表记录
|
||||
String userId = sysAnnouncement.getUserIds();
|
||||
//update-begin-author:liusq---date:2023-10-31--for:[issues/5503]【公告】通知无法接收
|
||||
// 代码逻辑说明: [issues/5503]【公告】通知无法接收
|
||||
if(StringUtils.isNotBlank(userId) && userId.endsWith(",")){
|
||||
userId = userId.substring(0, (userId.length()-1));
|
||||
}
|
||||
String[] userIds = userId.split(",");
|
||||
//update-end-author:liusq---date:2023-10-31--for:[issues/5503]【公告】通知无法接收
|
||||
String anntId = sysAnnouncement.getId();
|
||||
Date refDate = new Date();
|
||||
for(int i=0;i<userIds.length;i++) {
|
||||
@ -216,7 +215,7 @@ public class SysAnnouncementServiceImpl extends ServiceImpl<SysAnnouncementMappe
|
||||
// });
|
||||
|
||||
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
log.info(" 获取登录人 LoginUser id: {}", sysUser.getId());
|
||||
log.debug(" 获取登录人 LoginUser id: {}", sysUser.getId());
|
||||
Page<SysAnnouncement> page = new Page<SysAnnouncement>(pageNo,pageSize);
|
||||
List<SysAnnouncement> list = baseMapper.queryAllMessageList(page, sysUser.getId(), fromUser, starFlag, busType, msgCategory,beginDate, endDate, noticeType);
|
||||
return list;
|
||||
|
||||
@ -24,6 +24,7 @@ import org.apache.shiro.SecurityUtils;
|
||||
import org.jeecg.common.api.dto.AiragFlowDTO;
|
||||
import org.jeecg.common.api.dto.DataLogDTO;
|
||||
import org.jeecg.common.api.dto.OnlineAuthDTO;
|
||||
import org.jeecg.common.api.dto.PushMessageDTO;
|
||||
import org.jeecg.common.api.dto.message.*;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.aspect.UrlMatchEnum;
|
||||
@ -41,7 +42,6 @@ import org.jeecg.common.util.dynamic.db.FreemarkerParseFactory;
|
||||
import org.jeecg.config.firewall.SqlInjection.IDictTableWhiteListHandler;
|
||||
import org.jeecg.config.mybatis.MybatisPlusSaasConfig;
|
||||
import org.jeecg.modules.airag.flow.service.IAiragFlowService;
|
||||
import org.jeecg.modules.airag.flow.vo.api.FlowRunParams;
|
||||
import org.jeecg.modules.message.entity.SysMessageTemplate;
|
||||
import org.jeecg.modules.message.handle.impl.DdSendMsgHandle;
|
||||
import org.jeecg.modules.message.handle.impl.EmailSendMsgHandle;
|
||||
@ -56,7 +56,12 @@ import org.jeecg.modules.system.util.SecurityUtil;
|
||||
import org.jeecg.modules.system.vo.lowapp.SysDictVo;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
|
||||
import org.springframework.util.AntPathMatcher;
|
||||
@ -64,6 +69,8 @@ import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.PathMatcher;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
@ -86,6 +93,13 @@ public class SysBaseApiImpl implements ISysBaseAPI {
|
||||
/** 当前系统数据库类型 */
|
||||
private static String DB_TYPE = "";
|
||||
|
||||
// 云函数的 URL 化地址
|
||||
@Value("${jeecg.unicloud.pushUrl:''}")
|
||||
private String jeecgPushUrl;
|
||||
|
||||
@Autowired
|
||||
private RestTemplate restTemplate;
|
||||
|
||||
@Autowired
|
||||
private ISysMessageTemplateService sysMessageTemplateService;
|
||||
@Resource
|
||||
@ -112,6 +126,8 @@ public class SysBaseApiImpl implements ISysBaseAPI {
|
||||
private ISysDataSourceService dataSourceService;
|
||||
@Autowired
|
||||
private ISysUserDepartService sysUserDepartService;
|
||||
@Autowired
|
||||
private ISysUserDepPostService sysUserDepPostService;
|
||||
@Resource
|
||||
private SysPermissionMapper sysPermissionMapper;
|
||||
@Autowired
|
||||
@ -149,11 +165,10 @@ public class SysBaseApiImpl implements ISysBaseAPI {
|
||||
@Override
|
||||
//@SensitiveDecode
|
||||
public LoginUser getUserByName(String username) {
|
||||
//update-begin-author:taoyan date:2022-6-6 for: VUEN-1276 【v3流程图】测试bug 1、通过我发起的流程或者流程实例,查看历史,流程图预览问题
|
||||
// 代码逻辑说明: VUEN-1276 【v3流程图】测试bug 1、通过我发起的流程或者流程实例,查看历史,流程图预览问题
|
||||
if (oConvertUtils.isEmpty(username)) {
|
||||
return null;
|
||||
}
|
||||
//update-end-author:taoyan date:2022-6-6 for: VUEN-1276 【v3流程图】测试bug 1、通过我发起的流程或者流程实例,查看历史,流程图预览问题
|
||||
LoginUser user = sysUserService.getEncodeUserInfo(username);
|
||||
|
||||
//相同类中方法间调用时脱敏解密 Aop会失效,获取用户信息太重要,此处采用原生解密方法,不采用@SensitiveDecodeAble注解方式
|
||||
@ -203,15 +218,14 @@ public class SysBaseApiImpl implements ISysBaseAPI {
|
||||
query.eq(SysPermission::getMenuType,2);
|
||||
query.eq(SysPermission::getDelFlag,0);
|
||||
|
||||
//update-begin-author:taoyan date:2023-2-21 for: 解决参数顺序问题
|
||||
// 代码逻辑说明: 解决参数顺序问题
|
||||
List<String> allPossiblePaths = this.getOnlinePossiblePaths(requestPath);
|
||||
log.info("获取的菜单地址= {}", allPossiblePaths.toString());
|
||||
log.debug("获取的菜单地址= {}", allPossiblePaths.toString());
|
||||
if(allPossiblePaths.size()==1){
|
||||
query.eq(SysPermission::getUrl, requestPath);
|
||||
}else{
|
||||
query.in(SysPermission::getUrl, allPossiblePaths);
|
||||
}
|
||||
//update-end-author:taoyan date:2023-2-21 for: 解决参数顺序问题
|
||||
|
||||
currentSyspermission = sysPermissionMapper.selectList(query);
|
||||
//2.未找到 再通过自定义匹配URL 获取菜单
|
||||
@ -219,9 +233,8 @@ public class SysBaseApiImpl implements ISysBaseAPI {
|
||||
//通过自定义URL匹配规则 获取菜单(实现通过菜单配置数据权限规则,实际上针对获取数据接口进行数据规则控制)
|
||||
String userMatchUrl = UrlMatchEnum.getMatchResultByUrl(requestPath);
|
||||
LambdaQueryWrapper<SysPermission> queryQserMatch = new LambdaQueryWrapper<SysPermission>();
|
||||
// update-begin-author:taoyan date:20211027 for: online菜单如果配置成一级菜单 权限查询不到 取消menuType = 1
|
||||
// 代码逻辑说明: online菜单如果配置成一级菜单 权限查询不到 取消menuType = 1
|
||||
//queryQserMatch.eq(SysPermission::getMenuType, 1);
|
||||
// update-end-author:taoyan date:20211027 for: online菜单如果配置成一级菜单 权限查询不到 取消menuType = 1
|
||||
queryQserMatch.eq(SysPermission::getDelFlag, 0);
|
||||
queryQserMatch.eq(SysPermission::getUrl, userMatchUrl);
|
||||
if(oConvertUtils.isNotEmpty(userMatchUrl)){
|
||||
@ -240,13 +253,12 @@ public class SysBaseApiImpl implements ISysBaseAPI {
|
||||
if(currentSyspermission!=null && currentSyspermission.size()>0){
|
||||
List<SysPermissionDataRuleModel> dataRules = new ArrayList<SysPermissionDataRuleModel>();
|
||||
for (SysPermission sysPermission : currentSyspermission) {
|
||||
// update-begin--Author:scott Date:20191119 for:数据权限规则编码不规范,项目存在相同包名和类名 #722
|
||||
// 代码逻辑说明: 数据权限规则编码不规范,项目存在相同包名和类名 #722
|
||||
List<SysPermissionDataRule> temp = sysPermissionDataRuleService.queryPermissionDataRules(username, sysPermission.getId());
|
||||
if(temp!=null && temp.size()>0) {
|
||||
//dataRules.addAll(temp);
|
||||
dataRules = oConvertUtils.entityListToModelList(temp,SysPermissionDataRuleModel.class);
|
||||
}
|
||||
// update-end--Author:scott Date:20191119 for:数据权限规则编码不规范,项目存在相同包名和类名 #722
|
||||
}
|
||||
return dataRules;
|
||||
}
|
||||
@ -499,9 +511,8 @@ public class SysBaseApiImpl implements ISysBaseAPI {
|
||||
announcement.setSendTime(new Date());
|
||||
announcement.setMsgCategory(CommonConstant.MSG_CATEGORY_2);
|
||||
announcement.setDelFlag(String.valueOf(CommonConstant.DEL_FLAG_0));
|
||||
//update-begin-author:liusq---date:2025-07-01--for: [QQYUN-12999]系统通知,系统通知时间更新,但是排到下面了
|
||||
// 代码逻辑说明: [QQYUN-12999]系统通知,系统通知时间更新,但是排到下面了
|
||||
announcement.setIzTop(CommonConstant.IZ_TOP_0);
|
||||
//update-end-author:liusq---date:2025-07-01--for: [QQYUN-12999]系统通知,系统通知时间更新,但是排到下面了
|
||||
sysAnnouncementMapper.insert(announcement);
|
||||
// 2.插入用户通告阅读标记表记录
|
||||
String userId = toUser;
|
||||
@ -572,9 +583,8 @@ public class SysBaseApiImpl implements ISysBaseAPI {
|
||||
announcement.setMsgType(CommonConstant.MSG_TYPE_UESR);
|
||||
announcement.setSendStatus(CommonConstant.HAS_SEND);
|
||||
announcement.setSendTime(new Date());
|
||||
//update-begin-author:liusq---date:2025-07-01--for: [QQYUN-12999]系统通知,系统通知时间更新,但是排到下面了
|
||||
// 代码逻辑说明: [QQYUN-12999]系统通知,系统通知时间更新,但是排到下面了
|
||||
announcement.setIzTop(CommonConstant.IZ_TOP_0);
|
||||
//update-end-author:liusq---date:2025-07-01--for: [QQYUN-12999]系统通知,系统通知时间更新,但是排到下面了
|
||||
if(tmplateParam!=null && oConvertUtils.isNotEmpty(tmplateParam.get(CommonSendStatus.MSG_ABSTRACT_JSON))){
|
||||
announcement.setMsgAbstract(tmplateParam.get(CommonSendStatus.MSG_ABSTRACT_JSON));
|
||||
}
|
||||
@ -860,26 +870,45 @@ public class SysBaseApiImpl implements ISysBaseAPI {
|
||||
|
||||
@Override
|
||||
public List<String> getDeptHeadByDepId(String deptId) {
|
||||
QueryWrapper<SysUser> queryWrapper = new QueryWrapper<SysUser>().eq("status", 1).eq("del_flag", 0);
|
||||
//支持逗号分割传递多个部门id
|
||||
if (oConvertUtils.isNotEmpty(deptId) && deptId.contains(SymbolConstant.COMMA)) {
|
||||
String[] vals = deptId.split(SymbolConstant.COMMA);
|
||||
queryWrapper.and(andWrapper -> {
|
||||
for (int i = 0; i < vals.length; i++) {
|
||||
andWrapper.like("depart_ids", vals[i]);
|
||||
andWrapper.or();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
queryWrapper.like("depart_ids", deptId);
|
||||
log.debug(" getDeptHeadByDepId 根据部门ID获取负责人,deptId:{}", deptId);
|
||||
if(oConvertUtils.isEmpty(deptId)){
|
||||
return null;
|
||||
}
|
||||
|
||||
List<SysUser> userList = userMapper.selectList(queryWrapper);
|
||||
List<String> list = new ArrayList<>();
|
||||
for(SysUser user : userList){
|
||||
list.add(user.getUsername());
|
||||
QueryWrapper<SysUser> queryWrapper = new QueryWrapper<SysUser>().eq("status", 1).eq("del_flag", 0);
|
||||
|
||||
// 支持逗号分割传递多个部门id
|
||||
if (oConvertUtils.isNotEmpty(deptId) && deptId.contains(SymbolConstant.COMMA)) {
|
||||
String[] vals = deptId.split(SymbolConstant.COMMA);
|
||||
|
||||
// 先trim去除空格,再过滤空字符串,最后去重
|
||||
List<String> validDeptIds = Arrays.stream(vals)
|
||||
.map(String::trim)
|
||||
.filter(oConvertUtils::isNotEmpty)
|
||||
.distinct() // 去重处理
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (!validDeptIds.isEmpty()) {
|
||||
queryWrapper.and(andWrapper -> {
|
||||
for (int i = 0; i < validDeptIds.size(); i++) {
|
||||
andWrapper.like("depart_ids", validDeptIds.get(i));
|
||||
if (i < validDeptIds.size() - 1) {
|
||||
andWrapper.or();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
} else if (oConvertUtils.isNotEmpty(deptId)) {
|
||||
queryWrapper.like("depart_ids", deptId.trim()); // 单个值也要trim
|
||||
}
|
||||
return list;
|
||||
|
||||
List<SysUser> userList = userMapper.selectList(queryWrapper);
|
||||
|
||||
// 对结果也进行去重处理
|
||||
return userList.stream()
|
||||
.map(SysUser::getUsername)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -941,7 +970,7 @@ public class SysBaseApiImpl implements ISysBaseAPI {
|
||||
List<SysUser> list= sysUserService.list(queryWrapper);
|
||||
if(ObjectUtils.isNotEmpty(list)){
|
||||
|
||||
//update-begin-author:taoyan date:2023-5-19 for: QQYUN-5326【简流】获取组织人员 单/多 筛选条件 没有部门筛选
|
||||
// 代码逻辑说明: QQYUN-5326【简流】获取组织人员 单/多 筛选条件 没有部门筛选
|
||||
String departKey = "depart";
|
||||
QueryCondition departCondition = null;
|
||||
try {
|
||||
@ -971,7 +1000,6 @@ public class SysBaseApiImpl implements ISysBaseAPI {
|
||||
if(flag){
|
||||
result.add(userJson);
|
||||
}
|
||||
//update-end-author:taoyan date:2023-5-19 for: QQYUN-5326【简流】获取组织人员 单/多 筛选条件 没有部门筛选
|
||||
|
||||
}
|
||||
}
|
||||
@ -1139,7 +1167,7 @@ public class SysBaseApiImpl implements ISysBaseAPI {
|
||||
public Set<String> getUserRoleSet(String username) {
|
||||
// 查询用户拥有的角色集合
|
||||
List<String> roles = sysUserRoleMapper.getRoleByUserName(username);
|
||||
log.info("-------通过数据库读取用户拥有的角色Rules------username: " + username + ",Roles size: " + (roles == null ? 0 : roles.size()));
|
||||
log.debug("-------通过数据库读取用户拥有的角色Rules------username: " + username + ",Roles size: " + (roles == null ? 0 : roles.size()));
|
||||
return new HashSet<>(roles);
|
||||
}
|
||||
|
||||
@ -1153,7 +1181,7 @@ public class SysBaseApiImpl implements ISysBaseAPI {
|
||||
public Set<String> getUserRoleSetById(String useId) {
|
||||
// 查询用户拥有的角色集合
|
||||
List<String> roles = sysUserRoleMapper.getRoleCodeByUserId(useId);
|
||||
log.info("-------通过数据库读取用户拥有的角色Rules------useId: " + useId + ",Roles size: " + (roles == null ? 0 : roles.size()));
|
||||
log.debug("-------通过数据库读取用户拥有的角色Rules------useId: " + useId + ",Roles size: " + (roles == null ? 0 : roles.size()));
|
||||
return new HashSet<>(roles);
|
||||
}
|
||||
|
||||
@ -1184,7 +1212,7 @@ public class SysBaseApiImpl implements ISysBaseAPI {
|
||||
permissionSet.add(po.getPerms());
|
||||
}
|
||||
}
|
||||
log.info("-------通过数据库读取用户拥有的权限Perms------userId: "+ userId+",Perms size: "+ (permissionSet==null?0:permissionSet.size()) );
|
||||
log.debug("-------通过数据库读取用户拥有的权限Perms------userId: "+ userId+",Perms size: "+ (permissionSet==null?0:permissionSet.size()) );
|
||||
return permissionSet;
|
||||
}
|
||||
|
||||
@ -1209,13 +1237,12 @@ public class SysBaseApiImpl implements ISysBaseAPI {
|
||||
sysPermission.setUrl(onlineFormUrl);
|
||||
int count = sysPermissionMapper.queryCountByUsername(username, sysPermission);
|
||||
if(count<=0){
|
||||
//update-begin---author:chenrui ---date:20240123 for:[QQYUN-7992]【online】工单申请下的online表单,未配置online表单开发菜单,操作报错无权限------------
|
||||
// 代码逻辑说明: [QQYUN-7992]【online】工单申请下的online表单,未配置online表单开发菜单,操作报错无权限------------
|
||||
sysPermission.setUrl(onlineAuthDTO.getOnlineWorkOrderUrl());
|
||||
count = sysPermissionMapper.queryCountByUsername(username, sysPermission);
|
||||
if(count<=0) {
|
||||
return false;
|
||||
}
|
||||
//update-end---author:chenrui ---date:20240123 for:[QQYUN-7992]【online】工单申请下的online表单,未配置online表单开发菜单,操作报错无权限------------
|
||||
}
|
||||
} else {
|
||||
//找到菜单了
|
||||
@ -1230,13 +1257,12 @@ public class SysBaseApiImpl implements ISysBaseAPI {
|
||||
sysPermission.setUrl(onlineFormUrl);
|
||||
int count = sysPermissionMapper.queryCountByUsername(username, sysPermission);
|
||||
if (count <= 0) {
|
||||
//update-begin---author:chenrui ---date:20240123 for:[QQYUN-7992]【online】工单申请下的online表单,未配置online表单开发菜单,操作报错无权限------------
|
||||
// 代码逻辑说明: [QQYUN-7992]【online】工单申请下的online表单,未配置online表单开发菜单,操作报错无权限------------
|
||||
sysPermission.setUrl(onlineAuthDTO.getOnlineWorkOrderUrl());
|
||||
count = sysPermissionMapper.queryCountByUsername(username, sysPermission);
|
||||
if (count > 0) {
|
||||
has = true;
|
||||
}
|
||||
//update-end---author:chenrui ---date:20240123 for:[QQYUN-7992]【online】工单申请下的online表单,未配置online表单开发菜单,操作报错无权限------------
|
||||
} else {
|
||||
has = true;
|
||||
}
|
||||
@ -1330,9 +1356,8 @@ public class SysBaseApiImpl implements ISysBaseAPI {
|
||||
announcement.setSendTime(new Date());
|
||||
announcement.setMsgCategory(setMsgCategory);
|
||||
announcement.setDelFlag(String.valueOf(CommonConstant.DEL_FLAG_0));
|
||||
//update-begin-author:liusq---date:2025-07-01--for: [QQYUN-12999]系统通知,系统通知时间更新,但是排到下面了
|
||||
// 代码逻辑说明: [QQYUN-12999]系统通知,系统通知时间更新,但是排到下面了
|
||||
announcement.setIzTop(CommonConstant.IZ_TOP_0);
|
||||
//update-end-author:liusq---date:2025-07-01--for: [QQYUN-12999]系统通知,系统通知时间更新,但是排到下面了
|
||||
if(oConvertUtils.isEmpty(noticeType)){
|
||||
noticeType = NoticeTypeEnum.NOTICE_TYPE_SYSTEM.getValue();
|
||||
}
|
||||
@ -1389,17 +1414,20 @@ public class SysBaseApiImpl implements ISysBaseAPI {
|
||||
announcement.setDelFlag(String.valueOf(CommonConstant.DEL_FLAG_0));
|
||||
announcement.setBusId(busId);
|
||||
announcement.setBusType(busType);
|
||||
announcement.setOpenType(SysAnnmentTypeEnum.getByType(busType).getOpenType());
|
||||
announcement.setOpenPage(SysAnnmentTypeEnum.getByType(busType).getOpenPage());
|
||||
//update-begin---author:chenrui ---date:20250807 for:[JHHB-136]【vue3】协同工作系统消息需要添加一个类型------------
|
||||
|
||||
// 代码逻辑说明: busType为空时,报错
|
||||
if(oConvertUtils.isNotEmpty(busType)){
|
||||
announcement.setOpenType(SysAnnmentTypeEnum.getByType(busType).getOpenType());
|
||||
announcement.setOpenPage(SysAnnmentTypeEnum.getByType(busType).getOpenPage());
|
||||
}
|
||||
|
||||
// 代码逻辑说明: [JHHB-136]【vue3】协同工作系统消息需要添加一个类型------------
|
||||
if(oConvertUtils.isEmpty(noticeType)){
|
||||
noticeType = NoticeTypeEnum.NOTICE_TYPE_FLOW.getValue();
|
||||
}
|
||||
announcement.setNoticeType(noticeType);
|
||||
//update-end---author:chenrui ---date:20250807 for:[JHHB-136]【vue3】协同工作系统消息需要添加一个类型------------
|
||||
//update-begin-author:liusq---date:2025-07-01--for: [QQYUN-12999]系统通知,系统通知时间更新,但是排到下面了
|
||||
// 代码逻辑说明: [QQYUN-12999]系统通知,系统通知时间更新,但是排到下面了
|
||||
announcement.setIzTop(CommonConstant.IZ_TOP_0);
|
||||
//update-end-author:liusq---date:2025-07-01--for: [QQYUN-12999]系统通知,系统通知时间更新,但是排到下面了
|
||||
sysAnnouncementMapper.insert(announcement);
|
||||
// 2.插入用户通告阅读标记表记录
|
||||
String userId = toUser;
|
||||
@ -1618,17 +1646,15 @@ public class SysBaseApiImpl implements ISysBaseAPI {
|
||||
public Map<String, List<DictModel>> translateManyDict(String dictCodes, String keys) {
|
||||
List<String> dictCodeList = Arrays.asList(dictCodes.split(","));
|
||||
List<String> values = Arrays.asList(keys.split(","));
|
||||
//update-begin---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
// 代码逻辑说明: [issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
return sysDictService.queryManyDictByKeys(dictCodeList, values);
|
||||
//update-end---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
}
|
||||
|
||||
//update-begin---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
// 代码逻辑说明: [issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
@Override
|
||||
public List<DictModel> translateDictFromTableByKeys(String table, String text, String code, String keys, String dataSource) {
|
||||
return sysDictService.queryTableDictTextByKeys(table, text, code, Arrays.asList(keys.split(",")), dataSource);
|
||||
}
|
||||
//update-end---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
|
||||
//-------------------------------------流程节点发送模板消息-----------------------------------------------
|
||||
@Autowired
|
||||
@ -1647,7 +1673,7 @@ public class SysBaseApiImpl implements ISysBaseAPI {
|
||||
public void sendTemplateMessage(MessageDTO message) {
|
||||
String messageType = message.getType();
|
||||
log.debug(" 【万能通用】推送消息 messageType = {}", messageType);
|
||||
//update-begin-author:taoyan date:2022-7-9 for: 将模板解析代码移至消息发送, 而不是调用的地方
|
||||
// 代码逻辑说明: 将模板解析代码移至消息发送, 而不是调用的地方
|
||||
String templateCode = message.getTemplateCode();
|
||||
if(oConvertUtils.isNotEmpty(templateCode)){
|
||||
SysMessageTemplate templateEntity = getTemplateEntity(templateCode);
|
||||
@ -1664,7 +1690,6 @@ public class SysBaseApiImpl implements ISysBaseAPI {
|
||||
throw new JeecgBootException("发送消息失败,消息内容为空!");
|
||||
}
|
||||
|
||||
//update-end-author:taoyan date:2022-7-9 for: 将模板解析代码移至消息发送, 而不是调用的地方
|
||||
if(MessageTypeEnum.XT.getType().equals(messageType)){
|
||||
if (message.isMarkdown()) {
|
||||
// 系统消息要解析Markdown
|
||||
@ -1676,13 +1701,12 @@ public class SysBaseApiImpl implements ISysBaseAPI {
|
||||
// 邮件消息要解析Markdown
|
||||
message.setContent(HTMLUtils.parseMarkdown(message.getContent()));
|
||||
}
|
||||
//update-begin---author:wangshuai---date:2024-11-20---for:【QQYUN-8523】敲敲云发邮件通知,不稳定---
|
||||
// 代码逻辑说明: 【QQYUN-8523】敲敲云发邮件通知,不稳定---
|
||||
if(message.getIsTimeJob() != null && message.getIsTimeJob()){
|
||||
emailSendMsgHandle.sendEmailMessage(message);
|
||||
}else{
|
||||
emailSendMsgHandle.sendMessage(message);
|
||||
}
|
||||
//update-end---author:wangshuai---date:2024-11-20---for:【QQYUN-8523】敲敲云发邮件通知,不稳定---
|
||||
}else if(MessageTypeEnum.DD.getType().equals(messageType)){
|
||||
ddSendMsgHandle.sendMessage(message);
|
||||
}else if(MessageTypeEnum.QYWX.getType().equals(messageType)){
|
||||
@ -1788,6 +1812,11 @@ public class SysBaseApiImpl implements ISysBaseAPI {
|
||||
return sysUserDepartService.listObjs(queryWrapper,e->e.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> queryUsernameByIds(List<String> userIds) {
|
||||
return userMapper.getUsernameByIds(userIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> queryUserIdsByCascadeDeptIds(List<String> deptIds) {
|
||||
Set<String> userIds = new HashSet<>();
|
||||
@ -1822,14 +1851,61 @@ public class SysBaseApiImpl implements ISysBaseAPI {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> queryUserIdsByDeptPostIds(List<String> deptPostIds) {
|
||||
// 1.查询兼职岗位对应的用户
|
||||
QueryWrapper<SysUserDepPost> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.lambda().select(SysUserDepPost::getUserId).in(true,SysUserDepPost::getDepId,deptPostIds);
|
||||
List<String> otherDepartPostUserIds = sysUserDepPostService.listObjs(queryWrapper,e->e.toString());
|
||||
log.info("兼职岗位对应的用户 otherDepartPostUserIds = "+ JSON.toJSONString(otherDepartPostUserIds));
|
||||
|
||||
// 2.查询主岗位对应的用户
|
||||
QueryWrapper<SysUser> mainQueryWrapper = new QueryWrapper<>();
|
||||
mainQueryWrapper.lambda().select(SysUser::getId).eq(SysUser::getStatus,Integer.parseInt(CommonConstant.STATUS_1)).eq(SysUser::getDelFlag,CommonConstant.DEL_FLAG_0)
|
||||
.and(wrapper -> wrapper.in(SysUser::getMainDepPostId, deptPostIds));
|
||||
List<String> mainDepartPostUserIds = sysUserService.listObjs(mainQueryWrapper,e->e.toString());
|
||||
log.info("主岗位对应的用户 mainDepartPostUserIds = "+ JSON.toJSONString(mainDepartPostUserIds));
|
||||
|
||||
// 3.合并主岗位和兼职岗位对应的用户
|
||||
Set<String> userIdSet = new HashSet<>();
|
||||
if (otherDepartPostUserIds != null && !otherDepartPostUserIds.isEmpty()) {
|
||||
userIdSet.addAll(otherDepartPostUserIds);
|
||||
}
|
||||
if (mainDepartPostUserIds != null && !mainDepartPostUserIds.isEmpty()) {
|
||||
userIdSet.addAll(mainDepartPostUserIds);
|
||||
}
|
||||
log.info("主岗位和兼职岗位,对应的用户 userIdSet = "+ JSON.toJSONString(userIdSet));
|
||||
return new ArrayList<>(userIdSet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> queryUsernameByDepartPositIds(List<String> deptPostIds) {
|
||||
// 1.查询兼职岗位对应的用户
|
||||
QueryWrapper<SysUserDepPost> otherQueryWrapper = new QueryWrapper<>();
|
||||
otherQueryWrapper.lambda().select(SysUserDepPost::getUserId).in(true, SysUserDepPost::getDepId, deptPostIds);
|
||||
List<String> otherUserIds = sysUserDepPostService.listObjs(otherQueryWrapper, e -> e.toString());
|
||||
log.info("兼职岗位对应的用户 otherUserIds = {},size = {}" + JSON.toJSONString(otherUserIds), oConvertUtils.getCollectionSize(otherUserIds));
|
||||
|
||||
// 2.查询主岗位和兼职岗位,对应的用户
|
||||
QueryWrapper<SysUser> mainQueryWrapper = new QueryWrapper<>();
|
||||
mainQueryWrapper.lambda().select(SysUser::getUsername).eq(SysUser::getStatus, Integer.parseInt(CommonConstant.STATUS_1)).eq(SysUser::getDelFlag, CommonConstant.DEL_FLAG_0)
|
||||
.and(wrapper -> wrapper
|
||||
.in(SysUser::getMainDepPostId, deptPostIds)
|
||||
.or()
|
||||
.in(otherUserIds != null && !otherUserIds.isEmpty(), SysUser::getId, otherUserIds)
|
||||
);
|
||||
List<String> allUsernames = sysUserService.listObjs(mainQueryWrapper, e -> e.toString());
|
||||
log.info("主岗位和兼职岗位,对应的用户账号 allUsernames = {},size = {}" ,JSON.toJSONString(allUsernames), oConvertUtils.getCollectionSize(allUsernames));
|
||||
return allUsernames;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> queryUserIdsByPositionIds(List<String> positionIds) {
|
||||
QueryWrapper<SysUserPosition> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.lambda().select(SysUserPosition::getUserId).in(true,SysUserPosition::getPositionId,positionIds);
|
||||
return sysUserPositionService.listObjs(queryWrapper,e->e.toString());
|
||||
}
|
||||
|
||||
//update-begin-author:taoyan date:2023-2-21 for: 解决参数顺序问题
|
||||
|
||||
/**
|
||||
* 获取带参数的报表地址,因为多个参数可能顺序会变,所以要将参数顺序重排,获取所有可能的地址集合
|
||||
* 如下:参数顺序调整使用in查询,就能查询出菜单数据
|
||||
@ -1840,7 +1916,7 @@ public class SysBaseApiImpl implements ISysBaseAPI {
|
||||
*/
|
||||
private List<String> getOnlinePossiblePaths(String path){
|
||||
List<String> result = new ArrayList<>();
|
||||
log.info(" path = "+ path);
|
||||
log.debug(" path = "+ path);
|
||||
if (path.indexOf("?") >= 0 && (path.contains("/online/cgreport/") || path.contains("/online/cgformList/") || path.contains("/online/graphreport/"))) {
|
||||
//包含?说明有多个参数
|
||||
String[] pathArray = path.split("\\?");
|
||||
@ -1898,7 +1974,6 @@ public class SysBaseApiImpl implements ISysBaseAPI {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
//update-end-author:taoyan date:2023-2-21 for: 解决参数顺序问题
|
||||
|
||||
@Override
|
||||
public List<String> getUserAccountsByDepCode(String orgCode) {
|
||||
@ -2032,15 +2107,82 @@ public class SysBaseApiImpl implements ISysBaseAPI {
|
||||
if(oConvertUtils.isEmpty(airagFlowDTO.getFlowId())) {
|
||||
throw new JeecgBootException("流程ID不能为空");
|
||||
}
|
||||
FlowRunParams params = new FlowRunParams();
|
||||
params.setFlowId(airagFlowDTO.getFlowId());
|
||||
params.setInputParams(airagFlowDTO.getInputParams());
|
||||
params.setResponseMode("blocking");
|
||||
Result<Object> o = (Result<Object>)airagFlowService.runFlow(params);
|
||||
Result<Object> o = (Result<Object>)airagFlowService.runFlow(airagFlowDTO);
|
||||
return o.getResult();
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* uniPush推送消息给APP用户
|
||||
* @param pushMessageDTO
|
||||
*/
|
||||
@Override
|
||||
public void uniPushMsgToUser(PushMessageDTO pushMessageDTO) {
|
||||
if(oConvertUtils.isEmpty(jeecgPushUrl)){
|
||||
log.warn("yml配置项: jeecg.unicloud.pushUrl 未设置,APP消息UniPush推送功能未启用!");
|
||||
return;
|
||||
}
|
||||
// 获取推送的用户信息
|
||||
List<String> usernames = pushMessageDTO.getUsernames();
|
||||
List<String> userIds = pushMessageDTO.getUserIds();
|
||||
|
||||
// 构建clientIds
|
||||
List<String> clientIds = getClientIds(usernames, userIds);
|
||||
|
||||
// 构建请求参数
|
||||
Map<String, Object> requestBody = new HashMap<>();
|
||||
requestBody.put("title", pushMessageDTO.getTitle());
|
||||
requestBody.put("content", pushMessageDTO.getContent());
|
||||
requestBody.put("data", pushMessageDTO.getPayload());
|
||||
requestBody.put("request_id", String.valueOf(System.currentTimeMillis()));
|
||||
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||
|
||||
// 全用户推送不需要clientIds,指定用户推送需要设置clientIds
|
||||
boolean isAllUserPush = CommonConstant.MSG_TYPE_ALL.equals(pushMessageDTO.getPushType());
|
||||
if (!isAllUserPush) {
|
||||
if (CollectionUtils.isEmpty(clientIds)) {
|
||||
log.warn("UniPush消息推送clientIds为空");
|
||||
return;
|
||||
}
|
||||
requestBody.put("cids", clientIds);
|
||||
}
|
||||
|
||||
// 统一推送逻辑
|
||||
HttpEntity<Map<String, Object>> request = new HttpEntity<>(requestBody, headers);
|
||||
ResponseEntity<Map> response = restTemplate.postForEntity(jeecgPushUrl, request, Map.class);
|
||||
|
||||
// 统一处理响应
|
||||
String pushType = isAllUserPush ? "全用户" : "单用户";
|
||||
if (response.getStatusCode().is2xxSuccessful()) {
|
||||
log.info("{} UniPush消息推送成功 返回response:{}", pushType, response.getBody());
|
||||
} else {
|
||||
log.error("{} UniPush消息推送失败 返回response:{}", pushType, response.getBody());
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 根据用户名或用户ID获取clientIds
|
||||
*/
|
||||
private List<String> getClientIds(List<String> usernames, List<String> userIds) {
|
||||
if (!CollectionUtils.isEmpty(usernames)) {
|
||||
return extractClientIds(this.queryUsersByUsernames(String.join(",", usernames)));
|
||||
} else if (!CollectionUtils.isEmpty(userIds)) {
|
||||
return extractClientIds(this.queryUsersByIds(String.join(",", userIds)));
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
/**
|
||||
* 从用户信息中提取clientIds
|
||||
*/
|
||||
private List<String> extractClientIds(List<JSONObject> users) {
|
||||
return users.stream()
|
||||
.map(user -> user.getString("clientId"))
|
||||
.filter(clientId -> oConvertUtils.isNotEmpty(clientId) && !clientId.trim().isEmpty())
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据orgCode找上级
|
||||
*
|
||||
* @param orgCode
|
||||
|
||||
@ -47,11 +47,10 @@ public class SysCategoryServiceImpl extends ServiceImpl<SysCategoryMapper, SysCa
|
||||
}
|
||||
}
|
||||
}
|
||||
//update-begin--Author:baihailong Date:20191209 for:分类字典编码规则生成器做成公用配置
|
||||
// 代码逻辑说明: 分类字典编码规则生成器做成公用配置
|
||||
JSONObject formData = new JSONObject();
|
||||
formData.put("pid",categoryPid);
|
||||
categoryCode = (String) FillRuleUtil.executeRule(FillRuleConstant.CATEGORY,formData);
|
||||
//update-end--Author:baihailong Date:20191209 for:分类字典编码规则生成器做成公用配置
|
||||
sysCategory.setCode(categoryCode);
|
||||
sysCategory.setPid(categoryPid);
|
||||
baseMapper.insert(sysCategory);
|
||||
@ -217,7 +216,7 @@ public class SysCategoryServiceImpl extends ServiceImpl<SysCategoryMapper, SysCa
|
||||
List<SysCategory> list = super.list(query);
|
||||
// 取出name并返回
|
||||
List<String> textList;
|
||||
// update-begin--author:sunjianlei--date:20210514--for:新增delNotExist参数,设为false不删除数据库里不存在的key ----
|
||||
// 代码逻辑说明: 新增delNotExist参数,设为false不删除数据库里不存在的key ----
|
||||
if (delNotExist) {
|
||||
textList = list.stream().map(SysCategory::getName).collect(Collectors.toList());
|
||||
} else {
|
||||
@ -227,7 +226,6 @@ public class SysCategoryServiceImpl extends ServiceImpl<SysCategoryMapper, SysCa
|
||||
textList.add(res.size() > 0 ? res.get(0).getName() : id);
|
||||
}
|
||||
}
|
||||
// update-end--author:sunjianlei--date:20210514--for:新增delNotExist参数,设为false不删除数据库里不存在的key ----
|
||||
return textList;
|
||||
}
|
||||
|
||||
|
||||
@ -197,7 +197,6 @@ public class SysCommentServiceImpl extends ServiceImpl<SysCommentMapper, SysComm
|
||||
sysFormFileMapper.insert(sysFormFile);
|
||||
// }
|
||||
}
|
||||
//update-end-author:taoyan date:2023-6-12 for: QQYUN-4310【文件】从文件库选择文件功能未做
|
||||
}
|
||||
|
||||
/**
|
||||
@ -271,7 +270,7 @@ public class SysCommentServiceImpl extends ServiceImpl<SysCommentMapper, SysComm
|
||||
md.setFromUser("system");
|
||||
md.setType(MessageTypeEnum.XT.getType());
|
||||
|
||||
// update-begin-author:taoyan date:2023-5-10 for: QQYUN-4744【系统通知】6、系统通知@人后,对方看不到是哪个表单@的,没有超链接
|
||||
// 代码逻辑说明: QQYUN-4744【系统通知】6、系统通知@人后,对方看不到是哪个表单@的,没有超链接
|
||||
String tableName = sysComment.getTableName();
|
||||
String prefix = "desform:";
|
||||
if (tableName != null) {
|
||||
@ -299,7 +298,6 @@ public class SysCommentServiceImpl extends ServiceImpl<SysCommentMapper, SysComm
|
||||
md.setData(data);
|
||||
}
|
||||
}
|
||||
// update-end-author:taoyan date:2023-5-10 for: QQYUN-4744【系统通知】6、系统通知@人后,对方看不到是哪个表单@的,没有超链接
|
||||
|
||||
sysBaseApi.sendTemplateMessage(md);
|
||||
}
|
||||
|
||||
@ -67,9 +67,8 @@ public class SysDepartPermissionServiceImpl extends ServiceImpl<SysDepartPermiss
|
||||
if(roleIds != null && roleIds.size()>0){
|
||||
departRolePermissionMapper.delete(new LambdaQueryWrapper<SysDepartRolePermission>()
|
||||
.eq(SysDepartRolePermission::getPermissionId,permissionId)
|
||||
//update-begin-author:liusq---date:2023-10-08--for: [issue/#5339]部门管理下部门赋权代码逻辑缺少判断条件
|
||||
// 代码逻辑说明: [issue/#5339]部门管理下部门赋权代码逻辑缺少判断条件
|
||||
.in(SysDepartRolePermission::getRoleId,roleIds)
|
||||
//update-end-author:liusq---date:2023-10-08--for: [issue/#5339]部门管理下部门赋权代码逻辑缺少判断条件
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@ import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
@ -28,9 +29,7 @@ import org.jeecg.modules.system.model.DepartIdModel;
|
||||
import org.jeecg.modules.system.model.SysDepartTreeModel;
|
||||
import org.jeecg.modules.system.service.ISysDepartService;
|
||||
import org.jeecg.modules.system.util.FindsDepartsChildrenUtil;
|
||||
import org.jeecg.modules.system.vo.SysDepartExportVo;
|
||||
import org.jeecg.modules.system.vo.SysDepartPositionVo;
|
||||
import org.jeecg.modules.system.vo.SysPositionSelectTreeVo;
|
||||
import org.jeecg.modules.system.vo.*;
|
||||
import org.jeecg.modules.system.vo.lowapp.ExportDepartVo;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
@ -70,17 +69,18 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
|
||||
private SysPositionMapper sysPositionMapper;
|
||||
@Autowired
|
||||
private RedisUtil redisUtil;
|
||||
@Autowired
|
||||
private SysUserDepPostMapper sysUserDepPostMapper;
|
||||
|
||||
@Override
|
||||
public List<SysDepartTreeModel> queryMyDeptTreeList(String departIds) {
|
||||
//根据部门id获取所负责部门
|
||||
LambdaQueryWrapper<SysDepart> query = new LambdaQueryWrapper<SysDepart>();
|
||||
String[] codeArr = this.getMyDeptParentOrgCode(departIds);
|
||||
//update-begin---author:wangshuai---date:2023-12-01---for:【QQYUN-7320】查询部门没数据,导致报错空指针---
|
||||
// 代码逻辑说明: 【QQYUN-7320】查询部门没数据,导致报错空指针---
|
||||
if(ArrayUtil.isEmpty(codeArr)){
|
||||
return null;
|
||||
}
|
||||
//update-end---author:wangshuai---date:2023-12-01---for:【QQYUN-7320】查询部门没数据,导致报错空指针---
|
||||
for(int i=0;i<codeArr.length;i++){
|
||||
query.or().likeRight(SysDepart::getOrgCode,codeArr[i]);
|
||||
}
|
||||
@ -122,15 +122,12 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------
|
||||
query.eq(SysDepart::getDelFlag, CommonConstant.DEL_FLAG_0.toString());
|
||||
//update-begin---author:wangshuai---date:2025-08-18---for:【QQYUN-13427】部门选择组件修改:需要过滤掉岗位 只保留 公司 子公司 部门---
|
||||
// 代码逻辑说明: 【QQYUN-13427】部门选择组件修改:需要过滤掉岗位 只保留 公司 子公司 部门---
|
||||
query.ne(SysDepart::getOrgCategory, DepartCategoryEnum.DEPART_CATEGORY_POST.getValue());
|
||||
//update-end---author:wangshuai---date:2025-08-18---for:【QQYUN-13427】部门选择组件修改:需要过滤掉岗位 只保留 公司 子公司 部门---
|
||||
query.orderByAsc(SysDepart::getDepartOrder);
|
||||
List<SysDepart> list = this.list(query);
|
||||
//update-begin---author:wangshuai ---date:20220307 for:[JTC-119]在部门管理菜单下设置部门负责人 创建用户的时候不需要处理
|
||||
//设置用户id,让前台显示
|
||||
this.setUserIdsByDepList(list);
|
||||
//update-begin---author:wangshuai ---date:20220307 for:[JTC-119]在部门管理菜单下设置部门负责人 创建用户的时候不需要处理
|
||||
// 调用wrapTreeDataToTreeList方法生成树状数据
|
||||
List<SysDepartTreeModel> listResult = FindsDepartsChildrenUtil.wrapTreeDataToTreeList(list);
|
||||
return listResult;
|
||||
@ -144,9 +141,8 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
|
||||
List<SysDepartTreeModel> listResult=new ArrayList<>();
|
||||
LambdaQueryWrapper<SysDepart> query = new LambdaQueryWrapper<SysDepart>();
|
||||
query.eq(SysDepart::getDelFlag, CommonConstant.DEL_FLAG_0.toString());
|
||||
//update-begin---author:wangshuai---date:2025-08-18---for:【QQYUN-13427】部门选择组件修改:需要过滤掉岗位 只保留 公司 子公司 部门---
|
||||
// 代码逻辑说明: 【QQYUN-13427】部门选择组件修改:需要过滤掉岗位 只保留 公司 子公司 部门---
|
||||
query.ne(SysDepart::getOrgCategory,DepartCategoryEnum.DEPART_CATEGORY_POST.getValue());
|
||||
//update-end---author:wangshuai---date:2025-08-18---for:【QQYUN-13427】部门选择组件修改:需要过滤掉岗位 只保留 公司 子公司 部门---
|
||||
if(oConvertUtils.isNotEmpty(ids)){
|
||||
query.in(true,SysDepart::getId,ids.split(","));
|
||||
}
|
||||
@ -190,24 +186,22 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void saveDepartData(SysDepart sysDepart, String username) {
|
||||
if (sysDepart != null && username != null) {
|
||||
//update-begin---author:wangshuai ---date:20230216 for:[QQYUN-4163]给部门表加个是否有子节点------------
|
||||
// 代码逻辑说明: [QQYUN-4163]给部门表加个是否有子节点------------
|
||||
if (oConvertUtils.isEmpty(sysDepart.getParentId())) {
|
||||
sysDepart.setParentId("");
|
||||
}else{
|
||||
//将父部门的设成不是叶子结点
|
||||
departMapper.setMainLeaf(sysDepart.getParentId(),CommonConstant.NOT_LEAF);
|
||||
}
|
||||
//update-end---author:wangshuai ---date:20230216 for:[QQYUN-4163]给部门表加个是否有子节点------------
|
||||
//String s = UUID.randomUUID().toString().replace("-", "");
|
||||
sysDepart.setId(IdWorker.getIdStr(sysDepart));
|
||||
// 先判断该对象有无父级ID,有则意味着不是最高级,否则意味着是最高级
|
||||
// 获取父级ID
|
||||
String parentId = sysDepart.getParentId();
|
||||
//update-begin--Author:baihailong Date:20191209 for:部门编码规则生成器做成公用配置
|
||||
// 代码逻辑说明: 部门编码规则生成器做成公用配置
|
||||
JSONObject formData = new JSONObject();
|
||||
formData.put("parentId",parentId);
|
||||
String[] codeArray = (String[]) FillRuleUtil.executeRule(FillRuleConstant.DEPART,formData);
|
||||
//update-end--Author:baihailong Date:20191209 for:部门编码规则生成器做成公用配置
|
||||
sysDepart.setOrgCode(codeArray[0]);
|
||||
String orgType = codeArray[1];
|
||||
sysDepart.setOrgType(String.valueOf(orgType));
|
||||
@ -224,12 +218,10 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
|
||||
}
|
||||
}
|
||||
this.save(sysDepart);
|
||||
//update-begin---author:wangshuai ---date:20220307 for:[JTC-119]在部门管理菜单下设置部门负责人 创建用户的时候不需要处理
|
||||
//新增部门的时候新增负责部门
|
||||
if(oConvertUtils.isNotEmpty(sysDepart.getDirectorUserIds())){
|
||||
this.addDepartByUserIds(sysDepart,sysDepart.getDirectorUserIds());
|
||||
}
|
||||
//update-end---author:wangshuai ---date:20220307 for:[JTC-119]在部门管理菜单下设置部门负责人 创建用户的时候不需要处理
|
||||
}
|
||||
|
||||
}
|
||||
@ -241,7 +233,7 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
|
||||
* @return
|
||||
*/
|
||||
private String[] generateOrgCode(String parentId) {
|
||||
//update-begin--Author:Steve Date:20190201 for:组织机构添加数据代码调整
|
||||
// 代码逻辑说明: 组织机构添加数据代码调整
|
||||
LambdaQueryWrapper<SysDepart> query = new LambdaQueryWrapper<SysDepart>();
|
||||
LambdaQueryWrapper<SysDepart> query1 = new LambdaQueryWrapper<SysDepart>();
|
||||
String[] strArray = new String[2];
|
||||
@ -297,7 +289,6 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
|
||||
strArray[0] = newOrgCode;
|
||||
strArray[1] = orgType;
|
||||
return strArray;
|
||||
//update-end--Author:Steve Date:20190201 for:组织机构添加数据代码调整
|
||||
}
|
||||
|
||||
|
||||
@ -325,10 +316,10 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
|
||||
//验证部门类型
|
||||
this.verifyOrgCategory(sysDepart);
|
||||
this.updateById(sysDepart);
|
||||
//update-begin---author:wangshuai ---date:20220307 for:[JTC-119]在部门管理菜单下设置部门负责人 创建用户的时候不需要处理
|
||||
//修改部门管理的时候,修改负责部门
|
||||
this.updateChargeDepart(sysDepart);
|
||||
//update-begin---author:wangshuai ---date:20220307 for:[JTC-119]在部门管理菜单下设置部门负责人 创建用户的时候不需要处理
|
||||
//redis清除缓存key
|
||||
redisUtil.removeAll(CommonConstant.DEPART_NAME_REDIS_KEY_PRE);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
@ -371,7 +362,6 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
|
||||
throw new JeecgBootBizTipException("当前子级存在子公司,无法变更为部门!");
|
||||
}
|
||||
}
|
||||
//update-end---author:wangshuai---date:2025-08-21---for: 当部门类型为岗位的时候,需要查看是否存在下级,存在下级无法变更为岗位---
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -385,20 +375,17 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
|
||||
idList.add(id);
|
||||
//此步骤是为了删除子级
|
||||
this.checkChildrenExists(id, idList);
|
||||
//update-begin---author:wangshuai ---date:20230712 for:【QQYUN-5757】批量删除部门时未正确置为叶子节点 ------------
|
||||
// 代码逻辑说明: 【QQYUN-5757】批量删除部门时未正确置为叶子节点 ------------
|
||||
SysDepart depart = this.getDepartById(id);
|
||||
if (oConvertUtils.isNotEmpty(depart.getParentId())) {
|
||||
if (!parentIdList.contains(depart.getParentId())) {
|
||||
parentIdList.add(depart.getParentId());
|
||||
}
|
||||
}
|
||||
//update-end---author:wangshuai ---date:20230712 for:【QQYUN-5757】批量删除部门时未正确置为叶子节点 ------------
|
||||
}
|
||||
this.removeByIds(idList);
|
||||
//update-begin---author:wangshuai ---date:20230712 for:【QQYUN-5757】批量删除部门时未正确置为叶子节点 ------------
|
||||
//再删除前需要获取父级id,不然会一直为空
|
||||
this.setParentDepartIzLeaf(parentIdList);
|
||||
//update-end---author:wangshuai ---date:20230712 for:【QQYUN-5757】批量删除部门时未正确置为叶子节点 ------------
|
||||
//根据部门id获取部门角色id
|
||||
List<String> roleIdList = new ArrayList<>();
|
||||
LambdaQueryWrapper<SysDepartRole> query = new LambdaQueryWrapper<>();
|
||||
@ -419,6 +406,8 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
|
||||
//根据角色id删除部门角色用户信息
|
||||
departRoleUserMapper.delete(new LambdaQueryWrapper<SysDepartRoleUser>().in(SysDepartRoleUser::getDroleId,roleIdList));
|
||||
}
|
||||
//删除岗位信息
|
||||
this.deleteDepartPostByDepIds(idList);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -453,7 +442,7 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
|
||||
}
|
||||
//根据部门id获取所负责部门
|
||||
String[] codeArr = this.getMyDeptParentOrgCode(departIds);
|
||||
//update-begin-author:taoyan date:20220104 for:/issues/3311 当用户属于两个部门的时候,且这两个部门没有上下级关系,我的部门-部门名称查询条件模糊搜索失效!
|
||||
// 代码逻辑说明: /issues/3311 当用户属于两个部门的时候,且这两个部门没有上下级关系,我的部门-部门名称查询条件模糊搜索失效!
|
||||
if (codeArr != null && codeArr.length > 0) {
|
||||
query.nested(i -> {
|
||||
for (String s : codeArr) {
|
||||
@ -461,11 +450,9 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
|
||||
}
|
||||
});
|
||||
}
|
||||
//update-end-author:taoyan date:20220104 for:/issues/3311 当用户属于两个部门的时候,且这两个部门没有上下级关系,我的部门-部门名称查询条件模糊搜索失效!
|
||||
query.eq(SysDepart::getDelFlag, CommonConstant.DEL_FLAG_0.toString());
|
||||
}
|
||||
query.like(SysDepart::getDepartName, keyWord);
|
||||
//update-begin---author:wangshuai---date:2025-08-20---for:【QQYUN-13428】增加岗位选择组件---
|
||||
//需要根据部门类型进行数据筛选
|
||||
if(oConvertUtils.isNotEmpty(orgCategory)){
|
||||
query.in(SysDepart::getOrgCategory, Arrays.asList(orgCategory.split(SymbolConstant.COMMA)));
|
||||
@ -483,15 +470,13 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
|
||||
});
|
||||
}
|
||||
}
|
||||
//update-end---author:wangshuai---date:2025-08-20---for:【QQYUN-13428】增加岗位选择组件---
|
||||
//update-begin--Author:huangzhilin Date:20140417 for:[bugfree号]组织机构搜索回显优化--------------------
|
||||
// 代码逻辑说明: [bugfree号]组织机构搜索回显优化--------------------
|
||||
SysDepartTreeModel model = new SysDepartTreeModel();
|
||||
List<SysDepart> departList = this.list(query);
|
||||
if(departList.size() > 0) {
|
||||
for(SysDepart depart : departList) {
|
||||
model = new SysDepartTreeModel(depart);
|
||||
model.setChildren(null);
|
||||
//update-end--Author:huangzhilin Date:20140417 for:[bugfree号]组织机构搜索功回显优化----------------------
|
||||
newList.add(model);
|
||||
}
|
||||
return newList;
|
||||
@ -553,7 +538,18 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
|
||||
|
||||
@Override
|
||||
public List<SysDepart> queryUserDeparts(String userId) {
|
||||
return baseMapper.queryUserDeparts(userId);
|
||||
List<SysDepart> sysDeparts = baseMapper.queryUserDeparts(userId);
|
||||
sysDeparts.stream()
|
||||
.filter(depart -> oConvertUtils.isNotEmpty(depart) &&
|
||||
oConvertUtils.isNotEmpty(depart.getOrgCode()))
|
||||
.forEach(depart -> {
|
||||
String orgCategory = depart.getOrgCategory();
|
||||
if(DepartCategoryEnum.DEPART_CATEGORY_DEPART.getValue().equalsIgnoreCase(orgCategory)){
|
||||
String departPathName = this.getDepartPathNameByOrgCode(depart.getOrgCode(), "");
|
||||
depart.setDepartPathName(departPathName);
|
||||
}
|
||||
});
|
||||
return sysDeparts;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -693,27 +689,22 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------
|
||||
lqw.eq(true,SysDepart::getDelFlag,CommonConstant.DEL_FLAG_0.toString());
|
||||
//update-begin---author:wangshuai---date:2025-08-18---for:【QQYUN-13427】部门选择组件修改:需要过滤掉岗位 只保留 公司 子公司 部门---
|
||||
// 代码逻辑说明: 【QQYUN-13427】部门选择组件修改:需要过滤掉岗位 只保留 公司 子公司 部门---
|
||||
lqw.ne(SysDepart::getOrgCategory,DepartCategoryEnum.DEPART_CATEGORY_POST.getValue());
|
||||
//update-end---author:wangshuai---date:2025-08-18---for:【QQYUN-13427】部门选择组件修改:需要过滤掉岗位 只保留 公司 子公司 部门---
|
||||
lqw.func(square);
|
||||
//update-begin---author:wangshuai ---date:20220527 for:[VUEN-1143]排序不对,vue3和2应该都有问题,应该按照升序排------------
|
||||
// 代码逻辑说明: [VUEN-1143]排序不对,vue3和2应该都有问题,应该按照升序排------------
|
||||
lqw.orderByAsc(SysDepart::getDepartOrder);
|
||||
//update-end---author:wangshuai ---date:20220527 for:[VUEN-1143]排序不对,vue3和2应该都有问题,应该按照升序排--------------
|
||||
List<SysDepart> list = list(lqw);
|
||||
//update-begin---author:wangshuai ---date:20220316 for:[JTC-119]在部门管理菜单下设置部门负责人 创建用户的时候不需要处理
|
||||
//设置用户id,让前台显示
|
||||
this.setUserIdsByDepList(list);
|
||||
//update-end---author:wangshuai ---date:20220316 for:[JTC-119]在部门管理菜单下设置部门负责人 创建用户的时候不需要处理
|
||||
List<SysDepartTreeModel> records = new ArrayList<>();
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
SysDepart depart = list.get(i);
|
||||
//update-begin---author:wangshuai---date:2025-08-18---for:【QQYUN-13427】部门选择组件修改:需要过滤掉岗位 只保留 公司 子公司 部门---
|
||||
// 代码逻辑说明: 【QQYUN-13427】部门选择组件修改:需要过滤掉岗位 只保留 公司 子公司 部门---
|
||||
long count = getNoDepartPostCount(depart.getId());
|
||||
if(count == 0){
|
||||
depart.setIzLeaf(CommonConstant.IS_LEAF);
|
||||
}
|
||||
//update-end---author:wangshuai---date:2025-08-18---for:【QQYUN-13427】部门选择组件修改:需要过滤掉岗位 只保留 公司 子公司 部门---
|
||||
SysDepartTreeModel treeModel = new SysDepartTreeModel(depart);
|
||||
//TODO 异步树加载key拼接__+时间戳,以便于每次展开节点会刷新数据
|
||||
//treeModel.setKey(treeModel.getKey()+"__"+System.currentTimeMillis());
|
||||
@ -755,7 +746,7 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
|
||||
}
|
||||
} else {
|
||||
if(oConvertUtils.isEmpty(parentId)){
|
||||
//update-begin---author:wangshuai---date:2025-08-20---for:如果前端传过来的部门id不为空的时候,说明是系统用户根据所属部门选择主岗位或者兼职岗位---
|
||||
// 代码逻辑说明: 如果前端传过来的部门id不为空的时候,说明是系统用户根据所属部门选择主岗位或者兼职岗位---
|
||||
if(oConvertUtils.isNotEmpty(departIds)){
|
||||
i.in(SysDepart::getId,Arrays.asList(departIds.split(SymbolConstant.COMMA)));
|
||||
}else{
|
||||
@ -765,7 +756,6 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
|
||||
i.like(SysDepart::getDepartName, orgName);
|
||||
}
|
||||
}
|
||||
//update-end---author:wangshuai---date:2025-08-20---for:如果前端传过来的部门id不为空的时候,说明是系统用户根据所属部门选择主岗位或者兼职岗位---
|
||||
}else{
|
||||
i.eq(true,SysDepart::getParentId,parentId);
|
||||
}
|
||||
@ -884,7 +874,6 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
|
||||
}
|
||||
}
|
||||
|
||||
//update-begin---author:wangshuai ---date:20200308 for:[JTC-119]在部门管理菜单下设置部门负责人,新增方法添加部门负责人、删除负责部门负责人、查询部门对应的负责人
|
||||
/**
|
||||
* 通过用户id设置负责部门
|
||||
* @param sysDepart SysDepart部门对象
|
||||
@ -1008,7 +997,6 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
|
||||
}
|
||||
}
|
||||
}
|
||||
//update-end---author:wangshuai ---date:20200308 for:[JTC-119]在部门管理菜单下设置部门负责人,新增方法添加部门负责人、删除负责部门负责人、查询部门对应的负责人
|
||||
|
||||
/**
|
||||
* 获取我的部门已加入的公司
|
||||
@ -1270,12 +1258,11 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
|
||||
}
|
||||
//查询部门名称是否已存在
|
||||
SysDepart parentDept = null;
|
||||
//update-begin---author:wangshuai ---date:20230721 for:一个租户部门名称可能有多个------------
|
||||
// 代码逻辑说明: 一个租户部门名称可能有多个------------
|
||||
List<SysDepart> sysDepartList = departMapper.getDepartByName(departName,tenantId,parentId);
|
||||
if(CollectionUtil.isNotEmpty(sysDepartList)){
|
||||
parentDept = sysDepartList.get(0);
|
||||
}
|
||||
//update-end---author:wangshuai ---date:20230721 for:一个租户部门名称可能有多个------------
|
||||
if(null != parentDept) {
|
||||
//部门名称已存在
|
||||
errorMessageList.add("第 " + lineNumber + " 行:记录部门名称“"+departName+"”已存在,请检查!");
|
||||
@ -1322,13 +1309,12 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
|
||||
*/
|
||||
private String getDepartListByName(String departName, Integer tenantId, SysDepart sysDepart,String[] departNameUrls, int count, int departNum,String name,Map<String,SysDepart> departMap) {
|
||||
//递归查找下一级
|
||||
//update-begin---author:wangshuai ---date:20230721 for:一个租户部门名称可能有多个------------
|
||||
// 代码逻辑说明: 一个租户部门名称可能有多个------------
|
||||
SysDepart parentDept = null;
|
||||
List<SysDepart> departList = departMapper.getDepartByName(departName,tenantId,sysDepart.getId());
|
||||
if(CollectionUtil.isNotEmpty(departList)){
|
||||
parentDept = departList.get(0);
|
||||
}
|
||||
//update-end---author:wangshuai ---date:20230721 for:一个租户部门名称可能有多个------------
|
||||
//判断是否包含/
|
||||
if(oConvertUtils.isNotEmpty(name)){
|
||||
name = name + SymbolConstant.SINGLE_SLASH + departName;
|
||||
@ -1387,8 +1373,13 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
|
||||
*/
|
||||
@Override
|
||||
public List<SysDepartExportVo> getExportDepart(Integer tenantId, List<String> idList) {
|
||||
String parentId = "";
|
||||
if(CollectionUtil.isEmpty(idList)){
|
||||
//-1代表父级部门为空的数据
|
||||
parentId = "-1";
|
||||
}
|
||||
//获取父级部门
|
||||
List<SysDepartExportVo> parentDepart = departMapper.getSysDepartList("", tenantId, idList);
|
||||
List<SysDepartExportVo> parentDepart = departMapper.getSysDepartList(parentId, tenantId, idList);
|
||||
//子部门
|
||||
List<SysDepartExportVo> childrenDepart = new ArrayList<>();
|
||||
//把一级部门名称放在里面
|
||||
@ -1396,6 +1387,9 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
|
||||
//存放部门一级id避免重复
|
||||
List<String> departIdList = new ArrayList<>();
|
||||
for (SysDepartExportVo sysDepart : parentDepart) {
|
||||
if(CollectionUtil.isNotEmpty(departIdList) && departIdList.contains(sysDepart.getId())){
|
||||
continue;
|
||||
}
|
||||
//step 1.添加第一级部门
|
||||
departIdList.add(sysDepart.getId());
|
||||
sysDepart.setDepartNameUrl(sysDepart.getDepartName());
|
||||
@ -1404,8 +1398,9 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
|
||||
//创建路径
|
||||
List<String> path = new ArrayList<>();
|
||||
path.add(sysDepart.getDepartName());
|
||||
//创建子部门路径
|
||||
findSysDepartPath(sysDepart, path, tenantId, childrenDepart, departIdList, idList);
|
||||
//创建子级部门路径
|
||||
// 代码逻辑说明: 【JHHB-222】导出,选中最顶级部门,只能导出选中的部门---
|
||||
findSysDepartPath(sysDepart, path, tenantId, childrenDepart, departIdList);
|
||||
path.clear();
|
||||
}
|
||||
exportDepartVoList.addAll(childrenDepart);
|
||||
@ -1514,12 +1509,11 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
|
||||
* @param tenantId 租户id
|
||||
* @param childrenDepart 子部门
|
||||
* @param departIdList 部门id集合
|
||||
* @param idList 需要查询sql的部门id集合
|
||||
*/
|
||||
private void findSysDepartPath(SysDepartExportVo departVo, List<String> path, Integer tenantId, List<SysDepartExportVo> childrenDepart, List<String> departIdList, List<String> idList) {
|
||||
private void findSysDepartPath(SysDepartExportVo departVo, List<String> path, Integer tenantId, List<SysDepartExportVo> childrenDepart, List<String> departIdList) {
|
||||
//step 1.查询子部门的数据
|
||||
//获取租户id和部门父id获取的部门数据
|
||||
List<SysDepartExportVo> departList = departMapper.getSysDepartList(departVo.getId(), tenantId, idList);
|
||||
List<SysDepartExportVo> departList = departMapper.getSysDepartList(departVo.getId(), tenantId, null);
|
||||
//部门为空判断
|
||||
if (departList == null || departList.size() <= 0) {
|
||||
//判断最后一个子部门是否已拼接
|
||||
@ -1541,8 +1535,9 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
|
||||
childrenDepart.add(departVo);
|
||||
}
|
||||
//step 3.递归查询子路径,直到找不到为止
|
||||
findSysDepartPath(exportDepartVo, cPath, tenantId, childrenDepart, departIdList, idList);
|
||||
}
|
||||
// 代码逻辑说明: 【JHHB-222】导出,选中最顶级部门,只能导出选中的部门---
|
||||
findSysDepartPath(exportDepartVo, cPath, tenantId, childrenDepart, departIdList);
|
||||
}
|
||||
}
|
||||
//========================end 系统下部门与人员导入 ==================================================================
|
||||
|
||||
@ -1567,82 +1562,50 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
|
||||
if(null == postLevel){
|
||||
throw new JeecgBootBizTipException("当前选择职级的职务等级为空,请前往职务管理进行修改!");
|
||||
}
|
||||
|
||||
//step3 查看是否为董事长
|
||||
if (1 == postLevel) {
|
||||
//step4 如果是董事长查询上级子公司或者总公司下部门的所有的岗位
|
||||
return this.getChairmanDepartPosition(sysDepart, departId);
|
||||
} else {
|
||||
//step5 如果不是董事长组查询当前父级部门、公司和子公司的岗位 和当前部门下的岗位,但是必须比当前职务的级别高
|
||||
return this.getNotChairmanDepartPosition(sysDepart, postLevel, departId);
|
||||
}
|
||||
return this.getParentDepartPosition(sysDepart, postLevel, departId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取董事长职位
|
||||
*
|
||||
* @param sysDepart
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
private List<SysPositionSelectTreeVo> getChairmanDepartPosition(SysDepart sysDepart, String id) {
|
||||
//step1 先递归获取为子公司或者总共司的id
|
||||
String departId = getCompanyDepartId(sysDepart.getParentId());
|
||||
if (oConvertUtils.isNotEmpty(departId)) {
|
||||
SysDepart depart = baseMapper.getDepartById(departId);
|
||||
//如果当前上级部门就是子公司或者总公司的情况下
|
||||
if (DepartCategoryEnum.DEPART_CATEGORY_COMPANY.getValue().equals(sysDepart.getOrgCategory()) || DepartCategoryEnum.DEPART_CATEGORY_SUB_COMPANY.getValue().equals(sysDepart.getOrgCategory())) {
|
||||
depart.setParentId(departId);
|
||||
List<SysPositionSelectTreeVo> departPosition = getDepartPosition(depart, null, id);
|
||||
if (CollectionUtil.isNotEmpty(departPosition)) {
|
||||
if (CollectionUtil.isNotEmpty(departPosition)) {
|
||||
//父级id不为空并且当前部门不是子公司或者总公司,则需要寻上顶级公司
|
||||
return getSuperiorCompany(departPosition);
|
||||
}
|
||||
}
|
||||
return departPosition;
|
||||
} else {
|
||||
//step2 获取上一个子公司或者总公司下的岗位
|
||||
String parentId = getCompanyDepartId(depart.getParentId());
|
||||
if (oConvertUtils.isNotEmpty(departId)) {
|
||||
depart = baseMapper.getDepartById(parentId);
|
||||
if (null != depart) {
|
||||
depart.setParentId(parentId);
|
||||
List<SysPositionSelectTreeVo> departPosition = getDepartPosition(depart, null, id);
|
||||
//step3 获取上级部门信息,一直获取到子公司或者总公司为止
|
||||
if (CollectionUtil.isNotEmpty(departPosition)) {
|
||||
//父级id不为空并且当前部门不是子公司或者总公司,则需要寻上顶级公司
|
||||
return getSuperiorCompany(departPosition);
|
||||
}
|
||||
return departPosition;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 获取不是董事长的数据
|
||||
* 获取上级部门岗位 或者当前部门下级别高的
|
||||
*
|
||||
* @param sysDepart
|
||||
* @param postLevel
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
private List<SysPositionSelectTreeVo> getNotChairmanDepartPosition(SysDepart sysDepart, Integer postLevel, String id) {
|
||||
private List<SysPositionSelectTreeVo> getParentDepartPosition(SysDepart sysDepart, Integer postLevel, String id) {
|
||||
//step1 先获取上级部门下的数据
|
||||
List<SysPositionSelectTreeVo> departPosition = getDepartPosition(sysDepart, postLevel, id);
|
||||
//已经存在的code
|
||||
List<String> existCodeList = new ArrayList<>();
|
||||
List<SysPositionSelectTreeVo> departPosition = getDepartPosition(sysDepart, postLevel, id, existCodeList);
|
||||
//step2 获取上级部门信息,一直获取到子公司或者总公司为止
|
||||
if (CollectionUtil.isNotEmpty(departPosition)) {
|
||||
if (CollectionUtil.isNotEmpty(departPosition)) {
|
||||
//父级id不为空并且当前部门不是子公司或者总公司,则需要寻上顶级公司
|
||||
return getSuperiorCompany(departPosition);
|
||||
//父级id不为空并且当前部门不是子公司或者总公司,则需要寻上顶级公司
|
||||
// 代码逻辑说明: 【JHHB-501】三级子公司的董事长岗位,存在向一级公司总经理汇报的职级关系,现在无法配置---
|
||||
String parentId = sysDepart.getParentId();
|
||||
SysDepart depart = departMapper.getDepartById(parentId);
|
||||
if(null != depart){
|
||||
//获取长度
|
||||
int codeNum = YouBianCodeUtil.ZHANWEI_LENGTH;
|
||||
List<String> codeList = getCodeHierarchy(depart.getOrgCode(), codeNum);
|
||||
if(null != codeList && codeList.size() > 1){
|
||||
//需要将当前和上级部门的排除掉
|
||||
existCodeList.add(codeList.get(codeList.size() - 1));
|
||||
//从上向下找存在子级的code
|
||||
List<SysPositionSelectTreeVo> parentDepartPost = this.getParentDepartPost(codeList, existCodeList);
|
||||
//当前父级部门下存在职级必当前高的需要同事渲染
|
||||
if (CollectionUtil.isNotEmpty(departPosition)) {
|
||||
departPosition.addAll(parentDepartPost);
|
||||
return buildTree(departPosition);
|
||||
}else if(CollectionUtil.isNotEmpty(parentDepartPost)){
|
||||
return buildTree(parentDepartPost);
|
||||
}
|
||||
}
|
||||
return departPosition;
|
||||
}
|
||||
return departPosition;
|
||||
// 代码逻辑说明: 【JHHB-501】三级子公司的董事长岗位,存在向一级公司总经理汇报的职级关系,现在无法配置---
|
||||
if(CollectionUtil.isNotEmpty(departPosition)){
|
||||
return getSuperiorCompany(departPosition);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1667,19 +1630,59 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取父级部门下的一级岗位
|
||||
*
|
||||
* @param codeList
|
||||
* @param existCodeList 已存在的部门编码
|
||||
*/
|
||||
private List<SysPositionSelectTreeVo> getParentDepartPost(List<String> codeList, List<String> existCodeList) {
|
||||
List<SysPositionSelectTreeVo> list = new ArrayList<>();
|
||||
for (String orgCode : codeList){
|
||||
if(existCodeList.contains(orgCode)){
|
||||
continue;
|
||||
}
|
||||
//当前部门
|
||||
SysDepart depart = departMapper.queryDepartByOrgCode(orgCode);
|
||||
SysPositionSelectTreeVo sysPositionSelectTreeVo = new SysPositionSelectTreeVo(depart);
|
||||
sysPositionSelectTreeVo.setLeaf(false);
|
||||
list.add(sysPositionSelectTreeVo);
|
||||
//查找当前部门下一级部门存在岗位的部门信息
|
||||
List<SysDepart> departByParentId = departMapper.getDepartByParentId(depart.getId());
|
||||
List<String> parentIds = new ArrayList<>();
|
||||
for (SysDepart sysDepart : departByParentId) {
|
||||
list.add(new SysPositionSelectTreeVo(sysDepart));
|
||||
// 代码逻辑说明: 上级岗位太慢,sql优化---
|
||||
parentIds.add(sysDepart.getId());
|
||||
}
|
||||
// 代码逻辑说明: 上级岗位太慢,sql优化---
|
||||
if(CollectionUtil.isNotEmpty(parentIds)){
|
||||
//根据父级id获取部门岗位信息
|
||||
List<SysDepart> departPositionList = departMapper.getDepartPositionByParentIds(parentIds);
|
||||
if(CollectionUtil.isNotEmpty(departPositionList)){
|
||||
List<SysPositionSelectTreeVo> sysDepartTreeModels = sysDepartToTreeModel(departPositionList);
|
||||
list.addAll(sysDepartTreeModels);
|
||||
}
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取部门职务
|
||||
*
|
||||
* @param sysDepart
|
||||
* @param postLevel
|
||||
* @param existCodeList
|
||||
*/
|
||||
private List<SysPositionSelectTreeVo> getDepartPosition(SysDepart sysDepart, Integer postLevel, String id) {
|
||||
private List<SysPositionSelectTreeVo> getDepartPosition(SysDepart sysDepart, Integer postLevel, String id, List<String> existCodeList) {
|
||||
//step1 获取部门下的所有部门
|
||||
String parentId = sysDepart.getParentId();
|
||||
List<SysDepart> departList = baseMapper.getDepartByParentId(parentId);
|
||||
List<SysPositionSelectTreeVo> treeModels = new ArrayList<>();
|
||||
for (int i = 0; i < departList.size(); i++) {
|
||||
SysDepart depart = departList.get(i);
|
||||
existCodeList.add(depart.getOrgCode());
|
||||
//如果是叶子节点说明没有岗位直接跳出循环
|
||||
if (depart.getIzLeaf() == 1) {
|
||||
if (DepartCategoryEnum.DEPART_CATEGORY_POST.getValue().equals(depart.getOrgCategory())) {
|
||||
@ -1800,36 +1803,44 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
|
||||
* 构建树形结构,只返回没有父级的一级节点
|
||||
*/
|
||||
public static List<SysPositionSelectTreeVo> buildTree(List<SysPositionSelectTreeVo> nodes) {
|
||||
// 存储一级节点(没有父级的节点)
|
||||
List<SysPositionSelectTreeVo> rootNodes = new ArrayList<>();
|
||||
// 先找出所有一级节点(parentId为null或空)
|
||||
for (SysPositionSelectTreeVo node : nodes) {
|
||||
if (node.getParentId() == null || node.getParentId().trim().isEmpty()) {
|
||||
rootNodes.add(node);
|
||||
// 1. 去重:根据ID去重,保留第一个
|
||||
Map<String, SysPositionSelectTreeVo> uniqueNodes = nodes.stream()
|
||||
.filter(Objects::nonNull)
|
||||
.filter(node -> node.getId() != null && !node.getId().trim().isEmpty())
|
||||
.collect(Collectors.toMap(
|
||||
SysPositionSelectTreeVo::getId,
|
||||
node -> node,
|
||||
(existing, replacement) -> existing,
|
||||
LinkedHashMap::new
|
||||
));
|
||||
// 2. 初始化所有节点的children列表
|
||||
uniqueNodes.values().forEach(node -> {
|
||||
if (node.getChildren() == null) {
|
||||
node.setChildren(new ArrayList<>());
|
||||
}
|
||||
});
|
||||
// 3. 构建树形结构
|
||||
List<SysPositionSelectTreeVo> rootNodes = new ArrayList<>();
|
||||
for (SysPositionSelectTreeVo node : uniqueNodes.values()) {
|
||||
String parentId = node.getParentId();
|
||||
|
||||
if (parentId == null || parentId.trim().isEmpty()) {
|
||||
// 根节点
|
||||
rootNodes.add(node);
|
||||
} else {
|
||||
// 子节点,查找父节点
|
||||
SysPositionSelectTreeVo parent = uniqueNodes.get(parentId);
|
||||
if (parent != null) {
|
||||
parent.getChildren().add(node);
|
||||
} else {
|
||||
// 父节点不存在,当作根节点处理
|
||||
rootNodes.add(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
// 为每个一级节点递归设置子节点
|
||||
for (SysPositionSelectTreeVo root : rootNodes) {
|
||||
setChildren(root, nodes);
|
||||
}
|
||||
return rootNodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归为节点设置子节点
|
||||
*/
|
||||
private static void setChildren(SysPositionSelectTreeVo parentNode, List<SysPositionSelectTreeVo> allNodes) {
|
||||
for (SysPositionSelectTreeVo node : allNodes) {
|
||||
// 如果当前节点的父ID等于父节点的ID,则是子节点
|
||||
if (parentNode.getId().equals(node.getParentId())) {
|
||||
// 递归为子节点设置它的子节点
|
||||
setChildren(node, allNodes);
|
||||
// 将子节点添加到父节点的子节点列表
|
||||
parentNode.getChildren().add(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=========================end 部门岗位改造 ==================================================================
|
||||
|
||||
@Override
|
||||
@ -1859,7 +1870,8 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
|
||||
List<SysDepart> sysDepartList = departMapper.selectList(query);
|
||||
if(!CollectionUtils.isEmpty(sysDepartList)){
|
||||
//获取部门名称拼接返回给前台
|
||||
List<String> departNameList = sysDepartList.stream().map(SysDepart::getDepartName).toList();
|
||||
// 代码逻辑说明: 【JHHB-631】【部门管理】存在缩写使用缩写来显示---
|
||||
List<String> departNameList = sysDepartList.stream().map(item-> oConvertUtils.getString(item.getDepartNameAbbr(),item.getDepartName())).toList();
|
||||
String departNames = String.join("/", departNameList);
|
||||
redisUtil.set(CommonConstant.DEPART_NAME_REDIS_KEY_PRE + orgCode,departNames);
|
||||
return departNames;
|
||||
@ -1889,4 +1901,355 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart
|
||||
}
|
||||
return hierarchy;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据多个部门id删除主岗位和兼职岗位
|
||||
*
|
||||
* @param idList
|
||||
*/
|
||||
private void deleteDepartPostByDepIds(List<String> idList) {
|
||||
//更新用户主岗位位空,使用LambdaUpdateWrapper,避免为空时受全局 updateStrategy 影响导致误更新
|
||||
LambdaUpdateWrapper<SysUser> userQuery = new LambdaUpdateWrapper<>();
|
||||
userQuery.in(SysUser::getMainDepPostId, idList);
|
||||
userQuery.set(SysUser::getMainDepPostId, null);
|
||||
sysUserMapper.update(userQuery);
|
||||
//删除兼职岗位
|
||||
LambdaQueryWrapper<SysUserDepPost> postQuery = new LambdaQueryWrapper<>();
|
||||
postQuery.in(SysUserDepPost::getDepId, idList);
|
||||
sysUserDepPostMapper.delete(postQuery);
|
||||
//redis清除缓存key
|
||||
redisUtil.removeAll(CommonConstant.DEPART_NAME_REDIS_KEY_PRE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据部门id获取部门下的岗位id
|
||||
*
|
||||
* @param depIds 当前选择的公司、子公司、部门id
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String getDepPostIdByDepId(String depIds) {
|
||||
if (oConvertUtils.isEmpty(depIds)) {
|
||||
return "";
|
||||
}
|
||||
//step1 先根据部门id获取编码
|
||||
List<SysUserDepVo> departIdList = departMapper.getDepartByIds(Arrays.asList(depIds.split(SymbolConstant.COMMA)));
|
||||
if (CollectionUtil.isNotEmpty(departIdList)) {
|
||||
//step2 根据部门编码查询岗位id
|
||||
LambdaQueryWrapper<SysDepart> query = new LambdaQueryWrapper<>();
|
||||
query.select(SysDepart::getId);
|
||||
departIdList.forEach(item -> {
|
||||
query.or(lq-> lq.likeRight(SysDepart::getOrgCode, item.getOrgCode()));
|
||||
});
|
||||
query.eq(SysDepart::getOrgCategory, DepartCategoryEnum.DEPART_CATEGORY_POST.getValue());
|
||||
List<SysDepart> departList = departMapper.selectList(query);
|
||||
//step3 返回部门id
|
||||
if (CollectionUtil.isNotEmpty(departList)) {
|
||||
return departList.stream().map(SysDepart::getId).collect(Collectors.joining(SymbolConstant.COMMA));
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 变更部门位置
|
||||
*
|
||||
* @param changeDepartVo
|
||||
* @return orgCode 部门id
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public void updateChangeDepart(SysChangeDepartVo changeDepartVo) {
|
||||
String dragId = changeDepartVo.getDragId();
|
||||
// 1. 获取被拖拽的部门
|
||||
SysDepart dragDept = baseMapper.getDepartById(dragId);
|
||||
if (null == dragDept) {
|
||||
throw new JeecgBootBizTipException("被拖拽的部门不存在");
|
||||
}
|
||||
// 2. 获取目标部门
|
||||
String dropId = changeDepartVo.getDropId();
|
||||
SysDepart targetDept = baseMapper.getDepartById(dropId);
|
||||
if (null == targetDept) {
|
||||
throw new JeecgBootBizTipException("目标部门不存在");
|
||||
}
|
||||
//3. 验证拖拽操作是否合法
|
||||
validateDragOperation(dragDept, targetDept, changeDepartVo.getDropPosition());
|
||||
//4. 根据dropPosition调整部门顺序
|
||||
Integer dropPosition = changeDepartVo.getDropPosition();
|
||||
switch (dropPosition) {
|
||||
case -1:
|
||||
// 拖拽到上方
|
||||
moveToAbove(dragDept, targetDept);
|
||||
break;
|
||||
case 0:
|
||||
// 拖拽到内部(作为子部门)
|
||||
moveAsChild(dragDept, targetDept);
|
||||
break;
|
||||
case 1:
|
||||
//拖拽到下方
|
||||
moveToBelow(dragDept, targetDept, changeDepartVo.getSort());
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("无效的拖拽位置");
|
||||
}
|
||||
//5. 清空缓存
|
||||
redisUtil.removeAll(CommonConstant.DEPART_NAME_REDIS_KEY_PRE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证拖拽操作是否合法
|
||||
*
|
||||
* @param dragDept 被拖拽的部门
|
||||
* @param targetDept 目标部门
|
||||
* @param dropPosition 拖拽位置
|
||||
*/
|
||||
private void validateDragOperation(SysDepart dragDept, SysDepart targetDept, Integer dropPosition) {
|
||||
// 禁止拖拽到自身
|
||||
if (dragDept.getId().equals(targetDept.getId())) {
|
||||
throw new RuntimeException("不能拖拽到自身");
|
||||
}
|
||||
// 禁止拖拽到自身子部门
|
||||
if (isDescendant(dragDept, targetDept.getId())) {
|
||||
throw new RuntimeException("不能拖拽到自身子部门");
|
||||
}
|
||||
//公司岗位判断
|
||||
String orgCategory = targetDept.getOrgCategory();
|
||||
String oldOrgCategory = dragDept.getOrgCategory();
|
||||
//部门为公司
|
||||
if(0 != dropPosition && DepartCategoryEnum.DEPART_CATEGORY_COMPANY.getValue().equals(orgCategory)){
|
||||
//当前部门不能为子公司、部门和岗位
|
||||
if(!DepartCategoryEnum.DEPART_CATEGORY_COMPANY.getValue().equals(oldOrgCategory)){
|
||||
throw new JeecgBootBizTipException("当前部门类型为【"+DepartCategoryEnum.getNameByValue(oldOrgCategory)+"】,不允许移动到公司");
|
||||
}
|
||||
}
|
||||
//部门为岗位不允许移入
|
||||
if(0 == dropPosition && DepartCategoryEnum.DEPART_CATEGORY_POST.getValue().equals(orgCategory)) {
|
||||
throw new JeecgBootBizTipException("岗位不允许存在子级");
|
||||
}
|
||||
//公司不能做为子级
|
||||
if(oConvertUtils.isNotEmpty(targetDept.getParentId()) && DepartCategoryEnum.DEPART_CATEGORY_COMPANY.getValue().equals(oldOrgCategory)){
|
||||
throw new JeecgBootBizTipException("公司不允许作为子级");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断目标部门是否是被拖拽部门的子部门
|
||||
*/
|
||||
private boolean isDescendant(SysDepart dragDept, String targetId) {
|
||||
List<SysDepart> children = departMapper.getDepartByParentId(dragDept.getId());
|
||||
for (SysDepart child : children) {
|
||||
if (child.getId().equals(targetId)) {
|
||||
return true;
|
||||
}
|
||||
if (isDescendant(child, targetId)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 拖拽到上方:将部门移动到目标部门上方(只有最上级 即公司才会走这个逻辑)
|
||||
* @param dragDept 被拖拽的部门
|
||||
* @param targetDept 目标部门
|
||||
*/
|
||||
private void moveToAbove(SysDepart dragDept, SysDepart targetDept) {
|
||||
// 获取目标部门同级的所有部门
|
||||
List<SysDepart> siblings = departMapper.getDepartNoParent();
|
||||
// 计算新的排序值
|
||||
Integer newDepartOrder = targetDept.getDepartOrder();
|
||||
// 更新被拖拽部门的排序值
|
||||
dragDept.setDepartOrder(newDepartOrder);
|
||||
// 更新被拖拽部门的排序值
|
||||
dragDept.setDepartOrder(0);
|
||||
if(CollectionUtil.isNotEmpty(siblings)){
|
||||
// 计算新的排序值
|
||||
this.computingSort(siblings,0,dragDept.getId());
|
||||
// 保存所有更新的部门
|
||||
this.updateBatchById(siblings);
|
||||
}
|
||||
departMapper.updateById(dragDept);
|
||||
}
|
||||
|
||||
/**
|
||||
* 拖拽到下方:将部门移动到目标部门下方
|
||||
*
|
||||
* @param dragDept 被拖拽的部门
|
||||
* @param targetDept 目标部门
|
||||
* @param sort 排序
|
||||
*/
|
||||
private void moveToBelow(SysDepart dragDept, SysDepart targetDept, Integer sort) {
|
||||
String parentId = targetDept.getParentId();
|
||||
List<SysDepart> siblings = null;
|
||||
if(oConvertUtils.isNotEmpty(parentId)){
|
||||
// 获取目标部门同级的所有部门
|
||||
siblings = departMapper.getDepartByParentId(parentId);
|
||||
}else{
|
||||
siblings = departMapper.getDepartNoParent();
|
||||
}
|
||||
String oldParentId = dragDept.getParentId();
|
||||
//判断父级部门id是否相同,不同则更新为目标部门的父部门id
|
||||
if(oConvertUtils.isNotEmpty(dragDept.getParentId()) &&
|
||||
oConvertUtils.isNotEmpty(parentId) &&
|
||||
!dragDept.getParentId().equals(parentId)){
|
||||
String oldOrgCode = dragDept.getOrgCode();
|
||||
//设置父级id和部门code
|
||||
this.setDepartParentAndOrgCode(dragDept, parentId);
|
||||
//修改子级的部门编码
|
||||
this.updateChildOrgCode(dragDept.getOrgCode(), oldOrgCode);
|
||||
}
|
||||
// 更新被拖拽部门的排序值
|
||||
dragDept.setDepartOrder(sort);
|
||||
if(CollectionUtil.isNotEmpty(siblings)){
|
||||
// 计算新的排序值
|
||||
this.computingSort(siblings,sort,dragDept.getId());
|
||||
// 保存所有更新的部门
|
||||
this.updateBatchById(siblings);
|
||||
}
|
||||
departMapper.updateById(dragDept);
|
||||
if(oConvertUtils.isNotEmpty(oldParentId)){
|
||||
long count = departMapper.countByParentId(oldParentId);
|
||||
if(count == 0){
|
||||
this.updateIzLeaf(oldParentId,CommonConstant.IS_LEAF);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 拖拽到内部:将部门移动到目标部门内部(作为子部门)
|
||||
*/
|
||||
private void moveAsChild(SysDepart dragDept, SysDepart targetDept) {
|
||||
// 更新父部门ID
|
||||
String parentId = targetDept.getId();
|
||||
String oldParentId = dragDept.getParentId();
|
||||
// 获取目标部门同级的所有部门
|
||||
List<SysDepart> siblings = departMapper.getDepartByParentId(parentId);
|
||||
//判断父级部门id是否相同,不同则更新为目标部门的父部门id
|
||||
if(oConvertUtils.isNotEmpty(dragDept.getParentId()) &&
|
||||
oConvertUtils.isNotEmpty(parentId) &&
|
||||
!dragDept.getParentId().equals(parentId)){
|
||||
String oldOrgCode = dragDept.getOrgCode();
|
||||
//设置父级id和部门code
|
||||
this.setDepartParentAndOrgCode(dragDept, parentId);
|
||||
//修改子级的部门编码
|
||||
this.updateChildOrgCode(dragDept.getOrgCode(), oldOrgCode);
|
||||
}
|
||||
//内部排序为0
|
||||
Integer sort = 0;
|
||||
// 设置新的排序值
|
||||
dragDept.setDepartOrder(sort);
|
||||
if(CollectionUtil.isNotEmpty(siblings)){
|
||||
// 计算新的排序值
|
||||
this.computingSort(siblings,sort,dragDept.getId());
|
||||
// 保存所有更新的部门
|
||||
this.updateBatchById(siblings);
|
||||
}
|
||||
departMapper.updateById(dragDept);
|
||||
this.updateIzLeaf(parentId, CommonConstant.NOT_LEAF);
|
||||
if(oConvertUtils.isNotEmpty(oldParentId)){
|
||||
long count = departMapper.countByParentId(oldParentId);
|
||||
if(count == 0){
|
||||
this.updateIzLeaf(oldParentId,CommonConstant.IS_LEAF);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算排序值
|
||||
*
|
||||
* @param siblings
|
||||
* @param sort
|
||||
* @param id
|
||||
*/
|
||||
private void computingSort(List<SysDepart> siblings, Integer sort, String id) {
|
||||
for (int i = 0; i < siblings.size(); i++) {
|
||||
SysDepart depart = siblings.get(i);
|
||||
if(id.equals(depart.getId())){
|
||||
continue;
|
||||
}
|
||||
//如果当前循环的sort大等于传入的sort值 则需要+1
|
||||
if(i >= sort){
|
||||
depart.setDepartOrder(sort + 1);
|
||||
sort++;
|
||||
} else {
|
||||
depart.setDepartOrder(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置被拖拽部门的父级id和部门编码
|
||||
*
|
||||
* @param dragDept 被拖拽的部门
|
||||
* @param parentId 目标部门的父级id
|
||||
*/
|
||||
private void setDepartParentAndOrgCode(SysDepart dragDept, String parentId) {
|
||||
// 更新父部门ID(与目标部门相同)
|
||||
dragDept.setParentId(parentId);
|
||||
Page<SysDepart> page = new Page<>(1, 1);
|
||||
//需要获取父级id,查看父级是否已经存在
|
||||
//获取一级部门的最大orgCode
|
||||
List<SysDepart> records = departMapper.getMaxCodeDepart(page, parentId);
|
||||
String newOrgCode = "";
|
||||
if (CollectionUtil.isNotEmpty(records)) {
|
||||
newOrgCode = YouBianCodeUtil.getNextYouBianCode(records.get(0).getOrgCode());
|
||||
} else {
|
||||
//查询父id
|
||||
if (oConvertUtils.isNotEmpty(parentId)) {
|
||||
SysDepart departById = departMapper.getDepartById(parentId);
|
||||
newOrgCode = YouBianCodeUtil.getSubYouBianCode(departById.getOrgCode(), null);
|
||||
} else {
|
||||
newOrgCode = YouBianCodeUtil.getNextYouBianCode(null);
|
||||
}
|
||||
}
|
||||
dragDept.setOrgCode(newOrgCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改子级的部门编码
|
||||
*
|
||||
* @param newOrgCode 当前父级新的部门编码
|
||||
* @param oldOrgCode 当前父级旧的部门编码
|
||||
*/
|
||||
private void updateChildOrgCode(String newOrgCode, String oldOrgCode) {
|
||||
//查询当前部门下的所有子级部门
|
||||
LambdaQueryWrapper<SysDepart> query = new LambdaQueryWrapper<>();
|
||||
query.likeRight(SysDepart::getOrgCode, oldOrgCode);
|
||||
query.orderByAsc(SysDepart::getDepartOrder);
|
||||
query.orderByDesc(SysDepart::getCreateTime);
|
||||
query.select(SysDepart::getId, SysDepart::getOrgCode);
|
||||
List<SysDepart> childDeparts = departMapper.selectList(query);
|
||||
if (CollectionUtil.isNotEmpty(childDeparts)) {
|
||||
for (SysDepart depart : childDeparts) {
|
||||
String orgCode = depart.getOrgCode();
|
||||
if (orgCode.startsWith(oldOrgCode)) {
|
||||
orgCode = newOrgCode + orgCode.substring(oldOrgCode.length());
|
||||
}
|
||||
depart.setOrgCode(orgCode);
|
||||
}
|
||||
}
|
||||
this.updateBatchById(childDeparts);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取部门负责人
|
||||
*
|
||||
* @param departId
|
||||
* @param page
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public IPage<SysUser> getDepartmentHead(String departId, Page<SysUser> page) {
|
||||
List<SysUser> departmentHead = departMapper.getDepartmentHead(page, departId);
|
||||
if(CollectionUtil.isNotEmpty(departmentHead)){
|
||||
departmentHead.forEach(item->{
|
||||
//兼职岗位
|
||||
List<String> depPostList = sysUserDepPostMapper.getDepPostByUserId(item.getId());
|
||||
if(CollectionUtil.isNotEmpty(depPostList)){
|
||||
item.setOtherDepPostId(StringUtils.join(depPostList.toArray(), SymbolConstant.COMMA));
|
||||
}
|
||||
});
|
||||
}
|
||||
return page.setRecords(departmentHead);
|
||||
}
|
||||
}
|
||||
|
||||
@ -95,11 +95,10 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
|
||||
|
||||
// 4.执行SQL 查询是否存在值
|
||||
try{
|
||||
//update-begin---author:chenrui ---date:20240715 for:[TV360X-49]postgres日期、年月日时分秒唯一校验报错------------
|
||||
// 代码逻辑说明: [TV360X-49]postgres日期、年月日时分秒唯一校验报错------------
|
||||
if(DbTypeUtils.dbTypeIsPostgre(CommonUtils.getDatabaseTypeEnum())){
|
||||
duplicateCheckVo.setFieldName("CAST("+duplicateCheckVo.getFieldName()+" as text)");
|
||||
}
|
||||
//update-end---author:chenrui ---date:20240715 for:[TV360X-49]postgres日期、年月日时分秒唯一校验报错------------
|
||||
if (StringUtils.isNotBlank(duplicateCheckVo.getDataId())) {
|
||||
// [1].编辑页面校验
|
||||
count = sysDictMapper.duplicateCheckCountSql(duplicateCheckVo);
|
||||
@ -151,9 +150,8 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
|
||||
for (DictModelMany dict : list) {
|
||||
List<DictModel> dictItemList = dictMap.computeIfAbsent(dict.getDictCode(), i -> new ArrayList<>());
|
||||
|
||||
//update-begin-author:taoyan date:2023-4-28 for: QQYUN-5183【简流】多字段拼接-多选框、下拉框 等需要翻译的字段
|
||||
// 代码逻辑说明: QQYUN-5183【简流】多字段拼接-多选框、下拉框 等需要翻译的字段
|
||||
//dict.setDictCode(null);
|
||||
//update-end-author:taoyan date:2023-4-28 for: QQYUN-5183【简流】多字段拼接-多选框、下拉框 等需要翻译的字段
|
||||
|
||||
dictItemList.add(new DictModel(dict.getValue(), dict.getText(), dict.getColor()));
|
||||
}
|
||||
@ -162,7 +160,7 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
|
||||
|
||||
@Override
|
||||
public Map<String, List<DictModel>> queryAllDictItems() {
|
||||
log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
|
||||
log.debug(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
|
||||
long start = System.currentTimeMillis();
|
||||
Map<String, List<DictModel>> sysAllDictItems = new HashMap(5);
|
||||
List<Integer> tenantIds = null;
|
||||
@ -181,16 +179,16 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
|
||||
sysAllDictItems = sysDictItemList.stream()
|
||||
.collect(Collectors.groupingBy(DictModelMany::getDictCode,
|
||||
Collectors.mapping(d -> new DictModel(d.getValue(), d.getText(), d.getColor()), Collectors.toList())));
|
||||
log.info(" >>> 1 获取系统字典项耗时(SQL):" + (System.currentTimeMillis() - start) + "毫秒");
|
||||
log.debug(" >>> 1 获取系统字典项耗时(SQL):" + (System.currentTimeMillis() - start) + "毫秒");
|
||||
|
||||
Map<String, List<DictModel>> enumRes = ResourceUtil.getEnumDictData();
|
||||
sysAllDictItems.putAll(enumRes);
|
||||
log.info(" >>> 2 获取系统字典项耗时(Enum):" + (System.currentTimeMillis() - start) + "毫秒");
|
||||
log.debug(" >>> 2 获取系统字典项耗时(Enum):" + (System.currentTimeMillis() - start) + "毫秒");
|
||||
|
||||
log.info(" >>> end 获取系统字典库总耗时:" + (System.currentTimeMillis() - start) + "毫秒");
|
||||
log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
|
||||
log.debug(" >>> end 获取系统字典库总耗时:" + (System.currentTimeMillis() - start) + "毫秒");
|
||||
log.debug(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
|
||||
|
||||
//log.info("-------登录加载系统字典-----" + sysAllDictItems.toString());
|
||||
//log.debug("-------登录加载系统字典-----" + sysAllDictItems.toString());
|
||||
return sysAllDictItems;
|
||||
}
|
||||
|
||||
@ -216,10 +214,9 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
|
||||
List<DictModel> dictItemList = dictMap.computeIfAbsent(dict.getDictCode(), i -> new ArrayList<>());
|
||||
dictItemList.add(new DictModel(dict.getValue(), dict.getText()));
|
||||
}
|
||||
//update-begin-author:taoyan date:2022-7-8 for: 系统字典数据应该包括自定义的java类-枚举
|
||||
// 代码逻辑说明: 系统字典数据应该包括自定义的java类-枚举
|
||||
Map<String, List<DictModel>> enumRes = ResourceUtil.queryManyDictByKeys(dictCodeList, keys);
|
||||
dictMap.putAll(enumRes);
|
||||
//update-end-author:taoyan date:2022-7-8 for: 系统字典数据应该包括自定义的java类-枚举
|
||||
return dictMap;
|
||||
}
|
||||
|
||||
@ -352,7 +349,6 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
|
||||
return null;
|
||||
}
|
||||
}
|
||||
//update-end---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
|
||||
// 2.分割SQL获取表名和条件
|
||||
String filterSql = null;
|
||||
@ -371,7 +367,6 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
|
||||
text = SqlInjectionUtil.getSqlInjectField(text);
|
||||
code = SqlInjectionUtil.getSqlInjectField(code);
|
||||
|
||||
//update-begin---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
// 切换为字典表的数据源
|
||||
if (isCustomDataSource) {
|
||||
DynamicDataSourceContextHolder.push(dataSource);
|
||||
@ -382,8 +377,6 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
|
||||
DynamicDataSourceContextHolder.clear();
|
||||
}
|
||||
return restData;
|
||||
//update-end---author:chenrui ---date:20231221 for:[issues/#5643]解决分布式下表字典跨库无法查询问题------------
|
||||
//update-end-author:taoyan date:20220113 for: @dict注解支持 dicttable 设置where条件
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -478,11 +471,10 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
|
||||
insert = sysDictMapper.insert(sysDict);
|
||||
if (sysDictItemList != null) {
|
||||
for (SysDictItem entity : sysDictItemList) {
|
||||
//update-begin---author:wangshuai ---date:20220211 for:[JTC-1168]如果字典项值为空,则字典项忽略导入------------
|
||||
// 代码逻辑说明: [JTC-1168]如果字典项值为空,则字典项忽略导入------------
|
||||
if(oConvertUtils.isEmpty(entity.getItemValue())){
|
||||
return -1;
|
||||
}
|
||||
//update-end---author:wangshuai ---date:20220211 for:[JTC-1168]如果字典项值为空,则字典项忽略导入------------
|
||||
entity.setDictId(sysDict.getId());
|
||||
entity.setStatus(1);
|
||||
sysDictItemMapper.insert(entity);
|
||||
@ -566,9 +558,8 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
|
||||
if (oConvertUtils.isNotEmpty(keyword)) {
|
||||
// 判断是否是多选
|
||||
if (keyword.contains(SymbolConstant.COMMA)) {
|
||||
//update-begin--author:scott--date:20220105--for:JTC-529【表单设计器】 编辑页面报错,in参数采用双引号导致 ----
|
||||
// 代码逻辑说明: JTC-529【表单设计器】 编辑页面报错,in参数采用双引号导致 ----
|
||||
String inKeywords = "'" + String.join("','", keyword.split(",")) + "'";
|
||||
//update-end--author:scott--date:20220105--for:JTC-529【表单设计器】 编辑页面报错,in参数采用双引号导致----
|
||||
keywordSql = "(" + text + " in (" + inKeywords + ") or " + code + " in (" + inKeywords + "))";
|
||||
} else {
|
||||
keywordSql = "("+text + " like '%"+keyword+"%' or "+ code + " like '%"+keyword+"%')";
|
||||
@ -577,7 +568,7 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
|
||||
}
|
||||
|
||||
//下拉搜索组件 支持传入排序信息 查询排序
|
||||
//update-begin---author:chenrui ---date:20240327 for:[QQYUN-8514]Online表单中 下拉搜索框 搜索时报sql错误,生成的SQL多了一个 “and" ------------
|
||||
// 代码逻辑说明: [QQYUN-8514]Online表单中 下拉搜索框 搜索时报sql错误,生成的SQL多了一个 “and" ------------
|
||||
if (oConvertUtils.isNotEmpty(condition) && oConvertUtils.isNotEmpty(keywordSql)) {
|
||||
filterSql += sqlWhere + (tableHasWhere ? sqlAnd : " ") + condition + sqlAnd + keywordSql;
|
||||
} else if (oConvertUtils.isNotEmpty(condition)) {
|
||||
@ -587,7 +578,6 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
|
||||
} else if (tableHasWhere) {
|
||||
filterSql += sqlWhere;
|
||||
}
|
||||
//update-end---author:chenrui ---date:20240327 for:[QQYUN-8514]Online表单中 下拉搜索框 搜索时报sql错误,生成的SQL多了一个 “and" ------------
|
||||
// 增加排序逻辑
|
||||
if (oConvertUtils.isNotEmpty(orderField)) {
|
||||
filterSql += " order by " + orderField + " " + orderType;
|
||||
@ -626,7 +616,15 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
|
||||
public List<TreeSelectModel> queryTreeList(Map<String, String> query, String table, String text, String code, String pidField, String pid, String hasChildField, int converIsLeafVal) {
|
||||
//为了防止sql(jeecg提供了防注入的方法,可以在拼接 SQL 语句时自动对参数进行转义,避免SQL注入攻击)
|
||||
// 1.针对采用 ${}写法的表名和字段进行转义和check
|
||||
table = SqlInjectionUtil.getSqlInjectTableName(table);
|
||||
//update-begin---author:chenrui ---date:20251015 for:[QQYUN-13741]【客户问题 南自】online表单自定义树 表后边加条件时 不生效------------
|
||||
// 分割SQL获取表名和条件
|
||||
String filterSql = null;
|
||||
if(table.toLowerCase().indexOf(DataBaseConstant.SQL_WHERE)>0){
|
||||
String[] arr = table.split(" (?i)where ");
|
||||
table = arr[0];
|
||||
filterSql = oConvertUtils.getString(arr[1], null);
|
||||
}
|
||||
table = SqlInjectionUtil.getSqlInjectTableName(table);
|
||||
text = SqlInjectionUtil.getSqlInjectField(text);
|
||||
code = SqlInjectionUtil.getSqlInjectField(code);
|
||||
pidField = SqlInjectionUtil.getSqlInjectField(pidField);
|
||||
@ -641,6 +639,7 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
|
||||
// 2.检测最终SQL是否存在SQL注入风险
|
||||
String dictCode = table + "," + text + "," + code;
|
||||
SqlInjectionUtil.filterContentMulti(dictCode);
|
||||
SqlInjectionUtil.specialFilterContentForDictSql(filterSql);
|
||||
|
||||
// 【QQYUN-6533】表字典白名单check
|
||||
sysBaseAPI.dictTableWhiteListCheckByDict(table, text, code);
|
||||
@ -650,14 +649,17 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
|
||||
return null;
|
||||
}
|
||||
// 4.检测查询条件是否存在SQL注入
|
||||
Map<String, String> queryParams = null;
|
||||
Map<String, String> queryParams = queryParams = new HashMap<>(4);
|
||||
if (query != null) {
|
||||
queryParams = new HashMap<>(5);
|
||||
for (Map.Entry<String, String> searchItem : query.entrySet()) {
|
||||
String fieldName = searchItem.getKey();
|
||||
queryParams.put(SqlInjectionUtil.getSqlInjectField(fieldName), searchItem.getValue());
|
||||
}
|
||||
}
|
||||
// 代码逻辑说明: [QQYUN-13741]【客户问题 南自】online表单自定义树 表后边加条件时 不生效------------
|
||||
if(oConvertUtils.isNotEmpty(filterSql)){
|
||||
queryParams.put("_tableFilterSql", filterSql);
|
||||
}
|
||||
|
||||
return baseMapper.queryTreeList(queryParams, table, text, code, pidField, pid, hasChildField, converIsLeafVal);
|
||||
}
|
||||
@ -675,14 +677,13 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
|
||||
|
||||
@Override
|
||||
public List<SysDict> queryDeleteList(String tenantId) {
|
||||
//update-begin---author:wangshuai---date:2024-02-27---for:【QQYUN-8340】回收站查找软删除记录时,没有判断是否启用多租户,造成可以查找并回收其他租户的数据 #5907---
|
||||
// 代码逻辑说明: 【QQYUN-8340】回收站查找软删除记录时,没有判断是否启用多租户,造成可以查找并回收其他租户的数据 #5907---
|
||||
if(MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL){
|
||||
if(oConvertUtils.isEmpty(tenantId)){
|
||||
return new ArrayList<>();
|
||||
}
|
||||
return baseMapper.queryDeleteListBtTenantId(oConvertUtils.getInt(tenantId));
|
||||
}
|
||||
//update-end---author:wangshuai---date:2024-02-27---for:【QQYUN-8340】回收站查找软删除记录时,没有判断是否启用多租户,造成可以查找并回收其他租户的数据 #5907---
|
||||
return baseMapper.queryDeleteList();
|
||||
}
|
||||
|
||||
@ -738,14 +739,13 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
|
||||
//字典表
|
||||
ls = this.queryDictItemsByCode(dictCode);
|
||||
}
|
||||
//update-begin-author:taoyan date:2022-8-30 for: 字典获取可以获取枚举类的数据
|
||||
// 代码逻辑说明: 字典获取可以获取枚举类的数据
|
||||
if (ls == null || ls.size() == 0) {
|
||||
Map<String, List<DictModel>> map = ResourceUtil.getEnumDictData();
|
||||
if (map.containsKey(dictCode)) {
|
||||
return map.get(dictCode);
|
||||
}
|
||||
}
|
||||
//update-end-author:taoyan date:2022-8-30 for: 字典获取可以获取枚举类的数据
|
||||
return ls;
|
||||
}
|
||||
|
||||
@ -763,7 +763,7 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
|
||||
SqlInjectionUtil.specialFilterContentForDictSql(dictCode);
|
||||
|
||||
if (dictCode.contains(SymbolConstant.COMMA)) {
|
||||
//update-begin-author:taoyan date:20210329 for: 下拉搜索不支持表名后加查询条件
|
||||
// 代码逻辑说明: 下拉搜索不支持表名后加查询条件
|
||||
String[] params = dictCode.split(",");
|
||||
String condition = null;
|
||||
if (params.length != 3 && params.length != 4) {
|
||||
@ -771,11 +771,10 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
|
||||
return null;
|
||||
} else if (params.length == 4) {
|
||||
condition = params[3];
|
||||
// update-begin-author:taoyan date:20220314 for: online表单下拉搜索框表字典配置#{sys_org_code}报错 #3500
|
||||
// 代码逻辑说明: online表单下拉搜索框表字典配置#{sys_org_code}报错 #3500
|
||||
if(condition.indexOf(SymbolConstant.SYS_VAR_PREFIX)>=0){
|
||||
condition = QueryGenerator.getSqlRuleValue(condition);
|
||||
}
|
||||
// update-end-author:taoyan date:20220314 for: online表单下拉搜索框表字典配置#{sys_org_code}报错 #3500
|
||||
}
|
||||
|
||||
// 字典Code格式不正确 [表名为空]
|
||||
@ -788,7 +787,6 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
|
||||
} else {
|
||||
ls = this.queryAllTableDictItems(params[0], params[1], params[2], condition, keyword);
|
||||
}
|
||||
//update-end-author:taoyan date:20210329 for: 下拉搜索不支持表名后加查询条件
|
||||
return ls;
|
||||
} else {
|
||||
// 字典Code格式不正确
|
||||
|
||||
@ -65,14 +65,13 @@ public class SysGatewayRouteServiceImpl extends ServiceImpl<SysGatewayRouteMappe
|
||||
try {
|
||||
json = json.getJSONObject("router");
|
||||
String id = json.getString("id");
|
||||
//update-begin-author:taoyan date:20211025 for: oracle路由网关新增小bug /issues/I4EV2J
|
||||
// 代码逻辑说明: oracle路由网关新增小bug /issues/I4EV2J
|
||||
SysGatewayRoute route;
|
||||
if(oConvertUtils.isEmpty(id)){
|
||||
route = new SysGatewayRoute();
|
||||
}else{
|
||||
route = getById(id);
|
||||
}
|
||||
//update-end-author:taoyan date:20211025 for: oracle路由网关新增小bug /issues/I4EV2J
|
||||
if (ObjectUtil.isEmpty(route)) {
|
||||
route = new SysGatewayRoute();
|
||||
}
|
||||
|
||||
@ -45,7 +45,6 @@ public class SysLogServiceImpl extends ServiceImpl<SysLogMapper, SysLog> impleme
|
||||
return sysLogMapper.findTotalVisitCount();
|
||||
}
|
||||
|
||||
//update-begin--Author:zhangweijian Date:20190428 for:传入开始时间,结束时间参数
|
||||
@Override
|
||||
public Long findTodayVisitCount(Date dayStart, Date dayEnd) {
|
||||
return sysLogMapper.findTodayVisitCount(dayStart,dayEnd);
|
||||
@ -55,7 +54,6 @@ public class SysLogServiceImpl extends ServiceImpl<SysLogMapper, SysLog> impleme
|
||||
public Long findTodayIp(Date dayStart, Date dayEnd) {
|
||||
return sysLogMapper.findTodayIp(dayStart,dayEnd);
|
||||
}
|
||||
//update-end--Author:zhangweijian Date:20190428 for:传入开始时间,结束时间参数
|
||||
|
||||
@Override
|
||||
public List<Map<String,Object>> findVisitCount(Date dayStart, Date dayEnd) {
|
||||
|
||||
@ -60,11 +60,10 @@ public class SysPermissionDataRuleImpl extends ServiceImpl<SysPermissionDataRule
|
||||
@Override
|
||||
public List<SysPermissionDataRule> queryPermissionDataRules(String username,String permissionId) {
|
||||
List<String> idsList = this.baseMapper.queryDataRuleIds(username, permissionId);
|
||||
//update-begin--Author:scott Date:20191119 for:数据权限失效问题处理--------------------
|
||||
// 代码逻辑说明: 数据权限失效问题处理--------------------
|
||||
if(idsList==null || idsList.size()==0) {
|
||||
return null;
|
||||
}
|
||||
//update-end--Author:scott Date:20191119 for:数据权限失效问题处理--------------------
|
||||
Set<String> set = new HashSet<String>();
|
||||
for (String ids : idsList) {
|
||||
if(oConvertUtils.isEmpty(ids)) {
|
||||
|
||||
@ -242,14 +242,13 @@ public class SysPermissionServiceImpl extends ServiceImpl<SysPermissionMapper, S
|
||||
permissionList = new ArrayList<>();
|
||||
}
|
||||
List<SysPermission> testRoleList = sysPermissionMapper.queryPermissionByTestRoleId();
|
||||
//update-begin-author:liusq date:20230427 for: [QQYUN-5168]【vue3】为什么出现两个菜单 菜单根据id去重
|
||||
// 代码逻辑说明: [QQYUN-5168]【vue3】为什么出现两个菜单 菜单根据id去重
|
||||
for (SysPermission permission: testRoleList) {
|
||||
boolean hasPerm = permissionList.stream().anyMatch(a->a.getId().equals(permission.getId()));
|
||||
if(!hasPerm){
|
||||
permissionList.add(permission);
|
||||
}
|
||||
}
|
||||
//update-end-author:liusq date:20230427 for: [QQYUN-5168]【vue3】为什么出现两个菜单 菜单根据id去重
|
||||
}
|
||||
//================= end 开启租户的时候 如果没有test角色,默认加入test角色================
|
||||
return permissionList;
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package org.jeecg.modules.system.service.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
@ -32,6 +33,7 @@ public class SysRoleIndexServiceImpl extends ServiceImpl<SysRoleIndexMapper, Sys
|
||||
public SysRoleIndex queryDefaultIndex() {
|
||||
LambdaQueryWrapper<SysRoleIndex> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(SysRoleIndex::getRoleCode, DefIndexConst.DEF_INDEX_ALL);
|
||||
queryWrapper.eq(SysRoleIndex::getStatus, CommonConstant.STATUS_1);
|
||||
SysRoleIndex entity = super.getOne(queryWrapper);
|
||||
// 保证不为空
|
||||
if (entity == null) {
|
||||
@ -150,4 +152,33 @@ public class SysRoleIndexServiceImpl extends ServiceImpl<SysRoleIndexMapper, Sys
|
||||
redisUtil.set(DefIndexConst.CACHE_TYPE + username,type);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新其他全局默认的状态值
|
||||
*
|
||||
* @param roleCode
|
||||
* @param status
|
||||
* @param id
|
||||
*/
|
||||
@Override
|
||||
public void updateOtherDefaultStatus(String roleCode, String status, String id) {
|
||||
//roleCode是全局默认
|
||||
if(oConvertUtils.isNotEmpty(roleCode) && DefIndexConst.DEF_INDEX_ALL.equals(roleCode)){
|
||||
//状态为开启状态
|
||||
if(oConvertUtils.isNotEmpty(status) && CommonConstant.STATUS_1.equals(status)){
|
||||
LambdaQueryWrapper<SysRoleIndex> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(SysRoleIndex::getRoleCode,roleCode);
|
||||
queryWrapper.eq(SysRoleIndex::getStatus,CommonConstant.STATUS_1);
|
||||
queryWrapper.ne(SysRoleIndex::getId,id);
|
||||
queryWrapper.select(SysRoleIndex::getId);
|
||||
List<SysRoleIndex> list = this.list(queryWrapper);
|
||||
if(CollectionUtil.isNotEmpty(list)){
|
||||
list.forEach(sysRoleIndex -> {
|
||||
sysRoleIndex.setStatus(CommonConstant.STATUS_0);
|
||||
});
|
||||
this.updateBatchById(list);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -23,10 +23,7 @@ import org.springframework.stereotype.Service;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
@ -90,7 +87,6 @@ public class SysTenantPackServiceImpl extends ServiceImpl<SysTenantPackMapper, S
|
||||
if (null != tenantId && tenantId != 0) {
|
||||
List<String> userIds = sysUserTenantMapper.getUserIdsByTenantId(tenantId);
|
||||
if (CollectionUtil.isNotEmpty(userIds)) {
|
||||
//update-begin---author:wangshuai---date:2025-09-03---for: 编辑时需要查看有没有未分配的用户---
|
||||
// 查询已存在的用户
|
||||
LambdaQueryWrapper<SysTenantPackUser> query = new LambdaQueryWrapper<>();
|
||||
query.eq(SysTenantPackUser::getTenantId, tenantId);
|
||||
@ -106,7 +102,6 @@ public class SysTenantPackServiceImpl extends ServiceImpl<SysTenantPackMapper, S
|
||||
.filter(userId -> !existingUserIds.contains(userId))
|
||||
.toList();
|
||||
for (String userId : newUserIds) {
|
||||
//update-end---author:wangshuai---date:2025-09-03---for: 编辑时需要查看有没有未分配的用户---
|
||||
SysTenantPackUser tenantPackUser = new SysTenantPackUser(tenantId, packId, userId);
|
||||
sysTenantPackUserMapper.insert(tenantPackUser);
|
||||
}
|
||||
@ -318,8 +313,11 @@ public class SysTenantPackServiceImpl extends ServiceImpl<SysTenantPackMapper, S
|
||||
LambdaQueryWrapper<SysTenantPack> query = new LambdaQueryWrapper<>();
|
||||
query.eq(SysTenantPack::getPackType,"default");
|
||||
List<SysTenantPack> sysTenantPacks = sysTenantPackMapper.selectList(query);
|
||||
// 取当前租户用户列表
|
||||
List<String> userIds = sysUserTenantMapper.getUserIdsByTenantId(tenantId);
|
||||
for (SysTenantPack sysTenantPack: sysTenantPacks) {
|
||||
syncDefaultPack2CurrentTenant(tenantId, sysTenantPack);
|
||||
// 代码逻辑说明: 【QQYUN-14007】演示系统,初始化租户套餐很慢---
|
||||
syncDefaultPack2CurrentTenant(tenantId, sysTenantPack, userIds);
|
||||
}
|
||||
}
|
||||
|
||||
@ -334,16 +332,24 @@ public class SysTenantPackServiceImpl extends ServiceImpl<SysTenantPackMapper, S
|
||||
query.eq(SysTenantPack::getPackType,"custom");
|
||||
query.eq(SysTenantPack::getTenantId, tenantId);
|
||||
List<SysTenantPack> currentTenantPacks = sysTenantPackMapper.selectList(query);
|
||||
Map<String, SysTenantPack> currentTenantPackMap = new HashMap<String, SysTenantPack>();
|
||||
// 代码逻辑说明: 【QQYUN-14007】演示系统,初始化租户套餐很慢---
|
||||
Map<String, SysTenantPack> currentTenantPackMap;
|
||||
if (oConvertUtils.listIsNotEmpty(currentTenantPacks)) {
|
||||
currentTenantPackMap = currentTenantPacks.stream().collect(Collectors.toMap(SysTenantPack::getPackName, o -> o, (existing, replacement) -> existing));
|
||||
} else {
|
||||
currentTenantPackMap = new HashMap<String, SysTenantPack>();
|
||||
}
|
||||
// 添加不存在的套餐包
|
||||
for (SysTenantPack defaultPacks : sysDefaultTenantPacks) {
|
||||
if(!currentTenantPackMap.containsKey(defaultPacks.getPackName())){
|
||||
syncDefaultPack2CurrentTenant(tenantId, defaultPacks);
|
||||
}
|
||||
}
|
||||
// 预取当前租户用户列表,避免在循环中重复查询
|
||||
List<String> userIds = sysUserTenantMapper.getUserIdsByTenantId(tenantId);
|
||||
// 计算需要同步的默认套餐包列表
|
||||
List<SysTenantPack> packsToSync = sysDefaultTenantPacks.stream()
|
||||
.filter(p -> !currentTenantPackMap.containsKey(p.getPackName()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 并行同步缺失的套餐包
|
||||
packsToSync.parallelStream().forEach(defaultPacks -> {
|
||||
syncDefaultPack2CurrentTenant(tenantId, defaultPacks, userIds);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -354,7 +360,7 @@ public class SysTenantPackServiceImpl extends ServiceImpl<SysTenantPackMapper, S
|
||||
* @author chenrui
|
||||
* @date 2025/2/5 19:41
|
||||
*/
|
||||
private void syncDefaultPack2CurrentTenant(Integer tenantId, SysTenantPack defaultPacks) {
|
||||
private void syncDefaultPack2CurrentTenant(Integer tenantId, SysTenantPack defaultPacks, List<String> userIds) {
|
||||
SysTenantPack pack = new SysTenantPack();
|
||||
BeanUtils.copyProperties(defaultPacks,pack);
|
||||
pack.setTenantId(tenantId);
|
||||
@ -362,22 +368,26 @@ public class SysTenantPackServiceImpl extends ServiceImpl<SysTenantPackMapper, S
|
||||
pack.setId("");
|
||||
sysTenantPackMapper.insert(pack);
|
||||
List<String> permissionsByPackId = sysPackPermissionMapper.getPermissionsByPackId(defaultPacks.getId());
|
||||
List<SysPackPermission> permissionList = new ArrayList<>();
|
||||
for (String permission:permissionsByPackId) {
|
||||
SysPackPermission packPermission = new SysPackPermission();
|
||||
packPermission.setPackId(pack.getId());
|
||||
packPermission.setPermissionId(permission);
|
||||
sysPackPermissionMapper.insert(packPermission);
|
||||
permissionList.add(packPermission);
|
||||
}
|
||||
if(CollectionUtil.isNotEmpty(permissionList)){
|
||||
sysPackPermissionMapper.insert(permissionList);
|
||||
}
|
||||
//如果需要自动分配给用户时候再去添加用户与套餐的关系数据
|
||||
if(oConvertUtils.isNotEmpty(defaultPacks.getIzSysn()) && CommonConstant.STATUS_1.equals(defaultPacks.getIzSysn())) {
|
||||
//查询当前租户下的用户
|
||||
List<String> userIds = sysUserTenantMapper.getUserIdsByTenantId(tenantId);
|
||||
List<SysTenantPackUser> packUserList = new ArrayList<>();
|
||||
if (oConvertUtils.isNotEmpty(userIds)) {
|
||||
for (String userId : userIds) {
|
||||
//根据租户id和套餐id添加用户与套餐关系数据
|
||||
SysTenantPackUser tenantPackUser = new SysTenantPackUser(tenantId, pack.getId(), userId);
|
||||
sysTenantPackUserMapper.insert(tenantPackUser);
|
||||
packUserList.add(tenantPackUser);
|
||||
}
|
||||
sysTenantPackUserMapper.insert(packUserList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -109,7 +109,7 @@ public class SysTenantServiceImpl extends ServiceImpl<SysTenantMapper, SysTenant
|
||||
String[] idArray = ids.split(SymbolConstant.COMMA);
|
||||
String userId = null;
|
||||
SysUser userByPhone = null;
|
||||
//update-begin---author:wangshuai ---date:20230313 for:【QQYUN-4605】后台的邀请谁加入租户,没办法选不是租户下的用户,通过手机号邀请------------
|
||||
// 代码逻辑说明: 【QQYUN-4605】后台的邀请谁加入租户,没办法选不是租户下的用户,通过手机号邀请------------
|
||||
if(oConvertUtils.isNotEmpty(phone)){
|
||||
userByPhone = userService.getUserByPhone(phone);
|
||||
//说明用户不存在
|
||||
@ -128,7 +128,6 @@ public class SysTenantServiceImpl extends ServiceImpl<SysTenantMapper, SysTenant
|
||||
|
||||
//循环租户id
|
||||
for (String id:idArray) {
|
||||
//update-begin---author:wangshuai ---date:20221223 for:[QQYUN-3371]租户逻辑改造,改成关系表------------
|
||||
//获取被邀请人是否已存在
|
||||
SysUserTenant userTenant = userTenantMapper.getUserTenantByTenantId(userId, Integer.valueOf(id));
|
||||
if(null == userTenant){
|
||||
@ -139,21 +138,14 @@ public class SysTenantServiceImpl extends ServiceImpl<SysTenantMapper, SysTenant
|
||||
userTenantMapper.insert(relation);
|
||||
//给当前用户添加租户下的所有套餐
|
||||
this.addPackUser(userId,id);
|
||||
//update-begin---author:wangshuai---date:2025-09-06---for:【QQYUN-13720】邀请用户加入租户,没有系统提醒,移除有---
|
||||
//邀请用户加入租户,发送消息
|
||||
this.sendInvitationTenantMessage(userByPhone,id);
|
||||
//update-end---author:wangshuai---date:2025-09-06---for:【QQYUN-13720】邀请用户加入租户,没有系统提醒,移除有---
|
||||
}else{
|
||||
//update-begin---author:wangshuai ---date:20230711 for:【QQYUN-5723】2、用户已经在租户里了,再次要求提示成功,应该提示用户已经存在------------
|
||||
//update-begin---author:wangshuai ---date:20230724 for:【QQYUN-5885】邀请用户加入提示不准确------------
|
||||
// 代码逻辑说明: 【QQYUN-5885】邀请用户加入提示不准确------------
|
||||
String tenantErrorInfo = getTenantErrorInfo(userTenant.getStatus());
|
||||
String errMsg = "手机号用户:" + userByPhone.getPhone() + " 昵称:" + userByPhone.getRealname() + "," + tenantErrorInfo;
|
||||
//update-end---author:wangshuai ---date:20230724 for:【QQYUN-5885】邀请用户加入提示不准确------------
|
||||
throw new JeecgBootException(errMsg);
|
||||
//update-end---author:wangshuai ---date:20230711 for:【QQYUN-5723】2、用户已经在租户里了,再次要求提示成功,应该提示用户已经存在------------
|
||||
}
|
||||
//update-end---author:wangshuai ---date:20221223 for:[QQYUN-3371]租户逻辑改造,改成关系表------------
|
||||
//update-end---author:wangshuai ---date:20230313 for:【QQYUN-4605】后台的邀请谁加入租户,没办法选不是租户下的用户,通过手机号邀请------------
|
||||
}
|
||||
}
|
||||
|
||||
@ -186,19 +178,17 @@ public class SysTenantServiceImpl extends ServiceImpl<SysTenantMapper, SysTenant
|
||||
public void leaveTenant(String userIds, String tenantId) {
|
||||
String[] userIdArray = userIds.split(SymbolConstant.COMMA);
|
||||
for (String userId:userIdArray) {
|
||||
//update-begin---author:wangshuai ---date:20221223 for:[QQYUN-3371]租户逻辑改造,改成关系表------------
|
||||
// 代码逻辑说明: [QQYUN-3371]租户逻辑改造,改成关系表------------
|
||||
LambdaQueryWrapper<SysUserTenant> query = new LambdaQueryWrapper<>();
|
||||
query.eq(SysUserTenant::getTenantId,tenantId);
|
||||
query.eq(SysUserTenant::getUserId,userId);
|
||||
userTenantMapper.delete(query);
|
||||
//update-end---author:wangshuai ---date:20221223 for:[QQYUN-3371]租户逻辑改造,改成关系表------------
|
||||
//update-begin---author:wangshuai---date:2025-09-06---for:【QQYUN-13720】移出用户当前租户,没有系统提醒---
|
||||
//代码逻辑说明: 【QQYUN-13720】移出用户当前租户,没有系统提醒---
|
||||
// 给移除人员发送消息
|
||||
SysTenantPackUser sysTenantPackUser = new SysTenantPackUser();
|
||||
sysTenantPackUser.setTenantId(Integer.valueOf(tenantId));
|
||||
sysTenantPackUser.setUserId(userId);
|
||||
sendMsgForDelete(sysTenantPackUser);
|
||||
//update-end---author:wangshuai---date:2025-09-06---for:【QQYUN-13720】移出用户当前租户,没有系统提醒---
|
||||
}
|
||||
//租户移除用户,直接删除用户租户产品包
|
||||
sysTenantPackUserMapper.deletePackUserByTenantId(Integer.valueOf(tenantId),Arrays.asList(userIds.split(SymbolConstant.COMMA)));
|
||||
@ -225,11 +215,10 @@ public class SysTenantServiceImpl extends ServiceImpl<SysTenantMapper, SysTenant
|
||||
sysTenant.setHouseNumber(RandomUtil.randomStringUpper(6));
|
||||
sysTenant.setDelFlag(CommonConstant.DEL_FLAG_0);
|
||||
this.save(sysTenant);
|
||||
//update-begin---author:wangshuai ---date:20230710 for:【QQYUN-5723】1、把当前创建人加入到租户关系里面------------
|
||||
//代码逻辑说明:【QQYUN-5723】1、把当前创建人加入到租户关系里面------------
|
||||
//当前登录人的id
|
||||
LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
this.saveTenantRelation(sysTenant.getId(),loginUser.getId());
|
||||
//update-end---author:wangshuai ---date:20230710 for:【QQYUN-5723】1、把当前创建人加入到租户关系里面------------
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -291,15 +280,11 @@ public class SysTenantServiceImpl extends ServiceImpl<SysTenantMapper, SysTenant
|
||||
}
|
||||
//删除租户
|
||||
tenantMapper.deleteByTenantId(list);
|
||||
//update-begin---author:wangshuai ---date:20230710 for:【QQYUN-5723】3、租户彻底删除,用户租户关系表也需要删除------------
|
||||
//删除租户下的用户
|
||||
userTenantMapper.deleteUserByTenantId(list);
|
||||
//update-ennd---author:wangshuai ---date:20230710 for:【QQYUN-5723】3、租户彻底删除,用户租户关系表也需要删除------------
|
||||
|
||||
//update-begin---author:wangshuai ---date:20230710 for:【QQYUN-5723】3、租户彻底删除,用户租户关系表也需要删除------------
|
||||
//删除租户下的产品包
|
||||
this.deleteTenantPackByTenantId(list);
|
||||
//update-ennd---author:wangshuai ---date:20230710 for:【QQYUN-5723】3、租户彻底删除,用户租户关系表也需要删除------------
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -336,9 +321,8 @@ public class SysTenantServiceImpl extends ServiceImpl<SysTenantMapper, SysTenant
|
||||
public int tenantIdGenerate(){
|
||||
synchronized (this){
|
||||
//获取最大值id
|
||||
//update-begin---author:wangshuai ---date:20230424 for:数据库没有租户的时候,如果为空的话会报错sql返回类型不匹配------------
|
||||
// 代码逻辑说明: 数据库没有租户的时候,如果为空的话会报错sql返回类型不匹配------------
|
||||
int maxTenantId = oConvertUtils.getInt(tenantMapper.getMaxTenantId(),0);
|
||||
//update-end---author:wangshuai ---date:20230424 for:数据库没有租户的时候,如果为空的话会报错sql返回类型不匹配------------
|
||||
if(maxTenantId >= 1000){
|
||||
return maxTenantId + 1;
|
||||
}else{
|
||||
@ -362,10 +346,8 @@ public class SysTenantServiceImpl extends ServiceImpl<SysTenantMapper, SysTenant
|
||||
//需要指配拥有者
|
||||
throw new JeecgBootException("assignedOwen");
|
||||
} else if (null != userIdsByTenantId && userIdsByTenantId.size() == 1) {
|
||||
//update-begin---author:wangshuai ---date:20230426 for:【QQYUN-5270】名下租户全部退出后,再次登录,提示租户全部冻结------------
|
||||
//只有拥有者的时候需要去注销租户
|
||||
throw new JeecgBootException("cancelTenant");
|
||||
//update-end---author:wangshuai ---date:20230426 for:【QQYUN-5270】名下租户全部退出后,再次登录,提示租户全部冻结------------
|
||||
} else {
|
||||
throw new JeecgBootException("退出租户失败,租户信息已不存在");
|
||||
}
|
||||
@ -379,14 +361,13 @@ public class SysTenantServiceImpl extends ServiceImpl<SysTenantMapper, SysTenant
|
||||
@Override
|
||||
public void changeOwenUserTenant(String userId, String tId) {
|
||||
//查询当前用户是否存在该租户下
|
||||
//update-begin---author:wangshuai ---date:20230705 for:租户id应该是传过来的,不应该是当前租户的------------
|
||||
// 代码逻辑说明: 租户id应该是传过来的,不应该是当前租户的------------
|
||||
int tenantId = oConvertUtils.getInt(tId, 0);
|
||||
SysTenant sysTenant = tenantMapper.selectById(tenantId);
|
||||
if(null == sysTenant){
|
||||
throw new JeecgBootException("退出租户失败,不存在此租户");
|
||||
}
|
||||
String createBy = sysTenant.getCreateBy();
|
||||
//update-end---author:wangshuai ---date:20230705 for:租户id应该是传过来的,不应该是当前租户的------------
|
||||
Integer count = userTenantMapper.userTenantIzExist(userId, tenantId);
|
||||
if (count == 0) {
|
||||
throw new JeecgBootException("退出租户失败,此租户下没有该用户");
|
||||
@ -408,7 +389,6 @@ public class SysTenantServiceImpl extends ServiceImpl<SysTenantMapper, SysTenant
|
||||
SysUserTenant userTenant = new SysUserTenant();
|
||||
userTenant.setStatus(CommonConstant.USER_TENANT_QUIT);
|
||||
userTenantMapper.update(userTenant,query);
|
||||
//update-end---author:wangshuai ---date:20230705 for:旧拥有者退出后,需要将就拥有者的用户租户关系改成已离职------------
|
||||
//离职流程
|
||||
this.leveUserProcess(userId, String.valueOf(tenantId));
|
||||
}
|
||||
@ -471,13 +451,11 @@ public class SysTenantServiceImpl extends ServiceImpl<SysTenantMapper, SysTenant
|
||||
result.setSuccess(true);
|
||||
result.setMessage("邀请成员成功,成员同意后方可加入");
|
||||
|
||||
//update-begin---author:wangshuai ---date:20230329 for:[QQYUN-4671]部门与用户,手机号邀请,没有在当前部门下,目前是在全组织中------------
|
||||
//6.保存用户部门关系
|
||||
if(oConvertUtils.isNotEmpty(departId)){
|
||||
//保存用户部门关系
|
||||
this.saveUserDepart(userByPhone.getId(),departId);
|
||||
}
|
||||
//update-end---author:wangshuai ---date:20230329 for:[QQYUN-4671]部门与用户,手机号邀请,没有在当前部门下,目前是在全组织中------------
|
||||
|
||||
// QQYUN-4527【应用】邀请成员加入组织,发送消息提醒
|
||||
sendMsgForInvitation(userByPhone, tenantId, sysUser.getRealname());
|
||||
@ -743,21 +721,18 @@ public class SysTenantServiceImpl extends ServiceImpl<SysTenantMapper, SysTenant
|
||||
messageDTO.setToAll(false);
|
||||
messageDTO.setToUser(user.getUsername());
|
||||
messageDTO.setFromUser("system");
|
||||
//update-begin---author:wangshuai ---date:20230706 for:【QQYUN-5730】租户邀请加入提示消息应该显示邀请人的名字------------
|
||||
// 代码逻辑说明: 【QQYUN-5730】租户邀请加入提示消息应该显示邀请人的名字------------
|
||||
String title = realname + " 邀请您加入 "+sysTenant.getName()+"。";
|
||||
//update-end---author:wangshuai ---date:20230706 for:【QQYUN-5730】租户邀请加入提示消息应该显示邀请人的名字------------
|
||||
messageDTO.setTitle(title);
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
messageDTO.setData(data);
|
||||
messageDTO.setContent(title);
|
||||
messageDTO.setType("system");
|
||||
//update-begin---author:wangshuai---date:2023-11-24---for:【QQYUN-7168】邀请成员时,会报错,但实际已经邀请成功了---
|
||||
// 代码逻辑说明: 【QQYUN-7168】邀请成员时,会报错,但实际已经邀请成功了---
|
||||
messageDTO.setCategory(CommonConstant.MSG_CATEGORY_1);
|
||||
//update-end---author:wangshuai---date:2023-11-24---for:【QQYUN-7168】邀请成员时,会报错,但实际已经邀请成功了---
|
||||
//update-begin---author:wangshuai ---date:20230721 for:【QQYUN-5726】邀请加入租户加个按钮直接跳转过去------------
|
||||
// 代码逻辑说明: 【QQYUN-5726】邀请加入租户加个按钮直接跳转过去------------
|
||||
messageDTO.setBusType(SysAnnmentTypeEnum.TENANT_INVITE.getType());
|
||||
sysBaseApi.sendBusAnnouncement(messageDTO);
|
||||
//update-end---author:wangshuai ---date:20230721 for:【QQYUN-5726】邀请加入租户加个按钮直接跳转过去------------
|
||||
}
|
||||
|
||||
|
||||
@ -774,13 +749,11 @@ public class SysTenantServiceImpl extends ServiceImpl<SysTenantMapper, SysTenant
|
||||
packUser.setRealname(sysTenantPackUser.getRealname());
|
||||
currentService.addTenantPackUser(packUser);
|
||||
|
||||
//update-begin---author:wangshuai ---date:20230328 for:[QQYUN-4674]租户管理员同意或拒绝成员没有系统通知------------
|
||||
//超级管理员成功加入发送系统消息
|
||||
SysTenant sysTenant = tenantMapper.selectById(sysTenantPackUser.getTenantId());
|
||||
String content = " 您已成功加入"+sysTenant.getName()+"的超级管理员的成员。";
|
||||
SysUser sysUser = userService.getById(sysTenantPackUser.getUserId());
|
||||
this.sendMsgForAgreeAndRefuseJoin(sysUser,content);
|
||||
//update-end---author:wangshuai ---date:20230328 for:[QQYUN-4674]租户管理员同意或拒绝成员没有系统通知------------
|
||||
}
|
||||
}
|
||||
|
||||
@ -793,13 +766,11 @@ public class SysTenantServiceImpl extends ServiceImpl<SysTenantMapper, SysTenant
|
||||
SysTenantPackUser packUser = sysTenantPackUserMapper.selectOne(query);
|
||||
if(packUser!=null && packUser.getId()!=null && packUser.getStatus()==0){
|
||||
sysTenantPackUserMapper.deleteById(packUser.getId());
|
||||
//update-begin---author:wangshuai ---date:20230328 for:[QQYUN-4674]租户管理员同意或拒绝成员没有系统通知------------
|
||||
//超级管理员拒绝加入发送系统消息
|
||||
SysTenant sysTenant = tenantMapper.selectById(sysTenantPackUser.getTenantId());
|
||||
String content = " 管理员已拒绝您加入"+sysTenant.getName()+"的超级管理员的成员请求。";
|
||||
SysUser sysUser = userService.getById(sysTenantPackUser.getUserId());
|
||||
this.sendMsgForAgreeAndRefuseJoin(sysUser,content);
|
||||
//update-end---author:wangshuai ---date:20230328 for:[QQYUN-4674]租户管理员同意或拒绝成员没有系统通知------------
|
||||
}
|
||||
}
|
||||
|
||||
@ -946,9 +917,8 @@ public class SysTenantServiceImpl extends ServiceImpl<SysTenantMapper, SysTenant
|
||||
throw new JeecgBootException("您不是该用户的创建人,无法删除!");
|
||||
}
|
||||
|
||||
//update-begin---author:wangshuai---date:2025-04-11---for:【QQYUN-11839】删除用户,需要输入被删除用户的密码,这逻辑对吗?不应该是管理员的密码吗---
|
||||
// 代码逻辑说明: 【QQYUN-11839】删除用户,需要输入被删除用户的密码,这逻辑对吗?不应该是管理员的密码吗---
|
||||
this.verifyCreateTimeAndPassword(sysUserData,password);
|
||||
//update-end---author:wangshuai---date:2025-04-11---for:【QQYUN-11839】删除用户,需要输入被删除用户的密码,这逻辑对吗?不应该是管理员的密码吗---
|
||||
|
||||
//step5 逻辑删除用户
|
||||
userService.deleteUser(userId);
|
||||
|
||||
@ -166,7 +166,6 @@ public class SysThirdAccountServiceImpl extends ServiceImpl<SysThirdAccountMappe
|
||||
user.setRealname(tlm.getUsername());
|
||||
user.setThirdUserUuid(tlm.getUuid());
|
||||
user.setTenantId(tenantId);
|
||||
//update-begin---author:wangshuai ---date:20230306 for:判断如果是钉钉的情况下,需要将第三方的用户id查询出来,发送模板的时候有用------------
|
||||
//=============begin 判断如果是钉钉的情况下,需要将第三方的用户id查询出来,发送模板的时候有用==========
|
||||
if(CommonConstant.DINGTALK.toLowerCase().equals(tlm.getSource())){
|
||||
AccessToken accessToken = JdtBaseAPI.getAccessToken(dingTalkClientId, dingTalkClientSecret);
|
||||
@ -180,7 +179,6 @@ public class SysThirdAccountServiceImpl extends ServiceImpl<SysThirdAccountMappe
|
||||
}else{
|
||||
user.setThirdUserId(tlm.getUuid());
|
||||
}
|
||||
//update-end---author:wangshuai ---date:20230306 for:判断如果是钉钉的情况下,需要将第三方的用户id查询出来,发送模板的时候有用------------
|
||||
super.save(user);
|
||||
return user;
|
||||
}
|
||||
@ -216,13 +214,12 @@ public class SysThirdAccountServiceImpl extends ServiceImpl<SysThirdAccountMappe
|
||||
public SysThirdAccount getOneByUuidAndThirdType(String unionid, String thirdType,Integer tenantId,String thirdUserId) {
|
||||
LambdaQueryWrapper<SysThirdAccount> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(SysThirdAccount::getThirdType, thirdType);
|
||||
//update-begin---author:wangshuai---date:2023-12-04---for: 如果第三方用户id为空那么就不走第三方用户查询逻辑,因为扫码登录third_user_id是唯一的,没有重复的情况---
|
||||
// 代码逻辑说明: 如果第三方用户id为空那么就不走第三方用户查询逻辑,因为扫码登录third_user_id是唯一的,没有重复的情况---
|
||||
if(oConvertUtils.isNotEmpty(thirdUserId)){
|
||||
queryWrapper.and((wrapper) ->wrapper.eq(SysThirdAccount::getThirdUserUuid,unionid).or().eq(SysThirdAccount::getThirdUserId,thirdUserId));
|
||||
}else{
|
||||
queryWrapper.eq(SysThirdAccount::getThirdUserUuid, unionid);
|
||||
}
|
||||
//update-end---author:wangshuai---date:2023-12-04---for:如果第三方用户id为空那么就不走第三方用户查询逻辑,因为扫码登录third_user_id是唯一的,没有重复的情况---
|
||||
queryWrapper.eq(SysThirdAccount::getTenantId, tenantId);
|
||||
return super.getOne(queryWrapper);
|
||||
}
|
||||
|
||||
@ -69,12 +69,11 @@ public class SysUserDepartServiceImpl extends ServiceImpl<SysUserDepartMapper, S
|
||||
depIdList.add(userDepart.getDepId());
|
||||
}
|
||||
|
||||
//update-begin---author:wangshuai ---date:20230112 for:判断是否开启租户saas模式,开启需要根据当前租户查询------------
|
||||
// 代码逻辑说明: 判断是否开启租户saas模式,开启需要根据当前租户查询------------
|
||||
if (MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL) {
|
||||
Integer tenantId = oConvertUtils.getInt(TenantContext.getTenant(), 0);
|
||||
queryDep.eq(SysDepart::getTenantId,tenantId);
|
||||
}
|
||||
//update-end---author:wangshuai ---date:20230112 for:判断是否开启租户saas模式,开启需要根据当前租户查询------------
|
||||
|
||||
queryDep.in(SysDepart::getId, depIdList);
|
||||
List<SysDepart> depList = sysDepartService.list(queryDep);
|
||||
@ -109,12 +108,18 @@ public class SysUserDepartServiceImpl extends ServiceImpl<SysUserDepartMapper, S
|
||||
userIdList.add(uDep.getUserId());
|
||||
}
|
||||
List<SysUser> userList = (List<SysUser>) sysUserMapper.selectBatchIds(userIdList);
|
||||
//update-begin-author:taoyan date:201905047 for:接口调用查询返回结果不能返回密码相关信息
|
||||
for (SysUser sysUser : userList) {
|
||||
sysUser.setSalt("");
|
||||
sysUser.setPassword("");
|
||||
if(CollectionUtil.isNotEmpty(userList)){
|
||||
|
||||
// 代码逻辑说明: JHHB-812 人员按照排序展示
|
||||
userList.sort(Comparator.comparing(SysUser::getSort,
|
||||
Comparator.nullsFirst(Comparator.naturalOrder())));
|
||||
|
||||
// 代码逻辑说明: 接口调用查询返回结果不能返回密码相关信息
|
||||
for (SysUser sysUser : userList) {
|
||||
sysUser.setSalt("");
|
||||
sysUser.setPassword("");
|
||||
}
|
||||
}
|
||||
//update-end-author:taoyan date:201905047 for:接口调用查询返回结果不能返回密码相关信息
|
||||
return userList;
|
||||
}
|
||||
return new ArrayList<SysUser>();
|
||||
@ -125,7 +130,7 @@ public class SysUserDepartServiceImpl extends ServiceImpl<SysUserDepartMapper, S
|
||||
*/
|
||||
@Override
|
||||
public List<SysUser> queryUserByDepCode(String depCode,String realname) {
|
||||
//update-begin-author:taoyan date:20210422 for: 根据部门选择用户接口代码优化
|
||||
// 代码逻辑说明: 根据部门选择用户接口代码优化
|
||||
if(oConvertUtils.isNotEmpty(realname)){
|
||||
realname = realname.trim();
|
||||
}
|
||||
@ -138,7 +143,6 @@ public class SysUserDepartServiceImpl extends ServiceImpl<SysUserDepartMapper, S
|
||||
map.put(sysUser.getId(), sysUser);
|
||||
}
|
||||
return new ArrayList<SysUser>(map.values());
|
||||
//update-end-author:taoyan date:20210422 for: 根据部门选择用户接口代码优化
|
||||
|
||||
}
|
||||
|
||||
@ -160,10 +164,9 @@ public class SysUserDepartServiceImpl extends ServiceImpl<SysUserDepartMapper, S
|
||||
Page<SysUser> page = new Page<SysUser>(pageNo, pageSize);
|
||||
if(oConvertUtils.isEmpty(departId)){
|
||||
LambdaQueryWrapper<SysUser> query = new LambdaQueryWrapper<>();
|
||||
//update-begin---author:wangshuai ---date:20220104 for:[JTC-297]已冻结用户仍可设置为代理人------------
|
||||
// 代码逻辑说明: [JTC-297]已冻结用户仍可设置为代理人------------
|
||||
query.eq(SysUser::getStatus,Integer.parseInt(CommonConstant.STATUS_1));
|
||||
//update-end---author:wangshuai ---date:20220104 for:[JTC-297]已冻结用户仍可设置为代理人------------
|
||||
//update-begin---author:liusq ---date:20231215 for:逗号分割多个用户翻译问题------------
|
||||
// 代码逻辑说明: 逗号分割多个用户翻译问题------------
|
||||
if(oConvertUtils.isNotEmpty(username)){
|
||||
String COMMA = ",";
|
||||
if(oConvertUtils.isNotEmpty(isMultiTranslate) && username.contains(COMMA)){
|
||||
@ -173,9 +176,8 @@ public class SysUserDepartServiceImpl extends ServiceImpl<SysUserDepartMapper, S
|
||||
query.like(SysUser::getUsername, username);
|
||||
}
|
||||
}
|
||||
//update-end---author:liusq ---date:20231215 for:逗号分割多个用户翻译问题------------
|
||||
|
||||
//update-begin---author:liusq ---date:20250908 for:JHHB-304 流程转办 人员选择时,加姓名搜索------------
|
||||
// 代码逻辑说明: JHHB-304 流程转办 人员选择时,加姓名搜索------------
|
||||
if(oConvertUtils.isNotEmpty(realname)){
|
||||
String COMMA = ",";
|
||||
if(oConvertUtils.isNotEmpty(isMultiTranslate) && realname.contains(COMMA)){
|
||||
@ -185,11 +187,10 @@ public class SysUserDepartServiceImpl extends ServiceImpl<SysUserDepartMapper, S
|
||||
query.like(SysUser::getRealname, realname);
|
||||
}
|
||||
}
|
||||
//update-end---author:liusq ---date:20250908 for:JHHB-304 流程转办 人员选择时,加姓名搜索------------
|
||||
|
||||
//update-begin---author:wangshuai ---date:20220608 for:[VUEN-1238]邮箱回复时,发送到显示的为用户id------------
|
||||
// 代码逻辑说明: [VUEN-1238]邮箱回复时,发送到显示的为用户id------------
|
||||
if(oConvertUtils.isNotEmpty(id)){
|
||||
//update-begin---author:wangshuai ---date:2024-06-25 for:【TV360X-1482】写信,选择用户后第一次回显没翻译------------
|
||||
// 代码逻辑说明: 【TV360X-1482】写信,选择用户后第一次回显没翻译------------
|
||||
String COMMA = ",";
|
||||
if(oConvertUtils.isNotEmpty(isMultiTranslate) && id.contains(COMMA)){
|
||||
String[] idArr = id.split(COMMA);
|
||||
@ -197,23 +198,21 @@ public class SysUserDepartServiceImpl extends ServiceImpl<SysUserDepartMapper, S
|
||||
}else {
|
||||
query.eq(SysUser::getId, id);
|
||||
}
|
||||
//update-end---author:wangshuai ---date:2024-06-25 for:【TV360X-1482】写信,选择用户后第一次回显没翻译------------
|
||||
}
|
||||
//update-end---author:wangshuai ---date:20220608 for:[VUEN-1238]邮箱回复时,发送到显示的为用户id------------
|
||||
//update-begin---author:wangshuai ---date:20220902 for:[VUEN-2121]临时用户不能直接显示------------
|
||||
// 代码逻辑说明: [VUEN-2121]临时用户不能直接显示------------
|
||||
query.ne(SysUser::getUsername,"_reserve_user_external");
|
||||
//update-end---author:wangshuai ---date:20220902 for:[VUEN-2121]临时用户不能直接显示------------
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
// 代码逻辑说明: 【JHHB-765】需要能设置排序---
|
||||
query.orderByAsc(SysUser::getSort);
|
||||
query.orderByDesc(SysUser::getCreateTime);
|
||||
//------------------------------------------------------------------------------------------------
|
||||
//是否开启系统管理模块的多租户数据隔离【SAAS多租户模式】
|
||||
if (MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL) {
|
||||
String tenantId = oConvertUtils.getString(TenantContext.getTenant(), "0");
|
||||
//update-begin---author:wangshuai ---date:20221223 for:[QQYUN-3371]租户逻辑改造,改成关系表------------
|
||||
// 代码逻辑说明: [QQYUN-3371]租户逻辑改造,改成关系表------------
|
||||
List<String> userIdList = userTenantMapper.getUserIdsByTenantId(Integer.valueOf(tenantId));
|
||||
if(null!=userIdList && userIdList.size()>0){
|
||||
query.in(SysUser::getId,userIdList);
|
||||
}
|
||||
//update-end---author:wangshuai ---date:20221223 for:[QQYUN-3371]租户逻辑改造,改成关系表------------
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------
|
||||
pageList = sysUserMapper.selectPage(page, query);
|
||||
@ -225,7 +224,7 @@ public class SysUserDepartServiceImpl extends ServiceImpl<SysUserDepartMapper, S
|
||||
List<SysUser> userList = pageList.getRecords();
|
||||
if(userList!=null && userList.size()>0){
|
||||
List<String> userIds = userList.stream().map(SysUser::getId).collect(Collectors.toList());
|
||||
Map<String, SysUser> map = new HashMap(5);
|
||||
Map<String, SysUser> map = new LinkedHashMap(5);
|
||||
if(userIds!=null && userIds.size()>0){
|
||||
// 查部门名称
|
||||
Map<String,String> useDepNames = this.getDepNamesByUserIds(userIds);
|
||||
@ -274,46 +273,47 @@ public class SysUserDepartServiceImpl extends ServiceImpl<SysUserDepartMapper, S
|
||||
}else{
|
||||
// 有部门ID 需要走自定义sql
|
||||
SysDepart sysDepart = sysDepartService.getById(departId);
|
||||
//update-begin---author:wangshuai ---date:20220908 for:部门排除自己------------
|
||||
// 代码逻辑说明: 部门排除自己------------
|
||||
pageList = this.baseMapper.getUserInformation(page, sysDepart.getOrgCode(), keyword,sysUser.getId());
|
||||
//update-end---author:wangshuai ---date:20220908 for:部门排除自己--------------
|
||||
}
|
||||
return pageList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IPage<SysUser> getUserInformation(Integer tenantId, String departId,String roleId, String keyword, Integer pageSize, Integer pageNo, String excludeUserIdList) {
|
||||
public IPage<SysUser> getUserInformation(Integer tenantId, String departId,String roleId, String keyword, Integer pageSize, Integer pageNo, String excludeUserIdList, String includeUsernameList) {
|
||||
IPage<SysUser> pageList = null;
|
||||
// 部门ID不存在 直接查询用户表即可
|
||||
Page<SysUser> page = new Page<>(pageNo, pageSize);
|
||||
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
|
||||
List<String> userIdList = new ArrayList<>();
|
||||
List<String> inUsernameList = new ArrayList<>();
|
||||
if(oConvertUtils.isNotEmpty(excludeUserIdList)){
|
||||
userIdList = Arrays.asList(excludeUserIdList.split(SymbolConstant.COMMA));
|
||||
}
|
||||
if(oConvertUtils.isNotEmpty(includeUsernameList)){
|
||||
inUsernameList = Arrays.asList(includeUsernameList.split(SymbolConstant.COMMA));
|
||||
}
|
||||
if(oConvertUtils.isNotEmpty(departId)){
|
||||
// 有部门ID 需要走自定义sql
|
||||
SysDepart sysDepart = sysDepartService.getById(departId);
|
||||
//update-begin-author:taoyan date:2023-1-3 for: 用户选择组件 加载用户需要根据租户ID过滤
|
||||
//update-begin---author:wangshuai---date:2024-02-02---for:【QQYUN-8239】用户角色,添加用户 返回2页数据,实际只显示一页---
|
||||
//update-begin---author:wangshuai---date:2024-02-02---for:【QQYUN-8239】用户角色,添加用户 返回2页数据,实际只显示一页---
|
||||
// 代码逻辑说明: 【QQYUN-8239】用户角色,添加用户 返回2页数据,实际只显示一页---
|
||||
pageList = this.baseMapper.getProcessUserList(page, sysDepart.getOrgCode(), keyword, tenantId, userIdList);
|
||||
//update-end---author:wangshuai---date:2024-02-02---for:【QQYUN-8239】用户角色,添加用户 返回2页数据,实际只显示一页---
|
||||
} else if (oConvertUtils.isNotEmpty(roleId)) {
|
||||
//update-begin---author:wangshuai---date:2024-02-02---for:【QQYUN-8239】用户角色,添加用户 返回2页数据,实际只显示一页---
|
||||
// 代码逻辑说明: 【QQYUN-8239】用户角色,添加用户 返回2页数据,实际只显示一页---
|
||||
pageList = this.sysUserMapper.selectUserListByRoleId(page, roleId, keyword, tenantId,userIdList);
|
||||
//update-end---author:wangshuai---date:2024-02-02---for:【QQYUN-8239】用户角色,添加用户 返回2页数据,实际只显示一页---
|
||||
//update-end-author:taoyan date:2023-1-3 for: 用户选择组件 加载用户需要根据租户ID过滤
|
||||
} else{
|
||||
LambdaQueryWrapper<SysUser> query = new LambdaQueryWrapper<>();
|
||||
query.eq(SysUser::getStatus,Integer.parseInt(CommonConstant.STATUS_1));
|
||||
query.ne(SysUser::getUsername,"_reserve_user_external");
|
||||
//update-begin---author:wangshuai---date:2024-02-02---for:【QQYUN-8239】用户角色,添加用户 返回2页数据,实际只显示一页---
|
||||
if(inUsernameList!=null && inUsernameList.size()>0){
|
||||
query.in(SysUser::getUsername, inUsernameList);
|
||||
}
|
||||
|
||||
// 代码逻辑说明: 【QQYUN-8239】用户角色,添加用户 返回2页数据,实际只显示一页---
|
||||
if(oConvertUtils.isNotEmpty(excludeUserIdList)){
|
||||
query.notIn(SysUser::getId,Arrays.asList(excludeUserIdList.split(SymbolConstant.COMMA)));
|
||||
}
|
||||
//update-end---author:wangshuai---date:2024-02-02---for:【QQYUN-8239】用户角色,添加用户 返回2页数据,实际只显示一页---
|
||||
// 支持租户隔离
|
||||
if (tenantId != null) {
|
||||
List<String> userIds = userTenantMapper.getUserIdsByTenantId(tenantId);
|
||||
@ -328,6 +328,10 @@ public class SysUserDepartServiceImpl extends ServiceImpl<SysUserDepartMapper, S
|
||||
//这个语法可以将or用括号包起来,避免数据查不到
|
||||
query.and((wrapper) -> wrapper.like(SysUser::getUsername, keyword).or().like(SysUser::getRealname,keyword));
|
||||
}
|
||||
|
||||
// 【JHHB-811】添加排序
|
||||
query.orderByAsc(SysUser::getSort).orderByDesc(SysUser::getCreateTime);
|
||||
|
||||
pageList = sysUserMapper.selectPage(page, query);
|
||||
}
|
||||
// 批量查询用户的所属部门
|
||||
|
||||
@ -32,12 +32,14 @@ import org.jeecg.common.exception.JeecgBootException;
|
||||
import org.jeecg.common.system.vo.LoginUser;
|
||||
import org.jeecg.common.system.vo.SysUserCacheInfo;
|
||||
import org.jeecg.common.util.*;
|
||||
import org.jeecg.common.util.encryption.AesEncryptUtil;
|
||||
import org.jeecg.config.JeecgBaseConfig;
|
||||
import org.jeecg.config.mybatis.MybatisPlusSaasConfig;
|
||||
import org.jeecg.modules.base.service.BaseCommonService;
|
||||
import org.jeecg.modules.jmreport.common.util.OkConvertUtils;
|
||||
import org.jeecg.modules.message.handle.impl.SystemSendMsgHandle;
|
||||
import org.jeecg.modules.system.entity.*;
|
||||
import org.jeecg.modules.system.mapper.*;
|
||||
import org.jeecg.modules.system.model.SysLoginModel;
|
||||
import org.jeecg.modules.system.model.SysUserSysDepPostModel;
|
||||
import org.jeecg.modules.system.model.SysUserSysDepartModel;
|
||||
import org.jeecg.modules.system.service.*;
|
||||
@ -59,6 +61,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
@ -132,25 +135,37 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
|
||||
@Autowired
|
||||
private SysUserDepPostMapper depPostMapper;
|
||||
|
||||
|
||||
@Autowired
|
||||
private JeecgBaseConfig jeecgBaseConfig;
|
||||
|
||||
/**
|
||||
* 管理员账号
|
||||
*/
|
||||
public static final String[] ADMIN_ACCOUNT = new String[]{"admin"};
|
||||
|
||||
@Override
|
||||
public Result<IPage<SysUser>> queryPageList(HttpServletRequest req, QueryWrapper<SysUser> queryWrapper, Integer pageSize, Integer pageNo) {
|
||||
Result<IPage<SysUser>> result = new Result<IPage<SysUser>>();
|
||||
//update-begin-Author:wangshuai--Date:20211119--for:【vue3】通过部门id查询用户,通过code查询id
|
||||
//部门ID
|
||||
String departId = req.getParameter("departId");
|
||||
if (oConvertUtils.isNotEmpty(departId)) {
|
||||
LambdaQueryWrapper<SysUserDepart> query = new LambdaQueryWrapper<>();
|
||||
query.eq(SysUserDepart::getDepId, departId);
|
||||
List<SysUserDepart> list = sysUserDepartMapper.selectList(query);
|
||||
//代码逻辑说明:【JHHB-762】用户管理需要支持按组织架构查询用户(支持多选)---
|
||||
//兼容多个部门id
|
||||
LambdaQueryWrapper<SysUserDepart> query = new LambdaQueryWrapper<>();
|
||||
if(departId.contains(SymbolConstant.COMMA)) {
|
||||
query.in(SysUserDepart::getDepId, Arrays.asList(departId.split(SymbolConstant.COMMA)));
|
||||
} else {
|
||||
query.eq(SysUserDepart::getDepId, departId);
|
||||
}
|
||||
List<SysUserDepart> list = sysUserDepartMapper.selectList(query);
|
||||
List<String> userIds = list.stream().map(SysUserDepart::getUserId).collect(Collectors.toList());
|
||||
//update-begin---author:wangshuai ---date:20220322 for:[issues/I4XTYB]查询用户时,当部门id 下没有分配用户时接口报错------------
|
||||
// 代码逻辑说明: [issues/I4XTYB]查询用户时,当部门id 下没有分配用户时接口报错------------
|
||||
if (oConvertUtils.listIsNotEmpty(userIds)) {
|
||||
queryWrapper.in("id", userIds);
|
||||
} else {
|
||||
return Result.OK();
|
||||
}
|
||||
//update-end---author:wangshuai ---date:20220322 for:[issues/I4XTYB]查询用户时,当部门id 下没有分配用户时接口报错------------
|
||||
}
|
||||
//用户ID
|
||||
String code = req.getParameter("code");
|
||||
@ -158,16 +173,14 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
queryWrapper.in("id", Arrays.asList(code.split(",")));
|
||||
pageSize = code.split(",").length;
|
||||
}
|
||||
//update-end-Author:wangshuai--Date:20211119--for:【vue3】通过部门id查询用户,通过code查询id
|
||||
|
||||
//update-begin-author:taoyan--date:20220104--for: JTC-372 【用户冻结问题】 online授权、用户组件,选择用户都能看到被冻结的用户
|
||||
// 代码逻辑说明: JTC-372 【用户冻结问题】 online授权、用户组件,选择用户都能看到被冻结的用户
|
||||
String status = req.getParameter("status");
|
||||
if (oConvertUtils.isNotEmpty(status)) {
|
||||
queryWrapper.eq("status", Integer.parseInt(status));
|
||||
}
|
||||
//update-end-author:taoyan--date:20220104--for: JTC-372 【用户冻结问题】 online授权、用户组件,选择用户都能看到被冻结的用户
|
||||
|
||||
//update-begin---author:wangshuai---date:2024-03-08---for:【QQYUN-8110】在线通讯录支持设置权限(只能看分配的技术支持)---
|
||||
// 代码逻辑说明: 【QQYUN-8110】在线通讯录支持设置权限(只能看分配的技术支持)---
|
||||
String tenantId = TokenUtils.getTenantIdByRequest(req);
|
||||
String lowAppId = TokenUtils.getLowAppIdByRequest(req);
|
||||
// Object bean = ResourceUtil.getImplementationClass(DataEnhanceEnum.getClassPath(tenantId,lowAppId));
|
||||
@ -179,10 +192,12 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
// queryWrapper.in("id", userIds);
|
||||
// }
|
||||
// }
|
||||
//update-end---author:wangshuai---date:2024-03-08---for:【QQYUN-8110】在线通讯录支持设置权限(只能看分配的技术支持)---
|
||||
|
||||
//TODO 外部模拟登陆临时账号,列表不显示
|
||||
queryWrapper.ne("username", "_reserve_user_external");
|
||||
// 代码逻辑说明: 【JHHB-765】需要能设置排序---
|
||||
queryWrapper.orderByAsc("sort");
|
||||
queryWrapper.orderByDesc("create_time");
|
||||
Page<SysUser> page = new Page<SysUser>(pageNo, pageSize);
|
||||
IPage<SysUser> pageList = this.page(page, queryWrapper);
|
||||
|
||||
@ -194,6 +209,11 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
Map<String, String> useDepNames = this.getDepNamesByUserIds(userIds);
|
||||
pageList.getRecords().forEach(item -> {
|
||||
item.setOrgCodeTxt(useDepNames.get(item.getId()));
|
||||
//增加所属部门id,前台需要展示
|
||||
List<String> departs = sysDepartMapper.queryDepartsByUserId(item.getId());
|
||||
if(oConvertUtils.isNotEmpty(departs)){
|
||||
item.setBelongDepIds(String.join(SymbolConstant.COMMA, departs));
|
||||
}
|
||||
//查询用户的租户ids
|
||||
List<Integer> list = userTenantMapper.getTenantIdsByUserId(item.getId());
|
||||
if (oConvertUtils.isNotEmpty(list)) {
|
||||
@ -206,13 +226,10 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
posTenantId = oConvertUtils.getInt(TenantContext.getTenant(), 0);;
|
||||
}
|
||||
//查询用户职位关系表(获取租户下面的)
|
||||
//update-begin---author:wangshuai---date:2023-11-15---for:【QQYUN-7028】用户职务保存后未回显---
|
||||
// 代码逻辑说明: 【QQYUN-7028】用户职务保存后未回显---
|
||||
List<String> positionList = sysUserPositionMapper.getPositionIdByUserTenantId(item.getId(),posTenantId);
|
||||
//update-end---author:wangshuai---date:2023-11-15---for:【QQYUN-7028】用户职务保存后未回显---
|
||||
//update-end---author:wangshuai ---date:20230228 for:[QQYUN-4354]加入更多字段:当前加入时间应该取当前租户的/职位也是当前租户下的------------
|
||||
item.setPost(CommonUtils.getSplitText(positionList,SymbolConstant.COMMA));
|
||||
|
||||
//update-begin---author:wangshuai---date:2023-10-08---for:【QQYUN-6668】钉钉部门和用户同步,我怎么知道哪些用户是双向绑定成功的---
|
||||
//是否根据租户隔离(敲敲云用户列表专用,用于展示是否同步钉钉)
|
||||
if (MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL) {
|
||||
//查询账号表是否已同步钉钉
|
||||
@ -227,14 +244,11 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
item.setIzBindThird(true);
|
||||
}
|
||||
}
|
||||
//update-end---author:wangshuai---date:2023-10-08---for:【QQYUN-6668】钉钉部门和用户同步,我怎么知道哪些用户是双向绑定成功的---
|
||||
//update-begin---author:wangshuai---date:2025-09-06---for: 兼职岗位改造成中间表的方式---
|
||||
//查询部门的兼职岗位
|
||||
List<String> depPostList = depPostMapper.getDepPostByUserId(item.getId());
|
||||
if(CollectionUtil.isNotEmpty(depPostList)){
|
||||
item.setOtherDepPostId(StringUtils.join(depPostList.toArray(), SymbolConstant.COMMA));
|
||||
}
|
||||
//update-end---author:wangshuai---date:2025-09-06---for:兼职岗位改造成中间表的方式---
|
||||
});
|
||||
}
|
||||
|
||||
@ -272,6 +286,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
String password = sysUser.getPassword();
|
||||
String passwordEncode = PasswordUtil.encrypt(sysUser.getUsername(), password, salt);
|
||||
sysUser.setPassword(passwordEncode);
|
||||
sysUser.setLastPwdUpdateTime(new Date());
|
||||
this.userMapper.updateById(sysUser);
|
||||
return Result.ok("密码修改成功!");
|
||||
}
|
||||
@ -280,11 +295,9 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
@CacheEvict(value={CacheConstant.SYS_USERS_CACHE}, allEntries=true)
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean deleteUser(String userId) {
|
||||
//update-begin---author:wangshuai---date:2024-01-16---for:【QQYUN-7974】admin用户禁止删除---
|
||||
//1.验证当前用户是管理员账号 admin
|
||||
//验证用户是否为管理员
|
||||
this.checkUserAdminRejectDel(userId);
|
||||
//update-end---author:wangshuai---date:2024-01-16---for:【QQYUN-7974】admin用户禁止删除---
|
||||
|
||||
//2.删除用户
|
||||
this.removeById(userId);
|
||||
@ -366,7 +379,6 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
//只有 X-Version=v3 的时候,才读取sys_role_index表获取角色首页配置
|
||||
boolean isV3 = CommonConstant.VERSION_V3.equals(version);
|
||||
if (isV3) {
|
||||
//update-begin-author:liusq---date:2025-07-01--for: [QQYUN-12980] 【首页配置】首页自定义配置功能页面
|
||||
//1.先查询 用户USER级别 的所有首页配置
|
||||
if(oConvertUtils.isNotEmpty(username)){
|
||||
LambdaQueryWrapper<SysRoleIndex> routeIndexUserQuery = new LambdaQueryWrapper<>();
|
||||
@ -391,11 +403,10 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
String componentUrl = RoleIndexConfigEnum.getIndexByRoles(roles);
|
||||
roleIndex = new SysRoleIndex(componentUrl);
|
||||
//用户所有角色
|
||||
//update-begin-author:liusq---date:2025-07-21--for: [QQYUN-13187]【新用户登录报错】没有添加角色时 报错
|
||||
// 代码逻辑说明: [QQYUN-13187]【新用户登录报错】没有添加角色时 报错
|
||||
if(CollectionUtil.isNotEmpty(roles)){
|
||||
routeIndexQuery.in(SysRoleIndex::getRoleCode, roles);
|
||||
}
|
||||
//update-end-author:liusq---date:2025-07-21--for: [QQYUN-13187]【新用户登录报错】没有添加角色时 报错
|
||||
//优先级正序排序
|
||||
routeIndexQuery.orderByAsc(SysRoleIndex::getPriority);
|
||||
list = sysRoleIndexService.list(routeIndexQuery);
|
||||
@ -404,7 +415,6 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
}
|
||||
}
|
||||
}
|
||||
//update-end-author:liusq---date:2025-07-01--for: [QQYUN-12980] 【首页配置】首页自定义配置功能页面
|
||||
}
|
||||
|
||||
if (oConvertUtils.isEmpty(roleIndex.getComponent())) {
|
||||
@ -552,7 +562,6 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
return res;
|
||||
}
|
||||
|
||||
//update-begin-author:taoyan date:2022-9-13 for: VUEN-2245【漏洞】发现新漏洞待处理20220906 ----sql注入 方法没有使用,注掉
|
||||
/* @Override
|
||||
public IPage<SysUser> getUserByDepartIdAndQueryWrapper(Page<SysUser> page, String departId, QueryWrapper<SysUser> queryWrapper) {
|
||||
LambdaQueryWrapper<SysUser> lambdaQueryWrapper = queryWrapper.lambda();
|
||||
@ -562,7 +571,6 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
|
||||
return userMapper.selectPage(page, lambdaQueryWrapper);
|
||||
}*/
|
||||
//update-end-author:taoyan date:2022-9-13 for: VUEN-2245【漏洞】发现新漏洞待处理20220906 ----sql注入 方法没有使用,注掉
|
||||
|
||||
@Override
|
||||
public IPage<SysUserSysDepartModel> queryUserByOrgCode(String orgCode, SysUser userParams, IPage page) {
|
||||
@ -590,7 +598,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
*/
|
||||
@Override
|
||||
public IPage<SysUser> getUserByRoleId(Page<SysUser> page, String roleId, String username, String realname) {
|
||||
//update-begin---author:wangshuai ---date:20230220 for:[QQYUN-3980]组织管理中 职位功能 职位表加租户id 加职位-用户关联表------------
|
||||
// 代码逻辑说明: [QQYUN-3980]组织管理中 职位功能 职位表加租户id 加职位-用户关联表------------
|
||||
IPage<SysUser> userRoleList = userMapper.getUserByRoleId(page, roleId, username,realname);
|
||||
List<SysUser> records = userRoleList.getRecords();
|
||||
if (null != records && records.size() > 0) {
|
||||
@ -604,7 +612,6 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
}
|
||||
}
|
||||
return userRoleList;
|
||||
//update-end---author:wangshuai ---date:20230220 for:[QQYUN-3980]组织管理中 职位功能 职位表加租户id 加职位-用户关联表------------
|
||||
}
|
||||
|
||||
|
||||
@ -692,9 +699,8 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
return result;
|
||||
}
|
||||
//情况2:根据用户信息查询,该用户已注销
|
||||
//update-begin---author:王帅 Date:20200601 for:if条件永远为falsebug------------
|
||||
// 代码逻辑说明: if条件永远为falsebug------------
|
||||
if (CommonConstant.DEL_FLAG_1.equals(sysUser.getDelFlag())) {
|
||||
//update-end---author:王帅 Date:20200601 for:if条件永远为falsebug------------
|
||||
baseCommonService.addLog("用户登录失败,用户名:" + sysUser.getUsername() + "已注销!", CommonConstant.LOG_TYPE_1, null);
|
||||
result.error500("该用户已注销");
|
||||
return result;
|
||||
@ -710,11 +716,10 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
|
||||
@Override
|
||||
public List<SysUser> queryLogicDeleted() {
|
||||
//update-begin---author:wangshuai ---date:20221116 for:回收站查询未离职的------------
|
||||
// 代码逻辑说明: 回收站查询未离职的------------
|
||||
LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.ne(SysUser::getStatus, CommonConstant.USER_QUIT);
|
||||
return this.queryLogicDeleted(wrapper);
|
||||
//update-end---author:wangshuai ---date:20221116 for:回收站查询未离职的--------------
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -788,10 +793,13 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void saveUser(SysUser user, String selectedRoles, String selectedDeparts, String relTenantIds, boolean izSyncPack) {
|
||||
//step.1 保存用户
|
||||
if(null == user.getSort()){
|
||||
user.setSort(CommonConstant.DEFAULT_USER_SORT);
|
||||
}
|
||||
//step.1 保存用户
|
||||
this.save(user);
|
||||
//获取用户保存前台传过来的租户id并添加到租户
|
||||
this.saveUserTenant(user.getId(),relTenantIds, izSyncPack);
|
||||
this.saveUserTenant(user.getId(),relTenantIds, izSyncPack);
|
||||
//step.2 保存角色
|
||||
if(oConvertUtils.isNotEmpty(selectedRoles)) {
|
||||
String[] arr = selectedRoles.split(",");
|
||||
@ -822,6 +830,9 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
public void editUser(SysUser user, String roles, String departs, String relTenantIds, String updateFromPage) {
|
||||
//获取用户编辑前台传过来的租户id
|
||||
this.editUserTenants(user.getId(),relTenantIds);
|
||||
if(null == user.getSort()){
|
||||
user.setSort(CommonConstant.DEFAULT_USER_SORT);
|
||||
}
|
||||
//step.1 修改用户基础信息
|
||||
this.updateById(user);
|
||||
//step.2 修改角色
|
||||
@ -874,12 +885,11 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
//step.5 修改职位
|
||||
this.editUserPosition(user.getId(),user.getPost());
|
||||
|
||||
//update-begin---author:wangshuai---date:2025-09-06---for:兼职岗位改造成中间表的方式---
|
||||
//代码逻辑说明: 兼职岗位改造成中间表的方式---
|
||||
//step6 修改兼职岗位
|
||||
//先删后加
|
||||
depPostMapper.delete(new QueryWrapper<SysUserDepPost>().lambda().eq(SysUserDepPost::getUserId, user.getId()));
|
||||
this.saveUserOtherDepPost(user.getId(),user.getOtherDepPostId());
|
||||
//update-end---author:wangshuai---date:2025-09-06---for:兼职岗位改造成中间表的方式---
|
||||
}
|
||||
|
||||
|
||||
@ -939,7 +949,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
if(null == sysUser){
|
||||
throw new JeecgBootException("离职失败,该用户已不存在");
|
||||
}
|
||||
//update-begin---author:wangshuai ---date:20230111 for:[QQYUN-3951]租户用户离职重构------------
|
||||
// 代码逻辑说明: [QQYUN-3951]租户用户离职重构------------
|
||||
int tenantId = oConvertUtils.getInt(TenantContext.getTenant(), 0);
|
||||
//更新用户租户表的状态为离职状态
|
||||
if(tenantId==0){
|
||||
@ -951,7 +961,6 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
SysUserTenant userTenant = new SysUserTenant();
|
||||
userTenant.setStatus(CommonConstant.USER_TENANT_QUIT);
|
||||
userTenantMapper.update(userTenant,query);
|
||||
//update-end---author:wangshuai ---date:20230111 for:[QQYUN-3951]租户用户离职重构------------
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -971,16 +980,12 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
*/
|
||||
@Override
|
||||
public Result<JSONObject> setLoginTenant(SysUser sysUser, JSONObject obj, String username, Result<JSONObject> result){
|
||||
// update-begin--Author:sunjianlei Date:20210802 for:获取用户租户信息
|
||||
//用户有哪些租户
|
||||
// List<SysTenant> tenantList = null;
|
||||
//update-begin---author:wangshuai ---date:20221223 for:[QQYUN-3371]租户逻辑改造,改成关系表------------
|
||||
//update-begin---author:wangshuai ---date:20230427 for:【QQYUN-5270】名下租户全部退出后,再次登录出现租户冻结------------
|
||||
// 代码逻辑说明: [QQYUN-3371]租户逻辑改造,改成关系表
|
||||
List<SysTenant> tenantList = relationMapper.getTenantNoCancel(sysUser.getId());
|
||||
obj.put("tenantList", tenantList);
|
||||
//update-end---author:wangshuai ---date:20230427 for:【QQYUN-5270】名下租户全部退出后,再次登录出现租户冻结------------
|
||||
// if (null!=tenantIdList && tenantIdList.size()>0) {
|
||||
// //update-end---author:wangshuai ---date:20221223 for:[QQYUN-3371]租户逻辑改造,改成关系表--------------
|
||||
// //-------------------------------------------------------------------------------------
|
||||
// //查询有效的租户集合
|
||||
// LambdaQueryWrapper<SysTenant> queryWrapper = new LambdaQueryWrapper<>();
|
||||
@ -995,8 +1000,6 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
// obj.put("tenantList", tenantList);
|
||||
// }
|
||||
// }
|
||||
//update-end---author:wangshuai ---date:20221223 for:[QQYUN-3371]租户逻辑改造,改成关系表--------------
|
||||
// update-end--Author:sunjianlei Date:20210802 for:获取用户租户信息
|
||||
|
||||
|
||||
//登录会话租户ID,有效性重置
|
||||
@ -1016,7 +1019,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
}
|
||||
//设置用户登录缓存租户
|
||||
this.updateUserDepart(username, null,sysUser.getLoginTenantId());
|
||||
log.info(" 登录接口用户的租户ID = {}", sysUser.getLoginTenantId());
|
||||
log.debug(" 登录接口用户的租户ID = {}", sysUser.getLoginTenantId());
|
||||
if(sysUser.getLoginTenantId()!=null){
|
||||
//登录的时候需要手工设置下会话中的租户ID,不然登录接口无法通过租户隔离查询到数据
|
||||
TenantContext.setTenant(sysUser.getLoginTenantId()+"");
|
||||
@ -1073,7 +1076,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
}else{
|
||||
//是否开启系统管理模块的多租户数据隔离【SAAS多租户模式】
|
||||
if (MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL) {
|
||||
//update-begin---author:wangshuai ---date:20230220 for:判断当前用户是否在当前租户里面,如果不存在在新增------------
|
||||
// 代码逻辑说明: 判断当前用户是否在当前租户里面,如果不存在在新增------------
|
||||
String tenantId = TenantContext.getTenant();
|
||||
if(oConvertUtils.isNotEmpty(tenantId)){
|
||||
Integer count = relationMapper.userTenantIzExist(userId, Integer.parseInt(tenantId));
|
||||
@ -1090,7 +1093,6 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
}
|
||||
}
|
||||
}
|
||||
//update-end---author:wangshuai ---date:20230220 for:判断当前用户是否在当前租户里面,如果不存在在新增------------
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1164,12 +1166,10 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
String workAddress = json.getString("workAddress");
|
||||
//批量修改用户职位
|
||||
if(oConvertUtils.isNotEmpty(post)) {
|
||||
//update-begin---author:wangshuai ---date:20230220 for:[QQYUN-3980]组织管理中 职位功能 职位表加租户id 加职位-用户关联表------------
|
||||
//修改职位用户关系表
|
||||
for (String userId:idList) {
|
||||
this.editUserPosition(userId,post);
|
||||
}
|
||||
//update-end---author:wangshuai ---date:20230220 for:[QQYUN-3980]组织管理中 职位功能 职位表加租户id 加职位-用户关联表------------
|
||||
}
|
||||
if(oConvertUtils.isNotEmpty(selecteddeparts)) {
|
||||
//查询当前租户的部门列表
|
||||
@ -1321,14 +1321,13 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
this.baseMapper.updateById(user);
|
||||
}
|
||||
}
|
||||
//update-begin---author:wangshuai ---date:20230303 for:部门负责人不能被删除------------
|
||||
// 代码逻辑说明: 部门负责人不能被删除------------
|
||||
this.removeDepartmentManager(departChargeUserIdList,departChargeUsers,departId);
|
||||
}else{
|
||||
if(CollectionUtil.isNotEmpty(departChargeUsers)){
|
||||
//前端传过来用户列表id为空,说明数据库的负责部门人员均需要删除
|
||||
this.removeDepartmentManager(departChargeUserIdList,departChargeUsers,departId);
|
||||
}
|
||||
//update-end---author:wangshuai ---date:20230303 for:部门负责人不能被删除------------
|
||||
|
||||
}
|
||||
}
|
||||
@ -1336,7 +1335,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
|
||||
private List<SysUser> queryDepartChargePersons(String departId){
|
||||
List<SysUser> result = new ArrayList<>();
|
||||
//update-begin---author:wangshuai ---date:20230303 for:部门负责人不能被删除------------
|
||||
// 代码逻辑说明: 部门负责人不能被删除------------
|
||||
LambdaQueryWrapper<SysUser> userQuery = new LambdaQueryWrapper<>();
|
||||
userQuery.like(SysUser::getDepartIds,departId);
|
||||
List<SysUser> userList = userMapper.selectList(userQuery);
|
||||
@ -1349,7 +1348,6 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
if(deps.indexOf(departId)>=0){
|
||||
result.add(user);
|
||||
}
|
||||
//update-end---author:wangshuai ---date:20230303 for:部门负责人不能被删除------------
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1445,7 +1443,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
user.setWorkNo(sysUser.getWorkNo());
|
||||
user.setId(sysUser.getId());
|
||||
this.updateById(user);
|
||||
//update-begin---author:wangshuai ---date:20230424 for:【QQYUN-5251】人员与部门:部门删除不掉------------
|
||||
// 代码逻辑说明: 【QQYUN-5251】人员与部门:部门删除不掉------------
|
||||
if(oConvertUtils.isEmpty(departs)){
|
||||
//直接删除用户下的的租户部门
|
||||
sysUserDepartMapper.deleteUserDepart(user.getId(),tenantId);
|
||||
@ -1453,7 +1451,6 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
//修改租户用户下的部门
|
||||
this.updateTenantDepart(user, tenantId, departs);
|
||||
}
|
||||
//update-end---author:wangshuai ---date:20230424 for:【QQYUN-5251】人员与部门:部门删除不掉------------
|
||||
//修改用户下的职位
|
||||
this.editUserPosition(sysUser.getId(),sysUser.getPost());
|
||||
}
|
||||
@ -1648,11 +1645,10 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
for (SysUser sysUser : userList) {
|
||||
AppExportUserVo exportUserVo = new AppExportUserVo();
|
||||
BeanUtils.copyProperties(sysUser, exportUserVo);
|
||||
//update-begin---author:wangshuai---date:2025-01-17---for:【QQYUN-10926】组织管理——用户导出时,部门没有导出上下级关系---
|
||||
// 代码逻辑说明: 【QQYUN-10926】组织管理——用户导出时,部门没有导出上下级关系---
|
||||
Map<String, String> departMap = this.getDepartNamesAndCategory(userDepVos, sysUser);
|
||||
String departNames = departMap.get("departNames");
|
||||
exportUserVo.setDepart(departNames.toString());
|
||||
//update-end---author:wangshuai---date:2025-01-17---for:【QQYUN-10926】组织管理——用户导出时,部门没有导出上下级关系---
|
||||
String posNames = positionVos.stream().filter(item -> item.getUserId().equals(sysUser.getId())).map(SysUserPositionVo::getName).collect(Collectors.joining(SymbolConstant.SEMICOLON));
|
||||
exportUserVo.setPosition(posNames);
|
||||
exportUserVoList.add(exportUserVo);
|
||||
@ -1721,12 +1717,11 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
}
|
||||
departOrgCategorys.append(orgCatrgory);
|
||||
}
|
||||
//update-begin---author:wangshuai---date:2025-08-27---for:【QQYUN-13617】导入时 部门添加层级不对了---
|
||||
// 代码逻辑说明: 【QQYUN-13617】导入时 部门添加层级不对了---
|
||||
Map<String,String> map = new HashMap<>();
|
||||
map.put("departNames", departNames.toString());
|
||||
map.put("departOrgCategorys",departOrgCategorys.toString());
|
||||
return map;
|
||||
//update-end---author:wangshuai---date:2025-08-27---for:【QQYUN-13617】导入时 部门添加层级不对了---
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2044,22 +2039,19 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
userTenant.setUserId(userId);
|
||||
userTenant.setStatus(CommonConstant.USER_TENANT_INVITE);
|
||||
userTenantMapper.insert(userTenant);
|
||||
//update-begin---author:wangshuai ---date:20230710 for:【QQYUN-5731】导入用户时,没有提醒------------
|
||||
//发送系统消息通知
|
||||
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
MessageDTO messageDTO = new MessageDTO();
|
||||
String title = sysUser.getRealname() + " 邀请您加入 " + tenantName + "。";
|
||||
messageDTO.setTitle(title);
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
//update-begin---author:wangshuai---date:2024-03-11---for:【QQYUN-8425】用户导入成功后 消息提醒 跳转至同意页面---
|
||||
// 代码逻辑说明: 【QQYUN-8425】用户导入成功后 消息提醒 跳转至同意页面---
|
||||
data.put(CommonConstant.NOTICE_MSG_BUS_TYPE,SysAnnmentTypeEnum.TENANT_INVITE.getType());
|
||||
//update-end---author:wangshuai---date:2024-03-11---for:【QQYUN-8425】用户导入成功后 消息提醒 跳转至同意页面---
|
||||
messageDTO.setData(data);
|
||||
messageDTO.setContent(title);
|
||||
messageDTO.setToUser(invitedUsername);
|
||||
messageDTO.setFromUser("system");
|
||||
systemSendMsgHandle.sendMessage(messageDTO);
|
||||
//update-end---author:wangshuai ---date:20230710 for:【QQYUN-5731】导入用户时,没有提醒------------
|
||||
}
|
||||
//======================================= end 用户与部门 用户列表导入 =========================================
|
||||
|
||||
@ -2239,12 +2231,11 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
for (SysUser sysUser : userList) {
|
||||
SysUserExportVo userExportVo = new SysUserExportVo();
|
||||
BeanUtils.copyProperties(sysUser, userExportVo);
|
||||
//update-begin---author:wangshuai---date:2025-08-27---for:【QQYUN-13617】导入时 部门添加层级不对了---
|
||||
// 代码逻辑说明: 【QQYUN-13617】导入时 部门添加层级不对了---
|
||||
Map<String, String> departMap = this.getDepartNamesAndCategory(userDepVos, sysUser);
|
||||
String departNames = departMap.get("departNames");
|
||||
userExportVo.setDepartNames(departNames);
|
||||
userExportVo.setOrgCategorys(departMap.get("departOrgCategorys"));
|
||||
//update-end---author:wangshuai---date:2025-08-27---for:【QQYUN-13617】导入时 部门添加层级不对了---
|
||||
String departIds = sysUser.getDepartIds();
|
||||
if (oConvertUtils.isNotEmpty(departIds)) {
|
||||
List<SysUserDepVo> depVoList = sysDepartMapper.getDepartByIds(Arrays.asList(departIds.split(",")));
|
||||
@ -2263,12 +2254,11 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
userExportVo.setPostName(postName);
|
||||
postNameMap.put(sysUser.getMainDepPostId(), postName);
|
||||
}
|
||||
//update-begin---author:wangshuai---date:2025-09-06---for:兼职岗位改造成中间表的方式---
|
||||
// 代码逻辑说明: 兼职岗位改造成中间表的方式---
|
||||
List<String> depPost = depPostMapper.getDepPostByUserId(sysUser.getId());
|
||||
if(CollectionUtil.isNotEmpty(depPost)){
|
||||
userExportVo.setOtherDepPostId(String.join(SymbolConstant.COMMA, depPost));
|
||||
}
|
||||
//update-end---author:wangshuai---date:2025-09-06---for:兼职岗位改造成中间表的方式---
|
||||
list.add(userExportVo);
|
||||
}
|
||||
}
|
||||
@ -2303,7 +2293,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
SysUserImportVo sysUserExcel = listSysUsers.get(i);
|
||||
SysUser sysUser = new SysUser();
|
||||
BeanUtils.copyProperties(sysUserExcel, sysUser);
|
||||
if (OkConvertUtils.isEmpty(sysUser.getUsername())) {
|
||||
if (oConvertUtils.isEmpty(sysUser.getUsername())) {
|
||||
errorLines += 1;
|
||||
int lineNumber = i + 1;
|
||||
errorMessage.add("第 " + lineNumber + " 行:用户账号为空,忽略导入。");
|
||||
@ -2327,6 +2317,12 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
String passwordEncode = PasswordUtil.encrypt(sysUserExcel.getUsername(), sysUser.getPassword(), salt);
|
||||
sysUser.setPassword(passwordEncode);
|
||||
sysUser.setActivitiSync(CommonConstant.ACT_SYNC_1);
|
||||
if(null == sysUser.getDelFlag()){
|
||||
sysUser.setDelFlag(CommonConstant.DEL_FLAG_0);
|
||||
}
|
||||
if(null == sysUser.getStatus()){
|
||||
sysUser.setStatus(CommonConstant.STATUS_1_INT);
|
||||
}
|
||||
this.save(sysUser);
|
||||
}
|
||||
//添加部门
|
||||
@ -2335,9 +2331,9 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
//新增或编辑部门
|
||||
Integer tenantIdInt = 0;
|
||||
if (MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL) {
|
||||
tenantIdInt = OkConvertUtils.getInt(tenantId, 0);
|
||||
tenantIdInt = oConvertUtils.getInt(tenantId, 0);
|
||||
}
|
||||
this.lowAddOrEditDepart(sysUser.getId(), departNames, tenantIdInt, departMap, orgCategorys, sysUserExcel.getPostName(), sysUserExcel.getMainDepPostId(),postMap,positionMap);
|
||||
this.lowAddOrEditDepart(sysUser.getId(), departNames, tenantIdInt, departMap, orgCategorys, sysUserExcel.getPostName(), sysUserExcel.getMainDepPostId(),postMap,positionMap, sysUserExcel.getOtherDepPostId());
|
||||
//新增或编辑角色
|
||||
String roleNames = sysUserExcel.getRoleNames();
|
||||
this.saveOrEditRole(sysUser.getId(), roleNames, tenantIdInt);
|
||||
@ -2399,19 +2395,20 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
//================================================================ begin 【用户导入】导入时 部门添加层级不对了======================================================================
|
||||
/**
|
||||
* 低代码下添加部门和用户
|
||||
*
|
||||
* @Description 和敲敲云分割处理,原因:因低代码岗位等改造,有级别,故添加部门分开处理
|
||||
*
|
||||
* @param userId 用户id
|
||||
* @param depart 部门名称
|
||||
* @param tenantId 租户id
|
||||
* @param departMap 存放部门的map;key为名称 value为SysDepart对象。
|
||||
* @param orgCategorys 部门类型
|
||||
* @param postName 职级名称
|
||||
* @param mainDepPostName 岗位名称
|
||||
* @param mainDepPostName 主岗位名称
|
||||
* @param postMap key: 岗位名称 + 部门id value:岗位(部门id)
|
||||
* @param positionMap key: 职级名称 value: 职级id
|
||||
* @param otherDepPostName 兼职岗位名称
|
||||
* @Description 和敲敲云分割处理,原因:因低代码岗位等改造,有级别,故添加部门分开处理
|
||||
*/
|
||||
private void lowAddOrEditDepart(String userId, String depart, Integer tenantId, Map<String, SysDepart> departMap, String orgCategorys, String postName, String mainDepPostName, Map<String, String> postMap, Map<String, String> positionMap) {
|
||||
private void lowAddOrEditDepart(String userId, String depart, Integer tenantId, Map<String, SysDepart> departMap, String orgCategorys, String postName, String mainDepPostName, Map<String, String> postMap, Map<String, String> positionMap, String otherDepPostName) {
|
||||
//批量将部门和用户信息建立关联关系
|
||||
if (StringUtils.isNotEmpty(depart)) {
|
||||
Page<SysDepart> page = new Page<>(1, 1);
|
||||
@ -2426,6 +2423,8 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
departNameList = departNameList.stream().distinct().collect(Collectors.toList());
|
||||
//当下部门循环下标
|
||||
int index = 0;
|
||||
//是否已导入岗位,岗位只导入第一个部门下
|
||||
boolean izImportPost = false;
|
||||
for (String departName : departNameList) {
|
||||
//部门id
|
||||
String parentId = "";
|
||||
@ -2485,7 +2484,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
departMap.put(nameStr, sysDepart);
|
||||
}
|
||||
//最后一位新增部门用户关系表
|
||||
if (i == names.length - 1) {
|
||||
if (i == names.length - 1 && !izImportPost) {
|
||||
Long count = sysUserDepartMapper.getCountByDepartIdAndUserId(userId, sysDepart.getId());
|
||||
if (count == 0) {
|
||||
SysUserDepart userDepart = new SysUserDepart(userId, sysDepart.getId());
|
||||
@ -2495,6 +2494,11 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
if (oConvertUtils.isNotEmpty(mainDepPostName)) {
|
||||
this.insertDepartPost(userId, parentId ,postName, mainDepPostName, postMap, tenantId, positionMap);
|
||||
}
|
||||
//添加兼职岗位
|
||||
if(oConvertUtils.isNotEmpty(otherDepPostName)){
|
||||
this.insertOtherDepartPost(userId,parentId,postName, otherDepPostName, postMap, tenantId, positionMap);
|
||||
}
|
||||
izImportPost = true;
|
||||
}
|
||||
}
|
||||
index++;
|
||||
@ -2524,35 +2528,8 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
String departId = sysDepartMapper.getDepIdByDepIdAndPostName(depId, postName);
|
||||
//不存在新增岗位
|
||||
if (oConvertUtils.isEmpty(departId) ) {
|
||||
//新增岗位
|
||||
SysDepart sysDepart = new SysDepart();
|
||||
JSONObject formData = new JSONObject();
|
||||
formData.put("parentId", depId);
|
||||
String[] codeArray = (String[]) FillRuleUtil.executeRule(FillRuleConstant.DEPART, formData);
|
||||
sysDepart.setParentId(depId);
|
||||
sysDepart.setOrgCode(codeArray[0]);
|
||||
sysDepart.setOrgType(codeArray[1]);
|
||||
sysDepart.setTenantId(tenantId);
|
||||
sysDepart.setDepartName(mainDepPostName);
|
||||
sysDepart.setIzLeaf(CommonConstant.IS_LEAF);
|
||||
sysDepart.setDelFlag(String.valueOf(CommonConstant.DEL_FLAG_0));
|
||||
sysDepart.setStatus(CommonConstant.STATUS_1);
|
||||
sysDepart.setOrgCategory(DepartCategoryEnum.DEPART_CATEGORY_POST.getValue());
|
||||
//获取职级id
|
||||
String positionId = "";
|
||||
if(postionMap.containsKey(postName)){
|
||||
positionId = postionMap.get(postName);
|
||||
} else {
|
||||
//根据租户id和职级名称获取职级id
|
||||
positionId = this.getSysPosition(tenantId, postName);
|
||||
}
|
||||
sysDepart.setPositionId(positionId);
|
||||
postionMap.put(postName, positionId);
|
||||
sysDepartMapper.insert(sysDepart);
|
||||
sysDepartMapper.setMainLeaf(depId, CommonConstant.NOT_LEAF);
|
||||
postMap.put(mainDepPostName + depId, sysDepart.getId());
|
||||
//需要将用户表的主岗位进行关联
|
||||
departId = sysDepart.getId();
|
||||
//添加部门岗位信息
|
||||
departId = this.addCommontDepartPost(depId, tenantId, mainDepPostName, postionMap, postName, postMap);
|
||||
}
|
||||
if(oConvertUtils.isNotEmpty(departId)){
|
||||
//更新用户主岗位
|
||||
@ -2564,6 +2541,84 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 导入通用添加部门岗位方法
|
||||
*
|
||||
* @param depId
|
||||
* @param tenantId
|
||||
* @param mainDepPostName
|
||||
* @param postionMap
|
||||
* @param postName
|
||||
* @param map
|
||||
* @param postMap
|
||||
* @return
|
||||
*/
|
||||
private String addCommontDepartPost(String depId, Integer tenantId, String mainDepPostName, Map<String, String> postionMap, String postName, Map<String, String> postMap) {
|
||||
//新增岗位
|
||||
SysDepart sysDepart = new SysDepart();
|
||||
JSONObject formData = new JSONObject();
|
||||
formData.put("parentId", depId);
|
||||
String[] codeArray = (String[]) FillRuleUtil.executeRule(FillRuleConstant.DEPART, formData);
|
||||
sysDepart.setParentId(depId);
|
||||
sysDepart.setOrgCode(codeArray[0]);
|
||||
sysDepart.setOrgType(codeArray[1]);
|
||||
sysDepart.setTenantId(tenantId);
|
||||
sysDepart.setDepartName(mainDepPostName);
|
||||
sysDepart.setIzLeaf(CommonConstant.IS_LEAF);
|
||||
sysDepart.setDelFlag(String.valueOf(CommonConstant.DEL_FLAG_0));
|
||||
sysDepart.setStatus(CommonConstant.STATUS_1);
|
||||
sysDepart.setOrgCategory(DepartCategoryEnum.DEPART_CATEGORY_POST.getValue());
|
||||
//获取职级id
|
||||
String positionId = "";
|
||||
if (postionMap.containsKey(postName)) {
|
||||
positionId = postionMap.get(postName);
|
||||
} else {
|
||||
//根据租户id和职级名称获取职级id
|
||||
positionId = this.getSysPosition(tenantId, postName);
|
||||
}
|
||||
sysDepart.setPositionId(positionId);
|
||||
postionMap.put(postName, positionId);
|
||||
sysDepartMapper.insert(sysDepart);
|
||||
sysDepartMapper.setMainLeaf(depId, CommonConstant.NOT_LEAF);
|
||||
postMap.put(mainDepPostName + depId, sysDepart.getId());
|
||||
//需要将用户表的主岗位进行关联
|
||||
return sysDepart.getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加兼职岗位
|
||||
*
|
||||
* @param userId 用户id
|
||||
* @param departId 部门id【上级部门id】
|
||||
* @param postName 职级名称
|
||||
* @param otherDepPostName 兼职岗位名称
|
||||
* @param postMap 岗位map key:岗位名称 + 部门id value:岗位(部门id)
|
||||
* @param tenantId 租户id
|
||||
* @param postionMap 职级map key: 职级名称 value: 职级id
|
||||
*/
|
||||
private void insertOtherDepartPost(String userId, String depId, String postName, String otherDepPostName, Map<String, String> postMap, Integer tenantId, Map<String, String> positionMap) {
|
||||
String[] otherDepPostNames = otherDepPostName.split(SymbolConstant.SEMICOLON);
|
||||
for (int i = 0; i < otherDepPostNames.length; i++) {
|
||||
//当前部门下已经存在岗位就不需要再次添加岗位了
|
||||
String departId = "";
|
||||
if (null == postMap || !postMap.containsKey(otherDepPostNames[i] + depId)) {
|
||||
//不存在时新增部门岗位
|
||||
departId = this.addCommontDepartPost(depId, tenantId, otherDepPostNames[i], positionMap, postName, postMap);
|
||||
} else {
|
||||
departId = postMap.get(otherDepPostNames[i] + depId);
|
||||
}
|
||||
//插入用岗位第三方中间表
|
||||
if (oConvertUtils.isNotEmpty(departId)) {
|
||||
try {
|
||||
SysUserDepPost depPost = new SysUserDepPost(userId, departId);
|
||||
depPostMapper.insert(depPost);
|
||||
} catch (Exception e) {
|
||||
log.error("当前岗位插入失败:" + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取职务信息
|
||||
*
|
||||
@ -2584,7 +2639,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
|
||||
private void saveChargeDepart(SysUser sysUser, String departIds, Map<String, SysDepart> departMap) {
|
||||
//判断那些部门没有,即没有加入到部门,则不能成为负责部门人员
|
||||
if (OkConvertUtils.isEmpty(departIds)) {
|
||||
if (oConvertUtils.isEmpty(departIds)) {
|
||||
return;
|
||||
}
|
||||
//多个部门用;分隔开
|
||||
@ -2676,7 +2731,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
}
|
||||
//step5 修改密码
|
||||
String newPassWord = PasswordUtil.encrypt(username, password, user.getSalt());
|
||||
this.userMapper.update(new SysUser().setPassword(newPassWord), new LambdaQueryWrapper<SysUser>().eq(SysUser::getId, user.getId()));
|
||||
this.userMapper.update(new SysUser().setPassword(newPassWord).setLastPwdUpdateTime(new Date()), new LambdaQueryWrapper<SysUser>().eq(SysUser::getId, user.getId()));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2748,12 +2803,306 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
} else {
|
||||
item.setRelTenantIds("");
|
||||
}
|
||||
Integer posTenantId = null;
|
||||
if (MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL) {
|
||||
posTenantId = oConvertUtils.getInt(TenantContext.getTenant(), 0);;
|
||||
//兼职岗位
|
||||
List<String> depPostList = depPostMapper.getDepPostByUserId(item.getId());
|
||||
if(CollectionUtil.isNotEmpty(depPostList)){
|
||||
item.setOtherDepPostId(StringUtils.join(depPostList.toArray(), SymbolConstant.COMMA));
|
||||
}
|
||||
});
|
||||
}
|
||||
return page.setRecords(sysDepartModels);
|
||||
}
|
||||
|
||||
/**
|
||||
* 据 orgCode 查询用户信息(部门全路径,主岗位和兼职岗位的信息),包括公司、子公司、部门
|
||||
*
|
||||
* @param orgCode
|
||||
* @param userParams
|
||||
* @param page
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public IPage<SysUserSysDepPostModel> queryDepartUserByOrgCode(String orgCode, SysUser userParams, IPage page) {
|
||||
List<SysUserSysDepPostModel> sysDepartModels = baseMapper.queryDepartUserByOrgCode(page, orgCode, userParams);
|
||||
//用户id
|
||||
List<String> userIdList = sysDepartModels.stream().map(SysUserSysDepPostModel::getId).toList();
|
||||
if (CollectionUtil.isNotEmpty(userIdList)) {
|
||||
//根据用户ids获取部门名称 key 用户id value 部门名称
|
||||
Map<String, String> departNameMap = this.getDepartNamesByUserIds(userIdList, SymbolConstant.COMMA);
|
||||
//获取兼职岗位
|
||||
Map<String, String> departPostMap = this.getDepartOtherPostByUserIds(userIdList, SymbolConstant.COMMA);
|
||||
ISysDepartService service = SpringContextUtils.getBean(SysDepartServiceImpl.class);
|
||||
sysDepartModels.forEach(item -> {
|
||||
item.setDepartName(departNameMap.get(item.getId()));
|
||||
item.setOtherPostName(departPostMap.get(item.getId()));
|
||||
//获取主岗位全路径
|
||||
if (oConvertUtils.isNotEmpty(item.getMainDepPostId())) {
|
||||
SysDepart departById = sysDepartMapper.getDepartById(item.getMainDepPostId());
|
||||
if (null != departById) {
|
||||
String departPathName = service.getDepartPathNameByOrgCode(departById.getOrgCode(), "");
|
||||
item.setPostName(departPathName);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
return page.setRecords(sysDepartModels);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通讯录点击用户获取用户详情(包含用户基本信息、部门全路径、主岗位兼职岗位全路径)
|
||||
*
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public SysUserSysDepPostModel getUserDetailByUserId(String userId) {
|
||||
SysUser sysUser = baseMapper.selectById(userId);
|
||||
if (null != sysUser) {
|
||||
SysUserSysDepPostModel userModel = new SysUserSysDepPostModel();
|
||||
BeanUtils.copyProperties(sysUser, userModel);
|
||||
//获取部门名称
|
||||
List<String> userIds = new ArrayList<>();
|
||||
userIds.add(userId);
|
||||
Map<String, String> departNameMap = this.getDepartNamesByUserIds(userIds, "__");
|
||||
userModel.setDepartName(departNameMap.get(userId));
|
||||
ISysDepartService service = SpringContextUtils.getBean(SysDepartServiceImpl.class);
|
||||
//获取主岗位全路径
|
||||
if (oConvertUtils.isNotEmpty(sysUser.getMainDepPostId())) {
|
||||
SysDepart departById = sysDepartMapper.getDepartById(sysUser.getMainDepPostId());
|
||||
if (null != departById) {
|
||||
String departPathName = service.getDepartPathNameByOrgCode(departById.getOrgCode(), "");
|
||||
userModel.setPostName(departPathName);
|
||||
}
|
||||
}
|
||||
//获取兼职岗位全路径
|
||||
Map<String, String> departPostMap = this.getDepartOtherPostByUserIds(userIds, "__");
|
||||
userModel.setOtherPostName(departPostMap.get(userId));
|
||||
return userModel;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 登录获取用户部门信息
|
||||
* @param jsonObject
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Result loginGetUserDeparts(JSONObject jsonObject) {
|
||||
Result result = new Result<>();
|
||||
//返回内容
|
||||
JSONObject obj = new JSONObject(new LinkedHashMap<>());
|
||||
// 登录方式 phone:手机 account:账号密码
|
||||
String loginType = jsonObject.getString("loginType");
|
||||
String username = jsonObject.getString("username");
|
||||
String source = oConvertUtils.getString(jsonObject.getString("source"),"PC");
|
||||
// 手机号登录校验
|
||||
if("phone".equalsIgnoreCase(loginType)){
|
||||
String phone = jsonObject.getString("mobile");
|
||||
//1.校验用户有效性
|
||||
SysUser sysUser = baseMapper.getUserByPhone(phone);
|
||||
result = this.checkUserIsEffective(sysUser);
|
||||
if(!result.isSuccess()) {
|
||||
return result;
|
||||
}
|
||||
//2.校验验证码
|
||||
String smscode = jsonObject.getString("smscode");
|
||||
String redisKey = CommonConstant.PHONE_REDIS_KEY_PRE+phone;
|
||||
Object code = redisUtil.get(redisKey);
|
||||
if (!smscode.equals(code)) {
|
||||
return Result.error("手机验证码错误");
|
||||
}
|
||||
//3.当前登录账号
|
||||
username = sysUser.getUsername();
|
||||
String orgCode = sysUser.getOrgCode();
|
||||
obj.put("currentOrgCode", orgCode);
|
||||
}else{
|
||||
String password = AesEncryptUtil.resolvePassword(jsonObject.getString("password"));
|
||||
log.debug("登录密码,原始密码:{},解密密码:{}" , jsonObject.getString("password"), password);
|
||||
// 手机端没有验证码,不做校验
|
||||
if(!"APP".equalsIgnoreCase(source)){
|
||||
// step.1 验证码check
|
||||
SysLoginModel sysLoginModel = new SysLoginModel();
|
||||
String inputCode = jsonObject.getString("inputCode");
|
||||
String checkKey = jsonObject.getString("checkKey");
|
||||
sysLoginModel.setCaptcha(inputCode);
|
||||
sysLoginModel.setCheckKey(checkKey);
|
||||
if (inputCode == null) {
|
||||
result.error500("验证码无效");
|
||||
return result;
|
||||
}
|
||||
String lowerCaseCaptcha = inputCode.toLowerCase();
|
||||
String keyPrefix = Md5Util.md5Encode(sysLoginModel.getCheckKey() + jeecgBaseConfig.getSignatureSecret(), "utf-8");
|
||||
String realKey = keyPrefix + lowerCaseCaptcha;
|
||||
Object checkCode = redisUtil.get(realKey);
|
||||
if (checkCode == null || !checkCode.toString().equals(lowerCaseCaptcha)) {
|
||||
log.warn("验证码错误,key= {} , Ui checkCode= {}, Redis checkCode = {}", sysLoginModel.getCheckKey(), lowerCaseCaptcha, checkCode);
|
||||
result.error500("验证码错误");
|
||||
result.setCode(HttpStatus.PRECONDITION_FAILED.value());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
// step.2 校验用户是否存在且有效
|
||||
SysUser sysUser = baseMapper.getUserByName(username);
|
||||
result = this.checkUserIsEffective(sysUser);
|
||||
if(!result.isSuccess()) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// step.3 校验用户名或密码是否正确
|
||||
String userpassword = PasswordUtil.encrypt(username, password, sysUser.getSalt());
|
||||
String syspassword = sysUser.getPassword();
|
||||
if (!syspassword.equals(userpassword)) {
|
||||
result.error500("用户名或密码错误");
|
||||
return result;
|
||||
}
|
||||
String orgCode = sysUser.getOrgCode();
|
||||
obj.put("currentOrgCode", orgCode);
|
||||
}
|
||||
// step.4 获取用户部门信息,仅限部门
|
||||
List<SysDepart> departList = sysDepartMapper.queryDeptByUserAndCategory(username,DepartCategoryEnum.DEPART_CATEGORY_DEPART.getValue());
|
||||
if (CollectionUtil.isNotEmpty(departList)) {
|
||||
ISysDepartService service = SpringContextUtils.getBean(SysDepartServiceImpl.class);
|
||||
List<Map<String, String>> departs = departList.stream()
|
||||
.filter(depart -> oConvertUtils.isNotEmpty(depart) &&
|
||||
oConvertUtils.isNotEmpty(depart.getOrgCode()))
|
||||
.map(depart -> {
|
||||
String departName = depart.getDepartNameAbbr();
|
||||
//简称是空的情况下,查询全路径名称
|
||||
if(oConvertUtils.isEmpty(departName)){
|
||||
departName = service.getDepartPathNameByOrgCode(depart.getOrgCode(), "");
|
||||
}
|
||||
Map<String, String> map = new HashMap<>();
|
||||
map.put("orgCode", depart.getOrgCode());
|
||||
map.put("departName", departName);
|
||||
return map;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
obj.put("departs", departs);
|
||||
}
|
||||
result.setResult(obj);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量重置密码为系统密码
|
||||
* @param usernames
|
||||
*/
|
||||
@Override
|
||||
public void resetToSysPassword(String usernames) {
|
||||
//1.判断是否存在admin账户
|
||||
if(hasAdminIntersection(usernames)){
|
||||
throw new JeecgBootException("所选用户中包含管理员,管理员账号不允许重置密码!!");
|
||||
}
|
||||
List<String> userArr = Arrays.asList(usernames.split(","));
|
||||
userArr.stream().forEach(username -> {
|
||||
if(oConvertUtils.isNotEmpty(username)){
|
||||
String salt = oConvertUtils.randomGen(8);
|
||||
String passwordEncode = PasswordUtil.encrypt(username, PasswordConstant.DEFAULT_PASSWORD, salt);
|
||||
//重置密码
|
||||
UpdateWrapper<SysUser> updateWrapper = new UpdateWrapper<>();
|
||||
updateWrapper
|
||||
.eq("username", username)
|
||||
.set("last_pwd_update_time", new Date())
|
||||
.set("password", passwordEncode)
|
||||
.set("salt", salt);
|
||||
this.baseMapper.update(null, updateWrapper);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新设备信息
|
||||
* @param clientId
|
||||
* @param userId
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void updateClientId(String clientId,String userId) {
|
||||
//解绑之前的设备账户
|
||||
if(oConvertUtils.isNotEmpty(clientId)){
|
||||
UpdateWrapper<SysUser> updateWrapper = new UpdateWrapper<>();
|
||||
updateWrapper
|
||||
.eq("client_id", clientId)
|
||||
.set("client_id", null);
|
||||
this.baseMapper.update(null, updateWrapper);
|
||||
}
|
||||
//设置新的绑定
|
||||
SysUser sysUser = new SysUser();
|
||||
sysUser.setClientId(clientId);
|
||||
sysUser.setId(userId);
|
||||
this.baseMapper.updateById(sysUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否有交集
|
||||
*/
|
||||
public static boolean hasAdminIntersection(String usernames) {
|
||||
if (oConvertUtils.isEmpty(usernames)) {
|
||||
return false;
|
||||
}
|
||||
// 使用HashSet提高查找效率
|
||||
Set<String> adminSet = Arrays.stream(ADMIN_ACCOUNT)
|
||||
.map(String::toLowerCase)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
return Arrays.stream(usernames.split(SymbolConstant.COMMA))
|
||||
.map(String::trim)
|
||||
.map(String::toLowerCase)
|
||||
.anyMatch(adminSet::contains);
|
||||
}
|
||||
/**
|
||||
* 根据用户ids获取部门名称
|
||||
*
|
||||
* @param userIdList
|
||||
* @param symbol
|
||||
* @return
|
||||
*/
|
||||
private Map<String, String> getDepartOtherPostByUserIds(List<String> userIdList, String symbol) {
|
||||
Map<String, String> departPostMap = new HashMap<>();
|
||||
List<SysUserSysDepPostModel> departPost = sysDepartMapper.getDepartOtherPostByUserIds(userIdList);
|
||||
if (CollectionUtil.isNotEmpty(departPost)) {
|
||||
ISysDepartService service = SpringContextUtils.getBean(SysDepartServiceImpl.class);
|
||||
departPost.forEach(item -> {
|
||||
if (oConvertUtils.isNotEmpty(item.getId()) && oConvertUtils.isNotEmpty(item.getOtherDepPostId())) {
|
||||
String postName = service.getDepartPathNameByOrgCode(item.getOrgCode(), "");
|
||||
if (departPostMap.containsKey(item.getId())) {
|
||||
departPostMap.put(item.getId(), departPostMap.get(item.getId()) + symbol + postName);
|
||||
} else {
|
||||
departPostMap.put(item.getId(), postName);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
return departPostMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据用户ids获取部门名称
|
||||
*
|
||||
* @param userIdList
|
||||
* @param symbol
|
||||
* @return
|
||||
*/
|
||||
private Map<String, String> getDepartNamesByUserIds(List<String> userIdList, String symbol) {
|
||||
Map<String, String> userOrgCodeMap = new HashMap<>();
|
||||
if (CollectionUtil.isNotEmpty(userIdList)) {
|
||||
List<SysUserSysDepPostModel> userDepPosts = sysUserDepartMapper.getUserDepPostByUserIds(userIdList);
|
||||
if (CollectionUtil.isNotEmpty(userDepPosts)) {
|
||||
ISysDepartService service = SpringContextUtils.getBean(SysDepartServiceImpl.class);
|
||||
userDepPosts.forEach(item -> {
|
||||
if (oConvertUtils.isNotEmpty(item.getId()) && oConvertUtils.isNotEmpty(item.getOrgCode())) {
|
||||
String departNamePath = service.getDepartPathNameByOrgCode(item.getOrgCode(), "");
|
||||
if (userOrgCodeMap.containsKey(item.getId())) {
|
||||
userOrgCodeMap.put(item.getId(), userOrgCodeMap.get(item.getId()) + symbol + departNamePath);
|
||||
} else {
|
||||
userOrgCodeMap.put(item.getId(), departNamePath);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
return userOrgCodeMap;
|
||||
}
|
||||
}
|
||||
|
||||
@ -91,7 +91,19 @@ public class SysUserTenantServiceImpl extends ServiceImpl<SysUserTenantMapper, S
|
||||
|
||||
@Override
|
||||
public List<SysUserTenantVo> getTenantListByUserId(String userId, List<String> userTenantStatus) {
|
||||
return userTenantMapper.getTenantListByUserId(userId, userTenantStatus);
|
||||
List<SysUserTenantVo> tenantListByUserId = userTenantMapper.getTenantListByUserId(userId, userTenantStatus);
|
||||
// 代码逻辑说明: 【QQYUN-7283】1.已经是会员的租户,不是管理员时,没有购买按钮---
|
||||
String noVip = "default";
|
||||
tenantListByUserId.forEach((item) ->{
|
||||
if(oConvertUtils.isNotEmpty(item.getMemberType()) && !noVip.equals(item.getMemberType())){
|
||||
//查询是不是管理员
|
||||
Long count = packUserMapper.izHaveBuyAuth(item.getId(), Integer.valueOf(item.getTenantUserId()));
|
||||
if(count!=0){
|
||||
item.setTenantAdmin(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
return tenantListByUserId;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -87,13 +87,12 @@ public class ThirdAppDingtalkServiceImpl implements IThirdAppService {
|
||||
|
||||
@Override
|
||||
public String getAccessToken() {
|
||||
//update-begin---author:wangshuai ---date:20230224 for:[QQYUN-3440]新建企业微信和钉钉配置表,通过租户模式隔离------------
|
||||
// 代码逻辑说明: [QQYUN-3440]新建企业微信和钉钉配置表,通过租户模式隔离------------
|
||||
SysThirdAppConfig config = getDingThirdAppConfig();
|
||||
if(null != config){
|
||||
return getTenantAccessToken(config);
|
||||
}
|
||||
log.warn("租户下未配置钉钉");
|
||||
//update-end---author:wangshuai ---date:20230224 for:[QQYUN-3440]新建企业微信和钉钉配置表,通过租户模式隔离------------
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -229,9 +228,8 @@ public class ThirdAppDingtalkServiceImpl implements IThirdAppService {
|
||||
for (JdtDepartmentTreeVo departmentTree : departmentTreeList) {
|
||||
LambdaQueryWrapper<SysDepart> queryWrapper = new LambdaQueryWrapper<>();
|
||||
// 根据 source_identifier 字段查询
|
||||
//update-begin---author:wangshuai---date:2024-04-10---for:【issues/6017】钉钉同步部门时没有最顶层的部门名,同步用户时,用户没有部门信息---
|
||||
// 代码逻辑说明: 【issues/6017】钉钉同步部门时没有最顶层的部门名,同步用户时,用户没有部门信息---
|
||||
queryWrapper.and(item -> item.eq(SysDepart::getId, departmentTree.getSource_identifier()).or().eq(SysDepart::getDingIdentifier,departmentTree.getDept_id()));
|
||||
//update-end---author:wangshuai---date:2024-04-10---for:【issues/6017】钉钉同步部门时没有最顶层的部门名,同步用户时,用户没有部门信息---
|
||||
SysDepart sysDepart = sysDepartService.getOne(queryWrapper);
|
||||
if (sysDepart != null) {
|
||||
// 执行更新操作
|
||||
@ -580,14 +578,12 @@ public class ThirdAppDingtalkServiceImpl implements IThirdAppService {
|
||||
user.setTelephone(sysUser.getTelephone());
|
||||
user.setJob_number(sysUser.getWorkNo());
|
||||
// 职务翻译
|
||||
//update-begin---author:wangshuai ---date:20230220 for:[QQYUN-3980]组织管理中 职位功能 职位表加租户id 加职位-用户关联表------------
|
||||
//获取用户职位名称
|
||||
List<SysPosition> positionList = sysPositionService.getPositionList(sysUser.getId());
|
||||
if(null != positionList && positionList.size()>0){
|
||||
String positionName = positionList.stream().map(SysPosition::getName).collect(Collectors.joining(SymbolConstant.COMMA));
|
||||
user.setTitle(positionName);
|
||||
}
|
||||
//update-end---author:wangshuai ---date:20230220 for:[QQYUN-3980]组织管理中 职位功能 职位表加租户id 加职位-用户关联表------------
|
||||
user.setEmail(sysUser.getEmail());
|
||||
// 查询并同步用户部门关系
|
||||
List<SysDepart> departList = this.getUserDepart(sysUser);
|
||||
@ -636,9 +632,9 @@ public class ThirdAppDingtalkServiceImpl implements IThirdAppService {
|
||||
String passwordEncode = PasswordUtil.encrypt(sysUser.getUsername(), password, salt);
|
||||
sysUser.setSalt(salt);
|
||||
sysUser.setPassword(passwordEncode);
|
||||
// update-begin--Author:liusq Date:20210713 for:钉钉同步到本地的人员没有状态,导致同步之后无法登录 #I3ZC2L
|
||||
// 代码逻辑说明: 钉钉同步到本地的人员没有状态,导致同步之后无法登录 #I3ZC2L
|
||||
sysUser.setStatus(1);
|
||||
// update-end--Author:liusq Date:20210713 for:钉钉同步到本地的人员没有状态,导致同步之后无法登录 #I3ZC2L
|
||||
sysUser.setLastPwdUpdateTime(new Date());
|
||||
return this.dtUserToSysUser(dtUser, sysUser);
|
||||
}
|
||||
|
||||
@ -754,9 +750,8 @@ public class ThirdAppDingtalkServiceImpl implements IThirdAppService {
|
||||
}
|
||||
int count = 0;
|
||||
if (userIdList != null && userIdList.size() > 0) {
|
||||
//update-begin---author:wangshuai ---date:20230209 for:[QQYUN-3440]新建企业微信和钉钉配置表,通过租户模式隔离------------
|
||||
// 代码逻辑说明: [QQYUN-3440]新建企业微信和钉钉配置表,通过租户模式隔离------------
|
||||
String accessToken = this.getTenantAccessToken(appConfig);
|
||||
//update-end---author:wangshuai ---date:20230209 for:[QQYUN-3440]新建企业微信和钉钉配置表,通过租户模式隔离------------
|
||||
if (accessToken == null) {
|
||||
return count;
|
||||
}
|
||||
@ -881,7 +876,7 @@ public class ThirdAppDingtalkServiceImpl implements IThirdAppService {
|
||||
* @return
|
||||
*/
|
||||
public Response<JSONObject> recallMessageResponse(String msgTaskId) {
|
||||
//update-begin---author:wangshuai ---date:20230224 for:[QQYUN-3440]新建企业微信和钉钉配置表,通过租户模式隔离------------
|
||||
// 代码逻辑说明: [QQYUN-3440]新建企业微信和钉钉配置表,通过租户模式隔离------------
|
||||
SysThirdAppConfig config = this.getDingThirdAppConfig();
|
||||
String accessToken = this.getTenantAccessToken(config);
|
||||
if (accessToken == null) {
|
||||
@ -889,7 +884,6 @@ public class ThirdAppDingtalkServiceImpl implements IThirdAppService {
|
||||
}
|
||||
String agentId = config.getAgentId();
|
||||
return JdtMessageAPI.recallMessage(agentId, msgTaskId, accessToken);
|
||||
//update-end---author:wangshuai ---date:20230224 for:[QQYUN-3440]新建企业微信和钉钉配置表,通过租户模式隔离------------
|
||||
}
|
||||
|
||||
/**
|
||||
@ -901,7 +895,7 @@ public class ThirdAppDingtalkServiceImpl implements IThirdAppService {
|
||||
* @return
|
||||
*/
|
||||
public Response<String> sendActionCardMessage(SysAnnouncement announcement, String ddMobileUrl, boolean verifyConfig) {
|
||||
//update-begin---author:wangshuai ---date:20230224 for:[QQYUN-3440]新建企业微信和钉钉配置表,通过租户模式隔离------------
|
||||
// 代码逻辑说明: [QQYUN-3440]新建企业微信和钉钉配置表,通过租户模式隔离------------
|
||||
SysThirdAppConfig config = this.getDingThirdAppConfig();
|
||||
if (verifyConfig && null == config) {
|
||||
return null;
|
||||
@ -911,7 +905,6 @@ public class ThirdAppDingtalkServiceImpl implements IThirdAppService {
|
||||
return null;
|
||||
}
|
||||
String agentId = config.getAgentId();
|
||||
//update-end---author:wangshuai ---date:20230224 for:[QQYUN-3440]新建企业微信和钉钉配置表,通过租户模式隔离------------
|
||||
String emptySuffix = null;
|
||||
if (oConvertUtils.isNotEmpty(announcement.getMsgAbstract())) {
|
||||
String msgAbstract = announcement.getMsgAbstract().trim();
|
||||
@ -991,9 +984,8 @@ public class ThirdAppDingtalkServiceImpl implements IThirdAppService {
|
||||
*/
|
||||
public SysUser oauth2Login(String authCode,Integer tenantId) {
|
||||
this.tenantIzExist(tenantId);
|
||||
//update-begin---author:wangshuai ---date:20230224 for:[QQYUN-3440]新建企业微信和钉钉配置表,通过租户模式隔离------------
|
||||
// 代码逻辑说明: [QQYUN-3440]新建企业微信和钉钉配置表,通过租户模式隔离------------
|
||||
SysThirdAppConfig dtConfig = configMapper.getThirdConfigByThirdType(tenantId, MessageTypeEnum.DD.getType());
|
||||
//update-end---author:wangshuai ---date:20230224 for:[QQYUN-3440]新建企业微信和钉钉配置表,通过租户模式隔离------------
|
||||
// 1. 根据免登授权码获取用户 AccessToken
|
||||
String userAccessToken = JdtOauth2API.getUserAccessToken(dtConfig.getClientId(), dtConfig.getClientSecret(), authCode);
|
||||
if (userAccessToken == null) {
|
||||
@ -1025,19 +1017,17 @@ public class ThirdAppDingtalkServiceImpl implements IThirdAppService {
|
||||
LambdaQueryWrapper<SysThirdAccount> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(SysThirdAccount::getThirdType, THIRD_TYPE);
|
||||
queryWrapper.eq(SysThirdAccount::getTenantId, tenantId);
|
||||
//update-begin---author:wangshuai---date:2023-12-04---for: auth登录需要联查一下---
|
||||
// 代码逻辑说明: auth登录需要联查一下---
|
||||
queryWrapper.and((wrapper)->wrapper.eq(SysThirdAccount::getThirdUserUuid,appUserId).or().eq(SysThirdAccount::getThirdUserId,appUserId));
|
||||
//update-end---author:wangshuai---date:2023-12-04---for: auth登录需要联查一下---
|
||||
SysThirdAccount thirdAccount = sysThirdAccountService.getOne(queryWrapper);
|
||||
if (thirdAccount != null) {
|
||||
return this.getSysUserByThird(thirdAccount, null, appUserId, accessToken,tenantId);
|
||||
} else {
|
||||
// 直接创建新账号
|
||||
User appUser = JdtUserAPI.getUserById(appUserId, accessToken).getResult();
|
||||
//update-begin---author:wangshuai ---date:20230328 for:[QQYUN-4883]钉钉auth登录同一个租户下有同一个用户id------------
|
||||
//代码逻辑说明: [QQYUN-4883]钉钉auth登录同一个租户下有同一个用户id------------
|
||||
//应该存uuid
|
||||
ThirdLoginModel tlm = new ThirdLoginModel(THIRD_TYPE, appUser.getUnionid(), appUser.getName(), appUser.getAvatar());
|
||||
//update-end---author:wangshuai ---date:20230328 for:[QQYUN-4883]钉钉auth登录同一个租户下有同一个用户id------------
|
||||
thirdAccount = sysThirdAccountService.saveThirdUser(tlm,tenantId);
|
||||
return this.getSysUserByThird(thirdAccount, appUser, null, null,tenantId);
|
||||
}
|
||||
@ -1070,9 +1060,8 @@ public class ThirdAppDingtalkServiceImpl implements IThirdAppService {
|
||||
thirdAccount.setAvatar(appUser.getAvatar());
|
||||
thirdAccount.setRealname(appUser.getName());
|
||||
thirdAccount.setThirdUserId(appUser.getUserid());
|
||||
//update-begin---author:wangshuai ---date:20230328 for:[QQYUN-4883]钉钉auth登录同一个租户下有同一个用户id------------
|
||||
// 代码逻辑说明: [QQYUN-4883]钉钉auth登录同一个租户下有同一个用户id------------
|
||||
thirdAccount.setThirdUserUuid(appUser.getUnionid());
|
||||
//update-end---author:wangshuai ---date:20230328 for:[QQYUN-4883]钉钉auth登录同一个租户下有同一个用户id------------
|
||||
thirdAccount.setSysUserId(sysUser.getId());
|
||||
sysThirdAccountService.updateById(thirdAccount);
|
||||
return sysUser;
|
||||
@ -1147,11 +1136,10 @@ public class ThirdAppDingtalkServiceImpl implements IThirdAppService {
|
||||
}
|
||||
// 获取【钉钉】所有的部门
|
||||
List<Department> departments = JdtDepartmentAPI.listAll(accessToken);
|
||||
//update-begin---author:wangshuai---date:2024-06-25---for:【TV360X-1316】钉钉同步提示消息不正确---
|
||||
// 代码逻辑说明: 【TV360X-1316】钉钉同步提示消息不正确---
|
||||
if(departments.isEmpty()){
|
||||
throw new JeecgBootBizTipException("请查看配置参数和白名单是否配置!");
|
||||
}
|
||||
//update-end---author:wangshuai---date:2024-06-25---for:【TV360X-1316】钉钉同步提示消息不正确---
|
||||
String username = JwtUtil.getUserNameByToken(SpringContextUtils.getHttpServletRequest());
|
||||
List<JdtDepartmentTreeVo> departmentTreeList = JdtDepartmentTreeVo.listToTree(departments);
|
||||
int tenantId = oConvertUtils.getInt(TenantContext.getTenant(), 0);
|
||||
@ -1187,11 +1175,10 @@ public class ThirdAppDingtalkServiceImpl implements IThirdAppService {
|
||||
try {
|
||||
userMapper.updateById(updateSysUser);
|
||||
String str = String.format("用户 %s(%s) 更新成功!", updateSysUser.getRealname(), updateSysUser.getUsername());
|
||||
//update-begin---author:wangshuai---date:2024-06-24---for:【TV360X-1317】钉钉同步 同步成功之后 重复提示---
|
||||
// 代码逻辑说明: 【TV360X-1317】钉钉同步 同步成功之后 重复提示---
|
||||
if(!syncInfo.getSuccessInfo().contains(str)){
|
||||
syncInfo.addSuccessInfo(str);
|
||||
}
|
||||
//update-end---author:wangshuai---date:2024-06-24---for:【TV360X-1317】钉钉同步 同步成功之后 重复提示---
|
||||
} catch (Exception e) {
|
||||
this.syncUserCollectErrInfo(e, user, syncInfo);
|
||||
}
|
||||
|
||||
@ -103,11 +103,10 @@ public class ThirdAppWechatEnterpriseServiceImpl implements IThirdAppService {
|
||||
|
||||
@Override
|
||||
public String getAccessToken() {
|
||||
//update-begin---author:wangshuai ---date:20230224 for:[QQYUN-3440]新建企业微信和钉钉配置表,通过租户模式隔离------------
|
||||
// 代码逻辑说明: [QQYUN-3440]新建企业微信和钉钉配置表,通过租户模式隔离------------
|
||||
SysThirdAppConfig config = this.getWeChatThirdAppConfig();
|
||||
String corpId = config.getClientId();
|
||||
String secret = config.getClientSecret();
|
||||
//update-end---author:wangshuai ---date:20230224 for:[QQYUN-3440]新建企业微信和钉钉配置表,通过租户模式隔离------------
|
||||
AccessToken accessToken = JwAccessTokenAPI.getAccessToken(corpId, secret);
|
||||
if (accessToken != null) {
|
||||
return accessToken.getAccesstoken();
|
||||
@ -118,11 +117,10 @@ public class ThirdAppWechatEnterpriseServiceImpl implements IThirdAppService {
|
||||
|
||||
/** 获取APPToken,新版企业微信的秘钥是分开的 */
|
||||
public String getAppAccessToken(SysThirdAppConfig config) {
|
||||
//update-begin---author:wangshuai ---date:20230224 for:[QQYUN-3440]新建企业微信和钉钉配置表,通过租户模式隔离------------
|
||||
// 代码逻辑说明: [QQYUN-3440]新建企业微信和钉钉配置表,通过租户模式隔离------------
|
||||
String corpId = config.getClientId();
|
||||
// 如果没有配置APP秘钥,就说明是老企业,可以通用秘钥
|
||||
String secret = config.getClientSecret();
|
||||
//update-end---author:wangshuai ---date:20230224 for:[QQYUN-3440]新建企业微信和钉钉配置表,通过租户模式隔离------------
|
||||
|
||||
AccessToken accessToken = JwAccessTokenAPI.getAccessToken(corpId, secret);
|
||||
if (accessToken != null) {
|
||||
@ -282,9 +280,8 @@ public class ThirdAppWechatEnterpriseServiceImpl implements IThirdAppService {
|
||||
if (sysDepart != null) {
|
||||
// 执行更新操作
|
||||
SysDepart updateSysDepart = this.qwDepartmentToSysDepart(departmentTree, sysDepart);
|
||||
//update-begin---author:wangshuai---date:2024-04-10---for:【issues/6017】企业微信同步部门时没有最顶层的部门名,同步用户时,用户没有部门信息---
|
||||
// 代码逻辑说明: 【issues/6017】企业微信同步部门时没有最顶层的部门名,同步用户时,用户没有部门信息---
|
||||
if (sysParentId != null && !"0".equals(sysParentId)) {
|
||||
//update-end---author:wangshuai---date:2024-04-10---for:【issues/6017】企业微信同步部门时没有最顶层的部门名,同步用户时,用户没有部门信息---
|
||||
updateSysDepart.setParentId(sysParentId);
|
||||
}
|
||||
try {
|
||||
@ -601,13 +598,12 @@ public class ThirdAppWechatEnterpriseServiceImpl implements IThirdAppService {
|
||||
user.setIs_leader_in_dept(new Integer[]{0});
|
||||
}
|
||||
// 职务翻译
|
||||
//update-begin---author:wangshuai ---date:20230220 for:[QQYUN-3980]组织管理中 职位功能 职位表加租户id 加职位-用户关联表------------
|
||||
// 代码逻辑说明: [QQYUN-3980]组织管理中 职位功能 职位表加租户id 加职位-用户关联表------------
|
||||
List<SysPosition> positionList = sysPositionService.getPositionList(sysUser.getId());
|
||||
if(null != positionList && positionList.size()>0){
|
||||
String positionName = positionList.stream().map(SysPosition::getName).collect(Collectors.joining(SymbolConstant.COMMA));
|
||||
user.setPosition(positionName);
|
||||
}
|
||||
//update-end---author:wangshuai ---date:20230220 for:[QQYUN-3980]组织管理中 职位功能 职位表加租户id 加职位-用户关联表------------
|
||||
if (sysUser.getSex() != null) {
|
||||
user.setGender(sysUser.getSex().toString());
|
||||
}
|
||||
@ -625,11 +621,10 @@ public class ThirdAppWechatEnterpriseServiceImpl implements IThirdAppService {
|
||||
// 座机号
|
||||
user.setTelephone(sysUser.getTelephone());
|
||||
// --- 企业微信没有逻辑删除的功能
|
||||
// update-begin--Author:sunjianlei Date:20210520 for:本地逻辑删除的用户,在企业微信里禁用 -----
|
||||
// 代码逻辑说明: 本地逻辑删除的用户,在企业微信里禁用 -----
|
||||
if (CommonConstant.DEL_FLAG_1.equals(sysUser.getDelFlag())) {
|
||||
user.setEnable(0);
|
||||
}
|
||||
// update-end--Author:sunjianlei Date:20210520 for:本地逻辑删除的用户,在企业微信里冻结 -----
|
||||
|
||||
return user;
|
||||
}
|
||||
@ -893,7 +888,6 @@ public class ThirdAppWechatEnterpriseServiceImpl implements IThirdAppService {
|
||||
entity.setDescription(oConvertUtils.getString(announcement.getMsgAbstract(),"空"));
|
||||
entity.setUrl(geQywxtAnnouncementUrl(announcement));
|
||||
}
|
||||
//update-end---author:scott ---date::2025-08-05 for:【QQYUN-13257】【h5】催办、抄送消息,在企业微信中显示json乱码---
|
||||
|
||||
textCard.setTextcard(entity);
|
||||
return JwMessageAPI.sendTextCardMessage(textCard, accessToken);
|
||||
@ -963,10 +957,9 @@ public class ThirdAppWechatEnterpriseServiceImpl implements IThirdAppService {
|
||||
if(ObjectUtil.isEmpty(count) || 0 == count){
|
||||
throw new JeecgBootException("租户不存在!");
|
||||
}
|
||||
//update-begin---author:wangshuai ---date:20230224 for:[QQYUN-3440]新建企业微信和钉钉配置表,通过租户模式隔离------------
|
||||
// 代码逻辑说明: [QQYUN-3440]新建企业微信和钉钉配置表,通过租户模式隔离------------
|
||||
SysThirdAppConfig config = configMapper.getThirdConfigByThirdType(tenantId, MessageTypeEnum.QYWX.getType());
|
||||
String accessToken = this.getAppAccessToken(config);
|
||||
//update-end---author:wangshuai ---date:20230224 for:[QQYUN-3440]新建企业微信和钉钉配置表,通过租户模式隔离------------
|
||||
if (accessToken == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -0,0 +1,96 @@
|
||||
package org.jeecg.modules.system.util;
|
||||
|
||||
import org.apache.commons.fileupload.FileItem;
|
||||
import org.apache.commons.fileupload.FileItemFactory;
|
||||
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
|
||||
import org.jeecg.common.util.MyCommonsMultipartFile;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
|
||||
/**
|
||||
* @Description: http文件转MultipartFile
|
||||
* @author: wangshuai
|
||||
* @date: 2025/11/5 17:55
|
||||
*/
|
||||
public class HttpFileToMultipartFileUtil {
|
||||
|
||||
/**
|
||||
* 获取
|
||||
*
|
||||
* @param fileUrl
|
||||
* @param filename
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static MultipartFile httpFileToMultipartFile(String fileUrl, String filename) throws Exception {
|
||||
byte[] bytes = downloadImageData(fileUrl);
|
||||
return convertByteToMultipartFile(bytes, filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载图片数据
|
||||
*/
|
||||
private static byte[] downloadImageData(String fileUrl) throws IOException {
|
||||
URL url = new URL(fileUrl);
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
|
||||
connection.setRequestMethod("GET");
|
||||
connection.setConnectTimeout(5000);
|
||||
connection.setReadTimeout(10000);
|
||||
connection.setRequestProperty("User-Agent",
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36");
|
||||
connection.setRequestProperty("Accept", "image/*");
|
||||
|
||||
int responseCode = connection.getResponseCode();
|
||||
if (responseCode != HttpURLConnection.HTTP_OK) {
|
||||
throw new IOException("HTTP请求失败,响应码: " + responseCode);
|
||||
}
|
||||
|
||||
try (InputStream inputStream = connection.getInputStream();
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
|
||||
|
||||
byte[] buffer = new byte[4096];
|
||||
int bytesRead;
|
||||
|
||||
while ((bytesRead = inputStream.read(buffer)) != -1) {
|
||||
outputStream.write(buffer, 0, bytesRead);
|
||||
}
|
||||
|
||||
return outputStream.toByteArray();
|
||||
} finally {
|
||||
connection.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* byte转 MultipartFile
|
||||
*
|
||||
* @param data
|
||||
* @param fileName
|
||||
* @return
|
||||
*/
|
||||
private static MultipartFile convertByteToMultipartFile(byte[] data, String fileName) {
|
||||
FileItemFactory factory = new DiskFileItemFactory();
|
||||
FileItem item = factory.createItem(fileName, "application/octet-stream", true, fileName);
|
||||
|
||||
try (OutputStream os = item.getOutputStream();
|
||||
ByteArrayInputStream bis = new ByteArrayInputStream(data)) {
|
||||
byte[] buffer = new byte[8192];
|
||||
int bytesRead;
|
||||
while ((bytesRead = bis.read(buffer)) != -1) {
|
||||
os.write(buffer, 0, bytesRead);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("字节数组转换失败", e);
|
||||
}
|
||||
|
||||
try {
|
||||
return new MyCommonsMultipartFile(item);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -13,142 +13,291 @@ import java.util.Random;
|
||||
|
||||
/**
|
||||
* 登录验证码工具类
|
||||
* @author: jeecg-boot
|
||||
* @date 2025-09-11
|
||||
* @author AI优化
|
||||
*/
|
||||
public class RandImageUtil {
|
||||
|
||||
// 静态初始化块,解决无头环境字体配置问题
|
||||
static {
|
||||
System.setProperty("java.awt.headless", "true");
|
||||
}
|
||||
|
||||
public static final String KEY = "JEECG_LOGIN_KEY";
|
||||
|
||||
/**
|
||||
* 定义图形大小
|
||||
*/
|
||||
/** 验证码图片宽度 */
|
||||
private static final int WIDTH = 105;
|
||||
/**
|
||||
* 定义图形大小
|
||||
*/
|
||||
|
||||
/** 验证码图片高度 */
|
||||
private static final int HEIGHT = 35;
|
||||
|
||||
/**
|
||||
* 定义干扰线数量
|
||||
*/
|
||||
private static final int COUNT = 200;
|
||||
|
||||
/**
|
||||
* 干扰线的长度=1.414*lineWidth
|
||||
*/
|
||||
|
||||
/** 干扰线数量 */
|
||||
private static final int INTERFERENCE_LINE_COUNT = 200;
|
||||
|
||||
/** 干扰线宽度 */
|
||||
private static final int LINE_WIDTH = 2;
|
||||
|
||||
/**
|
||||
* 图片格式
|
||||
*/
|
||||
|
||||
/** 图片格式 */
|
||||
private static final String IMG_FORMAT = "JPEG";
|
||||
|
||||
/** base64 图片前缀 */
|
||||
private static final String BASE64_PREFIX = "data:image/jpg;base64,";
|
||||
|
||||
/** 字符间距 */
|
||||
private static final int CHAR_SPACING = 23;
|
||||
|
||||
/** 字体大小 */
|
||||
private static final int FONT_SIZE = 24;
|
||||
|
||||
/** 字符Y轴偏移 */
|
||||
private static final int CHAR_Y_OFFSET = 26;
|
||||
|
||||
/** 字符X轴起始偏移 */
|
||||
private static final int CHAR_X_OFFSET = 8;
|
||||
|
||||
/**
|
||||
* base64 图片前缀
|
||||
* 直接通过response输出验证码图片
|
||||
*
|
||||
* @param response HTTP响应对象
|
||||
* @param verifyCode 验证码字符串
|
||||
* @throws IOException 输出异常
|
||||
*/
|
||||
private static final String BASE64_PRE = "data:image/jpg;base64,";
|
||||
|
||||
/**
|
||||
* 直接通过response 返回图片
|
||||
* @param response
|
||||
* @param resultCode
|
||||
* @throws IOException
|
||||
*/
|
||||
public static void generate(HttpServletResponse response, String resultCode) throws IOException {
|
||||
BufferedImage image = getImageBuffer(resultCode);
|
||||
// 输出图象到页面
|
||||
ImageIO.write(image, IMG_FORMAT, response.getOutputStream());
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成base64字符串
|
||||
* @param resultCode
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
public static String generate(String resultCode) throws IOException {
|
||||
BufferedImage image = getImageBuffer(resultCode);
|
||||
|
||||
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
|
||||
//写入流中
|
||||
ImageIO.write(image, IMG_FORMAT, byteStream);
|
||||
//转换成字节
|
||||
byte[] bytes = byteStream.toByteArray();
|
||||
//转换成base64串
|
||||
String base64 = Base64.getEncoder().encodeToString(bytes).trim();
|
||||
//删除 \r\n
|
||||
base64 = base64.replaceAll("\n", "").replaceAll("\r", "");
|
||||
|
||||
//写到指定位置
|
||||
//ImageIO.write(bufferedImage, "png", new File(""));
|
||||
|
||||
return BASE64_PRE+base64;
|
||||
}
|
||||
|
||||
private static BufferedImage getImageBuffer(String resultCode){
|
||||
// 在内存中创建图象
|
||||
final BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
|
||||
// 获取图形上下文
|
||||
final Graphics2D graphics = (Graphics2D) image.getGraphics();
|
||||
// 设定背景颜色
|
||||
// ---1
|
||||
graphics.setColor(Color.WHITE);
|
||||
graphics.fillRect(0, 0, WIDTH, HEIGHT);
|
||||
// 设定边框颜色
|
||||
// graphics.setColor(getRandColor(100, 200)); // ---2
|
||||
graphics.drawRect(0, 0, WIDTH - 1, HEIGHT - 1);
|
||||
|
||||
// SHA1PRNG是-种常用的随机数生成算法,处理弱随机数问题
|
||||
SecureRandom random;
|
||||
public static void generate(HttpServletResponse response, String verifyCode) throws IOException {
|
||||
if (response == null || verifyCode == null || verifyCode.trim().isEmpty()) {
|
||||
throw new IllegalArgumentException("参数不能为空");
|
||||
}
|
||||
|
||||
try {
|
||||
random = SecureRandom.getInstance("SHA1PRNG");
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
random = new SecureRandom();
|
||||
BufferedImage image = createVerifyCodeImage(verifyCode);
|
||||
ImageIO.write(image, IMG_FORMAT, response.getOutputStream());
|
||||
} catch (Exception e) {
|
||||
throw new IOException("生成验证码图片失败", e);
|
||||
}
|
||||
// 随机产生干扰线,使图象中的认证码不易被其它程序探测到
|
||||
for (int i = 0; i < COUNT; i++) {
|
||||
// ---3
|
||||
graphics.setColor(getRandColor(150, 200));
|
||||
}
|
||||
|
||||
// 保证画在边框之内
|
||||
final int x = random.nextInt(WIDTH - LINE_WIDTH - 1) + 1;
|
||||
final int y = random.nextInt(HEIGHT - LINE_WIDTH - 1) + 1;
|
||||
final int xl = random.nextInt(LINE_WIDTH);
|
||||
final int yl = random.nextInt(LINE_WIDTH);
|
||||
graphics.drawLine(x, y, x + xl, y + yl);
|
||||
/**
|
||||
* 生成验证码的base64字符串
|
||||
*
|
||||
* @param verifyCode 验证码字符串
|
||||
* @return base64编码的图片字符串
|
||||
* @throws IOException 生成异常
|
||||
*/
|
||||
public static String generate(String verifyCode) throws IOException {
|
||||
if (verifyCode == null || verifyCode.trim().isEmpty()) {
|
||||
throw new IllegalArgumentException("验证码不能为空");
|
||||
}
|
||||
// 取随机产生的认证码
|
||||
for (int i = 0; i < resultCode.length(); i++) {
|
||||
// 将认证码显示到图象中,调用函数出来的颜色相同,可能是因为种子太接近,所以只能直接生成
|
||||
// graphics.setColor(new Color(20 + random.nextInt(130), 20 + random
|
||||
// .nextInt(130), 20 + random.nextInt(130)));
|
||||
// 设置字体颜色
|
||||
graphics.setColor(Color.BLACK);
|
||||
// 设置字体样式
|
||||
// graphics.setFont(new Font("Arial Black", Font.ITALIC, 18));
|
||||
graphics.setFont(new Font("Times New Roman", Font.BOLD, 24));
|
||||
// 设置字符,字符间距,上边距
|
||||
graphics.drawString(String.valueOf(resultCode.charAt(i)), (23 * i) + 8, 26);
|
||||
|
||||
try {
|
||||
BufferedImage image = createVerifyCodeImage(verifyCode);
|
||||
|
||||
try (ByteArrayOutputStream byteStream = new ByteArrayOutputStream()) {
|
||||
ImageIO.write(image, IMG_FORMAT, byteStream);
|
||||
byte[] bytes = byteStream.toByteArray();
|
||||
String base64 = Base64.getEncoder().encodeToString(bytes).trim();
|
||||
// 清理换行符
|
||||
base64 = base64.replaceAll("[\r\n]", "");
|
||||
return BASE64_PREFIX + base64;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new IOException("生成验证码base64失败", e);
|
||||
}
|
||||
// 图象生效
|
||||
graphics.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建验证码图像
|
||||
*
|
||||
* @param verifyCode 验证码字符串
|
||||
* @return 验证码图像
|
||||
*/
|
||||
private static BufferedImage createVerifyCodeImage(String verifyCode) {
|
||||
BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
|
||||
Graphics2D graphics = null;
|
||||
|
||||
try {
|
||||
graphics = (Graphics2D) image.getGraphics();
|
||||
|
||||
// 设置图形渲染质量
|
||||
setupRenderingHints(graphics);
|
||||
|
||||
// 绘制背景
|
||||
drawBackground(graphics);
|
||||
|
||||
// 绘制边框
|
||||
drawBorder(graphics);
|
||||
|
||||
// 获取安全的随机数生成器
|
||||
SecureRandom random = createSecureRandom();
|
||||
|
||||
// 绘制干扰线
|
||||
drawInterferenceLines(graphics, random);
|
||||
|
||||
// 绘制验证码字符
|
||||
drawVerifyCodeText(graphics, verifyCode);
|
||||
|
||||
} catch (Exception e) {
|
||||
// 如果绘制失败,创建简单的错误图像
|
||||
return createErrorImage(verifyCode);
|
||||
} finally {
|
||||
if (graphics != null) {
|
||||
graphics.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
private static Color getRandColor(int fc, int bc) { // 取得给定范围随机颜色
|
||||
final Random random = new Random();
|
||||
int length = 255;
|
||||
if (fc > length) {
|
||||
fc = length;
|
||||
}
|
||||
if (bc > length) {
|
||||
bc = length;
|
||||
}
|
||||
/**
|
||||
* 设置图形渲染质量
|
||||
*/
|
||||
private static void setupRenderingHints(Graphics2D graphics) {
|
||||
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
|
||||
graphics.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
|
||||
}
|
||||
|
||||
final int r = fc + random.nextInt(bc - fc);
|
||||
final int g = fc + random.nextInt(bc - fc);
|
||||
final int b = fc + random.nextInt(bc - fc);
|
||||
/**
|
||||
* 绘制白色背景
|
||||
*/
|
||||
private static void drawBackground(Graphics2D graphics) {
|
||||
graphics.setColor(Color.WHITE);
|
||||
graphics.fillRect(0, 0, WIDTH, HEIGHT);
|
||||
}
|
||||
|
||||
return new Color(r, g, b);
|
||||
/**
|
||||
* 绘制边框
|
||||
*/
|
||||
private static void drawBorder(Graphics2D graphics) {
|
||||
graphics.setColor(Color.GRAY);
|
||||
graphics.drawRect(0, 0, WIDTH - 1, HEIGHT - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建安全的随机数生成器
|
||||
*/
|
||||
private static SecureRandom createSecureRandom() {
|
||||
try {
|
||||
return SecureRandom.getInstance("SHA1PRNG");
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
return new SecureRandom();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制干扰线
|
||||
*/
|
||||
private static void drawInterferenceLines(Graphics2D graphics, SecureRandom random) {
|
||||
for (int i = 0; i < INTERFERENCE_LINE_COUNT; i++) {
|
||||
graphics.setColor(getRandomColor(150, 200, random));
|
||||
|
||||
// 确保干扰线在边框内
|
||||
int x1 = random.nextInt(WIDTH - LINE_WIDTH - 1) + 1;
|
||||
int y1 = random.nextInt(HEIGHT - LINE_WIDTH - 1) + 1;
|
||||
int x2 = x1 + random.nextInt(LINE_WIDTH);
|
||||
int y2 = y1 + random.nextInt(LINE_WIDTH);
|
||||
|
||||
graphics.drawLine(x1, y1, x2, y2);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制验证码文本
|
||||
*/
|
||||
private static void drawVerifyCodeText(Graphics2D graphics, String verifyCode) {
|
||||
graphics.setColor(Color.BLACK);
|
||||
Font font = createSafeFont();
|
||||
graphics.setFont(font);
|
||||
|
||||
for (int i = 0; i < verifyCode.length(); i++) {
|
||||
char character = verifyCode.charAt(i);
|
||||
int x = i * CHAR_SPACING + CHAR_X_OFFSET;
|
||||
graphics.drawString(String.valueOf(character), x, CHAR_Y_OFFSET);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建安全的字体,避免字体配置问题
|
||||
*/
|
||||
private static Font createSafeFont() {
|
||||
// 使用逻辑字体名称,在所有平台都可用
|
||||
String[] safeFontNames = {Font.SERIF, Font.SANS_SERIF, Font.MONOSPACED, "Dialog"};
|
||||
|
||||
for (String fontName : safeFontNames) {
|
||||
try {
|
||||
Font font = new Font(fontName, Font.BOLD, FONT_SIZE);
|
||||
if (font.getFamily() != null) {
|
||||
return font;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// 继续尝试下一个字体
|
||||
}
|
||||
}
|
||||
|
||||
// 最后的回退方案
|
||||
return new Font(Font.MONOSPACED, Font.BOLD, FONT_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建错误图像(当正常绘制失败时使用)
|
||||
*/
|
||||
private static BufferedImage createErrorImage(String verifyCode) {
|
||||
BufferedImage errorImage = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
|
||||
Graphics2D graphics = null;
|
||||
|
||||
try {
|
||||
graphics = (Graphics2D) errorImage.getGraphics();
|
||||
|
||||
// 白色背景
|
||||
graphics.setColor(Color.WHITE);
|
||||
graphics.fillRect(0, 0, WIDTH, HEIGHT);
|
||||
|
||||
// 黑色边框
|
||||
graphics.setColor(Color.BLACK);
|
||||
graphics.drawRect(0, 0, WIDTH - 1, HEIGHT - 1);
|
||||
|
||||
// 尝试绘制验证码
|
||||
try {
|
||||
graphics.setFont(new Font(Font.MONOSPACED, Font.BOLD, 20));
|
||||
graphics.setColor(Color.BLUE);
|
||||
for (int i = 0; i < verifyCode.length(); i++) {
|
||||
graphics.drawString(String.valueOf(verifyCode.charAt(i)),
|
||||
i * CHAR_SPACING + CHAR_X_OFFSET, CHAR_Y_OFFSET);
|
||||
}
|
||||
} catch (Exception fontException) {
|
||||
// 如果连基本字体都失败,显示ERROR
|
||||
graphics.setColor(Color.RED);
|
||||
graphics.drawString("ERROR", 10, 20);
|
||||
}
|
||||
} finally {
|
||||
if (graphics != null) {
|
||||
graphics.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
return errorImage;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定范围内的随机颜色
|
||||
*
|
||||
* @param minColorValue 最小颜色值
|
||||
* @param maxColorValue 最大颜色值
|
||||
* @param random 随机数生成器
|
||||
* @return 随机颜色
|
||||
*/
|
||||
private static Color getRandomColor(int minColorValue, int maxColorValue, Random random) {
|
||||
// 确保颜色值在有效范围内
|
||||
int min = Math.max(0, Math.min(minColorValue, 255));
|
||||
int max = Math.max(min, Math.min(maxColorValue, 255));
|
||||
|
||||
int range = max - min;
|
||||
if (range == 0) {
|
||||
return new Color(min, min, min);
|
||||
}
|
||||
|
||||
int red = min + random.nextInt(range);
|
||||
int green = min + random.nextInt(range);
|
||||
int blue = min + random.nextInt(range);
|
||||
|
||||
return new Color(red, green, blue);
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,32 @@
|
||||
package org.jeecg.modules.system.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @Description: 部门修改替换类
|
||||
*
|
||||
* @author: wangshuai
|
||||
* @date: 2025/9/28 18:52
|
||||
*/
|
||||
@Data
|
||||
public class SysChangeDepartVo {
|
||||
/**
|
||||
* 最终停止的部门id
|
||||
*/
|
||||
private String dropId;
|
||||
|
||||
/**
|
||||
* 拖拽的部门id
|
||||
*/
|
||||
private String dragId;
|
||||
|
||||
/**
|
||||
* 拖拽位置(-1上方 1下方 0子级)
|
||||
*/
|
||||
private Integer dropPosition;
|
||||
|
||||
/**
|
||||
* 当前位置
|
||||
*/
|
||||
private Integer sort;
|
||||
}
|
||||
@ -22,11 +22,9 @@ public class SysDepartUsersVO implements Serializable{
|
||||
this.depId = depId;
|
||||
this.userIdList = userIdList;
|
||||
}
|
||||
//update-begin--Author:kangxiaolin Date:20190908 for:[512][部门管理]点击添加已有用户失败修复--------------------
|
||||
|
||||
public SysDepartUsersVO(){
|
||||
|
||||
}
|
||||
//update-begin--Author:kangxiaolin Date:20190908 for:[512][部门管理]点击添加已有用户失败修复--------------------
|
||||
|
||||
}
|
||||
|
||||
@ -31,4 +31,9 @@ public class SysUserDepVo {
|
||||
* 职级
|
||||
*/
|
||||
private String positionId;
|
||||
|
||||
/**
|
||||
* 部门编码
|
||||
*/
|
||||
private String orgCode;
|
||||
}
|
||||
|
||||
@ -83,6 +83,12 @@ public class SysUserImportVo {
|
||||
@Excel(name="主岗位",width = 15)
|
||||
private String mainDepPostId;
|
||||
|
||||
/**
|
||||
* 兼职岗位
|
||||
*/
|
||||
@Excel(name="兼职岗位",width = 15)
|
||||
private String otherDepPostId;
|
||||
|
||||
/**
|
||||
* 职级
|
||||
*/
|
||||
|
||||
@ -56,13 +56,12 @@ public class JdtDepartmentTreeVo extends Department {
|
||||
department = departmentOptional.get();
|
||||
}
|
||||
getChildrenRecursion(treeList, allDepartment);
|
||||
//update-begin---author:wangshuai---date:2024-04-10---for:【issues/6017】钉钉同步部门时没有最顶层的部门名,同步用户时,用户没有部门信息---
|
||||
// 代码逻辑说明: 【issues/6017】钉钉同步部门时没有最顶层的部门名,同步用户时,用户没有部门信息---
|
||||
JdtDepartmentTreeVo treeVo = new JdtDepartmentTreeVo(department);
|
||||
treeVo.setChildren(treeList);
|
||||
List<JdtDepartmentTreeVo> list = new ArrayList<>();
|
||||
list.add(treeVo);
|
||||
return list;
|
||||
//update-end---author:wangshuai---date:2024-04-10---for:【issues/6017】钉钉同步部门时没有最顶层的部门名,同步用户时,用户没有部门信息---
|
||||
}
|
||||
|
||||
private static List<JdtDepartmentTreeVo> getByParentId(Integer parentId, List<Department> allDepartment) {
|
||||
|
||||
@ -56,13 +56,12 @@ public class JwDepartmentTreeVo extends Department {
|
||||
department = departmentOptional.get();
|
||||
}
|
||||
getChildrenRecursion(treeList, allDepartment);
|
||||
//update-begin---author:wangshuai---date:2024-04-10---for:【issues/6017】企业微信同步部门时没有最顶层的部门名,同步用户时,用户没有部门信息---
|
||||
// 代码逻辑说明: 【issues/6017】企业微信同步部门时没有最顶层的部门名,同步用户时,用户没有部门信息---
|
||||
JwDepartmentTreeVo treeVo = new JwDepartmentTreeVo(department);
|
||||
treeVo.setChildren(treeList);
|
||||
List<JwDepartmentTreeVo> list = new ArrayList<>();
|
||||
list.add(treeVo);
|
||||
return list;
|
||||
//update-begin---author:wangshuai---date:2024-04-10---for:【issues/6017】企业微信部门时没有最顶层的部门名,同步用户时,用户没有部门信息---
|
||||
}
|
||||
|
||||
private static List<JwDepartmentTreeVo> getByParentId(String parentId, List<Department> allDepartment) {
|
||||
|
||||
@ -81,7 +81,7 @@
|
||||
<#elseif po.classType=='cat_tree'>
|
||||
<#assign need_category = true>
|
||||
<j-category-select v-model:value="formData.${po.fieldName}" pcode="${po.dictField?default("")}" placeholder="请选择${po.filedComment}" <#if po.dictText?default("")?trim?length gt 1>back="${dashedToCamel(po.dictText)}"</#if> <#if po.readonly=='Y'>disabled</#if> @change="(value) => handleFormChange('${po.fieldName}', value)" allow-clear />
|
||||
<#elseif po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'>
|
||||
<#elseif po.fieldDbType=='int' || po.fieldDbType=='long' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'>
|
||||
<a-input-number v-model:value="formData.${po.fieldName}" placeholder="请输入${po.filedComment}" style="width: 100%" <#if po.readonly=='Y'>disabled</#if>/>
|
||||
<#elseif po.classType=='file'>
|
||||
<#assign need_upload = true>
|
||||
|
||||
@ -74,7 +74,7 @@
|
||||
<#else>
|
||||
<#if query_field_no gt 1> </#if><a-input placeholder="请输入${po.filedComment}" v-model:value="queryParam.${po.fieldName}" allow-clear ></a-input>
|
||||
</#if>
|
||||
<#elseif po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'>
|
||||
<#elseif po.fieldDbType=='int' || po.fieldDbType=='long' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'>
|
||||
<#if query_field_no gt 1> </#if><a-input-number placeholder="请输入${po.filedComment}" v-model:value="queryParam.${po.fieldName}"></a-input-number>
|
||||
<#else>
|
||||
<#if query_field_no gt 1> </#if><a-input placeholder="请输入${po.filedComment}" v-model:value="queryParam.${autoStringSuffixForModel(po)}" allow-clear ></a-input>
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<#list columns as po>
|
||||
<#if po.isShow == 'Y' && po.fieldName != 'id'>
|
||||
<#if po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'>
|
||||
<#if po.fieldDbType=='int' || po.fieldDbType=='long' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'>
|
||||
${po.fieldName}: <#if po.defaultVal??>${po.defaultVal}<#else>undefined</#if>,
|
||||
<#elseif po.fieldDbType=='Blob'>
|
||||
${po.fieldName}String: <#if po.defaultVal??>'${po.defaultVal}'<#else>''</#if>,
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<#list columns as po>
|
||||
<#if po.isShow == 'Y' && po.fieldName != 'id'>
|
||||
<#if po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'>
|
||||
<#if po.fieldDbType=='int' || po.fieldDbType=='long' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'>
|
||||
${po.fieldName}: <#if po.defaultVal??>${po.defaultVal}<#else>undefined</#if>,
|
||||
<#elseif po.fieldDbType=='Blob'>
|
||||
${po.fieldName}String: <#if po.defaultVal??>'${po.defaultVal}'<#else>''</#if>,
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<#list sub.colums as po>
|
||||
<#if po.isShow == 'Y' && po.fieldName != 'id'>
|
||||
<#if po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'>
|
||||
<#if po.fieldDbType=='int' || po.fieldDbType=='long' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'>
|
||||
${po.fieldName}: <#if po.defaultVal??>${po.defaultVal}<#else>undefined</#if>,
|
||||
<#elseif po.fieldDbType=='Blob'>
|
||||
${po.fieldName}String: <#if po.defaultVal??>'${po.defaultVal}'<#else>''</#if>,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user