feat 移除订单编号字段并优化订单创建逻辑

- 移除了 `Order` 实体中的 `OrderSN` 字段及相关逻辑。
- 修改 `Order` 构造函数,简化参数,新增默认状态字段。
- 更新 `AddressInfo` 属性访问修饰符为 `private set`。
- 调整 `OrderAppService` 的订单创建逻辑,适配新构造函数。
- 更新数据库迁移路径,新增迁移文件 `20251017042956_V1.0.0`。
- 新增 `AppOrder`、`AppProduct`、`AppServiceCategory` 表。
- 在 `AbpUsers` 表中新增字段以支持用户扩展。
- 更新实体配置,统一命名约定,支持扩展映射。
- 添加 `AdminDataSeedContributor` 类,预留数据种子逻辑。
This commit is contained in:
2025-10-17 13:24:27 +08:00
parent 89c8236f99
commit 28954870f6
10 changed files with 2778 additions and 46 deletions

View File

@ -79,7 +79,7 @@ public class OrderAppService(IOrderRepository orderRepository) : ApplicationServ
// 生成订单号 TODO
var orderSN = "SN001";
var address = ObjectMapper.Map<AddressDto, AddressInfo>(input.Address);
var order = new Order(Guid.NewGuid(), orderSN, input.CustomerId, input.ServiceCategoryId, input.ServiceTime,
var order = new Order(input.CustomerId, input.ServiceCategoryId, input.ServiceTime,
input.Amount, address, input.Remark);
await _orderRepository.InsertAsync(order);

View File

@ -7,16 +7,14 @@ namespace KonSoft.Admin.Entities;
public class Order : FullAuditedAggregateRoot<Guid>
{
protected Order()
private Order()
{
}
public Order(Guid id, string orderSN, Guid customerId, Guid serviceCategoryId, DateTime serviceTime, decimal amount,
AddressInfo address, string remark = null)
: base(id)
public Order(Guid customerId, Guid serviceCategoryId, DateTime serviceTime, decimal amount,
AddressInfo address, string? remark = null)
{
OrderSN = orderSN;
CustomerId = customerId;
ServiceCategoryId = serviceCategoryId;
ServiceTime = serviceTime;
@ -26,11 +24,6 @@ public class Order : FullAuditedAggregateRoot<Guid>
Status = OrderStatus.PendingPayment;
}
/// <summary>
/// 订单编号
/// </summary>
public string OrderSN { get; private set; }
/// <summary>
/// 用户ID
/// </summary>
@ -41,26 +34,19 @@ public class Order : FullAuditedAggregateRoot<Guid>
/// </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 ServiceCategoryId { get; private set; }
public virtual ServiceCategory ServiceCategory { get; private set; }
/// <summary>
/// 服务预约时间
/// </summary>
public DateTime ServiceTime { get; private set; }
/// <summary>
/// 订单状态
/// </summary>
public OrderStatus Status { get; private set; }
/// <summary>

View File

@ -8,10 +8,6 @@ namespace KonSoft.Admin.ValueObjects;
/// </summary>
public class AddressInfo : ValueObject
{
public AddressInfo()
{
}
public AddressInfo(string contactName, string contactPhone, string detailAddress, string city, string district)
{
ContactName = contactName;
@ -24,27 +20,27 @@ public class AddressInfo : ValueObject
/// <summary>
/// 联系人
/// </summary>
public string ContactName { get; }
public string ContactName { get; private set; }
/// <summary>
/// 手机号
/// </summary>
public string ContactPhone { get; }
public string ContactPhone { get; private set; }
/// <summary>
/// 详细地址
/// </summary>
public string DetailAddress { get; }
public string DetailAddress { get; private set; }
/// <summary>
/// 城市
/// </summary>
public string City { get; }
public string City { get; private set; }
/// <summary>
/// 区域
/// </summary>
public string District { get; }
public string District { get; private set; }
protected override IEnumerable<object> GetAtomicValues()

View File

@ -28,7 +28,7 @@ public class AdminDbContextFactory : IDesignTimeDbContextFactory<AdminDbContext>
private static IConfigurationRoot BuildConfiguration()
{
var builder = new ConfigurationBuilder()
.SetBasePath(Path.Combine(Directory.GetCurrentDirectory(), "../KonSoft.Admin.DbMigrator/"))
.SetBasePath(Path.Combine(Directory.GetCurrentDirectory(), "../../../../microservices/KonSoft.Admin.HttpApi.Host/"))
.AddJsonFile("appsettings.json", false);
return builder.Build();

View File

@ -2,6 +2,8 @@
using Microsoft.EntityFrameworkCore;
using System.Diagnostics.CodeAnalysis;
using Volo.Abp;
using Volo.Abp.EntityFrameworkCore.Modeling;
using Volo.Abp.Identity;
namespace KonSoft.Admin.EntityFrameworkCore.Configures;
@ -11,26 +13,35 @@ public static class ApplicationDbContextModelBuilderExtensions
{
Check.NotNull(builder, nameof(builder));
builder.Entity<Order>(b =>
builder.Entity<Order>(e =>
{
b.ToTable(AdminConsts.DbTablePrefix + nameof(Order) + AdminConsts.DbSchema);
e.ToTable(AdminConsts.DbTablePrefix + nameof(Order) + AdminConsts.DbSchema);
e.ConfigureByConvention();
b.ComplexProperty(e => e.Address);
e.ComplexProperty(b => b.Address);
e.ApplyObjectExtensionMappings();
});
builder.Entity<Product>(b =>
builder.Entity<Product>(e =>
{
b.ToTable(AdminConsts.DbTablePrefix + nameof(Product) + AdminConsts.DbSchema);
e.ToTable(AdminConsts.DbTablePrefix + nameof(Product) + AdminConsts.DbSchema);
e.ConfigureByConvention();
e.ApplyObjectExtensionMappings();
});
builder.Entity<HouseholdWorker>(b =>
builder.Entity<HouseholdWorker>(e =>
{
b.ToTable(AdminConsts.DbTablePrefix + nameof(HouseholdWorker) + AdminConsts.DbSchema);
e.ToTable(AbpIdentityDbProperties.DbTablePrefix + "Users" + AbpIdentityDbProperties.DbSchema);
e.ConfigureByConvention();
e.ApplyObjectExtensionMappings();
});
builder.Entity<ServiceCategory>(b =>
builder.Entity<ServiceCategory>(e =>
{
b.ToTable(AdminConsts.DbTablePrefix + nameof(ServiceCategory) + AdminConsts.DbSchema);
e.ToTable(AdminConsts.DbTablePrefix + nameof(ServiceCategory) + AdminConsts.DbSchema);
e.ConfigureByConvention();
e.ApplyObjectExtensionMappings();
});
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,157 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace KonSoft.Admin.Migrations
{
/// <inheritdoc />
public partial class V100 : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "Discriminator",
table: "AbpUsers",
type: "character varying(21)",
maxLength: 21,
nullable: false,
defaultValue: "");
migrationBuilder.AddColumn<int>(
name: "OrderCount",
table: "AbpUsers",
type: "integer",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "Profession",
table: "AbpUsers",
type: "text",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "ScopeOfCompetence",
table: "AbpUsers",
type: "text",
nullable: true);
migrationBuilder.CreateTable(
name: "AppOrder",
columns: table => new
{
Id = table.Column<Guid>(type: "uuid", nullable: false),
CustomerId = table.Column<Guid>(type: "uuid", nullable: false),
WorkerId = table.Column<Guid>(type: "uuid", nullable: true),
ServiceCategoryId = table.Column<Guid>(type: "uuid", nullable: false),
ServiceTime = table.Column<DateTime>(type: "timestamp without time zone", nullable: false),
Status = table.Column<int>(type: "integer", nullable: false),
Amount = table.Column<decimal>(type: "numeric", nullable: false),
PaidAmount = table.Column<decimal>(type: "numeric", nullable: false),
PaymentMethod = table.Column<string>(type: "text", nullable: false),
Remark = table.Column<string>(type: "text", nullable: true),
CancelReason = table.Column<string>(type: "text", nullable: true),
Address_City = table.Column<string>(type: "text", nullable: false),
Address_ContactName = table.Column<string>(type: "text", nullable: false),
Address_ContactPhone = table.Column<string>(type: "text", nullable: false),
Address_DetailAddress = table.Column<string>(type: "text", nullable: false),
Address_District = table.Column<string>(type: "text", nullable: false),
ExtraProperties = table.Column<string>(type: "text", nullable: false),
ConcurrencyStamp = table.Column<string>(type: "character varying(40)", maxLength: 40, nullable: false),
CreationTime = table.Column<DateTime>(type: "timestamp without time zone", nullable: false),
CreatorId = table.Column<Guid>(type: "uuid", nullable: true),
LastModificationTime = table.Column<DateTime>(type: "timestamp without time zone", nullable: true),
LastModifierId = table.Column<Guid>(type: "uuid", nullable: true),
IsDeleted = table.Column<bool>(type: "boolean", nullable: false, defaultValue: false),
DeleterId = table.Column<Guid>(type: "uuid", nullable: true),
DeletionTime = table.Column<DateTime>(type: "timestamp without time zone", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_AppOrder", x => x.Id);
});
migrationBuilder.CreateTable(
name: "AppProduct",
columns: table => new
{
Id = table.Column<Guid>(type: "uuid", nullable: false),
Name = table.Column<string>(type: "text", nullable: false),
Code = table.Column<string>(type: "text", nullable: false),
Price = table.Column<decimal>(type: "numeric", nullable: false),
Description = table.Column<string>(type: "text", nullable: false),
Type = table.Column<string>(type: "text", nullable: false),
ParentId = table.Column<Guid>(type: "uuid", nullable: true),
Status = table.Column<string>(type: "text", nullable: false),
Order = table.Column<int>(type: "integer", nullable: false),
ExtraProperties = table.Column<string>(type: "text", nullable: false),
ConcurrencyStamp = table.Column<string>(type: "character varying(40)", maxLength: 40, nullable: false),
CreationTime = table.Column<DateTime>(type: "timestamp without time zone", nullable: false),
CreatorId = table.Column<Guid>(type: "uuid", nullable: true),
LastModificationTime = table.Column<DateTime>(type: "timestamp without time zone", nullable: true),
LastModifierId = table.Column<Guid>(type: "uuid", nullable: true),
IsDeleted = table.Column<bool>(type: "boolean", nullable: false, defaultValue: false),
DeleterId = table.Column<Guid>(type: "uuid", nullable: true),
DeletionTime = table.Column<DateTime>(type: "timestamp without time zone", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_AppProduct", x => x.Id);
});
migrationBuilder.CreateTable(
name: "AppServiceCategory",
columns: table => new
{
Id = table.Column<Guid>(type: "uuid", nullable: false),
Name = table.Column<string>(type: "text", nullable: false),
ParentId = table.Column<Guid>(type: "uuid", nullable: true),
Path = table.Column<string>(type: "text", nullable: false),
Level = table.Column<int>(type: "integer", nullable: false),
ExtraProperties = table.Column<string>(type: "text", nullable: false),
ConcurrencyStamp = table.Column<string>(type: "character varying(40)", maxLength: 40, nullable: false),
CreationTime = table.Column<DateTime>(type: "timestamp without time zone", nullable: false),
CreatorId = table.Column<Guid>(type: "uuid", nullable: true),
LastModificationTime = table.Column<DateTime>(type: "timestamp without time zone", nullable: true),
LastModifierId = table.Column<Guid>(type: "uuid", nullable: true),
IsDeleted = table.Column<bool>(type: "boolean", nullable: false, defaultValue: false),
DeleterId = table.Column<Guid>(type: "uuid", nullable: true),
DeletionTime = table.Column<DateTime>(type: "timestamp without time zone", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_AppServiceCategory", x => x.Id);
});
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "AppOrder");
migrationBuilder.DropTable(
name: "AppProduct");
migrationBuilder.DropTable(
name: "AppServiceCategory");
migrationBuilder.DropColumn(
name: "Discriminator",
table: "AbpUsers");
migrationBuilder.DropColumn(
name: "OrderCount",
table: "AbpUsers");
migrationBuilder.DropColumn(
name: "Profession",
table: "AbpUsers");
migrationBuilder.DropColumn(
name: "ScopeOfCompetence",
table: "AbpUsers");
}
}
}

View File

@ -1,5 +1,6 @@
// <auto-generated />
using System;
using System.Collections.Generic;
using KonSoft.Admin.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
@ -24,6 +25,264 @@ namespace KonSoft.Admin.Migrations
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("KonSoft.Admin.Entities.Order", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<decimal>("Amount")
.HasColumnType("numeric");
b.Property<string>("CancelReason")
.HasColumnType("text");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.IsRequired()
.HasMaxLength(40)
.HasColumnType("character varying(40)")
.HasColumnName("ConcurrencyStamp");
b.Property<DateTime>("CreationTime")
.HasColumnType("timestamp without time zone")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("uuid")
.HasColumnName("CreatorId");
b.Property<Guid>("CustomerId")
.HasColumnType("uuid");
b.Property<Guid?>("DeleterId")
.HasColumnType("uuid")
.HasColumnName("DeleterId");
b.Property<DateTime?>("DeletionTime")
.HasColumnType("timestamp without time zone")
.HasColumnName("DeletionTime");
b.Property<string>("ExtraProperties")
.IsRequired()
.HasColumnType("text")
.HasColumnName("ExtraProperties");
b.Property<bool>("IsDeleted")
.ValueGeneratedOnAdd()
.HasColumnType("boolean")
.HasDefaultValue(false)
.HasColumnName("IsDeleted");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("timestamp without time zone")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnType("uuid")
.HasColumnName("LastModifierId");
b.Property<decimal>("PaidAmount")
.HasColumnType("numeric");
b.Property<string>("PaymentMethod")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Remark")
.HasColumnType("text");
b.Property<Guid>("ServiceCategoryId")
.HasColumnType("uuid");
b.Property<DateTime>("ServiceTime")
.HasColumnType("timestamp without time zone");
b.Property<int>("Status")
.HasColumnType("integer");
b.Property<Guid?>("WorkerId")
.HasColumnType("uuid");
b.ComplexProperty<Dictionary<string, object>>("Address", "KonSoft.Admin.Entities.Order.Address#AddressInfo", b1 =>
{
b1.IsRequired();
b1.Property<string>("City")
.IsRequired()
.HasColumnType("text");
b1.Property<string>("ContactName")
.IsRequired()
.HasColumnType("text");
b1.Property<string>("ContactPhone")
.IsRequired()
.HasColumnType("text");
b1.Property<string>("DetailAddress")
.IsRequired()
.HasColumnType("text");
b1.Property<string>("District")
.IsRequired()
.HasColumnType("text");
});
b.HasKey("Id");
b.ToTable("AppOrder", (string)null);
});
modelBuilder.Entity("KonSoft.Admin.Entities.Product", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("Code")
.IsRequired()
.HasColumnType("text");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.IsRequired()
.HasMaxLength(40)
.HasColumnType("character varying(40)")
.HasColumnName("ConcurrencyStamp");
b.Property<DateTime>("CreationTime")
.HasColumnType("timestamp without time zone")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("uuid")
.HasColumnName("CreatorId");
b.Property<Guid?>("DeleterId")
.HasColumnType("uuid")
.HasColumnName("DeleterId");
b.Property<DateTime?>("DeletionTime")
.HasColumnType("timestamp without time zone")
.HasColumnName("DeletionTime");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("text");
b.Property<string>("ExtraProperties")
.IsRequired()
.HasColumnType("text")
.HasColumnName("ExtraProperties");
b.Property<bool>("IsDeleted")
.ValueGeneratedOnAdd()
.HasColumnType("boolean")
.HasDefaultValue(false)
.HasColumnName("IsDeleted");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("timestamp without time zone")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnType("uuid")
.HasColumnName("LastModifierId");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<int>("Order")
.HasColumnType("integer");
b.Property<Guid?>("ParentId")
.HasColumnType("uuid");
b.Property<decimal>("Price")
.HasColumnType("numeric");
b.Property<string>("Status")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Type")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("AppProduct", (string)null);
});
modelBuilder.Entity("KonSoft.Admin.Entities.ServiceCategory", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.IsRequired()
.HasMaxLength(40)
.HasColumnType("character varying(40)")
.HasColumnName("ConcurrencyStamp");
b.Property<DateTime>("CreationTime")
.HasColumnType("timestamp without time zone")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("uuid")
.HasColumnName("CreatorId");
b.Property<Guid?>("DeleterId")
.HasColumnType("uuid")
.HasColumnName("DeleterId");
b.Property<DateTime?>("DeletionTime")
.HasColumnType("timestamp without time zone")
.HasColumnName("DeletionTime");
b.Property<string>("ExtraProperties")
.IsRequired()
.HasColumnType("text")
.HasColumnName("ExtraProperties");
b.Property<bool>("IsDeleted")
.ValueGeneratedOnAdd()
.HasColumnType("boolean")
.HasDefaultValue(false)
.HasColumnName("IsDeleted");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("timestamp without time zone")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnType("uuid")
.HasColumnName("LastModifierId");
b.Property<int>("Level")
.HasColumnType("integer");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<Guid?>("ParentId")
.HasColumnType("uuid");
b.Property<string>("Path")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("AppServiceCategory", (string)null);
});
modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLog", b =>
{
b.Property<Guid>("Id")
@ -783,6 +1042,11 @@ namespace KonSoft.Admin.Migrations
.HasColumnType("timestamp without time zone")
.HasColumnName("DeletionTime");
b.Property<string>("Discriminator")
.IsRequired()
.HasMaxLength(21)
.HasColumnType("character varying(21)");
b.Property<string>("Email")
.IsRequired()
.HasMaxLength(256)
@ -913,6 +1177,10 @@ namespace KonSoft.Admin.Migrations
b.HasIndex("UserName");
b.ToTable("AbpUsers", (string)null);
b.HasDiscriminator<string>("Discriminator").HasValue("IdentityUser");
b.UseTphMappingStrategy();
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserClaim", b =>
@ -1816,6 +2084,26 @@ namespace KonSoft.Admin.Migrations
b.ToTable("AbpTenantConnectionStrings", (string)null);
});
modelBuilder.Entity("KonSoft.Admin.Entities.HouseholdWorker", b =>
{
b.HasBaseType("Volo.Abp.Identity.IdentityUser");
b.Property<int>("OrderCount")
.HasColumnType("integer");
b.Property<string>("Profession")
.IsRequired()
.HasColumnType("text");
b.Property<string>("ScopeOfCompetence")
.IsRequired()
.HasColumnType("text");
b.ToTable("AbpUsers", (string)null);
b.HasDiscriminator().HasValue("HouseholdWorker");
});
modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLogAction", b =>
{
b.HasOne("Volo.Abp.AuditLogging.AuditLog", null)