前言
回顾上一节,我们熟悉的了解了消息的请求和响应,这一节我们来建立数据库的表,表的设计蛮复杂
你也可以按自己所分析的情形结构来建表
必须非常熟悉表的结果才能运用这张表,这表表的情形涵盖比较多
思维导图
我这个人比较喜欢用思维导图来分析和表达一些模型:
表结构
根据思维导图,我们可以建立的表可以是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) 回复:请回复您的地址和电话及收件人
这样我们将获得系统与用户之间的完整对话,当然我们也要对用户最后的信息进行处理
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。