feat(tenant): 新增手机号唯一性校验逻辑,重构密码重置和短信验证码接口支持多租户

- 优化部门校验使用isEmpty()方法
- 在SysMessageServiceImpl中为短信发送添加租户隔离支持
This commit is contained in:
PIG AI committed 2025-07-15 10:06:45 +08:00
1 parent 2b64a4cfe1
commit 7be922ef0f
2 files changed
+404 -400

No files matched your search

@@ -43,6 +43,7 @@ import com.pig4cloud.pigx.common.core.exception.ErrorCodes;
import com.pig4cloud.pigx.common.core.util.MsgUtils; import com.pig4cloud.pigx.common.core.util.MsgUtils;
import com.pig4cloud.pigx.common.core.util.R; import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.data.cache.RedisUtils; import com.pig4cloud.pigx.common.data.cache.RedisUtils;
import com.pig4cloud.pigx.common.data.tenant.TenantBroker;
import com.pig4cloud.pigx.common.data.tenant.TenantContextHolder; import com.pig4cloud.pigx.common.data.tenant.TenantContextHolder;
import com.pig4cloud.pigx.common.file.core.FileTemplate; import com.pig4cloud.pigx.common.file.core.FileTemplate;
import com.pig4cloud.pigx.common.log.util.JacksonSensitiveFieldUtil; import com.pig4cloud.pigx.common.log.util.JacksonSensitiveFieldUtil;
@@ -96,434 +97,425 @@ import java.util.Objects;
@Service @Service
@RequiredArgsConstructor @RequiredArgsConstructor
public class SysMessageServiceImpl extends ServiceImpl<SysMessageMapper, SysMessageEntity> public class SysMessageServiceImpl extends ServiceImpl<SysMessageMapper, SysMessageEntity>
implements SysMessageService { implements SysMessageService {
/** /**
* 支持短信服务商 * 支持短信服务商
*/ */
private static final Class[] SUPPORT_CONFIG_CLAZZ = {AlibabaConfig.class, CloopenConfig.class, CtyunConfig.class, private static final Class[] SUPPORT_CONFIG_CLAZZ = { AlibabaConfig.class, CloopenConfig.class, CtyunConfig.class,
EmayConfig.class, HuaweiConfig.class, JdCloudConfig.class, NeteaseConfig.class, TencentConfig.class, EmayConfig.class, HuaweiConfig.class, JdCloudConfig.class, NeteaseConfig.class, TencentConfig.class,
UniConfig.class, YunpianConfig.class, ZhutongConfig.class, DingZhongConfig.class, QiNiuConfig.class}; UniConfig.class, YunpianConfig.class, ZhutongConfig.class, DingZhongConfig.class, QiNiuConfig.class };
private final RemoteLogService remoteLogService; private final RemoteLogService remoteLogService;
private final SysSystemConfigMapper sysSystemConfigMapper; private final SysSystemConfigMapper sysSystemConfigMapper;
private final SysMessageRelationMapper relationMapper; private final SysMessageRelationMapper relationMapper;
private final SysUserMapper userMapper; private final SysUserMapper userMapper;
private final SysFileMapper fileMapper; private final SysFileMapper fileMapper;
private final FileTemplate fileTemplate; private final FileTemplate fileTemplate;
/** /**
* 发送信息 * 发送信息
* * @param id id
* @param id id * @return true/false
* @return true/false */
*/ @Override
@Override @Transactional(rollbackFor = Exception.class)
@Transactional(rollbackFor = Exception.class) public Boolean sendMessage(Long id) {
public Boolean sendMessage(Long id) { // 更新信息状态
// 更新信息状态 SysMessageEntity sysMessage = new SysMessageEntity();
SysMessageEntity sysMessage = new SysMessageEntity(); sysMessage.setSendFlag(YesNoEnum.YES.getCode());
sysMessage.setSendFlag(YesNoEnum.YES.getCode()); baseMapper.update(sysMessage, Wrappers.<SysMessageEntity>lambdaQuery().eq(SysMessageEntity::getId, id));
baseMapper.update(sysMessage, Wrappers.<SysMessageEntity>lambdaQuery().eq(SysMessageEntity::getId, id)); return Boolean.TRUE;
return Boolean.TRUE; }
}
/** /**
* 保存消息及其关联关系 * 保存消息及其关联关系
* * @param sysMessage 消息对象
* @param sysMessage 消息对象 * @return 是否保存成功
* @return 是否保存成功 */
*/ @Transactional(rollbackFor = Exception.class)
@Transactional(rollbackFor = Exception.class) public Boolean saveOrUpdateMessage(SysMessageVO sysMessage) {
public Boolean saveOrUpdateMessage(SysMessageVO sysMessage) { SysMessageEntity messageEntity = new SysMessageEntity();
SysMessageEntity messageEntity = new SysMessageEntity(); BeanUtils.copyProperties(sysMessage, messageEntity);
BeanUtils.copyProperties(sysMessage, messageEntity);
if (Objects.isNull(sysMessage.getId())) { if (Objects.isNull(sysMessage.getId())) {
baseMapper.insert(messageEntity); baseMapper.insert(messageEntity);
} else { }
baseMapper.updateById(sysMessage); else {
} baseMapper.updateById(sysMessage);
}
// 删除原有用户 // 删除原有用户
relationMapper.delete(Wrappers.<SysMessageRelationEntity>lambdaQuery() relationMapper.delete(Wrappers.<SysMessageRelationEntity>lambdaQuery()
.eq(SysMessageRelationEntity::getMsgId, messageEntity.getId())); .eq(SysMessageRelationEntity::getMsgId, messageEntity.getId()));
List<OrgTreeVO> userList = sysMessage.getUserList(); List<OrgTreeVO> userList = sysMessage.getUserList();
if (CollUtil.isNotEmpty(userList)) { if (CollUtil.isNotEmpty(userList)) {
userList.forEach(user -> { userList.forEach(user -> {
SysMessageRelationEntity relationEntity = new SysMessageRelationEntity(); SysMessageRelationEntity relationEntity = new SysMessageRelationEntity();
relationEntity.setMsgId(messageEntity.getId()); relationEntity.setMsgId(messageEntity.getId());
relationEntity.setUserId(user.getId()); relationEntity.setUserId(user.getId());
relationMapper.insert(relationEntity); relationMapper.insert(relationEntity);
}); });
} else { }
userMapper.selectList(Wrappers.emptyWrapper()).stream().map(SysUser::getUserId).forEach(userId -> { else {
SysMessageRelationEntity relationEntity = new SysMessageRelationEntity(); userMapper.selectList(Wrappers.emptyWrapper()).stream().map(SysUser::getUserId).forEach(userId -> {
relationEntity.setMsgId(messageEntity.getId()); SysMessageRelationEntity relationEntity = new SysMessageRelationEntity();
relationEntity.setUserId(userId); relationEntity.setMsgId(messageEntity.getId());
relationMapper.insert(relationEntity); relationEntity.setUserId(userId);
}); relationMapper.insert(relationEntity);
} });
return Boolean.TRUE; }
} return Boolean.TRUE;
}
/** /**
* 获取用户的信息列表 * 获取用户的信息列表
* * @return list
* @return list */
*/ @Override
@Override public IPage<SysMessageVO> pageUserMessage(Page page, SysMessageVO sysMessage) {
public IPage<SysMessageVO> pageUserMessage(Page page, SysMessageVO sysMessage) { MPJLambdaWrapper<SysMessageEntity> wrapper = new MPJLambdaWrapper<SysMessageEntity>()
MPJLambdaWrapper<SysMessageEntity> wrapper = new MPJLambdaWrapper<SysMessageEntity>() .selectAll(SysMessageEntity.class)
.selectAll(SysMessageEntity.class) .select(SysMessageRelationEntity::getReadFlag)
.select(SysMessageRelationEntity::getReadFlag) .leftJoin(SysMessageRelationEntity.class, SysMessageRelationEntity::getMsgId, SysMessageEntity::getId)
.leftJoin(SysMessageRelationEntity.class, SysMessageRelationEntity::getMsgId, SysMessageEntity::getId) .eq(SysMessageRelationEntity::getUserId, SecurityUtils.getUser().getId())
.eq(SysMessageRelationEntity::getUserId, SecurityUtils.getUser().getId()) .eq(SysMessageEntity::getSendFlag, YesNoEnum.YES.getCode())
.eq(SysMessageEntity::getSendFlag, YesNoEnum.YES.getCode()) .eq(StrUtil.isNotBlank(sysMessage.getCategory()), SysMessageEntity::getCategory, sysMessage.getCategory())
.eq(StrUtil.isNotBlank(sysMessage.getCategory()), SysMessageEntity::getCategory, sysMessage.getCategory()) .eq(StrUtil.isNotBlank(sysMessage.getReadFlag()), SysMessageRelationEntity::getReadFlag,
.eq(StrUtil.isNotBlank(sysMessage.getReadFlag()), SysMessageRelationEntity::getReadFlag, sysMessage.getReadFlag())
sysMessage.getReadFlag()) .orderByDesc(SysMessageEntity::getSort)
.orderByDesc(SysMessageEntity::getSort) .orderByDesc(SysMessageEntity::getCreateTime);
.orderByDesc(SysMessageEntity::getCreateTime); return baseMapper.selectJoinPage(page, SysMessageVO.class, wrapper);
return baseMapper.selectJoinPage(page, SysMessageVO.class, wrapper); }
}
/** /**
* 读取信息 * 读取信息
* * @param id id
* @param id id * @return true/false
* @return true/false */
*/ @Override
@Override public Boolean readMessage(Long id) {
public Boolean readMessage(Long id) { SysMessageRelationEntity relationEntity = new SysMessageRelationEntity();
SysMessageRelationEntity relationEntity = new SysMessageRelationEntity(); relationEntity.setReadFlag(YesNoEnum.YES.getCode());
relationEntity.setReadFlag(YesNoEnum.YES.getCode()); relationMapper.update(relationEntity,
relationMapper.update(relationEntity, Wrappers.<SysMessageRelationEntity>lambdaQuery()
Wrappers.<SysMessageRelationEntity>lambdaQuery() .eq(SysMessageRelationEntity::getMsgId, id)
.eq(SysMessageRelationEntity::getMsgId, id) .eq(SysMessageRelationEntity::getUserId, SecurityUtils.getUser().getId()));
.eq(SysMessageRelationEntity::getUserId, SecurityUtils.getUser().getId())); return Boolean.TRUE;
return Boolean.TRUE; }
}
/** /**
* 获取信息 * 获取信息
* * @param id id
* @param id id * @return messageVO
* @return messageVO */
*/ @Override
@Override public SysMessageVO getMessage(Long id) {
public SysMessageVO getMessage(Long id) { SysMessageEntity messageEntity = baseMapper.selectById(id);
SysMessageEntity messageEntity = baseMapper.selectById(id); SysMessageVO SysMessageVO = new SysMessageVO();
SysMessageVO SysMessageVO = new SysMessageVO(); BeanUtils.copyProperties(messageEntity, SysMessageVO);
BeanUtils.copyProperties(messageEntity, SysMessageVO);
// 全体通知 // 全体通知
if (messageEntity.getAllFlag().equals(YesNoEnum.YES.getCode())) { if (messageEntity.getAllFlag().equals(YesNoEnum.YES.getCode())) {
return SysMessageVO; return SysMessageVO;
} }
List<Long> userIdList = relationMapper List<Long> userIdList = relationMapper
.selectList(Wrappers.<SysMessageRelationEntity>lambdaQuery().eq(SysMessageRelationEntity::getMsgId, id)) .selectList(Wrappers.<SysMessageRelationEntity>lambdaQuery().eq(SysMessageRelationEntity::getMsgId, id))
.stream() .stream()
.map(SysMessageRelationEntity::getUserId) .map(SysMessageRelationEntity::getUserId)
.toList(); .toList();
if (CollUtil.isNotEmpty(userIdList)) { if (CollUtil.isNotEmpty(userIdList)) {
List<OrgTreeVO> orgNodeUserVoList = userMapper.selectByIds(userIdList).stream().map(user -> { List<OrgTreeVO> orgNodeUserVoList = userMapper.selectByIds(userIdList).stream().map(user -> {
OrgTreeVO nodeUserVo = new OrgTreeVO(); OrgTreeVO nodeUserVo = new OrgTreeVO();
nodeUserVo.setId(user.getUserId()); nodeUserVo.setId(user.getUserId());
nodeUserVo.setAvatar(user.getAvatar()); nodeUserVo.setAvatar(user.getAvatar());
nodeUserVo.setName(user.getName()); nodeUserVo.setName(user.getName());
return nodeUserVo; return nodeUserVo;
}).toList(); }).toList();
SysMessageVO.setUserList(orgNodeUserVoList); SysMessageVO.setUserList(orgNodeUserVoList);
} }
return SysMessageVO; return SysMessageVO;
} }
/** /**
* 查询用户阅读情况 * 查询用户阅读情况
* * @param page 分页
* @param page 分页 * @param messageId 消息ID
* @param messageId 消息ID * @param name 姓名
* @param name 姓名 * @return page
* @return page */
*/ @Override
@Override public Page pageUserRead(Page page, Long messageId, String name) {
public Page pageUserRead(Page page, Long messageId, String name) { MPJLambdaWrapper<SysMessageRelationEntity> wrapper = new MPJLambdaWrapper<SysMessageRelationEntity>()
MPJLambdaWrapper<SysMessageRelationEntity> wrapper = new MPJLambdaWrapper<SysMessageRelationEntity>() .selectAll(SysMessageRelationEntity.class)
.selectAll(SysMessageRelationEntity.class) .select(SysUser::getUsername, SysUser::getName, SysUser::getUserId)
.select(SysUser::getUsername, SysUser::getName, SysUser::getUserId) .select(SysMessageEntity::getTitle)
.select(SysMessageEntity::getTitle) .leftJoin(SysUser.class, SysUser::getUserId, SysMessageRelationEntity::getUserId)
.leftJoin(SysUser.class, SysUser::getUserId, SysMessageRelationEntity::getUserId) .leftJoin(SysMessageEntity.class, SysMessageEntity::getId, SysMessageRelationEntity::getMsgId)
.leftJoin(SysMessageEntity.class, SysMessageEntity::getId, SysMessageRelationEntity::getMsgId) .eq(SysMessageRelationEntity::getMsgId, messageId)
.eq(SysMessageRelationEntity::getMsgId, messageId) .like(StrUtil.isNotBlank(name), SysUser::getName, name);
.like(StrUtil.isNotBlank(name), SysUser::getName, name); return relationMapper.selectJoinPage(page, SysMessageReadVO.class, wrapper);
return relationMapper.selectJoinPage(page, SysMessageReadVO.class, wrapper); }
}
/** /**
* 发送手机验证码 TODO: 调用短信网关发送验证码,测试返回前端 * 发送手机验证码 TODO: 调用短信网关发送验证码,测试返回前端
* * @param mobile mobile
* @param mobile mobile * @return code
* @return code */
*/ @Override
@Override public R<Boolean> sendSmsCode(String mobile) {
public R<Boolean> sendSmsCode(String mobile) { List<SysUser> userList = TenantBroker
List<SysUser> userList = userMapper .noneAs(() -> userMapper.selectList(Wrappers.<SysUser>query().lambda().eq(SysUser::getPhone, mobile)));
.selectList(Wrappers.<SysUser>query().lambda().eq(SysUser::getPhone, mobile));
if (CollUtil.isEmpty(userList)) { if (CollUtil.isEmpty(userList)) {
log.info("手机号未注册:{}", mobile); log.info("手机号未注册:{}", mobile);
return R.ok(Boolean.FALSE, MsgUtils.getMessage(ErrorCodes.SYS_APP_PHONE_UNREGISTERED, mobile)); return R.ok(Boolean.FALSE, MsgUtils.getMessage(ErrorCodes.SYS_APP_PHONE_UNREGISTERED, mobile));
} }
String codeObj = RedisUtils String codeObj = RedisUtils
.get(CacheConstants.DEFAULT_CODE_KEY + LoginTypeEnum.SMS.getType() + StringPool.AT + mobile); .get(CacheConstants.DEFAULT_CODE_KEY + LoginTypeEnum.SMS.getType() + StringPool.AT + mobile);
if (StrUtil.isNotBlank(codeObj)) { if (StrUtil.isNotBlank(codeObj)) {
log.info("手机号验证码未过期:{},{}", mobile, codeObj); log.info("手机号验证码未过期:{},{}", mobile, codeObj);
return R.ok(Boolean.FALSE, MsgUtils.getMessage(ErrorCodes.SYS_APP_SMS_OFTEN)); return R.ok(Boolean.FALSE, MsgUtils.getMessage(ErrorCodes.SYS_APP_SMS_OFTEN));
} }
String code = RandomUtil.randomNumbers(Integer.parseInt(SecurityConstants.CODE_SIZE)); String code = RandomUtil.randomNumbers(Integer.parseInt(SecurityConstants.CODE_SIZE));
log.info("手机号生成验证码成功:{},{}", mobile, code); log.info("手机号生成验证码成功:{},{}", mobile, code);
RedisUtils.set(CacheConstants.DEFAULT_CODE_KEY + LoginTypeEnum.SMS.getType() + StringPool.AT + mobile, code, RedisUtils.set(CacheConstants.DEFAULT_CODE_KEY + LoginTypeEnum.SMS.getType() + StringPool.AT + mobile, code,
SecurityConstants.CODE_TIME); SecurityConstants.CODE_TIME);
// 发送 // 发送
return this.sendSms(MessageSmsDTO.builder() return this.sendSms(MessageSmsDTO.builder()
.mobile(mobile) .mobile(mobile)
.biz(SmsBizCodeEnum.SMS_NORMAL_CODE.getCode()) .biz(SmsBizCodeEnum.SMS_NORMAL_CODE.getCode())
.param(code) .param(code)
.build()); .build());
} }
/** /**
* 发送短信 * 发送短信
* * @param messageSmsDTO 消息 短信 DTO
* @param messageSmsDTO 消息 短信 DTO * @return {@link R }
* @return {@link R } */
*/ @Override
@Override public R sendSms(MessageSmsDTO messageSmsDTO) {
public R sendSms(MessageSmsDTO messageSmsDTO) {
// 根据业务编码获取短信通道配置 // 根据业务编码获取短信通道配置
List<SysSystemConfigEntity> configEntityList = sysSystemConfigMapper List<SysSystemConfigEntity> configEntityList = sysSystemConfigMapper
.selectList(Wrappers.<SysSystemConfigEntity>lambdaQuery() .selectList(Wrappers.<SysSystemConfigEntity>lambdaQuery()
.eq(SysSystemConfigEntity::getConfigType, SystemConfigTypeEnum.SMS.getValue()) .eq(SysSystemConfigEntity::getConfigType, SystemConfigTypeEnum.SMS.getValue())
.eq(SysSystemConfigEntity::getConfigStatus, YesNoEnum.YES.getCode()) .eq(SysSystemConfigEntity::getConfigStatus, YesNoEnum.YES.getCode())
.eq(SysSystemConfigEntity::getConfigKey, messageSmsDTO.getBizCode())); .eq(SysSystemConfigEntity::getConfigKey, messageSmsDTO.getBizCode()));
if (CollUtil.isEmpty(configEntityList)) { if (CollUtil.isEmpty(configEntityList)) {
return R.failed("发送失败,短信通道配置不存在"); return R.failed("发送失败,短信通道配置不存在");
} }
SysSystemConfigEntity configEntity = configEntityList.get(0); SysSystemConfigEntity configEntity = configEntityList.get(0);
JSONObject configMap = JSONUtil.parseObj(configEntity.getConfigValue()); JSONObject configMap = JSONUtil.parseObj(configEntity.getConfigValue());
// 组装SMS4J 的发送对象 // 组装SMS4J 的发送对象
SmsBlend smsBlend = SmsFactory.getSmsBlend(messageSmsDTO.getBizCode()); SmsBlend smsBlend = SmsFactory.getSmsBlend(messageSmsDTO.getBizCode());
if (Objects.isNull(smsBlend)) { if (Objects.isNull(smsBlend)) {
Class targetClass = Arrays.stream(SUPPORT_CONFIG_CLAZZ) Class targetClass = Arrays.stream(SUPPORT_CONFIG_CLAZZ)
.filter(config -> config.getSimpleName() .filter(config -> config.getSimpleName()
.toLowerCase() .toLowerCase()
.contains(configMap.getStr(MessageSmsDTO.Fields.supplier))) .contains(configMap.getStr(MessageSmsDTO.Fields.supplier)))
.findFirst() .findFirst()
.orElseThrow(() -> new CheckedException("发送失败,短信通道配置不存在")); .orElseThrow(() -> new CheckedException("发送失败,短信通道配置不存在"));
BaseConfig baseConfig = (BaseConfig) JSONUtil.toBean(configEntity.getConfigValue(), targetClass); BaseConfig baseConfig = (BaseConfig) JSONUtil.toBean(configEntity.getConfigValue(), targetClass);
// 如果渠道扩展参数不为空则增加特性化参数 // 如果渠道扩展参数不为空则增加特性化参数
if (StrUtil.isNotBlank(configMap.getStr(MessageSmsDTO.Fields.extParams))) { if (StrUtil.isNotBlank(configMap.getStr(MessageSmsDTO.Fields.extParams))) {
JSONObject extParams = configMap.getJSONObject(MessageSmsDTO.Fields.extParams); JSONObject extParams = configMap.getJSONObject(MessageSmsDTO.Fields.extParams);
BeanUtil.copyProperties(extParams, baseConfig); BeanUtil.copyProperties(extParams, baseConfig);
} }
baseConfig.setConfigId(configEntity.getConfigKey()); baseConfig.setConfigId(configEntity.getConfigKey());
SmsFactory.createSmsBlend(baseConfig); SmsFactory.createSmsBlend(baseConfig);
smsBlend = SmsFactory.getSmsBlend(messageSmsDTO.getBizCode()); smsBlend = SmsFactory.getSmsBlend(messageSmsDTO.getBizCode());
} }
// 异步发送短信 // 异步发送短信
SysLogDTO sysLog = SysLogUtils.getSysLog(); SysLogDTO sysLog = SysLogUtils.getSysLog();
Long start = System.currentTimeMillis(); Long start = System.currentTimeMillis();
sysLog.setTenantId(TenantContextHolder.getTenantId()); sysLog.setTenantId(TenantContextHolder.getTenantId());
for (String mobile : messageSmsDTO.getMobiles()) { for (String mobile : messageSmsDTO.getMobiles()) {
smsBlend.sendMessageAsync(mobile, configMap.getStr(MessageSmsDTO.Fields.templateId), smsBlend.sendMessageAsync(mobile, configMap.getStr(MessageSmsDTO.Fields.templateId),
messageSmsDTO.getParams(), smsResponse -> { messageSmsDTO.getParams(), smsResponse -> {
log.info("发送短信结果:{}", smsResponse); log.info("发送短信结果:{}", smsResponse);
sysLog.setTitle(String.format("发送短信 %s", mobile)); sysLog.setTitle(String.format("发送短信 %s", mobile));
sysLog.setLogType(LogTypeEnum.NORMAL.getType()); sysLog.setLogType(LogTypeEnum.NORMAL.getType());
sysLog.setServiceId(SystemConfigTypeEnum.SMS.getValue()); sysLog.setServiceId(SystemConfigTypeEnum.SMS.getValue());
sysLog.setParams(JacksonSensitiveFieldUtil.writeValueAsString(messageSmsDTO)); sysLog.setParams(JacksonSensitiveFieldUtil.writeValueAsString(messageSmsDTO));
sysLog.setTime(System.currentTimeMillis() - start); sysLog.setTime(System.currentTimeMillis() - start);
sysLog.setException(JacksonSensitiveFieldUtil.writeValueAsString(smsResponse)); sysLog.setException(JacksonSensitiveFieldUtil.writeValueAsString(smsResponse));
remoteLogService.saveLog(sysLog); remoteLogService.saveLog(sysLog);
}); });
} }
return R.ok(); return R.ok();
} }
/** /**
* 发送钩子消息 * 发送钩子消息
* * @param messageHookDTO 消息挂钩 DTO
* @param messageHookDTO 消息挂钩 DTO * @return {@link R }
* @return {@link R } */
*/ @Override
@Override public R sendHook(MessageHookDTO messageHookDTO) {
public R sendHook(MessageHookDTO messageHookDTO) {
// 根据业务编码获取短信通道配置 // 根据业务编码获取短信通道配置
List<SysSystemConfigEntity> configEntityList = sysSystemConfigMapper List<SysSystemConfigEntity> configEntityList = sysSystemConfigMapper
.selectList(Wrappers.<SysSystemConfigEntity>lambdaQuery() .selectList(Wrappers.<SysSystemConfigEntity>lambdaQuery()
.eq(SysSystemConfigEntity::getConfigType, SystemConfigTypeEnum.WEBHOOK.getValue()) .eq(SysSystemConfigEntity::getConfigType, SystemConfigTypeEnum.WEBHOOK.getValue())
.eq(SysSystemConfigEntity::getConfigStatus, YesNoEnum.YES.getCode()) .eq(SysSystemConfigEntity::getConfigStatus, YesNoEnum.YES.getCode())
.eq(SysSystemConfigEntity::getConfigKey, messageHookDTO.getBizCode())); .eq(SysSystemConfigEntity::getConfigKey, messageHookDTO.getBizCode()));
if (CollUtil.isEmpty(configEntityList)) { if (CollUtil.isEmpty(configEntityList)) {
return R.failed("发送失败,短信通道配置不存在"); return R.failed("发送失败,短信通道配置不存在");
} }
SysSystemConfigEntity configEntity = configEntityList.get(0); SysSystemConfigEntity configEntity = configEntityList.get(0);
JSONObject configMap = JSONUtil.parseObj(configEntity.getConfigValue()); JSONObject configMap = JSONUtil.parseObj(configEntity.getConfigValue());
String supplier = configMap.getStr("supplier"); String supplier = configMap.getStr("supplier");
// 根据配置创建服务实例并注册 // 根据配置创建服务实例并注册
OaSender alarm = OaFactory.getSmsOaBlend(messageHookDTO.getBizCode()); OaSender alarm = OaFactory.getSmsOaBlend(messageHookDTO.getBizCode());
if (Objects.isNull(alarm)) { if (Objects.isNull(alarm)) {
if (StrUtil.equalsAnyIgnoreCase(OaType.DING_TALK.toString(), supplier)) { if (StrUtil.equalsAnyIgnoreCase(OaType.DING_TALK.toString(), supplier)) {
DingTalkConfig dingTalkConfig = new DingTalkConfig(); DingTalkConfig dingTalkConfig = new DingTalkConfig();
dingTalkConfig.setConfigId(messageHookDTO.getBizCode()); dingTalkConfig.setConfigId(messageHookDTO.getBizCode());
dingTalkConfig.setSign(configMap.getStr("sign")); dingTalkConfig.setSign(configMap.getStr("sign"));
dingTalkConfig.setTokenId(configMap.getStr("tokenId")); dingTalkConfig.setTokenId(configMap.getStr("tokenId"));
OaFactory.createAndRegisterOaSender(dingTalkConfig); OaFactory.createAndRegisterOaSender(dingTalkConfig);
} }
if (StrUtil.equalsAnyIgnoreCase(OaType.BYTE_TALK.toString(), supplier)) { if (StrUtil.equalsAnyIgnoreCase(OaType.BYTE_TALK.toString(), supplier)) {
ByteTalkConfig byteTalkConfig = new ByteTalkConfig(); ByteTalkConfig byteTalkConfig = new ByteTalkConfig();
byteTalkConfig.setConfigId(messageHookDTO.getBizCode()); byteTalkConfig.setConfigId(messageHookDTO.getBizCode());
byteTalkConfig.setSign(configMap.getStr("sign")); byteTalkConfig.setSign(configMap.getStr("sign"));
byteTalkConfig.setTokenId(configMap.getStr("tokenId")); byteTalkConfig.setTokenId(configMap.getStr("tokenId"));
OaFactory.createAndRegisterOaSender(byteTalkConfig); OaFactory.createAndRegisterOaSender(byteTalkConfig);
} }
if (StrUtil.equalsAnyIgnoreCase(OaType.WE_TALK.toString(), supplier)) { if (StrUtil.equalsAnyIgnoreCase(OaType.WE_TALK.toString(), supplier)) {
WeTalkConfig weTalkConfig = new WeTalkConfig(); WeTalkConfig weTalkConfig = new WeTalkConfig();
weTalkConfig.setConfigId(messageHookDTO.getBizCode()); weTalkConfig.setConfigId(messageHookDTO.getBizCode());
weTalkConfig.setSign(configMap.getStr("sign")); weTalkConfig.setSign(configMap.getStr("sign"));
weTalkConfig.setTokenId(configMap.getStr("tokenId")); weTalkConfig.setTokenId(configMap.getStr("tokenId"));
OaFactory.createAndRegisterOaSender(weTalkConfig); OaFactory.createAndRegisterOaSender(weTalkConfig);
} }
alarm = OaFactory.getSmsOaBlend(messageHookDTO.getBizCode()); alarm = OaFactory.getSmsOaBlend(messageHookDTO.getBizCode());
} }
Request request = new Request(); Request request = new Request();
request.setContent(messageHookDTO.getMessageContent()); request.setContent(messageHookDTO.getMessageContent());
request.setTitle(messageHookDTO.getMessageTitle()); request.setTitle(messageHookDTO.getMessageTitle());
request.setMessageUrl(messageHookDTO.getMessageUrl()); request.setMessageUrl(messageHookDTO.getMessageUrl());
request.setPicUrl(messageHookDTO.getPicUrl()); request.setPicUrl(messageHookDTO.getPicUrl());
request.setIsNoticeAll(messageHookDTO.isNoticeAll()); request.setIsNoticeAll(messageHookDTO.isNoticeAll());
request.setPhoneList(messageHookDTO.getPhoneList()); request.setPhoneList(messageHookDTO.getPhoneList());
SysLogDTO sysLog = SysLogUtils.getSysLog(); SysLogDTO sysLog = SysLogUtils.getSysLog();
sysLog.setTenantId(TenantContextHolder.getTenantId()); sysLog.setTenantId(TenantContextHolder.getTenantId());
Long start = System.currentTimeMillis(); Long start = System.currentTimeMillis();
alarm.senderAsync(request, alarm.senderAsync(request,
MessageType.valueOf(String.format("%s_%s", supplier, messageHookDTO.getMessageType()).toUpperCase()), MessageType.valueOf(String.format("%s_%s", supplier, messageHookDTO.getMessageType()).toUpperCase()),
response -> { response -> {
log.info("发送Hook结果:{}", response); log.info("发送Hook结果:{}", response);
sysLog.setTitle(String.format("发送Hook %s", messageHookDTO.getBizCode())); sysLog.setTitle(String.format("发送Hook %s", messageHookDTO.getBizCode()));
sysLog.setLogType(LogTypeEnum.NORMAL.getType()); sysLog.setLogType(LogTypeEnum.NORMAL.getType());
sysLog.setServiceId(SystemConfigTypeEnum.WEBHOOK.getValue()); sysLog.setServiceId(SystemConfigTypeEnum.WEBHOOK.getValue());
sysLog.setParams(JacksonSensitiveFieldUtil.writeValueAsString(messageHookDTO)); sysLog.setParams(JacksonSensitiveFieldUtil.writeValueAsString(messageHookDTO));
sysLog.setTime(System.currentTimeMillis() - start); sysLog.setTime(System.currentTimeMillis() - start);
sysLog.setException(JacksonSensitiveFieldUtil.writeValueAsString(response)); sysLog.setException(JacksonSensitiveFieldUtil.writeValueAsString(response));
remoteLogService.saveLog(sysLog); remoteLogService.saveLog(sysLog);
}); });
return R.ok(); return R.ok();
} }
/** /**
* 发送邮件 * 发送邮件
* * @param messageEmailDTO 留言内容 电子邮件 DTO
* @param messageEmailDTO 留言内容 电子邮件 DTO * @return {@link R }
* @return {@link R } */
*/ @SneakyThrows
@SneakyThrows @Override
@Override public R sendEmail(MessageEmailDTO messageEmailDTO) {
public R sendEmail(MessageEmailDTO messageEmailDTO) { // 根据业务编码获取短信通道配置
// 根据业务编码获取短信通道配置 List<SysSystemConfigEntity> configEntityList = sysSystemConfigMapper
List<SysSystemConfigEntity> configEntityList = sysSystemConfigMapper .selectList(Wrappers.<SysSystemConfigEntity>lambdaQuery()
.selectList(Wrappers.<SysSystemConfigEntity>lambdaQuery() .eq(SysSystemConfigEntity::getConfigType, SystemConfigTypeEnum.EMAIL.getValue())
.eq(SysSystemConfigEntity::getConfigType, SystemConfigTypeEnum.EMAIL.getValue()) .eq(SysSystemConfigEntity::getConfigStatus, YesNoEnum.YES.getCode())
.eq(SysSystemConfigEntity::getConfigStatus, YesNoEnum.YES.getCode()) .eq(SysSystemConfigEntity::getConfigKey, messageEmailDTO.getBizCode()));
.eq(SysSystemConfigEntity::getConfigKey, messageEmailDTO.getBizCode())); if (CollUtil.isEmpty(configEntityList)) {
if (CollUtil.isEmpty(configEntityList)) { return R.failed("发送失败,通道配置不存在");
return R.failed("发送失败,通道配置不存在"); }
} SysSystemConfigEntity configEntity = configEntityList.get(0);
SysSystemConfigEntity configEntity = configEntityList.get(0); JSONObject configMap = JSONUtil.parseObj(configEntity.getConfigValue());
JSONObject configMap = JSONUtil.parseObj(configEntity.getConfigValue());
List<File> tempFileList = new ArrayList<>(); List<File> tempFileList = new ArrayList<>();
if (CollUtil.isNotEmpty(messageEmailDTO.getAttachmentList())) { if (CollUtil.isNotEmpty(messageEmailDTO.getAttachmentList())) {
TenantContextHolder.setTenantSkip(); TenantContextHolder.setTenantSkip();
for (String fileName : messageEmailDTO.getAttachmentList()) { for (String fileName : messageEmailDTO.getAttachmentList()) {
SysFile sysFile = fileMapper SysFile sysFile = fileMapper
.selectOne(Wrappers.<SysFile>lambdaQuery().eq(SysFile::getFileName, fileName)); .selectOne(Wrappers.<SysFile>lambdaQuery().eq(SysFile::getFileName, fileName));
S3Object s3Object = fileTemplate.getObject(sysFile.getBucketName(), sysFile.getDir(), fileName); S3Object s3Object = fileTemplate.getObject(sysFile.getBucketName(), sysFile.getDir(), fileName);
File file = FileUtil.file(FileUtil.getTmpDirPath(), sysFile.getOriginal()); File file = FileUtil.file(FileUtil.getTmpDirPath(), sysFile.getOriginal());
tempFileList.add(file); tempFileList.add(file);
IoUtil.copy(s3Object.getObjectContent(), FileUtil.getOutputStream(file)); IoUtil.copy(s3Object.getObjectContent(), FileUtil.getOutputStream(file));
} }
} }
MailAccount account = new MailAccount(); MailAccount account = new MailAccount();
account.setHost(configMap.getStr("smtpServer")); account.setHost(configMap.getStr("smtpServer"));
account.setPort(configMap.getInt("port")); account.setPort(configMap.getInt("port"));
account.setAuth(configMap.getBool("isAuth")); account.setAuth(configMap.getBool("isAuth"));
account.setSslEnable(configMap.getBool("isSSL")); account.setSslEnable(configMap.getBool("isSSL"));
account.setFrom(configMap.getStr("username")); account.setFrom(configMap.getStr("username"));
account.setUser(configMap.getStr("username")); account.setUser(configMap.getStr("username"));
account.setPass(configMap.getStr("password")); account.setPass(configMap.getStr("password"));
// 渲染模板 // 渲染模板
TemplateEngine engine = TemplateUtil.createEngine(new TemplateConfig()); TemplateEngine engine = TemplateUtil.createEngine(new TemplateConfig());
Template template = engine.getTemplate(configMap.getStr("html")); Template template = engine.getTemplate(configMap.getStr("html"));
String result = template.render(messageEmailDTO.getHtmlValues()); String result = template.render(messageEmailDTO.getHtmlValues());
Long start = System.currentTimeMillis(); Long start = System.currentTimeMillis();
MailUtil.send(account, messageEmailDTO.getMailAddress(), messageEmailDTO.getCcList(), MailUtil.send(account, messageEmailDTO.getMailAddress(), messageEmailDTO.getCcList(),
messageEmailDTO.getBccList(), messageEmailDTO.getTitle(), result, true, messageEmailDTO.getBccList(), messageEmailDTO.getTitle(), result, true,
tempFileList.toArray(new File[0])); tempFileList.toArray(new File[0]));
Long end = System.currentTimeMillis(); Long end = System.currentTimeMillis();
// 写入日志 // 写入日志
SysLogDTO sysLog = SysLogUtils.getSysLog(); SysLogDTO sysLog = SysLogUtils.getSysLog();
sysLog.setTitle(String.format("发送邮件 %s", messageEmailDTO.getTitle())); sysLog.setTitle(String.format("发送邮件 %s", messageEmailDTO.getTitle()));
sysLog.setLogType(LogTypeEnum.NORMAL.getType()); sysLog.setLogType(LogTypeEnum.NORMAL.getType());
sysLog.setServiceId(SystemConfigTypeEnum.EMAIL.getValue()); sysLog.setServiceId(SystemConfigTypeEnum.EMAIL.getValue());
sysLog.setParams(JacksonSensitiveFieldUtil.writeValueAsString(messageEmailDTO)); sysLog.setParams(JacksonSensitiveFieldUtil.writeValueAsString(messageEmailDTO));
sysLog.setTenantId(TenantContextHolder.getTenantId()); sysLog.setTenantId(TenantContextHolder.getTenantId());
sysLog.setTime(end - start); sysLog.setTime(end - start);
remoteLogService.saveLog(sysLog); remoteLogService.saveLog(sysLog);
// 删除临时文件 // 删除临时文件
tempFileList.forEach(FileUtil::del); tempFileList.forEach(FileUtil::del);
return R.ok(); return R.ok();
} }
/** /**
* 列出 Hook 业务代码 * 列出 Hook 业务代码
* * @param messageHookDTO 消息钩子 DTO
* @param messageHookDTO 消息钩子 DTO * @return {@link R }
* @return {@link R } */
*/ @Override
@Override public R listHookBizCode(MessageHookDTO messageHookDTO) {
public R listHookBizCode(MessageHookDTO messageHookDTO) { List<SysSystemConfigEntity> configEntityList = sysSystemConfigMapper
List<SysSystemConfigEntity> configEntityList = sysSystemConfigMapper .selectList(Wrappers.<SysSystemConfigEntity>lambdaQuery()
.selectList(Wrappers.<SysSystemConfigEntity>lambdaQuery()
.eq(SysSystemConfigEntity::getConfigType, messageHookDTO.getMessageType()) .eq(SysSystemConfigEntity::getConfigType, messageHookDTO.getMessageType())
.eq(SysSystemConfigEntity::getConfigStatus, YesNoEnum.YES.getCode())); .eq(SysSystemConfigEntity::getConfigStatus, YesNoEnum.YES.getCode()));
return R.ok(configEntityList); return R.ok(configEntityList);
@@ -47,6 +47,7 @@ import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.data.cache.RedisUtils; import com.pig4cloud.pigx.common.data.cache.RedisUtils;
import com.pig4cloud.pigx.common.data.datascope.DataScope; import com.pig4cloud.pigx.common.data.datascope.DataScope;
import com.pig4cloud.pigx.common.data.resolver.ParamResolver; import com.pig4cloud.pigx.common.data.resolver.ParamResolver;
import com.pig4cloud.pigx.common.data.tenant.TenantBroker;
import com.pig4cloud.pigx.common.excel.vo.ErrorMessage; import com.pig4cloud.pigx.common.excel.vo.ErrorMessage;
import com.pig4cloud.pigx.common.security.service.PigxUser; import com.pig4cloud.pigx.common.security.service.PigxUser;
import com.pig4cloud.pigx.common.security.util.SecurityUtils; import com.pig4cloud.pigx.common.security.util.SecurityUtils;
@@ -391,7 +392,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
// 执行数据插入操作 组装 UserDto // 执行数据插入操作 组装 UserDto
for (UserExcelVO excel : excelVOList) { for (UserExcelVO excel : excelVOList) {
// 个性化校验逻辑 // 个性化校验逻辑
List<SysUser> userList = this.list(); List<SysUser> userList = TenantBroker.noneAs(this::list);
Set<String> errorMsg = new HashSet<>(); Set<String> errorMsg = new HashSet<>();
// 校验用户名是否存在 // 校验用户名是否存在
@@ -402,11 +403,17 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
errorMsg.add(MsgUtils.getMessage(ErrorCodes.SYS_USER_USERNAME_EXISTING, excel.getUsername())); errorMsg.add(MsgUtils.getMessage(ErrorCodes.SYS_USER_USERNAME_EXISTING, excel.getUsername()));
} }
// 校验手机号是否存在
boolean exsitPhone = userList.stream().anyMatch(sysUser -> excel.getPhone().equals(sysUser.getPhone()));
if (exsitPhone) {
errorMsg.add(MsgUtils.getMessage(ErrorCodes.SYS_USER_PHONE_EXISTING, excel.getPhone()));
}
// 判断输入的部门名称列表是否合法 // 判断输入的部门名称列表是否合法
Optional<SysDept> deptOptional = deptList.stream() Optional<SysDept> deptOptional = deptList.stream()
.filter(dept -> excel.getDeptNameList().equals(dept.getName())) .filter(dept -> excel.getDeptNameList().equals(dept.getName()))
.findFirst(); .findFirst();
if (!deptOptional.isPresent()) { if (deptOptional.isEmpty()) {
errorMsg.add(MsgUtils.getMessage(ErrorCodes.SYS_DEPT_DEPTNAME_INEXISTENCE, excel.getDeptNameList())); errorMsg.add(MsgUtils.getMessage(ErrorCodes.SYS_DEPT_DEPTNAME_INEXISTENCE, excel.getDeptNameList()));
} }
@@ -488,15 +495,16 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public R<Boolean> registerUser(RegisterUserDTO userDto) { public R<Boolean> registerUser(RegisterUserDTO userDto) {
// 判断用户名是否存在 // 判断用户名是否存在
boolean usernameExists = this boolean usernameExists = TenantBroker
.exists(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getUsername, userDto.getUsername())); .noneAs(() -> this.exists(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getUsername, userDto.getUsername())));
if (usernameExists) { if (usernameExists) {
String message = MsgUtils.getMessage(ErrorCodes.SYS_USER_USERNAME_EXISTING, userDto.getUsername()); String message = MsgUtils.getMessage(ErrorCodes.SYS_USER_USERNAME_EXISTING, userDto.getUsername());
return R.failed(message); return R.failed(message);
} }
// 判断手机号是否存在 // 判断手机号是否存在
boolean phoneExists = this.exists(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getPhone, userDto.getPhone())); boolean phoneExists = TenantBroker
.noneAs(() -> this.exists(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getPhone, userDto.getPhone())));
if (phoneExists) { if (phoneExists) {
String message = MsgUtils.getMessage(ErrorCodes.SYS_USER_PHONE_EXISTING, userDto.getPhone()); String message = MsgUtils.getMessage(ErrorCodes.SYS_USER_PHONE_EXISTING, userDto.getPhone());
return R.failed(message); return R.failed(message);
@@ -626,7 +634,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
*/ */
@Override @Override
@CacheEvict(value = CacheConstants.USER_DETAILS, key = "#userDto.username") @CacheEvict(value = CacheConstants.USER_DETAILS, key = "#userDto.username")
public R<Boolean> resetUserPassword(RegisterUserDTO userDto) { public R resetUserPassword(RegisterUserDTO userDto) {
// 校验密码 // 校验密码
R checkedPassword = checkPassword(userDto.getUsername(), userDto.getPassword()); R checkedPassword = checkPassword(userDto.getUsername(), userDto.getPassword());
if (!checkedPassword.isOk()) { if (!checkedPassword.isOk()) {
@@ -666,19 +674,23 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
return R.failed("验证码错误"); return R.failed("验证码错误");
} }
String username = lambdaQuery().select(SysUser::getUsername) TenantBroker.noneAs(() -> {
.eq(SysUser::getPhone, userDto.getPhone()) String username = lambdaQuery().select(SysUser::getUsername)
.one() .eq(SysUser::getPhone, userDto.getPhone())
.getUsername(); .one()
.getUsername();
// 重置密码
String password = ENCODER.encode(userDto.getNewpassword1());
this.update(Wrappers.<SysUser>lambdaUpdate()
.set(SysUser::getPassword, password)
.set(SysUser::getPasswordModifyTime, LocalDateTime.now())
.set(SysUser::getPasswordExpireFlag, CommonConstants.STATUS_NORMAL)
.eq(SysUser::getPhone, userDto.getPhone()));
cacheManager.getCache(CacheConstants.USER_DETAILS).evict(username);
return username;
});
// 重置密码
String password = ENCODER.encode(userDto.getNewpassword1());
this.update(Wrappers.<SysUser>lambdaUpdate()
.set(SysUser::getPassword, password)
.set(SysUser::getPasswordModifyTime, LocalDateTime.now())
.set(SysUser::getPasswordExpireFlag, CommonConstants.STATUS_NORMAL)
.eq(SysUser::getPhone, userDto.getPhone()));
cacheManager.getCache(CacheConstants.USER_DETAILS).evict(username);
return R.ok(); return R.ok();
} }