当实体中已经存在用户相关的字段(如 handlerId, createdBy, userId, operatorId 等),需要将这些字段与 User 实体建立关联关系时使用。
找到实体文件 src/server/modules/[模块名]/[实体名].entity.ts,将现有用户字段改为关联关系:
// 修改前:原始字段定义
@Column({ name: 'handler_id', type: 'int', comment: '处理人ID' })
handlerId!: number;
// 修改后:单向关联关系定义
@ManyToOne(() => User)
@JoinColumn({ name: 'handler_id' })
handler!: User;
// 如果允许为空(单向关联)
@ManyToOne(() => User, { nullable: true })
@JoinColumn({ name: 'handler_id' })
handler?: User | null;
// 在实体顶部添加
import { User } from '@/server/modules/users/user.entity';
如果需要双向关联,在User实体中添加对应的关系定义:
// 在User实体中添加对应的关系定义(双向关联)
@OneToMany(() => AlertHandleLog, log => log.handler)
alertHandleLogs?: AlertHandleLog[];
注意:单向关联不需要此步骤,保持现有配置即可
在对应的 schema 文件中同步修改:
// 在文件顶部添加导入
import { UserSchema } from '@/server/modules/users/user.schema';
// 修改前
handlerId: z.number().int().positive().openapi({
description: '处理人ID',
example: 1
})
// 修改后 - 使用导入的UserSchema
handler: UserSchema.omit({ password: true }).nullable().optional().openapi({
description: '处理人信息'
})
// 修改前:Create DTO
export const CreateAlertHandleLogDto = z.object({
handlerId: z.number().int().positive().openapi({
description: '处理人ID',
example: 1
}),
// ... 其他字段
});
// 修改后:Create DTO
export const CreateAlertHandleLogDto = z.object({
handlerId: z.number().int().positive().openapi({
description: '处理人ID',
example: 1
}),
// ... 其他字段
});
// Update DTO保持不变,但handlerId改为optional
export const UpdateAlertHandleLogDto = z.object({
handlerId: z.number().int().positive().optional().openapi({
description: '处理人ID',
example: 1
}),
// ... 其他字段
});
如果使用通用CRUD路由,需要配置relations:
const routes = createCrudRoutes({
entity: AlertHandleLog,
createSchema: CreateAlertHandleLogDto,
updateSchema: UpdateAlertHandleLogDto,
getSchema: AlertHandleLogSchema,
listSchema: AlertHandleLogSchema,
relations: ['handler'], // 添加关联配置
middleware: [authMiddleware]
});
| 类型 | 命名格式 | 示例 | 说明 |
|---|---|---|---|
| 数据库字段 | {前缀}_id |
handler_id |
保持原有字段名不变 |
| 实体字段 | {前缀} |
handler |
关联实体对象 |
| 反向关联 | {实体名}s |
alertHandleLogs |
User实体中的集合名 |
| 外键字段 | {前缀}Id |
handlerId |
DTO中的外键字段 |
src/server/modules/alerts/alert-handle-log.entity.ts)import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, JoinColumn } from 'typeorm';
import { User } from '@/server/modules/users/user.entity';
@Entity('alert_handle_logs')
export class AlertHandleLog {
@PrimaryGeneratedColumn({ unsigned: true })
id!: number;
@Column({ name: 'handler_id', type: 'int', comment: '处理人ID' })
handlerId!: number;
// 单向关联定义(无需反向引用)
@ManyToOne(() => User)
@JoinColumn({ name: 'handler_id' })
handler!: User;
// ... 其他字段
}
如果需要双向关联,在User实体中添加:
@OneToMany(() => AlertHandleLog, log => log.handler)
alertHandleLogs?: AlertHandleLog[];
单向关联说明:当前配置为单向关联,无需在User实体中添加反向关系定义
src/server/modules/alerts/alert-handle-log.schema.ts)// 引入用户Schema
import { UserSchema } from '@/server/modules/users/user.schema';
// 响应Schema - 使用UserSchema.omit去掉敏感字段
handler: UserSchema.omit({ password: true }).nullable().optional().openapi({
description: '处理人信息'
}),
// 请求DTO中的外键字段
handlerId: z.number().int().positive().openapi({
description: '处理人ID',
example: 1
})
A: 重复上述步骤,为每个用户字段建立独立的关联关系,例如:
@ManyToOne(() => User, user => user.createdAlerts)
@JoinColumn({ name: 'created_by' })
creator!: User;
@ManyToOne(() => User, user => user.updatedAlerts)
@JoinColumn({ name: 'updated_by' })
updater?: User | null;
A: 使用相同的方法,只是字段名不同:
@ManyToOne(() => User, user => user.assignedTasks)
@JoinColumn({ name: 'assignee_id' })
assignee!: User;