# 甲辰藏品管理系统 - 测试环境部署手册

**版本**: v2.7.9  
**创建时间**: 2026-03-15  
**创建人**: 菜鸟小 D (开发程序员助理)  
**文档状态**: ✅ 完整可用  
**最后更新**: 2026-03-15 (实地检查后更新)

---

## ⚠️ 重要说明

### 🎯 v2.7.9 标准技术栈

**本文档描述的是甲辰藏品管理系统 v2.7.9 的标准部署方案。**

| 组件 | v2.7.9 技术栈 |
|------|-------------|
| **前端** | React 18 + Vite 6 + Tailwind CSS |
| **后端** | FastAPI 0.109 + Python 3.12 |
| **数据库** | PostgreSQL 13+ |
| **ORM** | SQLAlchemy 2.0 + Alembic |
| **认证** | JWT (python-jose) |
| **Web 服务器** | Nginx 1.20+ |
| **监控** | Prometheus (可选) |

### 📦 v2.7.9 核心依赖

**后端 (backend-fastapi/requirements.txt)**:
```
fastapi==0.109.0
uvicorn[standard]==0.27.0
sqlalchemy==2.0.25
asyncpg==0.29.0
python-jose[cryptography]==3.3.0
passlib[bcrypt]==1.7.4
pydantic==2.5.3
```

**前端 (zodiac-mobile/package.json)**:
```
react@18
vite@6
tailwindcss@3
```

---

### ⚠️ 测试环境现状（2026-03-15 检查）

**当前测试环境与 v2.7.9 标准不符！**

| 项目 | v2.7.9 标准 | 测试环境现状 | 状态 |
|------|-----------|------------|------|
| 后端框架 | FastAPI + Python | Node.js + Express | ❌ 不符 |
| ORM | SQLAlchemy | Prisma | ❌ 不符 |
| 数据库 | PostgreSQL | PostgreSQL | ✅ 符合 |
| 前端 | React + Vite | React + Vite | ✅ 符合 |

**需要重新部署测试环境以匹配 v2.7.9 标准！**

---

## 更新日志

| 版本 | 日期 | 更新人 | 更新内容 |
|------|------|--------|---------|
| v1.2 | 2026-03-15 | 菜鸟小 D | 添加详细版本要求和关键注意事项 |
| v1.2.4 | 2026-03-20 | 甲辰生产 | 修复OCR扩展名大小写问题、修复用户协议乱码、添加返回按钮 |
| v1.1 | 2026-03-15 | 菜鸟小 D | 根据实地检查更新实际配置 |
| v1.0 | 2026-03-15 | 菜鸟小 D | 初始版本 |

---

## 🔧 系统要求（v2.7.9 标准）

### ⚙️ 操作系统要求

| 服务器 | 操作系统 | 版本要求 |
|--------|---------|---------|
| 菜鸟测试 1 | Alibaba Cloud Linux | 3.x (OpenAnolis) |
| 菜鸟测试 2 | Alibaba Cloud Linux | 3.x (OpenAnolis) |

**替代方案**: CentOS 7+ / Ubuntu 20.04+ / Rocky Linux 8+

---

### 🖥️ 服务器配置要求

| 服务器 | CPU | 内存 | 磁盘 | 用途 |
|--------|-----|------|------|------|
| 菜鸟测试 1 | 2 核 + | 4GB+ | 40GB+ | Nginx + Prometheus + 前端 |
| 菜鸟测试 2 | 4 核 + | 8GB+ | 50GB+ SSD | FastAPI 后端 + PostgreSQL |

---

### 📦 前端技术栈（v2.7.9）

| 组件 | 版本 | 说明 |
|------|------|------|
| **React** | 18.x | UI 框架 |
| **Vite** | 6.x | 构建工具 |
| **Tailwind CSS** | 3.x | CSS 框架 |
| **Node.js** | 18.x+ | 运行时环境 |
| **npm** | 9.x+ | 包管理器 |

**构建命令**:
```bash
cd zodiac-mobile
npm install
npm run build
```

**部署路径**: `/var/www/mobile/dist`

---

### 🐍 后端技术栈（v2.7.9）

| 组件 | 版本 | 说明 |
|------|------|------|
| **FastAPI** | 0.109.0 | Web 框架 |
| **Python** | 3.12.x | 运行时环境 |
| **Uvicorn** | 0.27.0 | ASGI 服务器 |
| **SQLAlchemy** | 2.0.25 | ORM 框架 |
| **Alembic** | 1.13.1 | 数据库迁移 |
| **Pydantic** | 2.5.3 | 数据验证 |
| **python-jose** | 3.3.0 | JWT 认证 |
| **passlib** | 1.7.4 | 密码加密 |
| **asyncpg** | 0.29.0 | PostgreSQL 驱动 |

**完整依赖** (`backend-fastapi/requirements.txt`):
```
fastapi==0.109.0
uvicorn[standard]==0.27.0
sqlalchemy==2.0.25
asyncpg==0.29.0
python-jose[cryptography]==3.3.0
passlib[bcrypt]==1.7.4
python-multipart==0.0.6
pydantic==2.5.3
pydantic[email]==2.5.3
python-dotenv==1.0.0
alembic==1.13.1
requests
```

**安装命令**:
```bash
pip3.12 install -r requirements.txt
```

**启动命令**:
```bash
uvicorn app.main:app --port 3000 --host 0.0.0.0
```

---

### 🗄️ 数据库要求

| 组件 | 版本 | 说明 |
|------|------|------|
| **PostgreSQL** | 13.x+ | 关系型数据库 |
| **psql** | 13.x+ | 命令行工具 |

**数据库配置**:
```
数据库名：zodiac
用户名：postgres
密码：postgres (生产环境请使用强密码)
端口：5432
```

---

### 🌐 Web 服务器要求

| 组件 | 版本 | 说明 |
|------|------|------|
| **Nginx** | 1.20.x+ | Web 服务器/反向代理 |

**Nginx 配置要求**:
- 监听端口：3001 (前端)
- API 代理：/api → http://127.0.0.1:3000/api
- 文件上传限制：20MB (**必须配置 client_max_body_size**)
- SPA 路由支持：try_files

**Nginx 配置示例** (`/etc/nginx/conf.d/zodiac.conf`):
```nginx
server {
    listen 3001;
    server_name _;
    
    root /var/www/mobile/dist;
    index index.html;
    
    # ⚠️ 必须配置：允许上传最大 20MB 的文件
    client_max_body_size 20M;
    
    location / {
        try_files $uri $uri/ /index.html;
    }
    
    location /api {
        proxy_pass http://127.0.0.1:3000/api;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        
        # ⚠️ API 上传也要配置限制
        client_max_body_size 20M;
    }
}
```

**⚠️ 重要**: 如果不配置 `client_max_body_size`，Nginx 默认限制为 **1MB**，会导致图片上传失败！

---

### 🔧 其他工具要求

| 工具 | 版本 | 用途 |
|------|------|------|
| **Git** | 2.x+ | 版本控制 |
| **systemd** | 最新 | 服务管理 |
| **firewalld** | 最新 | 防火墙管理 |
| **Prometheus** | 2.45.x+ | 监控（可选） |

---

## 🚨 部署注意事项（必读）

### ⚠️ 部署前必须完成的配置

#### 1. 阿里云 OCR API Key 配置

**获取 API Key**:
```
1. 访问：https://dashscope.console.aliyun.com/apiKey
2. 登录阿里云账号
3. 创建/复制 API Key
4. 更新 .env 配置
```

**编辑 .env 文件**:
```bash
cd /opt/zodiac/backend/backend-fastapi
vi .env
```

**.env 内容**:
```ini
# ⚠️ 必须配置：阿里云 DashScope OCR API
# ⚠️ 注意：不要使用示例 Key，必须替换为您自己的
DASHSCOPE_API_KEY=sk-your-actual-api-key-here

# OCR 配置
OCR_MODEL=qwen-vl-max
OCR_TIMEOUT=60
```

**验证 API Key**:
```bash
curl -X POST https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions \
  -H "Authorization: Bearer sk-your-actual-api-key-here" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "qwen-vl-max",
    "input": {
      "messages": [{
        "role": "user",
        "content": [{"type": "text", "text": "你好"}]
      }]
    }
  }'

# 成功：{"output": {"choices": [...]}}
# 失败：{"error": {"message": "..."}}
```

---

#### 2. Nginx 图片上传限制

**⚠️ 必须配置**，否则会导致：
- 图片上传失败（413 错误）
- OCR 识别失败（图片太大）
- 前端收到 HTML 错误页面而不是 JSON

**编辑 Nginx 配置**:
```bash
sudo vi /etc/nginx/conf.d/zodiac.conf
```

**添加配置**:
```nginx
server {
    listen 3001;
    
    # ⚠️ 必须配置：允许上传 20MB 文件
    client_max_body_size 20M;
    
    location /api {
        proxy_pass http://127.0.0.1:3000/api;
        
        # ⚠️ API 上传也要配置
        client_max_body_size 20M;
    }
}
```

**重启服务**:
```bash
sudo nginx -t && sudo nginx -s reload
sudo systemctl restart zodiac-backend
```

---

## ⚠️ 关键注意事项

### 1. 测试环境必须完全按照 v2.7.9 标准

**当前测试环境问题** (2026-03-15 检查):

| 组件 | v2.7.9 标准 | 测试环境现状 | 状态 |
|------|-----------|------------|------|
| **后端框架** | FastAPI 0.109 + Python 3.12 | Node.js + Express | ❌ **严重不符** |
| **ORM** | SQLAlchemy 2.0 | Prisma | ❌ **严重不符** |
| **数据库** | PostgreSQL 13 | PostgreSQL 13 | ✅ 符合 |
| **前端** | React 18 + Vite 6 | React 18 + Vite 6 | ✅ 符合 |
| **操作系统** | Alibaba Cloud Linux 3 | Alibaba Cloud Linux 3 | ✅ 符合 |

**结论**: 测试环境后端需要**完全重新部署**，使用 FastAPI 替代 Node.js！

---

### 2. 版本兼容性要求

- ❌ **不能使用** Node.js 后端（测试环境当前版本）
- ❌ **不能使用** Prisma ORM
- ✅ **必须使用** FastAPI 0.109.0
- ✅ **必须使用** SQLAlchemy 2.0.25
- ✅ **必须使用** Python 3.12.x

---

### 3. 部署顺序

```
1. 准备服务器 (Alibaba Cloud Linux 3)
   ↓
2. 安装系统依赖 (Python 3.12, PostgreSQL 13, Nginx 1.20)
   ↓
3. 配置数据库 (创建 zodiac 数据库)
   ↓
4. 部署后端 (FastAPI + SQLAlchemy)
   ↓
5. 部署前端 (React + Vite 构建)
   ↓
6. 配置 Nginx (反向代理)
   ↓
7. 验证测试 (功能测试清单)
```

---

### 4. 重要提醒

⚠️ **测试环境是用于验证 v2.7.9 版本的环境，必须与生产环境保持一致！**

- ✅ 所有软件版本必须与 v2.7.9 要求一致
- ✅ 所有配置必须按照本文档说明
- ✅ 所有功能必须通过测试清单验证
- ❌ 不能使用旧版本技术栈（如 Node.js 后端）

---

## 📋 目录

1. [环境概述](#环境概述)
2. [服务器信息](#服务器信息)
3. [部署前准备](#部署前准备)
4. [数据库服务器部署 (菜鸟测试 2)](#数据库服务器部署)
5. [应用服务器部署 (菜鸟测试 1)](#应用服务器部署)
6. [Nginx 配置](#nginx 配置)
7. [Prometheus 监控配置](#prometheus 监控配置)
8. [部署验证与测试](#部署验证与测试)
9. [常见问题与解决方案](#常见问题与解决方案)
10. [维护与监控](#维护与监控)

---

## 环境概述

### 架构设计

```
┌─────────────────┐         ┌─────────────────┐
│  菜鸟测试 1      │         │  菜鸟测试 2      │
│  47.103.29.111  │         │  47.103.9.192   │
├─────────────────┤         ├─────────────────┤
│ Nginx (3001)    │ ──────▶ │ FastAPI (3000)  │
│ Prometheus      │         │ PostgreSQL (5432)│
│ 前端静态文件     │         │ 数据库           │
└─────────────────┘         └─────────────────┘
         ▲
         │
    用户访问
    http://47.103.29.111:3001/
```

### 版本信息

| 组件 | 版本 | 说明 |
|------|------|------|
| 甲辰系统 | v2.7.9 | 综合功能增强版 |
| Git 分支 | `v2.7.9` | 稳定分支 |
| Git 标签 | `v2.7.9-release` | 发布标签 |

---

## 服务器信息

### 菜鸟测试 1 (应用服务器)

| 项目 | 信息 |
|------|------|
| **名称** | 菜鸟测试 1 |
| **IP 地址** | 47.103.29.111 |
| **用途** | Nginx + Prometheus 监控 + 前端静态文件 |
| **开放端口** | 3001 (前端), 9090 (Prometheus) |
| **系统** | CentOS 7+ / Ubuntu 20.04+ |

### 菜鸟测试 2 (数据库服务器)

| 项目 | 信息 |
|------|------|
| **名称** | 菜鸟测试 2 |
| **IP 地址** | 47.103.9.192 |
| **用途** | FastAPI 后端 + PostgreSQL 数据库 |
| **开放端口** | 3000 (后端 API), 5432 (PostgreSQL) |
| **系统** | CentOS 7+ / Ubuntu 20.04+ |

---

## 部署前准备

### 1. 系统要求

#### 菜鸟测试 1 (应用服务器)
- **CPU**: 2 核+
- **内存**: 4GB+
- **磁盘**: 20GB+
- **系统**: CentOS 7+ 或 Ubuntu 20.04+

#### 菜鸟测试 2 (数据库服务器)
- **CPU**: 4 核+
- **内存**: 8GB+
- **磁盘**: 50GB+ SSD
- **系统**: CentOS 7+ 或 Ubuntu 20.04+

### 2. 软件依赖

#### 菜鸟测试 1 需要安装
```bash
# Nginx
sudo yum install nginx -y  # CentOS
# 或
sudo apt install nginx -y  # Ubuntu

# Node.js 18+
curl -fsSL https://rpm.nodesource.com/setup_18.x | sudo bash -  # CentOS
sudo yum install -y nodejs

# Prometheus (可选)
wget https://github.com/prometheus/prometheus/releases/download/v2.45.0/prometheus-2.45.0.linux-amd64.tar.gz
tar xvfz prometheus-*.tar.gz
```

#### 菜鸟测试 2 需要安装
```bash
# Python 3.12
sudo yum install python3.12 -y  # CentOS
# 或
sudo apt install python3.12 -y  # Ubuntu

# PostgreSQL 13+
sudo yum install postgresql13-server postgresql13 -y  # CentOS
# 或
sudo apt install postgresql-13 -y  # Ubuntu

# Git
sudo yum install git -y
```

### 3. 网络配置

#### 开放端口
```bash
# 菜鸟测试 1
firewall-cmd --permanent --add-port=3001/tcp  # 前端
firewall-cmd --permanent --add-port=9090/tcp  # Prometheus
firewall-cmd --reload

# 菜鸟测试 2
firewall-cmd --permanent --add-port=3000/tcp  # 后端 API
firewall-cmd --permanent --add-port=5432/tcp  # PostgreSQL
firewall-cmd --reload
```

#### 安全组配置 (阿里云)
- 菜鸟测试 1: 开放 3001, 9090 端口
- 菜鸟测试 2: 开放 3000, 5432 端口 (建议限制访问 IP)

---

## 数据库服务器部署 (菜鸟测试 2)

### 1. PostgreSQL 配置

```bash
# 初始化数据库 (如未初始化)
sudo postgresql-setup --initdb  # CentOS
# 或
sudo pg_createcluster 13 main --start  # Ubuntu

# 启动 PostgreSQL
sudo systemctl start postgresql
sudo systemctl enable postgresql

# 创建数据库和用户
sudo -u postgres psql
```

```sql
-- 创建数据库
CREATE DATABASE zodiac;

-- 创建用户 (生产环境请使用强密码)
CREATE USER postgres WITH PASSWORD 'postgres' SUPERUSER;

-- 授权
GRANT ALL PRIVILEGES ON DATABASE zodiac TO postgres;

-- 退出
\q
```

### 2. 配置远程访问

```bash
# 编辑 pg_hba.conf
sudo vi /var/lib/pgsql/data/pg_hba.conf  # CentOS
# 或
sudo vi /etc/postgresql/13/main/pg_hba.conf  # Ubuntu

# 添加 (允许菜鸟测试 1 访问)
host    zodiac    postgres    47.103.29.111/32    md5
```

```bash
# 编辑 postgresql.conf
sudo vi /var/lib/pgsql/data/postgresql.conf

# 修改
listen_addresses = '*'
port = 5432
```

```bash
# 重启 PostgreSQL
sudo systemctl restart postgresql
```

### 3. 部署 FastAPI 后端

```bash
# 创建部署目录
sudo mkdir -p /opt/zodiac/backend
sudo chown -R $USER:$USER /opt/zodiac/backend

# 克隆代码
cd /opt/zodiac/backend
git clone http://47.253.189.47:3000/coolbot/zodiac-collector.git .
git checkout v2.7.9

# 安装 Python 依赖
cd backend-fastapi
pip3.12 install -r requirements.txt

# 创建环境变量文件
cat > .env << EOF
# 生产环境配置

# 数据库配置 (PostgreSQL)
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/zodiac

# JWT 配置 (生产环境请修改为强密钥)
SECRET_KEY=your-production-secret-key-change-this
ACCESS_TOKEN_EXPIRE_MINUTES=60

# 服务器配置
PORT=3000
HOST=0.0.0.0

# 阿里云 DashScope OCR API
# ⚠️ 注意：需要替换为您自己的 API Key
# 获取方式：https://dashscope.console.aliyun.com/apiKey
DASHSCOPE_API_KEY=sk-9389024a37da4f7bb455ac9a6b28776f

# OCR 配置
OCR_MODEL=qwen-vl-max
OCR_TIMEOUT=60

# 文件上传配置
UPLOAD_DIR=./uploads
MAX_UPLOAD_SIZE=10485760
EOF

# 创建上传目录
mkdir -p uploads
chmod 755 uploads
```

### 4. 创建系统服务

```bash
# 创建 systemd 服务文件
sudo vi /etc/systemd/system/zodiac-backend.service
```

```ini
[Unit]
Description=甲辰藏品管理系统后端服务
After=network.target postgresql.service

[Service]
Type=simple
User=postgres
WorkingDirectory=/opt/zodiac/backend/backend-fastapi
Environment="PATH=/usr/local/python3.12/bin:%PATH"
ExecStart=/usr/local/python3.12/bin/python3.12 -m uvicorn app.main:app --port 3000 --host 0.0.0.0
Restart=always
RestartSec=5

# 日志
StandardOutput=journal
StandardError=journal
SyslogIdentifier=zodiac-backend

[Install]
WantedBy=multi-user.target
```

```bash
# 启动服务
sudo systemctl daemon-reload
sudo systemctl start zodiac-backend
sudo systemctl enable zodiac-backend

# 查看状态
sudo systemctl status zodiac-backend
```

### 5. 验证后端服务

```bash
# 测试健康检查
curl http://localhost:3000/health

# 预期输出
{"status":"healthy"}
```

---

## 应用服务器部署 (菜鸟测试 1)

### 1. 部署前端

```bash
# 创建部署目录
sudo mkdir -p /var/www/mobile/dist
sudo chown -R nginx:nginx /var/www/mobile/dist

# 方法 1: 从开发环境复制
# 在开发环境执行:
cd /home/admin/.openclaw/workspace/zodiac-collector/zodiac-mobile
npm run build
# 打包后复制到测试服务器
scp -r dist/* root@47.103.29.111:/var/www/mobile/dist/

# 方法 2: 在测试服务器构建
cd /opt
git clone http://47.253.189.47:3000/coolbot/zodiac-collector.git
cd zodiac-collector/zodiac-mobile
npm install
npm run build
sudo cp -r dist/* /var/www/mobile/dist/
sudo chown -R nginx:nginx /var/www/mobile/dist/
```

### 2. Nginx 配置

```bash
# 创建 Nginx 配置文件
sudo vi /etc/nginx/conf.d/zodiac.conf
```

```nginx
types {
    application/javascript js;
    text/css css;
}

server {
    listen 3001;
    server_name _;
    
    root /var/www/mobile/dist;
    index index.html;
    
    # 允许上传最大 20MB 的文件
    client_max_body_size 20M;
    
    # 前端静态文件
    location / {
        try_files $uri $uri/ /index.html;
        
        # 缓存配置
        location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
            expires 1y;
            add_header Cache-Control "public, immutable";
        }
    }
    
    # API 代理到后端服务器
    location /api {
        proxy_pass http://47.103.9.192:3000/api;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        
        # 允许大文件上传
        client_max_body_size 20M;
        
        # 超时配置
        proxy_connect_timeout 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;
    }
    
    # 日志配置
    access_log /var/log/nginx/zodiac-access.log;
    error_log /var/log/nginx/zodiac-error.log;
}
```

```bash
# 测试 Nginx 配置
sudo nginx -t

# 启动 Nginx
sudo systemctl start nginx
sudo systemctl enable nginx

# 重载配置
sudo systemctl reload nginx
```

### 3. Prometheus 监控配置 (可选)

```bash
# 创建 Prometheus 目录
sudo mkdir -p /opt/prometheus
cd /opt/prometheus

# 下载并解压
wget https://github.com/prometheus/prometheus/releases/download/v2.45.0/prometheus-2.45.0.linux-amd64.tar.gz
tar xvfz prometheus-*.tar.gz
cd prometheus-2.45.0.linux-amd64

# 创建配置文件
cat > prometheus.yml << EOF
global:
  scrape_interval: 15s
  evaluation_interval: 15s

scrape_configs:
  - job_name: 'zodiac-backend'
    static_configs:
      - targets: ['47.103.9.192:3000']
    metrics_path: '/metrics'
    
  - job_name: 'nginx'
    static_configs:
      - targets: ['localhost:9113']  # nginx exporter
EOF

# 创建 systemd 服务
sudo vi /etc/systemd/system/prometheus.service
```

```ini
[Unit]
Description=Prometheus Monitoring
After=network.target

[Service]
Type=simple
User=prometheus
WorkingDirectory=/opt/prometheus/prometheus-2.45.0.linux-amd64
ExecStart=/opt/prometheus/prometheus-2.45.0.linux-amd64/prometheus --config.file=prometheus.yml
Restart=always

[Install]
WantedBy=multi-user.target
```

```bash
# 启动 Prometheus
sudo systemctl daemon-reload
sudo systemctl start prometheus
sudo systemctl enable prometheus
```

---

## 部署验证与测试

### 1. 基础服务检查

```bash
# 菜鸟测试 1
systemctl status nginx
systemctl status prometheus  # 如安装

# 菜鸟测试 2
systemctl status zodiac-backend
systemctl status postgresql

# 端口检查
netstat -tlnp | grep -E "3001|3000|5432|9090"
```

### 2. 数据库连接测试

```bash
# 在菜鸟测试 2 上
psql -U postgres -d zodiac -c "SELECT version();"

# 在菜鸟测试 1 上测试远程连接
psql -h 47.103.9.192 -U postgres -d zodiac -c "SELECT version();"
```

### 3. 后端 API 测试

```bash
# 健康检查
curl http://47.103.9.192:3000/health

# API 文档
curl http://47.103.9.192:3000/docs

# 登录测试
curl -X POST http://47.103.9.192:3000/api/auth/login \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "username=admin&password=admin123"
```

### 4. 前端访问测试

```bash
# 访问前端页面
curl http://47.103.29.111:3001/

# 应该返回 HTML 内容
```

### 5. 完整功能测试清单

| 功能 | 测试步骤 | 预期结果 |
|------|---------|---------|
| 登录 | 访问 http://47.103.29.111:3001/，使用 admin/admin123 登录 | ✅ 登录成功，跳转首页 |
| 注册 | 点击"注册新账号"，填写信息并提交 | ✅ 注册成功 |
| 藏品列表 | 查看藏品列表 | ✅ 显示藏品数据 |
| 添加藏品 | 手工录入一个藏品 | ✅ 保存成功，编码自动生成 |
| 图片上传 | 上传藏品图片 | ✅ 上传成功，显示图片 |
| 筛选功能 | 按状态/珍惜度等筛选 | ✅ 筛选条件显示中文 |
| 统计页面 | 查看统计分析 | ✅ 显示 8 个分布统计 |
| 用户管理 | 管理员添加/删除用户 | ✅ 功能正常 |

---

## 错误码与故障排查

### 📋 完整错误码列表

#### 认证错误 (E00010-E00019)

| 错误码 | 说明 | HTTP 状态 | 解决方案 |
|--------|------|----------|---------|
| **E00010** | 未登录或登录已过期 | 401 | 重新登录获取新 Token |
| **E00011** | 用户名或密码错误 | 401 | 检查用户名密码是否正确 |
| **E00012** | 验证码错误 | 400 | 刷新验证码后重试 |
| **E00014** | 无权访问此资源 | 403 | 检查用户权限（需管理员） |
| **E00015** | 令牌无效或已过期 | 401 | 清除本地存储，重新登录 |

#### 验证错误 (E00020-E00029)

| 错误码 | 说明 | HTTP 状态 | 解决方案 |
|--------|------|----------|---------|
| **E00020** | 请输入用户名和密码 | 400 | 填写完整的登录信息 |
| **E00021** | 用户名至少 3 个字符 | 400 | 用户名长度≥3 字符 |
| **E00022** | 密码至少 6 个字符 | 400 | 密码长度≥6 字符 |
| **E00023** | 用户名已存在 | 400 | 更换其他用户名 |
| **E00024** | 邮箱已被注册 | 400 | 更换其他邮箱 |

#### 藏品管理错误 (E00030-E00039)

| 错误码 | 说明 | HTTP 状态 | 解决方案 |
|--------|------|----------|---------|
| **E00030** | 藏品名称不能为空 | 400 | 填写藏品名称 |
| **E00031** | 藏品名称至少 2 个字符 | 400 | 名称长度≥2 字符 |
| **E00032** | 藏品分类不能为空 | 400 | 选择藏品分类 |
| **E00033** | 藏品不存在 | 404 | 检查藏品 ID 是否正确 |
| **E00034** | 禁止重复：此冠字号已存在 | 400 | 检查冠字号是否重复 |
| **E00035** | 成本价格必须>=0 | 400 | 价格不能为负数 |
| **E00036** | 目标价格必须>=0 | 400 | 价格不能为负数 |
| **E00037** | 发行年份必须是 4 位数字 | 400 | 年份格式：YYYY |

#### OCR 识别错误 (E00040-E00049)

| 错误码 | 说明 | HTTP 状态 | 解决方案 |
|--------|------|----------|---------|
| **E00040** | 请选择图片文件 | 400 | 上传正确的图片 |
| **E00041** | 图片尺寸太小，无法识别 | 400 | 上传更清晰的图片 |
| **E00042** | OCR 识别失败，请重试 | 500 | 重新上传或检查 API Key |

#### 用户管理错误 (E00050-E00059)

| 错误码 | 说明 | HTTP 状态 | 解决方案 |
|--------|------|----------|---------|
| **E00050** | 仅管理员可访问 | 403 | 需要管理员权限 |
| **E00051** | 用户不存在 | 404 | 检查用户 ID 是否正确 |
| **E00052** | 不能删除自己 | 400 | 不能删除当前登录用户 |

#### 通用错误 (E00000-E00009)

| 错误码 | 说明 | HTTP 状态 | 解决方案 |
|--------|------|----------|---------|
| **E00000** | 请求失败 | - | 检查请求参数 |
| **E00001** | 网络连接失败 | - | 检查网络连接 |
| **E00003** | 服务器内部错误 | 500 | 联系管理员查看日志 |

---

### 🔧 常见错误处理流程

#### 1. E00010: 未登录或登录已过期

**现象**: 访问任何需要登录的页面都提示 E00010

**原因**:
- Token 已过期（默认 60 分钟）
- Token 被篡改或无效
- 本地存储被清除

**解决方案**:
```javascript
// 浏览器控制台执行
localStorage.clear()
sessionStorage.clear()
// 然后刷新页面，重新登录
```

**预防措施**:
- 设置合理的 Token 有效期（建议 24 小时）
- 前端实现 Token 自动刷新机制

---

#### 2. E00011: 用户名或密码错误

**现象**: 登录时提示用户名或密码错误

**原因**:
- 用户名或密码输入错误
- 大小写问题
- 用户不存在

**解决方案**:
1. 检查用户名密码是否正确
2. 确认大小写（密码区分大小写）
3. 联系管理员确认账号是否存在

---

#### 3. E00033: 藏品不存在

**现象**: 访问藏品详情时提示藏品不存在

**原因**:
- 藏品 ID 错误
- 藏品已被删除
- 无权访问此藏品

**解决方案**:
1. 检查藏品 ID 是否正确
2. 确认藏品是否被删除
3. 确认是否有访问权限

---

#### 4. E00042: OCR 识别失败

**现象**: 上传图片识别时失败

**错误日志**:
```
OCR API 调用失败：{"error": {"message": "Invalid API Key", ...}}
OCR API 调用失败：{"error": {"message": "you must provide a messages parameter", ...}}
```

**原因**:
- 阿里云 API Key 配置错误/失效
- API 请求格式不正确（兼容模式 vs 原生模式）
- 图片格式不支持
- 图片质量太差
- API 余额不足

**解决方案**:

**1. 检查 API Key 配置**
```bash
# 检查后端 .env 配置
cat .env | grep DASHSCOPE_API_KEY

# 应该显示：
# DASHSCOPE_API_KEY=sk-xxxxxxxxxxxxxxxx
```

**2. 验证 API Key 有效性**
```bash
# 测试 API Key
curl -X POST https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions \
  -H "Authorization: Bearer sk-xxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "qwen-vl-max",
    "input": {
      "messages": [{
        "role": "user",
        "content": [{"type": "text", "text": "你好"}]
      }]
    }
  }'

# 成功返回：{"output": {"choices": [...]}}
# 失败返回：{"error": {"message": "..."}}
```

**3. 检查 API 请求格式**
```python
# ✅ 正确格式（2026 年兼容模式）
payload = {
    "model": "qwen-vl-max",
    "input": {
        "messages": [{
            "role": "user",
            "content": [
                {"type": "image", "image": "data:image/jpeg;base64,..."},
                {"type": "text", "text": "提示词"}
            ]
        }]
    },
    "parameters": {
        "max_tokens": 1000
    }
}

# ❌ 错误格式（旧版）
payload = {
    "model": "qwen-vl-max",
    "messages": [...]  # 缺少 input 包裹
}
```

**4. 获取新的 API Key**
```
1. 访问：https://dashscope.console.aliyun.com/apiKey
2. 登录阿里云账号
3. 创建/复制 API Key
4. 更新 .env 配置
5. 重启后端服务
```

**5. 检查 API 余额**
```
访问：https://dashscope.console.aliyun.com/overview
查看：剩余额度和用量
```

---

#### 5. E00050: 仅管理员可访问

**现象**: 访问用户管理页面时提示无权访问

**原因**:
- 当前用户不是管理员角色

**解决方案**:
1. 联系管理员提升权限
2. 使用管理员账号登录

---

#### 5.5. OCR 识别成功但字段未保存

**现象**: OCR 识别成功，但 11 个字段信息没有正确保存到表单

**原因**:
- 后端返回的字段名与前端期望不一致
- 字段映射错误
- 布尔值处理问题

**后端返回字段** (`data.fields`):
```json
{
  "issuer": "中国人民银行",
  "version": "2024 龙",
  "denomination": "贰拾圆",
  "prefix_serial": "J01234567",
  "packaging": "标十",
  "grading_company": "ACG",
  "grading_score": "68",
  "special_mark": "金山标",
  "serial_feature": "金山号 2 张",
  "is_graded": true,
  "three_star": false
}
```

**前端期望字段** (form 状态):
```javascript
{
  issuer: "中国人民银行",
  version: "2024 龙",
  denomination: "贰拾圆",
  prefixSerial: "J01234567",  // ⚠️ 驼峰命名
  packaging: "标十",
  gradingCompany: "ACG",      // ⚠️ 驼峰命名
  gradingScore: "68",         // ⚠️ 驼峰命名
  specialMark: "金山标",      // ⚠️ 驼峰命名
  serialFeature: "金山号 2 张", // ⚠️ 驼峰命名
  isGraded: true,             // ⚠️ 驼峰命名
  threeStar: false            // ⚠️ 驼峰命名
}
```

**解决方案**:

**前端修复** (`Add.jsx` 的 `handleRecognize`):
```javascript
if (data.fields) {
  const recognizedForm = { ...getDefaultForm() }
  
  // 下划线 → 驼峰 映射
  if (data.fields.issuer) recognizedForm.issuer = data.fields.issuer
  if (data.fields.version) recognizedForm.version = data.fields.version
  if (data.fields.denomination) recognizedForm.denomination = data.fields.denomination
  if (data.fields.prefix_serial) recognizedForm.prefixSerial = data.fields.prefix_serial  // ✅
  if (data.fields.packaging) recognizedForm.packaging = data.fields.packaging
  if (data.fields.grading_company) recognizedForm.gradingCompany = data.fields.grading_company  // ✅
  if (data.fields.grading_score) recognizedForm.gradingScore = data.fields.grading_score  // ✅
  if (data.fields.special_mark && data.fields.special_mark !== '无') recognizedForm.specialMark = data.fields.special_mark  // ✅
  if (data.fields.serial_feature && data.fields.serial_feature !== '无') recognizedForm.serialFeature = data.fields.serial_feature  // ✅
  
  // 布尔字段
  if (data.fields.is_graded !== undefined) recognizedForm.isGraded = data.fields.is_graded
  if (data.fields.three_star !== undefined) recognizedForm.threeStar = data.fields.three_star
}
```

**调试方法**:
```javascript
// 在 handleRecognize 中添加
console.log('后端返回:', data.fields)
console.log('转换后:', recognizedForm)
```

---

#### 6. 识别失败：Unexpected token '<', "<html> <h"... is not valid JSON

**现象**: 登录、AI 识别或调用 API 时报错，提示收到 HTML 而不是 JSON

**发生频率**: ⚠️ **非常常见**（90% 的前端错误都是这个）

---

##### 原因分析

| 原因 | 概率 | 说明 |
|------|------|------|
| **浏览器缓存** | 60% | 缓存了旧的 Nginx 错误页面 |
| **图片太大** | 25% | 超过 Nginx 默认 1MB 限制 |
| **URL 端口错误** | 10% | 访问了错误的端口（如 8080） |
| **后端服务挂了** | 5% | Nginx 返回 502 错误页面 |

---

##### 排查流程

```
1. 查看错误详情 → 2. 检查浏览器缓存 → 3. 检查图片大小 → 
4. 检查 URL 端口 → 5. 检查后端服务
```

---

##### 解决方案

**方案 1: 清除浏览器缓存** (最常见)

```javascript
// Windows/Linux
Ctrl + Shift + R (强制刷新)

// Mac
Cmd + Shift + R

// 或者
F12 → Network 标签 → 勾选 "Disable cache" → 刷新页面

// 彻底清除
F12 → Application 标签 → Clear storage → Clear site data
```

---

**方案 2: 检查图片大小** (AI 识别专属)

```javascript
// 检查图片大小
// 方法 1: 右键图片 → 属性 → 查看大小
// 方法 2: 浏览器控制台
const file = document.querySelector('input[type="file"]').files[0]
console.log(`图片大小：${(file.size / 1024 / 1024).toFixed(2)} MB`)

// 如果 > 1MB，需要配置 Nginx
```

**配置 Nginx 图片上传限制**:
```nginx
server {
    listen 3001;
    
    # ⚠️ 必须配置：允许上传 20MB
    client_max_body_size 20M;
    
    location /api {
        proxy_pass http://127.0.0.1:3000/api;
        
        # ⚠️ API 上传也要配置
        client_max_body_size 20M;
    }
}
```

**重启 Nginx**:
```bash
sudo nginx -t && sudo nginx -s reload
```

---

**方案 3: 检查访问的 URL**

```javascript
// 正确 URL
http://47.103.29.111:3001/

// 错误 URL
http://47.103.29.111/          // 默认 80 端口
http://47.103.29.111:8080/     // 错误端口
http://47.103.29.111:3000/     // 后端端口（不能直接访问）
```

---

**方案 4: 检查后端服务**

```bash
# SSH 登录测试服务器
ssh root@47.103.9.192

# 检查后端健康状态
curl http://localhost:3000/health
# 应该返回：{"status":"healthy"}

# 如果返回空或报错，检查后端服务
systemctl status zodiac-backend

# 查看后端日志
sudo journalctl -u zodiac-backend -n 50 --no-pager
```

---

##### 快速诊断脚本

```bash
#!/bin/bash
# 保存为 check-api.sh

echo "=== 检查后端服务 ==="
curl -s http://localhost:3000/health | jq .

echo ""
echo "=== 检查 Nginx 配置 ==="
nginx -t 2>&1 | grep -i 'client_max_body_size'

echo ""
echo "=== 检查 Nginx 错误日志 ==="
sudo tail -20 /var/log/nginx/error.log | grep -i 'large\|body\|client'
```

---

##### 预防措施

1. **前端添加版本号**
   ```html
   <script src="/assets/index.js?v=2.7.9"></script>
   ```

2. **Nginx 配置正确的错误页面**
   ```nginx
   error_page 502 /502.html;
   error_page 413 /413.html;
   ```

3. **监控后端服务状态**
   ```bash
   # 添加到 crontab
   */5 * * * * curl -f http://localhost:3000/health || systemctl restart zodiac-backend
   ```

4. **前端添加错误处理**
   ```javascript
   try {
     const res = await fetch('/api/...')
     const data = await res.json()
   } catch (err) {
     if (err.message.includes('Unexpected token')) {
       alert('服务暂时不可用，请清除缓存后重试')
     }
   }
   ```

---

### 📝 故障排查通用步骤

```
1. 查看错误码 → 2. 查看错误信息 → 3. 查看日志 → 4. 定位问题
```

**后端日志**:
```bash
# 查看后端日志
sudo journalctl -u zodiac-backend -f

# 查看最近 100 行
sudo journalctl -u zodiac-backend -n 100
```

**Nginx 日志**:
```bash
# 访问日志
sudo tail -f /var/log/nginx/zodiac-access.log

# 错误日志
sudo tail -f /var/log/nginx/zodiac-error.log
```

**数据库日志**:
```bash
# PostgreSQL 日志
sudo tail -f /var/log/postgresql/postgresql-13-main.log
```

**浏览器控制台**:
```
F12 打开开发者工具 → Console 标签 → 查看 JavaScript 错误
```

---

## 常见问题与解决方案

### 问题 1: Nginx 启动失败

**现象**: `systemctl status nginx` 显示失败

**解决方案**:
```bash
# 检查配置
sudo nginx -t

# 查看错误日志
sudo tail -50 /var/log/nginx/error.log

# 常见原因:
# 1. 端口被占用：netstat -tlnp | grep 3001
# 2. 配置文件错误：检查 /etc/nginx/conf.d/zodiac.conf
# 3. 权限问题：sudo chown -R nginx:nginx /var/www/mobile/dist
```

### 问题 2: 后端无法连接数据库

**现象**: 后端日志显示数据库连接失败

**解决方案**:
```bash
# 1. 检查 PostgreSQL 是否运行
systemctl status postgresql

# 2. 检查 pg_hba.conf 配置
sudo cat /var/lib/pgsql/data/pg_hba.conf | grep -v "^#"

# 3. 测试数据库连接
psql -h localhost -U postgres -d zodiac

# 4. 检查防火墙
firewall-cmd --list-all | grep 5432
```

### 问题 3: 前端页面空白

**现象**: 访问 http://47.103.29.111:3001/ 显示空白

**解决方案**:
```bash
# 1. 检查 Nginx 日志
sudo tail -50 /var/log/nginx/zodiac-error.log

# 2. 检查前端文件是否存在
ls -la /var/www/mobile/dist/

# 3. 检查浏览器控制台错误
# F12 打开开发者工具，查看 Console 和 Network 标签

# 4. 清除浏览器缓存
# Ctrl+Shift+R 强制刷新
```

### 问题 4: 图片上传失败 (413 错误)

**现象**: 上传图片时返回 413 Request Entity Too Large

**解决方案**:
```bash
# 检查 Nginx 配置
sudo grep -i "client_max_body_size" /etc/nginx/conf.d/zodiac.conf

# 确保配置了 20M
client_max_body_size 20M;

# 重载 Nginx
sudo nginx -t && sudo nginx -s reload
```

### 问题 5: 跨域访问失败

**现象**: 前端调用 API 时出现 CORS 错误

**解决方案**:
```bash
# 检查后端 CORS 配置
cat /opt/zodiac/backend/backend-fastapi/app/main.py | grep -A 10 "CORS"

# 确保配置了允许所有来源 (开发/测试环境)
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)
```

### 问题 6: Prometheus 无法抓取指标

**现象**: Prometheus 界面显示 target down

**解决方案**:
```bash
# 1. 检查后端是否暴露 metrics 端点
curl http://47.103.9.192:3000/metrics

# 2. 检查 Prometheus 配置
cat /opt/prometheus/prometheus-2.45.0.linux-amd64/prometheus.yml

# 3. 重启 Prometheus
sudo systemctl restart prometheus
```

---

## 维护与监控

### 1. 日志管理

```bash
# 后端日志
sudo journalctl -u zodiac-backend -f

# Nginx 日志
sudo tail -f /var/log/nginx/zodiac-access.log
sudo tail -f /var/log/nginx/zodiac-error.log

# PostgreSQL 日志
sudo tail -f /var/log/postgresql/postgresql-13-main.log  # Ubuntu
# 或
sudo tail -f /var/lib/pgsql/data/log/postgresql.log  # CentOS

# Prometheus 日志
sudo journalctl -u prometheus -f
```

### 2. 备份策略

```bash
# 数据库备份脚本
cat > /opt/backup-zodiac.sh << 'EOF'
#!/bin/bash
BACKUP_DIR="/opt/backups/zodiac"
DATE=$(date +%Y%m%d_%H%M%S)
mkdir -p $BACKUP_DIR

# 备份数据库
pg_dump -U postgres -h localhost zodiac > $BACKUP_DIR/zodiac_$DATE.sql

# 备份上传文件
tar -czf $BACKUP_DIR/uploads_$DATE.tar.gz /opt/zodiac/backend/backend-fastapi/uploads/

# 删除 7 天前的备份
find $BACKUP_DIR -name "*.sql" -mtime +7 -delete
find $BACKUP_DIR -name "*.tar.gz" -mtime +7 -delete

echo "备份完成：$DATE"
EOF

chmod +x /opt/backup-zodiac.sh

# 添加到 crontab (每天凌晨 2 点备份)
crontab -e
0 2 * * * /opt/backup-zodiac.sh >> /var/log/zodiac-backup.log 2>&1
```

### 3. 监控告警

```bash
# Prometheus 告警规则示例
cat > /opt/prometheus/prometheus-2.45.0.linux-amd64/rules.yml << EOF
groups:
  - name: zodiac_alerts
    rules:
      - alert: BackendDown
        expr: up{job="zodiac-backend"} == 0
        for: 1m
        labels:
          severity: critical
        annotations:
          summary: "甲辰后端服务宕机"
          description: "后端服务 {{ \$labels.instance }} 已宕机超过 1 分钟"
          
      - alert: DatabaseDown
        expr: pg_up == 0
        for: 1m
        labels:
          severity: critical
        annotations:
          summary: "PostgreSQL 数据库宕机"
          description: "数据库 {{ \$labels.instance }} 已宕机超过 1 分钟"
EOF
```

### 4. 性能优化建议

#### Nginx 优化
```nginx
# 启用 gzip 压缩
gzip on;
gzip_types text/plain text/css application/json application/javascript;
gzip_min_length 1000;

# 连接优化
worker_connections 1024;
keepalive_timeout 65;
```

#### PostgreSQL 优化
```conf
# postgresql.conf
shared_buffers = 2GB  # 内存的 25%
effective_cache_size = 6GB  # 内存的 75%
work_mem = 64MB
maintenance_work_mem = 512MB
```

#### FastAPI 优化
```bash
# 使用 gunicorn + uvicorn workers
pip install gunicorn

# 启动命令
gunicorn app.main:app -w 4 -k uvicorn.workers.UvicornWorker --bind 0.0.0.0:3000
```

---

## 附录

### A. 快速部署脚本

```bash
#!/bin/bash
# 快速部署脚本 - 菜鸟测试 2 (数据库服务器)

set -e

echo "=== 甲辰系统快速部署脚本 ==="

# 1. 安装依赖
echo "安装依赖..."
sudo yum install -y postgresql13-server postgresql13 git python3.12

# 2. 初始化数据库
echo "初始化数据库..."
sudo postgresql-setup --initdb
sudo systemctl start postgresql
sudo systemctl enable postgresql

# 3. 创建数据库
echo "创建数据库..."
sudo -u postgres psql -c "CREATE DATABASE zodiac;"
sudo -u postgres psql -c "CREATE USER postgres WITH PASSWORD 'postgres' SUPERUSER;"
sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE zodiac TO postgres;"

# 4. 配置远程访问
echo "配置远程访问..."
echo "host    zodiac    postgres    47.103.29.111/32    md5" | sudo tee -a /var/lib/pgsql/data/pg_hba.conf
echo "listen_addresses = '*'" | sudo tee -a /var/lib/pgsql/data/postgresql.conf
sudo systemctl restart postgresql

# 5. 部署后端
echo "部署后端..."
sudo mkdir -p /opt/zodiac/backend
sudo chown -R $USER:$USER /opt/zodiac/backend
cd /opt/zodiac/backend
git clone http://47.253.189.47:3000/coolbot/zodiac-collector.git .
git checkout v2.7.9
cd backend-fastapi
pip3.12 install -r requirements.txt

# 6. 创建服务
echo "创建系统服务..."
sudo cp zodiac-backend.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl start zodiac-backend
sudo systemctl enable zodiac-backend

echo "=== 部署完成 ==="
echo "访问地址：http://47.103.29.111:3001/"
echo "默认账号：admin / admin123"
```

### B. 联系信息

- **开发团队**: 菜鸟小 D (AI 开发助理)
- **技术支持**: 酷博特
- **文档版本**: v1.0
- **最后更新**: 2026-03-15

---

**文档结束**
