最近在做一个多租户的云SAAS软件自助服务平台,途中遇到很多问题,我会将一些心得、体会逐渐分享出来,和大家一起探讨。这是本系列的第一篇文章。
大家知道,要做一个全自助服务的SAAS云平台是比较复杂的,稍微有些漏洞,就会被不法分子钻漏洞,牵涉到一些金钱上的纠纷。因此,一开始的设计就比较重要了。说到云自助服务平台,可能和网上购物、在线商城有些类似,但里面提供的是相关服务,还是有些区别的,我在这里先讲几个概念:
产品:产品即服务,即是提供给用户的服务。产品有单价,有些产品是基础产品,用户购买正式产品必须免费提供的,产品可以提供给用户进行试用。
模块:产品包括很多模块,有些模块是必然会提供给用户的,比如 操作人员管理、操作日志 等,还有些模块是可选的,用户针对自己的情况进行购买,类似增值服务,比如移动端、企业主页等。另外还有些一次性的服务,比如系统数据对接,硬件设备购买等;
服务:用户所能享受到的服务,有一定的使用期限;
订单:用户根据所拥有的 服务 所下的订单(而不是产品哦,为什么?);
购物车:在用户订单生成前先把产品放在购物车里,购物车有很多类别,有的购物车是对目前服务进行的延期,有些是把试用的产品转为正式,有些是对现有服务模块的增删,牵涉到追加购买等。购物车操作频繁、需要做非常多的校验,要和已经购买的服务做无缝的对接,这也是云SAAS产品和普通电商很大不同的地方。到了订单阶段,就相对比较简单了,生成订单后将购物车清空、可以生成多张订单,支付的时候再做一遍校验。
总体的概念流程是 服务->产品->购物车->订单->服务
上一张购物车验证规则的流程图
一些类(还没有全部完成):
对实体类的操作大都采用工厂方式:
购物车类代码:
1 public class UserCart 2 { 3 public string UserId { get; set; } 4 /// <summary> 5 /// 设置域名 6 /// </summary> 7 public string ServiceIndentify { get; set; } 8 public OrderType OrderType { get; set; } 9 public IList<UserCartProduct> UserCartProducts { get; set; } 10 public float TotalPrice 11 { 12 get 13 { 14 if (OrderType == OrderType.Experience) 15 { 16 return 0; 17 } 18 else 19 { 20 return UserCartProducts.Sum(p => p.Price); 21 } 22 } 23 } 24 public virtual IList<UserCartProduct> UserCartProduct { get; set; } 25 } 26 27 public class UserCartProduct 28 { 29 public string ProductId { get; set; } 30 public int ProductBasePrice { get; set; } 31 public Period Period { get; set; } 32 public DateTime StartDate { get; set; } 33 public DateTime EndDate { get; set; } 34 public IList<string> UserCartProductBasicModules { get; set; } 35 public IList<UserCartAddtionalModule> UserCartProductAddtionalModules { get; set; } 36 public IList<UserCartAddtionalService> UserCartAddtionalServices { get; set; } 37 public IList<UserCartOption> UserCartOptions { get; set; } 38 public float Price 39 { 40 get 41 { 42 return ProductBasePrice 43 + UserCartProductAddtionalModules.Sum(m => m.UintPrice.GetPriceByPeriod(Period)) 44 + UserCartAddtionalServices.Sum(m => m.UintPrice.GetPriceByPeriod(new Period(PeriodType.Times, m.Quantity))) 45 + UserCartOptions.Sum(m => m.UintPrice.GetPriceByPeriod(Period)); 46 } 47 } 48 public virtual UserCart UserCart { get; set; } 49 } 50 51 public class ModuleBase 52 { 53 public string ModuleId { get; set; } 54 55 public PeriodPrice UintPrice { get; set; } 56 57 } 58 59 public class UserCartAddtionalModule: ModuleBase 60 { 61 } 62 63 public class UserCartAddtionalService : ModuleBase 64 { 65 public int Quantity { get; set; } 66 } 67 68 public class UserCartOption: ModuleBase 69 { 70 public string CheckId { get; set; } 71 public string OriginCheckedId { get; set; } 72 public PeriodPrice OriginPeriodPrice { get; set; } 73 }