微信快速开发框架(五)-- 利用快速开发框架,快速搭建微信浏览博客园首页文章


这几天接连发布了《快速开发微信公众平台框架---简介》和《体验微信公众平台快速开发框架》几篇关于微信平台的文章,不过反响一般,可能需求不是很多吧。闲来无事,还是继续改造一下这个框架。

今天更新了框架代码,听取了 @RMay 的建议,加入了一个信息中间件,用来处理xelement,避免了重复解析,所以所有接口都更改了下。此次更新如下:

1、增加信息中间件MiddleMessage

2、更改了接口参数类型,把原来的XElement都改成了MiddleMessage

3、删除了Demo项目,以后都用WebDemo进行演示。

所有代码都已经更新到我的Gibhub上

介绍了更新内容,下面继续打造我们的Demo项目。

之前我们写的,都是返回文本信息,今天上午,我加入了一个CnblogsArticleNewsMessageHandler,主要是返回一个ResponseNewsMessage(图文信息),只要发消息:博客园文章,就能获取在首页前5的文章列表,但为了避免给博客园造成鸭梨,我把信息缓存了下,10分钟更新一次。这次主要采用了webclient+正则的方式,采集的方式无所谓,大家都可以自由发挥。

先看下CnblogsArticleNewsMessageHandler:

public class CnblogsArticleNewsMessageHandler : IMessageHandler
    {
        public ResponseMessage HandlerRequestMessage(MiddleMessage msg)
        {
            //var request = new RequestTextMessage(xml);
            var response = new ResponseNewsMessage(msg.RequestMessage);
            var cnblogsFeed = new CnBlogsFeed(5);
            var articles = cnblogsFeed.GetTopCnblogsFeed();
            response.ArticleCount = articles.Count;
            response.CreateTime = DateTime.Now.Ticks;
            response.Articles = articles;

            return response;
        }
    }

大家可以看到,接口参数已经改成了MiddleMessage,这样就避免了原先我再new一个RequestMessage了, 直接用了MiddleMessage.RequestMessage。

CnBlogsFeed是一个自己写的采集类,目的是采集博客园首页数据,数字类型的构造函数,是一个提取数量,因为微信平台的限制,这个值必须在1-10之间。

因为是图文消息,而博客园呢只在Description中提供了用户的头像,而微信多图文消息会把第一篇文章的图片作为主图,大小为:320*200,所以我把第一张图片做成了默认图片,小图的话如果用户有头像就用用户的头像,如果没有则会显示一个默认小图,大小为:200*200。

看下CnBlogsFeed类,写的不好,将就看看吧:

public class CnBlogsFeed
    {
        private int m_topNum = 5;

        //缓存过期时间,这里是10分钟
        private static int s_timeout = 10 * 60 * 1000;
        //缓存过期时间
        private static DateTime s_outDate = DateTime.Now;
        //博客园文章列表正则表达式
        private static Regex s_cnblogsIndexRegex = new Regex("\\s*.*\\s*.*\\s*.*\\s*.*\\s*.*\\s*.*\\s*.*\\s*\\s*

.*)\"\\s*target=\"_blank\">(?.*)</a>.*\\s*<p\\s*class=\"post_item_summary\">\\s*(?<content>.*)\\s*</p>"</span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">); </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 128, 0, 1)">//内容中,用户头像正则表达式 </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 255, 1)">private static </span><span style="background: rgba(255, 255, 255, 1); color: rgba(43, 145, 175, 1)">Regex </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">s_picUrlRegex = </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 255, 1)">new </span><span style="background: rgba(255, 255, 255, 1); color: rgba(43, 145, 175, 1)">Regex</span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">(</span><span style="background: rgba(255, 255, 255, 1); color: rgba(163, 21, 21, 1)">"src=\"(?<picurl>.*)\"\\s"</span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">); </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 128, 0, 1)">//博客园文章列表uri </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 255, 1)">private static string </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">s_cnblogsIndexUri = </span><span style="background: rgba(255, 255, 255, 1); color: rgba(163, 21, 21, 1)">"http://www.cnblogs.com/mvc/AggSite/PostList.aspx?CategoryId=808&PageIndex=1"</span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">; </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 128, 0, 1)">//默认的一个大图,一个小图的图片地址 </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 255, 1)">private static string </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">s_defaultBigPicUri = </span><span style="background: rgba(255, 255, 255, 1); color: rgba(163, 21, 21, 1)">"http://wx.jamesying.com/images/default_title.jpg"</span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">; </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 255, 1)">private static string </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">s_defaultSmallPicUri = </span><span style="background: rgba(255, 255, 255, 1); color: rgba(163, 21, 21, 1)">"http://wx.jamesying.com/images/default_small.jpg"</span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">; </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 128, 0, 1)">//用来缓存请求过来的数据,不高兴用Cache了。 </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 255, 1)">private static </span><span style="background: rgba(255, 255, 255, 1); color: rgba(43, 145, 175, 1)">List</span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)"><</span><span style="background: rgba(255, 255, 255, 1); color: rgba(43, 145, 175, 1)">Article</span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">> s_articles = </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 255, 1)">null</span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">; </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 255, 1)">public </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">CnBlogsFeed(</span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 255, 1)">int </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">topNum) { m_topNum = topNum; } </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 255, 1)">public </span><span style="background: rgba(255, 255, 255, 1); color: rgba(43, 145, 175, 1)">List</span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)"><</span><span style="background: rgba(255, 255, 255, 1); color: rgba(43, 145, 175, 1)">Article</span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">> GetTopCnblogsFeed() { </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 255, 1)">if </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">(s_articles == </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 255, 1)">null</span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">) { GetTopCnblogsFeed(m_topNum); } </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 255, 1)">else </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">{ </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 255, 1)">if </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">(</span><span style="background: rgba(255, 255, 255, 1); color: rgba(43, 145, 175, 1)">DateTime</span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">.Now > s_outDate) { GetTopCnblogsFeed(m_topNum); } } </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 255, 1)">return </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">s_articles; } </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 255, 1)">private void </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">GetTopCnblogsFeed(</span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 255, 1)">int </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">m_topNum) { </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 255, 1)">try </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">{ </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 255, 1)">var </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">html = GetRemoteUri(s_cnblogsIndexUri, </span><span style="background: rgba(255, 255, 255, 1); color: rgba(43, 145, 175, 1)">Encoding</span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">.UTF8); </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 255, 1)">var </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">matchs = s_cnblogsIndexRegex.Matches(html); </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 255, 1)">var </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">i = 0; s_articles = </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 255, 1)">new </span><span style="background: rgba(255, 255, 255, 1); color: rgba(43, 145, 175, 1)">List</span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)"><</span><span style="background: rgba(255, 255, 255, 1); color: rgba(43, 145, 175, 1)">Article</span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">>(); </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 255, 1)">foreach </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">(</span><span style="background: rgba(255, 255, 255, 1); color: rgba(43, 145, 175, 1)">Match </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">match </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 255, 1)">in </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">matchs) { </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 255, 1)">if </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">(i >= m_topNum) </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 255, 1)">break</span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">; </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 255, 1)">var </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">article = </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 255, 1)">new </span><span style="background: rgba(255, 255, 255, 1); color: rgba(43, 145, 175, 1)">Article </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">{ Title = match.Groups[2].Value, Url = match.Groups[1].Value, Description = match.Groups[3].Value }; </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 255, 1)">if </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">(i == 0) { article.PicUrl = s_defaultBigPicUri; } </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 255, 1)">else </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">{ </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 255, 1)">var </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">matchPic = s_picUrlRegex.Match(article.Description); </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 255, 1)">if </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">(matchPic.Success) { article.PicUrl = matchPic.Groups[1].Value; } </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 255, 1)">else </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">{ article.PicUrl = s_defaultSmallPicUri; } } s_articles.Add(article); i += 1; } s_outDate = </span><span style="background: rgba(255, 255, 255, 1); color: rgba(43, 145, 175, 1)">DateTime</span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">.Now.AddMilliseconds(s_timeout); } </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 255, 1)">catch</span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">(</span><span style="background: rgba(255, 255, 255, 1); color: rgba(43, 145, 175, 1)">Exception </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">ex) { s_articles = </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 255, 1)">null</span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">; s_outDate = </span><span style="background: rgba(255, 255, 255, 1); color: rgba(43, 145, 175, 1)">DateTime</span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">.Now; </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 255, 1)">#if </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">DEBUG </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 255, 1)">throw </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">ex; </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 255, 1)">#endif </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">} </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 128, 0, 1)">//return s_articles; </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">} </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 255, 1)">private string </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">GetRemoteUri(</span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 255, 1)">string </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">uri, </span><span style="background: rgba(255, 255, 255, 1); color: rgba(43, 145, 175, 1)">Encoding </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">encoding) { </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 255, 1)">var </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">client = </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 255, 1)">new </span><span style="background: rgba(255, 255, 255, 1); color: rgba(43, 145, 175, 1)">WebClient</span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">(); client.Encoding = encoding; </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 255, 1)">return </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">client.DownloadString(uri); } }</span></pre> <p>基本工作完成,只要更改之前的TextMessageRole:</p> <pre class="code"><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 255, 1)">public </span><span style="background: rgba(255, 255, 255, 1); color: rgba(43, 145, 175, 1)">IMessageHandler </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">MessageRole(</span><span style="background: rgba(255, 255, 255, 1); color: rgba(43, 145, 175, 1)">MiddleMessage </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">msg) { </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 255, 1)">var </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">request = (</span><span style="background: rgba(255, 255, 255, 1); color: rgba(43, 145, 175, 1)">RequestTextMessage</span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">)msg.RequestMessage; </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 255, 1)">if </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">(request.Content.IndexOf(</span><span style="background: rgba(255, 255, 255, 1); color: rgba(163, 21, 21, 1)">"博客园文章"</span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">) > -1) { </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 255, 1)">return new </span><span style="background: rgba(255, 255, 255, 1); color: rgba(43, 145, 175, 1)">CnblogsArticleNewsMessageHandler</span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">(); } </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 255, 1)">if </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">(request.Content.IndexOf(</span><span style="background: rgba(255, 255, 255, 1); color: rgba(163, 21, 21, 1)">"博客园"</span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">) > -1) { </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 255, 1)">return new </span><span style="background: rgba(255, 255, 255, 1); color: rgba(43, 145, 175, 1)">CnblogsTextMessageHandler</span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">(); } </span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 255, 1)">return new </span><span style="background: rgba(255, 255, 255, 1); color: rgba(43, 145, 175, 1)">DefaultMessageHandler</span><span style="background: rgba(255, 255, 255, 1); color: rgba(0, 0, 0, 1)">(); }</span></pre> <p><span style="color: rgba(0, 0, 0, 1)">这个规则简陋了点,之后会考虑下,打造一个文本命令的规范,因为Demo还不涉及到数据库,暂时都是手工判断。</span></p> <p>接下来上传代码,测试一下:</p> <p>输入博客园:</p> <p></p> <p><span style="color: rgba(68, 68, 68, 1)">输入博客园文章:</span></p> <p></p> <p>测试完成,还能凑活用用,后续会用一个统一的文本命令方式,但有点纠结,不知道用什么方式,大家可以提供下意见。目前想到的是:</p> <p>关键字+命令+参数(可选)</p> <p>博客园+inday+5(博客园,用户为inday,前5文章)</p> <p>天气+上海(获取上海今天的天气)</p> <p>天气+上海+3(获取上海未来3天的天气)</p> <p>后面会写一系列教程,尽量把常用的消息类型都用到。</p> <p>PS:求职下吧,上海地区+电子商务类型公司,最好有旅游行业,职位的话无所谓,一个抬头而已,有发展前景,因本人30+了,不太想经常换工作了,薪资12k+就行,对于自我评价,还算是个负责的人,项目也好,学习也好,都会投入进去,对于C#比较精通点,也可以其他语言。需要的Email给我:james#taogame.com(#->@)</p> <p>PS2:今天收到宝宝的台历了,哈,真嗲</p> </div> <!--conend--> <div class="p-2"></div> <div class="arcinfo my-3 fs-7 text-center"> <a href='/t/etagid7103-0.html' class='tagbtn' target='_blank'>一路走来</a><a href='/t/etagid7086-0.html' class='tagbtn' target='_blank'>WXPPQuickFramework</a><a href='/t/etagid7087-0.html' class='tagbtn' target='_blank'>微信公众平台快速开发框架</a><a href='/t/etagid5819-0.html' class='tagbtn' target='_blank'>微信公众平台</a> </div> <div class="p-2"></div> </div> <div class="p-2"></div> <!--xg--> <div class="lbox p-4 shadow-sm rounded-3"> <div class="boxtitle"><h2 class="fs-4">相关</h2></div> <hr> <div class="row g-0 py-2 border-bottom align-items-center"> <div class="col-7 col-lg-11 border-lg-end"> <h3 class="fs-6 mb-0 mb-lg-2"><a href="/a/1-488631.html">微信公众平台开发(一) 配置接口</a></h3> <div class="ltag fs-8 d-none d-lg-block"> </div> </div> </div><div class="row g-0 py-2 border-bottom align-items-center"> <div class="col-7 col-lg-11 border-lg-end"> <h3 class="fs-6 mb-0 mb-lg-2"><a href="/a/1-479691.html">Java微信公众平台开发之将本地开发环境映射到公网访问</a></h3> <div class="ltag fs-8 d-none d-lg-block"> </div> </div> </div><div class="row g-0 py-2 border-bottom align-items-center"> <div class="col-7 col-lg-11 border-lg-end"> <h3 class="fs-6 mb-0 mb-lg-2"><a href="/a/1-348029.html">Senparc.Weixin.MP SDK 微信公众平台开发教程(二十):使用菜单消息功能</a></h3> <div class="ltag fs-8 d-none d-lg-block"> </div> </div> </div><div class="row g-0 py-2 border-bottom align-items-center"> <div class="col-7 col-lg-11 border-lg-end"> <h3 class="fs-6 mb-0 mb-lg-2"><a href="/a/1-338917.html">Senparc.Weixin.MP SDK 微信公众平台开发教程(十):多客服接口说明</a></h3> <div class="ltag fs-8 d-none d-lg-block"> </div> </div> </div><div class="row g-0 py-2 border-bottom align-items-center"> <div class="col-7 col-lg-11 border-lg-end"> <h3 class="fs-6 mb-0 mb-lg-2"><a href="/a/1-338878.html">Senparc.Weixin.MP SDK 微信公众平台开发教程(十二):OAuth2.0说明</a></h3> <div class="ltag fs-8 d-none d-lg-block"> </div> </div> </div><div class="row g-0 py-2 border-bottom align-items-center"> <div class="col-7 col-lg-11 border-lg-end"> <h3 class="fs-6 mb-0 mb-lg-2"><a href="/a/1-338924.html">Senparc.Weixin.MP SDK 微信公众平台开发教程(三):微信公众平台开发验证</a></h3> <div class="ltag fs-8 d-none d-lg-block"> </div> </div> </div><div class="row g-0 py-2 border-bottom align-items-center"> <div class="col-7 col-lg-11 border-lg-end"> <h3 class="fs-6 mb-0 mb-lg-2"><a href="/a/1-289112.html">开发微信公众平台时需要注意的安全问题</a></h3> <div class="ltag fs-8 d-none d-lg-block"> </div> </div> </div><div class="row g-0 py-2 border-bottom align-items-center"> <div class="col-7 col-lg-11 border-lg-end"> <h3 class="fs-6 mb-0 mb-lg-2"><a href="/a/1-21102.html">微信公众平台快速开发框架 For Core 2.0 beta –JCSoft.WX.Core 5.2.0 beta发布</a></h3> <div class="ltag fs-8 d-none d-lg-block"> </div> </div> </div><div class="row g-0 py-2 border-bottom align-items-center"> <div class="col-7 col-lg-11 border-lg-end"> <h3 class="fs-6 mb-0 mb-lg-2"><a href="/a/1-16548.html">微信快速开发框架(三)-- 建立微信公众平台测试账号</a></h3> <div class="ltag fs-8 d-none d-lg-block"> </div> </div> </div> <!----> <!----> </div> <!--xgend--> </div> <div class="col-lg-3 col-12 p-0 ps-lg-2"> <!--box--> <!--boxend--> <!--<div class="p-2"></div>--> <!--box--> <div class="lbox p-4 shadow-sm rounded-3"> <div class="boxtitle pb-2"><h2 class="fs-4"><a href="#">标签</a></h2></div> <div class="clearfix"></div> <ul class="m-0 p-0 fs-7 r-tag"> </ul> <div class="clearfix"></div> </div> <!--box end--> </div> </div> </div> </main> <div class="p-2"></div> <footer> <div class="container-fluid p-0 bg-black"> <div class="container p-0 fs-8"> <p class="text-center m-0 py-2 text-white-50">一品网 <a class="text-white-50" href="https://beian.miit.gov.cn/" target="_blank">冀ICP备14022925号-6</a></p> </div> </div> <script> var _hmt = _hmt || []; (function() { var hm = document.createElement("script"); hm.src = "https://hm.baidu.com/hm.js?6e3dd49b5f14d985cc4c6bdb9248f52b"; var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(hm, s); })(); </script> </footer> <script src="/skin/bootstrap.bundle.js"></script> </body> </html>