Parcourir la source

新增消息发送前端页面

hsj il y a 1 mois
Parent
commit
4aad0984e0

+ 0 - 5
src/main/java/top/husj/husj_wx/Application.java

@@ -13,9 +13,4 @@ public class Application {
     public static void main(String[] args) {
         SpringApplication.run(Application.class, args);
     }
-
-    @Bean
-    public RestTemplate restTemplate() {
-        return new RestTemplate();
-    }
 }

+ 15 - 9
src/main/java/top/husj/husj_wx/controller/WeChatController.java

@@ -68,20 +68,26 @@ public class WeChatController {
         );
     }
 
-    // 3. 发送消息给最后一个活跃用户 (GET)
+    // 3. 发送消息给指定用户 (GET)
     @GetMapping("/send")
-    public ResponseEntity<String> sendMessageToLastUser(@RequestParam("msg") String msg) {
-        log.info("收到发送消息请求,消息内容: {}", msg);
+    public ResponseEntity<String> sendMessage(
+            @RequestParam("openId") String openId,
+            @RequestParam("msg") String msg) {
+        log.info("收到发送消息请求 - openId: {}, 消息内容: {}", openId, msg);
 
-        String lastUserOpenId = weChatService.getLastUserOpenId();
-        if (lastUserOpenId == null || lastUserOpenId.isEmpty()) {
-            log.warn("暂无活跃用户,无法发送消息");
-            return ResponseEntity.badRequest().body("暂无活跃用户,请先通过公众号发送一条消息");
+        if (openId == null || openId.trim().isEmpty()) {
+            log.warn("openId为空,无法发送消息");
+            return ResponseEntity.badRequest().body("openId不能为空");
         }
 
-        boolean success = weChatService.sendMessageToLastUser(msg);
+        if (msg == null || msg.trim().isEmpty()) {
+            log.warn("消息内容为空");
+            return ResponseEntity.badRequest().body("消息内容不能为空");
+        }
+
+        boolean success = weChatService.sendCustomMessage(openId, msg);
         if (success) {
-            log.info("成功发送消息给最后活跃用户: {}", lastUserOpenId);
+            log.info("成功发送消息给用户: {}", openId);
             return ResponseEntity.ok("消息发送成功");
         } else {
             log.error("发送消息失败");

+ 2 - 0
src/main/java/top/husj/husj_wx/properties/WeChatProperties.java

@@ -15,4 +15,6 @@ public class WeChatProperties {
     private String appsecret;
     @Value("${wechat.encodingaeskey}")
     private String encodingAESKey;
+    @Value("${wechat.templateId}")
+    private String templateId;
 }

+ 10 - 0
src/main/java/top/husj/husj_wx/service/UserService.java

@@ -1,5 +1,6 @@
 package top.husj.husj_wx.service;
 
+import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.IService;
 import top.husj.husj_wx.entity.model.User;
 
@@ -16,4 +17,13 @@ public interface UserService extends IService<User> {
      * @return
      */
     User getUserByOpenId(String openId, Boolean searchDb);
+
+    /**
+     * 分页查询用户,支持按name模糊搜索
+     * @param page 页码 (从1开始)
+     * @param size 每页大小
+     * @param name 用户名称 (可选,用于模糊搜索)
+     * @return
+     */
+    IPage<User> searchUsers(int page, int size, String name);
 }

+ 76 - 1
src/main/java/top/husj/husj_wx/service/WeChatService.java

@@ -71,8 +71,17 @@ public class WeChatService {
         text.put("content", content);
         message.put("text", text);
 
+
         try {
-            String response = restTemplate.postForObject(url, message.toJSONString(), String.class);
+            // 设置请求头,确保使用UTF-8编码
+            org.springframework.http.HttpHeaders headers = new org.springframework.http.HttpHeaders();
+            headers.setContentType(org.springframework.http.MediaType.APPLICATION_JSON);
+            headers.set("Accept-Charset", "UTF-8");
+            
+            org.springframework.http.HttpEntity<String> entity = 
+                new org.springframework.http.HttpEntity<>(message.toJSONString(), headers);
+            
+            String response = restTemplate.postForObject(url, entity, String.class);
             JSONObject jsonResponse = JSONObject.parseObject(response);
             
             int errcode = jsonResponse.getIntValue("errcode");
@@ -103,4 +112,70 @@ public class WeChatService {
         }
         return sendCustomMessage(openId, content);
     }
+
+    /**
+     * 发送模板消息给指定用户
+     * 模板格式: 你好,{{name.DATA}},{{content.DATA}}
+     * @param openId 接收消息的用户OpenID
+     * @param name 用户名称
+     * @param content 消息内容
+     * @return 是否发送成功
+     */
+    public boolean sendTemplateMessage(String openId, String name, String content) {
+        String accessToken = AccessTokenUtil.getAccessToken();
+        if (accessToken == null || accessToken.isEmpty()) {
+            log.error("access_token为空,无法发送模板消息");
+            return false;
+        }
+
+        // 从配置中获取templateId (需要注入WeChatProperties)
+        String url = String.format("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=%s", accessToken);
+
+        // 构建模板消息JSON
+        JSONObject message = new JSONObject();
+        message.put("touser", openId);
+        message.put("template_id", "cQevVsdm6hLYMGKcNv7KVr8OtYbYVA8nNYx4qQ2nWkE");
+        message.put("url", "https://www.baidu.com"); // 点击跳转到百度
+
+        // 构建模板数据
+        JSONObject data = new JSONObject();
+        
+        JSONObject nameData = new JSONObject();
+        nameData.put("value", name);
+        nameData.put("color", "#173177");
+        data.put("name", nameData);
+
+        JSONObject contentData = new JSONObject();
+        contentData.put("value", content);
+        contentData.put("color", "#173177");
+        data.put("content", contentData);
+
+        message.put("data", data);
+
+        try {
+            // 设置请求头,确保使用UTF-8编码
+            org.springframework.http.HttpHeaders headers = new org.springframework.http.HttpHeaders();
+            headers.setContentType(org.springframework.http.MediaType.APPLICATION_JSON);
+            headers.set("Accept-Charset", "UTF-8");
+            
+            org.springframework.http.HttpEntity<String> entity = 
+                new org.springframework.http.HttpEntity<>(message.toJSONString(), headers);
+            
+            String response = restTemplate.postForObject(url, entity, String.class);
+            JSONObject jsonResponse = JSONObject.parseObject(response);
+            
+            int errcode = jsonResponse.getIntValue("errcode");
+            if (errcode == 0) {
+                log.info("成功发送模板消息给用户 {}: name={}, content={}", openId, name, 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;
+        }
+    }
 }

+ 15 - 0
src/main/java/top/husj/husj_wx/service/impl/UserServiceImpl.java

@@ -1,6 +1,7 @@
 package top.husj.husj_wx.service.impl;
 
 import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import jakarta.annotation.PostConstruct;
 import lombok.RequiredArgsConstructor;
@@ -73,4 +74,18 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
         user.setName(name);
         return user;
     }
+
+    @Override
+    public IPage<User> searchUsers(int page, int size, String name) {
+        com.baomidou.mybatisplus.extension.plugins.pagination.Page<User> pageParam = 
+            new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(page, size);
+        
+        if (name != null && !name.trim().isEmpty()) {
+            return lambdaQuery()
+                .like(User::getName, name.trim())
+                .page(pageParam);
+        } else {
+            return lambdaQuery().page(pageParam);
+        }
+    }
 }

+ 6 - 0
src/main/resources/application.yml

@@ -8,6 +8,11 @@ spring:
     password: 15629747218hsjH
   jackson:
     time-zone: Asia/Shanghai
+  http:
+    encoding:
+      charset: UTF-8
+      enabled: true
+      force: true
 server:
   servlet:
     context-path: /wechat
@@ -18,3 +23,4 @@ wechat:
   appid: wxebbc42cc41337ad6
   appsecret: b0e5198cd442efe767f473f1445bd162
   encodingAESKey: TAuWfJHftr4CmGtLe8aHwkA9JVaEMCA3VoQi9VhLVpD
+  templateId: cQevVsdm6hLYMGKcNv7KVr8OtYbYVA8nNYx4qQ2nWkE