ASP.NET MVC5+EF6+EasyUI后台管理系统 微信公众平台开发之消息管理
前言
回顾上一节,我们熟悉的了解了消息的请求和响应,这一节我们来建立数据库的表,表的设计蛮复杂
你也可以按自己所分析的情形结构来建表
必须非常熟悉表的结果才能运用这张表,这表表的情形涵盖比较多
思维导图
我这个人比较喜欢用思维导图来分析和表达一些模型:
表结构
根据思维导图,我们可以建立的表可以是3张表:消息表,规则表,类型表
消息表:实际的消息
规则表:文本、图文、语音等
类型表:文本、图文、语音(默认回复,订阅回复)
也可以是两张表:规制表,消息表(+一个类型字段)
我这里只设计一张表:消息表(+一个规则字段+一个类型字段)
设计表结构与个人的平时习惯有关系,我还是喜欢简单的东西,别为了设计而去专门设计,这样只会增加系统的复杂度
create table [dbo].[wc_messageresponse]( [id] [varchar](50) not null, --主键 [officalaccountid] [varchar](50) null, --所属公众号 [messagerule] [int] null, --消息规则(枚举) [category] [int] null, --类型(枚举) [matchkey] [varchar](1000) null, --关键字 [textcontent] [varchar](max) null, --文本内容 [imgtextcontext] [varchar](max) null, --图文文本内容 [imgtexturl] [varchar](1000) null, --图文图片url [imgtextlink] [varchar](1000) null, --图文图片超链接 [meidaurl] [varchar](1000) null, --语音url [meidalink] [varchar](1000) null, --语音超链接 [enable] [bit] not null, --是否启用 [isdefault] [bit] not null, --是否默认 [remark] [varchar](2000) null, --说明 [sort] [int] not null, --排序 [createtime] [datetime] not null, --创建时间 [createby] [varchar](50) not null, --创建人 [modifytime] [datetime] not null, --修改时间 [modifyby] [varchar](50) null, --修改人 constraint [pk_wc_messageresponse] primary key clustered ( [id] asc )with (pad_index = off, statistics_norecompute = off, ignore_dup_key = off, allow_row_locks = on, allow_page_locks = on) on [primary] ) on [primary] textimage_on [primary] go set ansi_padding off go alter table [dbo].[wc_messageresponse] with check add constraint [fk_wc_messageresponse_wc_officalacconts] foreign key([officalaccountid]) references [dbo].[wc_officalaccounts] ([id]) on delete cascade go alter table [dbo].[wc_messageresponse] check constraint [fk_wc_messageresponse_wc_officalacconts] go
表对应了两个枚举和关联主表公众号管理的主表
create table [dbo].[wc_officalaccounts]( [id] [varchar](50) not null, --主键 [officalid] [varchar](200) null, --公众号的唯一id [officalname] [varchar](200) not null, --公众号名称 [officalcode] [varchar](200) not null, --公众号帐号 [officalphoto] [varchar](1000) null, --头像 [officalkey] [varchar](500) null, --encodingaeskey [apiurl] [varchar](1000) null, --我们的资源服务器 [token] [varchar](200) null, --token [appid] [varchar](200) null, --appid [appsecret] [varchar](200) null, --appsecret [accesstoken] [varchar](200) null, --访问token [remark] [varchar](2000) null, --说明 [enable] [bit] not null, --是否启用 [isdefault] [bit] not null, --是否为当前默认操作号 [category] [int] not null, --类别(媒体号,企业号,个人号,开发测试号) [createtime] [datetime] not null, --创建时间 [createby] [varchar](50) not null, --创建人 [modifytime] [datetime] not null, --修改时间 [modifyby] [varchar](50) null, --修改人 constraint [pk_wc_officalacconts] primary key clustered ( [id] asc )with (pad_index = off, statistics_norecompute = off, ignore_dup_key = off, allow_row_locks = on, allow_page_locks = on) on [primary] ) on [primary]
对应的枚举
public enum wechatreplycategory { //文本 text =1, //图文 image =2, //语音 voice =3, //相等,用于回复关键字 equal=4, //包含,用于回复关键字 contain = 5 } public enum wechatrequestruleenum { /// <summary> /// 默认回复,没有处理的 /// </summary> default =0, /// <summary> /// 关注回复 /// </summary> subscriber =1, /// <summary> /// 文本回复 /// </summary> text =2, /// <summary> /// 图片回复 /// </summary> image =3, /// <summary> /// 语音回复 /// </summary> voice =4, /// <summary> /// 视频回复 /// </summary> video =5, /// <summary> /// 超链接回复 /// </summary> link =6, /// <summary> /// lbs位置回复 /// </summary> location =7, }
枚举其实对应就是我省掉的其余两张表
到这里,相信表的设计已经非常清晰
后台代码
增删改查非常普通,主要关注点在前端,前端处理提交的消息中,必须包含规则,类型,来指定消息的最终表达
controller
[httppost] [supportfilter(actionname = "edit")] public jsonresult postdata(wc_messageresponsemodel model) { wc_officalaccountsmodel accountmodel = account_bll.getcurrentaccount(); if (string.isnullorempty(model.id)) { model.id = resulthelper.newid; } model.createby = getuserid(); model.createtime = resulthelper.nowtime; model.modifyby = getuserid(); model.modifytime = resulthelper.nowtime; model.officalaccountid = accountmodel.id; model.enable = true; model.isdefault = true; if (m_bll.postdata(ref errors, model)) { loghandler.writeservicelog(getuserid(), "id" + model.id + ",officalaccountid" + model.officalaccountid, "成功", "保存", "wc_messageresponse"); return json(jsonhandler.createmessage(1, resource.savesucceed)); } else { string errorcol = errors.error; loghandler.writeservicelog(getuserid(), "id" + model.id + ",officalaccountid" + model.officalaccountid + "," + errorcol, "失败", "保存", "wc_messageresponse"); return json(jsonhandler.createmessage(0, resource.savefail + errorcol)); } }
bll
public bool postdata(ref validationerrors errors, wc_messageresponsemodel model) { try { wc_messageresponse entity = new wc_messageresponse(); if (isexists(model.id)) { entity = m_rep.getbyid(model.id); } entity.id = model.id; entity.officalaccountid = model.officalaccountid; entity.messagerule = model.messagerule; entity.category = model.category; entity.matchkey = model.matchkey; entity.textcontent = model.textcontent; entity.imgtextcontext = model.imgtextcontext; entity.imgtexturl = model.imgtexturl; entity.imgtextlink = model.imgtextlink; entity.meidaurl = model.meidaurl; entity.enable = model.enable; entity.isdefault = model.isdefault; entity.remark = model.remark; entity.createtime = model.createtime; entity.createby = model.createby; entity.sort = model.sort; entity.modifytime = model.modifytime; entity.modifyby = model.modifyby; if (m_rep.postdata(entity)) { return true; } else { errors.add(resource.nodatachange); return false; } } catch (exception ex) { errors.add(ex.message); exceptionhander.writeexception(ex); return false; } }
dal
public bool postdata(wc_messageresponse model) { //如果所有开关都关掉,证明不启用回复 if (model.category == null) { return true; } //全部设置为不默认 executesqlcommand(string.format("update [dbo].[wc_messageresponse] set isdefault=0 where officalaccountid ='{0}' and messagerule={1}", model.officalaccountid, model.messagerule)); //默认回复和订阅回复,且不是图文另外处理,因为他们有3种模式,但是只有一个是默认的 if (model.category!= (int)wechatreplycategory.image && (model.messagerule == (int)wechatrequestruleenum.default || model.messagerule == (int)wechatrequestruleenum.subscriber)) { //查看数据库是否存在数据 var entity = context.wc_messageresponse.where(p => p.officalaccountid == model.officalaccountid && p.messagerule == model.messagerule && p.category == model.category).firstordefault(); if (entity != null) { //删除原来的 context.wc_messageresponse.remove(entity); } } //全部设置为默认 executesqlcommand(string.format("update [dbo].[wc_messageresponse] set isdefault=1 where officalaccountid ='{0}' and messagerule={1} and category={2}", model.officalaccountid, model.messagerule,model.category)); //修改 if(isexist(model.id)) { context.entry<wc_messageresponse>(model).state = entitystate.modified; return edit(model); } else { return create(model); } }
dal层有必要来说明一下
默认回复和关注回复有3种类型:文本,图文,语音(但是只能有一种,所以有isdefault字段来表明执行哪种回复)所以这两个规则必须另外处理,且看dal的代码执行的sql语句便明白。
所以我们尽情的设计前端吧!
前端如何设计?
我们来看一个思维导图:
前端完整代码
<style> .formtable td { vertical-align: top; padding: 10px; } .formtable th { text-align: left; padding: 10px; height: 30px; } .formtablenormal { width: 500px; } .formtablenormal th { border: 0px; text-align: right; } .formtablenormal td { border: 0px; vertical-align: middle; } </style> <script> //1文本2图文3语音 var category = { text: 1, image: 2, voice: 3, equal: 4, contain: 5 }; // var requestrule = { default: 0, subscriber: 1, text: 2, image: 3, voice: 4, video: 5, link: 6, location: 7 }; function initdefault() { $('#swtext0').switchbutton({ onchange: function(checked) { if (checked) { $('#swimage0').switchbutton("uncheck"); $('#swvoice0').switchbutton("uncheck"); $("#div01").show(); $("#div02,#div03").hide(); $("#category").val(category.text); } } }); $('#swimage0').switchbutton({ onchange: function(checked) { if (checked) { $('#swvoice0').switchbutton("uncheck"); $('#swtext0').switchbutton("uncheck"); $("#div02").show(); $("#div01,#div03").hide(); $("#category").val(category.image); $("#list0").datagrid("resize"); } } }); $('#swvoice0').switchbutton({ onchange: function(checked) { if (checked) { $('#swimage0').switchbutton("uncheck"); $('#swtext0').switchbutton("uncheck"); $("#div03").show(); $("#div01,#div02").hide(); $("#category").val(category.voice); } } }); //文本 $.post('@url.action("getlist")', { page: 1, rows: 1, category: category.text, messagerule: requestrule.default }, function(data) { var rows = data.rows; for (var i = 0; i < rows.length; i++) { if (rows[i].category == category.text) { $("#text0").val(rows[i].textcontent); if (rows[i].isdefault) { $('#swtext0').switchbutton("check"); $('#swimage0').switchbutton("uncheck"); $('#swvoice0').switchbutton("uncheck"); } } } }); //语音 $.post('@url.action("getlist")', { page: 1, rows: 1, category: category.voice, messagerule: requestrule.default }, function (data) { var rows = data.rows; for (var i = 0; i < rows.length; i++) { if (rows[i].category == category.voice) { $("#voicetitle0").val(rows[i].textcontent); $("#voicecontent0").val(rows[i].remark); $("#voiceurl0").val(rows[i].meidaurl); if (rows[i].isdefault) { $('#swvoice0').switchbutton("check"); $('#swtext0').switchbutton("uncheck"); $('#swimage0').switchbutton("uncheck"); } } } }); $('#list0').datagrid({ url: '@url.action("getlist")?messagerule=' + requestrule.default + '&category=' + category.image, width: setgridwidthsub(40), methord: 'post', height: setgridheightsub(175), fitcolumns: true, sortname: 'sort', sortorder: 'asc', idfield: 'id', pagesize: 15, pagelist: [15, 20, 30, 40, 50], pagination: true, striped: true, //奇偶行是否区分 singleselect: true, onloadsuccess: function (data) { if (data.rows.length > 0) { if (data.rows[0].isdefault) { $('#swimage0').switchbutton("check"); $('#swtext0').switchbutton("uncheck"); $('#swvoice0').switchbutton("uncheck"); $("#category").val(category.image); } } }, //单选模式 //rownumbers: true,//行号 columns: [[{ field: 'id', title: 'id', width: 80, hidden: true }, { field: 'textcontent', title: '标题', width: 80, sortable: true }, { field: 'imgtexturl', title: '图片', width: 50, sortable: true, align: 'center', formatter: function (value) { return "<img width='80' height='80' src='" + value + "'/>" } }, { field: 'imgtextlink', title: '超链接', width: 80, sortable: true }, { field: 'imgtextcontext', title: '回复内容', width: 180, sortable: true }, ]] }); $("#btncreate02").unbind().click(function () { $("#modalwindow0").window({ title: '@resource.create', width: 700, height: 500, iconcls: 'fa fa-plus' }).window('open'); }); $("#btnsava01").unbind().click(function() { //默认回复 $("#messagerule").val(requestrule.default); if ($.trim($("#text0").val())=="") { $.messager.alert('@resource.tip', '内容必须填写!', 'warning'); return; } $("#textcontent").val($.trim($("#text0").val())); if ($("#form").valid()) { $.ajax({ url: "@url.action("postdata")", type: "post", data: $("#form").serialize(), datatype: "json", success: function(data) { $.messagebox5s('@resource.tip', data.message); } }); } }); $("#btnsava02").unbind().click(function () { if ($.trim($("#imagetitle0").val()) == "") { $.messager.alert('@resource.tip', '标题必须填写!', 'warning'); return; } if ($.trim($("#imageurl0").val()) == "") { $.messager.alert('@resource.tip', '图片必须上传!', 'warning'); return; } if ($.trim($("#sort0").val()) == "") { $.messager.alert('@resource.tip', '排序必须填写!', 'warning'); return; } //图文回复 $("#messagerule").val(requestrule.default); $("#textcontent").val($("#imagetitle0").val()); $("#imgtexturl").val($("#imageurl0").val()); $("#imgtextcontext").val($("#imagecontent0").val()); $("#imgtextlink").val($("#imagelink0").val()); $("#sort").val($("#sort0").val()); if ($("#form").valid()) { $.ajax({ url: "@url.action("postdata")", type: "post", data: $("#form").serialize(), datatype: "json", success: function(data) { if (data.type == 1) { $("#id").val(""); $("#list0").datagrid('reload'); $("#modalwindow0").window('close'); $("#imagetitle0").val(""); $("#form02 img").attr("src", "/content/images/notpic.jpg"); $("#imagecontent0").val(""); $("#imagelink0").val(""); $("#sort0").val(0); $('#fileupload02').val(''); } $.messagebox5s('@resource.tip', data.message); } }); } }); $("#btnsava03").unbind().click(function() { //默认回复 $("#messagerule").val(requestrule.default); if ($.trim($("#text0").val())=="") { if ($.trim($("#voicetitle0").val()) == "") { $.messager.alert('@resource.tip', '标题必须填写!', 'warning'); return; } if ($.trim($("#voiceurl0").val()) == "") { $.messager.alert('@resource.tip', '必须上传语音!', 'warning'); return; } $("#textcontent").val($("#voicetitle0").val()); $("#meidaurl").val($("#voiceurl0").val()); $("#remark").val($("#voicecontent0").val()); } if ($("#form").valid()) { $.ajax({ url: "@url.action("postdata")", type: "post", data: $("#form").serialize(), datatype: "json", success: function(data) { $.messagebox5s('@resource.tip', data.message); } }); } }); } function initsubscriber() { $('#swtext1').switchbutton({ onchange: function(checked) { if (checked) { $('#swimage1').switchbutton("uncheck"); $('#swvoice1').switchbutton("uncheck"); $("#div11").show(); $("#div12,#div13").hide(); $("#category").val(category.text); } } }); $('#swimage1').switchbutton({ onchange: function(checked) { if (checked) { $('#swvoice1').switchbutton("uncheck"); $('#swtext1').switchbutton("uncheck"); $("#div12").show(); $("#div11,#div13").hide(); $("#category").val(category.image); $("#list1").datagrid("resize"); } } }); $('#swvoice1').switchbutton({ onchange: function(checked) { if (checked) { $('#swimage1').switchbutton("uncheck"); $('#swtext1').switchbutton("uncheck"); $("#div13").show(); $("#div11,#div12").hide(); $("#category").val(category.voice); } } }); //文本 $.post('@url.action("getlist")', { page: 1, rows: 1, category: category.text, messagerule: requestrule.subscriber }, function(data) { var rows = data.rows; for (var i = 0; i < rows.length; i++) { if (rows[i].category == category.text) { $("#text1").val(rows[i].textcontent); if (rows[i].isdefault) { $('#swtext1').switchbutton("check"); $('#swimage1').switchbutton("uncheck"); $('#swvoice1').switchbutton("uncheck"); } } } }); //语音 $.post('@url.action("getlist")', { page: 1, rows: 1, category: category.voice, messagerule: requestrule.subscriber }, function (data) { var rows = data.rows; for (var i = 0; i < rows.length; i++) { if (rows[i].category == category.voice) { $("#voicetitle1").val(rows[i].textcontent); $("#voicecontent1").val(rows[i].remark); if (rows[i].isdefault) { $('#swvoice1').switchbutton("check"); $('#swtext1').switchbutton("uncheck"); $('#swimage1').switchbutton("uncheck"); } } } }); $('#list1').datagrid({ url: '@url.action("getlist")?messagerule=' + requestrule.subscriber + '&category=' + category.image, width: setgridwidthsub(40), methord: 'post', height: setgridheightsub(175), fitcolumns: true, sortname: 'sort', sortorder: 'asc', idfield: 'id', pagesize: 15, pagelist: [15, 20, 30, 40, 50], pagination: true, striped: true, //奇偶行是否区分 singleselect: true, onloadsuccess: function (data) { if (data.rows.length > 0) { if (data.rows[0].isdefault) { $('#swimage1').switchbutton("check"); $('#swtext1').switchbutton("uncheck"); $('#swvoice1').switchbutton("uncheck"); } } }, //单选模式 //rownumbers: true,//行号 columns: [[{ field: 'id', title: 'id', width: 80, hidden: true }, { field: 'textcontent', title: '标题', width: 80, sortable: true }, { field: 'imgtexturl', title: '图片', width: 50, sortable: true, align: 'center', formatter: function (value) { return "<img width='80' height='80' src='" + value + "'/>" } }, { field: 'imgtextlink', title: '超链接', width: 80, sortable: true }, { field: 'imgtextcontext', title: '回复内容', width: 180, sortable: true }, ]] }); $("#btncreate12").unbind().click(function () { $("#modalwindow1").window({ title: '@resource.create', width: 700, height: 500, iconcls: 'fa fa-plus' }).window('open'); }); $("#btnsava11").unbind().click(function() { //默认回复 $("#messagerule").val(requestrule.subscriber); if ($.trim($("#text1").val())=="") { $.messager.alert('@resource.tip', '内容必须填写!', 'warning'); return; } $("#textcontent").val($.trim($("#text1").val())); if ($("#form").valid()) { $.ajax({ url: "@url.action("postdata")", type: "post", data: $("#form").serialize(), datatype: "json", success: function(data) { $.messagebox5s('@resource.tip', data.message); } }); } }); $("#btnsava12").unbind().click(function () { if ($.trim($("#imagetitle1").val()) == "") { $.messager.alert('@resource.tip', '标题必须填写!', 'warning'); return; } if ($.trim($("#imageurl1").val()) == "") { $.messager.alert('@resource.tip', '图片必须上传!', 'warning'); return; } if ($.trim($("#sort1").val()) == "") { $.messager.alert('@resource.tip', '排序必须填写!', 'warning'); return; } //图文回复 $("#messagerule").val(requestrule.subscriber); $("#textcontent").val($("#imagetitle1").val()); $("#imgtexturl").val($("#imageurl1").val()); $("#imgtextcontext").val($("#imagecontent1").val()); $("#imgtextlink").val($("#imagelink1").val()); $("#sort").val($("#sort1").val()); if ($("#form").valid()) { $.ajax({ url: "@url.action("postdata")", type: "post", data: $("#form").serialize(), datatype: "json", success: function(data) { if (data.type == 1) { $("#id").val(""); $("#list1").datagrid('reload'); $("#modalwindow1").window('close'); $("#imagetitle1").val(""); $("#form12 img").attr("src", "/content/images/notpic.jpg"); $("#imagecontent1").val(""); $("#imagelink1").val(""); $("#sort1").val(0); $('#fileupload12').val(''); } $.messagebox5s('@resource.tip', data.message); } }); } }); $("#btnsava13").unbind().click(function() { //默认回复 $("#messagerule").val(requestrule.subscriber); if ($.trim($("#text1").val())=="") { if ($.trim($("#voicetitle1").val()) == "") { $.messager.alert('@resource.tip', '标题必须填写!', 'warning'); return; } if ($.trim($("#voiceurl1").val()) == "") { $.messager.alert('@resource.tip', '必须上传语音!', 'warning'); return; } $("#textcontent").val($("#voicetitle1").val()); $("#meidaurl").val($("#voiceurl1").val()); $("#remark").val($("#voicecontent1").val()); } if ($("#form").valid()) { $.ajax({ url: "@url.action("postdata")", type: "post", data: $("#form").serialize(), datatype: "json", success: function(data) { $.messagebox5s('@resource.tip', data.message); } }); } }); } function inittext() { $("#category").val(category.equal); $('#list2').datagrid({ url: '@url.action("getlist")?messagerule=' + requestrule.text, width: setgridwidthsub(40), methord: 'post', height: setgridheightsub(100), fitcolumns: true, sortname: 'createtime', sortorder: 'desc', idfield: 'id', pagesize: 15, pagelist: [15, 20, 30, 40, 50], pagination: true, striped: true, //奇偶行是否区分 singleselect: true, //单选模式 //rownumbers: true,//行号 columns: [[{ field: 'id', title: 'id', width: 80, hidden: true }, { field: 'category', title: 'category', width: 80, sortable: true, hidden: true }, { field: 'matchkey', title: '关键字', width: 80, sortable: true, formatter: function (value,row,index){ if (row.category == category.equal) { return "(完全匹配)" + value } else { return "(模糊匹配)" + value } } }, { field: 'textcontent', title: '回复内容', width: 80, sortable: true }, ]] }); $('#swmessagerule2').switchbutton({ onchange: function(checked) { if (checked) { $("#category").val(category.equal); } else { $("#category").val(category.contain); } } }); $("#btncreate2").unbind().click(function () { $("#modalwindow2").window({ title: '@resource.create', width: 700, height: 400, iconcls: 'fa fa-plus' }).window('open'); }); $("#btnsava2").unbind().click(function () { if ($.trim($("#textmatchkey2").val()) == "") { $.messager.alert('@resource.tip', '关键字必须填写!', 'warning'); return; } if ($.trim($("#text2").val()) == "") { $.messager.alert('@resource.tip', '内容必须填写!', 'warning'); return; } //文本回复 $("#messagerule").val(requestrule.text); $("#matchkey").val($.trim($("#textmatchkey2").val())); $("#textcontent").val($("#text2").val()); if ($("#form").valid()) { $.ajax({ url: "@url.action("postdata")", type: "post", data: $("#form").serialize(), datatype: "json", success: function(data) { if (data.type == 1) { $("#id").val(""); $("#list2").datagrid('reload'); $("#modalwindow2").window('close'); $("#textmatchkey2").val(""); $("#text2").val(""); } $.messagebox5s('@resource.tip', data.message); } }); } }); } function initimage() { $("#category").val(category.equal); $('#list31').datagrid({ url: '@url.action("getlistproperty")?messagerule=' + requestrule.image, width: 300, methord: 'post', height: setgridheightsub(100), fitcolumns: true, sortname: 'createtime', sortorder: 'desc', idfield: 'id', pagesize: 15, pagelist: [15, 20, 30, 40, 50], pagination: true, striped: true, //奇偶行是否区分 singleselect: true, onclickrow: function (index,data) { var row = $('#list31').datagrid('getselected'); if (row != null) { $('#list3').datagrid({url:'@url.action("getlist")?messagerule='+requestrule.image+'&category='+row.category+'&matchkey='+row.matchkey}); } }, //单选模式 //rownumbers: true,//行号 columns: [[{ field: 'id', title: 'id', width: 80, hidden: true }, { field: 'category', title: 'category', width: 80, sortable: true, hidden: true }, { field: 'matchkey', title: '关键字', width: 130, sortable: true, formatter: function (value, row, index) { if (row.category == category.equal) { return "(完全匹配)" + value } else { return "(模糊匹配)" + value } } }, { field: 'createtime', title: '创建时间', width: 80, sortable: true }, ]] }).datagrid('getpager').pagination({ showpagelist: true, showrefresh: false, displaymsg: '' }); $('#list3').datagrid({ url:'@url.action("getlist")?messagerule='+requestrule.image+'&category=x&matchkey=x', width: setgridwidthsub(340), methord: 'post', height: setgridheightsub(100), fitcolumns: true, sortname: 'sort', sortorder: 'asc', idfield: 'id', pagesize: 15, pagelist: [15, 20, 30, 40, 50], pagination: true, striped: true, //奇偶行是否区分 singleselect: true, //单选模式 //rownumbers: true,//行号 columns: [[{ field: 'id', title: 'id', width: 80, hidden: true }, { field: 'category', title: 'category', width: 80, sortable: true, hidden: true }, { field: 'textcontent', title: '标题', width: 80, sortable: true }, { field: 'matchkey', title: '关键字', width: 80, sortable: true, formatter: function (value,row,index){ if (row.category == category.equal) { return "(完全匹配)" + value } else { return "(模糊匹配)" + value } } }, { field: 'imgtexturl', title: '图片', width: 50, sortable: true, align: 'center', formatter: function (value) { return "<img width='80' height='80' src='" + value + "'/>" } }, { field: 'imgtextlink', title: '超链接', width: 80, sortable: true }, { field: 'imgtextcontext', title: '回复内容', width: 180, sortable: true }, { field: 'sort', title: '排序', width: 50, sortable: true }, ]] }); $('#swmessagerule3').switchbutton({ onchange: function(checked) { if (checked) { $("#category").val(category.equal); } else { $("#category").val(category.contain); } } }); $("#btncreate3").unbind().click(function () { $("#modalwindow3").window({ title: '@resource.create', width: 700, height: 550, iconcls: 'fa fa-plus' }).window('open'); }); $("#btnsava3").unbind().click(function () { if ($.trim($("#imagetitle3").val()) == "") { $.messager.alert('@resource.tip', '标题必须填写!', 'warning'); return; } if ($.trim($("#textmatchkey3").val()) == "") { $.messager.alert('@resource.tip', '关键字必须填写!', 'warning'); return; } if ($.trim($("#imageurl3").val()) == "") { $.messager.alert('@resource.tip', '图片必须上传!', 'warning'); return; } //图文回复 $("#messagerule").val(requestrule.image); $("#matchkey").val($.trim($("#textmatchkey3").val())); $("#textcontent").val($("#imagetitle3").val()); $("#imgtexturl").val($("#imageurl3").val()); $("#imgtextcontext").val($("#imagecontent3").val()); $("#imgtextlink").val($("#imagelink3").val()); $("#sort").val($("#sort3").val()); if ($("#form").valid()) { $.ajax({ url: "@url.action("postdata")", type: "post", data: $("#form").serialize(), datatype: "json", success: function(data) { if (data.type == 1) { $("#id").val(""); $("#list3").datagrid('reload'); $("#list31").datagrid('reload'); $("#modalwindow3").window('close'); $("#imagetitle3").val(""); $("#form3 img").attr("src", "/content/images/notpic.jpg"); $("#imagecontent3").val(""); $("#imagelink3").val(""); $("#sort3").val(0); $('#fileupload3').val(''); $("#textmatchkey3").val(''); } $.messagebox5s('@resource.tip', data.message); } }); } }); } function initvoice() { $("#category").val(category.equal); $('#list4').datagrid({ url: '@url.action("getlist")?messagerule=' + requestrule.voice, width: setgridwidthsub(40), methord: 'post', height: setgridheightsub(100), fitcolumns: true, sortname: 'createtime', sortorder: 'desc', idfield: 'id', pagesize: 15, pagelist: [15, 20, 30, 40, 50], pagination: true, striped: true, //奇偶行是否区分 singleselect: true, //单选模式 //rownumbers: true,//行号 columns: [[{ field: 'id', title: 'id', width: 80, hidden: true }, { field: 'category', title: 'category', width: 80, sortable: true, hidden: true }, { field: 'textcontent', title: '标题', width: 80, sortable: true }, { field: 'matchkey', title: '关键字', width: 80, sortable: true, formatter: function (value,row,index){ if (row.category == category.equal) { return "(完全匹配)" + value } else { return "(模糊匹配)" + value } } }, { field: 'meidaurl', title: '语音', width: 80, sortable: true, align: 'center', formatter: function (value) { return "<img width='80' height='80' src='" + value + "'/>" } }, { field: 'imgtextlink', title: '超链接', width: 80, sortable: true }, { field: 'imgtextcontext', title: '回复内容', width: 80, sortable: true }, ]] }); $('#swmessagerule4').switchbutton({ onchange: function(checked) { if (checked) { $("#category").val(category.equal); } else { $("#category").val(category.contain); } } }); $("#btncreate4").unbind().click(function() { $("#modalwindow4").window({ title: '@resource.create', width: 700, height: 500, iconcls: 'fa fa-plus' }).window('open'); }); $("#btnsava4").unbind().click(function () { if ($.trim($("#voicetitle4").val()) == "") { $.messager.alert('@resource.tip', '标题必须填写!', 'warning'); return; } if ($.trim($("#textmatchkey4").val()) == "") { $.messager.alert('@resource.tip', '关键字必须填写!', 'warning'); return; } if ($.trim($("#voiceurl4").val()) == "") { $.messager.alert('@resource.tip', '必须上传语音!', 'warning'); return; } //图文回复 $("#messagerule").val(requestrule.voice); $("#matchkey").val($("#textmatchkey4").val()); $("#textcontent").val($("#voicetitle4").val()); $("#meidaurl").val($("#voiceurl4").val()); $("#remark").val($("#voicecontent4").val()); if ($("#form").valid()) { $.ajax({ url: "@url.action("postdata")", type: "post", data: $("#form").serialize(), datatype: "json", success: function(data) { if (data.type == 1) { $("#id").val(""); $("#list4").datagrid('reload'); $("#modalwindow4").window('close'); $("#textmatchkey4").val(""); $("#voicetitle4").val(""); $("#voiceurl4").val(""); $("#voicecontent4").val(""); $("#fileupload4").val(""); $("#form3 img").attr("src", "/content/images/notpic.jpg"); } $.messagebox5s('@resource.tip', data.message); } }); } }); } $(function() { $('#tt').tabs({ justified: true, width: '100%', height: $(window).height() - 20 }); $('#tt').tabs({ onselect: function(title, index) { switch (index) { case requestrule.default: initdefault(); break; case requestrule.subscriber: initsubscriber(); break; case requestrule.text: inittext(); break; case requestrule.image: initimage(); break; case requestrule.voice: initvoice(); break; } } }); //初始化第一个标签 initdefault(); //自动宽高 $(window).resize(function() { $('#tt').tabs({ height:$(window).height() - 20 }); //$('#list2').datagrid('resize', { // width: setgridwidthsub(40), // height: setgridheightsub(100) //}); }); }); $(function () { $('input.textbox').validatebox().bind('blur', function () { $(this).validatebox('enablevalidation').validatebox('validate'); }); }) </script> <form id="form" method="post"> <input type="hidden" id="id" name="id" /> <input type="hidden" id="messagerule" name="messagerule" /> <input type="hidden" id="category" name="category" /> <input type="hidden" id="matchkey" name="matchkey" /> <input type="hidden" id="textcontent" name="textcontent" /> <input type="hidden" id="imgtextcontext" name="imgtextcontext" /> <input type="hidden" id="imgtexturl" name="imgtexturl" /> <input type="hidden" id="imgtextlink" name="imgtextlink" /> <input type="hidden" id="meidaurl" name="meidaurl" /> <input type="hidden" id="meidalink" name="meidalink" /> <input type="hidden" id="remark" name="remark" /> <input type="hidden" id="sort" name="sort" value="0" /> <input type="hidden" id="createtime" name="createtime" /> <input type="hidden" id="createby" name="createby" /> <input type="hidden" id="modifytime" name="modifytime" /> <input type="hidden" id="modifyby" name="modifyby" /> </form> <div style="padding:10px;"> <div id="tt" class="easyui-tabs"> <div title="默认回复"> <table class="formtable" style="height:45px; line-height:45px; width:100%; border-bottom:1px solid #e7eaec"> <tr> <td style="width:100px;"> 文本: @html.switchbuttonbyedit("swtext0", false) </td> <td style="width:100px;"> 图文: @html.switchbuttonbyedit("swimage0", false) </td> <td style="width:100px;"> 语音: @html.switchbuttonbyedit("swvoice0", false) </td> <td></td> <td style="width:300px;"> <div class="color-green">当前操作公众号:<span id="currentofficalaccount">@viewbag.currentofficalacount</span></div> </td> </tr> </table> <div id="div01" class="displaynone"> <div class="mvctool bgb"> @html.toolbutton("btnsava01", "fa fa-plus", "提交保存", ref perm, "edit", false) </div> <textarea id="text0" style="width: 300px;height: 330px; margin:20px;"></textarea> </div> <div id="div02" class="displaynone"> <div class="mvctool bgb"> @html.toolbutton("btncreate02", "fa fa-search", "添加回复", ref perm, "edit", false) </div> <div id="modalwindow0" class="easyui-window" style="width:600px; height:550px;" data-options="modal:true,closed: true,minimizable:false,shadow:false"> <div class="mvctool bgb"> @html.toolbutton("btnsava02", "fa fa-search", "提交保存", ref perm, "edit", false) </div> <table class="formtablenormal"> <tr><th>标题: </th><td><input type="text" id="imagetitle0" class="textbox" data-options="required:true" /></td></tr> <tr> <th>图片: </th> <td> <form id="form02" method="post"> <input type="hidden" name="imageurl0" id="imageurl0" /> <img class="expic" src="/content/images/notpic.jpg" /> <br /> <a href="javascript:$('#fileupload02').trigger('click');" class="files">@resource.browse</a> <input type="file" id="fileupload02" class="displaynone" name="fileupload02" onchange="upload('singlefile', 'imageurl0', 'fileupload02', '1', '1', '#form02');" /> <span class="uploading">@resource.uploading</span> </form> </tr> <tr><th>内容: </th><td><textarea id="imagecontent0" style="width: 300px; height: 100px;"></textarea></td></tr> <tr><th>链接: </th><td><input type="text" id="imagelink0" /></td></tr> <tr><th>排序: </th><td><input type="number" id="sort0" value="0" /></td></tr> </table> </div> <div style="padding:10px;"> <table id="list0"></table> </div> </div> <div id="div03" class="displaynone"> <div class="mvctool bgb"> @html.toolbutton("btnsava03", "fa fa-plus", "提交保存", ref perm, "edit", false) </div> <table class="formtablenormal" style="margin:20px;"> <tr><th>标题: </th><td><input type="text" id="voicetitle0" /></td></tr> <tr><th>语音: </th><td> <form id="form03" method="post"> <input type="text" name="voiceurl0" class="left" id="voiceurl0" /> <a href="javascript:$('#fileupload03').trigger('click');" class="files">@resource.browse</a> <input type="file" accept="audio/mpeg" id="fileupload03" class="displaynone" name="fileupload03" onchange="upload('singlefile', 'voiceurl0', 'fileupload03', '', '', '#form03');" /> <span class="uploading">@resource.uploading</span> </form> </td></tr> <tr><th>描述: </th><td><textarea id="voicecontent0" style="width:335px; height:300px;"></textarea></td></tr> </table> </div> </div> <div title="关注时回复" > <table class="formtable" style="height:45px; line-height:45px; width:100%; border-bottom:1px solid #e7eaec"> <tr> <td style="width:100px;"> 文本: @html.switchbuttonbyedit("swtext1", false) </td> <td style="width:100px;"> 图文: @html.switchbuttonbyedit("swimage1", false) </td> <td style="width:100px;"> 语音: @html.switchbuttonbyedit("swvoice1", false) </td> <td></td> <td style="width:300px;"> <div class="color-green">当前操作公众号:<span id="currentofficalaccount">@viewbag.currentofficalacount</span></div> </td> </tr> </table> <div id="div11" class="displaynone"> <div class="mvctool bgb"> @html.toolbutton("btnsava11", "fa fa-plus", "提交保存", ref perm, "edit", false) </div> <textarea id="text1" style="width: 300px;height: 330px; margin:20px;"></textarea> </div> <div id="div12" class="displaynone"> <div class="mvctool bgb"> @html.toolbutton("btncreate12", "fa fa-search", "添加回复", ref perm, "edit", false) @html.toolbutton("btnedit12", "fa fa-search", "编辑", ref perm, "edit", true) @html.toolbutton("btndelete12", "fa fa-search", "删除", ref perm, "delete", false) </div> <div id="modalwindow1" class="easyui-window" style="width:600px; height:550px;" data-options="modal:true,closed: true,minimizable:false,shadow:false"> <div class="mvctool bgb"> @html.toolbutton("btnsava12", "fa fa-search", "提交保存", ref perm, "edit", false) </div> <table class="formtablenormal"> <tr><th>标题: </th><td><input type="text" id="imagetitle1" class="textbox" data-options="required:true" /></td></tr> <tr> <th>图片: </th> <td> <form id="form12" method="post"> <input type="hidden" name="imageurl1" id="imageurl1" /> <img class="expic" src="/content/images/notpic.jpg" /> <br /> <a href="javascript:$('#fileupload12').trigger('click');" class="files">@resource.browse</a> <input type="file" id="fileupload12" class="displaynone" name="fileupload12" onchange="upload('singlefile', 'imageurl1', 'fileupload12', '1', '1', '#form12');" /> <span class="uploading">@resource.uploading</span> </form> </tr> <tr><th>内容: </th><td><textarea id="imagecontent1" style="width: 300px; height: 100px;"></textarea></td></tr> <tr><th>链接: </th><td><input type="text" id="imagelink1" /></td></tr> <tr><th>排序: </th><td><input type="number" id="sort1" value="0" /></td></tr> </table> </div> <div style="padding:10px;"> <table id="list1"></table> </div> </div> <div id="div13" class="displaynone"> <div class="mvctool bgb"> @html.toolbutton("btnsava13", "fa fa-plus", "提交保存", ref perm, "edit", false) </div> <table class="formtablenormal" style="margin:20px;"> <tr><th>标题: </th><td><input type="text" id="voicetitle1" /></td></tr> <tr> <th>语音: </th> <td> <form id="form13" method="post"> <input type="text" name="voiceurl1" class="left" id="voiceurl0" /> <a href="javascript:$('#fileupload13').trigger('click');" class="files">@resource.browse</a> <input type="file" accept="audio/mpeg" id="fileupload13" class="displaynone" name="fileupload13" onchange="upload('singlefile', 'voiceurl1', 'fileupload13', '', '', '#form13');" /> <span class="uploading">@resource.uploading</span> </form> </td> </tr> <tr><th>描述: </th><td><textarea id="voicecontent1" style="width:335px; height:300px;"></textarea></td></tr> </table> </div> </div> <div title="文本回复" style="padding:10px"> <div class="mvctool "> @html.toolbutton("btncreate2", "fa fa-search", "添加回复", ref perm, "edit", true) @html.toolbutton("btnedit2", "fa fa-search", "编辑", ref perm, "edit", true) @html.toolbutton("btndelete2", "fa fa-search", "删除", ref perm, "delete", false) <div class="rightdiv color-green"> 当前操作公众号: <span id="currentofficalaccount">@viewbag.currentofficalacount</span> </div> </div> <div id="modalwindow2" class="easyui-window" style="width:600px; height:500px;" data-options="modal:true,closed: true,minimizable:false,shadow:false"> <div class="mvctool bgb"> @html.toolbutton("btnsava2", "fa fa-search", "提交保存", ref perm, "edit", false) <div class="rightdiv color-green"> 当前操作公众号: <span id="currentofficalaccount">@viewbag.currentofficalacount</span> </div> </div> <table class="formtablenormal"> <tr> <th>关键字: </th> <td> <input type="text" id="textmatchkey2" /> </td> </tr> <tr> <th>规则: </th> <td> @html.switchbuttonbyedit("swmessagerule2", true, "模糊匹配(关键字包含内容) ", "完全匹配(内容与关键字完全匹配)", "280") </td> </tr> <tr> <th>内容: </th> <td> <textarea id="text2" style="width: 280px;height:200px"></textarea> </td> </tr> </table> </div> <table id="list2"></table> </div> <div title="图片回复" style="padding:10px"> <div class="mvctool"> @html.toolbutton("btncreate3", "fa fa-search", "添加回复", ref perm, "edit", true) @html.toolbutton("btnedit3", "fa fa-search", "编辑", ref perm, "edit", true) @html.toolbutton("btndelete3", "fa fa-search", "删除", ref perm, "delete", false) <div class="rightdiv color-green"> 当前操作公众号: <span id="currentofficalaccount">@viewbag.currentofficalacount</span> </div> </div> <div id="modalwindow3" class="easyui-window" style="width:600px; height:550px;" data-options="modal:true,closed: true,minimizable:false,shadow:false"> <div class="mvctool bgb"> @html.toolbutton("btnsava3", "fa fa-search", "提交保存", ref perm, "edit", false) <div class="rightdiv color-green"> 当前操作公众号: <span id="currentofficalaccount">@viewbag.currentofficalacount</span> </div> </div> <table class="formtablenormal"> <tr><th>标题: </th><td><input type="text" id="imagetitle3" /></td></tr> <tr> <th>关键字: </th> <td> <input type="text" id="textmatchkey3" /> </td> </tr> <tr> <th>规则: </th> <td> @html.switchbuttonbyedit("swmessagerule3", true, "模糊匹配(关键字包含内容) ", "完全匹配(内容与关键字完全匹配)", "280") </td> </tr> <tr> <th>图片: </th> <td> <form id="form3" method="post"> <input type="hidden" name="imageurl3" id="imageurl3" /> <img class="expic" src="/content/images/notpic.jpg" /> <br /> <a href="javascript:$('#fileupload3').trigger('click');" class="files">@resource.browse</a> <input type="file" id="fileupload3" class="displaynone" name="fileupload3" onchange="upload('singlefile', 'imageurl3', 'fileupload3', '1', '1', '#form3');" /> <span class="uploading">@resource.uploading</span> </form> </td> </tr> <tr><th>内容: </th><td><textarea id="imagecontent3" style="width: 300px; height: 80px;"></textarea></td></tr> <tr><th>链接: </th><td><input type="text" id="imagelink3" /></td></tr> <tr><th>排序: </th><td><input type="number" id="sort3" value="0" /></td></tr> </table> </div> <table><tr><td><table id="list31"></table></td><td> </td><td><table id="list3"></table></td></tr></table> </div> <div title="语音回复" style="padding:10px"> <div class="mvctool "> @html.toolbutton("btncreate4", "fa fa-search", "添加回复", ref perm, "edit", false) @html.toolbutton("btnedit4", "fa fa-search", "编辑", ref perm, "edit", true) @html.toolbutton("btndelete4", "fa fa-search", "删除", ref perm, "delete", false) <div class="rightdiv color-green"> 当前操作公众号: <span id="currentofficalaccount">@viewbag.currentofficalacount</span> </div> </div> <div id="modalwindow4" class="easyui-window" style="width:600px; height:500px;" data-options="modal:true,closed: true,minimizable:false,shadow:false"> <div class="mvctool bgb"> @html.toolbutton("btnsava4", "fa fa-search", "提交保存", ref perm, "edit", false) <div class="rightdiv color-green"> 当前操作公众号: <span id="currentofficalaccount">@viewbag.currentofficalacount</span> </div> </div> <table class="formtablenormal"> <tr><th>标题: </th><td><input type="text" id="voicetitle4" /></td></tr> <tr> <th>关键字: </th> <td> <input type="text" id="textmatchkey4" /> </td> </tr> <tr> <th>规则: </th> <td> @html.switchbuttonbyedit("swmessagerule4", true, "模糊匹配(关键字包含内容) ", "完全匹配(内容与关键字完全匹配)", "280") </td> </tr> <tr> <th>语音: </th> <td> <form id="form4" method="post"> <input type="text" class="left" name="voiceurl4" id="voiceurl4" /> <a href="javascript:$('#fileupload4').trigger('click');" class="files">@resource.browse</a> <input type="file" id="fileupload4" accept="audio/mpeg" class="displaynone" name="fileupload4" onchange="upload('singlefile', 'voiceurl4', 'fileupload4', '', '', '#form4');" /> <span class="uploading">@resource.uploading</span> </form> </td> </tr> <tr><th>描述: </th><td><textarea id="voicecontent4" style="width: 300px; height: 100px;"></textarea></td></tr> </table> </div> <table id="list4"></table> </div> @*<div title="视频回复" style="padding:10px"> </div>*@ @*<div title="链接回复" styie="padding:10px"> </div> <div title="lbs位置回复" style="padding:10px"> </div>*@ </div> </div>
利用前端的思维导图,来快速理解前端代码,和应用于实际
总结
消息的管理是非常有技巧的一件事
1.消息在没有任务回复的情况 下,我们应该启用默认回复,要不用户会得不到回应,丢失体验
2.关键字的设计一般是一环扣一环,是有引导作用的
比如:
关键字:(我要) 回复: 按1加入获得礼品一份,按2直接获得50元
关键字:(1) 回复: 按3获得铁观音茶一份,按4获得普洱茶
关键字:(3或4) 回复:请回复您的地址和电话及收件人
这样我们将获得系统与用户之间的完整对话,当然我们也要对用户最后的信息进行处理。
本文已被整理到了《asp.net微信开发教程汇总》,欢迎大家学习阅读。
关于管理系统的更多内容请点击《管理系统专题》进行学习
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
推荐阅读
-
ASP.NET MVC5+EF6+EasyUI后台管理系统 微信公众平台开发之消息管理
-
Java微信公众平台开发之消息管理
-
Koa2微信公众号开发之消息管理
-
Java微信公众平台开发之消息管理
-
ASP.NET MVC5+EF6+EasyUI微信后台管理系统实例解析
-
利用asp.net开发微信公众平台之获取用户消息并处理方法
-
ASP.NET MVC5+EF6+EasyUI 后台管理系统微信公众平台开发- 资源环境准备
-
ASP.NET MVC5+EF6+EasyUI 后台管理系统微信公众平台开发- 资源环境准备
-
利用asp.net开发微信公众平台之获取用户消息并处理方法
-
微信公众平台开发管理后台开发