微信开发小结——积累与沉淀
前言
微信开发是个人、企业或组织在拥有超大用户群体的微信应用上,利用微信公众平台,开发类似插件或服务的轻应用。微信公众平台分为三种:订阅号:主要面向媒体和个人,旨在为用户提供信息资讯,每天能够群发1条消息,通过微信认证,可获得菜单、获得用户信息等接口权限;服务号:主要面向企业、政府和组织,旨在为用户提供服务,每月能够群发4条消息,通过微信认证,可获得高级接口权限;企业号:主要面向企业,旨在为企业用户提供移动端办公,只有企业通讯录中的用户才能关注使用,可以自由推送消息,不受限制,保密消息,防转发。期间我负责开发了基于服务号的微信投票和基于企业号的微信ERP,以下我主要从开发的角度介绍期间遇到的问题和心得体会。
前提准备
1、微信公众号申请,并通过微信认证。
2、准备一个二级以上域名,域名必须要备案。
3、对于需要自定义开发,需要提供可以部署程序的公网服务器。
对于2、3点,可以由开发公司提供,只需提供客户方一个管理后台地址和管理员账号密码,由客户方管理人员进行维护。
开发者认证获取票据
无论何种公众平台,开发者第一步工作是,获取AccessToken票据,因为绝大部分调用接口时都需携带AccessToken票据。AccessToken需要用申请的公众平台提供的CorpID和Secret(服务号则用AppID和Secret)来换取,不同的Secret会返回不同的AccessToken,换取的过程就是一次接口的调用。每次获取的AccessToken有效期是2个小时,失效后需要重新换取,我利用缓存处理把每次获取的AccessToken保存起来,设置7100秒,防止临界值的情况,并把它设置成静态属性,封装获取过程。在每次调用微信接口时,直接校验是否失效。
static string AccessToken { get { return qyUtils.GetTenket(); } }/// <summary>/// 应用toket获取/// </summary>/// <returns></returns>public static string GetTenket(){try{var cache = new mCache("token", "qyAccessToken");if (cache.ValidCache()) return cache.GetCache().ToString();string url = string.Format("{0}/cgi-bin/gettoken", Globals.QY_HTTP);StringBuilder param = new StringBuilder();param.Append("corpid=");param.Append(Globals.CORP_ID);param.Append("&corpsecret=");param.Append(Globals.CORP_SECRET);string strValue = Utils.GetData(url, param.ToString());ACCESS_TOKEN ac_token = JsonConvert.DeserializeObject<ACCESS_TOKEN>(strValue);if (ac_token.errcode == ReturnCode.请求成功){cache.ExpireTime = 7100;cache.SetCache(ac_token.access_token);return ac_token.access_token;}else{HttpContext.Current.Response.Write("<script>$.alert('" + ac_token.errmsg + "');</script>");return null;}}catch { }return null;}
接口封装
工欲善其事必先利其器!微信提供的API接口都是HTTP的POST请求和Get请求,我们可以封装成工具类,方面后期的使用。对于Get请求,我把URL变量作为参数传入发送 HttpWebRequest请求,获取 HttpWebResponse响应,反序列化结果判断请求是否成功,对于Post请求也差不多,只是多加一个传入数据的参数变量。
public static string PostData(string url, string data){data = Regex.Unescape(data);string json = HttpPost(url, data);try{var item = JsonConvert.DeserializeObject<WxJsonResult>(json);if (item.errcode != 0){if (item.errcode == ReturnCode.获取access_token时AppSecret错误或者access_token无效 || item.errcode == ReturnCode.oauth_code超时){ClearTenket();}item.errmsg = item.errcode.ToString();json = JsonConvert.SerializeObject(item);}}catch { }return json;}
公众号经常有需要用到一些临时性的多媒体素材的场景,是通过media_id来进行的,而对于上传文件的POST请求,我直接使用的.NET语言自带的 WebClient进行处理,先将文件上传到自己服务器端,使用相对路径获取服务器上的文件资源,调用微信公众号API,上传文件,返回媒体文件唯一标识。
public static QyUploadTemp WeChatUpload(string url, string type){try{if (!string.IsNullOrEmpty(qyUtils.GetTenket())){string posturl = string.Format("{0}/cgi-bin/media/upload?access_token={1}&type={2}", Globals.QY_HTTP, AccessToken, type);System.Net.WebClient webclient = new System.Net.WebClient();string media = HttpContext.Current.Server.MapPath(url);byte[] be = webclient.UploadFile(new Uri(String.Format(posturl, AccessToken, type)), media);string content = Encoding.Default.GetString(be);var result = JsonConvert.DeserializeObject<QyUploadTemp>(content);if (result.errcode == ReturnCode_QY.请求成功){return result;}}}catch { }return null;}
身份验证
微信应用经常需要获取用户身份信息,这就需要通过OAuth2.0验证接口。利用.NET应用的FormsAuthentication机制,判断请求是否已经过身份验证,否则跳转统一的授权认证处理/OAuth/QyLogOn调用OAuth验证接口获取code,这里需要指定成功获取code之后,根据code获取成员信息,并记录用户信息,身份验证处理。将需获取用户身份信息的方法继承基类QyBaseController,就可以在每次获取用户身份前,先OAuth验证,如果已经过身份验证,则无需重复身份验证。
1、未通过身份验证处理public ActionResult QyLogOn(string returnUrl){if (!String.IsNullOrEmpty(returnUrl)){Session["WX_returnUrl"] = returnUrl;}string action = "OAuth/QyLogOnOAuth";return Redirect(Utils.GetAuthorizeUrl(Globals.CORP_ID, action, "", OAuthScope.snsapi_base));}
2、调用OAuth验证接口获取code,这里主要特别注意的是redirectUrl必须保证和浏览器中的地址一致public static string GetAuthorizeUrl(string appId, string action, string state, OAuthScope scope, string responseType = "code"){string redirectUrl = HttpUtility.UrlEncode(string.Format("{0}/{1}", Globals.DOMAIN_URL, action));string url =string.Format("https://open.weixin.qq.com/connect/oauth2/authorize?appid={0}&redirect_uri={1}&response_type={2}&scope={3}&state={4}#wechat_redirect",appId, redirectUrl, responseType, scope, state);return url;}
3、根据code获取成员信息,并记录用户信息,身份验证处理public ActionResult QyLogOnOAuth(string code, string state){if (string.IsNullOrEmpty(code)) return Content("您拒绝了授权!");try{//通过,用code获取成员信息OAuthUserInfoResult result = qyUtils.GetUserInfobyCode(code);if (string.IsNullOrEmpty(result.UserId))return Content("<div><span class='fa fa-error'>您不是企业用户,请通知管理员添加!</span></div>");var user = qyUtils.GetUserInfobyUserId(result.UserId);qyWxUser.LogOn(user);if (Session["WX_returnUrl"] != null) { return Redirect(Session["WX_returnUrl"].ToString()); }}catch (Exception ex){return Content(ex.Message);}return RedirectToAction("ErrorTip", "Account");}
微信端UI框架
由于之前缺乏移动端开发经验,对于前端框架都不熟悉,只能网上了解一些开源的UI框架,又因为自己毕竟不是专业的前端开发工程师,最佳的选择是自带功能丰富组件的开源UI库。经过筛选,最先尝试的是由微信官方的推的weui,发现只有一些简单的组件,对于js请求处理响应都得自己写,便放弃了。后来了解到由阿里巴巴基于Framework7开发的SUI库,轻量、精美,实现了下拉刷新、日历、省市区选择器等功能非常强大的组件。这种资源对于一个只是刚刚入门的前端开发来说,无疑是最好的。但却忽略了很重要的一点,对于这种开源项目来说,团队的的持续维护更新,是至关重要的。随着使用频率增加,以及业务要求的复杂,SUI框架中隐藏的问题渐渐暴露出来:路由跳转页面和路由返回上一个页面存在问题,下拉滚动加载数据不能与上拉刷新并存,Android 端微信显示效果比IOS端微信差,日历组件初次打开不会聚焦输入框里的时间;这套UI库是引用Zepto.js,再引用Jquery库,会出现冲突以致组件失效、不稳定,而且SUI的主力开发人员已离开阿里巴巴,没有人继续负责维护这个项目了。后来了解到SUI框架的作者另外开了一个新的项目Light7,相当于SUI的升级版,修复了很多bug,还扩展了一些新的功能,而且会长期维护更新,于是又切换新的UI库。
这次前端UI框架的选择,给我最大的体会是项目风险管理,在开发过程中引入新技术,不可避免地要遇到各种风险。对于新技术开发,在项目开发早期,就应该建立系统的架构,解决关键技术难题、开发的基础构件,对所需要应用的技术做深度探索。越是技术复杂度高的项目,就越应该早地处理技术难题。新技术开发是探索性很强的工作,潜在着许多失败的风险,在可行性分析阶段,要广泛搜集相关信息,设计多种可行方案,进行充分论证。如果针对新技术,没有经验可借鉴,探索过程中要充分利用互联网资源,学习同行经验,往往事半功倍。
用户体验
微信端开发类似一个App软件应用,页面数据渲染速度对用户体验是至关重要的,微信端数据加载采用的是Juicer模板渲染的方式,高效、轻量的前端 (Javascript) 模板引擎,当用户进行滚动加载或者下拉刷新时,体验很流畅。对于ASP.NET MVC程序,需要解决一个符号的冲突,把@符号换成&,然后把后端处理得到的数据封装成指定的JSON格式,绑定模板即可。模板的定义(注:这里的"{&"符号使用必须修改juicer.js中的"{@"):
<script type="text/template" id="morder_li_head">{&if head != null }<div class="list-group"><ul class="list-block list-container media-list" ><li class="list-group-title" >${head.ItemClassName}</li></ul></div>{&/if}
</script>
封装JS调用,以参数的形式指定渲染的模板ID和数据,统一处理渲染数据的判断过程,降低代码冗余:
initTpl = function (e, t, n) {n || (n = !1),"feed_list" != e || t.showDing || 0 == t.showDing || (t.showDing = !0);var i = $("#" + e).html(),a = juicer(i),o = a.render(t);console.log(t);return t.page && !n && t.total > t.page * t.count && null != t.data && t.data.length > 0 && !n && (o += loadMoreHtml),o
}
调用方法就是:
list = JSON.parse(e);
$("#popup-info").find("#inventoryview").html(initTpl("morder_li_head ", list));
管理后台
当申请微信公众号,都会有一个相应的微信管理登陆后台,但是,对于微信端很多自定义功能,需要管理后台进行统一的管理,比如:微信投票项目的发起,参与公司的审核,投票数据统计,ERP用户与微信账号的对应关系,ERP菜单权限分配。数据处理采用的优秀的开源项目jQuery MiniUI,丰富的UI控件、高度的稳定性、强大的扩展能力和平滑的版本升级能力。
集成的功能:系统管理里添加了登陆用户角色和权限管理,指定不同用户类型不同的功能,最高管理员权限用户可以管理多个微信公众号(这一点仍在开发中...),只需开放企业管理员账户给相应客户即可。管理后台添加了日志管理功能,做到错误记录,方便管理员跟踪。对于微信ERP主要是企业号应用管理,微信端ERP菜单管理,微信用户添加、修改和关联ERP用户,分配ERP菜单权限,以及指定微信用户发送文本、图文、图片、文件、视频、语音消息。
注:后续我还会针对应用的技术进行拆分讲解记录,主要是给自己做一个积累,也供大家学习参考,少走弯路。
微信开发小结——积累与沉淀相关推荐
- Android 即时通讯开发小结(二)
<Android 即时通讯开发小结>基于IM Andriod 开发的各种常见问题,结合网易云信即时通讯技术的实践,对 IM 开发做一个全面的总结. 相关推荐阅读:. Android即时通讯 ...
- 微信摇一摇插件ios_微信开发平台 Jeewx-Boot
项目介绍 JeewxBoot 是一款基于SpringBoot的免费微信开发平台.支持微信公众号.小程序官网.微信抽奖活动.Jeewx-Boot实现了微信公众号管理.小程序CMS.微信抽奖活动等基础功能 ...
- pdfjs viewer 开发小结
此文已由作者吴家联授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 1. pdfjs库简介 PDF.js 是由Mozilla 主导推出的可以将PDF文件转换为H5页面进行展示的 ...
- Android 即时通讯开发小结(一)
本文将基于 IM Andriod 开发的各种常见问题,结合网易云信即时通讯技术的实践,对 IM 开发做一个全面的总结. 客户端架构 作为一个 IM 软件,最重要的一个特性就是保证消息的达到率和实时性. ...
- 第一个 iOS 项目开发小结 - SwiftUI 学习资料、开源项目
第一个 iOS 项目开发小结 SwiftUI 知识点小记 学习资料 开源项目 一些问题记录 项目预览 这段时间由于项目需要,我学习了一段时间 SwiftUI 并单独完成了一个系统的开发,耗时两个星期, ...
- 财务自由?这样做微信开发可以吗?
本文来自作者 jerry 在 GitChat 上分享「如何通过微信开发实现财富自由」,「阅读原文」查看交流实录 「文末高能」 编辑 | 嘉仔 相信很多人看到这个标题会想,简直是哗众取宠,标题党. 为什 ...
- 基于微信开发的十大火爆应用
微信已成生态,这早已不是秘密.如何从这个生态上赚到钱,同时又能找到避免被腾讯"微创新"的方法是无数创业者努力的方向.为大家分析盘点十大基于微信开发的火爆应用,让我们一起看看这批创业 ...
- 微信php开发用户分组,微信开发之用户分组管理接口(增)
本文将带你了解微信开发41----用户分组管理接口(增),希望本文对大家学微信有所帮助. 当一个公众平台运营一段时间,会积累很多用户粉丝,为了更加方便的管理用户,我们需要对用户分组进行管理,这样群发推 ...
- java微信附件下载_WxJava微信开发工具包
下面我们对WxJava微信开发工具包文件阐述相关使用资料和WxJava微信开发工具包文件的更新信息. WxJava微信开发工具包 WxJava微信开发Java开发工具包(SDK),支持包括微信支付.微 ...
最新文章
- TensorFlow Estimators: Managing Simplicity vs. Flexibility in High-Level Machine Learning Frameworks
- 数据结构与算法:二分法
- 【复杂网络】图模型在欺诈检测应用一点看法
- Web.py Cookbook 简体中文版 - 用cherrypy提供SSL支持
- 融合通信常见问题3月刊 | 云信小课堂
- 90 % 的 Python 开发者不知道的描述符应用
- asp.net 分页控件
- python3键盘事件_python+selenium3 鼠标事件和键盘事件
- 【Codeforces 1096D】Easy Problem
- 四年级计算机笔试题,四年级计算机考试卷.doc
- 操作系统之进程管理:15、哲学家进餐问题
- JavaScript数据类型之typeof检测变量数据类型(5)
- 深度学习(01)——安装anaconda
- layer子窗口与父窗口传值
- JDK和CGLIB生成动态代理类的区别
- AsPack压缩工具
- Python开发基础(一)基本数据类型
- 销售新人必看书籍推荐
- 51单片机:共阴数码管动态显示(定时器+中断)
- 【NOIP2012提高组】开车旅行
热门文章
- 随手记高管专访之CEO谷风专访——随手记理财安全吗
- java linux 微软雅黑_Linux下安装宋体以及微软雅黑字体
- [译]搜索与优化不存在免费的午餐
- lte协议软件 开源的4g_lte协议软件 开源的4g_Wi-Fi和4G大PK!谁网速快?谁耗电多?和你想的一样吗?...
- 第四章-循环程序设计代码实例(C++蓝豹子)
- poj 1228 Grandpa's Estate
- 协议-ISIS基础知识
- 代码评级指南:请用四个字形容你的代码水平
- bash shock vulnerable
- 电影怎么转成gif动画?一分钟教你在线转gif动图