From 01197c5fbd606343dedabbba72baa55a00df3b77 Mon Sep 17 00:00:00 2001 From: "DESKTOP-G961P6V\\Zhh" <839860190@qq.com> Date: Mon, 18 Mar 2024 02:44:25 +0800 Subject: [PATCH] CardRegister UnitOfWork --- .../CardRegisters/CreateCardBillDto.cs | 26 ++++ .../CardRegisters/CardRegisterAppService.cs | 22 ++- .../Enums/CardBillFlag.cs | 20 +++ src/Shentun.Peis.Domain/CardBills/CardBill.cs | 1 + .../CardRegisters/CardRegisterManager.cs | 63 ++++++++ src/Shentun.Peis.Domain/Sexs/Sex.cs | 2 +- .../EntityFrameworkCore/PeisDbContext.cs | 13 +- .../IncludeDetails/IncludeDetailsExtr.cs | 54 +++++++ .../CardRegisterManagerTest.cs | 135 ++++++++++++++++++ .../GuideTypeManagerTest.cs | 2 +- 10 files changed, 333 insertions(+), 5 deletions(-) create mode 100644 src/Shentun.Peis.Application.Contracts/CardRegisters/CreateCardBillDto.cs create mode 100644 src/Shentun.Peis.Domain.Shared/Enums/CardBillFlag.cs create mode 100644 src/Shentun.Peis.EntityFrameworkCore/IncludeDetails/IncludeDetailsExtr.cs create mode 100644 test/Shentun.Peis.Domain.Tests/CardRegisterManagerTest.cs diff --git a/src/Shentun.Peis.Application.Contracts/CardRegisters/CreateCardBillDto.cs b/src/Shentun.Peis.Application.Contracts/CardRegisters/CreateCardBillDto.cs new file mode 100644 index 00000000..691d85da --- /dev/null +++ b/src/Shentun.Peis.Application.Contracts/CardRegisters/CreateCardBillDto.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Shentun.Peis.CardRegisters +{ + public class CreateCardBillDto + { + /// + /// 卡登记编号 + /// + public Guid CardRegisterId { get; set; } + /// + /// 支付方式 + /// + public string PayModeId { get; set; } + /// + /// 记账金额 + /// + public decimal BillMoney { get; set; } + /// + /// 记账标志 0、扣费 1、退费 2、充值 + /// + public char BillFlag { get; set; } + } +} diff --git a/src/Shentun.Peis.Application/CardRegisters/CardRegisterAppService.cs b/src/Shentun.Peis.Application/CardRegisters/CardRegisterAppService.cs index 5a8bd218..e254598a 100644 --- a/src/Shentun.Peis.Application/CardRegisters/CardRegisterAppService.cs +++ b/src/Shentun.Peis.Application/CardRegisters/CardRegisterAppService.cs @@ -229,8 +229,9 @@ namespace Shentun.Peis.CardRegisters await _cardRegisterRepository.UpdateAsync(entity); } + /* /// - /// 会员卡充值 + /// 会员卡充值 delete by zhh 2024-03-17 /// /// [HttpPost("api/app/cardregister/cardregisterrecharge")] @@ -245,7 +246,7 @@ namespace Shentun.Peis.CardRegisters await _cardRegisterRepository.UpdateAsync(cardRegisterEnt); //增加充值记录 - var cardBill = new CardBill + var cardBill = new CardBill(GuidGenerator.Create()) { BillFlag = '2', BillMoney = input.RechargeAmount, @@ -266,6 +267,23 @@ namespace Shentun.Peis.CardRegisters throw new UserFriendlyException("参数有误"); } } + */ + /// + /// 会员卡充值 + /// + /// + [HttpPost("api/app/cardregister/addcardbill")] + public async Task AddCardBill(CreateCardBillDto createCardBillDto) + { + Check.NotNull(createCardBillDto ,"CreateCardBillDto"); + var cardRegister = await _cardRegisterRepository.GetAsync(createCardBillDto.CardRegisterId); + var cardBill = _manager.CreateCardBill(cardRegister, + createCardBillDto.PayModeId, createCardBillDto.BillFlag, createCardBillDto.BillMoney); + + await _cardRegisterRepository.UpdateAsync(cardRegister); + await _cardBillRepository.InsertAsync(cardBill); + + } } } diff --git a/src/Shentun.Peis.Domain.Shared/Enums/CardBillFlag.cs b/src/Shentun.Peis.Domain.Shared/Enums/CardBillFlag.cs new file mode 100644 index 00000000..faeb157c --- /dev/null +++ b/src/Shentun.Peis.Domain.Shared/Enums/CardBillFlag.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Text; + +namespace Shentun.Peis.Enums +{ + public static class CardBillFlag + { + + [Description("充值")] + public const char Charge = '0'; + + [Description("扣费")] + public const char Deduction = '1'; + + [Description("退费")] + public const char Refund = '2'; + } +} diff --git a/src/Shentun.Peis.Domain/CardBills/CardBill.cs b/src/Shentun.Peis.Domain/CardBills/CardBill.cs index 2a1ca402..40d385c5 100644 --- a/src/Shentun.Peis.Domain/CardBills/CardBill.cs +++ b/src/Shentun.Peis.Domain/CardBills/CardBill.cs @@ -63,5 +63,6 @@ namespace Shentun.Peis.Models //{ // return new object[] { CardBillId }; //} + public CardBill(Guid id):base(id) { } } } diff --git a/src/Shentun.Peis.Domain/CardRegisters/CardRegisterManager.cs b/src/Shentun.Peis.Domain/CardRegisters/CardRegisterManager.cs index 8d7a38d3..ffe25fd0 100644 --- a/src/Shentun.Peis.Domain/CardRegisters/CardRegisterManager.cs +++ b/src/Shentun.Peis.Domain/CardRegisters/CardRegisterManager.cs @@ -118,6 +118,69 @@ namespace Shentun.Peis.CardRegisters } } } + + public CardBill CreateCardBill(CardRegister entity, string payModeId ,char billFlag, decimal amount) + { + Check.NotNull(entity, nameof(entity)); + Check.NotNull(billFlag, "记账标志"); + + if (amount == 0 ) { + throw new ArgumentException("金额等于0"); + }; + if(billFlag == Shentun.Peis.Enums.CardBillFlag.Charge && amount < 0) + { + throw new ArgumentException("充值金额不能小于0"); + } + else if(billFlag != Shentun.Peis.Enums.CardBillFlag.Charge && amount > 0) + { + throw new ArgumentException("扣费或退费金额不能大于0"); + } + if ((entity.CardBalance + amount) < 0 ) + { + throw new ArgumentException($"扣费或退费金额不能小于余额{entity.CardBalance}"); + } + entity.CardBalance += amount; + var cardBill = new CardBill(GuidGenerator.Create()) + { + CardRegisterId = entity.Id, + PayModeId = payModeId, + BillFlag = billFlag, + BillMoney = amount, + }; + return cardBill; + } + + public void AddCardBill(CardRegister entity, string payModeId, char billFlag, decimal amount) + { + Check.NotNull(entity, nameof(entity)); + Check.NotNull(billFlag, "记账标志"); + + if (amount == 0) + { + throw new ArgumentException("金额等于0"); + }; + if (billFlag == Shentun.Peis.Enums.CardBillFlag.Charge && amount < 0) + { + throw new ArgumentException("充值金额不能小于0"); + } + else if (billFlag != Shentun.Peis.Enums.CardBillFlag.Charge && amount > 0) + { + throw new ArgumentException("扣费或退费金额不能大于0"); + } + if ((entity.CardBalance + amount) < 0) + { + throw new ArgumentException($"扣费或退费金额不能小于余额{entity.CardBalance}"); + } + entity.CardBalance += amount; + var cardBill = new CardBill(GuidGenerator.Create()) + { + CardRegisterId = entity.Id, + PayModeId = payModeId, + BillFlag = billFlag, + BillMoney = amount, + }; + entity.CardBills.Add(cardBill); + } public void Verify(CardRegister entity) { Check.NotNull(entity, nameof(entity)); diff --git a/src/Shentun.Peis.Domain/Sexs/Sex.cs b/src/Shentun.Peis.Domain/Sexs/Sex.cs index 3813c552..a8531f36 100644 --- a/src/Shentun.Peis.Domain/Sexs/Sex.cs +++ b/src/Shentun.Peis.Domain/Sexs/Sex.cs @@ -12,7 +12,7 @@ namespace Shentun.Peis.Models /// 性别设置 /// [Table("sex")] - public class Sex : AuditedEntity, IHasConcurrencyStamp, ICharId,IDisplayName + public class Sex : AuditedEntity, IHasConcurrencyStamp, ICharId,IDisplayName { [Key] [Column("id")] diff --git a/src/Shentun.Peis.EntityFrameworkCore/EntityFrameworkCore/PeisDbContext.cs b/src/Shentun.Peis.EntityFrameworkCore/EntityFrameworkCore/PeisDbContext.cs index 85aa4082..5edbe443 100644 --- a/src/Shentun.Peis.EntityFrameworkCore/EntityFrameworkCore/PeisDbContext.cs +++ b/src/Shentun.Peis.EntityFrameworkCore/EntityFrameworkCore/PeisDbContext.cs @@ -37,6 +37,16 @@ using Volo.Abp.TenantManagement.EntityFrameworkCore; namespace Shentun.Peis.EntityFrameworkCore; +/// +/// 用于建立EfCoreCardRegisterRepository,采用接口注入, +/// 它不是必须的,只是一个推荐的习惯,此处暂时用于测试是否可行 +/// +public interface IPeisDbContext: IEfCoreDbContext +{ + public DbSet CardBills { get; set; } + public DbSet CardRegisters { get; set; } +} + [ReplaceDbContext(typeof(IIdentityDbContext))] [ReplaceDbContext(typeof(IOpenIddictDbContext))] [ReplaceDbContext(typeof(IAuditLoggingDbContext))] @@ -55,7 +65,8 @@ public class PeisDbContext : IBackgroundJobsDbContext, ISettingManagementDbContext, IPermissionManagementDbContext, - ITenantManagementDbContext + ITenantManagementDbContext, + IPeisDbContext { /* Add DbSet properties for your Aggregate Roots / Entities here. */ diff --git a/src/Shentun.Peis.EntityFrameworkCore/IncludeDetails/IncludeDetailsExtr.cs b/src/Shentun.Peis.EntityFrameworkCore/IncludeDetails/IncludeDetailsExtr.cs new file mode 100644 index 00000000..3808dbf2 --- /dev/null +++ b/src/Shentun.Peis.EntityFrameworkCore/IncludeDetails/IncludeDetailsExtr.cs @@ -0,0 +1,54 @@ +using Microsoft.EntityFrameworkCore; +using Shentun.Peis.EntityFrameworkCore; +using Shentun.Peis.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Volo.Abp.Domain.Repositories; +using Volo.Abp.Domain.Repositories.EntityFrameworkCore; +using Volo.Abp.EntityFrameworkCore; +using Volo.Abp.Identity; +using Volo.Abp.Identity.EntityFrameworkCore; + +namespace Shentun.Peis.IncludeDetails +{ + internal static class IncludeDetailsExtr + { + public static async Task> IncludeDetails(this Task> queryable, + bool include = true) + { + if (!include) + { + return queryable.Result; + } + + return queryable.Result + .Include(x => x.CardBills); + } + } + + public interface ICardRegisterRepository : IBasicRepository, IBasicRepository, + IReadOnlyRepository, IRepository, IReadOnlyBasicRepository + { + } + + + public class EfCoreCardRegisterRepository + : EfCoreRepository, ICardRegisterRepository + { + public EfCoreCardRegisterRepository( + IDbContextProvider dbContextProvider) + : base(dbContextProvider) + { + } + + public async override Task> WithDetailsAsync() + { + var query = await GetQueryableAsync().IncludeDetails(); + return query; // Uses the extension method defined above + } + } + +} diff --git a/test/Shentun.Peis.Domain.Tests/CardRegisterManagerTest.cs b/test/Shentun.Peis.Domain.Tests/CardRegisterManagerTest.cs new file mode 100644 index 00000000..311ba1b4 --- /dev/null +++ b/test/Shentun.Peis.Domain.Tests/CardRegisterManagerTest.cs @@ -0,0 +1,135 @@ +using NSubstitute; +using NSubstitute.Exceptions; +using Shentun.Peis.CardRegisters; +using Shentun.Peis.Enums; +using Shentun.Peis.GuidTypes; +using Shentun.Peis.IncludeDetails; +using Shentun.Peis.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using TencentCloud.Cpdp.V20190820.Models; +using Volo.Abp.Domain.Repositories; +using Volo.Abp.Uow; +using Xunit; +using Xunit.Abstractions; + +namespace Shentun.Peis +{ + public class CardRegisterManagerTest : PeisDomainTestBase + { + private readonly IRepository _repository; + private readonly IRepository _cardBillRepository; + private readonly ICardRegisterRepository _cardRegisterRepository; + private readonly CardRegisterManager _manager; + private readonly ITestOutputHelper _output; + private readonly IUnitOfWorkManager _unitOfWorkManager; + public CardRegisterManagerTest(ITestOutputHelper output) + { + _output = output; + _repository = GetRequiredService>(); + _cardRegisterRepository = GetRequiredService(); + _cardBillRepository = GetRequiredService>(); + _manager = GetRequiredService(); + + _unitOfWorkManager = GetRequiredService(); + } + + [Fact] + [UnitOfWork] + public async void AddCardBillTest() + { + var id = new Guid("3a0d9464-e69e-67d5-c292-b2e11fb334b1"); + using (IUnitOfWork unitOfWork = _unitOfWorkManager.Begin()) + { + var cardRegister = await _cardRegisterRepository.GetAsync(id, includeDetails: true); + //var cardRegister = _cardRegisterRepository.WithDetails().Where(o => o.Id == id).FirstOrDefault(); + //var cardRegister = await _cardRegisterRepository.GetAsync(id, includeDetails: true); + //var cardRegister = await _cardRegisterRepository.Get(new Guid("3a0d9464-e69e-67d5-c292-b2e11fb334b1"), includeDetails: true); + //await _repository.EnsureCollectionLoadedAsync(cardRegister, x => x.CardBills); + _output.WriteLine(cardRegister.CardBalance.ToString()); + _output.WriteLine(cardRegister.CardBills.Count.ToString()); + + var cardBill = _manager.CreateCardBill(cardRegister, "01", CardBillFlag.Charge, Convert.ToDecimal(10)); + try + { + await _repository.UpdateAsync(cardRegister); + await _cardBillRepository.InsertAsync(cardBill); + await unitOfWork.CompleteAsync(); + } + catch (Exception ex) + { + await unitOfWork.RollbackAsync(); + } + + + + _output.WriteLine(cardRegister.CardBalance.ToString()); + } + + + } + + [Fact] + public async void AddCardBillNoUnitOfWorkTest() + { + var id = new Guid("3a0d9464-e69e-67d5-c292-b2e11fb334b1"); + + var cardRegister = await _cardRegisterRepository.GetAsync(id, includeDetails: true); + //var cardRegister = _cardRegisterRepository.WithDetails().Where(o => o.Id == id).FirstOrDefault(); + //var cardRegister = await _cardRegisterRepository.GetAsync(id, includeDetails: true); + //var cardRegister = await _cardRegisterRepository.Get(new Guid("3a0d9464-e69e-67d5-c292-b2e11fb334b1"), includeDetails: true); + //await _repository.EnsureCollectionLoadedAsync(cardRegister, x => x.CardBills); + _output.WriteLine(cardRegister.CardBalance.ToString()); + _output.WriteLine(cardRegister.CardBills.Count.ToString()); + + var cardBill = _manager.CreateCardBill(cardRegister, "01", CardBillFlag.Refund, Convert.ToDecimal(-1000)); + await _repository.UpdateAsync(cardRegister); + await _cardBillRepository.InsertAsync(cardBill); + + + + + } + /// + /// 要支持级联更新,必须使用工作单元UnitOfWork + /// + [Fact] + //[UnitOfWork] + public async void AddCardBillByGetIdTest() + { + var id = new Guid("3a0d9464-e69e-67d5-c292-b2e11fb334b1"); + + + + using (IUnitOfWork unitOfWork = _unitOfWorkManager.Begin()) + { + var cardRegister = await _cardRegisterRepository.GetAsync(id, includeDetails: true); + _output.WriteLine(cardRegister.CardBalance.ToString()); + _output.WriteLine(cardRegister.CardBills.Count.ToString()); + + _manager.AddCardBill(cardRegister, "01", CardBillFlag.Charge, Convert.ToDecimal(100)); + + try + { + await _repository.UpdateAsync(cardRegister); + await unitOfWork.CompleteAsync(); + } + catch (Exception ex) + { + await unitOfWork.RollbackAsync(); + } + + + + _output.WriteLine(cardRegister.CardBalance.ToString()); + } + + + + } + + } +} diff --git a/test/Shentun.Peis.Domain.Tests/GuideTypeManagerTest.cs b/test/Shentun.Peis.Domain.Tests/GuideTypeManagerTest.cs index c5419617..34de8e12 100644 --- a/test/Shentun.Peis.Domain.Tests/GuideTypeManagerTest.cs +++ b/test/Shentun.Peis.Domain.Tests/GuideTypeManagerTest.cs @@ -80,7 +80,7 @@ namespace Shentun.Peis { using (var uow = _unitOfWorkManager.Begin()) { - var entity = await _repository.GetAsync(new Guid("3a0d6c49-cecf-19d9-0f4b-0923a28a3889")); + var entity = await _repository.GetAsync(new Guid("3a0d9464-e69e-67d5-c292-b2e11fb334b1")); await _manager.CheckAndDeleteAsync(entity); }