diff --git a/.gitignore b/.gitignore index 6b621b6..8512bf0 100644 --- a/.gitignore +++ b/.gitignore @@ -47,4 +47,10 @@ temp/ *.ntvs* *.njsproj *.sln -*.sw? \ No newline at end of file +*.sw? + +# Database files (SQLite) +*.db +*.db-shm +*.db-wal +numerology.db* \ No newline at end of file diff --git a/Procfile b/Procfile new file mode 100644 index 0000000..e8f79ea --- /dev/null +++ b/Procfile @@ -0,0 +1 @@ +web: npm start \ No newline at end of file diff --git a/VERCEL_DEPLOYMENT.md b/VERCEL_DEPLOYMENT.md deleted file mode 100644 index 04506d7..0000000 --- a/VERCEL_DEPLOYMENT.md +++ /dev/null @@ -1,152 +0,0 @@ -# Vercel 部署指南 - -本指南将帮助您将三算命项目部署到 Vercel 平台。 - -## 🚀 快速部署 - -### 1. 准备工作 - -确保您的项目已推送到 GitHub: -```bash -git add . -git commit -m "准备Vercel部署" -git push origin master -``` - -### 2. 连接 Vercel - -1. 访问 [vercel.com](https://vercel.com) -2. 使用 GitHub 账号登录 -3. 点击 "New Project" -4. 选择您的 `suanming` 仓库 -5. 点击 "Import" - -### 3. 配置环境变量 - -在 Vercel 项目设置中添加以下环境变量: - -``` -NODE_ENV=production -JWT_SECRET=your_secure_jwt_secret_here -CORS_ORIGIN=https://your-app-name.vercel.app -``` - -**生成 JWT Secret:** -```bash -node -e "console.log(require('crypto').randomBytes(64).toString('hex'))" -``` - -### 4. 数据库配置 - -由于 Vercel 不支持 SQLite 文件存储,您需要迁移到云数据库: - -#### 选项 1: Vercel Postgres(推荐) -1. 在 Vercel 项目中添加 Postgres 数据库 -2. 复制连接字符串到环境变量 `DATABASE_URL` -3. 修改数据库连接代码 - -#### 选项 2: PlanetScale -1. 注册 [PlanetScale](https://planetscale.com) -2. 创建数据库 -3. 获取连接字符串 -4. 添加到环境变量 `DATABASE_URL` - -### 5. 部署 - -配置完成后,Vercel 会自动部署您的应用。 - -## 📁 项目结构说明 - -``` -├── vercel.json # Vercel 配置文件 -├── .env.production # 生产环境变量模板 -├── src/ # 前端代码 -└── server/ # 后端 API -``` - -## 🔧 配置文件说明 - -### vercel.json -- 配置构建和路由规则 -- 将 `/api/*` 路由到后端服务 -- 其他路由指向前端应用 - -### 环境变量 -- `NODE_ENV`: 设置为 production -- `JWT_SECRET`: JWT 令牌密钥 -- `CORS_ORIGIN`: 允许的跨域来源 -- `DATABASE_URL`: 数据库连接字符串(如使用云数据库) - -## 🗄️ 数据库迁移 - -如果您选择使用云数据库,需要执行以下步骤: - -### 1. 修改数据库连接 - -编辑 `server/database/index.cjs`: - -```javascript -// 替换 SQLite 连接为 PostgreSQL -const { Pool } = require('pg'); - -const pool = new Pool({ - connectionString: process.env.DATABASE_URL, - ssl: process.env.NODE_ENV === 'production' ? { rejectUnauthorized: false } : false -}); -``` - -### 2. 更新 SQL 语法 - -将 SQLite 语法转换为 PostgreSQL 语法: -- `INTEGER PRIMARY KEY AUTOINCREMENT` → `SERIAL PRIMARY KEY` -- `TEXT` → `VARCHAR` 或 `TEXT` -- 日期时间处理差异 - -### 3. 运行迁移 - -在 Vercel 部署后,通过 API 端点初始化数据库: -``` -POST https://your-app.vercel.app/api/init-database -``` - -## 🚨 常见问题 - -### 1. 构建失败 -- 检查 `package.json` 中的 `vercel-build` 脚本 -- 确保所有依赖都在 `dependencies` 中 - -### 2. API 路由不工作 -- 检查 `vercel.json` 路由配置 -- 确保后端文件路径正确 - -### 3. 数据库连接错误 -- 验证环境变量设置 -- 检查数据库连接字符串格式 - -### 4. CORS 错误 -- 设置正确的 `CORS_ORIGIN` 环境变量 -- 检查后端 CORS 配置 - -## 📊 性能优化 - -1. **启用缓存**:配置适当的缓存头 -2. **压缩资源**:Vercel 自动启用 gzip -3. **CDN 加速**:静态资源自动通过 CDN 分发 -4. **函数优化**:保持 API 函数轻量级 - -## 🔄 持续部署 - -Vercel 会自动监听 GitHub 仓库变化: -- 推送到 `master` 分支触发生产部署 -- 推送到其他分支创建预览部署 - -## 📞 获取帮助 - -如果遇到问题: -1. 查看 Vercel 部署日志 -2. 检查浏览器控制台错误 -3. 参考 [Vercel 文档](https://vercel.com/docs) - ---- - -部署完成后,您的应用将在 `https://your-app-name.vercel.app` 可用! \ No newline at end of file diff --git a/api/index.js b/api/index.js deleted file mode 100644 index 24414e5..0000000 --- a/api/index.js +++ /dev/null @@ -1,5 +0,0 @@ -// Vercel API 入口文件 -const app = require('../server/index.cjs'); - -// 导出为 Vercel 函数 -module.exports = app; \ No newline at end of file diff --git a/numerology.db-shm b/numerology.db-shm index 7ed1269..77a5f66 100644 Binary files a/numerology.db-shm and b/numerology.db-shm differ diff --git a/numerology.db-wal b/numerology.db-wal index 9688553..6ba2637 100644 Binary files a/numerology.db-wal and b/numerology.db-wal differ diff --git a/package.json b/package.json index 47f1f15..133a92b 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,6 @@ "server": "nodemon server/index.cjs", "build": "tsc -b && vite build", "build:prod": "tsc -b && BUILD_MODE=prod vite build", - "vercel-build": "npm run build", "lint": "eslint .", "preview": "vite preview", "start": "node server/index.cjs", diff --git a/railway.json b/railway.json new file mode 100644 index 0000000..3fa6500 --- /dev/null +++ b/railway.json @@ -0,0 +1,13 @@ +{ + "$schema": "https://railway.app/railway.schema.json", + "build": { + "builder": "NIXPACKS" + }, + "deploy": { + "startCommand": "npm start", + "healthcheckPath": "/health", + "healthcheckTimeout": 100, + "restartPolicyType": "ON_FAILURE", + "restartPolicyMaxRetries": 10 + } +} \ No newline at end of file diff --git a/server/index.cjs b/server/index.cjs index bbb6495..d2c738d 100644 --- a/server/index.cjs +++ b/server/index.cjs @@ -42,7 +42,12 @@ app.use(helmet({ // CORS配置 app.use(cors({ origin: process.env.NODE_ENV === 'production' - ? ['http://localhost:5173', 'http://localhost:4173'] // 生产环境允许的域名 + ? [ + 'http://localhost:5173', + 'http://localhost:4173', + /\.railway\.app$/, // Railway域名 + /\.up\.railway\.app$/ // Railway新域名格式 + ] : true, // 开发环境允许所有域名 credentials: true, methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'], @@ -92,36 +97,31 @@ app.use('*', (req, res) => { // 错误处理中间件 app.use(errorHandler); -// 启动服务器(仅在非Vercel环境) -if (process.env.VERCEL !== '1') { - const server = app.listen(PORT, () => { - console.log(`🚀 服务器运行在 http://localhost:${PORT}`); - console.log(`📊 数据库文件: ${path.resolve('./numerology.db')}`); - console.log(`🌍 环境: ${process.env.NODE_ENV || 'development'}`); - }); - - // 优雅关闭 - process.on('SIGTERM', () => { - console.log('收到SIGTERM信号,开始优雅关闭...'); - server.close(() => { - console.log('HTTP服务器已关闭'); - dbManager.close(); - process.exit(0); - }); - }); - - process.on('SIGINT', () => { - console.log('收到SIGINT信号,开始优雅关闭...'); - server.close(() => { - console.log('HTTP服务器已关闭'); - dbManager.close(); - process.exit(0); - }); - }); -} else { - console.log('🚀 Vercel serverless 环境已就绪'); +// 启动服务器 +const server = app.listen(PORT, () => { + console.log(`🚀 服务器运行在 http://localhost:${PORT}`); + console.log(`📊 数据库文件: ${path.resolve('./numerology.db')}`); console.log(`🌍 环境: ${process.env.NODE_ENV || 'development'}`); -} +}); + +// 优雅关闭 +process.on('SIGTERM', () => { + console.log('收到SIGTERM信号,开始优雅关闭...'); + server.close(() => { + console.log('HTTP服务器已关闭'); + dbManager.close(); + process.exit(0); + }); +}); + +process.on('SIGINT', () => { + console.log('收到SIGINT信号,开始优雅关闭...'); + server.close(() => { + console.log('HTTP服务器已关闭'); + dbManager.close(); + process.exit(0); + }); +}); // 未捕获异常处理 process.on('uncaughtException', (error) => { diff --git a/src/lib/localApi.ts b/src/lib/localApi.ts index bd560b9..2b5f62b 100644 --- a/src/lib/localApi.ts +++ b/src/lib/localApi.ts @@ -1,8 +1,7 @@ // 本地API客户端 // 替代Supabase客户端,提供相同的接口 -const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || - (import.meta.env.PROD ? '/api' : 'http://localhost:3001/api'); +const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || 'http://localhost:3001/api'; interface ApiResponse { data?: T; diff --git a/vercel.json b/vercel.json deleted file mode 100644 index ee9e322..0000000 --- a/vercel.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "version": 2, - "builds": [ - { - "src": "package.json", - "use": "@vercel/static-build", - "config": { - "distDir": "dist" - } - }, - { - "src": "api/index.js", - "use": "@vercel/node" - } - ], - "routes": [ - { - "src": "/api/(.*)", - "dest": "/api/index.js" - }, - { - "src": "/(.*)", - "dest": "/index.html" - } - ], - "env": { - "NODE_ENV": "production", - "VERCEL": "1" - }, - "functions": { - "api/index.js": { - "maxDuration": 30 - } - } -} \ No newline at end of file