Files
MemeMind-Server/src/modules/auth/repositories/user.repository.ts
richarjiang fe2c13258e refactor: 拆分核心玩法模块并优化代码质量
将 WechatGame 单体模块拆分为独立的 User、Level、GameConfig 模块,
新增体力值系统、关卡闯关流程,并修复多项代码质量问题:
- 体力不足错误码从 401 修正为 400
- enterLevel 改用 findById 替代全表扫描
- consumeStamina 增加原子更新防止并发竞态
- 并行化独立数据库查询 (Promise.all)
- 移除 WechatGameService/Controller 死代码
2026-04-10 09:07:50 +08:00

47 lines
1.3 KiB
TypeScript

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<User>,
) {}
async findById(id: string): Promise<User | null> {
return this.repository.findOne({ where: { id } });
}
async findByOpenid(openid: string): Promise<User | null> {
return this.repository.findOne({ where: { openid } });
}
create(data: Partial<User>): User {
return this.repository.create(data);
}
async save(user: User): Promise<User> {
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 };
}
}