This commit is contained in:
caozehui
2026-04-09 18:31:55 +08:00
parent fc6fc9642b
commit d44f6423e0
10 changed files with 54 additions and 48 deletions

View File

@@ -60,7 +60,8 @@ public class AliyunEmailSender implements EmailSender {
RuntimeOptions runtimeOptions = new RuntimeOptions(); RuntimeOptions runtimeOptions = new RuntimeOptions();
runtimeOptions.autoretry = true; runtimeOptions.autoretry = true;
JSONObject jsonObject = JSON.parseObject(message.getExtraInfo()); // JSONObject jsonObject = JSON.parseObject(message.getExtraInfo());
JSONObject jsonObject = null;
SingleSendMailRequest request = new SingleSendMailRequest() SingleSendMailRequest request = new SingleSendMailRequest()
.setAccountName(jsonObject.getString(ACCOUNT_NAME)) .setAccountName(jsonObject.getString(ACCOUNT_NAME))
.setAddressType(1) .setAddressType(1)

View File

@@ -200,36 +200,36 @@ public class TelecomSmsSender implements SmsSender {
return; return;
} }
TelecomSmsSelectDetailRes detailRes = selectResponse.getList().get(0); TelecomSmsSelectDetailRes detailRes = selectResponse.getList().get(0);
// if (detailRes.getStatus() == 5) { if (detailRes.getStatus() == 5) {
// SendResult failedResult = this.sender.buildFailureResult(
// message,
// detailRes.getStat(),
// null,
// "THIRD_PARTY_CALLBACK_FAILED",
// "短信回执返回失败",
// false
// );
// this.sender.applyCallbackResult(message, failedResult);
// } else if (detailRes.getStatus() == 4) {
// // 回执确认成功后,复用统一成功落库逻辑。
// this.sender.applyCallbackResult(message, SendResult.success(message.getSendTime(), message.getCostTime(), message.getThirdPartyId()));
// }
double random = Math.random();
System.out.println(random + " aaaa");
if (random > 0.5) {
SendResult failedResult = this.sender.buildFailureResult( SendResult failedResult = this.sender.buildFailureResult(
message, message,
detailRes.getStat(), detailRes.getStat(),
null, null,
"THIRD_PARTY_CALLBACK_FAILED", "THIRD_PARTY_CALLBACK_FAILED",
"短信回执返回失败", "短信回执返回失败",
true false
); );
this.sender.applyCallbackResult(message, failedResult); this.sender.applyCallbackResult(message, failedResult);
} else { } else if (detailRes.getStatus() == 4) {
// 回执确认成功后,复用统一成功落库逻辑。 // 回执确认成功后,复用统一成功落库逻辑。
this.sender.applyCallbackResult(message, SendResult.success(message.getSendTime(), message.getCostTime(), message.getThirdPartyId())); this.sender.applyCallbackResult(message, SendResult.success(message.getSendTime(), message.getCostTime(), message.getThirdPartyId()));
} }
// double random = Math.random();
// System.out.println(random + " aaaa");
// if (random > 0.5) {
// SendResult failedResult = this.sender.buildFailureResult(
// message,
// detailRes.getStat(),
// null,
// "THIRD_PARTY_CALLBACK_FAILED",
// "短信回执返回失败",
// true
// );
// this.sender.applyCallbackResult(message, failedResult);
// } else {
// // 回执确认成功后,复用统一成功落库逻辑。
// this.sender.applyCallbackResult(message, SendResult.success(message.getSendTime(), message.getCostTime(), message.getThirdPartyId()));
// }
} catch (Exception e) { } catch (Exception e) {
log.error("电信短信回执查询失败", e); log.error("电信短信回执查询失败", e);
} }

View File

@@ -20,7 +20,7 @@ import org.springframework.web.bind.annotation.RestController;
*/ */
@Tag(name = "系统凭证管理") @Tag(name = "系统凭证管理")
@RestController @RestController
@RequestMapping("/credential") @RequestMapping("/push/credential")
public class CredentialController { public class CredentialController {
@Autowired @Autowired

View File

@@ -8,6 +8,8 @@ import com.njcn.msgpush.module.push.controller.admin.message.vo.MessageRecordReq
import com.njcn.msgpush.module.push.controller.admin.message.vo.MessageSendResultVO; import com.njcn.msgpush.module.push.controller.admin.message.vo.MessageSendResultVO;
import com.njcn.msgpush.module.push.dal.dataobject.message.MessageRecordDO; import com.njcn.msgpush.module.push.dal.dataobject.message.MessageRecordDO;
import com.njcn.msgpush.module.push.enums.ChannelTypeEnum; import com.njcn.msgpush.module.push.enums.ChannelTypeEnum;
import com.njcn.msgpush.module.push.service.credential.CredentialServiceImpl;
import com.njcn.msgpush.module.push.service.credential.ICredentialService;
import com.njcn.msgpush.module.push.service.message.MessageRecordService; import com.njcn.msgpush.module.push.service.message.MessageRecordService;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Parameter;
@@ -31,29 +33,40 @@ public class MessageRecordController {
@Autowired @Autowired
private MessageRecordService messageRecordService; private MessageRecordService messageRecordService;
@Autowired
private ICredentialService credentialService;
@PermitAll @PermitAll
@PostMapping("/send/sms") @PostMapping("/send/sms")
@Operation(summary = "短信推送") @Operation(summary = "短信推送")
@Idempotent(timeout = 2) @Idempotent(timeout = 2)
public CommonResult<List<MessageSendResultVO>> sendSms(@Valid @RequestBody List<MessageRecordReqVO> reqVOList) { public CommonResult<List<MessageSendResultVO>> sendSms(@Valid @RequestBody List<MessageRecordReqVO> reqVOList,
return success(messageRecordService.send(reqVOList, ChannelTypeEnum.SMS)); @RequestHeader(value = "X-Credential-Token", required = false) String credentialToken) {
CredentialServiceImpl.CredentialInfo credentialInfo = credentialService.verifyCredential(credentialToken);
String systemName = credentialInfo.getSystemName();
return success(messageRecordService.send(reqVOList, ChannelTypeEnum.SMS, systemName));
} }
@PermitAll @PermitAll
@PostMapping("/send/email") @PostMapping("/send/email")
@Operation(summary = "邮箱推送") @Operation(summary = "邮箱推送")
@Idempotent(timeout = 2) @Idempotent(timeout = 2)
public CommonResult<List<MessageSendResultVO>> sendEmail(@Valid @RequestBody List<MessageRecordReqVO> reqVOList) { public CommonResult<List<MessageSendResultVO>> sendEmail(@Valid @RequestBody List<MessageRecordReqVO> reqVOList,
return success(messageRecordService.send(reqVOList, ChannelTypeEnum.EMAIL)); @RequestHeader(value = "X-Credential-Token", required = false) String credentialToken) {
CredentialServiceImpl.CredentialInfo credentialInfo = credentialService.verifyCredential(credentialToken);
String systemName = credentialInfo.getSystemName();
return success(messageRecordService.send(reqVOList, ChannelTypeEnum.EMAIL, systemName));
} }
@PermitAll @PermitAll
@PostMapping("/send/app") @PostMapping("/send/app")
@Operation(summary = "app推送") @Operation(summary = "app推送")
@Idempotent(timeout = 2) @Idempotent(timeout = 2)
public CommonResult<List<MessageSendResultVO>> sendApp(@Valid @RequestBody List<MessageRecordReqVO> reqVOList) { public CommonResult<List<MessageSendResultVO>> sendApp(@Valid @RequestBody List<MessageRecordReqVO> reqVOList,
return success(messageRecordService.send(reqVOList, ChannelTypeEnum.APP)); @RequestHeader(value = "X-Credential-Token", required = false) String credentialToken) {
CredentialServiceImpl.CredentialInfo credentialInfo = credentialService.verifyCredential(credentialToken);
String systemName = credentialInfo.getSystemName();
return success(messageRecordService.send(reqVOList, ChannelTypeEnum.APP, systemName));
} }
@PostMapping("/page") @PostMapping("/page")

View File

@@ -1,5 +1,6 @@
package com.njcn.msgpush.module.push.dal.dataobject.credential; package com.njcn.msgpush.module.push.dal.dataobject.credential;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data; import lombok.Data;
/** /**
@@ -7,6 +8,7 @@ import lombok.Data;
* @data 2026-04-09 * @data 2026-04-09
*/ */
@Data @Data
@TableName("push_sys_secret")
public class SystemSecretDO { public class SystemSecretDO {
private String id; private String id;
private String systemName; private String systemName;

View File

@@ -62,10 +62,6 @@ public class MessageRecordDO extends BaseDO {
*/ */
private String templateParams; private String templateParams;
/**
* 额外信息
*/
private String extraInfo;
/** /**
* 状态pending/sending/success/failed/final_failed/blacklisted/quota_exceeded/rate_limited/abandoned * 状态pending/sending/success/failed/final_failed/blacklisted/quota_exceeded/rate_limited/abandoned

View File

@@ -1,5 +1,6 @@
package com.njcn.msgpush.module.push.dal.dataobject.retry; package com.njcn.msgpush.module.push.dal.dataobject.retry;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import com.njcn.msgpush.framework.mybatis.core.dataobject.BaseDO; import com.njcn.msgpush.framework.mybatis.core.dataobject.BaseDO;
import lombok.Data; import lombok.Data;

View File

@@ -32,7 +32,8 @@ public class CredentialServiceImpl implements ICredentialService {
/** /**
* 凭证加密密钥(生产环境应通过配置中心或环境变量注入) * 凭证加密密钥(生产环境应通过配置中心或环境变量注入)
*/ */
private String credentialSecretKey = "88888888"; private String credentialSecretKey = "88888888888888888888888888888888"; // 32 字节
@Autowired @Autowired
private ISystemSecretService systemSecretService; private ISystemSecretService systemSecretService;

View File

@@ -16,10 +16,11 @@ public interface MessageRecordService extends IService<MessageRecordDO> {
* 发送消息包括email、sms、app * 发送消息包括email、sms、app
* *
* @param reqVOList * @param reqVOList
* @param systemName
* @return channelTypeEnum * @return channelTypeEnum
* @return 发送的结果 * @return 发送的结果
*/ */
List<MessageSendResultVO> send(List<MessageRecordReqVO> reqVOList, ChannelTypeEnum channelTypeEnum); List<MessageSendResultVO> send(List<MessageRecordReqVO> reqVOList, ChannelTypeEnum channelTypeEnum, String systemName);
/** /**
* 处理发送消息 * 处理发送消息

View File

@@ -71,17 +71,18 @@ public class MessageRecordServiceImpl extends ServiceImpl<MessageRecordMapper, M
private MessageConfirmRedisDAO messageConfirmRedisDAO; private MessageConfirmRedisDAO messageConfirmRedisDAO;
@Override @Override
public List<MessageSendResultVO> send(List<MessageRecordReqVO> reqVOList, ChannelTypeEnum channelTypeEnum) { public List<MessageSendResultVO> send(List<MessageRecordReqVO> reqVOList, ChannelTypeEnum channelTypeEnum, String systemName) {
List<MessageRecordDO> messageRecordDOList = this.createMessageRecords(reqVOList, channelTypeEnum); List<MessageRecordDO> messageRecordDOList = this.createMessageRecords(reqVOList, channelTypeEnum, systemName);
return this.processSendMsg(messageRecordDOList, null); return this.processSendMsg(messageRecordDOList, null);
} }
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public List<MessageRecordDO> createMessageRecords(List<MessageRecordReqVO> reqVOList, ChannelTypeEnum channelTypeEnum) { public List<MessageRecordDO> createMessageRecords(List<MessageRecordReqVO> reqVOList, ChannelTypeEnum channelTypeEnum, String systemName) {
List<MessageRecordDO> messageRecordDOList = BeanUtil.copyToList(reqVOList, MessageRecordDO.class); List<MessageRecordDO> messageRecordDOList = BeanUtil.copyToList(reqVOList, MessageRecordDO.class);
messageRecordDOList.forEach(messageRecordDO -> { messageRecordDOList.forEach(messageRecordDO -> {
messageRecordDO.setChannel(channelTypeEnum.getCode()); messageRecordDO.setChannel(channelTypeEnum.getCode());
messageRecordDO.setStatus(MsgStatusConstant.PENDING); messageRecordDO.setStatus(MsgStatusConstant.PENDING);
messageRecordDO.setAppName(systemName);
// messageRecordDO.setRetryCount(0); // messageRecordDO.setRetryCount(0);
}); });
this.saveBatch(messageRecordDOList); this.saveBatch(messageRecordDOList);
@@ -123,22 +124,12 @@ public class MessageRecordServiceImpl extends ServiceImpl<MessageRecordMapper, M
} }
List<ChannelProviderConfigDO> enabledProviders = channelProviderConfigService.getEnabledProviders(messageRecordDO.getChannel()); List<ChannelProviderConfigDO> enabledProviders = channelProviderConfigService.getEnabledProviders(messageRecordDO.getChannel());
SendResult sendResult = null; SendResult sendResult = null;
if (CollectionUtil.isNotEmpty(enabledProviders)) {
ChannelProviderConfigDO channelProviderConfigDO = enabledProviders.get(0);
MessageProviderFactory messageProviderFactory = messageProviderFactoryMap.get(channelProviderConfigDO.getProviderType());
sendResult = this.sendMessage(messageRecordDO, channelProviderConfigDO, messageProviderFactory);
this.applySendResult(messageRecordDO, sendResult);
this.recordRetryHistory(messageRecordDO, retrySource);
} else {
sendResult = this.sendMessage(messageRecordDO, null, null);
this.applySendResult(messageRecordDO, sendResult);
}
if (CollectionUtil.isNotEmpty(enabledProviders)) { if (CollectionUtil.isNotEmpty(enabledProviders)) {
ChannelProviderConfigDO channelProviderConfigDO = enabledProviders.get(0); ChannelProviderConfigDO channelProviderConfigDO = enabledProviders.get(0);
MessageProviderFactory messageProviderFactory = messageProviderFactoryMap.get(channelProviderConfigDO.getProviderType()); MessageProviderFactory messageProviderFactory = messageProviderFactoryMap.get(channelProviderConfigDO.getProviderType());
sendResult = this.validateProviderAndChannel(messageRecordDO, channelProviderConfigDO, messageProviderFactory); sendResult = this.validateProviderAndChannel(messageRecordDO, channelProviderConfigDO, messageProviderFactory);
messageRecordDO.setProviderType(channelProviderConfigDO.getProviderType());
if (sendResult == null) { if (sendResult == null) {
sendResult = this.sendMessage(messageRecordDO, channelProviderConfigDO, messageProviderFactory); sendResult = this.sendMessage(messageRecordDO, channelProviderConfigDO, messageProviderFactory);
} }
@@ -284,7 +275,7 @@ public class MessageRecordServiceImpl extends ServiceImpl<MessageRecordMapper, M
public Page<MessageRecordDO> getPage(MessageRecordReqVO reqVO) { public Page<MessageRecordDO> getPage(MessageRecordReqVO reqVO) {
QueryWrapper<MessageRecordDO> wrapper = new QueryWrapper<>(); QueryWrapper<MessageRecordDO> wrapper = new QueryWrapper<>();
wrapper.lambda() wrapper.lambda()
.eq(StrUtil.isNotBlank(reqVO.getChannel()), MessageRecordDO::getChannel, reqVO.getChannel()); .eq(StrUtil.isNotBlank(reqVO.getMessageType()), MessageRecordDO::getChannel, reqVO.getChannel());
return this.page(new Page<>(PageUtils.getPageNum(reqVO), PageUtils.getPageSize(reqVO)), wrapper); return this.page(new Page<>(PageUtils.getPageNum(reqVO), PageUtils.getPageSize(reqVO)), wrapper);
} }
} }