用数据表管理多个菜单

普通用户可以忽略本节内容。

自行编写JSON格式的菜单,是一件比较繁琐和容易出错的工作,特别是有大量的个性化菜单需要维护的时候。

我们也可以用数据表管理和生成菜单,之前我们在介绍生成默认菜单的时候,已经提供了一个简单的例子。

本节的例子更进一步,可以通过数据表管理和生成多个菜单,包括默认菜单和数量不等的个性化菜单。

1、首先我们设计一个表,名为Menus,表结构如下:



menu列为菜单名称。

matchrule列为菜单的匹配条件,为了方便输入,我们这里模仿了get数据格式"键1=值1&键2=值2"。

如果matchrule为空,也就是没有设置匹配条件,表示这是默认菜单。

默认菜单只有一个,虽然你可以设置多个默认菜单,但是新生成的会覆盖之前生成的。

个性化菜单可以有多个,微信服务器生成个性化菜单生成之后,会返回一个MenuID,我们需要将此值保存在MenuID列,方便维护。

2、再设计一个名为MenuButtons的表,用于输入菜单按钮,表结构为:



Menu列和上一个表的menu列对应,用于输入此按钮所属的菜单。

菜单按钮有一级和二级之分,parent列用于输入上菜单按钮名称,如果不设置,表示此按钮为一级菜单按钮。

type为view的按钮,必须输入url值;type为media_id或view_limited的按钮,必须输入media_id值(素材ID);其它类型的按钮,必须输入key值,否则会出错。

上面两个表定义了三个菜单,default为默认菜单,Menu1和Menu2为个性化菜单。

提示:所有列名都必须和接口说明中的属性名保持一致(包括大小写),以方便编码。

3、最后在菜单或窗口设计一个按钮,用于基于上面两个表生成菜单,代码为:

'首先要删除以前的菜单,这是必须的,否则个性化菜单会越来越多.
Dim
ur As String = "https://api.weixin.qq.com/cgi-bin/menu/delete?access_token={0}"
Dim
hc As new HttpClient(Cexp(ur,Functions.Execute("GetAccessToken")))
Dim
RO As New JObject
RO
= JObject.Parse(hc.GetData)
If
RO("errcode") <> "0" Then
    MessageBox.Show(RO("errcode"))
   
Return

End
If
'
基于数据表生成菜单.
For
Each menuRow As DataRow In DataTables("Menus").DataRows 'Menu表中每一行都对应一个菜单
    Dim FRows As List(of DataRow) = DataTables("MenuButtons").Select(CExp("menu='{0}' And [parent] is null",menuRow("menu")),"_SortKey")
    Dim nms As String() = {"type","name","url","key","media_id"}
    Dim FButtons As New Jarray
    For Each FRow As DataRow In FRows
'
生成一级菜单
        Dim SRows As List(of DataRow)
        SRows = DataTables("MenuButtons").Select(CExp("menu='{0}' And [parent] = '{1}'", menuRow("menu"), FRow("name")),"_SortKey")
        Dim FButton As New JObject
        If sRows.Count = 0 Then
            For Each nm As String In nms
                If FRow.IsNull(nm) = False Then
                    FButton(nm) = FRow(nm).ToString()
               
End If
            Next
       
Else

            Dim SButtons As New JArray
            For Each SRow As DataRow In SRows
'
生成二级菜单
                Dim SButton As New JObject
                For Each nm As String In nms
                    If SRow.IsNull(nm) = False Then
                        SButton(nm) = SRow(nm).ToString()
                    End If
                Next
                SButtons.Add(SButton)
            Next
            FButton("name") = FRow("name").ToString()
            FButton("sub_button") = SButtons
        End If
        FButtons.Add(FButton)
    Next
    Dim MO As New JObject
    MO("button") = FButtons
    If MenuRow.IsNull("matchrule") = False
'
如果设置了过滤条件,那就是个性化菜单了
        Dim FO As New JObject
        Dim fts() As String = MenuRow("matchrule").Split("&")
        For Each ft As String In fts
            Dim kv() As String = ft.Split("=")
            FO(kv(0)) = kv(1)
        Next
        MO("matchrule") = FO
        ur = "https://api.weixin.qq.com/cgi-bin/menu/addconditional?access_token={0}"
    Else
        ur = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token={0}"
    End If
    hc = New HttpClient(CExp(ur,Functions.Execute("GetAccessToken")))
    hc.Content = MO.ToString()
    RO = JObject.Parse(hc.GetData)
    If  RO("menuid") IsNot Nothing Then
        menuRow("MenuID") = RO("menuid")
    ElseIf RO("errcode") <> "0" Then
        MessageBox.Show(RO("errcode"))
    End
If

Next


本页地址:http://www.foxtable.com/mobilehelp/topics/0204.htm