当然可以!以下是《跟着AI学习C#之项目实战:电商平台开发 Day5》的详细内容,我们将继续以“项目实战驱动学习”的方式推进,假设你前几天已经完成了基础架构、用户模块、商品模块和分类管理。


🧠 跟着AI学习 C# 项目实战 —— 电商平台开发 Day5

主题:订单模块开发(创建订单 + 订单详情 + 数据持久化)


📘 目录

  1. 功能目标与知识点
  2. 数据库设计(订单主表+详情表)
  3. 创建订单接口设计
  4. 订单逻辑处理(订单号生成、库存扣减)
  5. 订单查询(分页 + 按用户ID)
  6. 代码实现:Entity、Service、Controller
  7. 前后端联调说明(API测试)
  8. 今日作业与思考
  9. 参考资料

🎯 1. 功能目标与知识点

目标:实现用户下单流程,包括订单创建、订单详情记录、库存校验等功能。

知识点包括:

  • 数据库关系映射(1对多)
  • 事务处理(防止库存出错)
  • 订单号规则(雪花算法/时间戳)
  • JSON 反序列化对象嵌套
  • Web API 模型绑定和数据校验

🗃️ 2. 数据库设计

我们需要两个表:

🧾 表1:Orders(订单主表)

字段类型描述
OrderIdstring (PK)订单ID(唯一)
UserIdint用户ID
OrderTimeDateTime下单时间
TotalAmountdecimal(10,2)订单总金额
Statusint状态(0未支付等)

🧾 表2:OrderItems(订单详情表)

字段类型描述
Idint (PK)自增ID
OrderIdstring (FK)所属订单ID
ProductIdint商品ID
ProductNamenvarchar(100)商品名称
Quantityint数量
Pricedecimal(10,2)商品单价

⚙️ 3. 创建订单 API 设计

✅ 请求 URL:

POST /api/order/create

✅ 请求参数(JSON):

{
  "userId": 1,
  "items": [
    { "productId": 101, "quantity": 2 },
    { "productId": 102, "quantity": 1 }
  ]
}

🔄 4. 创建订单逻辑步骤

  1. 校验商品是否存在、库存是否足够
  2. 计算总金额
  3. 生成订单ID(推荐用时间戳+随机)
  4. 使用事务处理以下操作:
    • 插入 Orders 表
    • 批量插入 OrderItems
    • 扣减库存
  5. 返回订单号和状态码

🧑‍💻 5. 后端代码实现(选摘)

📦 Entity 示例(Order.cs)

public class Order
{
    public string OrderId { get; set; }
    public int UserId { get; set; }
    public DateTime OrderTime { get; set; }
    public decimal TotalAmount { get; set; }
    public int Status { get; set; } = 0;
    public List<OrderItem> Items { get; set; }
}

📦 OrderItem.cs

public class OrderItem
{
    public int Id { get; set; }
    public string OrderId { get; set; }
    public int ProductId { get; set; }
    public string ProductName { get; set; }
    public int Quantity { get; set; }
    public decimal Price { get; set; }
}

📂 OrderService.cs 中的核心逻辑

public async Task<string> CreateOrderAsync(OrderCreateDto dto)
{
    using var transaction = _dbContext.Database.BeginTransaction();

    try
    {
        var orderId = "ORD" + DateTime.Now.Ticks;
        decimal total = 0;
        var items = new List<OrderItem>();

        foreach (var item in dto.Items)
        {
            var product = await _dbContext.Products.FindAsync(item.ProductId);
            if (product == null || product.Stock < item.Quantity)
                throw new Exception("库存不足");

            product.Stock -= item.Quantity;
            total += product.Price * item.Quantity;

            items.Add(new OrderItem {
                OrderId = orderId,
                ProductId = product.ProductId,
                ProductName = product.Name,
                Quantity = item.Quantity,
                Price = product.Price
            });
        }

        var order = new Order {
            OrderId = orderId,
            UserId = dto.UserId,
            OrderTime = DateTime.Now,
            TotalAmount = total,
            Items = items
        };

        _dbContext.Orders.Add(order);
        await _dbContext.SaveChangesAsync();
        transaction.Commit();

        return orderId;
    }
    catch
    {
        transaction.Rollback();
        throw;
    }
}

📡 Controller 示例

[HttpPost("create")]
public async Task<IActionResult> CreateOrder([FromBody] OrderCreateDto dto)
{
    try
    {
        var orderId = await _orderService.CreateOrderAsync(dto);
        return Ok(new { success = true, orderId });
    }
    catch (Exception ex)
    {
        return BadRequest(new { success = false, message = ex.Message });
    }
}

📑 6. 前后端联调建议

  • 使用 Postman/Postwoman 发送测试请求
  • 对于订单请求体,务必保证格式正确
  • 处理返回 JSON 结果中的 orderId,可跳转订单详情页面

💡 7. 今日作业与思考

✅ 实践任务:

  • 用 Postman 创建一个包含两个商品的订单
  • 实现用户ID条件下的订单列表分页接口
  • 尝试引入枚举管理订单状态(枚举转文字)

🤔 思考题:

  • 如何设计“取消订单”功能?应恢复库存?是否设置过期时间?
  • 多用户并发下单时如何防止超卖?

🔗 8. 参考资料