本指令指导如何在实体中添加与文件管理系统的关联关系,基于用户实体(UserEntity)的最佳实践。
在实体类中添加文件关联字段:
// 1. 导入文件实体
import { File } from '@/server/modules/files/file.entity';
// 2. 在实体类中添加字段
@Column({
name: '{field_prefix}_file_id',
type: 'int',
unsigned: true,
nullable: true,
comment: '{描述}文件ID'
})
{fieldPrefix}FileId!: number | null;
@ManyToOne(() => File, { nullable: true })
@JoinColumn({
name: '{field_prefix}_file_id',
referencedColumnName: 'id'
})
{fieldPrefix}File!: File | null;
在实体的schema文件中添加文件关联字段:
// 基础字段定义
{fieldPrefix}FileId: z.number()
.int()
.positive()
.nullable()
.openapi({
example: 1,
description: '{描述}文件ID'
}),
// 关联文件对象(用于响应)
{fieldPrefix}File: z.object({
id: z.number().int().positive().openapi({ description: '文件ID' }),
name: z.string().max(255).openapi({ description: '文件名', example: 'example.jpg' }),
fullUrl: z.string().openapi({ description: '文件完整URL', example: 'https://example.com/file.jpg' }),
type: z.string().nullable().openapi({ description: '文件类型', example: 'image/jpeg' }),
size: z.number().nullable().openapi({ description: '文件大小(字节)', example: 102400 })
}).nullable().optional().openapi({
description: '{描述}文件信息'
}),
| 类型 | 命名格式 | 示例 |
|---|---|---|
| 数据库字段 | {前缀}_file_id |
avatar_file_id |
| 实体字段 | {前缀}FileId |
fileId |
| 关联实体 | {前缀}File |
file |
| 描述注释 | {描述}文件ID |
头像文件ID |
实体类 (src/server/modules/users/user.entity.ts):
@Column({ name: 'avatar_file_id', type: 'int', unsigned: true, nullable: true, comment: '头像文件ID' })
fileId!: number | null;
@ManyToOne(() => File, { nullable: true })
@JoinColumn({ name: 'avatar_file_id', referencedColumnName: 'id' })
file!: File | null;
Schema定义 (src/server/modules/users/user.schema.ts):
fileId: z.number().int().positive().nullable().openapi({
example: 1,
description: '头像文件ID'
}),
file: z.object({
id: z.number().int().positive().openapi({ description: '文件ID' }),
name: z.string().max(255).openapi({ description: '文件名', example: 'avatar.jpg' }),
fullUrl: z.string().openapi({ description: '文件完整URL', example: 'https://example.com/avatar.jpg' }),
type: z.string().nullable().openapi({ description: '文件类型', example: 'image/jpeg' }),
size: z.number().nullable().openapi({ description: '文件大小(字节)', example: 102400 })
}).nullable().optional().openapi({
description: '头像文件信息'
}),
{prefix}FileId 和 {prefix}File 字段@ManyToOne 关联 File 实体@JoinColumn 指定外键字段名Create{Entity}Dto 中添加 {prefix}FileId 字段Update{Entity}Dto 中添加可选的 {prefix}FileId 字段{prefix}File 对象用于响应确保数据库表包含 {prefix}_file_id 字段,类型为 INT UNSIGNED NULL
适用于实体只需要关联单个文件的情况,如:
如需关联多个文件,请使用 ManyToMany 关联,参考广告实体的实现。
对于使用通用CRUD路由的实体,需要配置 relations 以自动关联查询文件信息:
// 示例:广告实体的通用CRUD配置
import { createCrudRoutes } from '@/server/utils/generic-crud.routes';
import { Advertisement } from '@/server/modules/advertisements/advertisement.entity';
import { AdvertisementSchema, CreateAdvertisementDto, UpdateAdvertisementDto } from '@/server/modules/advertisements/advertisement.schema';
import { authMiddleware } from '@/server/middleware/auth.middleware';
const advertisementRoutes = createCrudRoutes({
entity: Advertisement,
createSchema: CreateAdvertisementDto,
updateSchema: UpdateAdvertisementDto,
getSchema: AdvertisementSchema,
listSchema: AdvertisementSchema,
searchFields: ['title', 'code'],
relations: ['imageFile'], // 关键配置:自动关联查询图片文件
middleware: [authMiddleware]
});
null,允许无文件关联relations 后,通用CRUD会自动处理关联查询此标准基于用户实体的头像文件关联实现,适用于项目中所有需要文件关联的实体。后续实体按此标准实现即可保持统一性。