# 订单商品保存功能使用指南

## 功能概述

本功能为下单接口添加了保存订单商品的能力，支持在创建订单时同时保存多个商品项到订单商品表中。

## 前端数据结构

根据您提供的前端数据结构，系统现在支持以下格式的订单创建请求：

```json
{
  "goodsItems": [
    {
      "goodsId": 10018,
      "quantity": 1,
      "payType": 1
    }
  ],
  "addressId": 10832,
  "comments": "科技小王子大米年卡套餐2.5kg",
  "deliveryType": 0,
  "type": 0,
  "totalPrice": 99.00,
  "payPrice": 99.00,
  "totalNum": 1,
  "payType": 1,
  "tenantId": 1
}
```

## 代码修改说明

### 1. OrderCreateRequest DTO 修改

在 `OrderCreateRequest` 类中添加了 `goodsItems` 字段：

```java
@Schema(description = "订单商品列表")
@Valid
@NotEmpty(message = "订单商品列表不能为空")
private List<OrderGoodsItem> goodsItems;

/**
 * 订单商品项
 */
@Data
@Schema(name = "OrderGoodsItem", description = "订单商品项")
public static class OrderGoodsItem {
    @Schema(description = "商品ID", required = true)
    @NotNull(message = "商品ID不能为空")
    private Integer goodsId;

    @Schema(description = "商品数量", required = true)
    @NotNull(message = "商品数量不能为空")
    @Min(value = 1, message = "商品数量必须大于0")
    private Integer quantity;

    @Schema(description = "支付类型")
    private Integer payType;
}
```

### 2. OrderBusinessService 修改

在 `OrderBusinessService` 中添加了保存订单商品的逻辑：

```java
// 5. 保存订单商品
saveOrderGoods(request, shopOrder);

/**
 * 保存订单商品
 */
private void saveOrderGoods(OrderCreateRequest request, ShopOrder shopOrder) {
    if (CollectionUtils.isEmpty(request.getGoodsItems())) {
        log.warn("订单商品列表为空，订单号：{}", shopOrder.getOrderNo());
        return;
    }

    List<ShopOrderGoods> orderGoodsList = new ArrayList<>();
    for (OrderCreateRequest.OrderGoodsItem item : request.getGoodsItems()) {
        // 获取商品信息
        ShopGoods goods = shopGoodsService.getById(item.getGoodsId());
        if (goods == null) {
            throw new BusinessException("商品不存在，商品ID：" + item.getGoodsId());
        }
        
        ShopOrderGoods orderGoods = new ShopOrderGoods();
        
        // 设置订单关联信息
        orderGoods.setOrderId(shopOrder.getOrderId());
        orderGoods.setOrderCode(shopOrder.getOrderNo());
        
        // 设置商户信息
        orderGoods.setMerchantId(shopOrder.getMerchantId());
        orderGoods.setMerchantName(shopOrder.getMerchantName());
        
        // 设置商品信息
        orderGoods.setGoodsId(item.getGoodsId());
        orderGoods.setGoodsName(goods.getName());
        orderGoods.setImage(goods.getImage());
        orderGoods.setPrice(goods.getPrice());
        orderGoods.setTotalNum(item.getQuantity());
        
        // 设置支付相关信息
        orderGoods.setPayStatus(0); // 0 未付款
        orderGoods.setOrderStatus(0); // 0 未使用
        orderGoods.setIsFree(false); // 默认收费
        orderGoods.setVersion(0); // 当前版本
        
        // 设置其他信息
        orderGoods.setComments(request.getComments());
        orderGoods.setUserId(shopOrder.getUserId());
        orderGoods.setTenantId(shopOrder.getTenantId());
        
        orderGoodsList.add(orderGoods);
    }

    // 批量保存订单商品
    boolean saved = shopOrderGoodsService.saveBatch(orderGoodsList);
    if (!saved) {
        throw new BusinessException("保存订单商品失败");
    }
    
    log.info("成功保存订单商品，订单号：{}，商品数量：{}", shopOrder.getOrderNo(), orderGoodsList.size());
}
```

## 功能特性

### 1. 数据验证
- 商品ID不能为空
- 商品数量必须大于0
- 订单商品列表不能为空

### 2. 商品信息自动填充
- 自动从商品表获取商品名称、图片、价格等信息
- 验证商品是否存在

### 3. 状态管理
- 默认设置为未付款状态（payStatus = 0）
- 默认设置为未使用状态（orderStatus = 0）
- 默认设置为收费商品（isFree = false）

### 4. 事务支持
- 整个订单创建过程在同一个事务中
- 如果保存订单商品失败，整个订单创建会回滚

## 使用示例

### 单商品订单
```json
{
  "goodsItems": [
    {
      "goodsId": 10018,
      "quantity": 1,
      "payType": 1
    }
  ],
  "type": 0,
  "totalPrice": 99.00,
  "payPrice": 99.00,
  "totalNum": 1,
  "payType": 1,
  "tenantId": 1,
  "comments": "科技小王子大米年卡套餐2.5kg"
}
```

### 多商品订单
```json
{
  "goodsItems": [
    {
      "goodsId": 10018,
      "quantity": 1,
      "payType": 1
    },
    {
      "goodsId": 10019,
      "quantity": 2,
      "payType": 1
    }
  ],
  "type": 0,
  "totalPrice": 297.00,
  "payPrice": 297.00,
  "totalNum": 3,
  "payType": 1,
  "tenantId": 1,
  "comments": "多商品订单"
}
```

## 测试建议

1. **单元测试**: 已创建 `OrderBusinessServiceTest` 测试类，包含单商品和多商品订单的测试用例
2. **集成测试**: 建议使用 Postman 或类似工具测试完整的订单创建流程
3. **数据验证**: 测试各种边界情况，如商品不存在、数量为0等

## 注意事项

1. 确保商品表中存在对应的商品记录
2. 前端需要正确计算订单总金额和总数量
3. 支付类型字段在订单商品表中暂未使用，但保留了接口兼容性
4. 建议在生产环境部署前进行充分测试

## 后续优化建议

1. 添加库存检查和扣减逻辑
2. 支持商品规格（SKU）选择
3. 添加商品价格变动检查
4. 支持优惠券和折扣计算
