123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292 |
- package com.caimei365.wechat.service.impl;
- import com.alibaba.fastjson.JSONObject;
- import com.caimei365.wechat.dao.WeChatDao;
- import com.caimei365.wechat.entity.WeChatConstant;
- import com.caimei365.wechat.entity.WechatArticleDetail;
- import com.caimei365.wechat.entity.WechatReply;
- import com.caimei365.wechat.service.WechatServerService;
- import com.caimei365.wechat.utils.MessageUtil;
- import com.caimei365.wechat.utils.SignUtil;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.beans.factory.annotation.Value;
- import org.springframework.stereotype.Service;
- import org.springframework.util.CollectionUtils;
- import org.springframework.util.StringUtils;
- import org.springframework.web.client.RestTemplate;
- import javax.annotation.Resource;
- import javax.servlet.http.HttpServletRequest;
- import java.io.UnsupportedEncodingException;
- import java.net.URLEncoder;
- import java.util.ArrayList;
- import java.util.List;
- import java.util.Map;
- /**
- * 微信公众号服务配置
- *
- * @author : Charles
- * @date : 2022/1/13
- */
- @Slf4j
- @Service
- public class WechatServerServiceImpl implements WechatServerService {
- @Value("${caimei.wwwDomain}")
- private String wwwDomain;
- @Value("${caimei.coreDomain}")
- private String coreDomain;
- @Value("${caimei.imageDomain}")
- private String imageDomain;
- @Value("${wechat.caimei.appid}")
- private String caimeiAppid;
- @Value("${wechat.caimei.secret}")
- private String caimeiSecret;
- @Resource
- private WeChatDao weChatDao;
- /**
- * 验证消息的确来自微信服务器
- *
- * 通过检验signature对请求进行校验。
- * 若确认此次GET请求来自微信服务器,请原样返回echostr参数内容,则接入生效,成为开发者成功,否则接入失败。
- * 加密/校验流程如下:
- * 1)将token、timestamp、nonce三个参数进行字典序排序
- * 2)将三个参数字符串拼接成一个字符串进行sha1加密
- * 3)开发者获得加密后的字符串可与signature对比,标识该请求来源于微信
- */
- @Override
- public String validateSignature(HttpServletRequest request) {
- String signature = request.getParameter("signature");
- String timestamp = request.getParameter("timestamp");
- String nonce = request.getParameter("nonce");
- String echostr = request.getParameter("echostr");
- boolean flag = SignUtil.checkSignature(signature, timestamp, nonce);
- if (flag) {
- return echostr;
- } else {
- return null;
- }
- }
- /**
- * 处理接收的文本消息
- * <xml>
- * <ToUserName><![CDATA[toUser]]></ToUserName>
- * <FromUserName><![CDATA[fromUser]]></FromUserName>
- * <CreateTime>12345678</CreateTime>
- * <MsgType><![CDATA[text]]></MsgType>
- * <Content><![CDATA[你好]]></Content>
- * </xml>
- */
- @Override
- public String handleTextMsg(Map<String, String> requestMap) {
- // 根据接收的关键字回复
- String keyword = requestMap.get(WeChatConstant.CONTENT);
- // 用户openid
- String openid = requestMap.get(WeChatConstant.FROM_USER_NAME);
- // 微信号公众号Id
- String wxType = requestMap.get(WeChatConstant.TO_USER_NAME);
- log.info(">>>>>>>>>>处理接收的文本消息,keyword:" + keyword + ",openid:" + openid + ",wxType:" + wxType);
- // 根据口令获取用户openid
- if("caimei:get_openid".equals(keyword)) {
- return MessageUtil.setTextXml(openid, wxType, openid);
- }
- // 根据keyword匹配数据库回复配置
- WechatReply reply = weChatDao.getReplyByParams("input", keyword, wxType);
- // if (null == reply) {
- // reply = weChatDao.getReplyByParams("input", "autoReply", wxType);
- // }
- // if (null == reply) {
- // // 将消息转发到到客服系统
- // return MessageUtil.setCustomerXml(openid, wxType);
- // }
- log.info(">>>>>>>>>>匹配已配置关键词:" + keyword);
- String replyXml = setXmlByDatabaseReply(openid, wxType, reply);
- if (replyXml != null) {
- return replyXml;
- }
- log.info(">>>>>>>>>>模糊搜索:" + keyword);
- WechatArticleDetail article = null;
- RestTemplate restTemplate = new RestTemplate();
- // https://core.caimei365.com/commodity/search/query/product?keyword=
- String uri = coreDomain + "commodity/search/query/product?keyword="+keyword;
- JSONObject forObject = restTemplate.getForObject(uri, JSONObject.class);
- if(forObject != null){
- String data = forObject.getString("data");
- if(StringUtils.hasLength(data)){
- JSONObject parse = JSONObject.parseObject(data);
- if(parse != null){
- Integer total = parse.getInteger("total");
- if(total>0){
- article = new WechatArticleDetail();
- article.setTitle("帮您匹配到"+ total + "个商品,点击查看");
- article.setPicUrl(imageDomain + "/group1/M00/03/EC/rB-lGGHg9ZOAe8VdAAJevlD1ofg562.png");
- String url = wwwDomain + "product/list.html?keyword="+keyword;
- try {
- url = URLEncoder.encode(url, "UTF-8");
- } catch (UnsupportedEncodingException ignored) {}
- article.setLinkUrl("https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + caimeiAppid + "&redirect_uri=" + url +"&response_type=code&scope=snsapi_base&state=reLogin#wechat_redirect");
- }
- }
- }
- }
- if (null != article) {
- List<WechatArticleDetail> articles = new ArrayList<>();
- articles.add(article);
- return MessageUtil.setArticleXml(openid, wxType, articles);
- }
- log.info(">>>>>>>>>>默认无关键字匹配回复图文1220");
- List<WechatArticleDetail> defaultList = weChatDao.getArticleDetailList(1220);
- if (CollectionUtils.isEmpty(defaultList)) {
- return MessageUtil.setArticleXml(openid, wxType, defaultList);
- }
- return null;
- }
- /**
- * 点击自定义菜单事件
- *
- * 点击菜单拉取消息时的事件推送:
- * <xml>
- * <ToUserName><![CDATA[toUser]]></ToUserName>
- * <FromUserName><![CDATA[FromUser]]></FromUserName>
- * <CreateTime>123456789</CreateTime>
- * <MsgType><![CDATA[event]]></MsgType>
- * <Event><![CDATA[CLICK]]></Event>
- * <EventKey><![CDATA[EVENTKEY]]></EventKey>
- * </xml>
- *
- * 点击菜单跳转链接时的事件推送:
- * <xml>
- * <ToUserName><![CDATA[toUser]]></ToUserName>
- * <FromUserName><![CDATA[FromUser]]></FromUserName>
- * <CreateTime>123456789</CreateTime>
- * <MsgType><![CDATA[event]]></MsgType>
- * <Event><![CDATA[VIEW]]></Event>
- * <EventKey><![CDATA[www.qq.com]]></EventKey>
- * </xml>
- */
- @Override
- public String handleClickMenuMsg(Map<String, String> requestMap) {
- // 用户openid
- String openid = requestMap.get(WeChatConstant.FROM_USER_NAME);
- // 微信号公众号Id
- String wxType = requestMap.get(WeChatConstant.TO_USER_NAME);
- // 事件类型
- String event = requestMap.get(WeChatConstant.EVENT);
- // 事件KEY值,设置的跳转URL/与自定义菜单接口中KEY值对应
- String eventKey = requestMap.get(WeChatConstant.EVENT_KEY);
- log.info(">>>>>>>>>>处理点击自定义菜单事件,event:" + event + ",eventKey:" + eventKey + ",openid:" + openid + ",wxType:" + wxType);
- // 匹配数据库回复配置
- WechatReply reply = weChatDao.getReplyByParams("click", eventKey, wxType);
- return setXmlByDatabaseReply(openid, wxType, reply);
- }
- /**
- * 上报地理位置
- * <xml>
- * <ToUserName><![CDATA[toUser]]></ToUserName>
- * <FromUserName><![CDATA[fromUser]]></FromUserName>
- * <CreateTime>123456789</CreateTime>
- * <MsgType><![CDATA[event]]></MsgType>
- * <Event><![CDATA[LOCATION]]></Event>
- * <Latitude>23.137466</Latitude>
- * <Longitude>113.352425</Longitude>
- * <Precision>119.385040</Precision>
- * </xml>
- *
- * * <纬度>23.137466</纬度>
- * * <经度>113.352425</经度>
- * * <精度>119.385040</精度>
- */
- @Override
- public String handleLocationMsg(Map<String, String> requestMap) {
- // 用户openid
- String openid = requestMap.get(WeChatConstant.FROM_USER_NAME);
- // 微信号公众号Id
- String wxType = requestMap.get(WeChatConstant.TO_USER_NAME);
- //Longitude 地理位置经度
- String longitude = requestMap.get(WeChatConstant.LONGITUDE);
- //Latitude 地理位置纬度
- String latitude = requestMap.get(WeChatConstant.LATITUDE);
- //Precision 地理位置精度
- String precision = requestMap.get(WeChatConstant.PRECISION);
- String content = "您当前位置,经度:" + longitude + ",纬度:" + latitude + ",精度:" + precision;
- log.info(">>>>>>>>>>处理上报地理位置事件," + content + ",openid:" + openid + ",wxType:" + wxType);
- return MessageUtil.setTextXml(openid, wxType, content);
- }
- /**
- * subscribe(订阅/关注)
- * <xml>
- * <ToUserName><![CDATA[toUser]]></ToUserName>
- * <FromUserName><![CDATA[FromUser]]></FromUserName>
- * <CreateTime>123456789</CreateTime>
- * <MsgType><![CDATA[event]]></MsgType>
- * <Event><![CDATA[subscribe]]></Event>
- * </xml>
- */
- @Override
- public String handleSubscribeMsg(Map<String, String> requestMap) {
- // 用户openid
- String openid = requestMap.get(WeChatConstant.FROM_USER_NAME);
- // 微信号公众号Id
- String wxType = requestMap.get(WeChatConstant.TO_USER_NAME);
- log.info(">>>>>>>>>>处理接收的订阅关注事件,openid:" + openid + ",wxType:" + wxType);
- // 匹配数据库回复配置
- WechatReply reply = weChatDao.getReplyByParams("subscribe", null, wxType);
- return setXmlByDatabaseReply(openid, wxType, reply);
- }
- /**
- * 扫描带参数二维码事件
- * <xml>
- * <ToUserName><![CDATA[toUser]]></ToUserName>
- * <FromUserName><![CDATA[FromUser]]></FromUserName>
- * <CreateTime>123456789</CreateTime>
- * <MsgType><![CDATA[event]]></MsgType>
- * <Event><![CDATA[subscribe]]></Event>
- * <EventKey><![CDATA[qrscene_123123]]></EventKey>
- * <Ticket><![CDATA[TICKET]]></Ticket>
- * </xml>
- */
- @Override
- public String handleScanMsg(Map<String, String> requestMap) {
- // 用户openid
- String openid = requestMap.get(WeChatConstant.FROM_USER_NAME);
- // 微信号公众号Id
- String wxType = requestMap.get(WeChatConstant.TO_USER_NAME);
- // 扫码参数
- String eventKey = requestMap.get(WeChatConstant.EVENT_KEY);
- log.info(">>>>>>>>>>处理扫描带参数二维码事件,二维码参数:" + eventKey + ",openid:" + openid + ",wxType:" + wxType);
- //todo 用户绑定微信
- // 匹配数据库回复配置
- WechatReply reply = weChatDao.getReplyByParams("subscribe", null, wxType);
- return setXmlByDatabaseReply(openid, wxType, reply);
- }
- /**
- * 根据数据库回复配置设置
- */
- private String setXmlByDatabaseReply(String openid, String wxType, WechatReply reply) {
- if ("news".equals(reply.getResponseType())) {
- // 回复图文
- List<WechatArticleDetail> articleList = weChatDao.getArticleDetailList(reply.getRelateId());
- if (CollectionUtils.isEmpty(articleList)) {
- return MessageUtil.setArticleXml(openid, wxType, articleList);
- }
- } else {
- // 回复文本
- String textContent = weChatDao.getTextContent(reply.getRelateId());
- if (StringUtils.hasLength(textContent)) {
- return MessageUtil.setTextXml(openid, wxType, textContent);
- }
- }
- return null;
- }
- }
|