# ✅ 必须修改清单（上线前）

## 🎯 修改目标

解决 5 个架构问题：
1. ✅ CORS 支持 CEP 环境（`Origin: null`）
2. ✅ 生产环境 API 地址配置
3. ✅ 静态文件由 Caddy 处理（性能优化）
4. ✅ Token 通过 Header 传递（已经正确，确认即可）
5. ✅ 使用 Caddy 自动 HTTPS

---

## 📝 需要修改的文件

### 1. 后端 CORS 配置 ⭐ 重要

**文件**: `Server/app/main.py`

**修改前** (第 16-28 行):
```python
# CORS configuration
origins = [
    "http://localhost:5173", # Vite default
    "http://localhost:3000",
    "*" # For development convenience
]

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)
```

**修改后**:
```python
# ========== CORS 配置 ==========
import os

IS_DEV = os.getenv("ENV", "development") == "development"

if IS_DEV:
    # 开发环境：保持宽松
    app.add_middleware(
        CORSMiddleware,
        allow_origins=["*"],
        allow_credentials=True,
        allow_methods=["*"],
        allow_headers=["*"],
    )
else:
    # 生产环境：严格配置
    allowed_origins = os.getenv("ALLOWED_ORIGINS", "").split(",")
    
    app.add_middleware(
        CORSMiddleware,
        allow_origins=allowed_origins,
        allow_credentials=True,
        allow_methods=["GET", "POST", "PUT", "DELETE", "OPTIONS"],
        allow_headers=["*"],
    )
    
    # ✅ CEP 环境特殊处理
    @app.middleware("http")
    async def cep_cors_middleware(request: Request, call_next):
        origin = request.headers.get("origin")
        
        # CEP 的 Origin 是 null 或 cep://
        if origin in ["null", None] or (origin and origin.startswith("cep://")):
            response = await call_next(request)
            response.headers["Access-Control-Allow-Origin"] = "*"
            response.headers["Access-Control-Allow-Credentials"] = "true"
            response.headers["Access-Control-Allow-Methods"] = "GET, POST, PUT, DELETE, OPTIONS"
            response.headers["Access-Control-Allow-Headers"] = "*"
            return response
        
        return await call_next(request)
```

**还需要在文件开头添加导入**:
```python
from fastapi import FastAPI, Request  # ← 添加 Request
```

---

### 2. 删除 FastAPI 静态文件挂载 ⭐ 重要

**文件**: `Server/app/main.py`

**修改前** (第 36-55 行):
```python
# Mount archives directory for download
app.mount("/download", StaticFiles(directory="archives"), name="download")

# Mount Shell directory (登录页面)
shell_dir = Path(__file__).parent.parent / "Designer"
if shell_dir.exists():
    app.mount("/shell", StaticFiles(directory=str(shell_dir), html=True), name="shell")
    print(f"✓ Shell 已挂载: {shell_dir}")
else:
    print(f"⚠️ Shell 目录不存在: {shell_dir}")
    print("  请先运行: cd Designer && npm run build:shell")

# Mount DesignerCache directory to serve Core application files
designer_cache = Path.home() / "AppData" / "Roaming" / "DesignerCache"
if designer_cache.exists():
    app.mount("/core", StaticFiles(directory=str(designer_cache), html=True), name="core")
else:
    # Create directory if it doesn't exist
    designer_cache.mkdir(parents=True, exist_ok=True)
    app.mount("/core", StaticFiles(directory=str(designer_cache), html=True), name="core")
```

**修改后**:
```python
# ❌ 删除所有静态文件挂载（交给 Caddy 处理）
# 生产环境不需要 FastAPI 处理静态文件

# 可以添加健康检查接口
@app.get("/health")
def health_check():
    return {"status": "healthy", "timestamp": datetime.now().isoformat()}
```

---

### 3. 后端环境变量配置

**文件**: `Server/.env`

**新建或修改**:
```bash
# 环境配置
ENV=production

# 项目配置
PROJECT_NAME=DesignerCEP
API_V1_STR=/api/v1

# 安全配置
SECRET_KEY=your-secret-key-here-change-this-in-production

# 数据库配置
DATABASE_URL=mysql://username:password@localhost:3306/designer_cep

# CORS 允许的来源（生产环境）
ALLOWED_ORIGINS=https://your-domain.com,https://www.your-domain.com

# 管理员配置
ADMIN_TOKEN=your-admin-token-here
```

**⚠️ 重要**：将 `your-domain.com` 替换为你的实际域名！

---

### 4. 前端 API 地址配置

**文件**: `Designer/src/config/index.ts`

**修改前** (第 14-16 行):
```typescript
apiServer: isDev 
  ? 'http://127.0.0.1:8000' 
  : 'http://127.0.0.1:8000',  // ❌ 生产环境还是 localhost
```

**修改后**:
```typescript
apiServer: isDev 
  ? 'http://127.0.0.1:8000' 
  : 'https://your-domain.com',  // ✅ 生产环境用线上地址
```

**或者使用环境变量** (推荐):

**新建文件**: `Designer/.env.production`
```bash
VITE_API_SERVER=https://your-domain.com
```

**修改**: `Designer/src/config/index.ts`
```typescript
const isDev = import.meta.env.DEV;
const PROD_API_SERVER = import.meta.env.VITE_API_SERVER || 'http://127.0.0.1:8000';

export const config = {
  apiServer: isDev 
    ? 'http://127.0.0.1:8000' 
    : PROD_API_SERVER,  // ✅ 从环境变量读取
  
  apiPrefix: '/api/v1',
  
  shellLoginUrl: isDev 
    ? 'http://localhost:5173/#/login' 
    : 'https://your-domain.com/shell/#/login',  // ✅ 生产环境登录页
  
  get apiBaseUrl() {
    return `${this.apiServer}${this.apiPrefix}`;
  },
  
  getDownloadUrl(path: string): string {
    if (path.startsWith('/')) {
      return `${this.apiServer}${path}`;
    }
    return path;
  },
  
  getCoreUrl(version: string): string {
    if (isDev) {
      return `http://localhost:5173/`;
    }
    return `${this.apiServer}/core/${version}/index.html`;  // ✅ 线上加载
  }
};
```

---

### 5. 确认 Token 传递方式（已经正确）✅

**文件**: `Designer/src/utils/request.ts`

**检查** (第 16-18 行):
```typescript
const token = localStorage.getItem('token');
if (token) {
    config.headers['Authorization'] = `Bearer ${token}`;  // ✅ 已经正确
}
```

**这个不需要改，已经是对的！**

---

## 🚀 部署步骤

### 步骤 1: 修改代码

```bash
# 1. 后端修改
# - Server/app/main.py（CORS + 删除静态挂载）
# - Server/.env（环境变量）

# 2. 前端修改
# - Designer/.env.production（API 地址）
# - Designer/src/config/index.ts（可选）
```

### 步骤 2: 本地测试

```bash
# 1. 测试后端
cd Server
ENV=development python -m uvicorn app.main:app --reload
# 访问 http://localhost:8000/health

# 2. 测试前端
cd Designer
npm run dev
# 访问 http://localhost:5173
# 登录测试，检查 Network 标签
```

### 步骤 3: 构建生产版本

```bash
cd Designer
npm run build

# 检查生成的文件
ls -la dist/Shell/
ls -la dist/Designer/
```

### 步骤 4: 部署到服务器

```bash
# 方法 A: 自动化部署（推荐）
cd AdminTool
python auto_deploy_core.py --version 1.0.6 --deploy --update-db

# 方法 B: 手动部署
scp -r dist/Shell/* user@server:/var/www/DesignerCEP/Server/static/shell/
scp -r dist/Designer/* user@server:/var/www/DesignerCEP/Server/static/core/1.0.6/
```

### 步骤 5: 配置 Caddy

参考 `Caddy部署指南.md` 的完整配置。

**关键配置**:
```caddy
your-domain.com {
    # API → FastAPI
    handle /api/* {
        reverse_proxy localhost:8000
    }
    
    # Shell 静态文件
    handle /shell/* {
        root * /var/www/DesignerCEP/Server/static/shell
        file_server
    }
    
    # Core 静态文件
    handle /core/* {
        root * /var/www/DesignerCEP/Server/static/core
        file_server
    }
    
    # 下载文件
    handle /downloads/* {
        root * /var/www/DesignerCEP/Server/static/downloads
        file_server
    }
}
```

### 步骤 6: 启动服务

```bash
# 1. 启动 FastAPI
sudo systemctl restart designer-cep

# 2. 启动 Caddy
sudo systemctl restart caddy

# 3. 检查状态
sudo systemctl status designer-cep
sudo systemctl status caddy
```

### 步骤 7: 测试上线

```bash
# 1. 测试 API
curl https://your-domain.com/api/v1/health

# 2. 测试 CEP CORS
curl -X OPTIONS https://your-domain.com/api/v1/client/login \
  -H "Origin: null" \
  -H "Access-Control-Request-Method: POST" \
  -v

# 3. 浏览器测试
# 打开 https://your-domain.com/shell/
# 登录并检查功能
```

---

## 📊 修改影响评估

| 修改项 | 风险 | 是否必须 | 回滚难度 |
|--------|------|---------|---------|
| CORS CEP 支持 | ⭐ 低 | 是 | 容易 |
| 删除静态挂载 | ⭐⭐ 中 | 是 | 中等 |
| 环境变量配置 | ⭐ 低 | 是 | 容易 |
| 前端 API 地址 | ⭐⭐ 中 | 是 | 容易 |
| Token 方式确认 | ⭐ 无 | 否（已正确） | - |

---

## 🔍 常见问题

### Q: 改完后本地开发会受影响吗？

**A**: 不会！代码中有环境判断：
- 开发环境（`ENV=development`）：保持原样，CORS 宽松
- 生产环境（`ENV=production`）：严格 CORS + CEP 支持

### Q: 如果改错了怎么办？

**A**: 
1. Git 回滚：`git checkout Server/app/main.py`
2. 或保留 FastAPI 静态挂载（性能差一点，但能用）
3. 环境变量改回 `ENV=development`

### Q: 必须用 Caddy 吗？

**A**: 不必须，但强烈推荐：
- ✅ Caddy：配置简单，自动 HTTPS
- ⚠️ Nginx：配置复杂，需要手动申请证书
- 二选一即可

---

## ✅ 完成后检查

- [ ] 本地开发环境测试通过
- [ ] 生产构建无错误
- [ ] API 请求正常（200）
- [ ] CORS 无错误
- [ ] CEP 扩展能登录
- [ ] 浏览器能访问
- [ ] Token 在 Header 里
- [ ] 静态文件正常加载
- [ ] HTTPS 证书有效

---

## 📞 如需帮助

1. 查看日志：`sudo journalctl -u designer-cep -f`
2. 查看 Caddy 日志：`sudo journalctl -u caddy -f`
3. 测试 API：`curl -v https://your-domain.com/api/v1/health`

---

**总结**：改动不大，主要是添加环境判断和 CEP CORS 支持，风险可控！

