|
|
@@ -1,84 +1,138 @@
|
|
|
---
|
|
|
-description: "文件关联关系文档,记录各实体与文件系统的关联方式"
|
|
|
+description: "实体与文件关联开发指令 - 指导如何在实体中添加文件关联字段"
|
|
|
---
|
|
|
|
|
|
-# 文件关联关系文档
|
|
|
+# 实体与文件关联开发指令
|
|
|
|
|
|
## 概述
|
|
|
-本文档记录项目中各实体与文件管理系统的关联关系,包括实体字段、关联方式、使用场景等信息。
|
|
|
-
|
|
|
-## 用户实体 (UserEntity) 文件关联
|
|
|
-
|
|
|
-### 1. 头像文件关联
|
|
|
-- **实体文件**: [`src/server/modules/users/user.entity.ts`](src/server/modules/users/user.entity.ts:29-34)
|
|
|
-- **关联字段**:
|
|
|
- - `avatarFileId: number | null` - 头像文件ID
|
|
|
- - `avatarFile: File | null` - 头像文件实体
|
|
|
-- **关联类型**: Many-to-One
|
|
|
-- **数据库字段**: `avatar_file_id` (INT, unsigned, nullable)
|
|
|
-- **关联实体**: [`File`](src/server/modules/files/file.entity.ts)
|
|
|
-- **使用场景**: 用户头像上传、显示用户头像
|
|
|
-
|
|
|
-### 2. 相关Schema定义
|
|
|
-- **Schema文件**: [`src/server/modules/users/user.schema.ts`](src/server/modules/users/user.schema.ts:33-45)
|
|
|
-- **字段定义**:
|
|
|
- ```typescript
|
|
|
- avatarFileId: z.number().int().positive().nullable()
|
|
|
- avatarFile: z.object({
|
|
|
- id: z.number(),
|
|
|
- name: z.string(),
|
|
|
- fullUrl: z.string(),
|
|
|
- type: z.string().nullable(),
|
|
|
- size: z.number().nullable()
|
|
|
- }).nullable().optional()
|
|
|
- ```
|
|
|
-
|
|
|
-### 3. API使用示例
|
|
|
-- **创建用户时**:
|
|
|
- ```typescript
|
|
|
- {
|
|
|
- username: 'newuser',
|
|
|
- password: 'password123',
|
|
|
- avatarFileId: 123 // 关联已上传的文件ID
|
|
|
- }
|
|
|
- ```
|
|
|
-
|
|
|
-- **更新用户时**:
|
|
|
- ```typescript
|
|
|
- {
|
|
|
- avatarFileId: 456 // 更新头像文件ID
|
|
|
- }
|
|
|
- ```
|
|
|
-
|
|
|
-## 文件关联规范
|
|
|
-
|
|
|
-### 关联字段命名规范
|
|
|
-- 文件ID字段: `{关联名称}FileId`
|
|
|
-- 文件实体字段: `{关联名称}File`
|
|
|
-
|
|
|
-### 数据库字段命名
|
|
|
-- 文件ID数据库字段: `{关联名称}_file_id` (snake_case)
|
|
|
-
|
|
|
-### 关联配置
|
|
|
-- **关联方式**: `@ManyToOne` 单向关联
|
|
|
-- **级联操作**: 默认不级联,删除文件不会影响关联实体
|
|
|
-- **空值处理**: 支持null,表示无关联文件
|
|
|
-
|
|
|
-## 常见使用模式
|
|
|
-
|
|
|
-### 1. 文件上传流程
|
|
|
-1. 先调用文件上传API获取文件ID
|
|
|
-2. 在创建/更新实体时使用文件ID进行关联
|
|
|
-
|
|
|
-### 2. 文件更新流程
|
|
|
-1. 上传新文件获取新文件ID
|
|
|
-2. 更新实体关联的文件ID
|
|
|
-3. 可选择删除旧文件(需手动处理)
|
|
|
-
|
|
|
-### 3. 文件删除处理
|
|
|
-- 删除文件不会自动清除关联
|
|
|
-- 需要手动更新关联字段为null
|
|
|
-- 建议先检查文件是否被其他实体引用
|
|
|
+本指令指导如何在实体中添加与文件管理系统的关联关系,基于用户实体(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` | `avatarFileId` |
|
|
|
+| 关联实体 | `{前缀}File` | `avatarFile` |
|
|
|
+| 描述注释 | `{描述}文件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' })
|
|
|
+avatarFileId!: number | null;
|
|
|
+
|
|
|
+@ManyToOne(() => File, { nullable: true })
|
|
|
+@JoinColumn({ name: 'avatar_file_id', referencedColumnName: 'id' })
|
|
|
+avatarFile!: File | null;
|
|
|
+```
|
|
|
+
|
|
|
+**Schema定义** ([`src/server/modules/users/user.schema.ts`](src/server/modules/users/user.schema.ts:33-45)):
|
|
|
+```typescript
|
|
|
+avatarFileId: z.number().int().positive().nullable().openapi({
|
|
|
+ example: 1,
|
|
|
+ description: '头像文件ID'
|
|
|
+}),
|
|
|
+avatarFile: 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 关联,参考广告实体的实现。
|
|
|
+
|
|
|
+## 注意事项
|
|
|
+
|
|
|
+1. **空值处理**: 字段必须支持 `null`,允许无文件关联
|
|
|
+2. **级联操作**: 默认不级联,删除文件不会影响关联实体
|
|
|
+3. **文件验证**: 前端需先上传文件获取文件ID,再进行实体关联
|
|
|
+4. **类型安全**: 确保所有字段类型定义一致(number | null)
|
|
|
|
|
|
## 扩展说明
|
|
|
-此文档将作为模板,后续其他实体与文件的关联关系将按此格式补充到本文档中。
|
|
|
+
|
|
|
+此标准基于用户实体的头像文件关联实现,适用于项目中所有需要文件关联的实体。后续实体按此标准实现即可保持统一性。
|