feat: add task reward economy APIs

This commit is contained in:
ANG-Server
2026-07-22 00:45:59 +08:00
parent 9119737f11
commit fe52ab1696
14 changed files with 824 additions and 2 deletions

View File

@@ -1,6 +1,6 @@
import { BadRequestException, Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { EntityManager, Repository } from 'typeorm';
import { UserWallets } from './user_wallets.entity';
import { WalletTransactions } from './wallet_transactions.entity';
@@ -96,6 +96,60 @@ export class UserWalletsService {
};
}
async earnInTransaction(
manager: EntityManager,
userId: bigint,
amount: number,
referenceType: string,
referenceId: string,
note?: string,
): Promise<EarnWalletResult> {
if (!Number.isInteger(amount) || amount < 0) {
throw new BadRequestException('鲸币收入数量不正确');
}
const walletRepository = manager.getRepository(UserWallets);
const transactionRepository = manager.getRepository(WalletTransactions);
let wallet = await walletRepository.findOne({
where: { user_id: userId },
lock: { mode: 'pessimistic_write' },
});
if (!wallet) {
wallet = walletRepository.create({
user_id: userId,
balance: DEFAULT_INITIAL_WHALE_COINS,
created_at: new Date(),
updated_at: new Date(),
});
wallet = await walletRepository.save(wallet);
await transactionRepository.save(transactionRepository.create({
user_id: userId,
type: 'grant',
amount: DEFAULT_INITIAL_WHALE_COINS,
balance_after: wallet.balance,
reference_type: 'registration',
reference_id: 'initial_wallet',
note: '新用户初始鲸币',
created_at: new Date(),
}));
}
wallet.balance += amount;
wallet.updated_at = new Date();
const savedWallet = await walletRepository.save(wallet);
const transaction = await transactionRepository.save(transactionRepository.create({
user_id: userId,
type: 'earn',
amount,
balance_after: savedWallet.balance,
reference_type: referenceType,
reference_id: referenceId,
note: note || null,
created_at: new Date(),
}));
return { wallet: savedWallet, transaction };
}
private async createTransaction(
userId: bigint,
type: string,