Browse Source

接入微信,用户绑定,模板消息推送

liusw 7 years ago
parent
commit
07a8e58d8a

+ 19 - 0
src/main/java/com/uas/platform/b2c/common/weixin/Readme.md

@@ -0,0 +1,19 @@
+## name
+
+weixin
+
+## 名称
+
+微信
+
+## 创建人
+
+liusw
+
+## 创建时间
+
+2018年5月29日14:22:32
+
+## 说明
+
+用户绑定微信

+ 105 - 0
src/main/java/com/uas/platform/b2c/common/weixin/contoller/WeChatController.java

@@ -0,0 +1,105 @@
+package com.uas.platform.b2c.common.weixin.contoller;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.uas.platform.b2c.common.account.model.User;
+import com.uas.platform.b2c.common.weixin.model.MessageModel;
+import com.uas.platform.b2c.common.weixin.model.TemplateData;
+import com.uas.platform.b2c.common.weixin.service.WeChatService;
+import com.uas.platform.b2c.common.weixin.util.CheckoutUtil;
+import com.uas.platform.b2c.common.weixin.util.WeChatUtil;
+import com.uas.platform.b2c.fa.payment.utils.StringUtils;
+import com.uas.sso.common.util.HttpUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.ui.Model;
+import org.springframework.ui.ModelMap;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.List;
+
+/**
+ * @author liusw
+ * @create 2018-05-29 10:21
+ * @desc 微信登录controller
+ **/
+@RestController
+@RequestMapping("/wx")
+public class WeChatController {
+
+
+    @Autowired
+    private WeChatService weChatService;
+
+    @RequestMapping(value = "/check", method = RequestMethod.GET)
+    public void wenxinCheck(Model model, HttpServletRequest request, HttpServletResponse response) {
+        // 微信加密签名
+        String signature = request.getParameter("signature");
+        // 时间戳
+        String timestamp = request.getParameter("timestamp");
+        // 随机数
+        String nonce = request.getParameter("nonce");
+        // 随机字符串
+        String echostr = request.getParameter("echostr");
+        PrintWriter print;
+        // 通过检验signature对请求进行校验,若校验成功则原样返回echostr,表示接入成功,否则接入失败
+        if (signature != null && CheckoutUtil.checkSignature(signature, timestamp, nonce)) {
+            try {
+                print = response.getWriter();
+                print.write(echostr);
+                print.flush();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+//    /**
+//     * 微信授权,获取code
+//     * @return
+//     */
+//    @RequestMapping("/wxLoginPage")
+//    public ModelMap loginPage(HttpServletRequest request) {
+//        ModelMap data = new ModelMap();
+//        String redirect_url = "http://a2v86u.natappfree.cc";
+//        String url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect";
+//        url = url.replace("APPID", appID);
+//        url = url.replace("REDIRECT_URI", redirect_url + "/weChat/pcAuth");
+//        url = url.replace("SCOPE", "snsapi_userinfo");
+//        url = url.replace("STATE", request.getSession().getId());
+//        data.put("sessionId", request.getSession().getId());
+//        data.put("url", url);
+//        System.out.println(url);
+//        return data;
+//    }
+
+    /**
+     * 用户微信授权成功返回接口
+     * @param code 用于获取AccessToken
+     * @param state 获取code的state参数
+     * @return
+     */
+    @RequestMapping(value = "/getWxUserInfo", method = RequestMethod.GET)
+    public ModelMap getWxUserInfo(String code,String state) {
+        return weChatService.getWxUserInfo(code, state);
+    }
+
+    /**
+     * 发送模板消息
+     * @return
+     */
+    @RequestMapping(value = "/sendTemplateMessage", method = RequestMethod.POST)
+    public ModelMap sendTemplateMessage(List<MessageModel> messages){
+        return weChatService.sendTemplateMessage(messages);
+    }
+
+    @RequestMapping(value = "/bindUser", method = RequestMethod.POST)
+    public ModelMap bindUser(User user){
+        return weChatService.bindUser(user);
+    }
+}

+ 184 - 0
src/main/java/com/uas/platform/b2c/common/weixin/model/MessageModel.java

@@ -0,0 +1,184 @@
+package com.uas.platform.b2c.common.weixin.model;
+
+/**
+ * @author liusw
+ * @date 2018-05-29 20:14
+ */
+public class MessageModel {
+    /**
+     * 消息类型
+     */
+    private String type;
+    /**
+     * 消息内容
+     */
+    private String content;
+    /**
+     * 备注
+     */
+    private String remark;
+    /**
+     * 来源id
+     */
+    private Long sourceId;
+    /**
+     * 消息接收者uu
+     */
+    private Long receiverUu;
+    /**
+     * 消息接收者企业uu
+     */
+    private Long receiverEnuu;
+    /**
+     * 消息发送者
+     */
+    private Long senderUu;
+    /**
+     * 消息发送者企业uu
+     */
+    private Long senderEnuu;
+    /**
+     * 来源应用
+     */
+    private String producerApp;
+    /**
+     * 消费类型(所有应用共享:"PUBLIC",单个应用独享:"SINGLE",多个应用共享:"MULTI")
+     */
+    private String consumerType;
+    /**
+     * 推送方式类型
+     * 邮件、短信、IM:"MAIL_AND_SM_AND_IM"
+     * 邮件、短信:"MAIL_AND_SM"
+     * 邮件、IM:"MAIL_AND_IM"
+     * 短信、IM:"SM_AND_IM"
+     * 邮件:"MAIL"
+     * 短信:"SM"
+     * IM:"IM"
+     * 不发送:"DONT_SEND"
+     */
+    private String smsType;
+    /**
+     * 邮件模板id
+     */
+    private String mailTemplate;
+    /**
+     * 短息模板id
+     */
+    private String smTemplate;
+    /**
+     * 接收应用(以","拼接应用名称)
+     */
+    private String consumerApp;
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public String getContent() {
+        return content;
+    }
+
+    public void setContent(String content) {
+        this.content = content;
+    }
+
+    public String getRemark() {
+        return remark;
+    }
+
+    public void setRemark(String remark) {
+        this.remark = remark;
+    }
+
+    public Long getReceiverUu() {
+        return receiverUu;
+    }
+
+    public void setReceiverUu(Long receiverUu) {
+        this.receiverUu = receiverUu;
+    }
+
+    public Long getReceiverEnuu() {
+        return receiverEnuu;
+    }
+
+    public void setReceiverEnuu(Long receiverEnuu) {
+        this.receiverEnuu = receiverEnuu;
+    }
+
+    public Long getSenderUu() {
+        return senderUu;
+    }
+
+    public void setSenderUu(Long senderUu) {
+        this.senderUu = senderUu;
+    }
+
+    public Long getSenderEnuu() {
+        return senderEnuu;
+    }
+
+    public void setSenderEnuu(Long senderEnuu) {
+        this.senderEnuu = senderEnuu;
+    }
+
+    public String getProducerApp() {
+        return producerApp;
+    }
+
+    public void setProducerApp(String producerApp) {
+        this.producerApp = producerApp;
+    }
+
+    public String getConsumerType() {
+        return consumerType;
+    }
+
+    public void setConsumerType(String consumerType) {
+        this.consumerType = consumerType;
+    }
+
+    public String getSmsType() {
+        return smsType;
+    }
+
+    public void setSmsType(String smsType) {
+        this.smsType = smsType;
+    }
+
+    public String getMailTemplate() {
+        return mailTemplate;
+    }
+
+    public void setMailTemplate(String mailTemplate) {
+        this.mailTemplate = mailTemplate;
+    }
+
+    public String getSmTemplate() {
+        return smTemplate;
+    }
+
+    public void setSmTemplate(String smTemplate) {
+        this.smTemplate = smTemplate;
+    }
+
+    public String getConsumerApp() {
+        return consumerApp;
+    }
+
+    public void setConsumerApp(String consumerApp) {
+        this.consumerApp = consumerApp;
+    }
+
+    public Long getSourceId() {
+        return sourceId;
+    }
+
+    public void setSourceId(Long sourceId) {
+        this.sourceId = sourceId;
+    }
+}

+ 48 - 0
src/main/java/com/uas/platform/b2c/common/weixin/model/TemplateData.java

@@ -0,0 +1,48 @@
+package com.uas.platform.b2c.common.weixin.model;
+
+import java.util.List;
+
+/**
+ * @author liusw
+ * @date 2018-05-29 19:25
+ */
+public class TemplateData {
+    /**
+     * 头部信息
+     */
+    private TemplateDataDetail first;
+
+    /**
+     * 关键字信息
+     */
+    private List<TemplateDataDetail> keywords;
+
+    /**
+     * 备注
+     */
+    private TemplateDataDetail remark;
+
+    public TemplateDataDetail getFirst() {
+        return first;
+    }
+
+    public void setFirst(TemplateDataDetail first) {
+        this.first = first;
+    }
+
+    public List<TemplateDataDetail> getKeywords() {
+        return keywords;
+    }
+
+    public void setKeywords(List<TemplateDataDetail> keywords) {
+        this.keywords = keywords;
+    }
+
+    public TemplateDataDetail getRemark() {
+        return remark;
+    }
+
+    public void setRemark(TemplateDataDetail remark) {
+        this.remark = remark;
+    }
+}

+ 33 - 0
src/main/java/com/uas/platform/b2c/common/weixin/model/TemplateDataDetail.java

@@ -0,0 +1,33 @@
+package com.uas.platform.b2c.common.weixin.model;
+
+/**
+ * @author liusw
+ * @date 2018-05-29 19:26
+ */
+public class TemplateDataDetail {
+    /**
+     * 值
+     */
+    private String value;
+
+    /**
+     * 颜色
+     */
+    private String color;
+
+    public String getValue() {
+        return value;
+    }
+
+    public void setValue(String value) {
+        this.value = value;
+    }
+
+    public String getColor() {
+        return color;
+    }
+
+    public void setColor(String color) {
+        this.color = color;
+    }
+}

+ 61 - 0
src/main/java/com/uas/platform/b2c/common/weixin/model/TemplateMessage.java

@@ -0,0 +1,61 @@
+package com.uas.platform.b2c.common.weixin.model;
+
+import java.util.List;
+
+/**
+ * @author liusw
+ * @date 2018-05-29 19:17
+ */
+public class TemplateMessage {
+    /**
+     * 接受openid
+     */
+    private String touser;
+
+    /**
+     * 模板Id
+     */
+    private String templateId;
+
+    /**
+     * 模板跳转地址
+     */
+    private String url;
+
+    /**
+     * 模板消息
+     */
+    private List<TemplateData> data;
+
+    public String getTouser() {
+        return touser;
+    }
+
+    public void setTouser(String touser) {
+        this.touser = touser;
+    }
+
+    public String getTemplateId() {
+        return templateId;
+    }
+
+    public void setTemplateId(String templateId) {
+        this.templateId = templateId;
+    }
+
+    public String getUrl() {
+        return url;
+    }
+
+    public void setUrl(String url) {
+        this.url = url;
+    }
+
+    public List<TemplateData> getData() {
+        return data;
+    }
+
+    public void setData(List<TemplateData> data) {
+        this.data = data;
+    }
+}

+ 36 - 0
src/main/java/com/uas/platform/b2c/common/weixin/service/WeChatService.java

@@ -0,0 +1,36 @@
+package com.uas.platform.b2c.common.weixin.service;
+
+import com.uas.platform.b2c.common.account.model.User;
+import com.uas.platform.b2c.common.weixin.model.MessageModel;
+import org.springframework.ui.ModelMap;
+
+import java.util.List;
+
+/**
+ * @author liusw
+ * @date 2018-05-30 9:24
+ */
+public interface WeChatService {
+
+    /**
+     * 获取微信用户信息
+     * @param code
+     * @param state
+     * @return
+     */
+    ModelMap getWxUserInfo(String code, String state);
+
+    /**
+     * 发送模板消息
+     * @param messages
+     * @return
+     */
+    ModelMap sendTemplateMessage(List<MessageModel> messages);
+
+    /**
+     * 绑定用户
+     * @param user
+     * @return
+     */
+    ModelMap bindUser(User user);
+}

+ 145 - 0
src/main/java/com/uas/platform/b2c/common/weixin/service/impl/WeChatServiceImpl.java

@@ -0,0 +1,145 @@
+package com.uas.platform.b2c.common.weixin.service.impl;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.uas.platform.b2c.common.account.dao.UserDao;
+import com.uas.platform.b2c.common.account.model.User;
+import com.uas.platform.b2c.common.weixin.model.MessageModel;
+import com.uas.platform.b2c.common.weixin.model.TemplateData;
+import com.uas.platform.b2c.common.weixin.model.TemplateMessage;
+import com.uas.platform.b2c.common.weixin.service.WeChatService;
+import com.uas.platform.b2c.common.weixin.util.WeChatUtil;
+import com.uas.platform.core.exception.IllegalOperatorException;
+import com.uas.sso.common.util.HttpUtil;
+import com.uas.sso.entity.UserView;
+import com.uas.sso.util.AccountUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.ui.ModelMap;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.StringUtils;
+
+import java.util.List;
+
+/**
+ * @author liusw
+ * @date 2018-05-30 9:24
+ */
+@Service
+public class WeChatServiceImpl implements WeChatService{
+
+    @Autowired
+    private UserDao userDao;
+
+    @Override
+    public ModelMap getWxUserInfo(String code, String state) {
+        ModelMap result = new ModelMap();
+        if (!StringUtils.isEmpty(code)) {
+            JSONObject userInfo = getAccessTokenByCode(code);
+            result.put("nickname", userInfo.getString("nickname"));
+            result.put("headimgurl", userInfo.getString("headimgurl"));
+            String openid = userInfo.getString("openid");
+            result.put("openid", openid);
+            // todo 检查当前用户是否绑定
+            result.put("status", 0);
+        }
+        return result;
+    }
+
+    @Override
+    public ModelMap sendTemplateMessage(List<MessageModel> messages) {
+        ModelMap result = new ModelMap();
+        String url = WeChatUtil.GET_ACCESS_TOKEN;
+        url = url.replace("APPID", WeChatUtil.APPID);
+        url = url.replace("SECRET", WeChatUtil.APPSECRET);
+        try {
+            HttpUtil.ResponseWrap res = HttpUtil.doGet(url);
+            JSONObject jsonObject = JSON.parseObject(res.getContent());
+            String access_token = jsonObject.getString("access_token");
+            String sendTemplateUrl = WeChatUtil.GET_ACCESS_TOKEN.replace("ACCESS_TOKEN", access_token);
+            TemplateMessage templateMessage = new TemplateMessage();
+            templateMessage.setTemplateId(WeChatUtil.INQUIRY_TEMPLATE_ID);
+            for (MessageModel messageModel : messages) {
+                User user= userDao.findOne(messageModel.getReceiverUu());
+//                String jsonstr = array.toString();
+//                HttpUtil.doPost(sendTemplateUrl, jsonstr);
+            }
+            result.put("success", true);
+            return result;
+        } catch (Exception e) {
+            e.printStackTrace();
+            result.put("success", false);
+            result.put("message", e.getMessage());
+            return result;
+        }
+    }
+
+    @Override
+    public ModelMap bindUser(User user) {
+        ModelMap result = new ModelMap();
+        // 账户中心校验手机号和密码是否正确
+        if (StringUtils.isEmpty(user) || StringUtils.isEmpty(user.getUserTel()) || StringUtils.isEmpty(user.getUserPwd())) {
+            throw new IllegalOperatorException("信息不完整!");
+        }
+        // 是否存在用户信息
+        List<User> oldUsers = userDao.findUserByUserTel(user.getUserTel());
+        if (CollectionUtils.isEmpty(oldUsers)) {
+            throw new IllegalOperatorException("未找到用户信息");
+        }
+        UserView userView = new UserView();
+        userView.setMobile(user.getUserTel());
+        userView.setPassword(user.getUserPwd());
+        boolean pass = false;
+        try {
+            pass = AccountUtils.fuzzyCheckPassword(userView);
+            if (!pass) {
+                throw new IllegalOperatorException("手机号或密码不正确");
+            }
+            user = oldUsers.get(0);
+            result.put("success", true);
+            return result;
+        } catch (Exception e) {
+            e.printStackTrace();
+            result.put("success", false);
+            result.put("message", e.getMessage());
+            return result;
+        }
+    }
+
+    /**
+     * 通过code获取用户openId
+     * @param code
+     */
+    private JSONObject getAccessTokenByCode(String code) {
+        String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
+        url = url.replace("APPID", WeChatUtil.APPID);
+        url = url.replace("SECRET", WeChatUtil.APPSECRET);
+        url = url.replace("CODE", code);
+        try {
+            HttpUtil.ResponseWrap res = HttpUtil.doGet(url);
+            JSONObject jsonObject = JSON.parseObject(res.getContent());
+            String accessToken = jsonObject.getString("access_token");
+            String openId = jsonObject.getString("openid");
+            String refreshToken = jsonObject.getString("refresh_token");
+            JSONObject userInfo = getUserInfo(accessToken, openId);
+            return userInfo;
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    private JSONObject getUserInfo(String accessToken, String openId) {
+        String url = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";
+        url = url.replace("ACCESS_TOKEN", accessToken);
+        url = url.replace("OPENID", openId);
+        try {
+            HttpUtil.ResponseWrap res = HttpUtil.doGet(url);
+            JSONObject jsonObject = JSON.parseObject(res.getContent());
+            return jsonObject;
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+}

+ 89 - 0
src/main/java/com/uas/platform/b2c/common/weixin/util/CheckoutUtil.java

@@ -0,0 +1,89 @@
+package com.uas.platform.b2c.common.weixin.util;
+
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+/**
+ * @author wangmh
+ * @create 2018-05-24 14:28
+ * @desc 第三方校验
+ **/
+public class CheckoutUtil {
+    /**
+     *  与接口配置信息中的Token要一致
+     */
+    private static String token = "usoftmall";
+
+    /**
+     * 验证签名
+     *
+     * @param signature
+     * @param timestamp
+     * @param nonce
+     * @return
+     */
+    public static boolean checkSignature(String signature, String timestamp, String nonce) {
+        String[] arr = new String[] { token, timestamp, nonce };
+        // 将token、timestamp、nonce三个参数进行字典序排序
+        // Arrays.sort(arr);
+        sort(arr);
+        StringBuilder content = new StringBuilder();
+        for (int i = 0; i < arr.length; i++) {
+            content.append(arr[i]);
+        }
+        MessageDigest md = null;
+        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()) : false;
+    }
+
+    /**
+     * 将字节数组转换为十六进制字符串
+     *
+     * @param byteArray
+     * @return
+     */
+    private static String byteToStr(byte[] byteArray) {
+        String strDigest = "";
+        for (int i = 0; i < byteArray.length; i++) {
+            strDigest += byteToHexStr(byteArray[i]);
+        }
+        return strDigest;
+    }
+
+    /**
+     * 将字节转换为十六进制字符串
+     *
+     * @param mByte
+     * @return
+     */
+    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;
+                }
+            }
+        }
+    }
+}

+ 30 - 0
src/main/java/com/uas/platform/b2c/common/weixin/util/WeChatUtil.java

@@ -0,0 +1,30 @@
+package com.uas.platform.b2c.common.weixin.util;
+
+/**
+ * @author liusw
+ * @date 2018-05-29 19:33
+ */
+public class WeChatUtil {
+
+    /**
+     * appid
+     */
+    public static final String APPID = "wxd29bbca61728b189";
+
+    /**
+     * appsecret
+     */
+    public static final String APPSECRET = "57c19428c09de7ab9d38125a757fafd5";
+
+    public static final String INQUIRY_TEMPLATE_ID = "";
+
+    /**
+     * 发送模板消息url
+     */
+    public static final String SEND_TEMPLATE_URL = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN";
+
+    /**
+     * 获取access_token
+     */
+    public static final String GET_ACCESS_TOKEN = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=SECRET";
+}

+ 2 - 0
src/main/webapp/WEB-INF/spring/webmvc.xml

@@ -121,6 +121,8 @@
 			<mvc:exclude-mapping path="/basic/enterprise/**/info"/>
 			<mvc:exclude-mapping path="/vendor/introduction/vendor/**" />
 			<mvc:exclude-mapping path="/vendor/introduction/product/**" />
+			<mvc:exclude-mapping path="/wx/check"/>
+			<mvc:exclude-mapping path="/wx/getWxUserInfo"/>
 			<bean class="com.uas.platform.b2c.core.filter.SSOInterceptor"></bean>
 		</mvc:interceptor>
 		<!-- 对所有的请求拦截,将Session中的User信息设置进SystemSession -->