- 后端新增管理员、商品、分类聚合模型 - 实现积分规则、礼品、订单、会员等完整功能 - 添加管理员认证和权限管理 - 完善数据库迁移和实体配置 - 前端管理后台实现登录、仪表盘、积分规则、礼品、订单、会员等页面 - 集成shadcn-vue UI组件库 - 添加前后端功能文档和截图
508 lines
18 KiB
Markdown
508 lines
18 KiB
Markdown
## 后端功能概览
|
||
|
||
> 本文档说明当前后端(Backend)已完成的主要功能与技术实现,便于后续开发和前后端联调。
|
||
> 最后更新时间:2026-02-11
|
||
|
||
---
|
||
|
||
## 一、整体技术栈与架构
|
||
|
||
### 1.1 技术栈
|
||
- **.NET 10** - 最新的 .NET 运行时
|
||
- **EF Core + SQLite** - 数据持久化(已从 PostgreSQL 迁移到 SQLite)
|
||
- **CAP + NetCorePal** - 分布式事务与集成事件框架
|
||
- **FastEndpoints** - 高性能 API 端点框架
|
||
- **Hangfire** - 后台任务调度
|
||
- **Redis** - 分布式缓存与 CAP 消息存储
|
||
- **MediatR** - CQRS 模式实现
|
||
- **Swashbuckle/Swagger** - API 文档
|
||
|
||
### 1.2 架构风格
|
||
- **CleanDDD 分层结构**:Domain / Infrastructure / Web
|
||
- **聚合根**:统一继承 `Entity<TId>, IAggregateRoot`
|
||
- **强类型 ID**:所有实体 ID 使用 `xxxId : IGuidStronglyTypedId`
|
||
- **领域事件 + 集成事件**:解耦跨聚合、跨事务操作
|
||
- **CQRS**:命令(Command)与查询(Query)分离,命令处理器操作仓储,查询直接访问 DbContext
|
||
- **最终一致性**:通过领域事件 → 集成事件 → 事件处理器实现
|
||
|
||
---
|
||
|
||
## 二、已完成的核心聚合与领域模型
|
||
|
||
### 2.1 会员聚合 (MemberAggregate)
|
||
- **实体**:`Member`
|
||
- **核心字段**:
|
||
- 手机号、密码(加密)、昵称
|
||
- 累计总积分 `TotalPoints`
|
||
- 可用积分 `AvailablePoints`
|
||
- 状态(正常/禁用)、注册时间
|
||
- **值对象**:
|
||
- `MemberLevel`:等级编码、名称、所需积分、积分倍率
|
||
- **领域行为**:
|
||
- `AddPoints(amount, source, reason, relatedId, expiryDate)` - 增加积分
|
||
- `ConsumePoints(amount, reason, orderId)` - 消费积分
|
||
- `RefundPoints(amount, reason, orderId)` - 退还积分
|
||
- **领域事件**:
|
||
- `PointsAddedDomainEvent`
|
||
- `PointsConsumedDomainEvent`
|
||
- `PointsRefundedDomainEvent`
|
||
|
||
### 2.2 营销码聚合 (MarketingCodeAggregate)
|
||
- **实体**:`MarketingCode`
|
||
- **核心字段**:
|
||
- 营销码 `Code`(唯一)
|
||
- 批次号 `BatchNo`
|
||
- 是否已使用 `IsUsed`
|
||
- 使用者会员ID、使用时间
|
||
- 过期时间
|
||
- **值对象**:
|
||
- `ProductInfo`:产品ID、产品名称、品类ID、品类名称
|
||
- **领域行为**:
|
||
- `Use(memberId)` - 使用营销码
|
||
- **领域事件**:
|
||
- `MarketingCodeUsedDomainEvent`
|
||
|
||
### 2.3 积分规则聚合 (PointsRuleAggregate)
|
||
- **实体**:`PointsRule`
|
||
- **核心字段**:
|
||
- 规则名称、规则类型(产品/时间/会员等级)
|
||
- 积分值、奖励倍数
|
||
- 产品ID、品类ID、会员等级编码
|
||
- 生效时间范围(开始/结束)
|
||
- 是否激活
|
||
- **领域行为**:
|
||
- `CalculatePoints(memberBonusRate)` - 计算应得积分
|
||
|
||
### 2.4 积分交易聚合 (PointsTransactionAggregate)
|
||
- **实体**:`PointsTransaction`
|
||
- **核心字段**:
|
||
- 会员ID、交易类型(获取/消费/退还/过期)
|
||
- 积分数量、来源、原因描述
|
||
- 关联ID(营销码ID/订单ID等)
|
||
- 过期时间(仅获取类型有效)
|
||
- 创建时间
|
||
- **静态工厂方法**:
|
||
- `CreateEarnTransaction(...)` - 创建获取积分记录
|
||
- `CreateConsumeTransaction(...)` - 创建消费积分记录
|
||
- `CreateRefundTransaction(...)` - 创建退还积分记录
|
||
- `CreateExpireTransaction(...)` - 创建过期积分记录
|
||
- **说明**:通过集成事件异步创建,与会员聚合解耦
|
||
|
||
### 2.5 礼品聚合 (GiftAggregate)
|
||
- **实体**:`Gift`
|
||
- **核心字段**:
|
||
- 礼品名称、类型(实物/虚拟/自有产品)
|
||
- 描述、图片URL
|
||
- 所需积分、总库存、可用库存
|
||
- 每人限兑数量、是否上架、排序
|
||
- 创建/更新时间
|
||
- **领域行为**:
|
||
- `Update(...)` - 更新礼品信息
|
||
- `AddStock(quantity)` - 增加库存
|
||
- `ReserveStock(quantity)` - 预留库存(下单时)
|
||
- `DeductStock(quantity)` - 扣减总库存(发货时)
|
||
- `ReleaseStock(quantity)` - 释放库存(订单取消时)
|
||
- `PutOnShelf()` / `PutOffShelf()` - 上架/下架
|
||
- **领域事件**:
|
||
- `GiftCreatedDomainEvent`
|
||
- `GiftUpdatedDomainEvent`
|
||
- `GiftStockChangedDomainEvent`
|
||
|
||
### 2.6 兑换订单聚合 (RedemptionOrderAggregate)
|
||
- **实体**:`RedemptionOrder`
|
||
- **核心字段**:
|
||
- 订单号、会员ID、礼品ID/名称/类型
|
||
- 数量、消耗积分
|
||
- 物流单号、取消原因
|
||
- 状态(待处理/已发货/已送达/已完成/已取消)
|
||
- 创建/更新时间
|
||
- **值对象**:
|
||
- `Address`:收货人姓名、电话、省市区、详细地址(实物礼品必填)
|
||
- **领域行为**:
|
||
- `MarkAsDispatched(trackingNo)` - 标记为已发货
|
||
- `MarkAsDelivered()` - 标记为已送达
|
||
- `Complete()` - 完成订单
|
||
- `Cancel(reason)` - 取消订单
|
||
- **领域事件**:
|
||
- `RedemptionOrderCreatedDomainEvent`
|
||
- `RedemptionOrderDispatchedDomainEvent`
|
||
- `RedemptionOrderDeliveredDomainEvent`
|
||
- `RedemptionOrderCompletedDomainEvent`
|
||
- `RedemptionOrderCancelledDomainEvent`
|
||
|
||
---
|
||
|
||
## 三、核心业务流程
|
||
|
||
### 3.1 会员注册与登录
|
||
|
||
#### 会员注册
|
||
- **端点**:`POST /api/members/register`
|
||
- **请求**:`RegisterMemberRequest { Phone, Password, Nickname? }`
|
||
- **命令**:`RegisterMemberCommand`
|
||
- **流程**:
|
||
1. 校验手机号唯一性
|
||
2. 密码加密存储
|
||
3. 创建会员并设置初始等级
|
||
4. 返回会员ID
|
||
|
||
#### 会员登录
|
||
- **端点**:`POST /api/members/login`
|
||
- **请求**:`LoginMemberRequest { Phone, Password }`
|
||
- **命令**:`LoginMemberCommand`
|
||
- **流程**:
|
||
1. 验证手机号和密码
|
||
2. 返回会员信息和 Token(TODO: 完善 JWT 认证)
|
||
|
||
### 3.2 扫码获取积分流程
|
||
|
||
#### 使用营销码
|
||
- **端点**:`POST /api/marketing-codes/scan`
|
||
- **请求**:`UseMarketingCodeRequest { Code, MemberId }`
|
||
- **命令**:`UseMarketingCodeCommand`
|
||
|
||
#### 完整流程
|
||
```
|
||
1. UseMarketingCodeCommand
|
||
├─ 校验营销码存在且未使用
|
||
├─ 校验未过期
|
||
├─ 关联会员并标记为已使用
|
||
└─ 发布 MarketingCodeUsedDomainEvent
|
||
|
||
2. MarketingCodeUsedDomainEvent
|
||
└─ MarketingCodeUsedDomainEventHandlerForEarnPoints
|
||
├─ 加载会员聚合
|
||
├─ 匹配积分规则(IPointsRuleRepository.GetEffectiveRulesAsync)
|
||
├─ 计算应得积分和过期时间
|
||
├─ 调用 Member.AddPoints(...)
|
||
├─ 更新会员聚合
|
||
└─ 发布 PointsAddedDomainEvent
|
||
|
||
3. PointsAddedDomainEvent
|
||
└─ PointsAddedToPointsEarnedConverter (集成事件转换器)
|
||
└─ 发布 PointsEarnedIntegrationEvent
|
||
|
||
4. PointsEarnedIntegrationEvent
|
||
└─ PointsEarnedIntegrationEventHandler
|
||
├─ 幂等性检查(基于 RelatedId)
|
||
├─ 创建 PointsTransaction.CreateEarnTransaction(...)
|
||
└─ 保存到积分交易表
|
||
```
|
||
|
||
### 3.3 礼品兑换流程
|
||
|
||
#### 创建兑换订单
|
||
- **端点**:`POST /api/gifts/redeem`
|
||
- **请求**:`CreateRedemptionOrderCommand { MemberId, GiftId, Quantity, ShippingAddress? }`
|
||
|
||
#### 完整流程
|
||
```
|
||
1. CreateRedemptionOrderCommand
|
||
├─ 校验礼品存在且已上架
|
||
├─ 校验库存充足
|
||
├─ 校验限兑数量(IRedemptionOrderRepository.GetMemberRedemptionCountAsync)
|
||
├─ 校验会员积分充足
|
||
├─ 调用 Member.ConsumePoints(...) 扣减积分
|
||
├─ 更新会员聚合 → 发布 PointsConsumedDomainEvent
|
||
├─ 构造收货地址(实物礼品必填)
|
||
├─ 创建 RedemptionOrder 聚合
|
||
└─ 发布 RedemptionOrderCreatedDomainEvent
|
||
|
||
2. PointsConsumedDomainEvent
|
||
└─ PointsConsumedToPointsConsumedIntegrationEventConverter
|
||
└─ 发布 PointsConsumedIntegrationEvent
|
||
└─ 创建消费积分交易记录
|
||
|
||
3. RedemptionOrderCreatedDomainEvent
|
||
└─ RedemptionOrderCreatedDomainEventHandler
|
||
├─ 加载礼品聚合
|
||
├─ 调用 Gift.ReserveStock(quantity)
|
||
└─ 更新礼品聚合(预留库存)
|
||
```
|
||
|
||
#### 订单状态流转
|
||
```
|
||
订单发货: POST /api/admin/redemption-orders/{OrderId}/dispatch
|
||
├─ MarkOrderAsDispatchedCommand
|
||
├─ Order.MarkAsDispatched(trackingNo)
|
||
├─ 发布 RedemptionOrderDispatchedDomainEvent
|
||
└─ RedemptionOrderDispatchedDomainEventHandler
|
||
└─ Gift.DeductStock(quantity) 扣减总库存
|
||
|
||
订单取消: POST /api/admin/redemption-orders/{OrderId}/cancel
|
||
├─ CancelOrderCommand
|
||
├─ Order.Cancel(reason)
|
||
├─ 发布 RedemptionOrderCancelledDomainEvent
|
||
├─ RedemptionOrderCancelledDomainEventHandler
|
||
│ └─ Gift.ReleaseStock(quantity) 释放库存
|
||
└─ 退还积分(TODO: 待实现)
|
||
```
|
||
|
||
---
|
||
|
||
## 四、积分交易与集成事件架构
|
||
|
||
### 4.1 领域事件与集成事件流转
|
||
|
||
#### 领域事件 (Domain Events)
|
||
在会员聚合中发布,用于触发同一事务内或跨事务的业务逻辑:
|
||
- `PointsAddedDomainEvent` - 会员增加积分时
|
||
- `PointsConsumedDomainEvent` - 会员消费积分时
|
||
- `PointsRefundedDomainEvent` - 积分退还时
|
||
- `PointsExpiredDomainEvent` - 积分过期时
|
||
|
||
#### 集成事件 (Integration Events)
|
||
实现 `IIntegrationEvent` 接口,通过 CAP 框架发布和消费:
|
||
- `PointsEarnedIntegrationEvent` - 对应 Earn 交易
|
||
- `PointsConsumedIntegrationEvent` - 对应 Consume 交易
|
||
- `PointsRefundedIntegrationEvent` - 对应 Refund 交易
|
||
- `PointsExpiredIntegrationEvent` - 对应 Expire 交易
|
||
|
||
#### 集成事件转换器 (IIntegrationEventConverter)
|
||
将领域事件转换为集成事件:
|
||
- `PointsAddedToPointsEarnedConverter`
|
||
- `PointsConsumedToPointsConsumedIntegrationEventConverter`
|
||
- `PointsRefundedToPointsRefundedIntegrationEventConverter`
|
||
- `PointsExpiredToPointsExpiredIntegrationEventConverter`
|
||
|
||
### 4.2 集成事件处理器
|
||
|
||
位于 Web 层,通过 `ApplicationDbContext` 操作积分交易表:
|
||
|
||
```csharp
|
||
// 示例:处理获取积分集成事件
|
||
public class PointsEarnedIntegrationEventHandler : IIntegrationEventHandler<PointsEarnedIntegrationEvent>
|
||
{
|
||
public async Task Handle(PointsEarnedIntegrationEvent @event, CancellationToken cancellationToken)
|
||
{
|
||
// 1. 幂等性检查:基于 RelatedId 查询是否已存在
|
||
var exists = await dbContext.PointsTransactions
|
||
.AnyAsync(x => x.RelatedId == @event.RelatedId, cancellationToken);
|
||
|
||
if (exists) return; // 已处理过,跳过
|
||
|
||
// 2. 创建积分交易记录
|
||
var transaction = PointsTransaction.CreateEarnTransaction(
|
||
memberId: new MemberId(@event.MemberId),
|
||
amount: @event.Amount,
|
||
source: @event.Source,
|
||
reason: @event.Reason,
|
||
relatedId: @event.RelatedId,
|
||
expiryDate: @event.ExpiryDate
|
||
);
|
||
|
||
// 3. 保存到数据库
|
||
await dbContext.PointsTransactions.AddAsync(transaction, cancellationToken);
|
||
await dbContext.SaveChangesAsync(cancellationToken);
|
||
}
|
||
}
|
||
```
|
||
|
||
### 4.3 事务与一致性保证
|
||
|
||
#### 最终一致性
|
||
- **会员积分变更**(会员聚合)和 **积分交易记录**(PointsTransaction 聚合)处于**不同事务**
|
||
- 通过 **领域事件 → 集成事件 → 事件处理器** 链路实现最终一致性
|
||
- CAP 框架保证集成事件至少一次送达
|
||
|
||
#### 幂等性保证
|
||
- 基于 `RelatedId`(营销码ID、订单ID等)进行幂等性检查
|
||
- 防止重复消费导致的数据不一致
|
||
|
||
---
|
||
|
||
## 五、API 端点一览
|
||
|
||
### 5.1 会员模块 (Members)
|
||
|
||
| 端点 | 方法 | 说明 | 认证 |
|
||
|------|------|------|------|
|
||
| `/api/members/register` | POST | 会员注册 | 匿名 |
|
||
| `/api/members/login` | POST | 会员登录 | 匿名 |
|
||
| `/api/members/{MemberId}` | GET | 获取会员信息 | 需要 |
|
||
|
||
### 5.2 营销码模块 (MarketingCodes)
|
||
|
||
| 端点 | 方法 | 说明 | 认证 |
|
||
|------|------|------|------|
|
||
| `/api/marketing-codes/scan` | POST | 扫码使用营销码 | 匿名 |
|
||
| `/api/admin/marketing-codes/generate` | POST | 批量生成营销码(管理端) | 需要 |
|
||
|
||
### 5.3 礼品模块 (Gifts)
|
||
|
||
#### 会员端
|
||
| 端点 | 方法 | 说明 | 认证 |
|
||
|------|------|------|------|
|
||
| `/api/gifts` | GET | 获取上架礼品列表 | 匿名 |
|
||
| `/api/gifts/{GiftId}` | GET | 获取礼品详情 | 匿名 |
|
||
| `/api/gifts/redeem` | POST | 兑换礼品 | 需要 |
|
||
|
||
#### 管理端
|
||
| 端点 | 方法 | 说明 | 认证 |
|
||
|------|------|------|------|
|
||
| `/api/admin/gifts` | POST | 创建礼品 | 需要 |
|
||
| `/api/admin/gifts/{GiftId}` | PUT | 更新礼品信息 | 需要 |
|
||
| `/api/admin/gifts/{GiftId}/putonshelf` | POST | 上架礼品 | 需要 |
|
||
| `/api/admin/gifts/{GiftId}/putoffshelf` | POST | 下架礼品 | 需要 |
|
||
| `/api/admin/gifts/{GiftId}/addstock` | POST | 增加库存 | 需要 |
|
||
| `/api/admin/gifts` | GET | 获取礼品列表(支持筛选) | 需要 |
|
||
| `/api/admin/gifts/{GiftId}` | GET | 获取礼品详情 | 需要 |
|
||
|
||
### 5.4 兑换订单模块 (RedemptionOrders)
|
||
|
||
#### 会员端
|
||
| 端点 | 方法 | 说明 | 认证 |
|
||
|------|------|------|------|
|
||
| `/api/redemption-orders/my` | GET | 获取我的兑换订单列表 | 需要 |
|
||
| `/api/redemption-orders/{OrderId}` | GET | 获取订单详情 | 需要 |
|
||
|
||
#### 管理端
|
||
| 端点 | 方法 | 说明 | 认证 |
|
||
|------|------|------|------|
|
||
| `/api/admin/redemption-orders` | GET | 获取兑换订单列表 | 需要 |
|
||
| `/api/admin/redemption-orders/{OrderId}` | GET | 获取订单详情 | 需要 |
|
||
| `/api/admin/redemption-orders/{OrderId}/dispatch` | POST | 标记为已发货 | 需要 |
|
||
| `/api/admin/redemption-orders/{OrderId}/complete` | POST | 完成订单 | 需要 |
|
||
| `/api/admin/redemption-orders/{OrderId}/cancel` | POST | 取消订单 | 需要 |
|
||
|
||
### 5.5 积分规则模块 (PointsRules)
|
||
|
||
| 端点 | 方法 | 说明 | 认证 |
|
||
|------|------|------|------|
|
||
| `/api/admin/points-rules` | POST | 创建积分规则(管理端) | 需要 |
|
||
|
||
### 5.6 通用端点
|
||
|
||
| 端点 | 方法 | 说明 | 认证 |
|
||
|------|------|------|------|
|
||
| `/api/hello` | GET | 健康检查 | 匿名 |
|
||
| `/swagger` | GET | API 文档 | 匿名 |
|
||
|
||
**注意**:
|
||
- 所有端点返回统一的 `ResponseData<T>` 格式
|
||
- 强类型ID(如 `MemberId`, `GiftId`)在 Swagger 中映射为字符串类型
|
||
- 当前 JWT 认证尚未完全实现,部分端点暂时从请求参数获取 MemberId
|
||
|
||
---
|
||
|
||
## 六、数据库设计
|
||
|
||
### 6.1 数据库信息
|
||
- **数据库类型**:SQLite
|
||
- **数据库文件**:`app.db`(开发环境)
|
||
- **迁移工具**:EF Core Migrations
|
||
- **最新迁移**:`20260211044819_Init`
|
||
|
||
### 6.2 核心数据表
|
||
|
||
#### Members - 会员表
|
||
主要字段:Id, Phone(唯一), Password, Nickname, Status, TotalPoints, AvailablePoints, LevelCode, LevelName, BonusRate, RequiredPoints, RegisteredAt
|
||
|
||
#### MarketingCodes - 营销码表
|
||
主要字段:Id, Code(唯一), BatchNo, IsUsed, UsedByMemberId, UsedAt, ExpiryDate, ProductId, ProductName, CategoryId, CategoryName
|
||
|
||
#### PointsRules - 积分规则表
|
||
主要字段:Id, RuleName, RuleType, PointsValue, BonusMultiplier, ProductId, CategoryId, MemberLevelCode, StartDate, EndDate, IsActive
|
||
|
||
#### PointsTransactions - 积分交易表
|
||
主要字段:Id, MemberId, Type, Amount, Source, Reason, RelatedId, ExpiryDate, CreatedAt
|
||
|
||
**重要索引**:
|
||
- `IX_PointsTransactions_MemberId` - 会员积分查询
|
||
- `IX_PointsTransactions_RelatedId` - 幂等性检查(非唯一)
|
||
- `IX_PointsTransactions_Type` - 按类型筛选
|
||
- `IX_PointsTransactions_CreatedAt` - 时间排序
|
||
|
||
#### Gifts - 礼品表
|
||
主要字段:Id, Name, Type, Description, ImageUrl, RequiredPoints, TotalStock, AvailableStock, LimitPerMember, IsOnShelf, SortOrder, CreatedAt, UpdatedAt
|
||
|
||
#### RedemptionOrders - 兑换订单表
|
||
主要字段:Id, OrderNo(唯一), MemberId, GiftId, GiftName, GiftType, Quantity, ConsumedPoints, Status, TrackingNo, CancelReason, ReceiverName, ReceiverPhone, Province, City, District, DetailAddress, CreatedAt, UpdatedAt
|
||
|
||
### 6.3 数据表关系说明
|
||
- 所有表使用 GUID(Version 7)作为主键
|
||
- 使用软删除(`Deleted` 字段)
|
||
- 使用行版本(`RowVersion`)实现乐观并发控制
|
||
- 积分交易表与会员表通过 MemberId 关联,但不设置外键(最终一致性)
|
||
- 兑换订单表包含礼品快照信息,减少关联查询
|
||
|
||
---
|
||
|
||
## 七、当前状态与后续建议
|
||
|
||
### 7.1 当前状态
|
||
✅ **已完成功能**:
|
||
- 后端项目成功编译和运行(`dotnet build` & `dotnet run`)
|
||
- 数据库迁移已修复(SQLite 切换完成,EF Core 模型与迁移一致)
|
||
- Swagger API 文档正常生成(Schema 冲突已解决)
|
||
- 会员、营销码、积分规则、积分交易、礼品、兑换订单等核心领域模型完整
|
||
- 扫码获取积分、礼品兑换等主要业务流程已打通
|
||
- 集成事件架构实现(领域事件 → 集成事件 → 事件处理器)
|
||
|
||
⚠️ **已知问题**:
|
||
- 存在若干 Sonar 质量规则警告(TODO 注释、异常处理建议等),不影响运行
|
||
- JWT 认证尚未完全实现,部分端点暂时从请求参数获取 MemberId
|
||
- 订单取消后的积分退还逻辑待完善
|
||
|
||
### 7.2 后续建议
|
||
|
||
#### 短期优化
|
||
1. **完善认证鉴权**
|
||
- 实现完整的 JWT Token 认证流程
|
||
- 从 Token 中获取当前登录会员ID
|
||
- 添加基于角色的权限控制(会员端/管理端)
|
||
|
||
2. **补充查询功能**
|
||
- 会员积分流水查询(分页、筛选)
|
||
- 礼品库存统计和销售报表
|
||
- 订单统计和数据分析
|
||
|
||
3. **完善业务逻辑**
|
||
- 实现订单取消后的积分退还
|
||
- 添加积分过期处理定时任务
|
||
- 完善会员等级自动升级逻辑
|
||
|
||
#### 长期规划
|
||
- 根据前端实际需求调整 API 结构和 DTO 字段
|
||
- 增加单元测试和集成测试覆盖率
|
||
- 性能优化和缓存策略
|
||
- 监控和日志完善
|
||
|
||
---
|
||
|
||
## 八、开发与部署
|
||
|
||
### 8.1 本地开发
|
||
```bash
|
||
# 启动基础设施(Redis)
|
||
cd Backend/scripts
|
||
./init-infrastructure.sh # Linux/Mac
|
||
./init-infrastructure.ps1 # Windows
|
||
|
||
# 运行后端
|
||
cd Backend/src/Fengling.Backend.Web
|
||
dotnet run
|
||
|
||
# 访问 Swagger 文档
|
||
http://localhost:5511/swagger
|
||
```
|
||
|
||
### 8.2 数据库迁移
|
||
```bash
|
||
# 添加新迁移
|
||
cd Backend/src/Fengling.Backend.Infrastructure
|
||
dotnet ef migrations add MigrationName
|
||
|
||
# 应用迁移(自动在启动时执行)
|
||
dotnet ef database update
|
||
```
|
||
|
||
### 8.3 项目结构
|
||
```
|
||
Backend/
|
||
├── src/
|
||
│ ├── Fengling.Backend.Domain/ # 领域层:聚合、实体、值对象、领域事件
|
||
│ ├── Fengling.Backend.Infrastructure/ # 基础设施层:数据库、仓储实现
|
||
│ └── Fengling.Backend.Web/ # 应用层:API端点、命令查询、事件处理器
|
||
├── test/ # 测试项目
|
||
└── scripts/ # 基础设施脚本 |