|  | @ -0,0 +1,288 @@
 | 
	
		
			
				|  |  | package com.yihu.jw.business.wx.service;
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  | import com.yihu.jw.base.wx.WxReplySceneDO;
 | 
	
		
			
				|  |  | import com.yihu.jw.base.wx.WxWechatDO;
 | 
	
		
			
				|  |  | import com.yihu.jw.business.wx.controller.WechatCoreController;
 | 
	
		
			
				|  |  | import com.yihu.jw.business.wx.dao.WechatDao;
 | 
	
		
			
				|  |  | import com.yihu.jw.business.wx.dao.WxReplySceneDao;
 | 
	
		
			
				|  |  | import com.yihu.jw.util.wechat.WeiXinMessageReplyUtils;
 | 
	
		
			
				|  |  | import com.yihu.jw.util.wechat.WeiXinMessageUtils;
 | 
	
		
			
				|  |  | import org.apache.commons.lang3.StringUtils;
 | 
	
		
			
				|  |  | import org.dom4j.Document;
 | 
	
		
			
				|  |  | import org.dom4j.DocumentException;
 | 
	
		
			
				|  |  | import org.dom4j.DocumentHelper;
 | 
	
		
			
				|  |  | import org.dom4j.Element;
 | 
	
		
			
				|  |  | import org.dom4j.io.SAXReader;
 | 
	
		
			
				|  |  | import org.slf4j.Logger;
 | 
	
		
			
				|  |  | import org.slf4j.LoggerFactory;
 | 
	
		
			
				|  |  | import org.springframework.beans.factory.annotation.Autowired;
 | 
	
		
			
				|  |  | import org.springframework.jdbc.core.JdbcTemplate;
 | 
	
		
			
				|  |  | import org.springframework.stereotype.Service;
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  | import javax.servlet.http.HttpServletRequest;
 | 
	
		
			
				|  |  | import java.io.InputStream;
 | 
	
		
			
				|  |  | import java.util.ArrayList;
 | 
	
		
			
				|  |  | import java.util.HashMap;
 | 
	
		
			
				|  |  | import java.util.List;
 | 
	
		
			
				|  |  | import java.util.Map;
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  | /**
 | 
	
		
			
				|  |  |  * Created by Trick on 2018/8/16.
 | 
	
		
			
				|  |  |  */
 | 
	
		
			
				|  |  | @Service
 | 
	
		
			
				|  |  | public class WechatCoreService {
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     private Logger logger = LoggerFactory.getLogger(WechatCoreService.class);
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     @Autowired
 | 
	
		
			
				|  |  |     private WechatDao wechatDao;
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     @Autowired
 | 
	
		
			
				|  |  |     private WxAccessTokenService wxAccessTokenService;
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     @Autowired
 | 
	
		
			
				|  |  |     private WxReplySceneDao wxReplySceneDao;
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     @Autowired
 | 
	
		
			
				|  |  |     private JdbcTemplate jdbcTemplate;
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     /**
 | 
	
		
			
				|  |  |      * 微信推送消息处理
 | 
	
		
			
				|  |  |      *
 | 
	
		
			
				|  |  |      * @param request
 | 
	
		
			
				|  |  |      */
 | 
	
		
			
				|  |  |     public String messageProcess(HttpServletRequest request) {
 | 
	
		
			
				|  |  |         try {
 | 
	
		
			
				|  |  |             String returnStr = "";
 | 
	
		
			
				|  |  |             // 将解析结果存储在HashMap中
 | 
	
		
			
				|  |  |             Map<String, String> message = new HashMap();
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |             // 从request中取得输入流
 | 
	
		
			
				|  |  |             InputStream inputStream = request.getInputStream();
 | 
	
		
			
				|  |  |             // 读取输入流
 | 
	
		
			
				|  |  |             SAXReader reader = new SAXReader();
 | 
	
		
			
				|  |  |             Document document = reader.read(inputStream);
 | 
	
		
			
				|  |  |             // 得到xml根元素
 | 
	
		
			
				|  |  |             Element root = document.getRootElement();
 | 
	
		
			
				|  |  |             // 得到根元素的所有子节点
 | 
	
		
			
				|  |  |             List elementList = root.elements();
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |             // 遍历所有子节点
 | 
	
		
			
				|  |  |             for (Object e : elementList) {
 | 
	
		
			
				|  |  |                 Element ele = (Element) e;
 | 
	
		
			
				|  |  |                 message.put(ele.getName(), ele.getText());
 | 
	
		
			
				|  |  |             }
 | 
	
		
			
				|  |  |             logger.info("weixin  event:" + message.toString());
 | 
	
		
			
				|  |  |             // 释放资源
 | 
	
		
			
				|  |  |             inputStream.close();
 | 
	
		
			
				|  |  |             // 消息处理
 | 
	
		
			
				|  |  |             returnStr = messageProcess(message);
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |             return returnStr;
 | 
	
		
			
				|  |  |         } catch (Exception e) {
 | 
	
		
			
				|  |  |             e.printStackTrace();
 | 
	
		
			
				|  |  |             return "error";
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  |     }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     /**
 | 
	
		
			
				|  |  |      * 对接收到的消息进行处理
 | 
	
		
			
				|  |  |      *
 | 
	
		
			
				|  |  |      * @param message
 | 
	
		
			
				|  |  |      * @return
 | 
	
		
			
				|  |  |      */
 | 
	
		
			
				|  |  |     private String messageProcess(Map<String, String> message) throws Exception {
 | 
	
		
			
				|  |  |         String msgType = message.get("MsgType");
 | 
	
		
			
				|  |  |         String result = "";
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         switch (msgType) {
 | 
	
		
			
				|  |  |             case WeiXinMessageUtils.REQ_MESSAGE_TYPE_EVENT:  // 事件消息
 | 
	
		
			
				|  |  |                 result = eventProcess(message);
 | 
	
		
			
				|  |  |                 break;
 | 
	
		
			
				|  |  |             case WeiXinMessageUtils.RESP_MESSAGE_TYPE_TEXT:  // 回复文本消息
 | 
	
		
			
				|  |  |                 //回复文本消息 处理
 | 
	
		
			
				|  |  |                 result = textProcess(message);
 | 
	
		
			
				|  |  |                 break;
 | 
	
		
			
				|  |  |             default:
 | 
	
		
			
				|  |  |                 break;
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         return result;
 | 
	
		
			
				|  |  |     }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     /**
 | 
	
		
			
				|  |  |      * 事件细分处理:
 | 
	
		
			
				|  |  |      * 1.扫描二维码事件
 | 
	
		
			
				|  |  |      * 2.订阅事件
 | 
	
		
			
				|  |  |      * 3.取消订阅事件
 | 
	
		
			
				|  |  |      * 4.菜单点击
 | 
	
		
			
				|  |  |      * @param message
 | 
	
		
			
				|  |  |      * @return
 | 
	
		
			
				|  |  |      */
 | 
	
		
			
				|  |  |     public String eventProcess(Map<String, String> message) throws Exception{
 | 
	
		
			
				|  |  |         String result = "";
 | 
	
		
			
				|  |  |         String event = message.get("Event");
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         switch (event) {
 | 
	
		
			
				|  |  |             case WeiXinMessageUtils.EVENT_TYPE_SCAN: // 扫描二维码事件
 | 
	
		
			
				|  |  |                 result = scanEventProcess(message);
 | 
	
		
			
				|  |  |                 break;
 | 
	
		
			
				|  |  |             case WeiXinMessageUtils.EVENT_TYPE_SUBSCRIBE: // 订阅事件
 | 
	
		
			
				|  |  |                 if (message.containsKey("EventKey") && StringUtils.isNotEmpty(message.get("EventKey")) && message.containsKey("Ticket")
 | 
	
		
			
				|  |  |                         && StringUtils.isNotEmpty(message.get("Ticket"))) {
 | 
	
		
			
				|  |  |                     result = scanEventProcess(message);
 | 
	
		
			
				|  |  |                 } else {
 | 
	
		
			
				|  |  |                     result = subscribeEventProcess(message);
 | 
	
		
			
				|  |  |                 }
 | 
	
		
			
				|  |  |                 break;
 | 
	
		
			
				|  |  |             case WeiXinMessageUtils.EVENT_TYPE_UNSUBSCRIBE: // 取消订阅事件
 | 
	
		
			
				|  |  |                 result = unsubscribeEventProcess(message);
 | 
	
		
			
				|  |  |                 break;
 | 
	
		
			
				|  |  |             case WeiXinMessageUtils.EVENT_TYPE_CLICK: //菜单点击
 | 
	
		
			
				|  |  |                 result = this.clickProcess(message);
 | 
	
		
			
				|  |  |             default:
 | 
	
		
			
				|  |  |                 break;
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         return result;
 | 
	
		
			
				|  |  |     }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     public String scanEventProcess(Map<String, String> message){
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         return "";
 | 
	
		
			
				|  |  |     }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     /**
 | 
	
		
			
				|  |  |      * 搜索关注事件
 | 
	
		
			
				|  |  |      * @param message
 | 
	
		
			
				|  |  |      * @return
 | 
	
		
			
				|  |  |      */
 | 
	
		
			
				|  |  |     public String subscribeEventProcess(Map<String, String> message) throws Exception{
 | 
	
		
			
				|  |  |         String toUserName = message.get("ToUserName");
 | 
	
		
			
				|  |  |         List<WxReplySceneDO> scenes = wxReplySceneDao.findByAppOriginIdAndMsgTypeAndEventAndStatus(toUserName,WeiXinMessageUtils.RESP_MESSAGE_TYPE_TEXT,WeiXinMessageUtils.EVENT_TYPE_SUBSCRIBE,1);
 | 
	
		
			
				|  |  |         if(scenes!=null&&scenes.size()>0){
 | 
	
		
			
				|  |  |             WxReplySceneDO scene = scenes.get(0);
 | 
	
		
			
				|  |  |             if(StringUtils.isNotBlank(scene.getScene())){
 | 
	
		
			
				|  |  |                 return getGraphicXMl(scene.getScene(),scene.getWechatId(),message);
 | 
	
		
			
				|  |  |             }
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  |         return "";
 | 
	
		
			
				|  |  |     }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     public String unsubscribeEventProcess(Map<String, String> message){
 | 
	
		
			
				|  |  |         return "";
 | 
	
		
			
				|  |  |     }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     public String clickProcess(Map<String, String> message){
 | 
	
		
			
				|  |  |         return "";
 | 
	
		
			
				|  |  |     }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     /**
 | 
	
		
			
				|  |  |      * 文本消息动态生成图文消息
 | 
	
		
			
				|  |  |      * @param message
 | 
	
		
			
				|  |  |      * @return
 | 
	
		
			
				|  |  |      * @throws Exception
 | 
	
		
			
				|  |  |      */
 | 
	
		
			
				|  |  |     public String  textProcess(Map<String, String> message) throws Exception{
 | 
	
		
			
				|  |  |         String toUserName = message.get("ToUserName");
 | 
	
		
			
				|  |  |         String content = message.get("Content");
 | 
	
		
			
				|  |  |         List<WxReplySceneDO> scenes = wxReplySceneDao.findByAppOriginIdAndMsgTypeAndStatus(toUserName,WeiXinMessageUtils.RESP_MESSAGE_TYPE_TEXT,1);
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         if(scenes!=null&&scenes.size()>0){
 | 
	
		
			
				|  |  |             for(WxReplySceneDO scene:scenes){
 | 
	
		
			
				|  |  |                 if(StringUtils.isNotBlank(scene.getContent())
 | 
	
		
			
				|  |  |                         &&content.equals(scene.getContent())
 | 
	
		
			
				|  |  |                         &&StringUtils.isNotBlank(scene.getScene())){
 | 
	
		
			
				|  |  |                     //根据场景值,动态生成图文消息回复文斌
 | 
	
		
			
				|  |  |                     return getGraphicXMl(scene.getScene(),scene.getWechatId(),message);
 | 
	
		
			
				|  |  |                 }
 | 
	
		
			
				|  |  |             }
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         return null;
 | 
	
		
			
				|  |  |     }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     /**
 | 
	
		
			
				|  |  |      * 构造图文消息XML
 | 
	
		
			
				|  |  |      * @param secene
 | 
	
		
			
				|  |  |      * @param wxId
 | 
	
		
			
				|  |  |      * @param message
 | 
	
		
			
				|  |  |      * @return
 | 
	
		
			
				|  |  |      * @throws Exception
 | 
	
		
			
				|  |  |      */
 | 
	
		
			
				|  |  |     public String getGraphicXMl(String secene,String wxId,Map<String, String> message)throws Exception{
 | 
	
		
			
				|  |  |         List<Map<String,Object>> group = getGraphicGroupByScene(secene,wxId);
 | 
	
		
			
				|  |  |         String result = "";
 | 
	
		
			
				|  |  |         if(group!=null&&group.size()>0){
 | 
	
		
			
				|  |  |             List<Map<String, String>> articles = new ArrayList<>();
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |             for(Map<String,Object> graphic : group){
 | 
	
		
			
				|  |  |                 // 图文信息
 | 
	
		
			
				|  |  |                 Map<String, String> article = new HashMap<>();
 | 
	
		
			
				|  |  |                 String url = (String)graphic.get("url");
 | 
	
		
			
				|  |  |                 String baseUrl = (String)graphic.get("baseUrl");
 | 
	
		
			
				|  |  |                 String appId = (String)graphic.get("appId");
 | 
	
		
			
				|  |  |                 String title = (String)graphic.get("title");
 | 
	
		
			
				|  |  |                 String description = (String)graphic.get("description");
 | 
	
		
			
				|  |  |                 String picUrl = (String)graphic.get("picUrl");
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |                 url = url.replace("{server}",baseUrl).replace("{appId}",appId);
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |                 article.put("Url", url);
 | 
	
		
			
				|  |  |                 article.put("Title", title);
 | 
	
		
			
				|  |  |                 article.put("Description", description);
 | 
	
		
			
				|  |  |                 article.put("PicUrl", picUrl);
 | 
	
		
			
				|  |  |             }
 | 
	
		
			
				|  |  |             result = WeiXinMessageReplyUtils.replyNewsMessage(message.get("FromUserName"), message.get("ToUserName"), articles);
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  |         return result;
 | 
	
		
			
				|  |  |     }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     /**
 | 
	
		
			
				|  |  |      * 获取指定场景下所有图文消息分组
 | 
	
		
			
				|  |  |      * @param secene
 | 
	
		
			
				|  |  |      * @param wxId
 | 
	
		
			
				|  |  |      * @return
 | 
	
		
			
				|  |  |      */
 | 
	
		
			
				|  |  |     public List<Map<String,Object>> getGraphicGroupByScene(String secene,String wxId) {
 | 
	
		
			
				|  |  |         String sql = "SELECT " +
 | 
	
		
			
				|  |  |                 " m.title, " +
 | 
	
		
			
				|  |  |                 " m.description, " +
 | 
	
		
			
				|  |  |                 " m.url, " +
 | 
	
		
			
				|  |  |                 " m.pic_url AS picUrl," +
 | 
	
		
			
				|  |  |                 " w.app_id AS appId," +
 | 
	
		
			
				|  |  |                 " w.base_url AS baseUrl" +
 | 
	
		
			
				|  |  |                 " FROM " +
 | 
	
		
			
				|  |  |                 " wx_graphic_scene_group g " +
 | 
	
		
			
				|  |  |                 " JOIN wx_graphic_message m ON g.graphic_id = m.id " +
 | 
	
		
			
				|  |  |                 " JOIN wx_wechat w ON w.id = g.wechat_id" +
 | 
	
		
			
				|  |  |                 " WHERE " +
 | 
	
		
			
				|  |  |                 " m.wechat_id = '"+wxId+"' " +
 | 
	
		
			
				|  |  |                 " AND g.wechat_id = '"+wxId+"' " +
 | 
	
		
			
				|  |  |                 " AND g.scene = '"+secene+"' " +
 | 
	
		
			
				|  |  |                 " AND m.`status` = 1 " +
 | 
	
		
			
				|  |  |                 " ORDER BY m.sort ASC";
 | 
	
		
			
				|  |  |         List<Map<String,Object>> group = jdbcTemplate.queryForList(sql);
 | 
	
		
			
				|  |  |         return group;
 | 
	
		
			
				|  |  |     }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     /**
 | 
	
		
			
				|  |  |      * 判断是否是xml结构
 | 
	
		
			
				|  |  |      */
 | 
	
		
			
				|  |  |     public boolean isXML(String value) {
 | 
	
		
			
				|  |  |         try {
 | 
	
		
			
				|  |  |             DocumentHelper.parseText(value);
 | 
	
		
			
				|  |  |         } catch (DocumentException e) {
 | 
	
		
			
				|  |  |             return false;
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  |         return true;
 | 
	
		
			
				|  |  |     }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     public List<WxWechatDO> findAll(){
 | 
	
		
			
				|  |  |         return wechatDao.findAll();
 | 
	
		
			
				|  |  |     }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  | }
 |