|
@@ -0,0 +1,106 @@
|
|
|
|
|
+package top.husj.husj_wx.service;
|
|
|
|
|
+
|
|
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
|
|
+import org.springframework.web.client.RestTemplate;
|
|
|
|
|
+import top.husj.husj_wx.utils.AccessTokenUtil;
|
|
|
|
|
+
|
|
|
|
|
+import java.util.concurrent.locks.ReentrantReadWriteLock;
|
|
|
|
|
+
|
|
|
|
|
+@Service
|
|
|
|
|
+@Slf4j
|
|
|
|
|
+public class WeChatService {
|
|
|
|
|
+
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private RestTemplate restTemplate;
|
|
|
|
|
+
|
|
|
|
|
+ // 存储最后一个发消息用户的OpenID
|
|
|
|
|
+ private String lastUserOpenId;
|
|
|
|
|
+ private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 记录最后一个发消息的用户
|
|
|
|
|
+ * @param openId 用户的OpenID
|
|
|
|
|
+ */
|
|
|
|
|
+ public void recordLastUser(String openId) {
|
|
|
|
|
+ lock.writeLock().lock();
|
|
|
|
|
+ try {
|
|
|
|
|
+ this.lastUserOpenId = openId;
|
|
|
|
|
+ log.info("已记录最后活跃用户: {}", openId);
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ lock.writeLock().unlock();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 获取最后一个发消息的用户OpenID
|
|
|
|
|
+ * @return 用户OpenID,如果没有则返回null
|
|
|
|
|
+ */
|
|
|
|
|
+ public String getLastUserOpenId() {
|
|
|
|
|
+ lock.readLock().lock();
|
|
|
|
|
+ try {
|
|
|
|
|
+ return this.lastUserOpenId;
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ lock.readLock().unlock();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 发送客服消息给指定用户
|
|
|
|
|
+ * @param openId 接收消息的用户OpenID
|
|
|
|
|
+ * @param content 消息内容
|
|
|
|
|
+ * @return 是否发送成功
|
|
|
|
|
+ */
|
|
|
|
|
+ public boolean sendCustomMessage(String openId, String content) {
|
|
|
|
|
+ String accessToken = AccessTokenUtil.getAccessToken();
|
|
|
|
|
+ if (accessToken == null || accessToken.isEmpty()) {
|
|
|
|
|
+ log.error("access_token为空,无法发送消息");
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ String url = String.format("https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=%s", accessToken);
|
|
|
|
|
+
|
|
|
|
|
+ // 构建客服消息JSON
|
|
|
|
|
+ JSONObject message = new JSONObject();
|
|
|
|
|
+ message.put("touser", openId);
|
|
|
|
|
+ message.put("msgtype", "text");
|
|
|
|
|
+
|
|
|
|
|
+ JSONObject text = new JSONObject();
|
|
|
|
|
+ text.put("content", content);
|
|
|
|
|
+ message.put("text", text);
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ String response = restTemplate.postForObject(url, message.toJSONString(), String.class);
|
|
|
|
|
+ JSONObject jsonResponse = JSONObject.parseObject(response);
|
|
|
|
|
+
|
|
|
|
|
+ int errcode = jsonResponse.getIntValue("errcode");
|
|
|
|
|
+ if (errcode == 0) {
|
|
|
|
|
+ log.info("成功发送客服消息给用户 {}: {}", openId, content);
|
|
|
|
|
+ return true;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ String errmsg = jsonResponse.getString("errmsg");
|
|
|
|
|
+ log.error("发送客服消息失败 - errcode: {}, errmsg: {}", errcode, errmsg);
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.error("发送客服消息时发生异常: ", e);
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 发送消息给最后一个活跃用户
|
|
|
|
|
+ * @param content 消息内容
|
|
|
|
|
+ * @return 是否发送成功
|
|
|
|
|
+ */
|
|
|
|
|
+ public boolean sendMessageToLastUser(String content) {
|
|
|
|
|
+ String openId = getLastUserOpenId();
|
|
|
|
|
+ if (openId == null || openId.isEmpty()) {
|
|
|
|
|
+ log.warn("没有最后活跃用户,无法发送消息");
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ return sendCustomMessage(openId, content);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|