原文: DDD实战进阶第一波(十一):开发一般业务的大健康行业直销系统(实现经销商代注册用例与登录令牌分发) 前两篇文章主要实现了经销商代注册的仓储与领域逻辑、经销商登录的
前两篇文章主要实现了经销商代注册的仓储与领域逻辑、经销商登录的仓储与相关逻辑,这篇文章主要讲述经销商代注册的用例与经销商登录的查询功能。
一.经销商代注册用例
在经销商代注册用例中,我们需要传递经销商的基本注册信息,这个信息是做成了DTO对象。
1.经销商注册的DTO对象:
public class AddDealerDTO { public string Name { get; set; } public string Tel { get; set; } public decimal EleMoney { get; set; } public Guid? Parentid { get; set; } public List<string> ContactNames { get; set; } public List<string> ContactTels { get; set; } public List<string> ContactProvinces { get; set; } public List<string> ContactCities { get; set; } public List<string> ContactZeors { get; set; } public List<string> ContactStreets { get; set; } public List<int> IsDefaultContact { get; set; } }
在上述DTO对象中,Name和Tel属性是子经销商的名字和电话号码;EleMoney代表子经销商注册时的电子币,从领域逻辑中可以看到,电子币会从父经销商扣除并附加到子经销
商,并且根据EleMoney确定了子经销商的级别;Parentid是当前登录的父经销商的Id;其他剩余属性是子经销商的联系信息。
2.经销商注册用例:
public class AddDealerUseCase:BaseAppSrv { private readonly IRepository irepository; private readonly IDealerRepository idealerrepository; private readonly ILoginRepository iloginrepository; public AddDealerUseCase(IRepository irepository, IDealerRepository idealerrepository, ILoginRepository iloginrepository) { this.irepository = irepository; this.idealerrepository = idealerrepository; this.iloginrepository = iloginrepository; } public ResultEntity<bool> AddDealer(AddDealerDTO adddealerdto) { var dealerid = Guid.NewGuid(); var dealercontacts = new List<Contact>(); for(int i = 0; i < adddealerdto.ContactNames.Count; i++) { var dealercontact = new Contact().CreateContact(dealerid, adddealerdto.ContactNames[i], adddealerdto.ContactTels[i], adddealerdto.ContactProvinces[i], adddealerdto.ContactCities[i], adddealerdto.ContactZeors[i], adddealerdto.ContactStreets[i], adddealerdto.IsDefaultContact[i]); dealercontacts.Add(dealercontact); } var dealer = new Dealers(idealerrepository).RegisterDealer(dealerid, adddealerdto.Name, adddealerdto.Tel, adddealerdto.EleMoney, dealercontacts, adddealerdto.Parentid); var login = new Login().CreateLogin(dealer.Tel, dealerid); try { using (irepository) { idealerrepository.CreateDealer(dealer); if (adddealerdto.Parentid != null) { idealerrepository.SubParentEleMoney(Guid.Parse(adddealerdto.Parentid.ToString()), adddealerdto.EleMoney); } idealerrepository.AddParentSubCount(adddealerdto.Parentid); iloginrepository.CreateLogin(login); irepository.Commit(); } return GetResultEntity(true); } catch (OverTowSubException error) { throw error; } catch(Exception error) { throw error; } } }
从上面代码可以看到,调用了注册经销商的逻辑,并且调用了相关仓储进行父经销商电子币扣除、将父经销商子个数加1、并持久化子经销商信息,如果父经销商的子
经销商个数超过2个,则抛出OverTowSubException异常。
这里不再讲述经销商注册的WebApi实现,可以参考前面的文章实现相应的WebApi。
二.经销商登录功能
经销商登录时,只需要传递电话号码和密码就可以了,所以先定义相关的DTO对象。
1.经销商登录的DTO对象
public class UserLoginDTO { public string Telphone { get; set; } public string Password { get; set; } }
2.经销商登录查询
经销商登录这个功能不是一个用例,应该叫查询,调用前面文章实现的查询逻辑即可实现。
public class UserLoginQuery:BaseAppSrv { private readonly IRepository irepository; private readonly ILoginRepository iloginrepository; public UserLoginQuery(IRepository irepository, ILoginRepository iloginrepository) { this.iloginrepository = iloginrepository; this.irepository = irepository; } public Guid Login(UserLoginDTO userlogindto) { try { using (irepository) { return iloginrepository.UserLogin(userlogindto.Telphone, userlogindto.Password); } } catch(Exception error) { throw error; } } }
3.经销商登录的WebApi
在前一篇文章中,我们实现了登录成功时令牌生成的逻辑,所以在WebApi中,如果经销商登录成功,我们将返回经销商的Id、电话号码与Token信息,这些
信息存储到一个DTO对象中。
public class UserLoginResultDTO { public string Tel { get; set; } public Guid DealerId { get; set; } public string Token { get; set; } }
然后实现WebApi接口
[AllowAnonymous] [HttpPost] [Route("UserLogin")] public ResultEntity<UserLoginResultDTO> UserLogin([FromBody] UserLoginDTO userlogindto) { var result = new ResultEntity<UserLoginResultDTO>(); var idealercontext = servicelocator.GetService<IDealerContext>(); var irepository = servicelocator.GetService<IRepository>(new ParameterOverrides { { "context", idealercontext } }); var iloginrepository = servicelocator.GetService<ILoginRepository>(new ParameterOverrides { { "context", idealercontext } }); UserLoginQuery userloginquery = new UserLoginQuery(irepository, iloginrepository); try { var dealerid = userloginquery.Login(userlogindto); if (dealerid != Guid.Empty) { var token = new JwtTokenBuilder() .AddSecurityKey(JwtSecurityKey.Create("msshcjsecretmsshcjsecret")) .AddSubject(userlogindto.Telphone) .AddIssuer("DDD1ZXSystem") .AddAudience("DDD1ZXSystem") .AddClaim("role", "NormalUser") .AddExpiry(600) .Build(); var userloginresultdto = new UserLoginResultDTO(); userloginresultdto.Tel = userlogindto.Telphone; userloginresultdto.DealerId = dealerid; userloginresultdto.Token = token.Value; result.IsSuccess = true; result.Data = userloginresultdto; result.Msg = "登录成功!"; } else { result.ErrorCode = 300; result.Msg = "登录失败!"; } } catch (Exception error) { result.ErrorCode = 200; result.Msg = error.Message; } return result; }
上述代码中JwtTokenBuilder的相关方法说明请参考前一篇文章。
QQ讨论群:309287205
DDD实战进阶视频请关注微信公众号: