15-user-tracking.md 5.3 KB

通用CRUD操作人ID字段配置规范

概述

本规范定义了如何在通用CRUD模块中自动处理操作人ID字段,确保创建和更新操作时自动记录操作用户信息。

新增功能

通用CRUD模块已支持自动注入操作人ID字段,包含以下功能:

  1. 创建时自动记录创建人ID
  2. 更新时自动记录更新人ID
  3. 灵活配置字段名称
  4. 向后兼容现有实现

配置方式

1. 在CrudOptions中配置用户跟踪

import { createCrudRoutes } from '@/server/utils/generic-crud.routes';
import { YourEntity } from '@/server/modules/your-module/your-entity.entity';
import { YourEntitySchema, CreateYourEntityDto, UpdateYourEntityDto } from '@/server/modules/your-module/your-entity.entity';
import { authMiddleware } from '@/server/middleware/auth.middleware';

const yourEntityRoutes = createCrudRoutes({
  entity: YourEntity,
  createSchema: CreateYourEntityDto,
  updateSchema: UpdateYourEntityDto,
  getSchema: YourEntitySchema,
  listSchema: YourEntitySchema,
  middleware: [authMiddleware],
  // 用户跟踪配置
  userTracking: {
    createdByField: 'createdBy',    // 创建人ID字段名,默认 'createdBy'
    updatedByField: 'updatedBy'     // 更新人ID字段名,默认 'updatedBy'
  }
});

2. 实体类定义要求

实体必须包含与配置对应的字段:

@Entity('your_entities')
export class YourEntity {
  @PrimaryGeneratedColumn({ unsigned: true })
  id!: number;

  // 业务字段...
  
  @Column({ name: 'created_by', type: 'int', nullable: true, comment: '创建用户ID' })
  createdBy?: number;
  
  @Column({ name: 'updated_by', type: 'int', nullable: true, comment: '更新用户ID' })
  updatedBy?: number;
  
  @CreateDateColumn({ name: 'created_at' })
  createdAt!: Date;
  
  @UpdateDateColumn({ name: 'updated_at' })
  updatedAt!: Date;
}

3. 字段命名约定

配置字段名 推荐数据库字段名 类型 说明
createdByField created_by int/string 创建人用户ID
updatedByField updated_by int/string 更新人用户ID

配置示例

示例1:使用默认字段名

const routes = createCrudRoutes({
  entity: MyEntity,
  createSchema: CreateMyEntityDto,
  updateSchema: UpdateMyEntityDto,
  getSchema: MyEntitySchema,
  listSchema: MyEntitySchema,
  userTracking: {} // 使用默认字段名 createdBy 和 updatedBy
});

示例2:自定义字段名

const routes = createCrudRoutes({
  entity: MyEntity,
  createSchema: CreateMyEntityDto,
  updateSchema: UpdateMyEntityDto,
  getSchema: MyEntitySchema,
  listSchema: MyEntitySchema,
  userTracking: {
    createdByField: 'created_user_id',
    updatedByField: 'modified_user_id'
  }
});

示例3:只记录创建人

const routes = createCrudRoutes({
  entity: MyEntity,
  createSchema: CreateMyEntityDto,
  updateSchema: UpdateMyEntityDto,
  getSchema: MyEntitySchema,
  listSchema: MyEntitySchema,
  userTracking: {
    createdByField: 'created_by',
    updatedByField: undefined // 不记录更新人
  }
});

示例4:兼容现有字段名

const routes = createCrudRoutes({
  entity: Linkman,
  createSchema: CreateLinkmanDto,
  updateSchema: UpdateLinkmanDto,
  getSchema: LinkmanSchema,
  listSchema: LinkmanSchema,
  userTracking: {
    createdByField: 'createdUserId', // 匹配现有字段
    updatedByField: 'updatedUserId'  // 匹配现有字段
  }
});

工作原理

  1. 创建操作

    • 当用户创建新记录时,系统自动从认证上下文中提取用户ID
    • 将用户ID注入到配置的创建人字段中
    • 如果未配置createdByField,则跳过此步骤
  2. 更新操作

    • 当用户更新记录时,系统自动从认证上下文中提取用户ID
    • 将用户ID注入到配置的更新人字段中
    • 如果未配置updatedByField,则跳过此步骤
  3. 向后兼容

    • 未配置userTracking时,保持原有行为不变
    • 所有现有代码无需修改即可继续运行

注意事项

  1. 认证要求:必须在路由中添加authMiddleware才能获取用户信息
  2. 字段类型:用户ID字段应支持存储用户ID的数据类型(通常为int或varchar)
  3. 数据库字段:确保实体类中定义的数据库字段名与配置一致
  4. 空值处理:如果用户未登录,相关字段将保持为null

最佳实践

  1. 统一命名:在项目中统一使用相同的字段命名约定
  2. 索引优化:为操作人ID字段添加数据库索引以提高查询性能
  3. 关联查询:可以通过relations配置加载操作人详情
  4. 审计功能:结合时间戳字段实现完整的操作审计

常见问题

Q: 如何支持字符串类型的用户ID?

A: 实体类字段类型设置为varchar即可,系统会自动处理字符串类型

Q: 可以配置不同的用户ID字段吗?

A: 可以,通过createdByField和updatedByField分别配置

Q: 会影响现有实体吗?

A: 不会,只有配置了userTracking的实体才会启用此功能

Q: 如何获取操作人详情?

A: 在relations中配置用户关联关系即可: ```typescript const routes = createCrudRoutes({ entity: YourEntity, relations: ['createdByUser', 'updatedByUser'], // ...其他配置 });