# Store 前台购物闭环审查报告

**审查时间**：2026-05-09
**审查范围**：前端商城前台（不含 admin 管理后台）
**后端 API**：http://192.168.50.139:8000/api

---

## 一、验证结果汇总

| 检查项 | 状态 | 说明 |
|--------|------|------|
| `NUXT_PUBLIC_USE_MOCK=false` | ✅ PASS | `.env` 和 `.env.production` 均设为 `false` |
| API 请求统一走 `useApi` | ✅ PASS | useApi.ts 结构清晰，非硬编码 URL |
| 商品列表使用真实 `/store/products` | ✅ PASS | `getProducts()` 正确调用后端 |
| 商品详情支持 SKU 选择 | ⚠️ 部分通过 | UI 有规格选择，但规格数据为硬编码 mock，非 API 获取 |
| 购物车 payload（product_id + variant_id + qty） | ⚠️ 部分通过 | 字段结构正确，但 `variant_id` 始终为 `null`（规格数据未从 API 获取） |
| 结算（preview + create）带 Authorization | ✅ PASS | `$fetch` 调用均正确附加 `Authorization: Bearer {token}` |
| 会员中心展示真实订单 | ✅ PASS | `/store/orders` 和 `/store/orders/{order_no}` 均正常 |

---

## 二、详细问题分析

### 问题 1：商品详情页规格数据为硬编码（高优先级）

**文件**：`pages/products/[slug].vue`

**问题**：商品规格选择器（颜色/尺码）的选项是写死的 mock 数据，而非从 API `product.variants` 获取：

```typescript
// 硬编码的 mock 数据
const specs = [
  { name: '颜色', options: ['黑色', '白色', '深蓝', '卡其'] },
  { name: '尺码', options: ['S', 'M', 'L', 'XL', 'XXL'] },
]
```

后端返回的 `variants` 数组完全未被使用。由于当前后端商品 `variants: []` 为空，此问题暂未影响用户（系统尚未配置 SKU），但 SKU 上线后必须修复。

---

### 问题 2：`variant_id` 始终为 `null`（高优先级）

**根因**：ProductCard 的 `addToCart` 和 `[slug].vue` 的 `addToCart` 在调用 `cartStore.addItem` 时，都没有传递 `variant_id`。

即使 SKU 系统上线，规格选择产生的 `variant_id` 也没有被传入 cart store。

**影响**：结算时 `variant_id` 始终为 `null`，后端无法知道用户选择了哪个 SKU。

当前 `addToCart` 代码（`[slug].vue`）:
```typescript
function addToCart() {
  if (!product.value) return
  cartStore.addItem({
    id:        product.value.id,
    name:      product.value.name,
    slug:      product.value.slug,
    cover_url: product.value.cover_url,
    base_price: product.value.base_price,
    // variant_id 和 variant 缺失！
  }, qty.value)
  cartStore.drawerOpen = true
}
```

结算页 payload（`checkout/index.vue`）:
```typescript
items: cartStore.items.map(i => ({
  product_id: i.id,
  qty:        i.qty,
  variant:    i.variant || null,
  variant_id: null,   // ← 永远是 null
})),
```

---

### 问题 3：后端返回商品缺少 `original_price`（中优先级）

**实际 API 响应**：
```json
{
  "base_price": "299.00",   // ← string 类型，不是 number
  "market_price": null,
  "cover_url": null          // ← 大量商品 cover_url 为 null
}
```

`original_price` 字段不存在于 API 响应中（前端依赖它显示划线价）。同时 `base_price` 是字符串而非数字，模板中虽用了 `Number()` 转换，但可能有精度问题。

---

### 问题 4：商品图片展示（全为 null）

**现象**：API 返回的 `cover_url` 大量为 `null`，`images` 为空数组。

**当前表现**：ProductCard 正确显示了占位图标（`ImageIcon` 组件），不会崩溃，但所有商品卡片都显示灰色占位符而非真实图片。

这是**数据问题**而非代码问题，后端商品主图未上传导致，前端无需修改。

---

## 三、需要修复的问题汇总

### 🔴 必须修复（购物闭环核心）

**1. 商品详情页 — 支持真实 SKU/规格选择**

当后端 `product.variants` 有数据时，应：
- 用 `product.variants` 渲染规格选项（而非硬编码 mock）
- 用户选择规格后，确定对应的 `variant_id`
- `addToCart` 时传入 `variant_id` 和 `variant` 描述字符串

**2. 购物车 — 添加 `variant_id` 到 item**

修改 `[slug].vue` 的 `addToCart`：
```typescript
cartStore.addItem({
  id: product.value.id,
  name: product.value.name,
  slug: product.value.slug,
  cover_url: product.value.cover_url,
  base_price: product.value.base_price,
  variant_id: selectedVariantId,   // ← 新增
  variant: selectedVariantString, // ← 新增
}, qty.value)
```

**3. 结算页 — 传递真实 `variant_id`**

```typescript
items: cartStore.items.map(i => ({
  product_id: i.id,
  qty:        i.qty,
  variant:    i.variant || null,
  variant_id: i.variant_id ?? null,  // ← 从 cart item 读取
})),
```

### 🟡 建议优化（非阻断）

**4. 后端商品补充图片数据**：`cover_url` 为 null 的问题需要后端处理，前端暂无修复必要。

**5. 价格字段类型**：后端 `base_price` 是字符串，建议后端改为 number，或前端统一做 `parseFloat` 转换。

---

## 四、已通过验证的功能

- ✅ 环境变量 `NUXT_PUBLIC_USE_MOCK=false` 配置正确
- ✅ `useApi.ts` 统一封装所有 API 请求，包含 Authorization header
- ✅ 商品列表页调用 `/store/products` 真实 API，分页/搜索/排序正常
- ✅ 商品详情页正确展示商品信息（名称/价格/评分/销量/SEO meta/JSON-LD）
- ✅ 评价功能正确调用 `/store/reviews` 接口（含分页/筛选）
- ✅ 登录 `POST /store/auth/login`、注册 `POST /store/auth/register` 正常工作
- ✅ 会员中心订单列表 `/store/orders` 和订单详情 `/store/orders/{order_no}` 正确
- ✅ 收货地址管理 `/store/addresses` 正确
- ✅ 结算页预览 `POST /store/orders/preview` 和创建订单 `POST /store/orders` 带 Authorization
- ✅ 优惠券验证 `POST /store/coupons/validate` 正确

---

## 五、购物闭环完整性评估

**整体评估**：前端购物闭环基本完整，核心流程（浏览→加购→结算→订单）均已对接真实 API。

**SKU 规格选择** 是最关键的待完成项，一旦后端商品配置了 SKU，前端需要能够：
1. 从 `product.variants` 渲染可选规格
2. 根据用户选择的规格组合匹配到 `variant_id`
3. 将 `variant_id` 传递到购物车和结算 payload