开发微信企业号可以通过程序自定义菜单,只需要调用相关的接口就可以实现。

其实这个菜单也就是微信底部的菜单,目前自定义菜单最多包括3个一级菜单,每个一级菜单最多包含5个二级菜单。一级菜单最多4个汉字,二级菜单最多7个汉字,多出来的部分将会以“...”代替。其实创建菜单也很简单。

但有一点需要说明,如果有子菜单,那么这个菜单就不会向后端发送事件。例如:我定义了三个一级菜单一个click,两个view。

如果没有子菜单,则点击click类型的菜单时,后主动向后端发送上报菜单事件,如果有则不会发送上报菜单事件。

如果没有子菜单,则点击view类型的菜单时,回主动向后端发送点击菜单跳转链接的事件。并且会打开对应的网页,如果有则不会发送点击菜单跳转链接的事件,也不会打开对应的网页。

也就是,如果有子菜单,则这个菜单,就是点击单纯的显示子菜单,不会有其他的动作了。

例如:

核心代码菜单相关:

public enum MenuTypeEnum{click = 1,view = 2,scancode_push = 3,scancode_waitmsg = 4,pic_sysphoto = 5,pic_photo_or_album = 6,pic_weixin = 7,location_select = 8};public abstract class SubButton{/// <summary>/// 菜单的响应动作类型,目前有click、view两种类型 scancode_push   扫码推事件scancode_waitmsg   扫码推事件且弹出“消息接收中”提示框/// </summary>public string type { get; protected set; }/// <summary>/// 菜单标题,不超过16个字节,子菜单不超过40个字节 /// </summary>public string name { get; set; }public List<SubButton> sub_button { get; set; }public virtual bool  HasError(){if (string.IsNullOrEmpty(this.name)){LogInfo.Error("菜单名称为空");return true;}          if (string.IsNullOrEmpty(this.type)){LogInfo.Error("菜单类型为空");return true;}if (sub_button!=null&&sub_button.Count > 0){foreach (SubButton bt in sub_button){if (bt.HasError()){return true;}}            }return false;}      public static SubButton CreateSubButton(MenuTypeEnum type,string name,string key,string url){SubButton subButton = null;string menuTypeText = GetMenuTypeText(type);switch (type){  case MenuTypeEnum.view:subButton = new SubViewButton(menuTypeText,name, url);break;case MenuTypeEnum.click:case MenuTypeEnum.scancode_push:                 case MenuTypeEnum.scancode_waitmsg:                 case MenuTypeEnum.pic_sysphoto:                 case MenuTypeEnum.pic_photo_or_album:                  case MenuTypeEnum.pic_weixin:                case MenuTypeEnum.location_select:subButton = new SubClickButton(menuTypeText, name, key);                break;default:throw new Exception("type=" + type + ",此类型的SubButton没有实现");}return subButton;}public static MenuTypeEnum GetMenuType(string type){MenuTypeEnum text = MenuTypeEnum.click;switch (type){case "click":text = MenuTypeEnum.click;break;case "view":text = MenuTypeEnum.view ;break;case "scancode_push":text =MenuTypeEnum.scancode_push ;break;case "scancode_waitmsg":text = MenuTypeEnum.scancode_waitmsg ;break;case  "pic_sysphoto" :text = MenuTypeEnum.pic_sysphoto;break;case "pic_photo_or_album":text = MenuTypeEnum.pic_photo_or_album ;break;case "pic_weixin":text = MenuTypeEnum.pic_weixin ;break;case "location_select":text =MenuTypeEnum.location_select ;break;default:throw new Exception("type=" + type + ",此类型的MenuTypeEnum没有找到");}return text;}public static string GetMenuTypeText(MenuTypeEnum type){string text = "";switch (type){case MenuTypeEnum.click:text = "click";break;case MenuTypeEnum.view:text = "view";break;case MenuTypeEnum.scancode_push:text = "scancode_push";break;case MenuTypeEnum.scancode_waitmsg:text = "scancode_waitmsg";break;case MenuTypeEnum.pic_sysphoto:text = "pic_sysphoto";break;case MenuTypeEnum.pic_photo_or_album:text = "pic_photo_or_album";break;case MenuTypeEnum.pic_weixin:text = "pic_weixin";break;case MenuTypeEnum.location_select:text = "location_select";break;default:throw new Exception("type=" + type + ",此类型的MenuTypeEnum没有实现");}return text;}}public class SubClickButton : SubButton{public SubClickButton(string type,string name,string key){this.type = type;this.name = name;this.key = key;}/// <summary>/// 菜单KEY值,用于消息接口推送,不超过128字节 /// </summary>public string key { get; set; }public override bool HasError(){         if (string.IsNullOrEmpty(this.key)){LogInfo.Error("菜单key为空");return true;}         return base.HasError();} }public class SubViewButton : SubButton{public SubViewButton(string type, string name, string url){this.type = type;this.name = name;this.url = url;}/// <summary>/// 成员点击view类型按钮后,微信客户端将会打开开发者在按钮中填写的网页URL,可与网页授权获取成员基本信息接口结合,获得成员基本信息。/// </summary>public string url { get; set; }public override bool HasError(){if (string.IsNullOrEmpty(this.url)){LogInfo.Error("菜单url为空");return true;}return base.HasError();         } }
 /// <summary>/// 自定义菜单/// </summary>public class Menu{public List<SubButton> button { get; set; }public virtual bool HasError(){if (button.Count >= 4){LogInfo.Error("最多包括3个一级菜单");return true;}foreach(SubButton bt in button){if (bt.HasError()){return true;}              }return false;}   }

添加修改,删除菜单

public class BLLMenu{/// <summary>/// /// </summary>/// <param name="info"></param>/// <param name="agentid">企业应用的id,整型。可在应用的设置页面查看</param>/// <returns></returns>public static bool Create(Menu info, int agentid){if (info.HasError()){return false;}string urlFormat = "https://qyapi.weixin.qq.com/cgi-bin/menu/create?access_token={0}&agentid={1}";var url = string.Format(urlFormat, BLLAccessToken.GetAccessToken(), agentid);WebUtils wut = new WebUtils();var postData = Tools.ToJsonString<Menu>(info);//数据不用加密发送  LogInfo.Info("创建应用菜单消息: " + postData);string sendResult = wut.DoPost(url, postData);ReturnResult tempAccessTokenjson = Tools.JsonStringToObj<ReturnResult>(sendResult);if (tempAccessTokenjson.HasError()){LogInfo.Error("发送创建应用菜单返回错误: " + Tools.ToJsonString<ReturnResult>(tempAccessTokenjson));return false;}return true;}/// <summary>/// /// </summary>/// <param name="agentid">企业应用的id,整型。可在应用的设置页面查看</param>/// <returns></returns>public static bool DelAll(int agentid){string urlFormat = "https://qyapi.weixin.qq.com/cgi-bin/menu/delete?access_token={0}&agentid={1}";var url = string.Format(urlFormat, BLLAccessToken.GetAccessToken(), agentid);WebUtils wut = new WebUtils();//数据不用加密发送  LogInfo.Info("发送删除菜单消息: " + url);string sendResult = wut.DoGet(url);ReturnResult tempAccessTokenjson = Tools.JsonStringToObj<ReturnResult>(sendResult);if (tempAccessTokenjson.HasError()){LogInfo.Error("发送删除菜单返回错误: " + Tools.ToJsonString<ReturnResult>(tempAccessTokenjson));return false;}return true;}public static bool GetAll(int agentid){string urlFormat = "https://qyapi.weixin.qq.com/cgi-bin/menu/get?access_token={0}&agentid={1}";var url = string.Format(urlFormat, BLLAccessToken.GetAccessToken(), agentid);WebUtils wut = new WebUtils();//数据不用加密发送  LogInfo.Info("发送获取菜单列表消息: " + url);string sendResult = wut.DoGet(url);MenuListResult tempAccessTokenjson = Tools.JsonStringToObj<MenuListResult>(sendResult);if (tempAccessTokenjson.HasError()){LogInfo.Error("发送获取菜单列表返回错误: " + Tools.ToJsonString<MenuListResult>(tempAccessTokenjson));return false;}return true;}}

测试代码

 private void button7_Click(object sender, EventArgs e){///测试添加ConmonWeixin.MenuInfo.Menu info = new ConmonWeixin.MenuInfo.Menu();SubButton subbt1 = SubButton.CreateSubButton(MenuTypeEnum.click, "Click1", "Click1", "");          subbt1.sub_button = new List<SubButton>();SubButton bt11 = SubButton.CreateSubButton(MenuTypeEnum.scancode_push, "codePush2", "CancodePushButton11", "");SubButton bt12 = SubButton.CreateSubButton(MenuTypeEnum.scancode_waitmsg, "codeWaitmsg2", "CancodeWaitmsgButton12", "");SubButton bt13 = SubButton.CreateSubButton(MenuTypeEnum.click, "Click12", "Click12", "");SubButton bt14 = SubButton.CreateSubButton(MenuTypeEnum.view, "V2级", "V22", "https://www.baidu.com"); subbt1.sub_button.Add(bt11);subbt1.sub_button.Add(bt12);subbt1.sub_button.Add(bt13);subbt1.sub_button.Add(bt14);SubButton subbt2 = SubButton.CreateSubButton(MenuTypeEnum.view, "V1级", "", "www.baidu.com");            subbt2.sub_button = new List<SubButton>();SubButton bt21 = SubButton.CreateSubButton(MenuTypeEnum.pic_sysphoto, "PicSysphoto", "PicSysphotoButton21", "");SubButton bt22 = SubButton.CreateSubButton(MenuTypeEnum.pic_photo_or_album, "photoalbum2", "PicSysphotoButton22", "");           subbt2.sub_button.Add(bt21);subbt2.sub_button.Add(bt22);SubButton subbt3 = SubButton.CreateSubButton(MenuTypeEnum.view, "V1级", "", "http://hlogin.html");          subbt3.sub_button = new List<SubButton>();SubButton bt31 = SubButton.CreateSubButton(MenuTypeEnum.pic_weixin, "pic_weixin2", "Subpic_weixinButton31", "");SubButton bt32 = SubButton.CreateSubButton(MenuTypeEnum.location_select, "location_selec", "location_selec32", "");subbt3.sub_button.Add(bt31);subbt3.sub_button.Add(bt32);info.button = new List<SubButton>();info.button.Add(subbt1);info.button.Add(subbt2);info.button.Add(subbt3);BLLMenu.Create(info,7);//  Menu info, int agentid}private void button8_Click(object sender, EventArgs e){//测试删除BLLMenu.DelAll(7);}

创建应用菜单官方文档

菜单接收事件官方文档

微信企业号开发:自定义菜单相关推荐

  1. 微信企业号创建自定义菜单

    微信企业号创建菜单 <?php define('CorpID', "wx82e2c31215d9a5a7"); define('CorpSecret', "&quo ...

  2. 微信企业号开发(7)--自定义菜单

    [本文所描述的内容具有一定的时效性,请以实际开发所处环境为准] 今天,我们来介绍另一个在微信中,我们经常用到的功能,那就是菜单.在本文中,由于博主之前开发企业号时,微信企业号仅有链接,点击事件两个选项 ...

  3. java自定义菜单跳转页面_微信公众号开发 自定义菜单跳转页面并获取用户信息实例详解...

    微信公众号开发 自定义菜单 请先读完本文再进行配置开发 请先前往微信平台开发者文档阅读"网页授权获取用户基本信息"的接口说明 在微信公众账号开发中,往往有定义一个菜单,然后用户点击 ...

  4. 微信公众帐号开发-自定义菜单的创建及菜单事件响应的实例

    微信开发公众平台自定义菜单需要花钱认证才能实现,不想花钱只能玩测试账号了,不过这并不影响开发.我的开发都是基于柳峰老师的微信公众平台应用开发做的. 只要我们使用公众平台测试账号就可以开发自定义菜单了, ...

  5. 微信公众号开发--自定义菜单跳转页面并获取用户信息(续)

    之前写过一篇微信公众号开发–自定义菜单跳转页面并获取用户信息 由于当时是刚学习微信公众号开发当时的思路虽然可行,不过不是最好的,最近也用到了需要获取用户信息的地方,再次整理一下. 流程 注意点 ### ...

  6. php微信自定义菜单开发,微信公众平台开发自定义菜单功能开发

    一.简介 微信公众平台服务号以及之前成功申请内测资格的订阅号都具有自定义菜单的功能.开发者可利用该功能为公众账号的会话界面底部增加自定义菜单,用户点击菜单中的选项,可以调出相应的回复信息或网页链接.自 ...

  7. 公众号如何跳转到页面php,图文详解微信公众号开发自定义菜单跳转页面并获取用户信息实例...

    这篇文章主要介绍了微信公众号开发 自定义菜单跳转页面并获取用户信息实例详解的相关资料,需要的朋友可以参考下 微信公众号开发 自定义菜单 请先读完本文再进行配置开发 请先前往微信平台开发者文档阅读&qu ...

  8. 微信开发 -- 自定义菜单

    目前微信服务号自定义菜单最多包括3个一级菜单,每个一级菜单最多包含5个二级菜单.一级菜单最多4个汉字,二级菜单最多7个汉字,多出来的部分将会以"..."代替.请注意,创建自定义菜单 ...

  9. 微信企业号开发实例源码

    从微信服务号到微信企业号开发也有段时间了,微信服务号主要是参考柳峰的博客学习的,http://blog.csdn.net/lyq8479/article/category/1366622/2. 微信企 ...

最新文章

  1. oracle的quit命令,Oracle的启动和关闭
  2. 解决error C2760:语法错误: 意外的令牌“标识符”,预期的令牌为“类型说明符”
  3. numpy中常用的函数
  4. LocalReport Print with C# C#打印RDLC
  5. 奥迪坚为中民燃气打造专业便民服务呼叫中心
  6. P3899-[湖南集训]谈笑风生【主席树】
  7. 怎么查看linux服务器有cpu
  8. 顶点计划:520日讨论
  9. redis数据类型 - Zset(有序集合sorted set)
  10. VS中的“该文件可能不存在或已被锁定”错误解决办法
  11. 堆栈宽度学习Stacked BLS的简单python代码实现
  12. 由中缀、后缀确定前缀表达式
  13. yaml css教程,YAML 语法
  14. win10 WLAN共享给以太网口
  15. 手机上怎么访问电脑html页面,手机UC浏览器怎么访问电脑版 访问电脑页面方法...
  16. 从零搭建一辆ROS小车
  17. Millet谷仓区块链和电子商务及Token相结合的产物
  18. Re: 客户协作 OVER 合同谈判
  19. MPa和psi,bar压力单位换算成公斤
  20. 月影村汉化版还有多远?

热门文章

  1. word 以嵌入式插入图片显示不全,被文字掩盖在下方
  2. nginx 502 Bad Gateway解决办法
  3. 电机磁电热多场耦合 matlab,永磁电机电磁-温度场耦合仿真分析流程
  4. CS5262: DP转HDMI+VGA
  5. 混合波束成形| 高速铁路通信系统的信道估计:Location-Aided mMIMO Channel Tracking and Hybrid Beamforming for High-Speed
  6. mysql gis_MySQL的GIS、GEO入门笔记
  7. 竟然有删不了的文件夹?
  8. Centos7创建DNS服务器(超级简单,一看就会)
  9. 【前端】用百度BAE和express部署自己的node后台
  10. NetSpider 网络蜘蛛1.0 的简介