订餐系统之微信点餐

  经过几天的开发、测试微信点餐demo终于完成了,特在此分享下,不好的地方请大家多指正下哈!一开始,就想这东西出来这么久了,网上应该有很多现成的东西,于是,baidu、google了半天,基本没发现现成的东西,也许是我搜索不得其道,也有可能大家都不愿意分享吧...于是,还得自己动手,丰衣足食!

  还是先交代下背景:所谓“微信点餐”,其实就是用户通过微信app,关注公众号,发送指定类型的信息,如地理位置信息,网站返回相关链接到微信上,通过这些链接进入wap或者html5网站,然后开始选择商家、点餐、提交订单等。关于微信app,与订餐网站的关系,我简单的画了一个图,比较潦草,请别喷得太厉害了!如图1,说简单点:微信app通过微信服务器,传给订餐网站(申请公众号时,会输入一个地址,微信服务器就是通过此地址post,get消息的),网站根据收到的消息,返回具体信息,再通过某些信息的链接进入wap或者html5站点。微信公众平台地址:https://mp.weixin.qq.com/
,这几天好像升级了,不叫公众号了,叫订阅号。

                                  (图1)

  至于,如何申请、如何关注,这里就不赘述了,你懂的。要说明的是:关注后,订餐网站会收到一个用户关注的消息,网站返回一段说明文字,提示如何操作等信息,如图2:

          

                                                 (图2)

  

  下面,我就把我自己设计的处理微信消息的代码介绍下吧,不好的地方,请大伙儿多给我指正指正。还是先上一张UML模型图吧,关于依赖和关联的关系,真不怎么弄得明白,所以都有依赖的关系表示了下,这张图片不是很清晰,有兴趣的可以下载源文件看下uml.rar,见图3:

      

  

  下面还是简单对几个类进行说明下吧,这样大家看得明白点。

  BaseNotice.cs,此类表示消息基类,因为每个消息都有几个字段是相同的,如ToUserName、FromUserName、CreateTime、MsgType等,所有抽象出一个基类,此类还有一个抽象方法LoadXml,根据xml返回类的对像的实例。其他具体消息继承此类,加上自己特定的信息。

text.cs ,此类表示文本消息类,除了有BaseNotice中有的属性外,还有一个Content,表示文本信息内容。且实现LoadXml方法,返回一个text实例,代码如下:

/// <summary>
    /// 文本消息
    /// </summary>
    public class text : BaseNotice
    {
        /// <summary>
        /// 根据xml返回对像
        /// </summary>
        /// <param name="xml"></param>
        /// <returns></returns>
        public override BaseNotice LoadXml(string xml)
        {
            text notice = new text();

            //<xml>
            //<ToUserName><![CDATA[toUser]]></ToUserName>
            //<FromUserName><![CDATA[fromUser]]></FromUserName>
            //<CreateTime>1348831860</CreateTime>
            //<MsgType><![CDATA[text]]></MsgType>
            //<Content><![CDATA[this is a test]]></Content>
            //<MsgId>1234567890123456</MsgId>
            //</xml>

            System.Xml.XmlDocument d = new System.Xml.XmlDocument();
            d.LoadXml(xml);
            System.Xml.XmlCDataSection n = d.SelectSingleNode("/xml/ToUserName").FirstChild as System.Xml.XmlCDataSection;

            notice.ToUserName = n.Value;

            n = d.SelectSingleNode("/xml/FromUserName").FirstChild as System.Xml.XmlCDataSection;
            notice.FromUserName = n.Value;

            //n = d.SelectSingleNode("/xml/CreateTime").FirstChild as System.Xml.XmlCDataSection;
            //notice.CreateTime = n.Value;

            n = d.SelectSingleNode("/xml/MsgType").FirstChild as System.Xml.XmlCDataSection;
            notice.MsgType = n.Value;

            n = d.SelectSingleNode("/xml/Content").FirstChild as System.Xml.XmlCDataSection;
            notice.Content = n.Value;

            //n = d.SelectSingleNode("/xml/MsgId").FirstChild as System.Xml.XmlCDataSection;
            //notice.MsgId = n.Value;

            return notice;
        }

        /// <summary>
        /// 消息内容
        /// </summary>
        public string Content
        {
            get;
            set;
        }
    }

 location.cs,此类表示地理位置消息类,除了有BaseNotice中有的属性外,还有Location_X(纬度),Location_Y(经度)等信息。实现代码与text.cs差不多,这里就不再贴了。

BaseHandler.cs,表示处理消息的基类,定义了一个抽象方法HandleNotice,由具体处理类,去实现,代码比较简单,如下:

 /// <summary>
    /// 处理消息基类
    /// </summary>
    public abstract class BaseHandler
    {
        protected BaseNotice notice;

        public BaseHandler(BaseNotice _notice)
        {
            notice = _notice;
        }

        /// <summary>
        /// 处理消息,每个子类重写此法
        /// </summary>
        /// <returns></returns>
        public abstract string HandleNotice();

    }

  TextHandler.cs,此类表示处理文本信息的类,对用户发送的文本进行处理,然后返回相关信息。按上面的描述,发送“d”或者“订单”,返回今天的订单,其他文本,直接返回说明信息。代码如下:

/// <summary>
    /// 文本信息处理类
    /// </summary>
    public class TextHandler : BaseHandler
    {
        public TextHandler(BaseNotice _notice)
            : base(_notice)
        {

        }

        /// <summary>
        /// 文本信息处理方法,如果文本信息 = d,返回今天订单
        /// </summary>
        /// <returns></returns>
        public override string HandleNotice()
        {
            StringBuilder backmsg = new StringBuilder();
            text model = (text)base.notice;

            backmsg.Append("<xml>");
            backmsg.Append("<ToUserName><![CDATA[" + model.FromUserName + "]]></ToUserName>");
            backmsg.Append("<FromUserName><![CDATA[" + model.ToUserName + "]]></FromUserName>");
            backmsg.Append("<CreateTime>" + DateTime.Now.Ticks + "</CreateTime>");

            string Content = "";

            if (model.Content.ToLower().Trim() == "d" || model.Content.ToLower().IndexOf("订单") >= 0)
            {
                ETogoOrder dal = new ETogoOrder();

                StringBuilder ordermsg = new StringBuilder("");

                IList<ETogoOrderInfo> orderlist = dal.GetList(3, 1, " tempcode=‘" + model.ToUserName + "‘ and ordertime > ‘"+DateTime.Now.ToShortDateString()+"‘ ", "dataid", 1);
                if (orderlist.Count > 0)
                {
                    ordermsg.Append("今日订单");

                    foreach (var item in orderlist)
                    {
                        ordermsg.Append("\r\n订单号:");
                        ordermsg.Append("\r\n" + item.OrderID);
                        ordermsg.Append("\r\n订单时间:" + item.orderTime.ToShortTimeString());
                        ordermsg.Append("\r\n订单状态:" + ConfigHelper.TurnOrderState(item.State));

                        IList<FoodInOrderInfo> foodlist = new EOrderFood().GetAllByOrderID(item.OrderID);
                        foreach (var food in foodlist)
                        {
                            ordermsg.Append("\r\n" + food.FoodName + "(" + food.FoodPrice + "x" + food.Num + ")");
                        }

                        ordermsg.Append("\r\n==================");
                    }

                }
                else
                {
                    ordermsg.Append("您今天还没有订餐点哦");
                    ordermsg.Append("\r\n==================");
                }
                Content = ordermsg.ToString();

            }
            else//其他地方返回原信息
            {
                Content = ConfigHelper.GetConfigBackMsg();
            }
            backmsg.Append("<Content><![CDATA[" + Content.ToString() + "]]></Content>");
            backmsg.Append(" <MsgType><![CDATA[text]]></MsgType>");
            backmsg.Append(" </xml> ");

            return backmsg.ToString();
        }
    }

 LocationHandler.cs,此类用于处理地理位置信息,和TextHandler.cs代码差不多,就是实现了HandleNotice方法。

NoticeFactory.cs,此类表示根据消息类型,返回具体处理类,用了简单工厂,每次要增加具体消息处理类,这还要加个分支,有点纠结,代码如下:

/// <summary>
    /// 根据消息类型,返回对像
    /// </summary>
    public class NoticeFactory
    {
        const string AssemblyPath = "Hangjing.Weixin";//用于反射
        public static BaseHandler CreateInstance(string xml)
        {
            BaseHandler handler = null;
            //解析数据
            System.Xml.XmlDocument d = new System.Xml.XmlDocument();
            d.LoadXml(xml);
            System.Xml.XmlCDataSection n = d.SelectSingleNode("/xml/MsgType").FirstChild as System.Xml.XmlCDataSection;
            HJlog.toLog("MsgType=" + n.Value);

            Type type = Type.GetType(string.Format(AssemblyPath + ".{0}," + AssemblyPath, n.Value.Trim()), false, true);
            BaseNotice noticemodel = (BaseNotice)Activator.CreateInstance(type);

            if (noticemodel != null)
            {
                noticemodel = noticemodel.LoadXml(xml);
                switch (noticemodel.MsgType)
                {
                    case "text":
                        handler = new TextHandler(noticemodel);
                        break;
                    case "event":
                        handler = new EventHandler(noticemodel);
                        break;
                    case "location":
                        handler = new LocationHandler(noticemodel);
                        break;
                    default:
                        break;
                }
            }
            else
            {
                HJlog.toLog("noticemodel=mull");
            }

            return handler;
        }
    }

 weixinHelper.cs,此类封装了一些基本操作,如验证消息是否来来自微信服务器,获取微信服务器post来的消息,最主要的还是处理消息的地方,不管添加多少消息类型,这里都不用修改,代码如下:

 /// <summary>
        /// 根据接到的信息,返回内容
        /// </summary>
        /// <returns></returns>
        public string HandleData()
        {
            string userdata = reciveData();

            string backmsg = "";

            BaseHandler handler = NoticeFactory.CreateInstance(userdata);//根据不同消息类型,返回具体处理类,
            if (handler != null)
            {
                backmsg = handler.HandleNotice();
                HJlog.toLog("handler != null " + backmsg);
            }
            else
            {
                HJlog.toLog("handler == null ");
            }

            return backmsg.ToString();
        }

客户端(指在公众平台设置的那个链接)代码就相对简单了(不过判断是否网站接入的不知道是什么时间调用的),代码如下:

protected void Page_Load(object sender, EventArgs e)
    {
        weixinHelper wx = new weixinHelper(Context);

        if (wx.isJoin())//如果是网站接入
        {
            Response.Write(wx.isValidRequest());
            Response.End();
            //HJlog.toLog("如果是网站接入");
            return;
        }
        else//接收消息
        {
            Response.Write(wx.HandleData());
            //HJlog.toLog("接收消息");
            Response.End();
            return;
        }

    }

通过返回的链接,进入网站后,就全是html5的事儿了,第一次写,还真是用了不少时间。写得不好,代码就不贴了,上几个截图吧【html5界面为我家妞妞制作,妞妞辛苦了^_^】:

 
  

以上就是微信点餐相关内容了,其实也就那点事儿,写得不好,见谅,有兴趣的就扫一扫吧,如果你也开发这方便的,一起交流下:

                        

时间: 2025-01-04 02:37:55

订餐系统之微信点餐的相关文章

订餐系统之微信支付

    最近一个项目要增加微信支付的功能,想来这个东西出来这么久了,按微信提供的应该可以很快搞定的,结果提供的demo( JS API网页支付)中各种坑,咨询他们的客服,态度倒是非常好,就是解决不了问题,最后让我发邮件,一想,这个邮件一来一回至少又得好几个小时,没有办法只能根据开发文档一个一个核对,再加上些猜想,终于完成了.为了别的朋友少踩些坑,特此小文,希望对一此朋友有所帮助. 准备工作 当然,要集成微信支付,首先还是要先有一个微网站,熟悉的请飘过,不了解的,可以参考下我之前的一篇小文 订餐系

用微信点单 订餐系统打造属于个人的O2O外卖订餐行业商业平台

首先,我不能说我是一个成功的微信达人,我也不能说我是一个优秀的互联网专家,但我就目前所使用的一套订餐系统来讲,正在逐渐的规划一个餐饮行业的商业圈! 我所使用的系统叫"微铺子订餐系统",所购买的是[豪华旗舰版],最主要的功能就是:不限制店铺个数!就是看到这点才选择的这套系统!下面我详细说一下思路. 1.建立一个独立平台官网,便于宣传平台,增加可信度.官网不用太花哨,简单明了,毕竟咱是做微信平台的,还是尽量把客户引到微信来,所以,我准备在主页只放一个大的微信二维码,提示客户,我们只针对微信

微铺子点单系统详细介绍 - 争做国内最专业的微信商店平台,微信外卖订餐系统!

什么是微铺子? 微铺子是国内专业的微信点单系统,集成了外卖.点餐.订座等众多功能.通过微铺子,店家可以在微信上建立店铺,消费者只需关注店家的帐号,即可浏览商品与店家的信息,消费者关注到商家后,根据提示,进行点击点单,简单三步,15秒内,即可完成订餐.店家可以通过电脑后台.电子邮件.短信或无线打印机多种方式即时查看订单,并提供相应的服务. 微铺子系统适用于:餐饮.酒店.水果店.蛋糕店.花店.零售.超市等. 微铺子从创立到与合作商家的长期测试,再到正式投入商用,期间不断根据客户的需求完善产品,不断开

微铺子点单系统具体介绍 - 争做国内最专业的微信商店平台,微信外卖订餐系统!

什么是微铺子? 微铺子是国内专业的微信点单系统,集成了外卖.点餐.订座等众多功能.通过微铺子,店家能够在微信上建立店铺,消费者仅仅需关注店家的帐号,就可以浏览商品与店家的信息,消费者关注到商家后,依据提示,进行点击点单,简单三步,15秒内,就可以完毕订餐.店家能够通过电脑后台.电子邮件.短信或无线打印机多种方式即时查看订单,并提供对应的服务. 微铺子系统适用于:餐饮.酒店.水果店.蛋糕店.花店.零售.超市等. 微铺子从创立到与合作商家的长期測试,再到正式投入商用,期间不断依据客户的需求完好产品,

Python Flask构建微信小程序订餐系统

call--->q-2304636824-q 第1章 <Python Flask构建微信小程序订餐系统>课程简介 本章内容会带领大家通览整体架构,功能模块,及学习建议.让大家在一个清晰的开发思路下,进行后续的学习.同时领着大家登陆https://food.54php.cn(使用微信扫码二维码体验下哦横须)一起来演示一下项目.本次课程是严格按照商业系统进行架构开发的,从PC管理员端到小程序会员端,从项目搭建到部署上线,通俗易懂.... 1-1 导学--Python Flask 构建微信小程

微铺子微信送餐系统 针对大学生兼职创业的实施方案

大学生活丰富多彩,但大多数人还是觉得虚度光阴,如何充分利用这些业余时间,发展自己的兼职业务呢?这里,微铺子给大家简单介绍一下大学生如何在校期间,利用微信送餐系统,自主创业! 微信就不多介绍了,几乎人手都有,那么,我们就好好的利用微信,来一次校园微营销! 准备工具: 1.微信公众帐号 2.微铺子系统 首先到微铺子官网注册帐号 ,然后申请试用,这里我们免费提供7天的试用哦. 接着,在配置里面,绑定微信公众帐号即可. 系统我们是有了,那如何营销呢? 这里,我们拿"校园卖水果"来说,我们开一个

www.vpuzi.cn微铺子微信订餐系统 - 餐饮O2O创业硝烟弥漫 草根创业者如何立足?

(中国电子商务研究中心讯)2014年以淘点点为代表的BAT大佬们杀入餐饮O2O市场了,当餐饮O2O市场狼烟四起.硝烟弥漫,大众点评网.美团和糯米团都在虎视眈眈,草根创业者还有没有机会呢? 中国有上千家的餐饮软件企业,他们在餐饮业扎根多年,难道这一次他们会全军覆没?餐饮O2O市场真的只是资本的战争吗?难道这些平常习惯于空中作战的大佬们深入餐饮腹地依然能够所向无敌?他们所到之处真的会寸草不生?真的会赢者通吃吗?今天,我们就来解析草根餐饮O2O创业者的发展机会. 首先,我认为,以淘点点为代表的BAT大

java Spring Boot企业微信点餐系统

 java Spring Boot企业微信点餐系统 后端开发: 1.2017龙果微服务架构的分布式事务解决方案 2.2017年龙果spring boot 入门实战视频教程-首套中文教程 3.51CTO Spring Boot实战与原理分析视频课程 4.ElasticSearch5视频教程 5.Elasticsearch顶尖高手系列:高手进阶篇(最新第二版) 6.IDEA学习视频 7.Java 微服务实践 - Spring Boot 系列 8.JAVA-ACE-架构师系列视频课程-RocketMQ

基于Springboot+SpringCloud的微信点餐系统开发视频教程

基于Springboot+SpringCloud的微信点餐系统开发视频教程课程分享链接:https://pan.baidu.com/s/1q7h9zn8sGf_e0k38pc69tw 密码:fk9w 随着互联网不断发展,大家的生活习惯也不断在改变,像美团,饿了么平台的外卖快速的发展起来,这就是我们所说的O2O,即线上和线下结合同时微信也给人们带来了沟通的便利,现在几乎每个年轻人都会有微信号,所以我们开发微信点餐系统,也是极大方便了大家的使用,只要在打开微信进入我们的点餐系统就可以方便的进行点餐.