chore: project initialization - Day 4 environment setup
This commit is contained in:
900
第一周开发指南.md
Normal file
900
第一周开发指南.md
Normal file
@@ -0,0 +1,900 @@
|
||||
# 第一周开发指南(Day 1-7)
|
||||
|
||||
> **目标:** 搭建完整的开发环境,实现第一个功能(用户认证)
|
||||
> **时间:** 7天
|
||||
> **状态:** 🚀 准备就绪!
|
||||
|
||||
---
|
||||
|
||||
## ✅ 已完成准备工作
|
||||
|
||||
- [x] Docker Desktop 安装完毕
|
||||
- [x] DeepSeek API Key 已申请
|
||||
- [x] Qwen API Key 已申请
|
||||
|
||||
---
|
||||
|
||||
## 📅 本周计划
|
||||
|
||||
| 天数 | 任务 | 预计时间 |
|
||||
|------|------|---------|
|
||||
| Day 1 | 验证环境 + 创建项目结构 | 2小时 |
|
||||
| Day 2 | 启动基础服务(Docker) | 1小时 |
|
||||
| Day 3 | 搭建后端框架 | 3小时 |
|
||||
| Day 4 | 搭建前端框架 | 3小时 |
|
||||
| Day 5 | 实现用户认证(后端) | 4小时 |
|
||||
| Day 6 | 实现登录界面(前端) | 4小时 |
|
||||
| Day 7 | 测试联调 | 2小时 |
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Day 1: 验证环境 + 创建项目结构
|
||||
|
||||
### 步骤1:验证 Docker 安装
|
||||
|
||||
打开终端(Windows用PowerShell或CMD,macOS用Terminal),执行:
|
||||
|
||||
```bash
|
||||
# 检查 Docker 版本
|
||||
docker --version
|
||||
# 应输出类似:Docker version 24.0.x
|
||||
|
||||
# 检查 Docker Compose 版本
|
||||
docker-compose --version
|
||||
# 应输出类似:Docker Compose version v2.x.x
|
||||
|
||||
# 检查 Docker 是否运行
|
||||
docker ps
|
||||
# 应输出表头(即使没有容器运行)
|
||||
```
|
||||
|
||||
**如果遇到错误:**
|
||||
- Windows: 确保 Docker Desktop 已启动(系统托盘有Docker图标)
|
||||
- macOS: 确保 Docker Desktop 已启动
|
||||
|
||||
---
|
||||
|
||||
### 步骤2:创建项目目录结构
|
||||
|
||||
```bash
|
||||
# 选择一个工作目录(比如 D:\Projects 或 ~/Projects)
|
||||
cd D:\Projects # Windows
|
||||
# 或
|
||||
cd ~/Projects # macOS/Linux
|
||||
|
||||
# 创建项目根目录
|
||||
mkdir ai-clinical-research
|
||||
cd ai-clinical-research
|
||||
|
||||
# 创建子目录
|
||||
mkdir backend frontend config docs
|
||||
|
||||
# 验证目录结构
|
||||
tree -L 1
|
||||
# 或 Windows: dir
|
||||
```
|
||||
|
||||
**预期结构:**
|
||||
```
|
||||
ai-clinical-research/
|
||||
├── backend/ # 后端代码
|
||||
├── frontend/ # 前端代码
|
||||
├── config/ # 配置文件
|
||||
└── docs/ # 文档
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 步骤3:创建 docker-compose.yml
|
||||
|
||||
在项目根目录创建 `docker-compose.yml`:
|
||||
|
||||
```yaml
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
# PostgreSQL 数据库
|
||||
postgres:
|
||||
image: postgres:15-alpine
|
||||
container_name: acr-postgres
|
||||
environment:
|
||||
POSTGRES_DB: ai_clinical_research
|
||||
POSTGRES_USER: dev_user
|
||||
POSTGRES_PASSWORD: dev_pass_2024
|
||||
ports:
|
||||
- "5432:5432"
|
||||
volumes:
|
||||
- postgres_data:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U dev_user -d ai_clinical_research"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
||||
# Redis 缓存
|
||||
redis:
|
||||
image: redis:7-alpine
|
||||
container_name: acr-redis
|
||||
ports:
|
||||
- "6379:6379"
|
||||
volumes:
|
||||
- redis_data:/data
|
||||
healthcheck:
|
||||
test: ["CMD", "redis-cli", "ping"]
|
||||
interval: 10s
|
||||
timeout: 3s
|
||||
retries: 5
|
||||
|
||||
# Dify Sandbox(沙箱环境,Dify依赖)
|
||||
dify-sandbox:
|
||||
image: langgenius/dify-sandbox:latest
|
||||
container_name: acr-dify-sandbox
|
||||
restart: unless-stopped
|
||||
|
||||
# Dify API
|
||||
dify-api:
|
||||
image: langgenius/dify-api:latest
|
||||
container_name: acr-dify-api
|
||||
environment:
|
||||
# 数据库配置
|
||||
DB_USERNAME: dify
|
||||
DB_PASSWORD: dify_pass_2024
|
||||
DB_HOST: dify-postgres
|
||||
DB_PORT: 5432
|
||||
DB_DATABASE: dify
|
||||
|
||||
# Redis配置
|
||||
REDIS_HOST: dify-redis
|
||||
REDIS_PORT: 6379
|
||||
REDIS_DB: 0
|
||||
|
||||
# 应用配置
|
||||
MODE: api
|
||||
SECRET_KEY: sk-9f73s3ljTXVcMT3Blb3ljTqtsKiGHXVcMT3BlbkFJLK7U
|
||||
CONSOLE_WEB_URL: http://localhost
|
||||
CONSOLE_API_URL: http://localhost:5001
|
||||
SERVICE_API_URL: http://localhost:5001
|
||||
APP_WEB_URL: http://localhost
|
||||
|
||||
# 文件存储(本地)
|
||||
STORAGE_TYPE: local
|
||||
STORAGE_LOCAL_PATH: /app/storage
|
||||
|
||||
# Vector Store(向量数据库)
|
||||
VECTOR_STORE: qdrant
|
||||
QDRANT_URL: http://dify-qdrant:6333
|
||||
QDRANT_API_KEY: dify-qdrant-key
|
||||
|
||||
# Celery(异步任务)
|
||||
CELERY_BROKER_URL: redis://dify-redis:6379/1
|
||||
|
||||
# 模型配置(可选,可在Web界面配置)
|
||||
# OPENAI_API_KEY: your-key-here
|
||||
ports:
|
||||
- "5001:5001"
|
||||
volumes:
|
||||
- dify_app_storage:/app/storage
|
||||
depends_on:
|
||||
- dify-postgres
|
||||
- dify-redis
|
||||
- dify-qdrant
|
||||
- dify-sandbox
|
||||
restart: unless-stopped
|
||||
|
||||
# Dify Worker(后台任务处理)
|
||||
dify-worker:
|
||||
image: langgenius/dify-api:latest
|
||||
container_name: acr-dify-worker
|
||||
environment:
|
||||
MODE: worker
|
||||
DB_USERNAME: dify
|
||||
DB_PASSWORD: dify_pass_2024
|
||||
DB_HOST: dify-postgres
|
||||
DB_PORT: 5432
|
||||
DB_DATABASE: dify
|
||||
REDIS_HOST: dify-redis
|
||||
REDIS_PORT: 6379
|
||||
REDIS_DB: 0
|
||||
CELERY_BROKER_URL: redis://dify-redis:6379/1
|
||||
SECRET_KEY: sk-9f73s3ljTXVcMT3Blb3ljTqtsKiGHXVcMT3BlbkFJLK7U
|
||||
STORAGE_TYPE: local
|
||||
STORAGE_LOCAL_PATH: /app/storage
|
||||
VECTOR_STORE: qdrant
|
||||
QDRANT_URL: http://dify-qdrant:6333
|
||||
QDRANT_API_KEY: dify-qdrant-key
|
||||
volumes:
|
||||
- dify_app_storage:/app/storage
|
||||
depends_on:
|
||||
- dify-postgres
|
||||
- dify-redis
|
||||
- dify-qdrant
|
||||
restart: unless-stopped
|
||||
|
||||
# Dify PostgreSQL
|
||||
dify-postgres:
|
||||
image: postgres:15-alpine
|
||||
container_name: acr-dify-postgres
|
||||
environment:
|
||||
POSTGRES_DB: dify
|
||||
POSTGRES_USER: dify
|
||||
POSTGRES_PASSWORD: dify_pass_2024
|
||||
PGDATA: /var/lib/postgresql/data/pgdata
|
||||
volumes:
|
||||
- dify_postgres_data:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U dify -d dify"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
restart: unless-stopped
|
||||
|
||||
# Dify Redis
|
||||
dify-redis:
|
||||
image: redis:7-alpine
|
||||
container_name: acr-dify-redis
|
||||
volumes:
|
||||
- dify_redis_data:/data
|
||||
healthcheck:
|
||||
test: ["CMD", "redis-cli", "ping"]
|
||||
interval: 10s
|
||||
timeout: 3s
|
||||
retries: 5
|
||||
restart: unless-stopped
|
||||
|
||||
# Qdrant 向量数据库
|
||||
dify-qdrant:
|
||||
image: qdrant/qdrant:latest
|
||||
container_name: acr-dify-qdrant
|
||||
environment:
|
||||
QDRANT__SERVICE__API_KEY: dify-qdrant-key
|
||||
ports:
|
||||
- "6333:6333"
|
||||
volumes:
|
||||
- dify_qdrant_data:/qdrant/storage
|
||||
restart: unless-stopped
|
||||
|
||||
# Dify Web界面
|
||||
dify-web:
|
||||
image: langgenius/dify-web:latest
|
||||
container_name: acr-dify-web
|
||||
environment:
|
||||
CONSOLE_API_URL: http://localhost:5001
|
||||
APP_API_URL: http://localhost:5001
|
||||
ports:
|
||||
- "3000:3000"
|
||||
depends_on:
|
||||
- dify-api
|
||||
restart: unless-stopped
|
||||
|
||||
volumes:
|
||||
postgres_data:
|
||||
redis_data:
|
||||
dify_postgres_data:
|
||||
dify_redis_data:
|
||||
dify_qdrant_data:
|
||||
dify_app_storage:
|
||||
|
||||
networks:
|
||||
default:
|
||||
name: acr-network
|
||||
```
|
||||
|
||||
**保存文件:** `ai-clinical-research/docker-compose.yml`
|
||||
|
||||
---
|
||||
|
||||
### 步骤4:创建 .gitignore
|
||||
|
||||
在项目根目录创建 `.gitignore`:
|
||||
|
||||
```gitignore
|
||||
# Node modules
|
||||
node_modules/
|
||||
*/node_modules/
|
||||
|
||||
# Environment variables
|
||||
.env
|
||||
.env.local
|
||||
.env.*.local
|
||||
*.env
|
||||
|
||||
# IDE
|
||||
.vscode/
|
||||
.idea/
|
||||
*.swp
|
||||
*.swo
|
||||
*~
|
||||
|
||||
# OS
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# Build outputs
|
||||
dist/
|
||||
build/
|
||||
*.log
|
||||
|
||||
# Database
|
||||
*.sqlite
|
||||
*.db
|
||||
|
||||
# API Keys(重要!)
|
||||
**/config/api-keys.json
|
||||
backend/config/api-keys.json
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 步骤5:创建 README.md
|
||||
|
||||
在项目根目录创建 `README.md`:
|
||||
|
||||
```markdown
|
||||
# AI科研助手
|
||||
|
||||
## 快速启动
|
||||
|
||||
### 启动所有服务
|
||||
\`\`\`bash
|
||||
docker-compose up -d
|
||||
\`\`\`
|
||||
|
||||
### 查看服务状态
|
||||
\`\`\`bash
|
||||
docker-compose ps
|
||||
\`\`\`
|
||||
|
||||
### 查看日志
|
||||
\`\`\`bash
|
||||
docker-compose logs -f
|
||||
\`\`\`
|
||||
|
||||
### 停止所有服务
|
||||
\`\`\`bash
|
||||
docker-compose down
|
||||
\`\`\`
|
||||
|
||||
## 访问地址
|
||||
|
||||
- 前端开发服务器: http://localhost:5173
|
||||
- 后端API: http://localhost:3001
|
||||
- Dify Web管理界面: http://localhost:3000
|
||||
- Dify API: http://localhost:5001
|
||||
- PostgreSQL: localhost:5432
|
||||
- Redis: localhost:6379
|
||||
|
||||
## 开发文档
|
||||
|
||||
详见 `docs/` 目录
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**✅ Day 1 完成检查清单:**
|
||||
- [ ] Docker 命令验证通过
|
||||
- [ ] 项目目录创建完成
|
||||
- [ ] docker-compose.yml 创建完成
|
||||
- [ ] .gitignore 创建完成
|
||||
- [ ] README.md 创建完成
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Day 2: 启动基础服务
|
||||
|
||||
### 步骤1:启动 Docker 服务
|
||||
|
||||
```bash
|
||||
# 确保在项目根目录
|
||||
cd ai-clinical-research
|
||||
|
||||
# 启动所有服务(首次启动会下载镜像,需要5-10分钟)
|
||||
docker-compose up -d
|
||||
|
||||
# 查看启动日志
|
||||
docker-compose logs -f
|
||||
|
||||
# 等待所有服务启动完成(约2-3分钟)
|
||||
# 看到类似信息表示成功:
|
||||
# acr-dify-api | INFO: Application startup complete.
|
||||
# acr-dify-web | ready - started server on 0.0.0.0:3000
|
||||
```
|
||||
|
||||
**注意:** 首次启动会下载Docker镜像(约2GB),请耐心等待。
|
||||
|
||||
---
|
||||
|
||||
### 步骤2:验证服务状态
|
||||
|
||||
```bash
|
||||
# 查看所有容器状态
|
||||
docker-compose ps
|
||||
|
||||
# 应该看到所有服务都是 "Up" 状态
|
||||
# NAME STATUS
|
||||
# acr-postgres Up (healthy)
|
||||
# acr-redis Up (healthy)
|
||||
# acr-dify-postgres Up (healthy)
|
||||
# acr-dify-redis Up (healthy)
|
||||
# acr-dify-qdrant Up
|
||||
# acr-dify-api Up
|
||||
# acr-dify-worker Up
|
||||
# acr-dify-web Up
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 步骤3:访问 Dify Web 界面
|
||||
|
||||
1. 打开浏览器访问:http://localhost:3000
|
||||
2. 首次访问会要求创建管理员账号
|
||||
3. 填写信息:
|
||||
- 邮箱:admin@example.com
|
||||
- 密码:Admin123!(自己设置一个)
|
||||
- 确认密码:Admin123!
|
||||
4. 点击"创建账号"
|
||||
|
||||
**成功标志:** 进入Dify管理后台
|
||||
|
||||
---
|
||||
|
||||
### 步骤4:获取 Dify API Key
|
||||
|
||||
1. 在Dify管理后台,点击左侧 "设置" → "API密钥"
|
||||
2. 点击 "创建密钥"
|
||||
3. 复制生成的API Key(类似:`app-xxx...`)
|
||||
4. 保存到安全的地方(后面会用到)
|
||||
|
||||
---
|
||||
|
||||
### 步骤5:测试数据库连接
|
||||
|
||||
```bash
|
||||
# 测试 PostgreSQL(业务数据库)
|
||||
docker exec -it acr-postgres psql -U dev_user -d ai_clinical_research -c "SELECT version();"
|
||||
|
||||
# 应输出 PostgreSQL 版本信息
|
||||
|
||||
# 测试 Redis
|
||||
docker exec -it acr-redis redis-cli ping
|
||||
# 应输出: PONG
|
||||
|
||||
# 测试 Dify API
|
||||
curl http://localhost:5001/health
|
||||
# 应输出: {"status":"ok"}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**✅ Day 2 完成检查清单:**
|
||||
- [ ] 所有Docker容器启动成功
|
||||
- [ ] Dify Web界面可访问
|
||||
- [ ] Dify管理员账号创建完成
|
||||
- [ ] Dify API Key获取完成
|
||||
- [ ] 数据库连接测试通过
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Day 3: 搭建后端框架
|
||||
|
||||
### 步骤1:初始化后端项目
|
||||
|
||||
```bash
|
||||
# 进入后端目录
|
||||
cd backend
|
||||
|
||||
# 初始化 Node.js 项目
|
||||
npm init -y
|
||||
|
||||
# 安装依赖
|
||||
npm install fastify@4.26.0 \
|
||||
@fastify/cors@9.0.0 \
|
||||
@fastify/jwt@7.2.0 \
|
||||
@prisma/client@5.10.0 \
|
||||
bcryptjs@2.4.3 \
|
||||
dotenv@16.4.0 \
|
||||
ioredis@5.3.0 \
|
||||
axios@1.6.0
|
||||
|
||||
# 安装开发依赖
|
||||
npm install -D \
|
||||
prisma@5.10.0 \
|
||||
typescript@5.3.0 \
|
||||
@types/node@20.11.0 \
|
||||
@types/bcryptjs@2.4.6 \
|
||||
tsx@4.7.0 \
|
||||
nodemon@3.0.0
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 步骤2:配置 TypeScript
|
||||
|
||||
创建 `backend/tsconfig.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"module": "commonjs",
|
||||
"lib": ["ES2022"],
|
||||
"outDir": "./dist",
|
||||
"rootDir": "./src",
|
||||
"strict": true,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"resolveJsonModule": true,
|
||||
"moduleResolution": "node"
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 步骤3:配置环境变量
|
||||
|
||||
创建 `backend/.env`:
|
||||
|
||||
```bash
|
||||
# 数据库配置
|
||||
DATABASE_URL="postgresql://dev_user:dev_pass_2024@localhost:5432/ai_clinical_research"
|
||||
|
||||
# Redis配置
|
||||
REDIS_URL="redis://localhost:6379"
|
||||
|
||||
# JWT配置
|
||||
JWT_SECRET="your-super-secret-jwt-key-change-this-in-production-2024"
|
||||
JWT_EXPIRES_IN="7d"
|
||||
|
||||
# LLM API Keys
|
||||
DEEPSEEK_API_KEY="你的DeepSeek API Key"
|
||||
DASHSCOPE_API_KEY="你的Qwen API Key"
|
||||
|
||||
# Dify配置
|
||||
DIFY_API_URL="http://localhost:5001"
|
||||
DIFY_API_KEY="你在Day2获取的Dify API Key"
|
||||
|
||||
# 应用配置
|
||||
NODE_ENV="development"
|
||||
PORT=3001
|
||||
```
|
||||
|
||||
**注意:** 把"你的XXX API Key"替换成你实际申请的Key
|
||||
|
||||
---
|
||||
|
||||
### 步骤4:初始化 Prisma
|
||||
|
||||
```bash
|
||||
# 初始化 Prisma
|
||||
npx prisma init
|
||||
|
||||
# 这会创建 prisma/schema.prisma 文件
|
||||
```
|
||||
|
||||
编辑 `backend/prisma/schema.prisma`:
|
||||
|
||||
```prisma
|
||||
generator client {
|
||||
provider = "prisma-client-js"
|
||||
}
|
||||
|
||||
datasource db {
|
||||
provider = "postgresql"
|
||||
url = env("DATABASE_URL")
|
||||
}
|
||||
|
||||
// 用户表
|
||||
model User {
|
||||
id String @id @default(uuid())
|
||||
email String @unique
|
||||
password String
|
||||
name String?
|
||||
role String @default("user") // user, admin
|
||||
status String @default("active") // active, inactive
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
// 关联
|
||||
projects Project[]
|
||||
knowledgeBases KnowledgeBase[]
|
||||
|
||||
@@map("users")
|
||||
}
|
||||
|
||||
// 项目/课题表
|
||||
model Project {
|
||||
id String @id @default(uuid())
|
||||
userId String
|
||||
name String
|
||||
description String @db.Text
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
// 关联
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
conversations Conversation[]
|
||||
|
||||
@@map("projects")
|
||||
}
|
||||
|
||||
// 对话表
|
||||
model Conversation {
|
||||
id String @id @default(uuid())
|
||||
projectId String?
|
||||
userId String
|
||||
agentId String
|
||||
title String
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
// 关联
|
||||
project Project? @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
||||
messages Message[]
|
||||
|
||||
@@map("conversations")
|
||||
}
|
||||
|
||||
// 消息表
|
||||
model Message {
|
||||
id String @id @default(uuid())
|
||||
conversationId String
|
||||
role String // user, assistant
|
||||
content String @db.Text
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
// 关联
|
||||
conversation Conversation @relation(fields: [conversationId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@map("messages")
|
||||
}
|
||||
|
||||
// 知识库表
|
||||
model KnowledgeBase {
|
||||
id String @id @default(uuid())
|
||||
userId String
|
||||
name String
|
||||
description String?
|
||||
difyDatasetId String // Dify中的知识库ID
|
||||
fileCount Int @default(0)
|
||||
totalSizeBytes BigInt @default(0)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
// 关联
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
documents Document[]
|
||||
|
||||
@@map("knowledge_bases")
|
||||
}
|
||||
|
||||
// 文档表
|
||||
model Document {
|
||||
id String @id @default(uuid())
|
||||
kbId String
|
||||
userId String
|
||||
filename String
|
||||
fileType String
|
||||
fileSizeBytes BigInt
|
||||
fileUrl String
|
||||
difyDocumentId String
|
||||
status String @default("uploading") // uploading, processing, completed, failed
|
||||
progress Int @default(0)
|
||||
errorMessage String?
|
||||
segmentsCount Int?
|
||||
tokensCount Int?
|
||||
uploadedAt DateTime @default(now())
|
||||
processedAt DateTime?
|
||||
|
||||
// 关联
|
||||
knowledgeBase KnowledgeBase @relation(fields: [kbId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@map("documents")
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 步骤5:创建数据库表
|
||||
|
||||
```bash
|
||||
# 生成 Prisma Client
|
||||
npx prisma generate
|
||||
|
||||
# 创建数据库迁移
|
||||
npx prisma migrate dev --name init
|
||||
|
||||
# 看到类似输出表示成功:
|
||||
# ✔ Generated Prisma Client
|
||||
# ✔ Your database is now in sync with your schema.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 步骤6:创建基础目录结构
|
||||
|
||||
```bash
|
||||
# 在 backend 目录下创建
|
||||
mkdir -p src/routes src/services src/config src/utils src/types
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 步骤7:创建服务器入口文件
|
||||
|
||||
创建 `backend/src/server.ts`:
|
||||
|
||||
```typescript
|
||||
import Fastify from 'fastify';
|
||||
import cors from '@fastify/cors';
|
||||
import dotenv from 'dotenv';
|
||||
|
||||
// 加载环境变量
|
||||
dotenv.config();
|
||||
|
||||
const server = Fastify({
|
||||
logger: true
|
||||
});
|
||||
|
||||
// 注册CORS
|
||||
server.register(cors, {
|
||||
origin: true // 开发环境允许所有来源
|
||||
});
|
||||
|
||||
// 健康检查端点
|
||||
server.get('/health', async (request, reply) => {
|
||||
return { status: 'ok', timestamp: new Date().toISOString() };
|
||||
});
|
||||
|
||||
// 测试端点
|
||||
server.get('/api/test', async (request, reply) => {
|
||||
return {
|
||||
message: 'AI科研助手后端服务运行正常!',
|
||||
env: process.env.NODE_ENV,
|
||||
timestamp: new Date().toISOString()
|
||||
};
|
||||
});
|
||||
|
||||
// 启动服务器
|
||||
const start = async () => {
|
||||
try {
|
||||
const port = parseInt(process.env.PORT || '3001');
|
||||
await server.listen({ port, host: '0.0.0.0' });
|
||||
console.log(`🚀 服务器启动成功!`);
|
||||
console.log(`📝 API地址: http://localhost:${port}`);
|
||||
console.log(`🏥 健康检查: http://localhost:${port}/health`);
|
||||
} catch (err) {
|
||||
server.log.error(err);
|
||||
process.exit(1);
|
||||
}
|
||||
};
|
||||
|
||||
start();
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 步骤8:配置 package.json scripts
|
||||
|
||||
编辑 `backend/package.json`,添加 scripts:
|
||||
|
||||
```json
|
||||
{
|
||||
"scripts": {
|
||||
"dev": "tsx watch src/server.ts",
|
||||
"build": "tsc",
|
||||
"start": "node dist/server.js",
|
||||
"prisma:generate": "prisma generate",
|
||||
"prisma:migrate": "prisma migrate dev",
|
||||
"prisma:studio": "prisma studio"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 步骤9:启动后端服务
|
||||
|
||||
```bash
|
||||
# 启动开发服务器
|
||||
npm run dev
|
||||
|
||||
# 看到类似输出表示成功:
|
||||
# 🚀 服务器启动成功!
|
||||
# 📝 API地址: http://localhost:3001
|
||||
# 🏥 健康检查: http://localhost:3001/health
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 步骤10:测试后端API
|
||||
|
||||
打开新的终端窗口:
|
||||
|
||||
```bash
|
||||
# 测试健康检查
|
||||
curl http://localhost:3001/health
|
||||
|
||||
# 测试API
|
||||
curl http://localhost:3001/api/test
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**✅ Day 3 完成检查清单:**
|
||||
- [ ] 后端项目初始化完成
|
||||
- [ ] 依赖安装完成
|
||||
- [ ] TypeScript配置完成
|
||||
- [ ] 环境变量配置完成
|
||||
- [ ] Prisma数据库模型创建完成
|
||||
- [ ] 数据库迁移成功
|
||||
- [ ] 后端服务启动成功
|
||||
- [ ] API测试通过
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Day 4-7: 继续开发...
|
||||
|
||||
(后续天数的详细步骤将在您完成Day 1-3后提供)
|
||||
|
||||
---
|
||||
|
||||
## 📊 当前进度
|
||||
|
||||
```
|
||||
✅ 环境准备: 100%
|
||||
⏳ Day 1: 待开始
|
||||
⏳ Day 2: 待开始
|
||||
⏳ Day 3: 待开始
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🆘 常见问题
|
||||
|
||||
### Q1: Docker 容器启动失败
|
||||
```bash
|
||||
# 查看日志
|
||||
docker-compose logs [服务名]
|
||||
|
||||
# 重启服务
|
||||
docker-compose restart [服务名]
|
||||
|
||||
# 完全重置
|
||||
docker-compose down -v
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
### Q2: 端口被占用
|
||||
```bash
|
||||
# Windows 查找占用端口的进程
|
||||
netstat -ano | findstr :3001
|
||||
|
||||
# macOS/Linux
|
||||
lsof -i :3001
|
||||
|
||||
# 修改端口(在 .env 中)
|
||||
PORT=3002
|
||||
```
|
||||
|
||||
### Q3: npm install 太慢
|
||||
```bash
|
||||
# 使用国内镜像
|
||||
npm config set registry https://registry.npmmirror.com
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎉 准备开始!
|
||||
|
||||
**现在就开始 Day 1 吧!**
|
||||
|
||||
执行第一个命令:
|
||||
```bash
|
||||
docker --version
|
||||
```
|
||||
|
||||
有任何问题随时告诉我!🚀
|
||||
|
||||
Reference in New Issue
Block a user