AI 加持 开发流程介绍:快速创建 CRUD 基础业务代码
在上一节中,我们借助 NestJS CLI 快速生成了所有业务模块的骨架代码。本节将演示如何利用 AI 工具(如 Cursor、Cline)高效完成字典类数据的 CRUD 接口开发,并梳理标准化的开发流程。
AI 辅助开发流程
第一步:根据 Schema 生成 DTO
将 Prisma Schema 中的 Model 定义提供给 AI 工具,让其生成对应的 DTO 类:
输入给 AI 的提示词:
以下是 Prisma Schema 定义,请生成 NestJS 中对应的 DTO 类(CreateDTO),
包含 class-validator 装饰器:
model DictCourseType {
id Int @id @default(autoincrement())
name String?
typeId Int?
type String?
order Int @default(0)
status Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
text
AI 生成的 DTO:
// dto/create-dict-course-type.dto.ts
import { IsString, IsInt, IsBoolean, IsOptional } from 'class-validator';
export class CreateDictCourseTypeDto {
@IsString()
@IsOptional()
name?: string;
@IsInt()
@IsOptional()
typeId?: number;
@IsString()
@IsOptional()
type?: string;
@IsInt()
@IsOptional()
order?: number;
@IsBoolean()
@IsOptional()
status?: boolean;
}
typescript
第二步:完善 Controller 和 Service
将 Prisma Client 注入 Service,实现标准的 CRUD 操作:
// dict/dict-course-type.controller.ts
import { Controller, Get, Post, Body, Patch, Param, Delete, Query } from '@nestjs/common';
import { DictCourseTypeService } from './dict-course-type.service';
import { CreateDictCourseTypeDto } from './dto/create-dict-course-type.dto';
import { UpdateDictCourseTypeDto } from './dto/update-dict-course-type.dto';
@Controller('dict/course-type')
export class DictCourseTypeController {
constructor(private readonly service: DictCourseTypeService) {}
@Post()
create(@Body() dto: CreateDictCourseTypeDto) {
return this.service.create(dto);
}
@Get()
findAll(
@Query('page') page?: number,
@Query('limit') limit?: number,
) {
return this.service.findAll(page, limit);
}
@Get(':id')
findOne(@Param('id') id: string) {
return this.service.findOne(+id);
}
@Patch(':id')
update(@Param('id') id: string, @Body() dto: UpdateDictCourseTypeDto) {
return this.service.update(+id, dto);
}
@Delete(':id')
remove(@Param('id') id: string) {
return this.service.remove(+id);
}
}
typescript
// dict/dict-course-type.service.ts
import { Injectable } from '@nestjs/common';
import { PrismaClient } from '@prisma/client';
import { CreateDictCourseTypeDto } from './dto/create-dict-course-type.dto';
import { UpdateDictCourseTypeDto } from './dto/update-dict-course-type.dto';
@Injectable()
export class DictCourseTypeService {
constructor(private prisma: PrismaClient) {}
async create(dto: CreateDictCourseTypeDto) {
return this.prisma.dictCourseType.create({ data: dto });
}
async findAll(page?: number, limit?: number) {
if (limit === -1) {
return this.prisma.dictCourseType.findMany();
}
const skip = page ? (page - 1) * (limit || 10) : 0;
return this.prisma.dictCourseType.findMany({
skip,
take: limit || 10,
});
}
async findOne(id: number) {
return this.prisma.dictCourseType.findUnique({ where: { id } });
}
async update(id: number, dto: UpdateDictCourseTypeDto) {
return this.prisma.dictCourseType.update({
where: { id },
data: dto,
});
}
async remove(id: number) {
return this.prisma.dictCourseType.delete({ where: { id } });
}
}
typescript
分页查询管道
使用自定义管道处理分页参数的可选值:
// common/pipes/custom-optional-int.pipe.ts
import { PipeTransform, Injectable } from '@nestjs/common';
@Injectable()
export class CustomOptionalIntPipe implements PipeTransform<string, number> {
constructor(private readonly optional = false) {}
transform(value: string): number {
if (!value && this.optional) return undefined;
return parseInt(value, 10);
}
}
typescript
在 Controller 中使用:
@Get()
findAll(
@Query('page', new CustomOptionalIntPipe(true)) page?: number,
@Query('limit', new CustomOptionalIntPipe(true)) limit?: number,
) {
return this.service.findAll(page, limit);
}
typescript
AI 辅助开发注意事项
| 注意事项 | 说明 |
|---|---|
| 校验 AI 生成的 DTO | AI 可能遗漏 @IsString() 等装饰器,导致 Prisma 类型错误 |
| Prisma 客户端导入 | 从 @prisma/client 导入,确保使用最新生成的客户端类型 |
limit = -1 查询全部 | 业务模块中慎用全量查询,数据量大时可能引起性能问题 |
| UpdateDTO 继承 | 使用 PartialType 从 CreateDTO 派生,所有字段变为可选 |
// dto/update-dict-course-type.dto.ts
import { PartialType } from '@nestjs/mapped-types';
import { CreateDictCourseTypeDto } from './create-dict-course-type.dto';
export class UpdateDictCourseTypeDto extends PartialType(CreateDictCourseTypeDto) {}
typescript
标准化开发流程总结
Schema 定义 → AI 生成 DTO → 校验 DTO 装饰器 → 完善 Controller 路由
↓ ↓
db push 推送数据库 Service 注入 PrismaClient
↓
AI 补全 CRUD 方法体
↓
Bruno/Postman 测试接口
text
接口测试
开发完成后,使用 API 测试工具(Bruno 或 Postman)对每个接口进行验证。建议:
- 导出测试集合文件(Bruno
.json和 Postman.json格式) - 将测试集合纳入 Git 版本管理
- 每个接口覆盖增、删、改、查四种场景
小结
借助 AI 工具 + Prisma 类型系统 + NestJS CLI 三者的配合,字典类数据的 CRUD 开发效率可大幅提升。核心要点:
- Schema 驱动:以 Prisma Schema 为数据源,AI 自动生成 DTO
- 类型安全:TypeScript + Prisma Client 在编译期捕获类型错误
- 标准化:Controller → Service → Prisma Client 的分层架构保持一致
- 人工校验:AI 生成的代码务必检查装饰器和类型是否完整
↑