liusheng
2 天以前 4c0da4f99ca97d2cfcaa00fd5cd9c3d69d089bfa
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
package com.ruoyi.common.utils;
 
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpInMemoryConfigStorage;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import me.chanjar.weixin.mp.bean.kefu.WxMpKefuMessage;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateData;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage;
 
import java.util.Map;
 
/**
 * 微信公众号消息发送工具类
 * 支持:文本客服消息、模板消息
 */
@Slf4j
public class WxMpUtils {
 
    private final WxMpService wxMpService;
 
    /**
     * 构造方法,通过 appId 和 appSecret 初始化微信公众号服务
     *
     * @param appId     微信公众号 AppID
     * @param appSecret 微信公众号 AppSecret
     */
    public WxMpUtils(String appId, String appSecret) {
        WxMpInMemoryConfigStorage configStorage = new WxMpInMemoryConfigStorage();
        configStorage.setAppId(appId);
        configStorage.setSecret(appSecret);
        wxMpService = new WxMpServiceImpl();
        wxMpService.setWxMpConfigStorage(configStorage);
    }
 
    // -------------------------------------------------------------------------
    // 文本客服消息
    // -------------------------------------------------------------------------
 
    /**
     * 向指定 openid 的用户发送文本客服消息
     * 注意:用户需在48小时内与公众号有过交互才可发送
     *
     * @param openid  用户的微信 openid
     * @param content 消息内容
     * @return 发送成功返回 true,失败返回 false
     */
    public boolean sendTextMessage(String openid, String content) {
        if (StringUtils.isEmpty(openid)) {
            log.warn("【WxMpUtils】sendTextMessage 失败:openid 为空");
            return false;
        }
        if (StringUtils.isEmpty(content)) {
            log.warn("【WxMpUtils】sendTextMessage 失败:content 为空");
            return false;
        }
        try {
            WxMpKefuMessage message = WxMpKefuMessage.TEXT()
                    .toUser(openid)
                    .content(content)
                    .build();
            boolean result = wxMpService.getKefuService().sendKefuMessage(message);
            log.info("【WxMpUtils】文本客服消息发送{},openid:{}", result ? "成功" : "失败", openid);
            return result;
        } catch (WxErrorException e) {
            log.error("【WxMpUtils】文本客服消息发送异常,openid:{},错误:{}", openid, e.getError(), e);
            return false;
        }
    }
 
    // -------------------------------------------------------------------------
    // 模板消息
    // -------------------------------------------------------------------------
 
    /**
     * 向指定 openid 的用户发送模板消息(含跳转URL)
     *
     * @param openid     用户的微信 openid
     * @param templateId 模板消息 ID(在微信公众平台配置)
     * @param url        点击消息后的跳转 URL,不需要跳转可传 null
     * @param dataMap    模板数据,key 为模板字段名,value 为 WxMpTemplateData(含值和颜色)
     *                   示例:{"first": new WxMpTemplateData("first", "你好", "#173177"), ...}
     * @return 发送成功返回微信返回的 msgid,失败返回 null
     */
    public String sendTemplateMessage(String openid, String templateId, String url,
                                      Map<String, WxMpTemplateData> dataMap) {
        if (StringUtils.isEmpty(openid)) {
            log.warn("【WxMpUtils】sendTemplateMessage 失败:openid 为空");
            return null;
        }
        if (StringUtils.isEmpty(templateId)) {
            log.warn("【WxMpUtils】sendTemplateMessage 失败:templateId 为空");
            return null;
        }
        try {
            WxMpTemplateMessage templateMessage = new WxMpTemplateMessage();
            templateMessage.setToUser(openid);
            templateMessage.setTemplateId(templateId);
            if (StringUtils.isNotEmpty(url)) {
                templateMessage.setUrl(url);
            }
            if (dataMap != null) {
                for (WxMpTemplateData data : dataMap.values()) {
                    templateMessage.addData(data);
                }
            }
            String msgId = wxMpService.getTemplateMsgService().sendTemplateMsg(templateMessage);
            log.info("【WxMpUtils】模板消息发送成功,openid:{},msgId:{}", openid, msgId);
            return msgId;
        } catch (WxErrorException e) {
            log.error("【WxMpUtils】模板消息发送异常,openid:{},templateId:{},错误:{}",
                    openid, templateId, e.getError(), e);
            return null;
        }
    }
 
    /**
     * 向指定 openid 的用户发送模板消息(简化版,value 不设置颜色)
     *
     * @param openid     用户的微信 openid
     * @param templateId 模板消息 ID
     * @param url        点击消息后的跳转 URL,不需要跳转可传 null
     * @param dataMap    模板数据,key 为模板字段名,value 为字段显示的文本内容
     *                   示例:{"first": "你好", "keyword1": "2024-01-01", "remark": "感谢使用"}
     * @return 发送成功返回微信返回的 msgid,失败返回 null
     */
    public String sendTemplateMessage(String openid, String templateId, String url,
                                      Map<String, String> dataMap, String defaultColor) {
        if (StringUtils.isEmpty(openid)) {
            log.warn("【WxMpUtils】sendTemplateMessage 失败:openid 为空");
            return null;
        }
        if (StringUtils.isEmpty(templateId)) {
            log.warn("【WxMpUtils】sendTemplateMessage 失败:templateId 为空");
            return null;
        }
        try {
            WxMpTemplateMessage templateMessage = new WxMpTemplateMessage();
            templateMessage.setToUser(openid);
            templateMessage.setTemplateId(templateId);
            if (StringUtils.isNotEmpty(url)) {
                templateMessage.setUrl(url);
            }
            if (dataMap != null) {
                String color = StringUtils.isEmpty(defaultColor) ? "#173177" : defaultColor;
                for (Map.Entry<String, String> entry : dataMap.entrySet()) {
                    templateMessage.addData(new WxMpTemplateData(entry.getKey(), entry.getValue(), color));
                }
            }
            String msgId = wxMpService.getTemplateMsgService().sendTemplateMsg(templateMessage);
            log.info("【WxMpUtils】模板消息发送成功,openid:{},msgId:{}", openid, msgId);
            return msgId;
        } catch (WxErrorException e) {
            log.error("【WxMpUtils】模板消息发送异常,openid:{},templateId:{},错误:{}",
                    openid, templateId, e.getError(), e);
            return null;
        }
    }
 
    // -------------------------------------------------------------------------
    // 静态工厂方法(快速构造)
    // -------------------------------------------------------------------------
 
    /**
     * 快速创建 WxMpUtils 实例
     *
     * @param appId     微信公众号 AppID
     * @param appSecret 微信公众号 AppSecret
     * @return WxMpUtils 实例
     */
    public static WxMpUtils of(String appId, String appSecret) {
        return new WxMpUtils(appId, appSecret);
    }
}