基于 Nest.js 和 Angular 的竞价平台-以及Jest测试和CICD

基于 Nest.js 和 Angular 的竞价平台

项目总体描述

本项目是一个基于 Nest.js 和 Angular 的竞价平台,旨在提供一个完整的竞标和管理系统。

项目的主要功能包括用户注册和登录、项目创建和管理、投标管理以及用户角色管理。项目的前端使用 Angular 框架构建,后端使用 Nest.js 框架构建,数据库使用 PostgreSQL,并通过 Swagger 提供 API 文档。

项目部署在 DigitalOcean 的 Droplet 上,前端通过 Nginx 进行部署。

前端 (Angular)
  ↓(API 请求)
Cognito (用户认证)
  ↓(验证通过后请求转发)
后端 (Nest.js)
  ↓(数据库查询)
数据库 (PostgreSQL)
  ↑(数据返回)
后端 (Nest.js)
  ↑(处理后的响应)
前端 (Angular)

项目结构

  • frontend: 包含所有前端代码,使用 Angular 框架构建。
  • backend: 包含所有后端代码,使用 Nest.js 框架构建。
  • .github: 包含 GitHub Actions 的配置文件,用于持续集成和部署。

后端

后端构建

后端使用 Nest.js 框架构建,提供了一个模块化、可扩展的架构。主要功能包括用户认证、项目管理、投标管理等。后端通过 TypeORM 进行数据库操作,支持多种数据库类型。

后端技术栈

  • Nest.js: 用于构建高效、可扩展的 Node.js 服务器端应用程序。
  • TypeORM: 用于数据库交互的 ORM 框架。
  • Swagger: 用于生成 API 文档,方便开发者查看和测试 API。

后端构建步骤

  1. 安装依赖: 在 backend 目录下运行 npm install 安装所有必要的依赖。
  2. 配置环境变量: 在项目根目录下创建 .env 文件,配置数据库连接信息和其他环境变量。
  3. 运行开发服务器: 使用 npm run start:dev 启动开发服务器,支持热重载。
  4. 生产构建: 使用 npm run build 进行生产环境构建,生成的文件位于 dist 目录。

数据库

项目使用 PostgreSQL 作为数据库,所有的数据库操作通过 TypeORM 进行。数据库初始化脚本位于 backend/SQL/init-script.sql,可以用于创建和初始化数据库。

后端代码结构清晰,模块化设计使得功能扩展和维护更加方便。

后端安全认证

后端的安全认证通过 AWS Cognito 实现,结合 Nest.js 的拦截器和服务,确保用户的身份验证和授权。

安全认证架构

  • AWS Cognito: 用于用户注册、登录和身份验证。Cognito 提供了安全的用户池和身份池管理。
  • Nest.js 拦截器: 用于拦截 HTTP 请求,验证请求头中的 JWT Token,确保用户身份的合法性。
  • Service 层: 负责处理与 Cognito 的交互,以及将 Cognito 用户与数据库中的用户信息关联。

实现步骤

  1. Cognito 用户池配置: 在 AWS Cognito 中创建用户池,并配置应用客户端以支持 JWT Token 的生成和验证。

  2. JWT 拦截器: 在 Nest.js 中创建一个拦截器,解析请求头中的 JWT Token,验证其有效性,并将用户信息附加到请求对象中。

    import { Injectable, NestInterceptor, ExecutionContext, CallHandler, UnauthorizedException } from '@nestjs/common';
    import { Observable } from 'rxjs';
    import { AuthService } from './auth.service';
    
    @Injectable()
    export class JwtInterceptor implements NestInterceptor {
      constructor(private readonly authService: AuthService) {}
    
      intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
        const request = context.switchToHttp().getRequest();
        const token = request.headers.authorization?.split(' ')[1];
    
        if (!token) {
          throw new UnauthorizedException('Token not found');
        }
    
        const user = this.authService.validateToken(token);
        if (!user) {
          throw new UnauthorizedException('Invalid token');
        }
    
        request.user = user;
        return next.handle();
      }
    }
    
    
  3. 用户服务: 创建一个用户服务,负责从数据库中检索用户信息,并将其与 Cognito 用户进行关联。通过 Cognito ID 作为唯一标识符,将用户信息存储在数据库中。

    import { Injectable } from '@nestjs/common';
    import { UsersRepository } from './users.repository';
    
    @Injectable()
    export class UsersService {
      constructor(private readonly usersRepository: UsersRepository) {}
    
      async findOrCreateUser(cognitoId: string, email: string) {
        let user = await this.usersRepository.findOneByCognitoId(cognitoId);
        if (!user) {
          user = await this.usersRepository.create({ cognitoId, email });
        }
        return user;
      }
    }
    
    
  4. 角色和权限管理: 在数据库中定义用户角色(如管理员、客户、投标者),并在拦截器中根据角色进行权限验证。

    import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
    import { Reflector } from '@nestjs/core';
    
    @Injectable()
    export class RolesGuard implements CanActivate {
      constructor(private reflector: Reflector) {}
    
      canActivate(context: ExecutionContext): boolean {
        const roles = this.reflector.get<string[]>('roles', context.getHandler());
        if (!roles) {
          return true;
        }
        const request = context.switchToHttp().getRequest();
        const user = request.user;
        return roles.includes(user.role);
      }
    }
    
    

    在需要权限验证的 API 上添加 @Roles('admin') 装饰器,指定需要的角色。

    @Post()
    @Roles('admin')
    createProject(@Body() createProjectDto: CreateProjectDto) {
      return this.projectsService.createProject(createProjectDto);
    }
    
    

通过这种方式,后端能够有效地管理用户身份和权限,确保系统的安全性和可靠性。

项目管理实现

在项目管理模块中,将展示如何通过 Controller 调用 Service,再通过 Service 与数据库交互。

Controller

ProjectsController 中,定义处理 HTTP 请求的路由和方法。

import { Controller, Get, Post, Body, Param, Put, Delete } from '@nestjs/common';
import { ProjectsService } from './projects.service';
import { ProjectsDto } from '../entities/DTO/projects.dto';

@Controller('projects')
export class ProjectsController {
  constructor(private readonly projectsService: ProjectsService) {}

  @Get()
  findAll() {
    return this.projectsService.findAll();
  }

  @Get(':id')
  findOne(@Param('id') id: number) {
    return this.projectsService.findOne(id);
  }

  @Post()
  create(@Body() projectDto: ProjectsDto) {
    return this.projectsService.create(projectDto);
  }

  @Put(':id')
  update(@Param('id') id: number, @Body() projectDto: ProjectsDto) {
    return this.projectsService.update(id, projectDto);
  }

  @Delete(':id')
  delete(@Param('id') id: number) {
    return this.projectsService.delete(id);
  }
}

Service

ProjectsService 负责业务逻辑处理,并与数据库进行交互。

import { Injectable } from '@nestjs/common';
import { DataSource } from 'typeorm';
im
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Dreaife-BW

感谢支持~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值