From 02f48927a397b94217fc5166f5ecd1fc567b43ba Mon Sep 17 00:00:00 2001 From: Developer Date: Wed, 18 Mar 2026 10:54:18 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E7=99=BB=E5=BD=95=E7=95=8C=E9=9D=A2?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=B8=8EAPI=E4=BB=A3=E7=90=86=E9=85=8D?= =?UTF-8?q?=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 移除登录页面的登录/注册切换,只保留登录功能 - 添加API代理配置支持远程访问 - 添加favicon.ico - 后端CORS配置支持前端访问 Co-Authored-By: Claude Opus 4.6 --- frontend/lib/api.js | 8 ++++++- frontend/pages/api/[...path].js | 17 ++++++++++++++ frontend/pages/login.js | 39 ++++---------------------------- frontend/public/favicon.ico | Bin 0 -> 1138 bytes server.js | 7 ++++-- 5 files changed, 34 insertions(+), 37 deletions(-) create mode 100644 frontend/pages/api/[...path].js create mode 100644 frontend/public/favicon.ico diff --git a/frontend/lib/api.js b/frontend/lib/api.js index bf244ec..3199b14 100644 --- a/frontend/lib/api.js +++ b/frontend/lib/api.js @@ -1,4 +1,4 @@ -const API_BASE = ''; // 使用相对路径,同源代理 +const API_BASE = ''; // 使用相对路径 function getAuthHeaders() { const token = typeof window !== 'undefined' ? localStorage.getItem('token') : null; @@ -15,6 +15,12 @@ async function apiCall(url, options = {}) { }, }); + const contentType = res.headers.get('content-type'); + if (!contentType || !contentType.includes('application/json')) { + const text = await res.text(); + throw new Error(`服务器错误: ${res.status} - ${text.substring(0, 100)}`); + } + const data = await res.json(); if (!res.ok) { diff --git a/frontend/pages/api/[...path].js b/frontend/pages/api/[...path].js new file mode 100644 index 0000000..e0510d3 --- /dev/null +++ b/frontend/pages/api/[...path].js @@ -0,0 +1,17 @@ +export default async function handler(req, res) { + const { 0: path } = req.query; + + const backendUrl = `http://localhost:3501/${path}`; + + const response = await fetch(backendUrl, { + method: req.method, + headers: { + 'Content-Type': 'application/json', + ...(req.headers.authorization ? { Authorization: req.headers.authorization } : {}), + }, + body: req.method !== 'GET' && req.method !== 'HEAD' ? JSON.stringify(req.body) : undefined, + }); + + const data = await response.json(); + res.status(response.status).json(data); +} diff --git a/frontend/pages/login.js b/frontend/pages/login.js index bc58be9..eec8182 100644 --- a/frontend/pages/login.js +++ b/frontend/pages/login.js @@ -8,7 +8,6 @@ import { useToast } from '../components/ToastProvider'; export default function Login() { const router = useRouter(); const { showToast } = useToast(); - const [isLoginMode, setIsLoginMode] = useState(true); const [username, setUsername] = useState(''); const [password, setPassword] = useState(''); const [error, setError] = useState(''); @@ -26,13 +25,8 @@ export default function Login() { setLoading(true); try { - if (isLoginMode) { - await login(username, password); - showToast('登录成功', { tone: 'success' }); - } else { - await register(username, password); - showToast('注册成功', { tone: 'success' }); - } + await login(username, password); + showToast('登录成功', { tone: 'success' }); router.push('/'); } catch (err) { setError(err.message); @@ -50,31 +44,8 @@ export default function Login() { -

{isLoginMode ? '欢迎回来' : '创建账户'}

-

{isLoginMode ? '登录后继续记录每一笔收支' : '注册后即可开始管理你的账本'}

- - -
- - +

欢迎回来

+

登录后继续记录每一笔收支

{error &&
{error}
} @@ -110,7 +81,7 @@ export default function Login() { 处理中... - ) : isLoginMode ? '登录' : '注册'} + ) : '登录'} diff --git a/frontend/public/favicon.ico b/frontend/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..0fbe92cc54d60901fe01907cc2991352a6a040d2 GIT binary patch literal 1138 zcmZQzU<5(|0R|wcz>vYhz#zuJz@P!dKp~(AL>x#lFaYI*xgi+L2NM7P|EDSz=w9`o tSd4BrvHC#jMugrjEqGXt2>&9box$Q?baxC7J}BQaFdSee9)r}wFaUhss2BhM literal 0 HcmV?d00001 diff --git a/server.js b/server.js index 3867592..a9c360b 100644 --- a/server.js +++ b/server.js @@ -6,11 +6,14 @@ const cors = require('cors'); const path = require('path'); const app = express(); -const PORT = 3500; +const PORT = 3501; const JWT_SECRET = process.env.JWT_SECRET || 'accountbook_secret_key_2024'; // 中间件 -app.use(cors()); +app.use(cors({ + origin: ['http://localhost:3500', 'http://127.0.0.1:3500'], + credentials: true +})); app.use(express.json()); app.use(express.static(path.join(__dirname, 'public'))); app.use(express.static(path.join(__dirname, 'frontend/.next')));