前言回顾上一节,我们熟悉的了解了消息的请求和响应,这一节我们来建立数据库的表,表的设计蛮复杂
你也可以按自己所分析的情形结构来建表
必须非常熟悉表的结果才能运用这张表,这表表的情形涵盖比较多
思维导图我这个人比较喜欢用思维导图来分析和表达一些模型:
表结构根据思维导图,我们可以建立的表可以是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]goset ansi_padding offgoalter table [dbo].[wc_messageresponse] with check add constraint [fk_wc_messageresponse_wc_officalacconts] foreign key([officalaccountid])references [dbo].[wc_officalaccounts] ([id])on delete cascadegoalter 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]
公众号管理在70节
对应的枚举
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,
}
枚举其实对应就是我省掉的其余两张表
到这里,相信表的设计已经非常清晰
后台代码增删改查非常普通,主要关注点在前端,前端处理提交的消息中,必须包含规则,类型,来指定消息的最终表达
[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));
}
}
controller
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;
}
}
bll
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
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");
$("#p01").show();
$("#p02,#p03").hide();
$("#category").val(category.text);
}
}
});
$('#swimage0').switchbutton({
onchange: function(checked) { if (checked) {
$('#swvoice0').switchbutton("uncheck");
$('#swtext0').switchbutton("uncheck");
$("#p02").show();
$("#p01,#p03").hide();
$("#category").val(category.image);
$("#list0").datagrid("resize");
}
}
});
$('#swvoice0').switchbutton({
onchange: function(checked) { if (checked) {
$('#swimage0').switchbutton("uncheck");
$('#swtext0').switchbutton("uncheck");
$("#p03").show();
$("#p01,#p02").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");
$("#p11").show();
$("#p12,#p13").hide();
$("#category").val(category.text);
}
}
});
$('#swimage1').switchbutton({
onchange: function(checked) { if (checked) {
$('#swvoice1').switchbutton("uncheck");
$('#swtext1').switchbutton("uncheck");
$("#p12").show();
$("#p11,#p13").hide();
$("#category").val(category.image);
$("#list1").datagrid("resize");
}
}
});
$('#swvoice1').switchbutton({
onchange: function(checked) { if (checked) {
$('#swimage1').switchbutton("uncheck");
$('#swtext1').switchbutton("uncheck");
$("#p13").show();
$("#p11,#p12").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>
<p style="padding:10px;">
<p id="tt" class="easyui-tabs">
<p 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;">
<p class="color-green">当前操作公众号:<span id="currentofficalaccount">@viewbag.currentofficalacount</span></p>
</td>
</tr>
</table>
<p id="p01" class="displaynone">
<p class="mvctool bgb">
@html.toolbutton("btnsava01", "fa fa-plus", "提交保存", ref perm, "edit", false) </p>
<textarea id="text0" style="width: 300px;height: 330px; margin:20px;"></textarea>
</p>
<p id="p02" class="displaynone">
<p class="mvctool bgb">
@html.toolbutton("btncreate02", "fa fa-search", "添加回复", ref perm, "edit", false) </p>
<p id="modalwindow0" class="easyui-window" style="width:600px; height:550px;" data-options="modal:true,closed: true,minimizable:false,shadow:false">
<p class="mvctool bgb">
@html.toolbutton("btnsava02", "fa fa-search", "提交保存", ref perm, "edit", false) </p>
<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>
</p>
<p style="padding:10px;">
<table id="list0"></table>
</p>
</p>
<p id="p03" class="displaynone">
<p class="mvctool bgb">
@html.toolbutton("btnsava03", "fa fa-plus", "提交保存", ref perm, "edit", false) </p>
<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>
</p>
</p>
<p 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;">
<p class="color-green">当前操作公众号:<span id="currentofficalaccount">@viewbag.currentofficalacount</span></p>
</td>
</tr>
</table>
<p id="p11" class="displaynone">
<p class="mvctool bgb">
@html.toolbutton("btnsava11", "fa fa-plus", "提交保存", ref perm, "edit", false) </p>
<textarea id="text1" style="width: 300px;height: 330px; margin:20px;"></textarea>
</p>
<p id="p12" class="displaynone">
<p 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) </p>
<p id="modalwindow1" class="easyui-window" style="width:600px; height:550px;" data-options="modal:true,closed: true,minimizable:false,shadow:false">
<p class="mvctool bgb">
@html.toolbutton("btnsava12", "fa fa-search", "提交保存", ref perm, "edit", false)
</p>
<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>
</p>
<p style="padding:10px;">
<table id="list1"></table>
</p>
</p>
<p id="p13" class="displaynone">
<p class="mvctool bgb">
@html.toolbutton("btnsava13", "fa fa-plus", "提交保存", ref perm, "edit", false) </p>
<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>
</p>
</p>
<p title="文本回复" style="padding:10px">
<p 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) <p class="rightp color-green">
当前操作公众号: <span id="currentofficalaccount">@viewbag.currentofficalacount</span>
</p>
</p>
<p id="modalwindow2"
class="easyui-window"
style="width:600px; height:500px;" data-options="modal:true,closed: true,minimizable:false,shadow:false">
<p class="mvctool bgb">
@html.toolbutton("btnsava2", "fa fa-search", "提交保存", ref perm, "edit", false) <p class="rightp color-green">
当前操作公众号: <span id="currentofficalaccount">@viewbag.currentofficalacount</span>
</p>
</p>
<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>
</p>
<table id="list2"></table>
</p>
<p title="图片回复" style="padding:10px">
<p 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) <p class="rightp color-green">
当前操作公众号: <span id="currentofficalaccount">@viewbag.currentofficalacount</span>
</p>
</p>
<p id="modalwindow3" class="easyui-window" style="width:600px; height:550px;" data-options="modal:true,closed: true,minimizable:false,shadow:false">
<p class="mvctool bgb">
@html.toolbutton("btnsava3", "fa fa-search", "提交保存", ref perm, "edit", false) <p class="rightp color-green">
当前操作公众号: <span id="currentofficalaccount">@viewbag.currentofficalacount</span>
</p>
</p>
<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>
</p>
<table><tr><td><table id="list31"></table></td><td> </td><td><table id="list3"></table></td></tr></table>
</p>
<p title="语音回复" style="padding:10px">
<p 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) <p class="rightp color-green">
当前操作公众号: <span id="currentofficalaccount">@viewbag.currentofficalacount</span>
</p>
</p>
<p id="modalwindow4"
class="easyui-window"
style="width:600px; height:500px;" data-options="modal:true,closed: true,minimizable:false,shadow:false">
<p class="mvctool bgb">
@html.toolbutton("btnsava4", "fa fa-search", "提交保存", ref perm, "edit", false) <p class="rightp color-green">
当前操作公众号: <span id="currentofficalaccount">@viewbag.currentofficalacount</span>
</p>
</p>
<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>
</p>
<table id="list4"></table>
</p>
@*<p title="视频回复"
style="padding:10px">
</p>*@
@*<p title="链接回复"
styie="padding:10px">
</p>
<p title="lbs位置回复"
style="padding:10px">
</p>*@ </p>
</p>
view code
利用前端的思维导图,来快速理解前端代码,和应用于实际
总结消息的管理是非常有技巧的一件事
1.消息在没有任务回复的情况 下,我们应该启用默认回复,要不用户会得不到回应,丢失体验
2.关键字的设计一般是一环扣一环,是有引导作用的
比如:关键字:(我要) 回复: 按1加入获得礼品一份,按2直接获得50元
关键字:(1) 回复: 按3获得铁观音茶一份,按4获得普洱茶
关键字:(3或4) 回复:请回复您的地址和电话及收件人
这样我们将获得系统与用户之间的完整对话,当然我们也要对用户最后的信息进行处理
以上就是asp.net mvc5+ef6+easyui 后台管理系统微信公众平台开发的详细内容。