add: Order #3
| @ -0,0 +1,17 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
| using System.Threading.Tasks; | ||||
|  | ||||
| namespace KonSoft.Admin.Dtos | ||||
| { | ||||
|     public class AddressDto | ||||
|     { | ||||
|         public string ContactName { get; set; } | ||||
|         public string ContactPhone { get; set; } | ||||
|         public string DetailAddress { get; set; } | ||||
|         public string City { get; set; } | ||||
|         public string District { get; set; } | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,25 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.ComponentModel.DataAnnotations; | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
| using System.Threading.Tasks; | ||||
|  | ||||
| namespace KonSoft.Admin.Dtos | ||||
| { | ||||
|     public class CreateOrderDto | ||||
|     { | ||||
|         [Required] | ||||
|         public Guid CustomerId { get; set; } | ||||
|         [Required] | ||||
|         public Guid ServiceId { get; set; } | ||||
|         [Required] | ||||
|         public DateTime ServiceTime { get; set; } | ||||
|         [Required] | ||||
|         public decimal Amount { get; set; } | ||||
|         [Required] | ||||
|         public AddressDto Address { get; set; } | ||||
|  | ||||
|         public string Remark { get; set; } | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,25 @@ | ||||
| using KonSoft.Admin.Enums; | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
| using System.Threading.Tasks; | ||||
|  | ||||
| namespace KonSoft.Admin.Dtos | ||||
| { | ||||
|     public class OrderDto | ||||
|     { | ||||
|         public Guid Id { get; set; } | ||||
|         public string OrderSN { get; set; } | ||||
|         public Guid CustomerId { get; set; } | ||||
|         public Guid? WorkerId { get; set; } | ||||
|         public Guid ServiceId { get; set; } | ||||
|         public DateTime ServiceTime { get; set; } | ||||
|         public OrderStatus Status { get; set; } | ||||
|         public decimal Amount { get; set; } | ||||
|         public decimal PaidAmount { get; set; } | ||||
|         public string PaymentMethod { get; set; } | ||||
|         public AddressDto Address { get; set; } | ||||
|         public string Remark { get; set; } | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,12 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
| using System.Threading.Tasks; | ||||
|  | ||||
| namespace KonSoft.Admin.Dtos | ||||
| { | ||||
|     public class PayOrderDto | ||||
|     { | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,26 @@ | ||||
| using KonSoft.Admin.Dtos; | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
| using System.Threading.Tasks; | ||||
| using Volo.Abp.Application.Services; | ||||
|  | ||||
| namespace KonSoft.Admin.IApplicationServices | ||||
| { | ||||
|     public interface IOrderAppService : IApplicationService | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// 创建订单 | ||||
|         /// </summary> | ||||
|         /// <param name="input"></param> | ||||
|         /// <returns></returns> | ||||
|         Task<OrderDto> CreateAsync(CreateOrderDto input); | ||||
|         Task<OrderDto> PayAsync(Guid orderId, PayOrderDto input); | ||||
|         Task AssignAsync(Guid orderId, Guid workerId); | ||||
|         Task StartServiceAsync(Guid orderId); | ||||
|         Task CompleteServiceAsync(Guid orderId); | ||||
|         Task ConfirmAsync(Guid orderId); | ||||
|         Task CancelAsync(Guid orderId, string reason); | ||||
|     } | ||||
| } | ||||
| @ -1,4 +1,6 @@ | ||||
| using AutoMapper; | ||||
| using KonSoft.Admin.Dtos; | ||||
| using KonSoft.Admin.Entities; | ||||
|  | ||||
| namespace KonSoft.Admin; | ||||
|  | ||||
| @ -9,5 +11,9 @@ public class AdminApplicationAutoMapperProfile : Profile | ||||
|         /* You can configure your AutoMapper mapping configuration here. | ||||
|          * Alternatively, you can split your mapping configurations | ||||
|          * into multiple profile classes for a better organization. */ | ||||
|  | ||||
|         CreateMap<Order, OrderDto>(); | ||||
|         //CreateMap<CreateOrderDto, Order>(); | ||||
|         CreateMap<AddressDto, AddressInfo>(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -0,0 +1,115 @@ | ||||
| using KonSoft.Admin.Dtos; | ||||
| using KonSoft.Admin.Entities; | ||||
| using KonSoft.Admin.IApplicationServices; | ||||
| using KonSoft.Admin.Repositories; | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
| using System.Threading.Tasks; | ||||
| using Volo.Abp.Application.Services; | ||||
| using Volo.Abp.ObjectMapping; | ||||
|  | ||||
| namespace KonSoft.Admin.ApplicationServices | ||||
| { | ||||
|     public class OrderAppService : ApplicationService, IOrderAppService | ||||
|     { | ||||
|         private readonly IOrderRepository _orderRepository; | ||||
|  | ||||
|         public OrderAppService(IOrderRepository orderRepository) | ||||
|         { | ||||
|             _orderRepository = orderRepository; | ||||
|         } | ||||
|         /// <summary> | ||||
|         /// 分配师傅 | ||||
|         /// </summary> | ||||
|         /// <param name="orderId"></param> | ||||
|         /// <param name="workerId"></param> | ||||
|         /// <returns></returns> | ||||
|         /// <exception cref="NotImplementedException"></exception> | ||||
|         public async Task  AssignAsync(Guid orderId, Guid workerId) | ||||
|         { | ||||
|             var order = await _orderRepository.GetAsync(o => o.Id == orderId); | ||||
|             order.AssignWorker(workerId); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 取消订单 | ||||
|         /// </summary> | ||||
|         /// <param name="orderId"></param> | ||||
|         /// <param name="reason"></param> | ||||
|         /// <returns></returns> | ||||
|         /// <exception cref="NotImplementedException"></exception> | ||||
|         public async Task CancelAsync(Guid orderId, string reason) | ||||
|         { | ||||
|             var order = await _orderRepository.GetAsync(o => o.Id == orderId); | ||||
|             order.Cancel(reason); | ||||
|         } | ||||
|         /// <summary> | ||||
|         /// 完成订单 | ||||
|         /// </summary> | ||||
|         /// <param name="orderId"></param> | ||||
|         /// <returns></returns> | ||||
|         /// <exception cref="NotImplementedException"></exception> | ||||
|         public async Task CompleteServiceAsync(Guid orderId) | ||||
|         { | ||||
|             var order = await _orderRepository.GetAsync(o => o.Id == orderId); | ||||
|             order.CompleteService(); | ||||
|         } | ||||
|         /// <summary> | ||||
|         /// 确认订单 | ||||
|         /// </summary> | ||||
|         /// <param name="orderId"></param> | ||||
|         /// <returns></returns> | ||||
|         /// <exception cref="NotImplementedException"></exception> | ||||
|         public async Task ConfirmAsync(Guid orderId) | ||||
|         { | ||||
|             var order = await _orderRepository.GetAsync(o => o.Id == orderId); | ||||
|             order.ConfirmCompletion(); | ||||
|         } | ||||
|         /// <summary> | ||||
|         /// 创建订单 | ||||
|         /// </summary> | ||||
|         /// <param name="input"></param> | ||||
|         /// <returns></returns> | ||||
|         /// <exception cref="NotImplementedException"></exception> | ||||
|         public async Task<OrderDto> CreateAsync(CreateOrderDto input) | ||||
|         { | ||||
|             // 生成订单号 TODO | ||||
|             var orderSN = "SN001"; | ||||
|             var address = ObjectMapper.Map<AddressDto, AddressInfo>(input.Address); | ||||
|             var order = new Order(Guid.NewGuid(), orderSN, input.CustomerId, input.ServiceId, input.ServiceTime, input.Amount, address, input.Remark); | ||||
|  | ||||
|             await _orderRepository.InsertAsync(order); | ||||
|             return ObjectMapper.Map<Order, OrderDto>(order); | ||||
|         } | ||||
|         /// <summary> | ||||
|         /// 支付 | ||||
|         /// </summary> | ||||
|         /// <param name="orderId"></param> | ||||
|         /// <param name="input"></param> | ||||
|         /// <returns></returns> | ||||
|         /// <exception cref="NotImplementedException"></exception> | ||||
|         public Task<OrderDto> PayAsync(Guid orderId, PayOrderDto input) | ||||
|         { | ||||
|             throw new NotImplementedException(); | ||||
|         } | ||||
|         /// <summary> | ||||
|         /// 开始订单 | ||||
|         /// </summary> | ||||
|         /// <param name="orderId"></param> | ||||
|         /// <returns></returns> | ||||
|         /// <exception cref="NotImplementedException"></exception> | ||||
|         public async Task StartServiceAsync(Guid orderId) | ||||
|         { | ||||
|             var order = await _orderRepository.GetAsync(o => o.Id == orderId); | ||||
|             order.StartService(); | ||||
|         } | ||||
|  | ||||
|         public async Task<OrderDto> GetAsync(Guid id) | ||||
|         { | ||||
|             var order = await _orderRepository.GetAsync(o => o.Id == id); | ||||
|             return ObjectMapper.Map<Order, OrderDto>(order); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -6,8 +6,8 @@ | ||||
|     <RootNamespace>KonSoft.Admin</RootNamespace> | ||||
|   </PropertyGroup> | ||||
|   <ItemGroup> | ||||
|     <ProjectReference Include="..\KonSoft.Admin.Domain\KonSoft.Admin.Domain.csproj"/> | ||||
|     <ProjectReference Include="..\KonSoft.Admin.Application.Contracts\KonSoft.Admin.Application.Contracts.csproj"/> | ||||
|     <ProjectReference Include="..\KonSoft.Admin.Domain\KonSoft.Admin.Domain.csproj" /> | ||||
|     <ProjectReference Include="..\KonSoft.Admin.Application.Contracts\KonSoft.Admin.Application.Contracts.csproj" /> | ||||
|   </ItemGroup> | ||||
|   <ItemGroup> | ||||
|     <PackageReference Include="Volo.Abp.Account.Application" Version="8.3.4" /> | ||||
|  | ||||
| @ -0,0 +1,22 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
| using System.Threading.Tasks; | ||||
|  | ||||
| namespace KonSoft.Admin.Enums | ||||
| { | ||||
|     public enum OrderStatus | ||||
|     { | ||||
|         PendingPayment,      // 待支付 | ||||
|         PaidWaitingAssign,   // 已支付待派单 | ||||
|         AssignedWaitingService, // 已派单待服务 | ||||
|         InService,           // 服务中 | ||||
|         WaitingConfirm,      // 待用户确认 | ||||
|         Completed,           // 已完成 | ||||
|         Canceled,            // 已取消 | ||||
|         Refunding,           // 退款中 | ||||
|         Refunded             // 已退款 | ||||
|  | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,60 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
| using System.Threading.Tasks; | ||||
| using Volo.Abp.Domain.Entities; | ||||
| using Volo.Abp.Domain.Values; | ||||
|  | ||||
| namespace KonSoft.Admin.Entities | ||||
| { | ||||
|     /// <summary> | ||||
|     /// 地址 | ||||
|     /// </summary> | ||||
|     public class AddressInfo :  ValueObject | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// 联系人 | ||||
|         /// </summary> | ||||
|         public string ContactName { get; private set; } | ||||
|         /// <summary> | ||||
|         /// 手机号 | ||||
|         /// </summary> | ||||
|         public string ContactPhone { get; private set; } | ||||
|         /// <summary> | ||||
|         /// 详细地址 | ||||
|         /// </summary> | ||||
|         public string DetailAddress { get; private set; } | ||||
|         /// <summary> | ||||
|         /// 城市 | ||||
|         /// </summary> | ||||
|         public string City { get; private set; } | ||||
|         /// <summary> | ||||
|         /// 区域 | ||||
|         /// </summary> | ||||
|         public string District { get; private set; } | ||||
|  | ||||
|  | ||||
|         public AddressInfo() { } | ||||
|  | ||||
|         public AddressInfo(string contactName, string contactPhone, string detailAddress, string city, string district) | ||||
|         { | ||||
|             ContactName = contactName; | ||||
|             ContactPhone = contactPhone; | ||||
|             DetailAddress = detailAddress; | ||||
|             City = city; | ||||
|             District = district; | ||||
|         } | ||||
|  | ||||
|  | ||||
|         protected override IEnumerable<object> GetAtomicValues() | ||||
|         { | ||||
|             yield return ContactName; | ||||
|             yield return ContactPhone; | ||||
|             yield return DetailAddress; | ||||
|             yield return City; | ||||
|             yield return District; | ||||
|         } | ||||
|  | ||||
|     } | ||||
| } | ||||
							
								
								
									
										155
									
								
								modules/admin/src/KonSoft.Admin.Domain/Entities/Order.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										155
									
								
								modules/admin/src/KonSoft.Admin.Domain/Entities/Order.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,155 @@ | ||||
| using KonSoft.Admin.Enums; | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
| using System.Threading.Tasks; | ||||
| using Volo.Abp.Domain.Entities.Auditing; | ||||
| using Volo.Abp.Identity; | ||||
|  | ||||
| namespace KonSoft.Admin.Entities | ||||
| { | ||||
|     public class Order : FullAuditedAggregateRoot<Guid> | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// 订单编号 | ||||
|         /// </summary> | ||||
|         public string OrderSN { get; private set; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 用户ID | ||||
|         /// </summary> | ||||
|         public Guid  CustomerId { get; private set; } | ||||
|         /// <summary> | ||||
|         /// 家政人员ID | ||||
|         /// </summary> | ||||
|         public Guid? WorkerId { get; private set; } | ||||
|  | ||||
|         ///// <summary> | ||||
|         ///// 用户ID | ||||
|         ///// </summary> | ||||
|         //public virtual IdentityUser Customer { get; private set; } | ||||
|         ///// <summary> | ||||
|         ///// 家政人员ID | ||||
|         ///// </summary> | ||||
|         //public virtual IdentityUser? Worker { get; private set; } | ||||
|         /// <summary> | ||||
|         /// 服务项目ID | ||||
|         /// </summary> | ||||
|         public Guid ServiceId { get; private set; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 服务预约时间 | ||||
|         /// </summary> | ||||
|         public DateTime ServiceTime { get; private set; } | ||||
|  | ||||
|         public OrderStatus Status { get; private set; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 应付金额 | ||||
|         /// </summary> | ||||
|         public decimal Amount { get; private set; } | ||||
|         /// <summary> | ||||
|         /// 实付金额 | ||||
|         /// </summary> | ||||
|         public decimal PaidAmount { get; private set; } | ||||
|         /// <summary> | ||||
|         /// 支付方式 | ||||
|         /// </summary> | ||||
|         public string PaymentMethod { get; private set; } | ||||
|         /// <summary> | ||||
|         /// 地址 | ||||
|         /// </summary> | ||||
|         public AddressInfo Address { get; private set; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 备注 | ||||
|         /// </summary> | ||||
|         public string? Remark { get; private set; } | ||||
|         /// <summary> | ||||
|         /// 取消原因 | ||||
|         /// </summary> | ||||
|         public string? CancelReason { get; private set; } | ||||
|  | ||||
|         protected Order() { } | ||||
|  | ||||
|  | ||||
|         public Order(Guid id, string orderSN, Guid customerId, Guid serviceId, DateTime serviceTime, decimal amount, AddressInfo address, string remark = null) | ||||
|         : base(id) | ||||
|         { | ||||
|             OrderSN = orderSN; | ||||
|             CustomerId = customerId; | ||||
|             ServiceId = serviceId; | ||||
|             ServiceTime = serviceTime; | ||||
|             Amount = amount; | ||||
|             Address = address; | ||||
|             Remark = remark; | ||||
|             Status = OrderStatus.PendingPayment; | ||||
|         } | ||||
|  | ||||
|  | ||||
|         public void MarkPaid(decimal paidAmount, string method) | ||||
|         { | ||||
|             if (Status != OrderStatus.PendingPayment) | ||||
|                 throw new InvalidOperationException("订单不在待付款状态"); | ||||
|  | ||||
|  | ||||
|             PaidAmount = paidAmount; | ||||
|             PaymentMethod = method; | ||||
|             Status = OrderStatus.PaidWaitingAssign; | ||||
|         } | ||||
|  | ||||
|  | ||||
|         public void AssignWorker(Guid workerId) | ||||
|         { | ||||
|             if (Status != OrderStatus.PaidWaitingAssign) | ||||
|                 throw new InvalidOperationException("订单无法分配师傅"); | ||||
|  | ||||
|  | ||||
|             WorkerId = workerId; | ||||
|             Status = OrderStatus.AssignedWaitingService; | ||||
|         } | ||||
|  | ||||
|  | ||||
|         public void StartService() | ||||
|         { | ||||
|             if (Status != OrderStatus.AssignedWaitingService) | ||||
|                 throw new InvalidOperationException("订单无法开始"); | ||||
|  | ||||
|  | ||||
|             Status = OrderStatus.InService; | ||||
|         } | ||||
|  | ||||
|  | ||||
|         public void CompleteService() | ||||
|         { | ||||
|             if (Status != OrderStatus.InService) | ||||
|                 throw new InvalidOperationException("订单未开始服务,无法完成"); | ||||
|  | ||||
|  | ||||
|             Status = OrderStatus.WaitingConfirm; | ||||
|         } | ||||
|  | ||||
|  | ||||
|         public void ConfirmCompletion() | ||||
|         { | ||||
|             if (Status != OrderStatus.WaitingConfirm) | ||||
|                 throw new InvalidOperationException("订单无法确认"); | ||||
|  | ||||
|  | ||||
|             Status = OrderStatus.Completed; | ||||
|         } | ||||
|  | ||||
|  | ||||
|         public void Cancel(string reason) | ||||
|         { | ||||
|             // 若已完成或退款中则不可取消 | ||||
|             if (Status == OrderStatus.Completed || Status == OrderStatus.Refunding || Status == OrderStatus.Refunded) | ||||
|                 throw new InvalidOperationException("订单无法被取消"); | ||||
|  | ||||
|  | ||||
|             CancelReason = reason; | ||||
|             Status = OrderStatus.Canceled; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,14 @@ | ||||
| using KonSoft.Admin.Entities; | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
| using System.Threading.Tasks; | ||||
| using Volo.Abp.Domain.Repositories; | ||||
|  | ||||
| namespace KonSoft.Admin.Repositories | ||||
| { | ||||
|     public interface IOrderRepository : IRepository<Order> | ||||
|     { | ||||
|     } | ||||
| } | ||||
| @ -1,4 +1,5 @@ | ||||
| using Microsoft.EntityFrameworkCore; | ||||
| using KonSoft.Admin.Entities; | ||||
| using Microsoft.EntityFrameworkCore; | ||||
| using Volo.Abp.AuditLogging.EntityFrameworkCore; | ||||
| using Volo.Abp.BackgroundJobs.EntityFrameworkCore; | ||||
| using Volo.Abp.Data; | ||||
| @ -53,6 +54,10 @@ public class AdminDbContext : | ||||
|  | ||||
|     #endregion | ||||
|  | ||||
|     #region 订单 | ||||
|     public DbSet<Order> Order { get; set; } | ||||
|     #endregion | ||||
|  | ||||
|     public AdminDbContext(DbContextOptions<AdminDbContext> options) | ||||
|         : base(options) | ||||
|     { | ||||
|  | ||||
| @ -0,0 +1,37 @@ | ||||
| using KonSoft.Admin.Entities; | ||||
| using Microsoft.EntityFrameworkCore; | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Diagnostics.CodeAnalysis; | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
| using System.Threading.Tasks; | ||||
| using Volo.Abp; | ||||
|  | ||||
| namespace KonSoft.Admin.EntityFrameworkCore.Configures | ||||
| { | ||||
|     public static class ApplicationDbContextModelBuilderExtensions | ||||
|     { | ||||
|         public static void ConfigureApplication([NotNull] this ModelBuilder builder) | ||||
|         { | ||||
|             Check.NotNull(builder, nameof(builder)); | ||||
|  | ||||
|             builder.Entity<Order>(b => | ||||
|             { | ||||
|                 b.ToTable(AdminConsts.DbTablePrefix + "Order" + AdminConsts.DbSchema); | ||||
|  | ||||
|                 b.OwnsOne(o => o.Address, a => | ||||
|                 { | ||||
|                     a.Property(p => p.ContactName).HasColumnName("ContactName").HasMaxLength(50); | ||||
|                     a.Property(p => p.ContactPhone).HasColumnName("ContactPhone").HasMaxLength(20); | ||||
|                     a.Property(p => p.DetailAddress).HasColumnName("DetailAddress").HasMaxLength(200); | ||||
|                     a.Property(p => p.City).HasColumnName("City").HasMaxLength(50); | ||||
|                     a.Property(p => p.District).HasColumnName("District").HasMaxLength(50); | ||||
|                 }); | ||||
|             }); | ||||
|  | ||||
|         } | ||||
|  | ||||
|  | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,21 @@ | ||||
| using KonSoft.Admin.Entities; | ||||
| using KonSoft.Admin.Repositories; | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
| using System.Threading; | ||||
| using System.Threading.Tasks; | ||||
| using Volo.Abp.Domain.Repositories; | ||||
| using Volo.Abp.Domain.Repositories.EntityFrameworkCore; | ||||
| using Volo.Abp.EntityFrameworkCore; | ||||
|  | ||||
| namespace KonSoft.Admin.EntityFrameworkCore.Repositories | ||||
| { | ||||
|     public class OrderRepository : EfCoreRepository<AdminDbContext, Order>, IOrderRepository | ||||
|     { | ||||
|         public OrderRepository(IDbContextProvider<AdminDbContext> dbContextProvider) : base(dbContextProvider) | ||||
|         { | ||||
|         } | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user