From 70d2a5d0f9c6951b2d4cac954041ed73582ff7eb Mon Sep 17 00:00:00 2001
From: liujie <1793218484@qq.com>
Date: 星期一, 09 六月 2025 11:54:00 +0800
Subject: [PATCH] 6.9新增登录失败冻结逻辑

---
 springcloud_k8s_panzhihuazhihuishequ/common/src/main/java/com/panzhihua/common/utlis/WxXCXTempSend.java |  319 ++++++++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 279 insertions(+), 40 deletions(-)

diff --git a/springcloud_k8s_panzhihuazhihuishequ/common/src/main/java/com/panzhihua/common/utlis/WxXCXTempSend.java b/springcloud_k8s_panzhihuazhihuishequ/common/src/main/java/com/panzhihua/common/utlis/WxXCXTempSend.java
index e1c81f8..904c51c 100644
--- a/springcloud_k8s_panzhihuazhihuishequ/common/src/main/java/com/panzhihua/common/utlis/WxXCXTempSend.java
+++ b/springcloud_k8s_panzhihuazhihuishequ/common/src/main/java/com/panzhihua/common/utlis/WxXCXTempSend.java
@@ -1,28 +1,97 @@
 package com.panzhihua.common.utlis;
 
+import cn.hutool.core.util.StrUtil;
 import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
 import com.panzhihua.common.constants.SecurityConstants;
+import com.panzhihua.common.controller.BaseController;
+import com.panzhihua.common.redis.RedisUtils;
 import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Autowired;
+import org.apache.commons.fileupload.FileItem;
+import org.apache.commons.fileupload.FileItemFactory;
+import org.apache.commons.fileupload.disk.DiskFileItemFactory;
+import org.apache.http.entity.ContentType;
+import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.data.redis.core.StringRedisTemplate;
 import org.springframework.data.redis.core.ValueOperations;
 import org.springframework.stereotype.Component;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.multipart.commons.CommonsMultipartFile;
 
-import java.io.IOException;
+import javax.annotation.PostConstruct;
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.text.MessageFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
 import java.util.Map;
 import java.util.concurrent.TimeUnit;
 
 @Slf4j
 @Component
-public class WxXCXTempSend {
+public class WxXCXTempSend extends BaseController {
 
+    public static final String APP_ID = "wx118de8a734d269f0";
+    private static final String APP_SECRET = "0264342daefde5cd70a6adada09ee5b1";
     private static String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential";
+    private static String APP_IMAGE_URL = "https://www.psciio.com//idcard/8fa82cfba258498eab2fa818220fb592.jpg";
+    private static String APP_IMAGE_NAME = "5.jpg";
+    private static String WX_CALL_BACK = "https://api.weixin.qq.com/cgi-bin/getcallbackip?access_token=";
+    //2小时
+    private static final Long EXPIRE_TIME = 2L;
+    @Resource
+    private RedisTemplate redisTemplate;
+    @Resource
+    private StringRedisTemplate stringRedisTemplate;
+    @Resource
+    private RedisUtils redisUtils;
 
-    public static final String APP_ID = "wx0cef797390444b75";
-    private static final String APP_SECRET = "c7ea9aaa7e391a487e8a5b9ba61045d1";
+    private static WxXCXTempSend wxXCXTempSend;
 
-    @Autowired
-    private StringRedisTemplate redisTemplate;
+    /**
+     * url转变为 MultipartFile对象
+     *
+     * @param url
+     * @param fileName
+     * @return
+     * @throws Exception
+     */
+    private static MultipartFile createFileItem(String url, String fileName) throws Exception {
+        FileItem item = null;
+        try {
+            HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
+            conn.setReadTimeout(30000);
+            conn.setConnectTimeout(30000);
+            // 设置应用程序要从网络连接读取数据
+            conn.setDoInput(true);
+            conn.setRequestMethod("GET");
+            if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
+                InputStream is = conn.getInputStream();
+
+                FileItemFactory factory = new DiskFileItemFactory(16, null);
+                String textFieldName = "uploadfile";
+                item =
+                        factory.createItem(textFieldName, ContentType.APPLICATION_OCTET_STREAM.toString(), false, fileName);
+                OutputStream os = item.getOutputStream();
+
+                int bytesRead = 0;
+                byte[] buffer = new byte[8192];
+                while ((bytesRead = is.read(buffer, 0, 8192)) != -1) {
+                    os.write(buffer, 0, bytesRead);
+                }
+                os.close();
+                is.close();
+            }
+        } catch (IOException e) {
+            throw new RuntimeException("文件下载失败", e);
+        }
+
+        return new CommonsMultipartFile(item);
+    }
 
     /**
      * 获取小程序token,(ps:0=token获取失败)
@@ -31,33 +100,72 @@
      */
     public String getAccessToken() throws Exception {
         String accessToken = "";
-        Boolean aBoolean = redisTemplate.hasKey(SecurityConstants.APPLETS_ACCESS_TOKEN);
-        ValueOperations<String, String> valueOperations = redisTemplate.opsForValue();
-        if(aBoolean){
-            Long expire = redisTemplate.boundHashOps(SecurityConstants.APPLETS_ACCESS_TOKEN).getExpire();
-            if(expire <= 0){
-                redisTemplate.delete(SecurityConstants.APPLETS_ACCESS_TOKEN);//如果过期则删除
-                accessToken = getAppAccessToken();
-                valueOperations.set(SecurityConstants.APPLETS_ACCESS_TOKEN, accessToken,110, TimeUnit.MINUTES);
-            }else{
-                accessToken = valueOperations.get(SecurityConstants.APPLETS_ACCESS_TOKEN);
+        String appId = this.getAppId();
+        accessToken = wxXCXTempSend.stringRedisTemplate.boundValueOps("access_token:access_token:" + appId).get();
+        return accessToken;
+    }
+
+
+    public String getAccessToken(String appId) throws Exception {
+        String accessToken = "";
+        accessToken = wxXCXTempSend.stringRedisTemplate.boundValueOps("access_token:access_token:" + appId).get();
+        return accessToken;
+    }
+
+    private String validAccessToken(String accessToken, String appId, String appSecret) throws Exception {
+        if (StrUtil.isEmpty(accessToken)) {
+            //重新获取并设置到缓存 该方法暂时只用在花城
+            accessToken = getAppAccessToken(appId, appSecret);
+            wxXCXTempSend.stringRedisTemplate.opsForValue().set("access_token:access_token:" + appId, accessToken, EXPIRE_TIME, TimeUnit.HOURS);
+        } else {
+            String accessTokenUrl = WX_CALL_BACK + accessToken;
+            String result = HttpClientUtil.httpGet(accessTokenUrl, null, null);
+            Map<String, Object> resultMap = JSON.parseObject(result, Map.class);
+            //如果Access_token过期也重新获取
+            if (resultMap.containsKey("errcode")) {
+                accessToken = getAppAccessToken(appId, appSecret);
+                wxXCXTempSend.stringRedisTemplate.opsForValue().set("access_token:access_token:" + appId, accessToken, EXPIRE_TIME, TimeUnit.HOURS);
             }
-        }else{
-            accessToken = getAppAccessToken();
-            valueOperations.set(SecurityConstants.APPLETS_ACCESS_TOKEN, accessToken,110, TimeUnit.MINUTES);
         }
         return accessToken;
     }
 
-    private String getAppAccessToken() throws Exception{
+    public String getAppAccessToken(String appId, String appSecret) throws Exception {
         String accessToken = "0";
         try {
-            //此处APP_ID APP_SECRET  在微信小程序后端可见
-//            String accessTokenUrl = String.format(TEMP_URL, APP_ID, APP_SECRET);
-            String accessTokenUrl = ACCESS_TOKEN_URL + "&appid=" + APP_ID + "&secret=" + APP_SECRET;
+            log.info("获取微信token参数:appid=" + appId + ",appSecret=" + appSecret);
+            String accessTokenUrl = ACCESS_TOKEN_URL + "&appid=" + appId + "&secret=" + appSecret;
             String result = HttpClientUtil.httpGet(accessTokenUrl, null, null);
             Map<String, Object> resultMap = JSON.parseObject(result, Map.class);
-            if(resultMap.containsKey("access_token")) {
+            StringRedisTemplate redisTemplate = wxXCXTempSend.stringRedisTemplate;
+            if (resultMap.containsKey("access_token")) {
+                accessToken = resultMap.get("access_token").toString();
+                redisTemplate.opsForValue().set("access_token:access_token:" + appId, accessToken);
+            }
+            HttpServletRequest request = ServletUtils.getRequest();
+            String requestURI = request.getRequestURI();
+            //加上时间戳
+            String datetime = new SimpleDateFormat("yyyyMMdd").format(new Date());
+            //这里是 Redis key的前缀,如: sys:tabieId:表名  如果不需要去掉表名也可以
+            String key = MessageFormat.format("{0}:{1}:{2}",  "access_token_request_incr",datetime,requestURI);
+            //查询 key 是否存在, 不存在返回 1 ,存在的话则自增加1
+            redisTemplate.opsForValue().increment(key, 1);
+
+        } catch (IOException ioe) {
+            log.error("小程序http请求异常");
+            ioe.printStackTrace();
+        }
+        return accessToken;
+    }
+
+    public String getWsAccessToken() throws Exception {
+        String accessToken = "0";
+        try {
+//            log.info("获取微信token参数:appid=" + APP_ID + ",appSecret=" + APP_SECRET);
+            String accessTokenUrl = ACCESS_TOKEN_URL + "&appid=wx98d62711dfbd8425" + "&secret=97a2a10b990c2774ed279724337b5337";
+            String result = HttpClientUtil.httpGet(accessTokenUrl, null, null);
+            Map<String, Object> resultMap = JSON.parseObject(result, Map.class);
+            if (resultMap.containsKey("access_token")) {
                 accessToken = resultMap.get("access_token").toString();
             }
         } catch (IOException ioe) {
@@ -67,23 +175,154 @@
         return accessToken;
     }
 
-    public static void main(String[] args) throws Exception {
-//        String accessToken = "0";
-//        try {
-//            //此处APP_ID APP_SECRET  在微信小程序后端可见
-//            String accessTokenUrl = String.format(TEMP_URL, APP_ID, APP_SECRET);
-//            String result = HttpClientUtil.httpGet(accessTokenUrl, null, null);
-//            Map<String, Object> resultMap = JSON.parseObject(result, Map.class);
-//            if(resultMap.containsKey("access_token")) {
-//                accessToken = resultMap.get("access_token").toString();
-//            }
-//        } catch (IOException ioe) {
-//            log.error("小程序http请求异常");
-//            ioe.printStackTrace();
-//        }
-//        System.out.println(accessToken);
+    /**
+     * 获取西区社区通微信token
+     *
+     * @return 西区社区通微信token
+     * @throws Exception 异常
+     */
+    public String getXQAppAccessToken() throws Exception {
+        String accessToken = "0";
+        try {
+            // 此处APP_ID APP_SECRET 在微信小程序后端可见
+            // String accessTokenUrl = String.format(TEMP_URL, APP_ID, APP_SECRET);
+            String accessTokenUrl = ACCESS_TOKEN_URL + "&appid=" + APP_ID + "&secret=" + APP_SECRET;
+            String result = HttpClientUtil.httpGet(accessTokenUrl, null, null);
+            Map<String, Object> resultMap = JSON.parseObject(result, Map.class);
+            if (resultMap.containsKey("access_token")) {
+                accessToken = resultMap.get("access_token").toString();
+            }
+        } catch (IOException ioe) {
+            log.error("小程序http请求异常");
+            ioe.printStackTrace();
+        }
+        return accessToken;
     }
 
+    public String getMediaId(String accessToken) {
+        String mediaId = "";
+        Boolean aBoolean = redisTemplate.hasKey(SecurityConstants.APPLETS_ACCESS_MEDIA_ID);
+        ValueOperations<String, String> valueOperations = redisTemplate.opsForValue();
+        if (aBoolean) {
+            Long expireTime = Long.parseLong(valueOperations.get(SecurityConstants.APPLETS_ACCESS_MEDIA_ID_TIME));
+            if (expireTime <= System.currentTimeMillis()) {
+                redisTemplate.delete(SecurityConstants.APPLETS_ACCESS_MEDIA_ID);// 如果过期则删除
+                redisTemplate.delete(SecurityConstants.APPLETS_ACCESS_MEDIA_ID_TIME);// 如果过期则删除
+                mediaId = getAppMediaId(accessToken);
+                valueOperations.set(SecurityConstants.APPLETS_ACCESS_MEDIA_ID, mediaId);
+                valueOperations.set(SecurityConstants.APPLETS_ACCESS_MEDIA_ID_TIME,
+                        System.currentTimeMillis() + 259000000 + "");
+            } else {
+                mediaId = valueOperations.get(SecurityConstants.APPLETS_ACCESS_MEDIA_ID);
+            }
+        } else {
+            mediaId = getAppMediaId(accessToken);
+            valueOperations.set(SecurityConstants.APPLETS_ACCESS_MEDIA_ID, mediaId);
+            valueOperations.set(SecurityConstants.APPLETS_ACCESS_MEDIA_ID_TIME,
+                    System.currentTimeMillis() + 259000000 + "");
+        }
+        return mediaId;
+    }
 
+    private String getAppMediaId(String accessToken) {
+        String appMediaId = "";
+        try {
+            MultipartFile file = createFileItem(APP_IMAGE_URL, APP_IMAGE_NAME);
+            appMediaId = uploadFile(file, accessToken);
+        } catch (Exception e) {
+            log.error("上传临时图片素材失败,错误原因:" + e.getMessage());
+        }
+        return appMediaId;
+    }
+
+    /**
+     * 微信小程序临时素材上传
+     *
+     * @param file
+     * @return
+     * @throws Exception
+     * @author yixiu
+     */
+    public String uploadFile(MultipartFile file, String access_token) throws Exception {
+        String url = "https://api.weixin.qq.com/cgi-bin/media/upload?access_token=" + access_token + "&type=image";
+        String result = null;
+        String fileName = file.getOriginalFilename();
+        URL urlObj = new URL(url);
+        HttpURLConnection con = (HttpURLConnection) urlObj.openConnection();
+        con.setRequestMethod("POST");
+        con.setDoInput(true);
+        con.setDoOutput(true);
+        con.setUseCaches(false);
+        // 设置请求头信息
+        con.setRequestProperty("Connection", "Keep-Alive");
+        con.setRequestProperty("Charset", "UTF-8");
+        // 设置边界
+        String BOUNDARY = "----------" + System.currentTimeMillis();
+        con.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
+        // 请求正文信息
+        // 第一部分:
+        StringBuilder sb = new StringBuilder();
+        sb.append("--"); // 必须多两道线
+        sb.append(BOUNDARY);
+        sb.append("\r\n");
+        sb.append("Content-Disposition: form-data;name=\"media\";filename=\"" + fileName + "\"\r\n");
+        sb.append("Content-Type:application/octet-stream\r\n\r\n");
+        byte[] head = sb.toString().getBytes(StandardCharsets.UTF_8);
+        // 获得输出流
+        OutputStream out = new DataOutputStream(con.getOutputStream());
+        // 输出表头
+        out.write(head);
+        // 文件正文部分
+        // 把文件已流文件的方式 推入到url中
+        DataInputStream in = new DataInputStream(file.getInputStream());
+        int bytes = 0;
+        byte[] bufferOut = new byte[1024];
+        while ((bytes = in.read(bufferOut)) != -1) {
+            out.write(bufferOut, 0, bytes);
+        }
+        in.close();
+        // 结尾部分
+        byte[] foot = ("\r\n--" + BOUNDARY + "--\r\n").getBytes(StandardCharsets.UTF_8);// 定义最后数据分隔线
+        out.write(foot);
+        out.flush();
+        out.close();
+        StringBuffer buffer = new StringBuffer();
+        BufferedReader reader = null;
+        try {
+            // 定义BufferedReader输入流来读取URL的响应
+            reader = new BufferedReader(new InputStreamReader(con.getInputStream()));
+            String line = null;
+            while ((line = reader.readLine()) != null) {
+                buffer.append(line);
+            }
+            if (result == null) {
+                result = buffer.toString();
+            }
+        } catch (IOException e) {
+            System.out.println("发送POST请求出现异常! {}");
+            e.printStackTrace();
+            throw new IOException("数据读取异常");
+        } finally {
+            if (reader != null) {
+                reader.close();
+            }
+        }
+        // 获取到返回HTTP结果
+        Map<String, Object> map = JSONObject.parseObject(result, Map.class);
+        if (map.containsKey("media_id")) {
+            return map.get("media_id").toString();
+        }
+        System.out.println("小程序上传临时素材出错,返回信息为:    " + result);
+        return null;
+    }
+
+    @PostConstruct
+    public void init() {
+        wxXCXTempSend = this;
+        wxXCXTempSend.redisTemplate = this.redisTemplate;
+        wxXCXTempSend.stringRedisTemplate = this.stringRedisTemplate;
+        wxXCXTempSend.redisUtils = this.redisUtils;
+
+    }
 
 }

--
Gitblit v1.7.1