概述
关于这个框架的背景,在前面我已经交代过了。不清楚的可以查看这个链接
1、极简实用的Asp.NetCore模块化框架决定免费开源了
2、极简实用的Asp.NetCore模块化框架新增CMS模块
算下来确实好长时间没更新博客了,在这段时间内一直在出差,闲暇时间一直在想dotnetcore框架本身就是模块化的,为什么还要在这个上层应用上面继续进行模块化封装,意义何在?是为了更好地划分业务还是轮子重复利用?
细细想来,这个框架不应该再继续模块化下去,主要有以下几点理由支持:
1、本身于我现有地业务而言,没必要模块化,我只是做个大而全地系统(权限管理,内容管理,商城,微信管理等)。
2、如果要做模块化,本身就要牺牲掉一些性能,这是我反反复复斟酌以后不能接受的,主要是牺牲性能有点多!
3、dotnetcore本身就更友好模块化,没必要在这个上层应用上面再包裹一层,没有任何意义,我下载了dotnetcore源码后,觉得它的设计理念特别棒,于是“dotnetcore”本身就是最好的模块化(组件化)框架,可以把很多时间和精力投身于源码上面研究,没有必要在纠结于模块化这个概念,在上层应用折腾来折腾去,对于技术的成长微乎其微。
4、以前划分为模块化,是想朝微服务的方向发展,到时尽量改动小一点。现在想想我就一个后台管理,没必要想那么多。
基于以上几点,我于是把框架进行了更改,对于原来的模块化框架也进行了分支保留(一定意义上来说也不全是模块化)。
新增业务功能
新增加一个商城模块,主要包含商品管理(支持多个sku),商品分类,小程序用户,用户收获地址、订单各种状态的列表。
关于添加和修改商品的部分后端代码:
public async TaskAddAsync(GoodsInput input) { try { Db.BeginTran(); // 保存商品 var goods = _mapper.Map (input); var goodsId = await Db.Insertable (goods).ExecuteReturnIdentityAsync(); // 保存规格 await DealwithGoodsSpec(goodsId, input); Db.CommitTran(); } catch (Exception e) { Db.RollbackTran(); return new ApiResult(e.Message); } return new ApiResult(); } /// /// 公共的商品规格信息处理 /// /// /// /// private async Task DealwithGoodsSpec(int goodsId, GoodsInput input) { // 保存规格 if (input.SpecType == SpecTypeEnum.Single.GetValue<int>()) { var specSingle = JsonConvert.DeserializeObject (input.SpecSingle); input.GoodsSpecInput = specSingle; var goodsSpec = input.BuildGoodsSpec(goodsId); if (null == goodsSpec) { throw new FriendlyException("商品规格实体数据不能为空!"); } await Db.Insertable(goodsSpec).ExecuteReturnIdentityAsync(); } else { var goodsSpecs = input.BuildGoodsSpecs(goodsId); if (null == goodsSpecs || goodsSpecs.Count == 0) { throw new FriendlyException("商品规格实体数据集合不能为空!"); } await Db.Insertable(goodsSpecs).ExecuteReturnIdentityAsync(); var goodsSpecRels = input.BuildGoodsSpecRels(goodsId); if (goodsSpecRels.Count == 0 || goodsSpecRels == null) { throw new FriendlyException("商品规格实体关系集合数据不能为空!"); } //根据规格值反推规格组id var specValues = await Db.Queryable ().Where(d => d.Status).ToListAsync(); foreach (var item in goodsSpecRels) { var specId = specValues.Where(d => d.Status && d.Id == item.SpecValueId).Select(d => d.SpecId); item.SpecId = specId.FirstOrDefault(); } await Db.Insertable(goodsSpecRels).ExecuteReturnIdentityAsync(); } } public async Task ModifyAsync(GoodsModifyInput input) { var goods = await GetModelAsync(d => d.Id == input.Id); if (goods == null) throw new FriendlyException($"此商品{input.Id}没有查找对应的商品信息"); try { Db.BeginTran(); // 更新商品 var model = _mapper.Map (input); var goodsId = await Db.Updateable(model).IgnoreColumns(d => new { d.CreateTime }).ExecuteCommandAsync(); // 更新规格 await Db.Deleteable ().Where(d => d.GoodsId == input.Id).ExecuteCommandAsync(); await Db.Deleteable ().Where(d => d.GoodsId == input.Id).ExecuteCommandAsync(); // 保存规格 await DealwithGoodsSpec(input.Id, input); Db.CommitTran(); } catch (Exception e) { Db.RollbackTran(); return new ApiResult(e.Message); } return new ApiResult(); }
前端添加商品部分代码:
@{ ViewData["Title"] = "Modify"; Layout = "~/Views/Shared/_Layout.cshtml"; } @section css{ }@section js{ @await Html.PartialAsync("~/Views/Shared/Templates/tpl_spec_many.cshtml") }
这里只贴部分代码吧,更多的细节可以直接去看源码。另外关于商城的设计其实写个系列也不过分,下次抽时间具体写篇文章介绍下商品的多规格怎么设计好一点。
源码地址:https://gitee.com/shenniu_code_group/shen-nius.-modularity
喜欢交流的人进微信群