统一用户信息付费查看

This commit is contained in:
2026-04-26 11:31:46 +08:00
parent f0269c7c17
commit af772350c9
13 changed files with 987 additions and 36 deletions
+55
View File
@@ -19,6 +19,9 @@ use App\Models\UserCurrencyLog;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
/**
* 类功能:统一处理用户经验、金币与魅力变更,并记录对应流水。
*/
class UserCurrencyService
{
/**
@@ -85,6 +88,58 @@ class UserCurrencyService
});
}
/**
* 在余额充足时扣除用户流通金币,并返回扣费后的金币余额。
*
* @param User $user 被扣费用户
* @param int $amount 扣费金币数量
* @param CurrencySource $source 扣费来源
* @param string $remark 扣费备注
* @param int|null $roomId 所在房间 ID(可选)
*/
public function deductGoldIfEnough(
User $user,
int $amount,
CurrencySource $source,
string $remark = '',
?int $roomId = null,
): ?int {
if ($amount <= 0) {
return (int) $user->jjb;
}
return DB::transaction(function () use ($user, $amount, $source, $remark, $roomId): ?int {
// 付费查看属于真实消费,先锁定用户行再判断余额,避免并发点击透支金币。
$lockedUser = User::query()
->whereKey($user->id)
->lockForUpdate()
->firstOrFail();
if ((int) $lockedUser->jjb < $amount) {
return null;
}
// 扣除流通金币后写入统一流水,方便后台统计与用户追溯消费来源。
$lockedUser->decrement('jjb', $amount);
$balanceAfter = (int) $lockedUser->fresh()->jjb;
UserCurrencyLog::create([
'user_id' => $lockedUser->id,
'username' => $lockedUser->username,
'currency' => 'gold',
'amount' => -$amount,
'balance_after' => $balanceAfter,
'source' => $source->value,
'remark' => $remark,
'room_id' => $roomId,
]);
$user->setAttribute('jjb', $balanceAfter);
return $balanceAfter;
}, attempts: 3);
}
/**
* 批量变更多个用户的货币属性(适用于自动存点:一次操作多人)。
* 每位用户仍独立走事务,单人失败不影响其他人。