当前位置: 首页 > news >正文

React 实战项目:从需求分析到生产级代码完整记录


一、前言

React 实战项目:从需求分析到生产级代码完整记录。本文从实际项目出发,给出完整可运行的代码,帮你快速掌握实战技能。


二、需求分析与架构设计

2.1 业务需求

功能需求: - 用户注册/登录,支持邮箱和手机号 - JWT 无状态认证,支持 RefreshToken 续期 - RBAC 权限控制(超级管理员/普通用户/访客) - 操作日志审计 非功能需求: - 支持 1000 并发 QPS - 接口响应时间 P99 < 200ms - 99.9% 可用性

2.2 技术选型

语言框架:Node.js + Fastify(或 React) 数据库:PostgreSQL + Redis 认证:JWT (access_token 15min, refresh_token 7d) ORM:Prisma(类型安全、自动迁移) API:RESTful + OpenAPI 文档 部署:Docker + K8s

三、核心功能实现

3.1 数据库设计与建模

-- 用户表 CREATE TABLE users ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), username VARCHAR(64) NOT NULL UNIQUE, email VARCHAR(255) NOT NULL UNIQUE, password_hash VARCHAR(255) NOT NULL, role VARCHAR(32) NOT NULL DEFAULT 'user', created_at TIMESTAMP DEFAULT NOW(), updated_at TIMESTAMP DEFAULT NOW(), CONSTRAINT email_format CHECK (email ~* '^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+.[A-Za-z]{2,}$') ); -- 角色表 CREATE TABLE roles ( id SERIAL PRIMARY KEY, name VARCHAR(32) NOT NULL UNIQUE, permissions JSONB NOT NULL DEFAULT '[]' ); -- 操作日志表 CREATE TABLE audit_logs ( id BIGSERIAL PRIMARY KEY, user_id UUID REFERENCES users(id), action VARCHAR(128) NOT NULL, resource VARCHAR(256), details JSONB, ip_address INET, created_at TIMESTAMP DEFAULT NOW() ); -- 索引 CREATE INDEX idx_users_email ON users(email); CREATE INDEX idx_users_role ON users(role); CREATE INDEX idx_audit_user ON audit_logs(user_id, created_at DESC);

3.2 用户认证服务

// React 用户认证服务 const bcrypt = require('bcrypt'); const jwt = require('jsonwebtoken'); class AuthService { constructor(db, redis) { this.db = db; this.redis = redis; } async register({ username, email, password, role = 'user' }) { // 1. 校验唯一性 const existing = await this.db.query( 'SELECT id FROM users WHERE username=$1 OR email=$2', [username, email] ); if (existing.rows.length > 0) { throw new Error('用户名或邮箱已存在'); } // 2. 密码哈希(bcrypt,cost=12) const password_hash = await bcrypt.hash(password, 12); // 3. 创建用户 const result = await this.db.query( `INSERT INTO users (username, email, password_hash, role) VALUES ($1, $2, $3, $4) RETURNING id, username, email, role`, [username, email, password_hash, role] ); // 4. 生成 Token const user = result.rows[0]; return this.issueTokens(user); } async login({ email, password }) { const result = await this.db.query( 'SELECT * FROM users WHERE email=$1', [email] ); const user = result.rows[0]; if (!user || !(await bcrypt.compare(password, user.password_hash))) { throw new Error('邮箱或密码错误'); } // 记录登录日志 await this.logAction(user.id, 'LOGIN', { email }); return this.issueTokens(user); } issueTokens(user) { const accessToken = jwt.sign( { user_id: user.id, role: user.role }, process.env.JWT_SECRET, { expiresIn: '15m' } ); const refreshToken = jwt.sign( { user_id: user.id, type: 'refresh' }, process.env.JWT_REFRESH_SECRET, { expiresIn: '7d' } ); // RefreshToken 黑名单(注销时使用) return { accessToken, refreshToken }; } async logAction(userId, action, details) { await this.db.query( `INSERT INTO audit_logs (user_id, action, details) VALUES ($1, $2, $3)`, [userId, action, JSON.stringify(details)] ); } }

3.3 权限控制中间件

// RBAC 权限检查 const ROLE_PERMISSIONS = { admin: ['users:read', 'users:write', 'users:delete', 'audit:read'], user: ['users:read', 'profile:write'], guest: [] }; function authorize(...requiredPermissions) { return async (req, res, next) => { const user = req.user; if (!user) { return res.status(401).json({ error: '未认证' }); } const userPermissions = ROLE_PERMISSIONS[user.role] || []; const hasPermission = requiredPermissions.every(p => userPermissions.includes(p) ); if (!hasPermission) { await authService.logAction(user.id, 'UNAUTHORIZED_ACCESS', { required: requiredPermissions, user_role: user.role }); return res.status(403).json({ error: '权限不足' }); } next(); }; } // 使用 app.get('/api/users', authenticate, // 认证 authorize('users:read'), // 权限 async (req, res) => { const users = await userService.list(req.query); res.json(users); } );

四、测试与质量保证

4.1 单元测试

// React 单元测试(Jest) describe('AuthService', () => { let authService; let mockDb; let mockRedis; beforeEach(() => { mockDb = { query: jest.fn() }; mockRedis = { set: jest.fn(), get: jest.fn() }; authService = new AuthService(mockDb, mockRedis); }); test('register: 正常注册返回 Token', async () => { mockDb.query .mockResolvedValueOnce({ rows: [] }) // 唯一性检查 .mockResolvedValueOnce({ // 创建用户 rows: [{ id: 'uuid-1', username: 'alice', email: 'a@b.com', role: 'user' }] }); const result = await authService.register({ username: 'alice', email: 'a@b.com', password: 'StrongPass123' }); expect(result).toHaveProperty('accessToken'); expect(result).toHaveProperty('refreshToken'); expect(mockDb.query).toHaveBeenCalledTimes(2); }); test('register: 重复邮箱抛异常', async () => { mockDb.query.mockResolvedValueOnce({ rows: [{ id: 'existing-uuid' }] }); await expect( authService.register({ username: 'alice', email: 'a@b.com', password: 'pass' }) ).rejects.toThrow('用户名或邮箱已存在'); }); test('login: 错误密码抛异常', async () => { mockDb.query.mockResolvedValueOnce({ rows: [{ id: 'uuid-1', password_hash: await bcrypt.hash('correct-password', 12) }] }); await expect( authService.login({ email: 'a@b.com', password: 'wrong-password' }) ).rejects.toThrow('邮箱或密码错误'); }); });

五、部署与运维

5.1 Docker Compose 本地开发

version: '3.8' services: app: build: . ports: - "8080:8080" environment: DATABASE_URL: postgresql://appuser:secret@db:5432/appdb REDIS_URL: redis://redis:6379/0 JWT_SECRET: ${JWT_SECRET} depends_on: db: condition: service_healthy redis: condition: service_started db: image: postgres:16-alpine environment: POSTGRES_DB: appdb POSTGRES_USER: appuser POSTGRES_PASSWORD: secret volumes: - pgdata:/var/lib/postgresql/data - ./init.sql:/docker-entrypoint-initdb.d/init.sql healthcheck: test: ["CMD-SHELL", "pg_isready -U appuser -d appdb"] interval: 10s timeout: 5s retries: 5 redis: image: redis:7-alpine command: redis-server --appendonly yes volumes: - redisdata:/data volumes: pgdata: redisdata:

5.2 GitHub Actions CI/CD

name: CI/CD on: push: branches: [main] pull_request: branches: [main] jobs: test: runs-on: ubuntu-latest services: postgres: image: postgres:16 env: POSTGRES_DB: testdb POSTGRES_USER: test POSTGRES_PASSWORD: test options: >- --health-cmd pg_isready --health-interval 10s steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: '20' - run: npm ci - run: npm test -- --coverage - uses: codecov/codecov-action@v3 deploy: needs: test if: github.ref == 'refs/heads/main' runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: docker build -t app . - run: docker push ghcr.io/${{ github.repository }}:latest

六、总结

  1. 先设计再写代码:数据库建模 + API 接口设计在前
  2. 测试驱动开发:每个功能有测试,提交前跑全量 suite
  3. 日志要完整:操作日志是排查问题的救命稻草
  4. 环境隔离:dev/staging/prod 配置要分开

💬收藏本文!关注我,后续更新更多实战项目系列。


💬觉得有用的话,点个赞+收藏,关注我,持续更新优质技术内容!

标签:React | 实战 | 项目 | 完整 | 后端

http://www.jsqmd.com/news/701655/

相关文章:

  • Rust嵌入式键值存储引擎silo:LSM-Tree架构、ACID事务与高性能实践
  • 可解释树模型实战:CatBoost与SHAP的黄金组合
  • Anything V5在社交媒体创作中的应用:快速生成吸睛配图与头像
  • 2026双面胶带技术推荐:阻燃EPDM泡棉EP-3545FR、阻燃EPDM泡棉EP-4555FR、阻燃EPDM泡棉EP-5565FR选择指南 - 优质品牌商家
  • Llama-3.2V-11B-cot 企业级应用:基于SpringBoot构建智能客服工单系统
  • 微软RD-Agent:自动化AI研发框架,实现数据驱动的智能体协同进化
  • SpringBoot 核心原理深度解析:架构设计与底层实现全指南
  • LSTM网络原理与应用:从门控机制到实战技巧
  • GLM-4.1V-9B-Base在办公自动化中的应用:会议白板照片智能摘要
  • 可验证与可演进强化学习智能体框架VERL实战解析
  • LaserGRBL终极指南:如何快速上手开源激光雕刻控制软件
  • Oracle 常用数据类型:数值类型、字符类型、日期时间、大对象、特殊类型(ROWID、XML、JSON)附:和 MySql对比,Oracle 特有的关键字或方法
  • 2026江诗丹顿名表维修全解析:欧米茄名表回收/江诗丹顿名表回收/浪琴名表回收/浪琴名表维修/百达翡丽名表回收/选择指南 - 优质品牌商家
  • 为什么你的低代码应用在VSCode里“看不见”变量?深度解析Webview沙箱隔离、eval上下文丢失与Source Map v3兼容性危机
  • Real Anime Z开源价值:可商用权重+本地运行保障数据隐私安全
  • Qwen3-ForcedAligner-0.6B模型架构解析:非自回归LLM的创新设计
  • NCHW与NHWC图像存储格式的性能对比与优化策略
  • 2026TOP5乐山麻辣烫店:乐山麻辣烫店推荐、乐山麻辣烫店电话、乐山麻辣烫推荐、老兵麻辣烫地址、老兵麻辣烫电话选择指南 - 优质品牌商家
  • SQL查询优化:NOT EXISTS与LEFT JOIN性能对比
  • Kandinsky-5.0-I2V-Lite-5s作品赏析:基于Matlab图像处理后的风格化视频生成
  • 浏览器工作原理从输入URL到页面渲染
  • Kotlin AI Agent框架Koog实战:类型安全、协程与生产级特性解析
  • SQL性能飙升秘籍:从索引到调优的实战全解析
  • WebArena:构建高保真互联网沙盒,系统评估AI智能体网页交互能力
  • 2026年CMA检测全解析:cma甲醛检测、cma资质检测机构、主体结构检测、公共卫生检测、四川CMA检测机构选择指南 - 优质品牌商家
  • 麦橘超然Flux控制台实战:如何生成赛博朋克风格的高清图片
  • real-anime-z镜像免配置:模型路径预置+WebUI自动加载checkpoint机制
  • 【线性代数笔记】伴随矩阵 A* 的性质汇总与还原原矩阵 A 的核心技巧
  • 机器学习模型持久化:pickle与joblib实战指南
  • 嵌入式+PLC+微服务联合调试实战(VSCode工业调试全栈手册)