你所在的位置:微信群>互联网推广>正文

微信公众平台开发技术-数据库设计

原创
发布时间: 2023-07-15 13:10:14 热度: 274 作者: 李斯特 来源: 微信加 本文共 20228 字 阅读需要 68 分钟
数据库设计为满足微商城的需要,需要将一些数据存储起来。下面介绍一些关键的数据表,主要有商品表、购物车表、用户表等。各数据表的字段如表11-1~表11-6所示。
数据库设计

为满足微商城的需要,需要将一些数据存储起来。下面介绍一些关键的数据表,主要有商品表、购物车表、用户表等。

各数据表的字段如表 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