yusm 4 週間 前
コミット
c291521277

+ 93 - 17
fhKeeper/formulahousekeeper/management-crm-qrcode/src/main/java/com/management/platform/controller/WechatCallbackController.java

@@ -1,24 +1,33 @@
 package com.management.platform.controller;
 
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.fasterxml.jackson.databind.ObjectMapper;
 import com.management.platform.entity.Custom;
 import com.management.platform.entity.MiniBindUser;
 import com.management.platform.entity.User;
+import com.management.platform.entity.WechatAccount;
 import com.management.platform.service.CustomService;
 import com.management.platform.service.MiniBindUserService;
 import com.management.platform.service.UserService;
+import com.management.platform.service.WechatAccountService;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.codec.digest.DigestUtils;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.util.EntityUtils;
 import org.dom4j.Document;
 import org.dom4j.DocumentHelper;
 import org.dom4j.Element;
 import org.springframework.web.bind.annotation.*;
+import org.springframework.web.client.RestTemplate;
 
 import javax.annotation.Resource;
 import java.util.Arrays;
 import java.util.Date;
 import java.util.List;
+import java.util.Map;
 
 @RestController
 @RequestMapping("/wechat")
@@ -35,6 +44,14 @@ public class WechatCallbackController {
     @Resource
     private CustomService customService;
 
+    @Resource
+    private RestTemplate restTemplate;
+
+    @Resource
+    private WechatAccountService wechatAccountService;
+
+    private final ObjectMapper objectMapper = new ObjectMapper();
+
     // 微信配置验证接口(GET请求)
     @GetMapping("/callback")
     public String validate(@RequestParam("signature") String signature,
@@ -107,27 +124,35 @@ public class WechatCallbackController {
     private void handleSubscribe(String openId) {
         // 实现用户关注的业务逻辑
         log.info("处理用户关注逻辑: {}", openId);
-        List<MiniBindUser> miniBindUserList = miniBindUserService.list(new QueryWrapper<MiniBindUser>().eq("openid", openId));
-        if (!miniBindUserList.isEmpty()) {
-            if (customService.count(new QueryWrapper<Custom>().eq("custom_name", openId))==0){
-                MiniBindUser miniBindUser = miniBindUserList.get(0);
-                Custom custom = new Custom();
-                custom.setCustomName(openId);//用户的openId
-                custom.setIsDelete(0);
-                custom.setCreateTime(new Date());
-                if (StringUtils.isNotEmpty(miniBindUser.getUserId())) {
-                    custom.setInchargerId(miniBindUser.getUserId());
-                    User user = userService.getById(miniBindUser.getUserId());
-                    custom.setCompanyId(user != null ? user.getCompanyId() : null);
-                    customService.save(custom);
-                    log.info("新增客户成功");
+        Map<String, Object> userInfo = getUserInfo(openId, null);
+        log.info("返回的userInfo信息==>"+userInfo.toString());
+        if (userInfo.get("unionid") != null) {
+            String unionid = (String) userInfo.get("unionid");
+            List<MiniBindUser> miniBindUserList = miniBindUserService.list(new QueryWrapper<MiniBindUser>().eq("unionid",unionid ));
+            if (!miniBindUserList.isEmpty()) {
+                if (customService.count(new QueryWrapper<Custom>().eq("custom_name", unionid))==0){
+                    MiniBindUser miniBindUser = miniBindUserList.get(0);
+                    Custom custom = new Custom();
+                    custom.setCustomName(unionid);//用户的openId
+                    custom.setIsDelete(0);
+                    custom.setCreateTime(new Date());
+                    if (StringUtils.isNotEmpty(miniBindUser.getUserId())) {
+                        custom.setInchargerId(miniBindUser.getUserId());
+                        User user = userService.getById(miniBindUser.getUserId());
+                        custom.setCompanyId(user != null ? user.getCompanyId() : null);
+                        customService.save(custom);
+                        log.info("新增客户成功");
+                    }
+                }else {
+                    log.info(unionid+":系统中已存在对应的客户");
                 }
             }else {
-                log.info(openId+":系统中已存在对应的客户");
+                log.info(unionid+":对应的客户,暂未绑定相关的销售人员");
             }
         }else {
-            log.info(openId+":对应的客户,暂未绑定相关的销售人员");
+            log.info("unionid为空");
         }
+
     }
 
     private void handleUnsubscribe(String openId) {
@@ -140,8 +165,8 @@ public class WechatCallbackController {
         log.info("处理用户扫码逻辑: {}", openId);
     }
 
-    // ========== 响应消息构建方法 ==========
 
+    // ========== 响应消息构建方法 ==========
     private String successResponse(Element root) {
         return String.format(
                 "<xml>" +
@@ -195,4 +220,55 @@ public class WechatCallbackController {
                 System.currentTimeMillis() / 1000);
     }*/
 
+    public Map<String, Object> getUserInfo(String openId, String userId) {
+        String accessToken=null;
+        if (StringUtils.isNotEmpty(userId)){
+            accessToken= getAccessToken(userId);
+        }else {
+            accessToken= getAccessToken();
+        }
+        if (accessToken == null) {
+            return null;
+        }
+
+        String url = String.format(
+                "https://api.weixin.qq.com/cgi-bin/user/info?access_token=%s&openid=%s&lang=zh_CN",
+                accessToken, openId);
+
+        try (CloseableHttpClient client = HttpClients.createDefault()) {
+            HttpGet request = new HttpGet(url);
+            String response = EntityUtils.toString(client.execute(request).getEntity());
+            log.info("获取用户信息===>"+response);
+            return objectMapper.readValue(response, Map.class);
+        } catch (Exception e) {
+            e.printStackTrace();
+            log.info("获取用户信息失败==>"+e.getMessage());
+            return null;
+        }
+    }
+
+    private String getAccessToken(String userId) {
+        User user = userService.getById(userId);
+        if (user==null){
+            log.info("获取企业的微信Token时,未获取该用户");
+            return null;
+        }else {
+            WechatAccount wechatAccount = wechatAccountService.getOne(new QueryWrapper<WechatAccount>().eq("company_id", user.getCompanyId()));
+            if (wechatAccount==null){
+                log.info("该公司没有配置公众号相关的参数");
+                return null;
+            }
+            return wechatAccountService.getAccessToken(user.getCompanyId(), wechatAccount.getAppId());
+        }
+    }
+
+    private String getAccessToken() {
+        WechatAccount wechatAccount = wechatAccountService.list().get(0);
+        if (wechatAccount==null){
+            log.info("该公司没有配置公众号相关的参数");
+            return null;
+        }
+        return wechatAccountService.getAccessToken(wechatAccount.getCompanyId(), wechatAccount.getAppId());
+    }
+
 }

+ 31 - 0
fhKeeper/formulahousekeeper/management-crm-qrcode/src/main/java/com/management/platform/mapper/WechatAccountMapper.java

@@ -0,0 +1,31 @@
+package com.management.platform.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.management.platform.entity.WechatAccount;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+import org.apache.ibatis.annotations.Update;
+
+import java.time.LocalDateTime;
+
+/**
+ * <p>
+ * 微信公众号账号表 Mapper 接口
+ * </p>
+ *
+ * @author Seyason
+ * @since 2025-04-15
+ */
+public interface WechatAccountMapper extends BaseMapper<WechatAccount> {
+    @Select("SELECT * FROM wechat_account WHERE company_id = #{companyId} AND app_id = #{appId}")
+    WechatAccount findByCompanyAndApp(@Param("companyId") Integer companyId,
+                                      @Param("appId") String appId);
+
+    @Update("UPDATE wechat_account SET access_token = #{accessToken}, " +
+            "token_expire_time = #{tokenExpireTime} " +
+            "WHERE company_id = #{companyId} AND app_id = #{appId}")
+    int updateTokenInfo(@Param("companyId") Integer companyId,
+                        @Param("appId") String appId,
+                        @Param("accessToken") String accessToken,
+                        @Param("tokenExpireTime") LocalDateTime tokenExpireTime);
+}

+ 16 - 0
fhKeeper/formulahousekeeper/management-crm-qrcode/src/main/java/com/management/platform/service/WechatAccountService.java

@@ -0,0 +1,16 @@
+package com.management.platform.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.management.platform.entity.WechatAccount;
+
+/**
+ * <p>
+ * 微信公众号账号表 服务类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2025-04-15
+ */
+public interface WechatAccountService extends IService<WechatAccount> {
+    public String getAccessToken(Integer companyId, String appId) ;
+}

+ 99 - 0
fhKeeper/formulahousekeeper/management-crm-qrcode/src/main/java/com/management/platform/service/impl/WechatAccountServiceImpl.java

@@ -0,0 +1,99 @@
+package com.management.platform.service.impl;
+
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONObject;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.management.platform.entity.WechatAccount;
+import com.management.platform.mapper.WechatAccountMapper;
+import com.management.platform.service.WechatAccountService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.web.client.RestTemplate;
+
+import java.time.LocalDateTime;
+
+/**
+ * <p>
+ * 微信公众号账号表 服务实现类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2025-04-15
+ */
+@Service
+public class WechatAccountServiceImpl extends ServiceImpl<WechatAccountMapper, WechatAccount> implements WechatAccountService {
+
+    @Autowired
+    private  WechatAccountMapper wechatAccountMapper;
+    @Autowired
+    private  RestTemplate restTemplate;
+
+    // 提前5分钟刷新,避免临界点问题
+    private static final int TOKEN_EXPIRE_BUFFER = 5 ;
+
+    /**
+     * 获取AccessToken
+     * @param companyId 企业ID
+     * @param appId 公众号AppID
+     * @return AccessToken
+     */
+    public String getAccessToken(Integer companyId, String appId) {
+        // 1. 从数据库获取账号信息
+        WechatAccount account = wechatAccountMapper.findByCompanyAndApp(companyId, appId);
+        if (account == null) {
+            throw new RuntimeException("未找到对应的公众号配置");
+        }
+
+        // 2. 检查Token是否有效
+        if (isTokenValid(account)) {
+            return account.getAccessToken();
+        }
+
+        // 3. Token无效则重新获取
+        return refreshAccessToken(account);
+    }
+
+    /**
+     * 判断Token是否有效
+     */
+    private boolean isTokenValid(WechatAccount account) {
+        return account.getAccessToken() != null
+                && account.getTokenExpireTime() != null
+                && account.getTokenExpireTime().isAfter(
+                LocalDateTime.now().plusMinutes(TOKEN_EXPIRE_BUFFER));
+    }
+
+    /**
+     * 刷新AccessToken
+     */
+    private String refreshAccessToken(WechatAccount account) {
+        String url = String.format(
+                "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s",
+                account.getAppId(), account.getAppSecret());
+
+        try {
+            System.out.println("url==>"+url);
+            String response = restTemplate.getForObject(url, String.class);
+            JSONObject json = JSON.parseObject(response);
+
+            if (json.containsKey("access_token")) {
+                String newToken = json.getString("access_token");
+                int expiresIn = json.getIntValue("expires_in");
+                LocalDateTime expireTime = LocalDateTime.now().plusSeconds(expiresIn);
+
+                // 更新数据库
+                wechatAccountMapper.updateTokenInfo(
+                        account.getCompanyId(),
+                        account.getAppId(),
+                        newToken,
+                        expireTime);
+
+                return newToken;
+            } else {
+                throw new RuntimeException("获取AccessToken失败: " + response);
+            }
+        } catch (Exception e) {
+            throw new RuntimeException("调用微信API失败", e);
+        }
+    }
+}

+ 4 - 1
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/controller/WechatCallbackController.java

@@ -215,7 +215,10 @@ public class WechatCallbackController {
                         log.info("已存在custom_name为"+openId+"的客户");
                     }*/
                     MiniBindUser miniBindUser = new MiniBindUser();
-                    miniBindUser.setUserId(salesmanId).setOpenid(openId).setCreateTime(LocalDateTime.now());
+                    miniBindUser.setUserId(salesmanId)
+                            .setOpenid(openId)
+                            .setUnionid(userInfo!=null?(String) userInfo.get("unionid"):null)
+                            .setCreateTime(LocalDateTime.now());
                     miniBindUserService.save(miniBindUser);
                     log.info("用户关注服务号销售人员的二维码,绑定销售人员和用户id成功");