Files
nexusphp/app/Repositories/BonusRepository.php

143 lines
5.9 KiB
PHP
Raw Normal View History

2021-06-21 02:01:26 +08:00
<?php
namespace App\Repositories;
use App\Models\BonusLogs;
use App\Models\HitAndRun;
2022-01-19 23:54:55 +08:00
use App\Models\Medal;
2021-06-21 02:01:26 +08:00
use App\Models\Setting;
use App\Models\User;
2022-03-19 14:55:43 +08:00
use App\Models\UserMedal;
2021-06-21 02:01:26 +08:00
use Carbon\Carbon;
2021-12-14 16:22:03 +08:00
use Illuminate\Database\Eloquent\Builder;
2021-06-21 02:01:26 +08:00
use Nexus\Database\NexusDB;
class BonusRepository extends BaseRepository
{
2022-01-19 23:54:55 +08:00
public function consumeToCancelHitAndRun($uid, $hitAndRunId): bool
2021-06-21 02:01:26 +08:00
{
2021-06-22 14:34:45 +08:00
if (!HitAndRun::getIsEnabled()) {
2021-06-21 02:01:26 +08:00
throw new \LogicException("H&R not enabled.");
}
$user = User::query()->findOrFail($uid);
$hitAndRun = HitAndRun::query()->findOrFail($hitAndRunId);
if ($hitAndRun->uid != $uid) {
throw new \LogicException("H&R: $hitAndRunId not belongs to user: $uid.");
}
2022-06-08 14:15:59 +08:00
if ($hitAndRun->status == HitAndRun::STATUS_PARDONED) {
throw new \LogicException("H&R: $hitAndRunId already pardoned.");
}
2021-06-21 02:01:26 +08:00
$requireBonus = BonusLogs::getBonusForCancelHitAndRun();
2022-01-19 23:54:55 +08:00
NexusDB::transaction(function () use ($user, $hitAndRun, $requireBonus) {
2021-06-21 02:01:26 +08:00
$comment = nexus_trans('hr.bonus_cancel_comment', [
'bonus' => $requireBonus,
], $user->locale);
do_log("comment: $comment");
2022-01-19 23:54:55 +08:00
$this->consumeUserBonus($user, $requireBonus, BonusLogs::BUSINESS_TYPE_CANCEL_HIT_AND_RUN, "$comment(H&R ID: {$hitAndRun->id})");
2021-06-21 02:01:26 +08:00
$hitAndRun->update([
'status' => HitAndRun::STATUS_PARDONED,
'comment' => NexusDB::raw("if(comment = '', '$comment', concat_ws('\n', '$comment', comment))"),
2021-06-21 02:01:26 +08:00
]);
});
2022-01-19 23:54:55 +08:00
return true;
2021-06-21 02:01:26 +08:00
}
2021-12-14 16:22:03 +08:00
2022-01-19 23:54:55 +08:00
public function consumeToBuyMedal($uid, $medalId): bool
{
$user = User::query()->findOrFail($uid);
$medal = Medal::query()->findOrFail($medalId);
$exists = $user->valid_medals()->where('medal_id', $medalId)->exists();
do_log(last_query());
if ($exists) {
throw new \LogicException("user: $uid already own this medal: $medalId.");
}
$requireBonus = $medal->price;
NexusDB::transaction(function () use ($user, $medal, $requireBonus) {
$comment = nexus_trans('bonus.comment_buy_medal', [
'bonus' => $requireBonus,
'medal_name' => $medal->name,
], $user->locale);
do_log("comment: $comment");
$this->consumeUserBonus($user, $requireBonus, BonusLogs::BUSINESS_TYPE_BUY_MEDAL, "$comment(medal ID: {$medal->id})");
$expireAt = null;
if ($medal->duration > 0) {
$expireAt = Carbon::now()->addDays($medal->duration)->toDateTimeString();
}
2022-03-19 14:55:43 +08:00
$user->medals()->attach([$medal->id => ['expire_at' => $expireAt, 'status' => UserMedal::STATUS_NOT_WEARING]]);
2022-01-19 23:54:55 +08:00
});
return true;
}
2022-04-04 17:26:26 +08:00
public function consumeToBuyAttendanceCard($uid): bool
{
$user = User::query()->findOrFail($uid);
$requireBonus = BonusLogs::getBonusForBuyAttendanceCard();
NexusDB::transaction(function () use ($user, $requireBonus) {
$comment = nexus_trans('bonus.comment_buy_attendance_card', [
'bonus' => $requireBonus,
], $user->locale);
do_log("comment: $comment");
2022-05-29 18:22:56 +08:00
$this->consumeUserBonus($user, $requireBonus, BonusLogs::BUSINESS_TYPE_BUY_ATTENDANCE_CARD, $comment);
2022-04-04 17:26:26 +08:00
User::query()->where('id', $user->id)->increment('attendance_card');
});
return true;
}
2022-07-25 03:31:19 +08:00
public function consumeUserBonus($user, $requireBonus, $logBusinessType, $logComment = '', array $userUpdates = [])
2022-01-19 23:54:55 +08:00
{
2022-07-25 03:31:19 +08:00
if (!isset(BonusLogs::$businessTypes[$logBusinessType])) {
throw new \InvalidArgumentException("Invalid logBusinessType: $logBusinessType");
}
if (isset($userUpdates['seedbonus']) || isset($userUpdates['bonuscomment'])) {
throw new \InvalidArgumentException("Not support update seedbonus or bonuscomment");
}
2022-06-08 14:15:59 +08:00
if ($requireBonus <= 0) {
return;
}
2022-07-25 03:31:19 +08:00
$user = $this->getUser($user);
2022-01-19 23:54:55 +08:00
if ($user->seedbonus < $requireBonus) {
do_log("user: {$user->id}, bonus: {$user->seedbonus} < requireBonus: $requireBonus", 'error');
throw new \LogicException("User bonus not enough.");
2022-01-19 23:54:55 +08:00
}
2022-07-25 03:31:19 +08:00
NexusDB::transaction(function () use ($user, $requireBonus, $logBusinessType, $logComment, $userUpdates) {
$logComment = addslashes($logComment);
2022-05-29 18:22:56 +08:00
$bonusComment = date('Y-m-d') . " - $logComment";
2022-01-19 23:54:55 +08:00
$oldUserBonus = $user->seedbonus;
$newUserBonus = bcsub($oldUserBonus, $requireBonus);
$log = "user: {$user->id}, requireBonus: $requireBonus, oldUserBonus: $oldUserBonus, newUserBonus: $newUserBonus, logBusinessType: $logBusinessType, logComment: $logComment";
do_log($log);
2022-07-25 03:31:19 +08:00
$userUpdates['seedbonus'] = $newUserBonus;
$userUpdates['bonuscomment'] = NexusDB::raw("if(bonuscomment = '', '$bonusComment', concat_ws('\n', '$bonusComment', bonuscomment))");
2022-01-19 23:54:55 +08:00
$affectedRows = NexusDB::table($user->getTable())
->where('id', $user->id)
->where('seedbonus', $oldUserBonus)
2022-07-25 03:31:19 +08:00
->update($userUpdates);
2022-01-19 23:54:55 +08:00
if ($affectedRows != 1) {
do_log("update user seedbonus affected rows != 1, query: " . last_query(), 'error');
throw new \RuntimeException("Update user seedbonus fail.");
}
$bonusLog = [
'business_type' => $logBusinessType,
'uid' => $user->id,
'old_total_value' => $oldUserBonus,
'value' => $requireBonus,
'new_total_value' => $newUserBonus,
2022-07-25 03:31:19 +08:00
'comment' => sprintf('[%s] %s', BonusLogs::$businessTypes[$logBusinessType]['text'], $logComment),
2022-01-19 23:54:55 +08:00
];
BonusLogs::query()->insert($bonusLog);
do_log("bonusLog: " . nexus_json_encode($bonusLog));
});
}
2021-06-21 02:01:26 +08:00
}