package com.ruoyi.platform.weixin.service;


import com.ruoyi.platform.weixin.domain.Article;
import com.ruoyi.platform.weixin.domain.Image;
import com.ruoyi.platform.weixin.domain.Music;
import com.ruoyi.platform.weixin.domain.Video;
import com.ruoyi.platform.weixin.domain.Voice;
import com.ruoyi.platform.weixin.domainResponse.ArticleMessageResponse;
import com.ruoyi.platform.weixin.domainResponse.ImageMessageResponse;
import com.ruoyi.platform.weixin.domainResponse.MusicMessageResponse;
import com.ruoyi.platform.weixin.domainResponse.TextMessageResponse;
import com.ruoyi.platform.weixin.domainResponse.VideoMessageResponse;
import com.ruoyi.platform.weixin.domainResponse.VoiceMessageResponse;
import com.ruoyi.platform.weixin.wxUtil.MessageUtil;
import com.ruoyi.platform.weixin.wxUtil.WxpubOAuth;
import com.ruoyi.system.service.ISysConfigService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 接收微信普通消息和事件推送服务和回复用户消息服务
 */
@Service
public class MessageAndEventService {

    //配置服务
    @Autowired
    private ISysConfigService sysConfigService;


    private static final Logger logger = LoggerFactory.getLogger(MessageAndEventService.class);

    /**
     * 处理微信请求
     */
    public String processRequest(HttpServletRequest request) {
        System.out.println(">>>>>>>>>>>>>>CoreService开始处理请求>>>>>>>>>>");
        String respXml = null;
        try {
            //解析微信服务器推送过来的消息和事件
            Map<String, String> requestMap = MessageUtil.parseXml(request);
            respXml = this.setMessageResponse(requestMap);
            logger.info("处理结束,返回参数为: {}", respXml);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return respXml;
    }

    /**
     * 判断用户执行的微信操作时消息还是事件,并确定消息或事件的具体类型
     *
     * @param requestMap 用户推送的事件或者消息
     * @return 返回给用户的消息体
     */
    public String setMessageResponse(Map<String, String> requestMap) {
        String respXml = null;
        String appId = sysConfigService.selectConfigByKey("APPID");
        String redirectUri1 = sysConfigService.selectConfigByKey("redirectUri");
        Map<String, String> responseMap = new HashMap<String, String>();

        //获取用户操作的是消息还是事件
        String msgType = requestMap.get("MsgType");
        if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_EVENT)) {
            //事件推送===>如果是事件,则多一个属性eventType
            String eventType = requestMap.get("Event");
            if (eventType.equals(MessageUtil.EVENT_TYPE_SUBSCRIBE)) {
                //订阅事件==>回复文本消息
                //false静默授权
                String urlForCode = WxpubOAuth.createOauthUrlForCode(appId, redirectUri1, false);
                String respContent = "感谢您关注中旭昊!\r\n1.回复数字2可获取智慧消防平台APP链接下载地址" +
                        "\r\n2.请点击<a href=\"" + urlForCode + "\">这里</a>进行授权登录\r\n注意:重复认证会覆盖掉之前的认证信息!";
                responseMap.put("content", respContent);
                //回复用户文本消息
                respXml = this.respText(requestMap, responseMap);
            } else if (eventType.equals(MessageUtil.EVENT_TYPE_UNSUBSCRIBE)) {
                //取消订阅事件
                //用户取消关注后不用回复消息.
            } else if (eventType.equals(MessageUtil.EVENT_TYPE_SCAN)) {
                //已关注用户扫描带参数二维码
            } else if (eventType.equals(MessageUtil.EVENT_TYPE_LOCATION)) {
                //上报地理位置事件
            } else if (eventType.equals(MessageUtil.EVENT_TYPE_CLICK)) {
                //获取自定义菜单中事件key值
                String key = requestMap.get("EventKey");
                if (key.equals("product_001")) {
                    //回复用户文本消息
                    responseMap.put("content", "这是我们的消火栓!");
                    respXml = this.respText(requestMap, responseMap);
                }
                if (key.equals("product_002")) {
                    //回复用户文本消息
                    responseMap.put("content", "这是我们的烟感器!");
                    respXml = this.respText(requestMap, responseMap);
                }
                if (key.equals("product_003")) {
                    //回复用户文本消息
                    responseMap.put("content", "这是我们的消防水压!");
                    respXml = this.respText(requestMap, responseMap);
                }
                if (key.equals("product_004")) {
                    //回复用户文本消息
                    responseMap.put("content", "这是我们的消防水箱!");
                    respXml = this.respText(requestMap, responseMap);
                }
                if (key.equals("product_012")) {
                    //回复用户文本消息
                    responseMap.put("content", "这是我们的安全用电仪表设备!");
                    respXml = this.respText(requestMap, responseMap);
                }
                if (key.equals("authLogin")) {
                    System.out.println("==============这是授权登录点击事件!============");
                    //false静默授权
                    String urlForCode = WxpubOAuth.createOauthUrlForCode(appId, redirectUri1, false);
                    String respContent = "请点击<a href=\"" + urlForCode + "\">这里</a>进行授权登录\r\n注意:重复认证会覆盖掉之前的认证信息!";
                    //回复用户文本消息
                    responseMap.put("content", respContent);
                    respXml = this.respText(requestMap, responseMap);
                }
            }
        } else {
            //消息推送
            if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_TEXT)) {
                //用户发送的文本消息==>根据用户发送关键字内容响应不同的消息【这里主要是文本和图文消息】
                String content = requestMap.get("Content");
                String text = "授权,登录,授权登录";
                String text1 = "二维码,智慧消防二维码,2";
                if (content.equals("1") || text.contains(content)) {
                    //false静默授权
                    String urlForCode = WxpubOAuth.createOauthUrlForCode(appId, redirectUri1, false);
                    String respContent = "请点击<a href=\"" + urlForCode + "\">这里</a>进行授权登录\r\n注意:重复认证会覆盖掉之前的认证信息!";
                    //回复用户文本消息
                    responseMap.put("content", respContent);
                    respXml = this.respText(requestMap, responseMap);
                } else if (text1.contains(content)) {
                    //图文消息标题
                    responseMap.put("title", "智慧消防APP");
                    //图文消息描述
                    responseMap.put("description", "根据自己需求扫描对应的二维码下载并安装APP");
                    //图片链接,支持JPG、PNG格式,较好的效果为大图360*200,小图200*200
                    responseMap.put("picUrl", "http://dd.zxhzn.com/img/logos.png");
                    //点击图文消息跳转链接
                    responseMap.put("url", "http://45.96.779.110:8078/download/indoorFire/qrCode.html");
                    respXml = this.respNews(requestMap, responseMap);
                } else {
                    //回复用户文本消息
                    responseMap.put("content", "感谢您关注中旭昊智能科技");
                    respXml = this.respText(requestMap, responseMap);
                }

            } else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_IMAGE)) {
                //回复用户文本消息
                responseMap.put("content", "送您一个图片消息~~~~~~!");
                respXml = this.respText(requestMap, responseMap);

            } else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_VOICE)) {
                //回复用户文本消息
                responseMap.put("content", "送您一个语音消息~~~~~~!");
                respXml = this.respText(requestMap, responseMap);
            } else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_VIDEO)) {
                //回复用户文本消息
                responseMap.put("content", "送您一个视频消息~~~~~~!");
                respXml = this.respText(requestMap, responseMap);
            } else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_SHORTVIDEO)) {
                //回复用户文本消息
                responseMap.put("content", "送您一个小视频消息~~~~~~!");
                respXml = this.respText(requestMap, responseMap);
            } else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_LOCATION)) {
                //回复用户文本消息
                responseMap.put("content", "送您一个地理位置消息~~~~~~!");
                respXml = this.respText(requestMap, responseMap);
            } else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_LINK)) {
                //回复用户文本消息
                responseMap.put("content", "送您一个链接消息~~~~~~!");
                respXml = this.respText(requestMap, responseMap);
            }
        }
        return respXml;
    }

    /**
     * 响应用户文本消息类型
     *
     * @param requestMap  用户请求的消息体
     * @param responseMap 响应用户请求的消息体
     */
    private String respText(Map<String, String> requestMap, Map<String, String> responseMap) {
        //给用户回复相应的消息,必须也要封装成xml的形式,微信才可以识别
        TextMessageResponse textMessageResponse = new TextMessageResponse();
        textMessageResponse.setFromUserName(requestMap.get("ToUserName"));
        textMessageResponse.setToUserName(requestMap.get("FromUserName"));
        textMessageResponse.setCreateTime(new Date().getTime());
        textMessageResponse.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_TEXT);
        textMessageResponse.setContent(responseMap.get("content"));
        //转换为xml(将回复给用户的信息封装成xml的形式,微信服务器解析后,返还给用户)
        String respXml = MessageUtil.messageToXml(textMessageResponse);
        logger.info("处理结束,返回参数为: {}", respXml);
        return respXml;
    }

    /**
     * 响应用户图片消息类型
     *
     * @param requestMap  用户请求的消息体
     * @param responseMap 响应用户请求的消息体
     */
    private String respImage(Map<String, String> requestMap, Map<String, String> responseMap) {
        //给用户回复相应的消息,必须也要封装成xml的形式,微信才可以识别
        ImageMessageResponse imageMessageResponse = new ImageMessageResponse();
        imageMessageResponse.setFromUserName(requestMap.get("ToUserName"));
        imageMessageResponse.setToUserName(requestMap.get("FromUserName"));
        imageMessageResponse.setCreateTime(new Date().getTime());
        imageMessageResponse.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_IMAGE);
        Image image = new Image();
        //通过素材管理中的接口上传多媒体文件,得到的id。
        image.setMediaId(responseMap.get("mediaId"));
        imageMessageResponse.setImage(image);
        //转换为xml(将回复给用户的信息封装成xml的形式,微信服务器解析后,返还给用户)
        String respXml = MessageUtil.messageToXml(imageMessageResponse);
        logger.info("处理结束,返回参数为: {}", respXml);
        return respXml;
    }

    /**
     * 响应用户图文消息类型
     *
     * @param requestMap  用户请求的消息体
     * @param responseMap 响应用户请求的消息体
     */
    private String respNews(Map<String, String> requestMap, Map<String, String> responseMap) {
        //给用户回复相应的消息,必须也要封装成xml的形式,微信才可以识别
        ArticleMessageResponse articleMessageResponse = new ArticleMessageResponse();
        articleMessageResponse.setFromUserName(requestMap.get("ToUserName"));
        articleMessageResponse.setToUserName(requestMap.get("FromUserName"));
        articleMessageResponse.setCreateTime(new Date().getTime());
        articleMessageResponse.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_ARTICLE);
        //图文消息个数;当用户发送文本、图片、视频、图文、地理位置这五种消息时,开发者只能回复1条图文消息;其余场景最多可回复8条图文消息
        articleMessageResponse.setArticleCount(1);
        List<Article> listArticles = new ArrayList<Article>();
        Article article = new Article();
        article.setTitle(responseMap.get("title"));
        article.setDescription(responseMap.get("description"));
        article.setPicUrl(responseMap.get("picUrl"));
        article.setUrl(responseMap.get("url"));
        listArticles.add(article);
        articleMessageResponse.setArticles(listArticles);
        String respXml = null;
        try {
            respXml = MessageUtil.messageToXml(articleMessageResponse);
            logger.info("处理结束,返回参数为: {}", respXml);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return respXml;
    }

    /**
     * 响应用户语音消息类型
     *
     * @param requestMap  用户请求的消息体
     * @param responseMap 响应用户请求的消息体
     */
    private String respVoice(Map<String, String> requestMap, Map<String, String> responseMap) {
        //给用户回复相应的消息,必须也要封装成xml的形式,微信才可以识别
        VoiceMessageResponse voiceMessageResponse = new VoiceMessageResponse();
        voiceMessageResponse.setFromUserName(requestMap.get("ToUserName"));
        voiceMessageResponse.setToUserName(requestMap.get("FromUserName"));
        voiceMessageResponse.setCreateTime(new Date().getTime());
        voiceMessageResponse.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_VOICE);
        Voice voice = new Voice();
        //通过素材管理中的接口上传多媒体文件,得到的id。
        voice.setMediaId(responseMap.get("mediaId"));
        voiceMessageResponse.setVoice(voice);
        //转换为xml(将回复给用户的信息封装成xml的形式,微信服务器解析后,返还给用户)
        String respXml = MessageUtil.messageToXml(voiceMessageResponse);
        logger.info("处理结束,返回参数为: {}", respXml);
        return respXml;
    }

    /**
     * 响应用户视频消息类型
     *
     * @param requestMap  用户请求的消息体
     * @param responseMap 响应用户请求的消息体
     */
    private String respVideo(Map<String, String> requestMap, Map<String, String> responseMap) {
        //给用户回复相应的消息,必须也要封装成xml的形式,微信才可以识别
        VideoMessageResponse videoMessageResponse = new VideoMessageResponse();
        videoMessageResponse.setFromUserName(requestMap.get("ToUserName"));
        videoMessageResponse.setToUserName(requestMap.get("FromUserName"));
        videoMessageResponse.setCreateTime(new Date().getTime());
        videoMessageResponse.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_VIDEO);
        Video video = new Video();
        //通过素材管理中的接口上传多媒体文件,得到的id。
        video.setMediaId(responseMap.get("mediaId"));
        video.setTitle(requestMap.get("title"));
        video.setDescription(requestMap.get("description"));
        videoMessageResponse.setVideo(video);
        //转换为xml(将回复给用户的信息封装成xml的形式,微信服务器解析后,返还给用户)
        String respXml = MessageUtil.messageToXml(videoMessageResponse);
        logger.info("处理结束,返回参数为: {}", respXml);
        return respXml;
    }

    /**
     * 响应用户音乐消息类型
     *
     * @param requestMap  用户请求的消息体
     * @param responseMap 响应用户请求的消息体
     */
    private String respMusic(Map<String, String> requestMap, Map<String, String> responseMap) {
        //给用户回复相应的消息,必须也要封装成xml的形式,微信才可以识别
        MusicMessageResponse musicMessageResponse = new MusicMessageResponse();
        musicMessageResponse.setFromUserName(requestMap.get("ToUserName"));
        musicMessageResponse.setToUserName(requestMap.get("FromUserName"));
        musicMessageResponse.setCreateTime(new Date().getTime());
        musicMessageResponse.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_MUSIC);
        Music music = new Music();
        music.setTitle(requestMap.get("title"));
        music.setDescription(requestMap.get("description"));
        music.setMusicURL(requestMap.get("musicURL"));
        music.setHQMusicUrl(requestMap.get("hQMusicUrl"));
        music.setThumbMediaId(requestMap.get("ThumbMediaId"));
        musicMessageResponse.setMusic(music);
        //转换为xml(将回复给用户的信息封装成xml的形式,微信服务器解析后,返还给用户)
        String respXml = MessageUtil.messageToXml(musicMessageResponse);
        logger.info("处理结束,返回参数为: {}", respXml);
        return respXml;
    }

}

消息服务用到的xml封装工具类MessageUtil

package com.ruoyi.platform.weixin.wxUtil;

import com.ruoyi.platform.weixin.domain.Article;
import com.ruoyi.platform.weixin.domainResponse.ArticleMessageResponse;
import com.ruoyi.platform.weixin.domainResponse.ImageMessageResponse;
import com.ruoyi.platform.weixin.domainResponse.MusicMessageResponse;
import com.ruoyi.platform.weixin.domainResponse.TextMessageResponse;
import com.ruoyi.platform.weixin.domainResponse.VideoMessageResponse;
import com.ruoyi.platform.weixin.domainResponse.VoiceMessageResponse;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.core.util.QuickWriter;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.xml.PrettyPrintWriter;
import com.thoughtworks.xstream.io.xml.XppDriver;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import javax.servlet.http.HttpServletRequest;
import java.io.InputStream;
import java.io.Writer;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 消息接收处理工具类
 */
public class MessageUtil {
    //请求消息的类型------------------------------------------------------
    //文本
    public static final String REQ_MESSAGE_TYPE_TEXT = "text";

    //图片
    public static final String REQ_MESSAGE_TYPE_IMAGE = "image";

    //语音
    public static final String REQ_MESSAGE_TYPE_VOICE = "voice";

    //视频
    public static final String REQ_MESSAGE_TYPE_VIDEO = "video";

    //小视频
    public static final String REQ_MESSAGE_TYPE_SHORTVIDEO = "shortvideo";

    //地理位置
    public static final String REQ_MESSAGE_TYPE_LOCATION = "location";

    //链接
    public static final String REQ_MESSAGE_TYPE_LINK = "link";

    //事件推送类型------------------------------------------------------------------------
    public static final String REQ_MESSAGE_TYPE_EVENT = "event";

    //事件类型--订阅
    public static final String EVENT_TYPE_SUBSCRIBE = "subscribe";

    //取消订阅
    public static final String EVENT_TYPE_UNSUBSCRIBE = "unsubscribe";

    //已关注用户扫描带参数二维码
    public static final String EVENT_TYPE_SCAN = "SCAN";

    //上报地理位置
    public static final String EVENT_TYPE_LOCATION = "LOCATION";

    //自定义菜单事件
    public static final String EVENT_TYPE_CLICK = "CLICK";

    //响应消息类型-----------------------------------------------------------------------
    //文本
    public static final String RESP_MESSAGE_TYPE_TEXT = "text";

    //图片
    public static final String RESP_MESSAGE_TYPE_IMAGE = "image";

    //语音
    public static final String RESP_MESSAGE_TYPE_VOICE = "voice";

    //视频
    public static final String RESP_MESSAGE_TYPE_VIDEO = "video";

    //音乐
    public static final String RESP_MESSAGE_TYPE_MUSIC = "music";

    //图文
    public static final String RESP_MESSAGE_TYPE_ARTICLE = "news";

    /**
     * 解析微信服务器推送过来的消息和事件
     * xml转map
     */
    @SuppressWarnings("unchecked")
    public static Map<String, String> parseXml(HttpServletRequest request) throws Exception {
        Map<String, String> map = new HashMap<>();
        // 从request中取得输入流
        InputStream inputStream = request.getInputStream();
        // 读取输入流
        SAXReader reader = new SAXReader();
        Document document = reader.read(inputStream);
        // 得到xml根元素
        Element rootElement = document.getRootElement();
        // 得到根元素的所有子节点
        List<Element> elements = rootElement.elements();
        System.out.println("==节点大小==" + elements.size());
        //遍历所有子节点,将数据存入map
        for (Element e : elements) {
            map.put(e.getName(), e.getText());
            System.out.println("==键==" + e.getName() + "==值==" + e.getText());
        }
        // 释放资源
        inputStream.close();
        inputStream = null;
        return map;
    }

    /**
     * 开发者回复给用户的信息必须封装成xml的形式,微信服务器才可以正确解析,转给用户
     * 扩展xstream,支持CDATA
     */
    @SuppressWarnings("unused")
    private static XStream xStream = new XStream(new XppDriver() {
        @Override
        public HierarchicalStreamWriter createWriter(Writer out) {
            return new PrettyPrintWriter(out) {
                //对所有xml节点的转换都增加CDATA标记
                boolean cdate = true;

                public void startNode(String name, Class clazz) {
                    super.startNode(name, clazz);
                }

                protected void writeText(QuickWriter writer, String text) {
                    if (cdate) {
                        writer.write("<![CDATA[");
                        writer.write(text);
                        writer.write("]]>");
                    } else {
                        writer.write(text);
                    }
                }
            };
        }
    });


    /**
     * 文本消息转换成xml
     */
    public static String messageToXml(TextMessageResponse textMessageResponse) {
        xStream.alias("xml", textMessageResponse.getClass());
        return xStream.toXML(textMessageResponse);
    }

    /**
     * 图片消息对象转换xml
     */
    public static String messageToXml(ImageMessageResponse imageMessageResponse) {
        xStream.alias("xml", imageMessageResponse.getClass());
        return xStream.toXML(imageMessageResponse);
    }

    /**
     * 语音消息转换为xml
     */
    public static String messageToXml(VoiceMessageResponse voiceMessageResponse) {
        xStream.alias("xml", voiceMessageResponse.getClass());
        return xStream.toXML(voiceMessageResponse);
    }

    /**
     * 视频消息转换成xml
     */
    public static String messageToXml(VideoMessageResponse videoMessageResponse) {
        xStream.alias("xml", videoMessageResponse.getClass());
        return xStream.toXML(videoMessageResponse);
    }

    /**
     * 音乐消息转换xml
     */
    public static String messageToXml(MusicMessageResponse musicMessageResponse) {
        xStream.alias("xml", musicMessageResponse.getClass());
        return xStream.toXML(musicMessageResponse);
    }

    /**
     * 图文消息转换成xml
     */
    public static String messageToXml(ArticleMessageResponse articleMessageResponse) {
        xStream.alias("xml", articleMessageResponse.getClass());
        xStream.alias("item", new Article().getClass());
        return xStream.toXML(articleMessageResponse);
    }





}

Logo

快速构建 Web 应用程序

更多推荐