diff --git a/README.md b/README.md
index a6cbc98..4152a99 100644
--- a/README.md
+++ b/README.md
@@ -283,6 +283,34 @@ LLM_API_KEY=your_api_key:your_secret_key
获取地址:https://console.bce.baidu.com/qianfan/
+
+Windows 导出 PDF 报错怎么办?
+
+PDF 导出功能使用 WeasyPrint 库,在 Windows 系统上需要安装 GTK 依赖:
+
+**方法一:使用 MSYS2 安装(推荐)**
+```bash
+# 1. 下载并安装 MSYS2: https://www.msys2.org/
+# 2. 打开 MSYS2 终端,执行:
+pacman -S mingw-w64-x86_64-pango mingw-w64-x86_64-gtk3
+
+# 3. 将 MSYS2 的 bin 目录添加到系统 PATH 环境变量:
+# C:\msys64\mingw64\bin
+```
+
+**方法二:使用 GTK3 Runtime 安装包**
+1. 下载 GTK3 Runtime: https://github.com/nickvidal/gtk3-runtime/releases
+2. 安装后将安装目录添加到系统 PATH
+
+**方法三:使用 Docker 部署(最简单)**
+使用 Docker 部署后端可以避免 Windows 上的依赖问题:
+```bash
+docker-compose up -d backend
+```
+
+安装完成后重启后端服务即可正常导出 PDF。
+
+
如何使用 API 中转站?
diff --git a/backend/app/services/llm/adapters/litellm_adapter.py b/backend/app/services/llm/adapters/litellm_adapter.py
index 880a476..fe4d199 100644
--- a/backend/app/services/llm/adapters/litellm_adapter.py
+++ b/backend/app/services/llm/adapters/litellm_adapter.py
@@ -105,6 +105,10 @@ class LiteLLMAdapter(BaseLLMAdapter):
# 禁用 LiteLLM 的缓存,确保每次都实际调用 API
litellm.cache = None
+ # 禁用 LiteLLM 自动添加的 reasoning_effort 参数
+ # 这可以防止模型名称被错误解析为 effort 参数
+ litellm.drop_params = True
+
# 构建消息
messages = [{"role": msg.role, "content": msg.content} for msg in request.messages]
diff --git a/frontend/src/pages/Login.tsx b/frontend/src/pages/Login.tsx
index 6301c90..4beeb0e 100644
--- a/frontend/src/pages/Login.tsx
+++ b/frontend/src/pages/Login.tsx
@@ -59,7 +59,16 @@ export default function Login() {
await login(response.data.access_token);
toast.success("登录成功");
} catch (error: any) {
- toast.error(error.response?.data?.detail || "登录失败,请检查邮箱和密码");
+ const detail = error.response?.data?.detail;
+ // 处理 Pydantic 验证错误(数组格式)
+ if (Array.isArray(detail)) {
+ const messages = detail.map((err: any) => err.msg || err.message || JSON.stringify(err)).join('; ');
+ toast.error(messages || "登录失败");
+ } else if (typeof detail === 'object') {
+ toast.error(detail.msg || detail.message || JSON.stringify(detail));
+ } else {
+ toast.error(detail || "登录失败,请检查邮箱和密码");
+ }
} finally {
setLoading(false);
}
diff --git a/frontend/src/pages/Register.tsx b/frontend/src/pages/Register.tsx
index 612e9ab..ed3639f 100644
--- a/frontend/src/pages/Register.tsx
+++ b/frontend/src/pages/Register.tsx
@@ -26,7 +26,16 @@ export default function Register() {
toast.success('注册成功,请登录');
navigate('/login');
} catch (error: any) {
- toast.error(error.response?.data?.detail || '注册失败');
+ const detail = error.response?.data?.detail;
+ // 处理 Pydantic 验证错误(数组格式)
+ if (Array.isArray(detail)) {
+ const messages = detail.map((err: any) => err.msg || err.message || JSON.stringify(err)).join('; ');
+ toast.error(messages || '注册失败');
+ } else if (typeof detail === 'object') {
+ toast.error(detail.msg || detail.message || JSON.stringify(detail));
+ } else {
+ toast.error(detail || '注册失败');
+ }
} finally {
setLoading(false);
}
diff --git a/frontend/src/shared/api/database.ts b/frontend/src/shared/api/database.ts
index 8b12fc1..4562296 100644
--- a/frontend/src/shared/api/database.ts
+++ b/frontend/src/shared/api/database.ts
@@ -68,6 +68,7 @@ export const api = {
const res = await apiClient.post('/projects/', {
name: project.name,
description: project.description,
+ source_type: project.source_type || 'repository',
repository_url: project.repository_url,
repository_type: project.repository_type,
default_branch: project.default_branch,