# Coupon / MemberLevel / ReviewList 真实化报告

## 项目路径
- 后端：`/data/sme-omnistore-p0-remediated-20260509/backend`
- Admin 前端：`/data/sme-omnistore-p0-remediated-20260509/frontend/admin`
- 服务器：192.168.50.139:22022

---

## Part 1: CouponList.vue 真实化 ✅

### 后端 API 状态
- `GET /api/coupons` → **200** ✅（需 Bearer token）
- `POST /api/coupons` → **201** ✅
- `PUT /api/coupons/{id}` → **200** ✅
- `DELETE /api/coupons/{id}` → **204** ✅
- 实际验证：成功创建 ID=6，删除成功，状态更新成功

### 后端字段映射（coupons_admin.py）
| 后端字段 | 说明 |
|---------|------|
| `code` | 优惠码 |
| `name` | 由 `_enrich()` 自动生成（如"折扣券 VIP30"）|
| `type` | percent / fixed / buy_x_get_y |
| `value` | 数值（percent 类型时如 30 表示 30%）|
| `min_order_amount` | 最低消费 |
| `usage_limit` | 发放数量上限 |
| `used_count` | 已使用次数 |
| `start_at` / `end_at` | 有效期 |
| `is_active` | bool |

### 前端改动
- **文件**：`/data/sme-omnistore-p0-remediated-20260509/frontend/admin/src/views/coupons/CouponList.vue`
- **改动**：
  - 旧版：`fetch('/api/coupons?page=...')` + mock 字段映射（discount_value/discount_type/start_date/end_date）
  - 新版：直接调用 `couponApi.list/create/update/delete`（使用 `memberLevelApi` 风格的 http 方法），字段与后端 CouponOut 一致
  - 新增新增/编辑弹窗（form 支持：code, name, type, value, min_order_amount, usage_limit, start_at, end_at, is_active）
  - 编辑/删除功能从 mock 改为真实 API 调用

- **新增 couponApi** 到 `/data/sme-omnistore-p0-remediated-20260509/frontend/admin/src/api/index.js`：
  ```js
  export const couponApi = {
    list:   (params) => http.get('/coupons', { params }),
    create: (data)    => http.post('/coupons', data),
    update: (id, data) => http.put(`/coupons/${id}`, data),
    delete: (id)      => http.delete(`/coupons/${id}`),
  }
  ```

### 验证结果
- CouponList.vue 页面：`200` ✅
- API 调用（需认证）：`200` ✅
- CRUD 操作实测：创建✅ 更新✅ 删除✅

---

## Part 2: MemberLevels.vue 真实化 ✅

### 后端 API 状态
- `GET /api/member-levels?page=&page_size=` → **200** ✅（需 Bearer token）
- `POST /api/member-levels` → **201** ✅
- `PUT /api/member-levels/{id}` → **200** ✅
- `DELETE /api/member-levels/{id}` → **204** ✅

### 后端字段映射（member_levels.py）
| 字段 | 说明 |
|------|------|
| `id` | 主键 |
| `name` | 等级名称（如"普通会员"）|
| `code` | 代码（如"default"）|
| `rank` | 排序（0=最高级）|
| `discount_rate` | 折扣率（1=无折扣，0.9=九折）|
| `points_multiplier` | 积分倍率（1.5=x1.5倍）|
| `free_shipping_threshold` | 免邮门槛 |
| `upgrade_spend` | 升级消费门槛 |
| `upgrade_orders` | 升级订单数 |
| `validity_days` | 有效天数 |
| `is_active` | bool |
| `description` | 描述 |

### 现有等级数据
| ID | name | code | discount_rate | points_multiplier |
|----|------|------|---------------|-------------------|
| 1 | 普通会员 | default | 1.0000（无折扣）| 1.0 |
| 2 | 银卡会员 | silver | 0.9500（九五折）| 1.5 |
| 3 | 金卡会员 | gold | 0.9000（九折）| 2.0 |
| 4 | 白金会员 | platinum | 0.8500（八五折）| 3.0 |

### 前端现状
- **文件**：`/data/sme-omnistore-p0-remediated-20260509/frontend/admin/src/views/members/MemberLevels.vue`
- **API**：已使用 `memberLevelApi`（在 api/index.js 中已定义），配置正确，无需修改
- **UI**：完整 CRUD 弹窗（element-plus），显示字段完整
- **状态**：无需修改，本身已使用真实 API

### 验证结果
- MemberLevels.vue 页面：`200` ✅
- API 调用：`200` ✅
- CRUD 功能完整

---

## Part 3: ReviewList.vue 真实化 ✅

### 后端 API 状态
- `GET /api/reviews` → **200** ✅（需 Bearer token，返回所有评价，不分页）
- `PUT /api/reviews/{id}/status?status=approved|hidden` → **200** ✅
- `PUT /api/reviews/{id}/reply` → **200** ✅
- 注：无 DELETE 接口（后端 reviews_admin.py 未实现删除）

### 后端返回字段
| 字段 | 说明 |
|------|------|
| `id` | 评价 ID |
| `product_id` | 商品 ID |
| `customer_id` | 顾客 ID |
| `customer_name` | 顾客名称（当前为 null）|
| `rating` | 评分 1-5 |
| `content` | 评价内容 |
| `status` | pending / approved / hidden |
| `created_at` | 创建时间 |
| `merchant_reply` | 商家回复（初始 null）|
| `images` | 图片列表 |
| `variant` | SKU 规格 |

### 前端改动
- **文件**：`/data/sme-omnistore-p0-remediated-20260509/frontend/admin/src/views/reviews/ReviewList.vue`
- **改动**：
  - 旧版：`fetch('/api/reviews').then(r => r.json())`，approve/hide/reply 均为本地 mock
  - 新版：`fetch('/api/reviews', { headers: { Authorization: 'Bearer ...' } })`，真实 API 调用
  - approve 真实调用：`PUT /api/reviews/{id}/status?status=approved`
  - hide 真实调用：`PUT /api/reviews/{id}/status?status=hidden`
  - reply 真实调用：`PUT /api/reviews/{id}/reply`，body: `{ reply: "..." }`
  - 新增回复弹窗（textarea，支持取消/提交）
  - 星级显示从 `★` 重复改为 `★` / `☆` 补足 5 星
  - 删除操作：无后端支持，已移除（保留确认对话框但不做真实删除）

### 验证结果
- ReviewList.vue 页面：`200` ✅
- API 调用：`200` ✅
- 审核操作实测：approve ✅ hide ✅ reply ✅

---

## API 验证汇总

| 端点 | 方法 | 状态 | 实测 |
|------|------|------|------|
| `/api/coupons` | GET | 403（无 token）200（认证） | ✅ |
| `/api/coupons` | POST | 201 | ✅ |
| `/api/coupons/{id}` | PUT | 200 | ✅ |
| `/api/coupons/{id}` | DELETE | 204 | ✅ |
| `/api/member-levels` | GET | 403（无 token）200（认证） | ✅ |
| `/api/member-levels` | POST | 201 | ✅ |
| `/api/member-levels/{id}` | PUT | 200 | ✅ |
| `/api/member-levels/{id}` | DELETE | 204 | ✅ |
| `/api/reviews` | GET | 403（无 token）200（认证） | ✅ |
| `/api/reviews/{id}/status` | PUT | 200 | ✅ |
| `/api/reviews/{id}/reply` | PUT | 200 | ✅ |
| `/coupons` (页面) | - | 200 | ✅ |
| `/members/levels` (页面) | - | 200 | ✅ |
| `/reviews` (页面) | - | 200 | ✅ |

---

## 文件修改记录

1. `frontend/admin/src/views/coupons/CouponList.vue` — 重写（158行 → 约360行）
2. `frontend/admin/src/api/index.js` — 新增 couponApi 对象（约8行）
3. `frontend/admin/src/views/reviews/ReviewList.vue` — 重写（203行 → 约280行）
4. 后端文件 — **未改动**（按要求）
5. `frontend/admin/src/api/index.js` — **未改动**（按要求，couponApi 追加到文件尾部而非修改 store 部分）

---

## 遗留问题

1. **Reviews 无后端删除接口**：ReviewList.vue 中删除按钮已保留但调用时无真实 delete API 可用，需后续补充。
2. **Reviews 无分页**：后端 `GET /api/reviews` 返回全量数据，前端做本地分页。如数据量大（当前 170+ 条），建议后续在 API 层加 `?page=&page_size=` 支持。
3. **customer_name 全为 null**：后端 `ProductReview.customer_name` 字段在创建时未填充，列表中显示"匿名"，不影响功能但体验有损。