import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; import { User } from '../entities/user.entity'; import { IUserRepository } from './user.repository.interface'; @Injectable() export class UserRepository implements IUserRepository { constructor( @InjectRepository(User) private readonly repository: Repository, ) {} async findById(id: string): Promise { return this.repository.findOne({ where: { id } }); } async findByOpenid(openid: string): Promise { return this.repository.findOne({ where: { openid } }); } create(data: Partial): User { return this.repository.create(data); } async save(user: User): Promise { return this.repository.save(user); } /** * 原子更新体力值,使用 WHERE 条件防止并发竞态。 * 只有当 stamina 仍等于 expectedOldStamina 时才更新。 */ async updateStaminaAtomic( userId: string, expectedOldStamina: number, newStamina: number, staminaUpdatedAt: Date, ): Promise<{ affected: number }> { const result = await this.repository.update( { id: userId, stamina: expectedOldStamina }, { stamina: newStamina, staminaUpdatedAt }, ); return { affected: result.affected ?? 0 }; } }