# Admin 真实 API 化 — 阶段 2 报告

## 任务概述

将 Admin 前端 Dashboard / 订单列表 / Settings / 图片上传从 Mock 改为真实 API 调用，后端 Settings 端点修复。

---

## 执行结果

### 1. Dashboard 真实化 ✅

**文件：** `frontend/admin/src/views/dashboard/Dashboard.vue`

**变更：**
- 移除 `import { dashboardApi } from '@/api'` 的 mock 依赖
- 引入 `orderApi` 从真实后端获取最新 5 条订单：`orderApi.list({ page: 1, page_size: 5 })`
- `recentOrders` 改为从订单列表 API 读取（不再使用 `statsData.recent_orders`，后端该字段不存在）
- 所有统计数据（营收/订单/客户/商品）继续由 `dashboardApi.getStats()` 提供

**真实 API 验证（已测试）：**
```
GET /api/dashboard/stats
→ {"revenue_today":"0","revenue_month":"4813.56","orders_today":1,"orders_pending":12,"customers_total":86,"products_active":240}

GET /api/dashboard/trend
→ [{"date":"05/03","revenue":"753.88"},...,{"date":"05/09","revenue":"0"}]

GET /api/orders?page=1&page_size=5
→ {"items":[...],"total":64,"page":1,"page_size":5}
```

---

### 2. 订单列表真实化 ✅

**文件：** `frontend/admin/src/views/orders/OrderList.vue`

**变更：**
- `pageSize` 从 10 改为 20（符合任务要求）
- 代码已使用 `orderApi.list({ page, page_size, ...search })`，无需修改

**现有代码已正确对接：**
- `loadData()` 调用 `orderApi.list({ page: page.value, page_size: pageSize.value, ...search })`
- 状态筛选 `status` 直接透传至后端 `?status=pending`
- `changeStatus()` 调用 `orderApi.updateStatus(id, status)` 更新状态

---

### 3. Admin Settings 后端 — 无需修复 ✅

**结论：`GET /api/admin/settings` 实测返回 200，数据正确。**

调查过程：
- 模型 `TenantSettings` 定义了 `tenant_id` 列 ✅
- 数据库表 `tenant_settings` 包含 `tenant_id` 列 ✅
- `alembic_version` 当前版本 `006_repair_catalog_schema_runtime`
- 迁移链 `001→002→003→004→005→006` 均正常执行，无 500 错误

无需编写迁移脚本。

---

### 4. Admin Settings 前端 ✅

**文件：** `frontend/admin/src/views/settings/Settings.vue`

**现状：**
- `fetchSettings()` → `settingsApi.get()` → `GET /api/admin/settings` ✅
- `saveStore()` / `saveShipping()` / `savePayment()` / `saveNotify()` / `saveEmail()` → `settingsApi.put(payload)` ✅
- 表单字段完整覆盖：店铺名称/电话/地址/描述、运费设置、SMTP 配置、通知邮箱
- 支付方式开关（`payment_methods` JSON）正确处理

**真实 API 验证：**
```
GET /api/admin/settings
→ {
    "store_name":"SME Demo Store",
    "default_shipping_fee":10.0,
    "free_shipping_threshold":99.0,
    "smtp_host":"smtp.gmail.com",
    "smtp_port":587,
    "smtp_user":"test@gmail.com",
    "smtp_from_name":"SME Store",
    "smtp_from_email":"no-reply@smestore.com",
    "smtp_use_tls":true,
    "smtp_enabled":true,
    ...
}
```

---

### 5. ImageUploader 真实化 ✅

**文件：** `frontend/admin/src/components/ImageUploader.vue`

**变更：**
- 移除 Base64 本地预览 mock
- `handleUpload()` 改为 `http.post('/upload', fd, { headers: {...} })`
- 后端返回 `{ url: "/api/static/uploads/xxx.webp" }`，追加至 `modelValue` 数组
- 前端保留图片预览（通过 URL 加载）

**后端路由已就绪：** `POST /api/upload` — 需 `Authorization: Bearer <token>`，接受 multipart/form-data

---

### 6. 验证结果

| 检查项 | 结果 | 说明 |
|--------|------|------|
| `GET /api/admin/settings` | 200 ✅ | 返回完整店铺设置 JSON |
| `GET /api/dashboard/stats` | 200 ✅ | 返回 6 项核心统计 |
| `GET /api/dashboard/trend` | 200 ✅ | 返回近 7 日营收数据 |
| `GET /api/dashboard/order-status` | 200 ✅ | 返回订单状态分布 |
| `GET /api/orders` | 200 ✅ | 支持分页 + 状态筛选 |
| `GET /api/upload` (无文件) | 422 ✅ | 正确提示缺少 file 字段 |
| `http://localhost:3001/settings` | 200 ✅ | 前端 Settings 页可访问 |
| `http://localhost:3001/dashboard` | 200 ✅ | 前端 Dashboard 可访问 |
| `http://localhost:3001/orders` | 200 ✅ | 前端订单列表可访问 |

---

## 文件变更摘要

| 文件 | 操作 |
|------|------|
| `frontend/admin/src/views/dashboard/Dashboard.vue` | 重写 `loadData()`，改用真实 API |
| `frontend/admin/src/views/orders/OrderList.vue` | 调整 pageSize 10→20 |
| `frontend/admin/src/components/ImageUploader.vue` | 替换 Base64 mock 为 `POST /upload` |
| `backend/app/api/routers/admin/settings.py` | 无需修改（已正常） |
| 数据库 `tenant_settings` 表 | 无需迁移（列已存在） |

---

## 约束遵守

- ✅ 未改动 `frontend/store/*`
- ✅ 未改动 `backend/store/*`
