--- description: "实体与文件关联开发指令 - 指导如何在实体中添加文件关联字段" --- # 实体与文件关联开发指令 ## 概述 本指令指导如何在实体中添加与文件管理系统的关联关系,基于用户实体(UserEntity)的最佳实践。 ## 文件关联标准实现 ### 1. 实体定义规范 在实体类中添加文件关联字段: ```typescript // 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; ``` ### 2. Schema定义规范 在实体的schema文件中添加文件关联字段: ```typescript // 基础字段定义 {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: '{描述}文件信息' }), ``` ### 3. 命名规范 | 类型 | 命名格式 | 示例 | |------|----------|------| | 数据库字段 | `{前缀}_file_id` | `avatar_file_id` | | 实体字段 | `{前缀}FileId` | `fileId` | | 关联实体 | `{前缀}File` | `file` | | 描述注释 | `{描述}文件ID` | `头像文件ID` | ### 4. 完整示例 - 基于用户实体 **实体类** ([`src/server/modules/users/user.entity.ts`](src/server/modules/users/user.entity.ts:29-34)): ```typescript @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`](src/server/modules/users/user.schema.ts:33-45)): ```typescript 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: '头像文件信息' }), ``` ## 使用步骤 ### 步骤1: 添加实体字段 1. 在实体类中添加 `{prefix}FileId` 和 `{prefix}File` 字段 2. 使用 `@ManyToOne` 关联 `File` 实体 3. 配置 `@JoinColumn` 指定外键字段名 ### 步骤2: 添加Schema定义 1. 在 `Create{Entity}Dto` 中添加 `{prefix}FileId` 字段 2. 在 `Update{Entity}Dto` 中添加可选的 `{prefix}FileId` 字段 3. 在实体Schema中添加 `{prefix}File` 对象用于响应 ### 步骤3: 数据库迁移 确保数据库表包含 `{prefix}_file_id` 字段,类型为 INT UNSIGNED NULL ## 使用场景 ### 场景1: 单文件关联 适用于实体只需要关联单个文件的情况,如: - 用户头像 - 商品封面图 - 文档附件 ### 场景2: 多文件关联 如需关联多个文件,请使用 ManyToMany 关联,参考广告实体的实现。 ### 场景3: 通用CRUD路由配置 对于使用通用CRUD路由的实体,需要配置 `relations` 以自动关联查询文件信息: ```typescript // 示例:广告实体的通用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] }); ``` ## 注意事项 1. **空值处理**: 字段必须支持 `null`,允许无文件关联 2. **级联操作**: 默认不级联,删除文件不会影响关联实体 3. **文件验证**: 前端需先上传文件获取文件ID,再进行实体关联 4. **类型安全**: 确保所有字段类型定义一致(number | null) 5. **关联查询**: 配置 `relations` 后,通用CRUD会自动处理关联查询 ## 扩展说明 此标准基于用户实体的头像文件关联实现,适用于项目中所有需要文件关联的实体。后续实体按此标准实现即可保持统一性。