mirror of
https://github.com/jeecgboot/JeecgBoot.git
synced 2026-02-04 17:45:34 +08:00
【3.7.3 版本合并升级】
Merge remote-tracking branch 'origin/springboot3' into springboot3_sas # Conflicts: # jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/util/JwtUtil.java # jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/ShiroConfig.java # jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/ShiroRealm.java # jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysTenantPackServiceImpl.java # jeecgboot-vue3/package.json
This commit is contained in:
@ -78,4 +78,30 @@ public class JimuReportTokenService implements JmReportTokenServiceI {
|
||||
// 将所有信息存放至map 解析sql/api会根据map的键值解析
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将jeecgboot平台的权限传递给积木报表
|
||||
* @param token
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String[] getPermissions(String token) {
|
||||
// 获取用户信息
|
||||
String username = JwtUtil.getUsername(token);
|
||||
SysUserCacheInfo userInfo = null;
|
||||
try {
|
||||
userInfo = sysBaseApi.getCacheUser(username);
|
||||
} catch (Exception e) {
|
||||
log.error("获取用户信息异常:"+ e.getMessage());
|
||||
}
|
||||
if(userInfo == null){
|
||||
return null;
|
||||
}
|
||||
// 查询权限
|
||||
Set<String> userPermissions = sysBaseApi.getUserPermissionSet(userInfo.getSysUserId());
|
||||
if(CollectionUtils.isEmpty(userPermissions)){
|
||||
return null;
|
||||
}
|
||||
return userPermissions.toArray(new String[0]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,12 +5,15 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.jeecg.common.api.dto.message.MessageDTO;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.constant.enums.MessageTypeEnum;
|
||||
import org.jeecg.common.system.util.JwtUtil;
|
||||
import org.jeecg.common.util.RedisUtil;
|
||||
import org.jeecg.common.util.SpringContextUtils;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.config.StaticConfig;
|
||||
import org.jeecg.modules.message.entity.SysMessage;
|
||||
import org.jeecg.modules.message.handle.ISendMsgHandle;
|
||||
import org.jeecg.modules.message.mapper.SysMessageMapper;
|
||||
import org.jeecg.modules.system.entity.SysUser;
|
||||
import org.jeecg.modules.system.mapper.SysUserMapper;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -43,6 +46,9 @@ public class EmailSendMsgHandle implements ISendMsgHandle {
|
||||
|
||||
@Autowired
|
||||
private RedisUtil redisUtil;
|
||||
|
||||
@Autowired
|
||||
private SysMessageMapper sysMessageMapper;
|
||||
|
||||
/**
|
||||
* 真实姓名变量
|
||||
@ -78,6 +84,23 @@ public class EmailSendMsgHandle implements ISendMsgHandle {
|
||||
|
||||
@Override
|
||||
public void sendMessage(MessageDTO messageDTO) {
|
||||
String content = messageDTO.getContent();
|
||||
String title = messageDTO.getTitle();
|
||||
//update-begin---author:wangshuai---date:2024-11-20---for:【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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 直接发送邮件
|
||||
*
|
||||
* @param messageDTO
|
||||
*/
|
||||
public void sendEmailMessage(MessageDTO messageDTO) {
|
||||
String[] arr = messageDTO.getToUser().split(",");
|
||||
LambdaQueryWrapper<SysUser> query = new LambdaQueryWrapper<SysUser>().in(SysUser::getUsername, arr);
|
||||
List<SysUser> list = sysUserMapper.selectList(query);
|
||||
@ -213,4 +236,35 @@ public class EmailSendMsgHandle implements ISendMsgHandle {
|
||||
redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME * 1 / 1000);
|
||||
return token;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否定时发送邮箱
|
||||
* @param toUser
|
||||
* @param title
|
||||
* @param content
|
||||
* @return
|
||||
*/
|
||||
private boolean isTimeJobSendEmail(String toUser, String title, String content) {
|
||||
StaticConfig staticConfig = SpringContextUtils.getBean(StaticConfig.class);
|
||||
Boolean timeJobSend = staticConfig.getTimeJobSend();
|
||||
if(null != timeJobSend && timeJobSend){
|
||||
this.addSysSmsSend(toUser,title,content);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存到短信发送表
|
||||
*/
|
||||
private void addSysSmsSend(String toUser, String title, String content) {
|
||||
SysMessage sysMessage = new SysMessage();
|
||||
sysMessage.setEsTitle(title);
|
||||
sysMessage.setEsContent(content);
|
||||
sysMessage.setEsReceiver(toUser);
|
||||
sysMessage.setEsSendStatus("0");
|
||||
sysMessage.setEsSendNum(0);
|
||||
sysMessage.setEsType(MessageTypeEnum.YJ.getType());
|
||||
sysMessageMapper.insert(sysMessage);
|
||||
}
|
||||
}
|
||||
|
||||
@ -51,6 +51,9 @@ 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】敲敲云发邮件通知,不稳定---
|
||||
md.setIsTimeJob(true);
|
||||
//update-end---author:wangshuai---date:2024-11-12---for:【QQYUN-8523】敲敲云发邮件通知,不稳定---
|
||||
sysBaseAPI.sendTemplateMessage(md);
|
||||
//发送消息成功
|
||||
sysMessage.setEsSendStatus(SendMsgStatusEnum.SUCCESS.getCode());
|
||||
|
||||
@ -18,7 +18,7 @@ import static org.springframework.boot.actuate.endpoint.annotation.Selector.Matc
|
||||
* @Date: 2024/5/13 17:02
|
||||
*/
|
||||
@Component
|
||||
@Endpoint(id = "httptrace-new")
|
||||
@Endpoint(id = "jeecghttptrace")
|
||||
public class CustomHttpTraceEndpoint{
|
||||
private final CustomInMemoryHttpTraceRepository repository;
|
||||
|
||||
|
||||
@ -14,6 +14,7 @@ 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.ImportExcelUtil;
|
||||
import org.jeecg.common.util.RedisUtil;
|
||||
import org.jeecg.common.util.YouBianCodeUtil;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.config.mybatis.MybatisPlusSaasConfig;
|
||||
@ -67,6 +68,8 @@ public class SysDepartController {
|
||||
private ISysUserService sysUserService;
|
||||
@Autowired
|
||||
private ISysUserDepartService sysUserDepartService;
|
||||
@Autowired
|
||||
private RedisUtil redisUtil;
|
||||
/**
|
||||
* 查询数据 查出我的部门,并以树结构数据格式响应给前端
|
||||
*
|
||||
@ -472,8 +475,8 @@ public class SysDepartController {
|
||||
//update-end---author:wangshuai---date:2023-10-19---for:【QQYUN-5482】系统的部门导入导出也可以改成敲敲云模式的部门路径---
|
||||
|
||||
//清空部门缓存
|
||||
Set keys3 = redisTemplate.keys(CacheConstant.SYS_DEPARTS_CACHE + "*");
|
||||
Set keys4 = redisTemplate.keys(CacheConstant.SYS_DEPART_IDS_CACHE + "*");
|
||||
List<String> keys3 = redisUtil.scan(CacheConstant.SYS_DEPARTS_CACHE + "*");
|
||||
List<String> keys4 = redisUtil.scan(CacheConstant.SYS_DEPART_IDS_CACHE + "*");
|
||||
redisTemplate.delete(keys3);
|
||||
redisTemplate.delete(keys4);
|
||||
return ImportExcelUtil.imporReturnRes(errorMessageList.size(), listSysDeparts.size() - errorMessageList.size(), errorMessageList);
|
||||
@ -666,8 +669,8 @@ public class SysDepartController {
|
||||
listSysDeparts = ExcelImportUtil.importExcel(file.getInputStream(), ExportDepartVo.class, params);
|
||||
sysDepartService.importExcel(listSysDeparts,errorMessageList);
|
||||
//清空部门缓存
|
||||
Set keys3 = redisTemplate.keys(CacheConstant.SYS_DEPARTS_CACHE + "*");
|
||||
Set keys4 = redisTemplate.keys(CacheConstant.SYS_DEPART_IDS_CACHE + "*");
|
||||
List<String> keys3 = redisUtil.scan(CacheConstant.SYS_DEPARTS_CACHE + "*");
|
||||
List<String> keys4 = redisUtil.scan(CacheConstant.SYS_DEPART_IDS_CACHE + "*");
|
||||
redisTemplate.delete(keys3);
|
||||
redisTemplate.delete(keys4);
|
||||
return ImportExcelUtil.imporReturnRes(errorMessageList.size(), listSysDeparts.size() - errorMessageList.size(), errorMessageList);
|
||||
|
||||
@ -94,12 +94,15 @@ public class SysDepartRoleController extends JeecgController<SysDepartRole, ISys
|
||||
// queryWrapper.in("depart_id",deptIds);
|
||||
|
||||
//我的部门,选中部门只能看当前部门下的角色
|
||||
//update-begin---author:chenrui ---date:20250107 for:[QQYUN-10775]验证码可以复用 #7674------------
|
||||
if(oConvertUtils.isNotEmpty(deptId)){
|
||||
queryWrapper.eq("depart_id",deptId);
|
||||
IPage<SysDepartRole> pageList = sysDepartRoleService.page(page, queryWrapper);
|
||||
return Result.ok(pageList);
|
||||
}else{
|
||||
return Result.ok(null);
|
||||
}
|
||||
|
||||
IPage<SysDepartRole> pageList = sysDepartRoleService.page(page, queryWrapper);
|
||||
return Result.ok(pageList);
|
||||
//update-end---author:chenrui ---date:20250107 for:[QQYUN-10775]验证码可以复用 #7674------------
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -24,11 +24,7 @@ import org.jeecg.config.mybatis.MybatisPlusSaasConfig;
|
||||
import org.jeecg.config.security.utils.SecureUtil;
|
||||
import org.jeecg.modules.base.service.BaseCommonService;
|
||||
import org.jeecg.modules.system.entity.*;
|
||||
import org.jeecg.modules.system.service.ISysTenantPackService;
|
||||
import org.jeecg.modules.system.service.ISysTenantService;
|
||||
import org.jeecg.modules.system.service.ISysUserService;
|
||||
import org.jeecg.modules.system.service.ISysUserTenantService;
|
||||
import org.jeecg.modules.system.service.ISysDepartService;
|
||||
import org.jeecg.modules.system.service.*;
|
||||
import org.jeecg.modules.system.vo.SysUserTenantVo;
|
||||
import org.jeecg.modules.system.vo.tenant.TenantDepartAuthInfo;
|
||||
import org.jeecg.modules.system.vo.tenant.TenantPackModel;
|
||||
@ -151,6 +147,21 @@ public class SysTenantController {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* [QQYUN-11032]【jeecg】租户套餐管理增加初始化套餐包按钮
|
||||
* @param tenantId
|
||||
* @return
|
||||
* @author chenrui
|
||||
* @date 2025/2/6 18:24
|
||||
*/
|
||||
@PreAuthorize("@jps.requiresPermissions('system:tenant:syncDefaultPack')")
|
||||
@PostMapping(value = "/syncDefaultPack")
|
||||
public Result<?> syncDefaultPack(@RequestParam(name="tenantId",required=true) Integer tenantId) {
|
||||
//同步默认产品包
|
||||
sysTenantPackService.syncDefaultPack(tenantId);
|
||||
return Result.OK("操作成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑
|
||||
* @param
|
||||
|
||||
@ -749,7 +749,10 @@ public class SysUserController {
|
||||
if(oConvertUtils.isEmpty(depId)){
|
||||
LoginUser user = SecureUtil.currentUser();
|
||||
int userIdentity = user.getUserIdentity() != null?user.getUserIdentity():CommonConstant.USER_IDENTITY_1;
|
||||
if(oConvertUtils.isNotEmpty(userIdentity) && userIdentity == CommonConstant.USER_IDENTITY_2 ){
|
||||
//update-begin---author:chenrui ---date:20250107 for:[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{
|
||||
@ -1277,12 +1280,6 @@ public class SysUserController {
|
||||
updateUser.setUpdateBy(JwtUtil.getUserNameByToken(request));
|
||||
updateUser.setUpdateTime(new Date());
|
||||
sysUserService.revertLogicDeleted(Arrays.asList(userIds.split(",")), updateUser);
|
||||
// 用户变更,触发同步工作流
|
||||
List<String> userNameList = sysUserService.userIdToUsername(Arrays.asList(userIds.split(",")));
|
||||
if (!userNameList.isEmpty()) {
|
||||
String joinedString = String.join(",", userNameList);
|
||||
}
|
||||
|
||||
}
|
||||
return Result.ok("还原成功");
|
||||
}
|
||||
@ -1851,4 +1848,57 @@ public class SysUserController {
|
||||
public Result<?> importAppUser(HttpServletRequest request, HttpServletResponse response)throws IOException {
|
||||
return sysUserService.importAppUser(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更改手机号(敲敲云个人设置专用)
|
||||
*
|
||||
* @param json
|
||||
* @param request
|
||||
*/
|
||||
@PutMapping("/changePhone")
|
||||
public Result<String> changePhone(@RequestBody JSONObject json, HttpServletRequest request){
|
||||
//获取登录用户名
|
||||
String username = JwtUtil.getUserNameByToken(request);
|
||||
sysUserService.changePhone(json,username);
|
||||
return Result.ok("修改手机号成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送短信验证码接口(修改手机号)
|
||||
*
|
||||
* @param jsonObject
|
||||
* @return
|
||||
*/
|
||||
@PostMapping(value = "/sendChangePhoneSms")
|
||||
public Result<String> sendChangePhoneSms(@RequestBody JSONObject jsonObject, HttpServletRequest request) {
|
||||
//获取登录用户名
|
||||
String username = JwtUtil.getUserNameByToken(request);
|
||||
String ipAddress = IpUtils.getIpAddr(request);
|
||||
sysUserService.sendChangePhoneSms(jsonObject, username, ipAddress);
|
||||
return Result.ok("发送验证码成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送注销用户手机号验证密码[敲敲云专用]
|
||||
*
|
||||
* @param jsonObject
|
||||
* @return
|
||||
*/
|
||||
@PostMapping(value = "/sendLogOffPhoneSms")
|
||||
public Result<String> sendLogOffPhoneSms(@RequestBody JSONObject jsonObject, HttpServletRequest request) {
|
||||
Result<String> result = new Result<>();
|
||||
//获取登录用户名
|
||||
String username = JwtUtil.getUserNameByToken(request);
|
||||
String name = jsonObject.getString("username");
|
||||
if (oConvertUtils.isEmpty(name) || !name.equals(username)) {
|
||||
result.setSuccess(false);
|
||||
result.setMessage("发送验证码失败,用户不匹配!");
|
||||
return result;
|
||||
}
|
||||
String ipAddress = IpUtils.getIpAddr(request);
|
||||
sysUserService.sendLogOffPhoneSms(jsonObject, username, ipAddress);
|
||||
result.setSuccess(true);
|
||||
result.setMessage("发送验证码成功!");
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@ -59,7 +59,7 @@ public class SysUserOnlineController {
|
||||
@RequestMapping(value = "/list", method = RequestMethod.GET)
|
||||
public Result<Page<SysUserOnlineVO>> list(@RequestParam(name="username", required=false) String username,
|
||||
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,@RequestParam(name="pageSize", defaultValue="10") Integer pageSize) {
|
||||
Collection<String> keys = redisTemplate.keys(CommonConstant.PREFIX_USER_TOKEN + "*");
|
||||
Collection<String> keys = redisUtil.scan(CommonConstant.PREFIX_USER_TOKEN + "*");
|
||||
List<SysUserOnlineVO> onlineList = new ArrayList<SysUserOnlineVO>();
|
||||
for (String key : keys) {
|
||||
String token = (String)redisUtil.get(key);
|
||||
|
||||
@ -15,6 +15,7 @@ import org.apache.commons.lang.StringUtils;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.constant.enums.MessageTypeEnum;
|
||||
import org.jeecg.common.system.api.ISysBaseAPI;
|
||||
import org.jeecg.common.system.util.JwtUtil;
|
||||
import org.jeecg.common.util.*;
|
||||
import org.jeecg.modules.base.service.BaseCommonService;
|
||||
@ -74,6 +75,9 @@ public class ThirdLoginController {
|
||||
@Autowired
|
||||
private ISysThirdAppConfigService appConfigService;
|
||||
|
||||
@Autowired
|
||||
public ISysBaseAPI sysBaseAPI;
|
||||
|
||||
@RequestMapping("/render/{source}")
|
||||
public void render(@PathVariable("source") String source, HttpServletResponse response) throws IOException {
|
||||
log.info("第三方登录进入render:" + source);
|
||||
@ -228,7 +232,11 @@ 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获取用户信息漏洞修复------------
|
||||
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);
|
||||
@ -557,4 +565,64 @@ public class ThirdLoginController {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 新版钉钉登录
|
||||
*
|
||||
* @param authCode
|
||||
* @param state
|
||||
* @param tenantId
|
||||
* @param response
|
||||
* @return
|
||||
*/
|
||||
@ResponseBody
|
||||
@GetMapping("/oauth2/dingding/login")
|
||||
public String OauthDingDingLogin(@RequestParam(value = "authCode", required = false) String authCode,
|
||||
@RequestParam("state") String state,
|
||||
@RequestParam(name = "tenantId",defaultValue = "0") String tenantId,
|
||||
HttpServletResponse response) {
|
||||
SysUser loginUser = thirdAppDingtalkService.oauthDingDingLogin(authCode,Integer.valueOf(tenantId));
|
||||
try {
|
||||
String redirect = "";
|
||||
if (state.indexOf("?") > 0) {
|
||||
String[] arr = state.split("\\?");
|
||||
state = arr[0];
|
||||
if(arr.length>1){
|
||||
redirect = arr[1];
|
||||
}
|
||||
}
|
||||
String token = saveToken(loginUser);
|
||||
state += "/oauth2-app/login?oauth2LoginToken=" + URLEncoder.encode(token, "UTF-8") + "&tenantId=" + URLEncoder.encode(tenantId, "UTF-8");
|
||||
state += "&thirdType=DINGTALK";
|
||||
if (redirect != null && redirect.length() > 0) {
|
||||
state += "&" + redirect;
|
||||
}
|
||||
log.info("OAuth2登录重定向地址: " + state);
|
||||
try {
|
||||
response.sendRedirect(state);
|
||||
return "ok";
|
||||
} catch (IOException e) {
|
||||
log.error(e.getMessage(),e);
|
||||
return "重定向失败";
|
||||
}
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
log.error(e.getMessage(),e);
|
||||
return "解码失败";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取企业id和应用id
|
||||
* @param tenantId
|
||||
* @return
|
||||
*/
|
||||
@ResponseBody
|
||||
@GetMapping("/get/corpId/clientId")
|
||||
public Result<SysThirdAppConfig> getCorpIdClientId(@RequestParam(value = "tenantId", defaultValue = "0") String tenantId){
|
||||
Result<SysThirdAppConfig> result = new Result<>();
|
||||
SysThirdAppConfig sysThirdAppConfig = thirdAppDingtalkService.getCorpIdClientId(Integer.valueOf(tenantId));
|
||||
result.setSuccess(true);
|
||||
result.setResult(sysThirdAppConfig);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@ -51,10 +51,10 @@ public class SysThirdAppConfig {
|
||||
@Schema(description = "钉钉/企业微信应用id对应的秘钥")
|
||||
private String clientSecret;
|
||||
|
||||
/**企业微信自建应用Secret*/
|
||||
@Excel(name = "企业微信自建应用Secret", width = 15)
|
||||
@Schema(description = "企业微信自建应用Secret")
|
||||
private String agentAppSecret;
|
||||
/**钉钉企业id*/
|
||||
@Excel(name = "钉钉企业id", width = 15)
|
||||
@Schema(description = "钉钉企业id")
|
||||
private String corpId;
|
||||
|
||||
/**第三方类别(dingtalk 钉钉 wechat_enterprise 企业微信)*/
|
||||
@Excel(name = "第三方类别(dingtalk 钉钉 wechat_enterprise 企业微信)", width = 15)
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
package org.jeecg.modules.system.service;
|
||||
|
||||
import org.jeecg.modules.system.entity.SysTenantPack;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import org.jeecg.modules.system.entity.SysTenantPack;
|
||||
import org.jeecg.modules.system.entity.SysTenantPackUser;
|
||||
|
||||
import java.util.List;
|
||||
@ -78,4 +78,13 @@ public interface ISysTenantPackService extends IService<SysTenantPack> {
|
||||
* @param id
|
||||
*/
|
||||
void addTenantDefaultPack(Integer id);
|
||||
|
||||
/**
|
||||
* 同步默认的套餐
|
||||
* for [QQYUN-11032]【jeecg】租户套餐管理增加初始化套餐包按钮
|
||||
* @param tenantId
|
||||
* @author chenrui
|
||||
* @date 2025/2/5 19:08
|
||||
*/
|
||||
void syncDefaultPack(Integer tenantId);
|
||||
}
|
||||
|
||||
@ -443,4 +443,19 @@ public interface ISysUserService extends IService<SysUser> {
|
||||
* @param ipAddress ip地址
|
||||
*/
|
||||
void sendChangePhoneSms(JSONObject jsonObject, String username, String ipAddress);
|
||||
|
||||
/**
|
||||
* 发送注销用户手机号验证密码[敲敲云专用]
|
||||
* @param jsonObject
|
||||
* @param username
|
||||
* @param ipAddress
|
||||
*/
|
||||
void sendLogOffPhoneSms(JSONObject jsonObject, String username, String ipAddress);
|
||||
|
||||
/**
|
||||
* 用户注销[敲敲云专用]
|
||||
* @param jsonObject
|
||||
* @param username
|
||||
*/
|
||||
void userLogOff(JSONObject jsonObject, String username);
|
||||
}
|
||||
|
||||
@ -27,6 +27,12 @@ public class ImportFileServiceImpl implements ImportFileServiceI {
|
||||
|
||||
@Override
|
||||
public String doUpload(byte[] data, String saveUrl) {
|
||||
return CommonUtils.uploadOnlineImage(data, upLoadPath, "import", uploadType);
|
||||
//update-begin---author:chenrui ---date:20250114 for:[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------------
|
||||
}
|
||||
}
|
||||
|
||||
@ -1633,7 +1633,13 @@ public class SysBaseApiImpl implements ISysBaseAPI {
|
||||
// 邮件消息要解析Markdown
|
||||
message.setContent(HTMLUtils.parseMarkdown(message.getContent()));
|
||||
}
|
||||
emailSendMsgHandle.sendMessage(message);
|
||||
//update-begin---author:wangshuai---date:2024-11-20---for:【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)){
|
||||
|
||||
@ -28,7 +28,9 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
@ -239,19 +241,54 @@ public class SysTenantPackServiceImpl extends ServiceImpl<SysTenantPackMapper, S
|
||||
query.eq(SysTenantPack::getPackType,"default");
|
||||
List<SysTenantPack> sysTenantPacks = sysTenantPackMapper.selectList(query);
|
||||
for (SysTenantPack sysTenantPack: sysTenantPacks) {
|
||||
SysTenantPack pack = new SysTenantPack();
|
||||
BeanUtils.copyProperties(sysTenantPack,pack);
|
||||
pack.setTenantId(tenantId);
|
||||
pack.setPackType("custom");
|
||||
pack.setId("");
|
||||
sysTenantPackMapper.insert(pack);
|
||||
List<String> permissionsByPackId = sysPackPermissionMapper.getPermissionsByPackId(sysTenantPack.getId());
|
||||
for (String permission:permissionsByPackId) {
|
||||
SysPackPermission packPermission = new SysPackPermission();
|
||||
packPermission.setPackId(pack.getId());
|
||||
packPermission.setPermissionId(permission);
|
||||
sysPackPermissionMapper.insert(packPermission);
|
||||
}
|
||||
syncDefaultPack2CurrentTenant(tenantId, sysTenantPack);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void syncDefaultPack(Integer tenantId) {
|
||||
// 查询默认套餐包
|
||||
LambdaQueryWrapper<SysTenantPack> query = new LambdaQueryWrapper<>();
|
||||
query.eq(SysTenantPack::getPackType,"default");
|
||||
List<SysTenantPack> sysDefaultTenantPacks = sysTenantPackMapper.selectList(query);
|
||||
// 查询当前租户套餐包
|
||||
query = new LambdaQueryWrapper<>();
|
||||
query.eq(SysTenantPack::getPackType,"custom");
|
||||
query.eq(SysTenantPack::getTenantId, tenantId);
|
||||
List<SysTenantPack> currentTenantPacks = sysTenantPackMapper.selectList(query);
|
||||
Map<String, SysTenantPack> currentTenantPackMap = new HashMap<String, SysTenantPack>();
|
||||
if (oConvertUtils.listIsNotEmpty(currentTenantPacks)) {
|
||||
currentTenantPackMap = currentTenantPacks.stream().collect(Collectors.toMap(SysTenantPack::getPackName, o -> o, (existing, replacement) -> existing));
|
||||
}
|
||||
// 添加不存在的套餐包
|
||||
for (SysTenantPack defaultPacks : sysDefaultTenantPacks) {
|
||||
if(!currentTenantPackMap.containsKey(defaultPacks.getPackName())){
|
||||
syncDefaultPack2CurrentTenant(tenantId, defaultPacks);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步默认套餐包到当前租户
|
||||
* for [QQYUN-11032]【jeecg】租户套餐管理增加初始化套餐包按钮
|
||||
* @param tenantId 目标租户
|
||||
* @param defaultPacks 默认套餐包
|
||||
* @author chenrui
|
||||
* @date 2025/2/5 19:41
|
||||
*/
|
||||
private void syncDefaultPack2CurrentTenant(Integer tenantId, SysTenantPack defaultPacks) {
|
||||
SysTenantPack pack = new SysTenantPack();
|
||||
BeanUtils.copyProperties(defaultPacks,pack);
|
||||
pack.setTenantId(tenantId);
|
||||
pack.setPackType("custom");
|
||||
pack.setId("");
|
||||
sysTenantPackMapper.insert(pack);
|
||||
List<String> permissionsByPackId = sysPackPermissionMapper.getPermissionsByPackId(defaultPacks.getId());
|
||||
for (String permission:permissionsByPackId) {
|
||||
SysPackPermission packPermission = new SysPackPermission();
|
||||
packPermission.setPackId(pack.getId());
|
||||
packPermission.setPermissionId(permission);
|
||||
sysPackPermissionMapper.insert(packPermission);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1984,15 +1984,50 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
}
|
||||
}
|
||||
//step4 发送短信验证码
|
||||
this.sendPhoneSms(phone, ipAddress);
|
||||
String redisKey = CommonConstant.CHANGE_PHONE_REDIS_KEY_PRE+phone;
|
||||
this.sendPhoneSms(phone, ipAddress,redisKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendLogOffPhoneSms(JSONObject jsonObject, String username, String ipAddress) {
|
||||
String phone = jsonObject.getString("phone");
|
||||
//通过用户名查询数据库中的手机号
|
||||
SysUser userByNameAndPhone = userMapper.getUserByNameAndPhone(phone, username);
|
||||
if (null == userByNameAndPhone) {
|
||||
throw new JeecgBootException("当前用户手机号不匹配,无法修改!");
|
||||
}
|
||||
String code = CommonConstant.LOG_OFF_PHONE_REDIS_KEY_PRE + phone;
|
||||
this.sendPhoneSms(phone, ipAddress, code);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void userLogOff(JSONObject jsonObject, String username) {
|
||||
String phone = jsonObject.getString("phone");
|
||||
String smsCode = jsonObject.getString("smscode");
|
||||
//通过用户名查询数据库中的手机号
|
||||
SysUser userByNameAndPhone = userMapper.getUserByNameAndPhone(phone, username);
|
||||
if (null == userByNameAndPhone) {
|
||||
throw new JeecgBootException("当前用户手机号不匹配,无法注销!");
|
||||
}
|
||||
String code = CommonConstant.LOG_OFF_PHONE_REDIS_KEY_PRE + phone;
|
||||
Object redisSmdCode = redisUtil.get(code);
|
||||
if (null == redisSmdCode) {
|
||||
throw new JeecgBootException("验证码失效,无法注销!");
|
||||
}
|
||||
if (!redisSmdCode.toString().equals(smsCode)) {
|
||||
throw new JeecgBootException("验证码不匹配,无法注销!");
|
||||
}
|
||||
this.deleteUser(userByNameAndPhone.getId());
|
||||
redisUtil.removeAll(code);
|
||||
redisUtil.removeAll(CacheConstant.SYS_USERS_CACHE + phone);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送短信验证码
|
||||
* @param phone
|
||||
*/
|
||||
private void sendPhoneSms(String phone, String clientIp) {
|
||||
String redisKey = CommonConstant.CHANGE_PHONE_REDIS_KEY_PRE+phone;
|
||||
private void sendPhoneSms(String phone, String clientIp,String redisKey) {
|
||||
Object object = redisUtil.get(redisKey);
|
||||
|
||||
if (object != null) {
|
||||
|
||||
@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.jeecg.dingtalk.api.base.JdtBaseAPI;
|
||||
import com.jeecg.dingtalk.api.core.response.Response;
|
||||
import com.jeecg.dingtalk.api.core.util.HttpUtil;
|
||||
import com.jeecg.dingtalk.api.core.vo.AccessToken;
|
||||
import com.jeecg.dingtalk.api.core.vo.PageResult;
|
||||
import com.jeecg.dingtalk.api.department.JdtDepartmentAPI;
|
||||
@ -46,10 +47,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.dao.DuplicateKeyException;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
@ -1254,4 +1252,57 @@ public class ThirdAppDingtalkServiceImpl implements IThirdAppService {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=================================== begin 新版钉钉登录 ============================================
|
||||
/**
|
||||
* 钉钉登录获取用户信息
|
||||
* 【QQYUN-9421】钉钉登录后打开了敲敲云,换其他账号登录后,再打开敲敲云显示的是原来账号的应用
|
||||
* @param authCode
|
||||
* @param tenantId
|
||||
* @return
|
||||
*/
|
||||
public SysUser oauthDingDingLogin(String authCode, Integer tenantId) {
|
||||
Long count = tenantMapper.tenantIzExist(tenantId);
|
||||
if(ObjectUtil.isEmpty(count) || 0 == count){
|
||||
throw new JeecgBootException("租户不存在!");
|
||||
}
|
||||
SysThirdAppConfig config = configMapper.getThirdConfigByThirdType(tenantId, MessageTypeEnum.DD.getType());
|
||||
String accessToken = this.getTenantAccessToken(config);
|
||||
if(StringUtils.isEmpty(accessToken)){
|
||||
throw new JeecgBootBizTipException("accessToken获取失败");
|
||||
}
|
||||
String getUserInfoUrl = "https://oapi.dingtalk.com/topapi/v2/user/getuserinfo?access_token=" + accessToken;
|
||||
Map<String,String> params = new HashMap<>();
|
||||
params.put("code",authCode);
|
||||
Response<JSONObject> userInfoResponse = HttpUtil.post(getUserInfoUrl, JSON.toJSONString(params));
|
||||
if (userInfoResponse.isSuccess()) {
|
||||
String userId = userInfoResponse.getResult().getString("userid");
|
||||
// 判断第三方用户表有没有这个人
|
||||
LambdaQueryWrapper<SysThirdAccount> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(SysThirdAccount::getThirdType, THIRD_TYPE);
|
||||
queryWrapper.eq(SysThirdAccount::getTenantId, tenantId);
|
||||
queryWrapper.and((wrapper)->wrapper.eq(SysThirdAccount::getThirdUserUuid,userId).or().eq(SysThirdAccount::getThirdUserId,userId));
|
||||
SysThirdAccount thirdAccount = sysThirdAccountService.getOne(queryWrapper);
|
||||
if (thirdAccount != null) {
|
||||
return this.getSysUserByThird(thirdAccount, null, userId, accessToken, tenantId);
|
||||
}else{
|
||||
throw new JeecgBootException("该用户没有同步,请先同步!");
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据租户id获取企业id和应用id
|
||||
* 【QQYUN-9421】钉钉登录后打开了敲敲云,换其他账号登录后,再打开敲敲云显示的是原来账号的应用
|
||||
* @param tenantId
|
||||
*/
|
||||
public SysThirdAppConfig getCorpIdClientId(Integer tenantId) {
|
||||
LambdaQueryWrapper<SysThirdAppConfig> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(SysThirdAppConfig::getThirdType, THIRD_TYPE);
|
||||
queryWrapper.eq(SysThirdAppConfig::getTenantId, tenantId);
|
||||
queryWrapper.select(SysThirdAppConfig::getCorpId,SysThirdAppConfig::getClientId);
|
||||
return configMapper.selectOne(queryWrapper);
|
||||
}
|
||||
//=================================== end 新版钉钉登录 ============================================
|
||||
}
|
||||
@ -119,12 +119,9 @@ public class ThirdAppWechatEnterpriseServiceImpl implements IThirdAppService {
|
||||
public String getAppAccessToken(SysThirdAppConfig config) {
|
||||
//update-begin---author:wangshuai ---date:20230224 for:[QQYUN-3440]新建企业微信和钉钉配置表,通过租户模式隔离------------
|
||||
String corpId = config.getClientId();
|
||||
String secret = config.getAgentAppSecret();
|
||||
// 如果没有配置APP秘钥,就说明是老企业,可以通用秘钥
|
||||
if (oConvertUtils.isEmpty(secret)) {
|
||||
secret = config.getClientSecret();
|
||||
String secret = config.getClientSecret();
|
||||
//update-end---author:wangshuai ---date:20230224 for:[QQYUN-3440]新建企业微信和钉钉配置表,通过租户模式隔离------------
|
||||
}
|
||||
|
||||
AccessToken accessToken = JwAccessTokenAPI.getAccessToken(corpId, secret);
|
||||
if (accessToken != null) {
|
||||
|
||||
Reference in New Issue
Block a user