用数据表管理多个菜单
普通用户可以忽略本节内容。
自行编写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