微信公众号开发

1.首先有一个公众号(服务号);

2.登陆微信公众平台设置Url(注意这个url是入口地址,每次请求都要从这个地址进)以及Token

3.公众号的基本设置就到此结束,其他的设置用到时再来设置。接下来就是写代码:

  3.1自定义公众号菜单:

     先获取Access_Token

using Common;
using System.Timers;

namespace Common
{
    /// <summary>
    /// 获取Access_Token
    /// </summary>
    public static class AccessTokenUtil
    {
        private static readonly string FILENAME = "AccessTokenUtil.cs";
        // AccessToken
        private static string AccessToken = "";
        // 超时时间
        private static int Expires_in = 7200;
        private static Timer timer = null;

        public static string GetAccessToken()
        {
            if (string.IsNullOrEmpty(AccessToken))
            {
                // 获取Token并定时刷新
                string httpcontent = GetTokenHttp();
                bool result = FormatResult(httpcontent);

                if (result == true)
                {
                    // 设置定时器
                    if (timer != null)
                    {
                        timer.Dispose();
                    }

                    timer = new Timer();
                    timer.Elapsed += delegate 
                    {
                        string httpcontent2 = GetTokenHttp();
                        bool result2 = FormatResult(httpcontent);
                        if (!result2)
                        {
                            LogHelper.FileNameError(FILENAME, string.Format("Timer获取Token失败"));
                        }
                    };
                    timer.Interval = Expires_in * 1000 / 2;
                }
                else
                {
                    LogHelper.FileNameError(FILENAME, string.Format("获取Token失败"));
                }
            }

            return AccessToken;
        }

        /// <summary>
        /// 发送请求获取AccessToken
        /// </summary>
        /// <returns></returns>
        private static string GetTokenHttp()
        {
            string url = "https://api.weixin.qq.com/cgi-bin/token";

            string appid = System.Configuration.ConfigurationManager.AppSettings["appid"];
            string appsecret = System.Configuration.ConfigurationManager.AppSettings["appsecret"];
            string param = string.Format("grant_type=client_credential&appid={0}&secret={1}", appid, appsecret);

            string result = HttpUtils.HttpGet(url, param);

            LogHelper.FileNameInfo(FILENAME, string.Format("access_token接收到的数据:{0}", result));
            return result;
        }

        private static bool FormatResult(string result)
        {
            AccessTokenResult resultObj = fastJSON.JSON.ToObject<AccessTokenResult>(result);
            if (!string.IsNullOrEmpty(resultObj.access_token))
            {
                AccessToken = resultObj.access_token;
                Expires_in = resultObj.expires_in;
                return true;
            }
            else
            {
                LogHelper.FileNameError(FILENAME, string.Format("获取失败,返回码:{0}, 错误信息:{1}", resultObj.errcode, resultObj.errmsg));
                return false;
            }
        }

        public class AccessTokenResult
        {
            public string access_token { get; set; }
            public int expires_in { get; set; }
            public string errcode { get; set; }
            public string errmsg { get; set; }
        }
    }
}

menu.txt

{
    "button":[
    {
            "type":"view",
            "name":"订水",
            "url":"http://wx."
    },
    {

           "type":"view",
           "name":"商城",
           "sub_button":[
           {    
               "type":"view",
               "name":"我的商城",
               "url":"http://wx"
            },
            {
                 "type":"view",
                 "name":"我的订单",
                 "url":"http://wx."
             },
            {
               "type":"view",
               "name":"我的地址",
               "url":"http://wx.sil"
            }]

    },
    {
            "type":"view",
            "name":"关于",
           "sub_button":[
           {    
               "type":"view",
               "name":"锶的作用",
               "url":"https://mp.weixin-KQ3Q"
            },
            {
                 "type":"view",
                 "name":"关于锶享家",
                 "url":"https://mp.weixin"
             },
            {
               "type":"view",
               "name":"联系我们",
               "url":"http://wx"
            }]
    }]
}

请求微信接口创建菜单

using Common;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace weixin_api
{
    public partial class createMenu : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            FileStream fs1 = new FileStream(Server.MapPath(".") + "\menu.txt", FileMode.Open);
            StreamReader sr = new StreamReader(fs1, Encoding.GetEncoding("GBK"));
            string menu = sr.ReadToEnd();
            sr.Close();
            fs1.Close();

            string token = AccessTokenUtil.GetAccessToken();
            GetPage("https://api.weixin.qq.com/cgi-bin/menu/create?access_token=" + token, menu);
        }
        public string GetPage(string posturl, string postData)
        {
            Stream outstream = null;
            Stream instream = null;
            StreamReader sr = null;
            HttpWebResponse response = null;
            HttpWebRequest request = null;
            Encoding encoding = Encoding.UTF8;
            byte[] data = encoding.GetBytes(postData);
            // 准备请求...
            try
            {
                // 设置参数
                request = WebRequest.Create(posturl) as HttpWebRequest;
                CookieContainer cookieContainer = new CookieContainer();
                request.CookieContainer = cookieContainer;
                request.AllowAutoRedirect = true;
                request.Method = "POST";
                request.ContentType = "application/x-www-form-urlencoded";
                request.ContentLength = data.Length;
                outstream = request.GetRequestStream();
                outstream.Write(data, 0, data.Length);
                outstream.Close();
                //发送请求并获取相应回应数据
                response = request.GetResponse() as HttpWebResponse;
                //直到request.GetResponse()程序才开始向目标网页发送Post请求
                instream = response.GetResponseStream();
                sr = new StreamReader(instream, encoding);
                //返回结果网页(html)代码
                string content = sr.ReadToEnd();
                string err = string.Empty;
                Response.Write(content);
                return content;
            }
            catch (Exception ex)
            {
                string err = ex.Message;
                return string.Empty;
            }
        }
    }
}

调接口之前还要在微信平台里面添加白名单即将本地的ip地址加进去,不然请求出错。接口调用成功后取消关注重新关注公众号就能看到创建的菜单。

3.2 菜单创建完成后接下来就是拿到用户信息存在数据库里面,在我们关注或取消关注的时候微信会给我们上面的填写的Url发送请求,所以在这个url(我这个是wxapi.aspx)对应的页面里面就可以拿到用户信息以及用户操作类型(关注事件还是取消事件等)

using Common;
using DAL;
using fastJSON;
using Model;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Xml;
using System.Xml.Linq;
using weixin_api.ViewModels;

namespace weixin_api
{
    public partial class wxapi : System.Web.UI.Page
    {
        private readonly string FILENAME = "wxapi.aspx";
        private static List<BaseMsg> _queue = null;
        protected void Page_Load(object sender, EventArgs e)
        {
            LogHelper.FileNameInfo(FILENAME, "收到服务器消息");

            // 取参数 signature、timestamp、nonce、encrypt_type、msg_signature
            string echoString = Request.QueryString["echoStr"];
            string signature = Request.QueryString["signature"];
            string timestamp = Request.QueryString["timestamp"];
            string nonce = Request.QueryString["nonce"];
            string encrypt_type = Request.QueryString["encrypt_type"];
            string msg_signature = Request.QueryString["msg_signature"];

            LogHelper.FileNameInfo(FILENAME, string.Format("参数分别是, echoString={0}, signature={1}, timestamp={2}, nonce={3},encrypt_type={4},msg_signature={5}", echoString, signature, timestamp, nonce, encrypt_type, msg_signature));

            if (!string.IsNullOrEmpty(echoString))
            {
                Response.Write(echoString);
                Response.End();
                return;
            }

            // 验证签名
            string token = System.Configuration.ConfigurationManager.AppSettings["Token"];
            if (!ParamCheck(signature, timestamp, nonce, echoString, token))
            {
                LogHelper.FileNameError(FILENAME, string.Format("服务器验证失败"));
                Response.End();
                return;
            }

            // 接收消息
            if (Request.HttpMethod.ToUpper() == "POST")
            {
                string str = ConvertUtils.StreamToString(Request.InputStream);
                LogHelper.FileNameInfo(FILENAME, "接收到的事件数据:" + str);


                //解密
                //公众平台上开发者设置的token, appID, EncodingAESKey
                string sToken = System.Configuration.ConfigurationManager.AppSettings["Token"];
                string sAppID = System.Configuration.ConfigurationManager.AppSettings["appid"];
                string sEncodingAESKey = System.Configuration.ConfigurationManager.AppSettings["EncodingAESKey"];

                WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(sToken, sEncodingAESKey, sAppID);
                string sMsg = "";  //解析之后的明文
                int ret = 0;
                ret = wxcpt.DecryptMsg(msg_signature, timestamp, nonce, str, ref sMsg);
                if (ret != 0)
                {
                    LogHelper.FileNameInfo(FILENAME, string.Format("解密失败:" + ret));
                    Response.End();
                    return;
                }

                // 判断队列是否超额
                if (_queue == null)
                {
                    _queue = new List<BaseMsg>();
                }
                else if (_queue.Count >= 50)
                {
                    // 保留20秒内未响应的消息
                    _queue = _queue.Where(q => { return q.CreateTime.AddSeconds(20) > DateTime.Now; }).ToList();
                }
                //这是解密出来的结果
                //<xml><ToUserName><![CDATA[gh_9fca63d34597]]></ToUserName>
                //<FromUserName><![CDATA[orhx-5o9]]></FromUserName>
                //<CreateTime>1557123110</CreateTime>
                //<MsgType><![CDATA[event]]></MsgType>
                //<Event><![CDATA[VIEW]]></Event>
                //<EventKey><![CDATA[http://wx.s/gzh_Ping.html]]></EventKey>
                //<MenuId>471589802</MenuId>
                //</xml>
                XElement xdoc = XElement.Parse(sMsg);
                var FromUserName = GetXmlElement(xdoc, "FromUserName");
                var CreateTime = GetXmlElement(xdoc, "CreateTime");
                var msgtype = GetXmlElement(xdoc, "MsgType").ToUpper();
                var MsgId = FromUserName + CreateTime;
                string openid = GetXmlElement(xdoc, "FromUserName");
                if (string.IsNullOrEmpty(openid))
                {
                    LogHelper.FileNameInfo(FILENAME, string.Format("没有获取到当前用户的openid"));
                    Response.Write("");
                    Response.End();
                    return;
                }

                GlobalInfo.openid = openid;

                MsgType type = (MsgType)Enum.Parse(typeof(MsgType), msgtype);

                if (type == MsgType.EVENT)
                {
                    try
                    {
                        // 事件消息
                        if (_queue.FirstOrDefault(m => { return m.MsgFlag == MsgId; }) == null)
                        {
                            _queue.Add(new BaseMsg
                            {
                                CreateTime = DateTime.Now,
                                FromUser = FromUserName,
                                MsgFlag = MsgId
                            });
                        }
                        else
                        {
                            Response.Write("");
                            Response.End();
                            return;
                        }
                        EventMsg(new EventModel
                        {
                            ToUserName = GetXmlElement(xdoc, "ToUserName"),
                            FromUserName = GetXmlElement(xdoc, "FromUserName"),
                            CreateTime = GetXmlElement(xdoc, "CreateTime"),
                            MsgType = GetXmlElement(xdoc, "MsgType"),
                            Event = GetXmlElement(xdoc, "Event"),
                            EventKey = GetXmlElement(xdoc, "EventKey"),
                            MenuId = GetXmlElement(xdoc, "MenuId")
                        });
                        return;
                    }
                    catch (Exception ex)
                    {
                        LogHelper.FileNameInfo(FILENAME, "事件消息处理出现异常" + ex.Message);
                    }
                }
                else
                {
                    Response.Write("");
                    Response.End();
                    return;
                }
            }

            LogHelper.FileNameInfo(FILENAME, "未知消息");
            Response.End();
            return;
        }
        /// <summary>
        /// 验证参数
        /// </summary>
        /// <returns></returns>
        private bool ParamCheck(string signature, string timestamp, string nonce, string echostr, string token)
        {
            List<string> list = new List<string>();
            list.Add(token);
            list.Add(timestamp);
            list.Add(nonce);
            list.Sort();

            string str = string.Join("", list);
            string shaStr = SHA1Common.SHA1(str);

            LogHelper.FileNameInfo(FILENAME, string.Format("sha结果:{0}, signature={1}", shaStr, signature));

            if (!string.IsNullOrEmpty(signature) && !string.IsNullOrEmpty(shaStr) && signature.ToUpper().Equals(shaStr.ToUpper()))
            {
                return true;
            }

            return false;
        }

        private void EventMsg(EventModel model)
        {
            LogHelper.FileNameInfo(FILENAME, "接收到事件:" + model.Event);
            switch (model.Event)
            {
                case "subscribe":
                    SubscribeEvent(model);
                    break;
                case "unsubscribe":
                    UnSubscribeEvent(model);
                    break;
                default: break;
            }
        }

        /// <summary>
        /// 订阅事件
        /// </summary>
        /// <param name="model"></param>
        private void SubscribeEvent(EventModel model)
        {
            try
            {
                 //发请求获取用户信息
                string url = "https://api.weixin.qq.com/cgi-bin/user/info";
                string access_token = AccessTokenUtil.GetAccessToken();
                string param = string.Format("access_token={0}&openid={1}&lang=zh_CN", access_token, model.FromUserName);
                string result = Common.HttpUtils.HttpGet(url, param);
                wx_user user = JSON.ToObject<wx_user>(result);
                wx_userDal wxUserDal = new wx_userDal();
                if (wxUserDal.Exists(user.openid))
                {
                    // 已存在,更新关注属性为1
                    wxUserDal.UpdateSubscribe(user.openid, 1, (long)user.subscribe_time);
                }
                else
                {
                    // 添加到数据库
                    user.balance = 0;
                    int n = wxUserDal.Add(user);
                    if (n != 1)
                    {
                        LogHelper.FileNameError(FILENAME, string.Format("用户订阅失败, openid:{0}", user.openid));
                    }
                }

                string r = sendTextMessage(model, System.Configuration.ConfigurationManager.AppSettings["DefaultWxMsg"]);
                HttpContext.Current.Response.Write(r);
                HttpContext.Current.Response.End();


            }
            catch (Exception e)
            {
                LogHelper.FileNameError(FILENAME, e.Message);
            }
        }

        /// <summary>
        /// 取消订阅事件
        /// </summary>
        /// <param name="model"></param>
        private void UnSubscribeEvent(EventModel model)
        {
            // 把数据库是否订阅字段改为0
            try
            {
                wx_userDal wxUserDal = new wx_userDal();
                wxUserDal.UpdateSubscribe(model.FromUserName, 0, Common.CommonUtils.GetTimeStamp());
            }
            catch (Exception e)
            {
                LogHelper.FileNameError(FILENAME, e.Message);
            }
        }

        private string GetXmlElement(XElement element, string nodeName)
        {
            if (element == null || string.IsNullOrEmpty(nodeName))
            {
                return string.Empty;
            }

            if (element.Element(nodeName) != null)
            {
                return element.Element(nodeName).Value;
            }

            return string.Empty;
        }


        #region 关注后自动回复
        /// <summary>  
        /// 发送文字消息  
        /// </summary>  
        /// <param name="wx" />获取的收发者信息  
        /// <param name="content" />内容  
        /// <returns></returns>  
        private string sendTextMessage(EventModel wx, string content)
        {
            string res = string.Format(Message_Text,
                wx.FromUserName, wx.ToUserName, DateTime.Now.Ticks, content);
            return res;
        }
        /// <summary>
        /// 普通文本消息
        /// </summary>
        private static string Message_Text
        {
            get
            {
                return @"<xml>
                            <ToUserName><![CDATA[{0}]]></ToUserName>
                            <FromUserName><![CDATA[{1}]]></FromUserName>
                            <CreateTime>{2}</CreateTime>
                            <MsgType><![CDATA[text]]></MsgType>
                            <Content><![CDATA[{3}]]></Content>
                            </xml>";
            }
        }

        #endregion


        #region 模型
           public class BaseMsg
        {
            /// <summary>
            /// 发送者标识
            /// </summary>
            public string FromUser { get; set; }
            /// <summary>
            /// 消息表示。普通消息时,为msgid,事件消息时,为事件的创建时间
            /// </summary>
            public string MsgFlag { get; set; }
            /// <summary>
            /// 添加到队列的时间
            /// </summary>
            public DateTime CreateTime { get; set; }
        }

        public enum MsgType
        {
            /// <summary>
            ///文本类型
            /// </summary>
            TEXT,
            /// <summary>
            /// 图片类型
            /// </summary>
            IMAGE,
            /// <summary>
            /// 语音类型
            /// </summary>
            VOICE,
            /// <summary>
            /// 视频类型
            /// </summary>
            VIDEO,
            /// <summary>
            /// 地理位置类型
            /// </summary>
            LOCATION,
            /// <summary>
            /// 链接类型
            /// </summary>
            LINK,
            /// <summary>
            /// 事件类型
            /// </summary>
            EVENT
        }

        public enum Event
        {
            /// <summary>
            /// 非事件类型
            /// </summary>
            NOEVENT,
            /// <summary>
            /// 订阅
            /// </summary>
            SUBSCRIBE,
            /// <summary>
            /// 取消订阅
            /// </summary>
            UNSUBSCRIBE,
            /// <summary>
            /// 扫描带参数的二维码
            /// </summary>
            SCAN,
            /// <summary>
            /// 地理位置
            /// </summary>
            LOCATION,
            /// <summary>
            /// 单击按钮
            /// </summary>
            CLICK,
            /// <summary>
            /// 链接按钮
            /// </summary>
            VIEW,
            /// <summary>
            /// 扫码推事件
            /// </summary>
            SCANCODE_PUSH,
            /// <summary>
            /// 扫码推事件且弹出“消息接收中”提示框
            /// </summary>
            SCANCODE_WAITMSG,
            /// <summary>
            /// 弹出系统拍照发图
            /// </summary>
            PIC_SYSPHOTO,
            /// <summary>
            /// 弹出拍照或者相册发图
            /// </summary>
            PIC_PHOTO_OR_ALBUM,
            /// <summary>
            /// 弹出微信相册发图器
            /// </summary>
            PIC_WEIXIN,
            /// <summary>
            /// 弹出地理位置选择器
            /// </summary>
            LOCATION_SELECT,
            /// <summary>
            /// 模板消息推送
            /// </summary>
            TEMPLATESENDJOBFINISH
        }
        #endregion
    }
}

 3.3 菜单完了、用户信息存了,接下来就是 具体的功能实现新建页面,在网上找一个公众号开发的框架比如我用的是weui,去官网下载。

比如一个简单的购买水的页面

代码:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=0" />
    <link href="static/weui-master/css/weui.css" rel="stylesheet" />
    <link href="static/weui-master/css/weuix.css" rel="stylesheet" />
    <script src="static/weui-master/js/zepto.min.js"></script>
    <script src="static/weui-master/js/zepto.weui.js"></script>
    <script src="static/weui-master/js/axios.min.js"></script>
    <script src="static/weui-master/js/zepto.weui.js"></script>
    <script src="static/weui-master/js/zepto.min.js"></script>
    <title>产品列表</title>
    <style>
        .lab {
            font-size: 15px;
            color: gray;
        }

        .price {
            color: red;
        }

        .page-bg {
            /*background-color:orange;*/
        }

        .weui-cells {
            margin-top: 0.5em;
        }

        .goumai {
            position: relative;
            top: 20px;
        }

        .weui-count {
            position: relative;
            top: 9px;
        }

        #goodslist {
            margin-bottom: 50px;
        }

        .weui_media_title {
            font-size: 13px;
        }

        .car {
            font-size: 8px;
            -o-border-radius: 100%;
            -ms-border-radius: 100%;
            -moz-border-radius: 100%;
            -webkit-border-radius: 100%;
        }

        .weui-cell__ft {
            text-align: center;
        }

        .weui-btn_mini {
            line-height: 2.1;
        }
        * {
            touch-action: pan-y;
        }
    </style>
    <script>
        $(function () {

            $('.weui-tab').tab({
                defaultIndex: 0,
                activeClass: 'weui-bar__item_on',
                onToggle: function (index) {
                    if (index > 0) {
                        if (index == 1) {
                            var spanCar = parseInt($('#spanCar').text());  //购物车里面数量
                            if (spanCar <= 0) {
                                $.toast("购物车太空啦。", "forbidden");
                            } else {
                                window.location.href = "gzh_ManageCar.html";
                            }
                        }
                    }
                }
            })
        })

    </script>

</head>
<body ontouchstart class="page-bg">
    <div class="weui-pull-to-refresh__layer">
        <div class='weui-pull-to-refresh__arrow'></div>
        <div class='weui-pull-to-refresh__preloader'></div>
        <div class="down">下拉刷新</div>
        <div class="up">释放刷新</div>
        <div class="refresh">正在刷新</div>
    </div>

    <div class="weui-cells" id="goodslist">
    </div>


    <div class="weui-tab tab-bottom " style="height:44px;z-index:100;">
        <div class="weui-tabbar">

            <a href="javascript:;" class="weui-tabbar__item">
                <span style="display: inline-block;position: relative;">
                    <i class="icon icon-67 f27"></i>
                    <span class="weui-badge" style="position: absolute;top: -2px;right: -13px;" id="ResPrice">¥0.0</span>
                </span>
                <p class="weui-tabbar__label">本次消费</p>
            </a>
            <a href="javascript:;" class="weui-tabbar__item">
                <span style="display: inline-block;position: relative;">
                    <i class="icon icon-24 f27 weui-icon-warn"></i>
                    <span class="weui-badge" style="position: absolute;top: -2px;right: -13px;" id="spanCar">0</span>
                </span>
                <p class="weui-tabbar__label">购物车</p>
            </a>

            <!--<a href="javascript:;" class="weui-tabbar__item weui-icon-warn">
                <i class="icon icon-43 f27 weui-icon-waiting"></i>
                <p class="weui-tabbar__label">去结算</p>
            </a>-->
            <!--<a href="javascript:;" class="weui-btn bg-orange">快去结算</a>-->
        </div>
    </div>

    <script type="text/javascript">
        //全局变量
        var load = false; // load为判断接口是否请求完成,防止多次触摸、多次点击导致接口的多次请求出错
        var page = 1;//默认第一页
        var pageSize = 20;  //默认一页显示6条数据
        $(function () {
            $(document.body).pullToRefresh({
                distance: 10,
                onRefresh: function () {
                    getData(page, "api/GetTicketListJson.ashx"); //初始化数据从第一页数据开始请求
                    getCar();
                    $(document.body).pullToRefreshDone();

                }
            });
            getData(page, "api/GetTicketListJson.ashx"); //初始化数据从第一页数据开始请求
            getCar();
            var MAX = 99, MIN = 0;
            $('.weui-count__decrease').click(function (e) {
                var id = $(this).attr("tag");
                var $input = $(e.currentTarget).parent().find('.weui-count__number');
                var number = parseInt($input.val() || "0") - 1
                if (number == 0) {
                    $('#des' + id).hide();
                }
                if (number < MIN) {
                    number = MIN;
                    return;
                }
                $input.val(number)
            })
            $('.weui-count__increase').click(function (e) {
                var id = $(this).attr("tag");var $input = $(e.currentTarget).parent().find('.weui-count__number');
                var number = parseInt($input.val() || "0") + 1
                if (number > MAX) number = MAX;
                $input.val(number)
            })

        });

        //请求后台数据
        function getData(page, url) {  //请求接口的方法,方法带page,url两个参数。
            $('#more').text('正在加载中...');
            $.ajax({
                url: url,  //请求接口的url
                type: 'get',//请求方式(post或get)默认为get
                async: false,  //默认情况下是true表示所有请求为异步请求,如果要为同步则用false
                dataType: "json",
                data: {
                    'page': page,
                    'limit': pageSize,
                    'name': ''  //$("#searchInput").val()
                },
                success: function (data) {  //请求成功调用的回调函数
                    if (data != null && data.code == 0) {
                        $("#pageNum").val(parseInt(data.currentPage) + 1);
                        showList(data);
                        if (data.currentPage >= data.totalPage) { //这里判断接口数据是否到底部
                            load = true;
                            $("#more").html('已经到底了');
                        } else if (data.currentPage < data.totalPage) {
                            load = false;
                            $("#more").html('查看更多');
                        }
                    }
                },
                error: function (error) { //请求失败调用的回调函数
                    console.log(error);
                }
            });
        }
        //查询当前用户的购物车信息
        function getCar() {
            axios.post('api/AddCar.ashx?goodId=0&numType=0')
                 .then(function (rs) {
                     if (rs.data.result) {
                         $('#spanCar').text(rs.data.code);
                     }
                 })
            .catch(function (e) {

            });
        }

        //显示数据
        function showList(data) {   //显示列表的html内容
            $("#goodslist").html("");
            for (var i = 0; i < data.list.length; i++) {
                var html = "<div class='weui-cell weui-cell_swiped'><div class='weui-cell__bd'><div class='weui-cell'><div class='weui-cell__hd'>"
                html += "<img src='" + data.list[i].imgurl + "' alt='' style='60px;margin-right:5px;display:block'>";
                html += "</div>";  //img外面的div结束
                html += "<div class='weui-cell__bd'><span class='weui_media_title product-buttom'>" + data.list[i].title + "</span><br><span class='lab'>规格:" + data.list[i].regulation + "</span><span id='spanPrice" + data.list[i].id + "' class='lab price'>¥" + data.list[i].price + "</span>";
                html += "</div>";  //标题 单价 规格 外面的div结束
                html += "<div class='weui-cell__ft'><div class='weui-count'><a class='weui-count__btn weui-count__decrease' style='display:none;' id='des" + data.list[i].id + "' tag=" + data.list[i].id + "></a><input class='weui-count__number' style='display:none;' tag=" + data.list[i].id + " id='txtCount" + data.list[i].id + "' type='number' value='0' /><a class='weui-count__btn weui-count__increase' tag=" + data.list[i].id + "></a>";
                html += "</div>";  //计数器外面的div结束
                html += "</div>";  //class="weui-cell__ft" div结束
                html += "</div></div></div>";

                $("#goodslist").append(html);

            }
        }

        //加减按钮事件
        function ChangeCount(v, op) {
            $.showLoading("加载中...");
            var id = v;
            if (parseInt(id) > 0 && id != "") {
                axios.post('api/AddCar.ashx?goodId=' + id + "&numType=" + op)
        .then(function (rs) {
            $.hideLoading();
            if (rs.data.result) {
                JsPrice();
                $('#spanCar').text(rs.data.code);
            } else {
                $.toast("添加失败" + rs.data.msg, "cancel");
            }
        })
        .catch(function (e) {
            $.hideLoading();
            $.toast("请求失败", 3000);
        });
            }
        }

        //计算本次消费金额
        function JsPrice() {
            var priceSum = 0;
            var chks = $('#goodslist input[type=number]');
            if (chks.length > 0) {
                for (var i = 0; i < chks.length; i++) {
                    var num = parseInt($(chks[i]).val());
                    var id = parseInt($(chks[i]).attr("tag"));
                    if (num > 0) {
                        //单价
                        var price = $('#spanPrice' + id).text().replace(/¥/, '');
                        //计算总价
                        priceSum += num * price;
                    }

                }
            }
            $('#ResPrice').text("" + parseFloat(parseFloat(priceSum)).toFixed(2));
        }

        //==============核心代码=============
        //鼠标向下滚动加载下一页数据,或者移动端向下滑动加载下一页数据
        var winH = $(window).height(); //页面可视区域高度
        var scrollHandler = function () {
            var pageH = $(document.body).height();
            var scrollT = $(window).scrollTop(); //滚动条top
            var aa = (pageH - winH - scrollT) / winH;
            if (aa < 0.02) {//0.02是个参数
                if (load == false) {
                    load = true;
                    page = $("#pageNum").val();
                    getData(page, "/api/GetTicketListJson.ashx");
                }

            }
        }
        //定义鼠标滚动事件
        $(window).scroll(scrollHandler);
    </script>
</body>
</html>

 具体功能画面根据自己需求去写,这里简单举例而已。到这里就已经基本完成了。希望可以帮助更多的刚开始接触公众号开发的伙伴们,后面有空再写公众号授权 微信支付等这些

原文地址:https://www.cnblogs.com/bin521/p/10898485.html