打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
微信企业号开发:自定义菜单

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

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

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

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

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

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


例如:


核心代码菜单相关:

[csharp] view plain copy
  1. public enum MenuTypeEnum  
  2.     {  
  3.         click = 1,  
  4.         view = 2,  
  5.         scancode_push = 3,  
  6.         scancode_waitmsg = 4,  
  7.         pic_sysphoto = 5,  
  8.         pic_photo_or_album = 6,  
  9.         pic_weixin = 7,  
  10.         location_select = 8  
  11.   
  12.     };  
  13.    public abstract class SubButton  
  14.     {  
  15.         /// <summary>  
  16.         /// 菜单的响应动作类型,目前有click、view两种类型 scancode_push   扫码推事件scancode_waitmsg   扫码推事件且弹出“消息接收中”提示框  
  17.         /// </summary>  
  18.         public string type { get; protected set; }  
  19.         /// <summary>  
  20.         /// 菜单标题,不超过16个字节,子菜单不超过40个字节   
  21.         /// </summary>  
  22.         public string name { get; set; }  
  23.         public List<SubButton> sub_button { get; set; }  
  24.         public virtual bool  HasError()  
  25.         {  
  26.             if (string.IsNullOrEmpty(this.name))  
  27.             {  
  28.                 LogInfo.Error("菜单名称为空");  
  29.                 return true;  
  30.             }            
  31.             if (string.IsNullOrEmpty(this.type))  
  32.             {  
  33.                 LogInfo.Error("菜单类型为空");  
  34.                 return true;  
  35.             }  
  36.             if (sub_button!=null&&sub_button.Count > 0)  
  37.             {  
  38.                 foreach (SubButton bt in sub_button)  
  39.                 {  
  40.                     if (bt.HasError())  
  41.                     {  
  42.                         return true;  
  43.                     }  
  44.                 }              
  45.             }  
  46.             return false;  
  47.         }        
  48.         public static SubButton CreateSubButton(MenuTypeEnum type,string name,string key,string url)  
  49.         {  
  50.             SubButton subButton = null;  
  51.             string menuTypeText = GetMenuTypeText(type);  
  52.             switch (type)  
  53.             {    
  54.                 case MenuTypeEnum.view:  
  55.                     subButton = new SubViewButton(menuTypeText,name, url);  
  56.                     break;  
  57.                 case MenuTypeEnum.click:  
  58.                 case MenuTypeEnum.scancode_push:                   
  59.                 case MenuTypeEnum.scancode_waitmsg:                   
  60.                 case MenuTypeEnum.pic_sysphoto:                   
  61.                 case MenuTypeEnum.pic_photo_or_album:                    
  62.                 case MenuTypeEnum.pic_weixin:                  
  63.                 case MenuTypeEnum.location_select:  
  64.                     subButton = new SubClickButton(menuTypeText, name, key);                  
  65.                     break;  
  66.                 default:  
  67.                     throw new Exception("type=" + type + ",此类型的SubButton没有实现");  
  68.   
  69.             }  
  70.             return subButton;  
  71.         }  
  72.         public static MenuTypeEnum GetMenuType(string type)  
  73.         {  
  74.             MenuTypeEnum text = MenuTypeEnum.click;  
  75.             switch (type)  
  76.             {  
  77.                 case "click":  
  78.                     text = MenuTypeEnum.click;  
  79.                     break;  
  80.                 case "view":  
  81.                     text = MenuTypeEnum.view ;  
  82.                     break;  
  83.                 case "scancode_push":  
  84.                     text =MenuTypeEnum.scancode_push ;  
  85.                     break;  
  86.                 case "scancode_waitmsg":  
  87.                     text = MenuTypeEnum.scancode_waitmsg ;  
  88.                     break;  
  89.                 case  "pic_sysphoto" :  
  90.                     text = MenuTypeEnum.pic_sysphoto;  
  91.                     break;  
  92.                 case "pic_photo_or_album":  
  93.                     text = MenuTypeEnum.pic_photo_or_album ;  
  94.                     break;  
  95.                 case "pic_weixin":  
  96.                     text = MenuTypeEnum.pic_weixin ;  
  97.                     break;  
  98.                 case "location_select":  
  99.                     text =MenuTypeEnum.location_select ;  
  100.                     break;  
  101.                 default:  
  102.                     throw new Exception("type=" + type + ",此类型的MenuTypeEnum没有找到");  
  103.   
  104.             }  
  105.             return text;  
  106.         }  
  107.         public static string GetMenuTypeText(MenuTypeEnum type)  
  108.         {  
  109.             string text = "";  
  110.             switch (type)  
  111.             {  
  112.                 case MenuTypeEnum.click:  
  113.                     text = "click";  
  114.                     break;  
  115.                 case MenuTypeEnum.view:  
  116.                     text = "view";  
  117.                     break;  
  118.                 case MenuTypeEnum.scancode_push:  
  119.                     text = "scancode_push";  
  120.                     break;  
  121.                 case MenuTypeEnum.scancode_waitmsg:  
  122.                     text = "scancode_waitmsg";  
  123.                     break;  
  124.                 case MenuTypeEnum.pic_sysphoto:  
  125.                     text = "pic_sysphoto";  
  126.                     break;  
  127.                 case MenuTypeEnum.pic_photo_or_album:  
  128.                     text = "pic_photo_or_album";  
  129.                     break;  
  130.                 case MenuTypeEnum.pic_weixin:  
  131.                     text = "pic_weixin";  
  132.                     break;  
  133.                 case MenuTypeEnum.location_select:  
  134.                     text = "location_select";  
  135.                     break;  
  136.                 default:  
  137.                     throw new Exception("type=" + type + ",此类型的MenuTypeEnum没有实现");  
  138.   
  139.             }  
  140.             return text;  
  141.         }  
  142.     }  
  143.    public class SubClickButton : SubButton  
  144.    {  
  145.        public SubClickButton(string type,string name,string key)  
  146.        {  
  147.            this.type = type;  
  148.            this.name = name;  
  149.            this.key = key;  
  150.        }  
  151.        /// <summary>  
  152.        /// 菜单KEY值,用于消息接口推送,不超过128字节   
  153.        /// </summary>  
  154.        public string key { get; set; }  
  155.        public override bool HasError()  
  156.        {           
  157.            if (string.IsNullOrEmpty(this.key))  
  158.            {  
  159.                LogInfo.Error("菜单key为空");  
  160.                return true;  
  161.            }           
  162.            return base.HasError();  
  163.        }   
  164.    }  
  165.    public class SubViewButton : SubButton  
  166.    {  
  167.        public SubViewButton(string type, string name, string url)  
  168.        {  
  169.            this.type = type;  
  170.            this.name = name;  
  171.            this.url = url;  
  172.        }  
  173.        /// <summary>  
  174.        /// 成员点击view类型按钮后,微信客户端将会打开开发者在按钮中填写的网页URL,可与网页授权获取成员基本信息接口结合,获得成员基本信息。  
  175.        /// </summary>  
  176.        public string url { get; set; }  
  177.        public override bool HasError()  
  178.        {  
  179.            if (string.IsNullOrEmpty(this.url))  
  180.            {  
  181.                LogInfo.Error("菜单url为空");  
  182.                return true;  
  183.            }  
  184.            return base.HasError();           
  185.        }   
  186.    }  

[csharp] view plain copy
  1. /// <summary>  
  2.    /// 自定义菜单  
  3.    /// </summary>  
  4.   public class Menu  
  5.    {  
  6.       public List<SubButton> button { get; set; }  
  7.       public virtual bool HasError()  
  8.       {  
  9.           if (button.Count >= 4)  
  10.           {  
  11.               LogInfo.Error("最多包括3个一级菜单");  
  12.               return true;  
  13.           }  
  14.           foreach(SubButton bt in button)  
  15.           {  
  16.               if (bt.HasError())  
  17.               {  
  18.                   return true;  
  19.               }                
  20.           }  
  21.           return false;  
  22.       }     
  23.    }  

添加修改,删除菜单

[csharp] view plain copy
  1. public class BLLMenu  
  2.     {  
  3.   
  4.        /// <summary>  
  5.        ///   
  6.        /// </summary>  
  7.        /// <param name="info"></param>  
  8.         /// <param name="agentid">企业应用的id,整型。可在应用的设置页面查看</param>  
  9.        /// <returns></returns>  
  10.         public static bool Create(Menu info, int agentid)  
  11.         {  
  12.             if (info.HasError())  
  13.             {  
  14.                 return false;  
  15.             }  
  16.             string urlFormat = "https://qyapi.weixin.qq.com/cgi-bin/menu/create?access_token={0}&agentid={1}";  
  17.             var url = string.Format(urlFormat, BLLAccessToken.GetAccessToken(), agentid);  
  18.             WebUtils wut = new WebUtils();  
  19.             var postData = Tools.ToJsonString<Menu>(info);  
  20.             //数据不用加密发送    
  21.             LogInfo.Info("创建应用菜单消息: " + postData);  
  22.             string sendResult = wut.DoPost(url, postData);  
  23.             ReturnResult tempAccessTokenjson = Tools.JsonStringToObj<ReturnResult>(sendResult);  
  24.             if (tempAccessTokenjson.HasError())  
  25.             {  
  26.                 LogInfo.Error("发送创建应用菜单返回错误: " + Tools.ToJsonString<ReturnResult>(tempAccessTokenjson));  
  27.                 return false;  
  28.             }  
  29.            
  30.             return true;  
  31.         }  
  32.        /// <summary>  
  33.        ///   
  34.        /// </summary>  
  35.         /// <param name="agentid">企业应用的id,整型。可在应用的设置页面查看</param>  
  36.        /// <returns></returns>  
  37.         public static bool DelAll(int agentid)  
  38.         {  
  39.             string urlFormat = "https://qyapi.weixin.qq.com/cgi-bin/menu/delete?access_token={0}&agentid={1}";  
  40.             var url = string.Format(urlFormat, BLLAccessToken.GetAccessToken(), agentid);  
  41.             WebUtils wut = new WebUtils();  
  42.   
  43.             //数据不用加密发送    
  44.             LogInfo.Info("发送删除菜单消息: " + url);  
  45.             string sendResult = wut.DoGet(url);  
  46.             ReturnResult tempAccessTokenjson = Tools.JsonStringToObj<ReturnResult>(sendResult);  
  47.             if (tempAccessTokenjson.HasError())  
  48.             {  
  49.                 LogInfo.Error("发送删除菜单返回错误: " + Tools.ToJsonString<ReturnResult>(tempAccessTokenjson));  
  50.                 return false;  
  51.             }  
  52.          
  53.             return true;  
  54.         }  
  55.         public static bool GetAll(int agentid)  
  56.         {  
  57.             string urlFormat = "https://qyapi.weixin.qq.com/cgi-bin/menu/get?access_token={0}&agentid={1}";  
  58.             var url = string.Format(urlFormat, BLLAccessToken.GetAccessToken(), agentid);  
  59.             WebUtils wut = new WebUtils();  
  60.   
  61.             //数据不用加密发送    
  62.             LogInfo.Info("发送获取菜单列表消息: " + url);  
  63.             string sendResult = wut.DoGet(url);  
  64.             MenuListResult tempAccessTokenjson = Tools.JsonStringToObj<MenuListResult>(sendResult);  
  65.             if (tempAccessTokenjson.HasError())  
  66.             {  
  67.                 LogInfo.Error("发送获取菜单列表返回错误: " + Tools.ToJsonString<MenuListResult>(tempAccessTokenjson));  
  68.                 return false;  
  69.             }  
  70.           
  71.             return true;  
  72.         }  
  73.     }  

测试代码

[csharp] view plain copy
  1. private void button7_Click(object sender, EventArgs e)  
  2.        {  
  3.     ///测试添加  
  4.            ConmonWeixin.MenuInfo.Menu info = new ConmonWeixin.MenuInfo.Menu();  
  5.            SubButton subbt1 = SubButton.CreateSubButton(MenuTypeEnum.click, "Click1", "Click1", "");            
  6.            subbt1.sub_button = new List<SubButton>();  
  7.            SubButton bt11 = SubButton.CreateSubButton(MenuTypeEnum.scancode_push, "codePush2", "CancodePushButton11", "");  
  8.            SubButton bt12 = SubButton.CreateSubButton(MenuTypeEnum.scancode_waitmsg, "codeWaitmsg2", "CancodeWaitmsgButton12", "");  
  9.            SubButton bt13 = SubButton.CreateSubButton(MenuTypeEnum.click, "Click12", "Click12", "");  
  10.            SubButton bt14 = SubButton.CreateSubButton(MenuTypeEnum.view, "V2级", "V22", "https://www.baidu.com");   
  11.            subbt1.sub_button.Add(bt11);  
  12.            subbt1.sub_button.Add(bt12);  
  13.            subbt1.sub_button.Add(bt13);  
  14.            subbt1.sub_button.Add(bt14);  
  15.            SubButton subbt2 = SubButton.CreateSubButton(MenuTypeEnum.view, "V1级", "", "www.baidu.com");              
  16.            subbt2.sub_button = new List<SubButton>();  
  17.            SubButton bt21 = SubButton.CreateSubButton(MenuTypeEnum.pic_sysphoto, "PicSysphoto", "PicSysphotoButton21", "");  
  18.   
  19.            SubButton bt22 = SubButton.CreateSubButton(MenuTypeEnum.pic_photo_or_album, "photoalbum2", "PicSysphotoButton22", "");             
  20.            subbt2.sub_button.Add(bt21);  
  21.            subbt2.sub_button.Add(bt22);  
  22.   
  23.            SubButton subbt3 = SubButton.CreateSubButton(MenuTypeEnum.view, "V1级", "", "http://hlogin.html");            
  24.            subbt3.sub_button = new List<SubButton>();  
  25.            SubButton bt31 = SubButton.CreateSubButton(MenuTypeEnum.pic_weixin, "pic_weixin2", "Subpic_weixinButton31", "");  
  26.   
  27.            SubButton bt32 = SubButton.CreateSubButton(MenuTypeEnum.location_select, "location_selec", "location_selec32", "");  
  28.            subbt3.sub_button.Add(bt31);  
  29.            subbt3.sub_button.Add(bt32);  
  30.   
  31.            info.button = new List<SubButton>();  
  32.            info.button.Add(subbt1);  
  33.            info.button.Add(subbt2);  
  34.            info.button.Add(subbt3);  
  35.            BLLMenu.Create(info,7);  
  36.          //  Menu info, int agentid  
  37.        }  
  38.   
  39.        private void button8_Click(object sender, EventArgs e)  
  40.        {  
  41.     //测试删除  
  42.            BLLMenu.DelAll(7);  
  43.        }  

创建应用菜单官方文档

菜单接收事件官方文档

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
C#开发微信门户及应用(20)
Delphi从Internet下载文件
利用IDL程序自动添加ENVI菜单
偷懒利器 EmEditor
关于在C#中调用C DLL 时的参数传递
钉钉免登录
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服