如何在我的软删除组件 Soft CrudRepository 方法中获取当前用户或用户 ID?

How can I get current user or user-id in my soft-delete-component's SoftCrudRepository method?

我正在处理 loopback4-soft-delete 组件。我需要将 deletedBy 字段添加到 SoftDeleteEntity 模型。 deletedBy 应与当前登录用户一起传播。

谁能告诉我,如何在软删除组件的 SoftCrudRepository 方法中获取当前用户或用户 ID?

这是我的模型:

export abstract class SoftDeleteEntity extends Entity {
  @property({
    type: 'boolean',
    default: false,
  })
  deleted?: boolean;

  @property({
    type: 'date',
    name: 'deleted_on',
  })
  deletedOn: Date;

  @property({
    type: 'string',
    name: 'deleted_by',
  })
  deletedBy: number;

  constructor(data?: Partial<SoftDeleteEntity>) {
    super(data);
  }
}

这是我的存储库:

export abstract class SoftCrudRepository<
  T extends SoftDeleteEntity,
  ID,
  Relations extends object = {}
> extends DefaultCrudRepository<T, ID, Relations> {
  constructor(
    entityClass: typeof SoftDeleteEntity & {
      prototype: T;
    },
    dataSource: juggler.DataSource,
  ) {
    super(entityClass, dataSource);
  }

  find(filter?: Filter<T>, options?: Options): Promise<(T & Relations)[]> {
    // Filter out soft deleted entries
    if (
      filter?.where &&
      (filter.where as AndClause<T>).and &&
      (filter.where as AndClause<T>).and.length > 0
    ) {
      (filter.where as AndClause<T>).and.push({
        deleted: false,
      } as Condition<T>);
    } else if (
      filter?.where &&
      (filter.where as OrClause<T>).or &&
      (filter.where as OrClause<T>).or.length > 0
    ) {
      filter = {
        where: {
          and: [
            {
              deleted: false,
            } as Condition<T>,
            {
              or: (filter.where as OrClause<T>).or,
            },
          ],
        },
      };
    } else {
      filter = filter ?? {};
      filter.where = filter.where ?? {};
      (filter.where as Condition<T>).deleted = false;
    }

    // Now call super
    return super.find(filter, options);
  }

  findOne(
    filter?: Filter<T>,
    options?: Options,
  ): Promise<(T & Relations) | null> {
    // Filter out soft deleted entries
    if (
      filter?.where &&
      (filter.where as AndClause<T>).and &&
      (filter.where as AndClause<T>).and.length > 0
    ) {
      (filter.where as AndClause<T>).and.push({
        deleted: false,
      } as Condition<T>);
    } else if (
      filter?.where &&
      (filter.where as OrClause<T>).or &&
      (filter.where as OrClause<T>).or.length > 0
    ) {
      filter = {
        where: {
          and: [
            {
              deleted: false,
            } as Condition<T>,
            {
              or: (filter.where as OrClause<T>).or,
            },
          ],
        },
      };
    } else {
      filter = filter ?? {};
      filter.where = filter.where ?? {};
      (filter.where as Condition<T>).deleted = false;
    }

    // Now call super
    return super.findOne(filter, options);
  }

  findById(
    id: ID,
    filter?: Filter<T>,
    options?: Options,
  ): Promise<T & Relations> {
    // Filter out soft deleted entries
    if (
      filter?.where &&
      (filter.where as AndClause<T>).and &&
      (filter.where as AndClause<T>).and.length > 0
    ) {
      (filter.where as AndClause<T>).and.push({
        deleted: false,
      } as Condition<T>);
    } else if (
      filter?.where &&
      (filter.where as OrClause<T>).or &&
      (filter.where as OrClause<T>).or.length > 0
    ) {
      filter = {
        where: {
          and: [
            {
              deleted: false,
            } as Condition<T>,
            {
              or: (filter.where as OrClause<T>).or,
            },
          ],
        },
      };
    } else {
      filter = filter ?? {};
      filter.where = filter.where ?? {};
      (filter.where as Condition<T>).deleted = false;
    }

    // Now call super
    return super.findById(id, filter, options);
  }

  updateAll(
    data: DataObject<T>,
    where?: Where<T>,
    options?: Options,
  ): Promise<Count> {
    // Filter out soft deleted entries
    if (
      where &&
      (where as AndClause<T>).and &&
      (where as AndClause<T>).and.length > 0
    ) {
      (where as AndClause<T>).and.push({
        deleted: false,
      } as Condition<T>);
    } else if (
      where &&
      (where as OrClause<T>).or &&
      (where as OrClause<T>).or.length > 0
    ) {
      where = {
        and: [
          {
            deleted: false,
          } as Condition<T>,
          {
            or: (where as OrClause<T>).or,
          },
        ],
      };
    } else {
      where = where ?? {};
      (where as Condition<T>).deleted = false;
    }

    // Now call super
    return super.updateAll(data, where, options);
  }

  count(where?: Where<T>, options?: Options): Promise<Count> {
    // Filter out soft deleted entries
    if (
      where &&
      (where as AndClause<T>).and &&
      (where as AndClause<T>).and.length > 0
    ) {
      (where as AndClause<T>).and.push({
        deleted: false,
      } as Condition<T>);
    } else if (
      where &&
      (where as OrClause<T>).or &&
      (where as OrClause<T>).or.length > 0
    ) {
      where = {
        and: [
          {
            deleted: false,
          } as Condition<T>,
          {
            or: (where as OrClause<T>).or,
          },
        ],
      };
    } else {
      where = where ?? {};
      (where as Condition<T>).deleted = false;
    }

    // Now call super
    return super.count(where, options);
  }

  delete(entity: T, options?: Options): Promise<void> {
    // Do soft delete, no hard delete allowed
    (entity as SoftDeleteEntity).deleted = true;
    (entity as SoftDeleteEntity).deletedOn = new Date();

    return super.update(entity, options);
  }

  deleteAll(where?: Where<T>, options?: Options): Promise<Count> {
    // Do soft delete, no hard delete allowed
    return this.updateAll(
      {
        deleted: true,
        deletedOn: new Date(),
      } as DataObject<T>,
      where,
      options,
    );
  }

  deleteById(id: ID, options?: Options): Promise<void> {
    // Do soft delete, no hard delete allowed
    return super.updateById(
      id,
      {
        deleted: true,
        deletedOn: new Date(),
      } as DataObject<T>,
      options,
    );
  }

  /**
   * Method to perform hard delete of entries. Take caution.
   * @param entity
   * @param options
   */
  deleteHard(entity: T, options?: Options): Promise<void> {
    // Do hard delete
    return super.delete(entity, options);
  }

  /**
   * Method to perform hard delete of entries. Take caution.
   * @param entity
   * @param options
   */
  deleteAllHard(where?: Where<T>, options?: Options): Promise<Count> {
    // Do hard delete
    return super.deleteAll(where, options);
  }

  /**
   * Method to perform hard delete of entries. Take caution.
   * @param entity
   * @param options
   */
  deleteByIdHard(id: ID, options?: Options): Promise<void> {
    // Do hard delete
    return super.deleteById(id, options);
  }

  static getUser(name: string): string {
    return name;
  }
}

来自 LoopBack 团队的问候

假设您正在使用 LoopBack 的内置身份验证和安全层(参见 https://loopback.io/doc/en/lb4/Authentication-overview.html),可以使用 SecurityBindings.USER.

注入当前登录的用户

最简单的选择是使用 property injection,如下所示:

import {SecurityBindings, UserProfile} from '@loopback/security';

export abstract class SoftCrudRepository<
  T extends SoftDeleteEntity,
  ID,
  Relations extends object = {}
> extends DefaultCrudRepository<T, ID, Relations> {

  @inject(SecurityBindings.USER, {optional: true})
  public currentUser?: UserProfile;

  // Your implementation goes here.
}

使用this.currentUser 从您的存储库方法访问当前登录的用户。请记住,该值是在实例化 class 之后设置的(您无法从构造函数访问它)并且当前用户是 undefined 匿名请求。