Commit a5c1a711 by zhangxingmin

push

parent 5ed42264
...@@ -120,5 +120,11 @@ ...@@ -120,5 +120,11 @@
<version>5.8.25</version> <version>5.8.25</version>
</dependency> </dependency>
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-miniapp</artifactId>
<version>4.6.0</version>
</dependency>
</dependencies> </dependencies>
</project> </project>
\ No newline at end of file
...@@ -2,7 +2,6 @@ package com.yd.notice.service.send; ...@@ -2,7 +2,6 @@ package com.yd.notice.service.send;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
......
package com.yd.notice.service.send;
import cn.binarywang.wx.miniapp.bean.WxMaSubscribeMessage;
import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl;
import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl;
import com.alibaba.fastjson.JSONObject;
import com.yd.notice.service.model.ChannelConfig;
import com.yd.notice.service.model.NotificationTask;
import com.yd.notice.service.model.NotificationTemplate;
import com.yd.notice.service.service.IChannelConfigService;
import com.yd.notice.service.service.INotificationTemplateService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@Slf4j
@Component
@RequiredArgsConstructor
public class MiniprogramMessageSender implements MessageSender {
private final IChannelConfigService channelConfigService;
private final INotificationTemplateService templateService;
// 不可重试的错误码(永久失败)
private static final String USER_REFUSE_ERROR = "43101"; // 用户拒绝接收
private static final String TEMPLATE_INVALID = "200002"; // 模板ID不合法
@Override
public SendResult send(NotificationTask task) {
try {
// 1. 查询渠道配置(获取 AppId 和 Secret)
ChannelConfig config = channelConfigService.getByChannelBizId(task.getChannelBizId());
if (config == null || config.getStatus() != 1) {
return SendResult.failNonRetryable("CONFIG_NOT_EXIST", "渠道配置不存在或已禁用");
}
JSONObject wxConfig = JSONObject.parseObject(config.getConfigValue());
String appid = wxConfig.getString("appid");
String secret = wxConfig.getString("secret");
// 2. 查询模板配置(获取微信侧 templateId 和 content 模板)
NotificationTemplate template = templateService.getById(task.getTemplateBizId());
if (template == null) {
return SendResult.failNonRetryable("TEMPLATE_NOT_EXIST", "模板不存在");
}
String wxTemplateId = template.getExtraTemplate(); // 微信公众平台的模板ID
if (!StringUtils.hasText(wxTemplateId)) {
return SendResult.failNonRetryable("TEMPLATE_ID_EMPTY", "未配置微信模板ID");
}
// 3. 解析 content_template 并渲染占位符
// task.getContent() 已经是渲染后的完整 JSON 字符串(由 TemplateRenderUtil 提前处理)
// 但为了标准化,我们在这里再次解析,顺便提取 page 跳转路径
String renderedContent = task.getContent();
JSONObject contentJson = JSONObject.parseObject(renderedContent);
// 提取 page(跳转路径),并从 data 中移除
String page = contentJson.getString("page");
contentJson.remove("page");
// 4. 构建微信订阅消息数据结构(新版本使用 List<MsgData>)
List<WxMaSubscribeMessage.MsgData> dataList = new ArrayList<>();
for (Map.Entry<String, Object> entry : contentJson.entrySet()) {
String key = entry.getKey();
String value = entry.getValue() != null ? entry.getValue().toString() : "";
dataList.add(new WxMaSubscribeMessage.MsgData(key, value));
}
// 5. 构建消息体
WxMaSubscribeMessage message = new WxMaSubscribeMessage();
message.setToUser(task.getReceiver());
message.setTemplateId(wxTemplateId);
message.setData(dataList); // 现在参数类型匹配
if (StringUtils.hasText(page)) {
message.setPage(page);
}
// 6. 调用微信 SDK 发送
WxMaService wxMaService = buildWxMaService(appid, secret);
wxMaService.getMsgService().sendSubscribeMsg(message);
log.info("微信小程序订阅消息发送成功, taskBizId={}, openid={}", task.getTaskBizId(), task.getReceiver());
return SendResult.success();
} catch (WxErrorException e) {
// 微信 API 抛出的具体异常(含错误码)
Integer errorCode = e.getError().getErrorCode(); // 正确获取错误码
String errCode = errorCode != null ? errorCode.toString() : "UNKNOWN";
String errMsg = e.getMessage();
log.error("微信小程序发送失败, taskBizId={}, errCode={}, errMsg={}", task.getTaskBizId(), errCode, errMsg);
// 处理不可重试错误
if (USER_REFUSE_ERROR.equals(errCode) || TEMPLATE_INVALID.equals(errCode)) {
return SendResult.failNonRetryable(errCode, errMsg);
}
return SendResult.failRetryable(errCode, errMsg);
} catch (Exception e) {
log.error("微信小程序发送异常, taskBizId={}", task.getTaskBizId(), e);
return SendResult.failRetryable("SEND_EXCEPTION", e.getMessage());
}
}
private WxMaService buildWxMaService(String appid, String secret) {
WxMaDefaultConfigImpl config = new WxMaDefaultConfigImpl();
config.setAppid(appid);
config.setSecret(secret);
WxMaService service = new WxMaServiceImpl();
service.setWxMaConfig(config);
return service;
}
@Override
public String getSupportedChannelType() {
return "miniprogram"; // 必须与 channel_config.channel_type 一致
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment