YueYunyun 1 год назад
Родитель
Сommit
5eb1675363

+ 133 - 0
SERVER/YanZhongXYH/xyh-system/src/main/java/cn/xyh/system/controller/wx/WxController.java

@@ -0,0 +1,133 @@
+package cn.xyh.system.controller.wx;
+
+import cn.dev33.satoken.annotation.SaIgnore;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+/**
+ * 微信授权
+ *
+ * @author Yue
+ */
+@Controller
+@Slf4j
+@SaIgnore
+@RequestMapping("wx")
+public class WxController {
+    // 与接口配置信息中的Token要一致
+    private static final String WECHAT_TOKEN = "WX9IWB8NET";
+
+    @RequestMapping("/checkToken")
+    public void get(HttpServletRequest request, HttpServletResponse response) throws Exception {
+
+        log.info("========checkToken Controller========= ");
+        boolean isGet = "get".equalsIgnoreCase(request.getMethod());
+        PrintWriter print;
+        if (isGet) {
+            // 微信加密签名
+            String signature = request.getParameter("signature");
+            // 时间戳
+            String timestamp = request.getParameter("timestamp");
+            // 随机数
+            String nonce = request.getParameter("nonce");
+            // 随机字符串
+            String echoStr = request.getParameter("echostr");
+            // 通过检验signature对请求进行校验,若校验成功则原样返回echostr,表示接入成功,否则接入失败
+            if (signature != null && checkSignature(signature, timestamp, nonce)) {
+                try {
+                    print = response.getWriter();
+                    print.write(echoStr);
+                    print.flush();
+                    log.info("========checkToken success ========= ");
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            } else {
+                log.error("========checkToken failed========= ");
+            }
+        } else {
+            log.error("========checkToken failed:Only support Get Method =========");
+        }
+    }
+
+    /**
+     * 验证签名
+     *
+     * @param signature 签名
+     * @param timestamp 时间戳
+     * @param nonce     随机字符串
+     * @return 是否验证成功
+     */
+    public static boolean checkSignature(String signature, String timestamp, String nonce) {
+        String[] arr = new String[]{WECHAT_TOKEN, timestamp, nonce};
+        // 将token、timestamp、nonce三个参数进行字典序排序
+        // Arrays.sort(arr);
+        sort(arr);
+        StringBuilder content = new StringBuilder();
+        for (String s : arr) {
+            content.append(s);
+        }
+        MessageDigest md;
+        String tmpStr = null;
+
+        try {
+            md = MessageDigest.getInstance("SHA-1");
+            // 将三个参数字符串拼接成一个字符串进行sha1加密
+            byte[] digest = md.digest(content.toString().getBytes());
+            tmpStr = byteToStr(digest);
+        } catch (NoSuchAlgorithmException e) {
+            e.printStackTrace();
+        }
+        content = null;
+        // 将sha1加密后的字符串可与signature对比,标识该请求来源于微信
+        return tmpStr != null && tmpStr.equals(signature.toUpperCase());
+    }
+
+    /**
+     * 将字节数组转换为十六进制字符串
+     *
+     * @param byteArray 字节数组
+     */
+    private static String byteToStr(byte[] byteArray) {
+        StringBuilder strDigest = new StringBuilder();
+        for (byte b : byteArray) {
+            strDigest.append(byteToHexStr(b));
+        }
+        return strDigest.toString();
+    }
+
+    /**
+     * 将字节转换为十六进制字符串
+     *
+     * @param mByte 字节
+     */
+    private static String byteToHexStr(byte mByte) {
+        char[] Digit = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
+        char[] tempArr = new char[2];
+        tempArr[0] = Digit[(mByte >>> 4) & 0X0F];
+        tempArr[1] = Digit[mByte & 0X0F];
+        String s = new String(tempArr);
+        return s;
+    }
+
+    public static void sort(String a[]) {
+        for (int i = 0; i < a.length - 1; i++) {
+            for (int j = i + 1; j < a.length; j++) {
+                if (a[j].compareTo(a[i]) < 0) {
+                    String temp = a[i];
+                    a[i] = a[j];
+                    a[j] = temp;
+                }
+            }
+        }
+    }
+
+}

+ 14 - 0
SERVER/YanZhongXYH/xyh-system/src/main/java/cn/xyh/wx/domain/dto/WxAccessTokenDto.java

@@ -0,0 +1,14 @@
+package cn.xyh.wx.domain.dto;
+
+import lombok.Data;
+
+/**
+ * @author Yue
+ */
+@Data
+public class WxAccessTokenDto {
+    private String access_token;
+    private Integer expires_in;
+    private String errcode;
+    private String errmsg;
+}

+ 18 - 0
SERVER/YanZhongXYH/xyh-system/src/main/java/cn/xyh/wx/domain/vo/WxMssVo.java

@@ -0,0 +1,18 @@
+package cn.xyh.wx.domain.vo;
+
+import lombok.Data;
+
+import java.util.Map;
+
+/**
+ * @author Yue
+ */
+@Data
+public class WxMssVo {
+    private String touser;//用户openid
+    private String template_id;//模版id
+    private String page = "pages/index/index";//默认跳到小程序首页
+    private String form_id;//收集到的用户formid
+    //    private String emphasis_keyword = "keyword1.DATA";//放大那个推送字段
+    private Map<String, WxTemplateDataVo> data;//推送文字
+}

+ 12 - 0
SERVER/YanZhongXYH/xyh-system/src/main/java/cn/xyh/wx/domain/vo/WxTemplateDataVo.java

@@ -0,0 +1,12 @@
+package cn.xyh.wx.domain.vo;
+
+import lombok.Data;
+
+/**
+ * @author Yue
+ */
+@Data
+public class WxTemplateDataVo {
+    //字段值例如:keyword1:订单类型,keyword2:下单金额,keyword3:配送地址,keyword4:取件地址,keyword5备注
+    private String value;//依次排下去
+}

+ 102 - 0
SERVER/YanZhongXYH/xyh-system/src/main/java/cn/xyh/wx/service/WeChatService.java

@@ -0,0 +1,102 @@
+package cn.xyh.wx.service;
+
+import cn.hutool.http.HttpUtil;
+import cn.hutool.json.JSONUtil;
+import cn.xyh.common.config.WxAppConfig;
+import cn.xyh.common.exception.user.UserException;
+import cn.xyh.wx.domain.dto.WxAccessTokenDto;
+import cn.xyh.wx.domain.vo.WxMssVo;
+import cn.xyh.wx.domain.vo.WxTemplateDataVo;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.util.StringUtils;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@RequiredArgsConstructor
+@Slf4j
+@Service
+public class WeChatService {
+
+    private final WxAppConfig wxAppConfig;
+
+
+    /**
+     * @param access_token app的token
+     * @param openid       用户openid
+     * @param formId       表单ID
+     * @param templateId   模板ID
+     * @param keywords     {与模板字段一一对应}
+     */
+    public String pushOneUser(String access_token, String openid, String formId, String templateId, String[] keywords) {
+
+        //如果access_token为空则从新获取
+        if (StringUtils.isEmpty(access_token)) {
+            access_token = getAccess_token();
+        }
+        String url = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send" + "?access_token=" + access_token;
+
+        //拼接推送的模版
+        WxMssVo wxMssVo = new WxMssVo();
+        wxMssVo.setTouser(openid);//用户openid
+        wxMssVo.setForm_id(formId);//formId
+        wxMssVo.setTemplate_id(templateId);//模版id
+        Map<String, WxTemplateDataVo> m = new HashMap<>();
+
+        //封装数据
+        if (keywords.length > 0) {
+            for (int i = 1; i <= keywords.length; i++) {
+                WxTemplateDataVo keyword = new WxTemplateDataVo();
+                keyword.setValue(keywords[i - 1]);
+                m.put("keyword" + i, keyword);
+            }
+            wxMssVo.setData(m);
+        } else {
+            log.error("keywords长度为空");
+            return null;
+        }
+        String data = HttpUtil.post(url, (Map<String, Object>) wxMssVo);
+        log.info("小程序推送结果" + data);
+        return data;
+    }
+
+    /*
+     * 获取access_token
+     * appid和appsecret到小程序后台获取,当然也可以让小程序开发人员给你传过来
+     * */
+    public String getAccess_token() {
+        //获取access_token
+        String url = cn.xyh.common.utils.StringUtils.format(
+                "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={}&secret={}", wxAppConfig.getAppId(), wxAppConfig.getAppSecret());
+
+        String data = HttpUtil.get(url);
+        log.info("微信获取获取openid和unionid,返回结果:{}", data);
+        try {
+            WxAccessTokenDto dto = JSONUtil.toBean(data, WxAccessTokenDto.class);
+            if (dto.getErrcode() != null) {
+                String msg = "获取access_token异常,代码:" + dto.getErrcode() + "," + dto.getErrmsg();
+                log.error(msg);
+                throw new UserException(msg);
+            }
+            return dto.getAccess_token();
+
+        } catch (Exception e) {
+            log.error("获取access_token异常", e);
+            throw new UserException("获取access_token异常");
+        }
+
+    }
+
+   /* public static void main(String[] args) {
+        System.out.println(new WeChatService().getAccess_token());
+
+        WeChatService weChatUtil = new WeChatService();
+        String values[] = {"Jack方", "2019-5-8 10:10:10", "xxx有限公司", "JAVA开发", "xx区xx广场xx号", "请带好入职材料"};
+        weChatUtil.pushOneUser(weChatUtil.getAccess_token()
+                , "o_fh25E0IufW7NIpezUReODfVH68", "ec76b8b81cd04cf6b464bb0adf309d3b", "zv0IsYDpJxgKWLHGUy8FEv0ajtJqkfhWTsFWiM7zzSU"
+                , values);
+    }*/
+}
+