微信公众平台开发技术-数据库设计
原创为满足微商城的需要,需要将一些数据存储起来。下面介绍一些关键的数据表,主要有商品表、购物车表、用户表等。
各数据表的字段如表 11-1~ 表 11-6 所示。
表 11-1 商品第一分类表说明
字段名 | 字段类型 | 字段描述 |
id | int | 主键,自增长 |
fClassName | varchar(50) | 分类名称 |
表 11-2 商品第二分类表说明
字段名 | 字段类型 | 字段描述 |
id | int | 主键,自增长 |
fRootID | Int | 第一分类 ID |
fClassName | varchar(50) | 第二分类名称 |
表 11-3 商品第三分类表说明

表 11-4 商品表说明

表 11-5 商品详情表说明

表 11-6 购物车表说明

微商城或微网站一般是一个完整的应用,在微信公众平台上通常以自定义菜单的形式来实现,这里的仿淘宝的微商城使用的是综合应用中的微商城二级菜单,具体如图 11-1 所示。

图 11-1 微商城菜单
微商城使用的菜单类型为 view,通过打开网站进行浏览,可以直接在微信公众平台上进行菜单发布。若使用第三方发布,需要将如下 JSON 数据发布到微信服务器。
1. { 2. 「menu」: { 3. 「button」: [ 4. { 5. 「sub_button」: [ 6. { 7. 「key」:「menu」, 8. 「type」:「pic_photo_or_album」, 9. 「name」:「拍照」 10. }, 11. { 12. 「url」:「https://www.wechatadd.com.html」, 13. 「type」:「view」, 14. 「name」:「微商城」 15. }, 16. { 17. 「url」:「https://www.wechatadd.com/」, 18. 「type」:「view」, 19. 「name」:「搜索」 20. } 21. ], 22. 「name」:「综合应用」 23. } 24. ] 25. }, 26. 「conditionalmenu」:null, 27. 「errcode」:0, 28. 「errmsg」:null, 29. 「P2PData」:null 30. }
微商城首页主要显示营销活动、打折信息,以及热销商品列表。微商城前端页面使用 JQuery、JUSTEP 等框架结构,后端使用 C#提供的 JSON 数据包,前端异步访问后台接口,获取到 JSON 数据后,前端框架解析数据,然后在页面上展示。首页是商城默认进入的页面,也就是一开始就要加载页面数据,先加载动态图片,图片从服务器传送到客户端缓存起来,再次打开时直接展示,提升用户体验;然后是商品信息,从后台获取后直接展示在页面,具体核心代码如下。
1. /* 2. * 写首页图片数据缓存的代码 1. 数据模型创建时事件 3. * 2. 判断有没有 localStorage,如果有,则显示 localStorage 中的内容,否则 显示静态内容 4. * 3. 从服务端获取最新数据和图片,获取之后,更新界面并写入 localStorage 5. */ 6. Model.prototype.modelModelConstruct = function(event) { 7. /* 8. * 1. 数据模型创建时事件 2. 加载静态图片或从缓存中加载图片 9. */ 10. var carousel = this.comp(「carousel1」); 11. 12. var fImgUrl = localStorage.getItem(「index_BannerImg_src」); 13. if (fImgUrl == undefined) { 14. $(carousel.domNode).find(「img」).eq(0).attr({ 15. 「src」 : 「./main/img/carouselBox61.jpg」, 16. 「pagename」 : 「./detail.w」 17. }); 18. } else { 19. var fUrl = localStorage.getItem(「index_BannerImg_url」); 20. $(carousel.domNode).find(「img」).eq(0).attr({ 21. 「src」 : fImgUrl, 22. 「pagename」 : fUrl 23. }); 24. } 25. }; 26. 27. Model.prototype.imgDataCustomRefresh = function(event) { 28. /* 29. * 1. 加载轮换图片数据 30. * 2. 根据 data 数据动态添加 carousel 组件中的 content 页面 31. * 3. 如果 img 已经创建了,则只修改属性 32. * 4. 将第一张图片信息存入 localStorage 33. */ 34. var url = require.toUrl(「./ashx/imgData.ashx」); 35. allData.loadDataFromURL(url, event.source, true); 36. var me = this; 37. var carousel = this.comp(「carousel1」); 38. event.source.each(function(obj) { 39. var fImgUrl = require.toUrl(obj.row.val(「fImgUrl」)); 40. var fUrl = require.toUrl(obj.row.val(「fUrl」)); 41. if (me.comp(『contentsImg』).getLength() > obj.index) { 42. $(carousel.domNode).find(「img」).eq(obj.index).attr({ 43. 「src」 : fImgUrl, 44. 「pagename」 : fUrl 45. }); 46. if (obj.index == 0) { 47. localStorage.setItem(「index_BannerImg_src」, fImgUrl); 48. localStorage.setItem(「index_BannerImg_url」, fUrl); 49. } 50. } else { 51. carousel.add(『<img src=「』 + fImgUrl + 『」 class=「tb-img1」 bind-click=「openPageClick」 pagename=「』 + fUrl + 『」/>』); 52. } 53. }); 54. }; 55. 56. Model.prototype.goodsDataCustomRefresh = function(event) { 57. /* 58. *加载商品数据 59. */ 60. var url = require.toUrl(「./ashx/goodsData.ashx」); 61. allData.loadDataFromURL(url, event.source, true); 62. };
首页展示效果如图 11-2 所示。

图 11-2 微商城首页展示效果
在分类页面中对商品进行了分类管理,方便用户按类别查找商品。商品分为三层类别,加载页面时先加载大类,再加载第二类,点击时加载第三类商品。
1. //获取一级分类信息 2. /* 3. 1. 默认显示当前一级菜单对应的二、三级数据 4. 2. 点击其他一级菜单,再加载它的二、三级数据 5. */ 6. Model.prototype.rootClassDataCustomRefresh = function(event){ 7. /* 8. 1. 加载一级分类数据 9. */ 10. var url = require.toUrl(「./ashx/rootClassData.ashx」); 11. allData.loadDataFromURL(url,event.source,true); 12. }; 13. //获取二级分类信息 14. Model.prototype.secondClassDataCustomRefresh = function(event){ 15. /* 16. 1. 加载二级分类数据 17. */ 18. var url = require.toUrl(「./ashx/secondClassData.ashx」); 19. allData.loadDataFromURL(url,event.source,true); 20. }; 21. //获取三级分类信息 22. Model.prototype.threeClassDataCustomRefresh = function(event){ 23. /* 24. 1. 加载三级分类数据 25. */ 26. var url = require.toUrl(「./ashx/threeClassData.ashx」); 27. allData.loadDataFromURL(url,event.source,true); 28. }; 29. 30. //商品点击事件 31. Model.prototype.listClick = function(event){ 32. /* 33. 1. 获取当前商品 ID 34. 2. 传入弹出窗口,弹出窗口中显示商品详细信息 35. 3. 在弹出窗口的接收事件中,从服务端过滤数据 36. */ 37. justep.Shell.showPage(「list」,{ 38. keyValue : this.comp(「threeClassData」).getValue(「fClassName」) 39. }); 40. };
分类展示效果如图 11-3 所示。

图 11-3 微商城分类展示效果
购物车原是在传统商城中消费者选中商品后暂时存放商品的小推车。这里也应用购物车的概念。消费者在页面上将选中的商品加入购物车,则购物车里就会增加相应的商品,用户挑选完毕可以进行统一付款。购物车的主要功能包括商品加减、商品结算等。
主要代码如下:
1. //获取商品列表 2. Model.prototype.goodsDataCustomRefresh = function(event){ 3. /* 4. 加载商品数据 5. */ 6. var url = require.toUrl(「./ashx/goodsData.ashx」); 7. allData.loadDataFromURL(url,event.source,true); 8. }; 9. //获取店铺信息 10. Model.prototype.shopDataCustomRefresh = function(event){ 11. /* 12. 加载店铺数据 13. */ 14. var url = require.toUrl(「./ashx/shopData.ashx」); 15. allData.loadDataFromURL(url,event.source,true); 16. }; 17. //全选 18. Model.prototype.allChooseChange = function(event){ 19. /* 20. 1. 「全选」复选框绑定变化事件 onChange() 21. 2. 选择「全选」复选框,获取其值 22. 3. 修改商品表中的 fChoose 字段为「全选」复选框的值 23. */ 24. var goodsData = this.comp(「goodsData」); 25. var choose=this.comp(「allChoose」).val(); 26. goodsData.each(function(obj){ 27. if(choose){ 28. goodsData.setValue(「fChoose」,「1」,obj.row); 29. } else { 30. goodsData.setValue(「fChoose」,「」,obj.row); 31. } 32. }); 33. }; 34. 35. //减数量 36. Model.prototype.reductionBtnClick = function(event){ 37. /* 38. 1. 减少数量按钮绑定点击事件 onClick() 39. 2. 点击按钮,当前记录的 fNumber 值减 1 40. 3. fNumber 为 1 时不再相减 41. */ 42. var row = event.bindingContext.$object; 43. var n=row.val(「fNumber」); 44. if(n>1){ 45. row.val(「fNumber」,n-1); 46. } 47. }; 48. 49. //加数量 50. Model.prototype.addBtnClick = function(event){ 51. /* 52. 1. 增加数量按钮绑定点击事件 onClick() 53. 2. 点击按钮,当前记录的 fNumber 值加 1 54. */ 55. var row = event.bindingContext.$object; 56. var n=row.val(「fNumber」); 57. row.val(「fNumber」,n+1); 58. }; 59. //删除 60. Model.prototype.delBtnClick = function(event){ 61. /* 62. 1.「删除」按钮点击事件 63. 2. 删除选中商品 64. 3. 如果商店里已经没有商品,则删除商店 65. */ 66. var goodsData = this.comp(「goodsData」); 67. var goodsRows = goodsData.find([「fChoose」],[「1」]); 68. goodsData.deleteData(goodsRows); 69. var shopData = this.comp(「shopData」); 70. var shopRows = new Array(); 71. shopData.each(function(obj){ 72. var n = goodsData.find([「fShopID」],[obj.row.val(「id」)]). length; 73. if(n == 0){ 74. shopRows.push(obj.row); 75. } 76. }); 77. shopData.deleteData(shopRows); 78. }; 79. Model.prototype.showBackBtn = function(isBack){ 80. /* 81. 根据参数修改 calculateData 82. */ 83. this.isBack = isBack; 84. var v = isBack ? 1 : 0; 85. this.comp(「calculateData」).setValue(「isBack」,v); 86. }; 87. //结算事件 88. Model.prototype.settlementClick = function(event){ 89. /* 90. 1.「结算」按钮点击事件 91. 2. 打开订单确认页面 92. 3. 点击「确认」按钮,选择支付方式 93. 4. 进入支付成功页面 94. */ 95. justep.Shell.showPage(「order」); 96. }; 97. Model.prototype.listClick = function(event){ 98. /* 99. 1. 获取当前商品 ID 100. 2.传入弹出窗口,弹出窗口中显示商品详细信息 101. 3.在弹出窗口的接收事件中,从服务端过滤数据 102. */ 103. var data=this.comp(「goodsData」); 104. justep.Shell.showPage(「detail」, { 105. goodsID : data.getValue(「id」), 106. shopID : data.getValue(「fShopID」) 107. }); 108. }
微商城购物车如图 11-4 所示。

图 11-4 微商城购物车
在我的商城中可对自己的信息进行管理,可以查看我的订单、我的收藏、优惠券、红包、剩余金额等,也可以切换用户,默认以微信号为登录号,如图 11-5 所示。

图 11-5 微商城我的商城
系统后台主要是为微商城的前台提供数据服务的,将后台数据以 JSON 数据的格式传送给前台,前台再进行相应的解析展示。此后台使用应用最广泛的三层系统架构,将整个业务应用划分为表现层(UI)、业务逻辑层(BLL)、数据访问层(DAL)。此处的表现层由前端 H5 页面来实现数据的展示,后台系统主要使用其中的数据展现功能,使用 HttpHandler 的 Web 组件 ashx 将从数据库获取到的数据转换成 JSON 格式,或者以 JSON 数据写入后台数据库。
这里首先来看一下如何实现数据访问层。以首页中的商品信息为例,主要实现商品的查询、修改、删除等功能,其中,DBAccessManager 对数据库访问进行了集成,执行 ExecuteScalar 方法,在数据库中执行 SQL 语句,再将返回的数据集通过 JSONhelper 转换成 JSON 串。具体 DAL 的代码如下:
1. namespace AutoLinkID.Dal 2. { 3. public class GoodsDataDal 4. { 5. public static GoodsDataDal Instance 6. { 7. get { return SingletonProvider<GoodsDataDal>.Instance; } 8. } 9. 10. public string GetJson(int pageindex, int pagesize, string filterJson, string sort = 「keyid」, 11. string order = 「asc」) 12. { 13. StringBuilder strSql = new StringBuilder(); 14. if (sort == null) 15. { 16. sort = 「keyid」; 17. } 18. string WhereString = FilterTranslator.ToSql(filterJson); 19. 20. strSql.Append(string.Format(「select top {0} * from goodsData where KeyId not in 」,pagesize)); 21. strSql.Append(string.Format(「(select top {0} KeyId from goodsData where {1} order by {2}) 」, (pageindex - 1) * pagesize, WhereString, sort)); 22. strSql.Append(string.Format(「and {0} order by {1}」, WhereString, sort)); 23. 24. using (var ds = DBAccessManager.Application.Fill(DBAccess Manager.Application.CreateCommand(System.Data.CommandType.Text, strSql. ToString()))) 25. { 26. StringBuilder s = new StringBuilder(); 27. s.Append(「select count(*) from goodsData 」); 28. s.Append(string.Format(「 where {0} 」, WhereString)); 29. int recordcount = (int)DBAccessManager.Application.Execute Scalar(DBAccessManager.Application.CreateCommand(System.Data. CommandType.Text, s.ToString()));//datagrid 的统计数据,即共显示多少条 30. DataTable dt = ds.Tables[0]; 31. return JSONhelper.FormatJSONForEasyuiDataGrid(recordcount, dt); 32. } 33. } 34. 35. public int Insert(GoodsDataModel model) 36. { 37. StringBuilder strSql=new StringBuilder(); 38. strSql.Append(「insert into goodsData (」); 39. strSql.Append(「id,fShopID,fTitle,fImg,fPrice,fPostage,fRecord」); 40. strSql.Append(「) values(」); 41. strSql.Append(「『」+model.id+「』」+「,『」+model.fShopID+「』」+「, 『」+model.fTitle+「』」+「,『」+model.fImg+「』」+「,『」+model.fPrice+「』」+「, 『」+model.fPostage+「』」+「,『」+model.fRecord+「』」); 42. strSql.Append(「)」); 43. return DBAccessManager.Application.ExecuteNonQuery(DBAccess Manager.Application.CreateCommand(System.Data.CommandType.Text, strSql.ToString())); 44. } 45. 46. public int Update(GoodsDataModel model) 47. { 48. StringBuilder strSql = new StringBuilder(); 49. strSql.Append(「update goodsData set 」); 50. strSql.Append(string.Format(「id={0}」,model.id)); 51. strSql.Append(「,」+string.Format(「fShopID=『{0}』」,model.fShopID)); 52. strSql.Append(「,」+string.Format(「fTitle=『{0}』」,model.fTitle)); 53. strSql.Append(「,」+string.Format(「fImg=『{0}』」,model.fImg)); 54. strSql.Append(「,」+string.Format(「fPrice={0}」,model.fPrice)); 55. strSql.Append(「,」+string.Format(「fPostage=『{0}』」,model. fPostage)); 56. strSql.Append(「,」+string.Format(「fRecord={0}」,model.fRecord)); 57. strSql.Append(「 where KeyId=」 + model.KeyId); 58. return DBAccessManager.Application.ExecuteNonQuery(DBAccess Manager.Application.CreateCommand(System.Data.CommandType.Text, strSql.ToString())); 59. } 60. 61. public int Delete(int Keyid) 62. { 63. string strSql = string.Format(「delete from goodsData where KeyId=『{0}』」,Keyid); 64. return DBAccessManager.Application.ExecuteNonQuery(DBAccess Manager.Application.CreateCommand(System.Data.CommandType.Text, strSql.ToString())); 65. } 66. 67. public int BatchDelete(string idstr) 68. { 69. string strSql = string.Format(「delete from goodsData where KeyId in ({0})」, idstr); 70. return DBAccessManager.Application.ExecuteNonQuery(DBAccess Manager.Application.CreateCommand(System.Data.CommandType.Text, strSql.ToString())); 71. } 72. } 73. }
在这个过程中需要用到 goodsData 实体对象,这个实体模型的定义如下:
1. namespace AutoLinkID.Model 2. { 3. [TableName("goodsData")] 4. [Description("")] 5. public class GoodsDataModel 6. { 7. /// <summary> 8. /// id 9. /// </summary> 10. [Description("id")] 11. public int id { get; set; } 12. 13. /// <summary> 14. /// fShopID 15. /// </summary> 16. [Description("fShopID")] 17. public string fShopID { get; set; } 18. 19. /// <summary> 20. /// fTitle 21. /// </summary> 22. [Description("fTitle")] 23. public string fTitle { get; set; } 24. 25. /// <summary> 26. /// fImg 27. /// </summary> 28. [Description("fImg")] 29. public string fImg { get; set; } 30. 31. /// <summary> 32. /// fPrice 33. /// </summary> 34. [Description("fPrice")] 35. public float fPrice { get; set; } 36. 37. /// <summary> 38. /// fPostage 39. /// </summary> 40. [Description("fPostage")] 41. public string fPostage { get; set; } 42. 43. /// <summary> 44. /// fRecord 45. /// </summary> 46. [Description("fRecord")] 47. public int fRecord { get; set; } 48. 49. 50. public override string ToString() 51. { 52. return JSONhelper.ToJson(this); 53. } 54. } 55. }
业务逻辑层(BLL)通过调用数据访问层和视图实体层来处理业务流程,完成系统业务调用。具体代码如下:
1. namespace AutoLinkID.Bll 2. { 3. public class GoodsDataBll 4. { 5. public static GoodsDataBll Instance 6. { 7. get { return SingletonProvider<GoodsDataBll>.Instance; } 8. } 9. 10. public int Add(GoodsDataModel model) 11. { 12. return GoodsDataDal.Instance.Insert(model); 13. } 14. 15. public int Update(GoodsDataModel model) 16. { 17. return GoodsDataDal.Instance.Update(model); 18. } 19. 20. public int Delete(int keyid) 21. { 22. return GoodsDataDal.Instance.Delete(keyid); 23. } 24. 25. public int BatchDelete(string idstr) 26. { 27. return GoodsDataDal.Instance.BatchDelete(idstr); 28. } 29. 30. public string GetJson(int pageindex, int pagesize, string filterJson, string sort = "Keyid", string order = "asc") 31. { 32. return GoodsDataDal.Instance.GetJson(pageindex, pagesize, filterJson, sort, order); 33. } 34. } 35. }
最后在数据展示层或数据提取层使用 C#的 ashx 提供数据服务。也就是说,前端只需要调用一些 ashx,根据不同的 action 进行相应的数据操作,商品信息使用的是 GoodsDataHandler.ashx 方法。具体代码如下:
1. namespace AutoLinkID.Web.ashx 2. { 3. /// <summary> 4. /// dbHandler 的摘要说明 5. /// </summary> 6. public class GoodsDataHandler : IHttpHandler,IRequiresSessionState 7. { 8. public void ProcessRequest(HttpContext context) 9. { 10. context.Response.ContentType = 「text/plain」; 11. 12. //UserBll.Instance.CheckUserOnlingState(); 13. var action = context.Request[「action」]; 14. var json = HttpContext.Current.Request[「DataEntity」]; 15. var msg = new { Code = 201, Result = 「没有传递正确的参数」 }; 16. //获取 datagrid 的设置参数 17. var rpm = new RequestParamModel<GoodsDataModel>(context) { CurrentContext = context }; 18. var model = new GoodsDataModel(); 19. if (!string.IsNullOrEmpty(json)) 20. { 21. model = JSONhelper.ConvertToObject<GoodsDataModel>(json); 22. } 23. 24. //如果没有登录,则检查传递参数有无 Token 值 25. if (context.Request[「AccessToken」] != null) 26. { 27. string token = context.Request[「AccessToken」]; 28. string uid = context.Request[「uid」]; 29. if (UserBll.Instance.GetUserIdFromToken(token).ToString() != uid) 30. { 31. msg = new { Code = 201, Result = 「无效的验证信息」 }; 32. context.Response.Write(JSONhelper.ToJson(msg)); 33. return; 34. } 35. } 36. else 37. { 38. //TODO:暂时不做限制,后续完善的时候再加 39. } 40. 41. switch (HttpContext.Current.Request[「action」]) 42. { 43. case 「add」: 44. if(GoodsDataBll.Instance.Add(model) > 0) 45. msg = new { Code = 200, Result = 「添加成功!」 }; 46. else 47. msg = new { Code = 201, Result = 「添加失败!」 }; 48. context.Response.Write(JSONhelper.ToJson(msg)); 49. break; 50. case 「edit」: 51. if(GoodsDataBll.Instance.Update(model) > 0) 52. msg = new { Code = 200, Result = 「修改成功!」 }; 53. else 54. msg = new { Code = 201, Result = 「修改失败!」 }; 55. context.Response.Write(JSONhelper.ToJson(msg)); 56. break; 57. case 「delete」: 58. if(GoodsDataBll.Instance.Delete(PublicMethod.GetInt (context.Request[「KeyId」])) > 0) 59. msg = new { Code = 200, Result = 「删除成功!」 }; 60. else 61. msg = new { Code = 201, Result = 「删除失败!」 }; 62. context.Response.Write(JSONhelper.ToJson(msg)); 63. break; 64. case 「batchdelete」: 65. if(GoodsDataBll.Instance.BatchDelete(context.Request [「KeyId」]) > 0) 66. msg = new { Code = 200, Result = 「删除成功!」 }; 67. else 68. msg = new { Code = 201, Result = 「删除失败!」 }; 69. context.Response.Write(JSONhelper.ToJson(msg)); 70. break; 71. default: 72. msg = new { Code = 200, Result = GoodsDataBll. Instance.GetJson(rpm.Pageindex, rpm.Pagesize, rpm.Filter, rpm.Sort, rpm.Order)}; 73. context.Response.Write(JSONhelper.ToJson(msg)); 74. break; 75. } 76. } 77. 78. public bool IsReusable 79. { 80. get 81. { 82. return false; 83. } 84. } 85. } 86. }
版权保护: 本文由 李斯特 原创,转载请保留链接: https://www.wechatadd.com/artdet/9570
- 上一篇:微信公众平台开发技术-项目介绍
- 下一篇:初识微信公众平台,获取自定义菜单配置接口
阅读推荐
更多...- 亚马逊电商平台是干什么的?什么是亚马逊? 2022-07-29
- 杰·亚伯拉罕:为产品和服务「加码」 2023-03-24
- 在网络营销中文案写作发挥了什么作用? 2022-07-03
- 「抖商经验」起个好的昵称更重要 2023-02-12
- 巧妙回答有关竞争对手产品的问题——销售技巧 2023-03-04
- 电商软文的写作技巧,电商开展软文营销的步骤,建议收藏! 2023-02-16
- 一条有吸引力的信息赢得未来,提高销售技巧 2023-03-14
- 顾客说「没听过你这牌子」,如何让他对你的产品「路转粉」呢? 2023-05-22
- (淘宝seo排名优化的方法之)促销引流:快速引流让生意爆棚 2023-01-24
- 「抖商经验」直播的吸粉引流技巧 2023-02-12
- 广告营销是否需要公司一把手来抓? 2024-02-12
- 让业绩高速增长!知识储备,打硬仗关键靠「软实力」 2023-04-01
- 不必害羞,勇于向亲朋好友推荐产品,实现您的梦想和目标,获得成功和财富 2023-04-01
- 客户比你还懂销售套路,如何应对才能拿下订单呢?送你 4 条建议 2023-05-22
- 聊天中的「饥饿营销」「销售技巧」 2023-03-02
- 微信营销:企业与消费者互动的新机遇与挑战 2024-01-20
- .好运升级,成功就是搞定人,100%保证:这些技巧让您的销售业绩翻倍 2023-04-01
- 3大技巧,成就自明星的高手运营 2022-07-07