|
|
|
@@ -1,16 +1,13 @@
|
|
|
|
|
<?php
|
|
|
|
|
namespace App\Repositories;
|
|
|
|
|
|
|
|
|
|
use App\Models\BonusLogs;
|
|
|
|
|
use App\Models\Claim;
|
|
|
|
|
use App\Models\Message;
|
|
|
|
|
use App\Models\Setting;
|
|
|
|
|
use App\Models\Snatch;
|
|
|
|
|
use App\Models\Torrent;
|
|
|
|
|
use App\Models\User;
|
|
|
|
|
use Carbon\Carbon;
|
|
|
|
|
use Illuminate\Support\Facades\DB;
|
|
|
|
|
use JetBrains\PhpStorm\ArrayShape;
|
|
|
|
|
use Nexus\Database\NexusDB;
|
|
|
|
|
|
|
|
|
|
class ClaimRepository extends BaseRepository
|
|
|
|
@@ -27,6 +24,10 @@ class ClaimRepository extends BaseRepository
|
|
|
|
|
|
|
|
|
|
public function store($uid, $torrentId)
|
|
|
|
|
{
|
|
|
|
|
$isEnabled = Claim::getConfigIsEnabled();
|
|
|
|
|
if ($isEnabled) {
|
|
|
|
|
throw new \RuntimeException(nexus_trans("torrent.claim_disabled"));
|
|
|
|
|
}
|
|
|
|
|
$exists = Claim::query()->where('uid', $uid)->where('torrent_id', $torrentId)->exists();
|
|
|
|
|
if ($exists) {
|
|
|
|
|
throw new \RuntimeException(nexus_trans("torrent.claim_already"));
|
|
|
|
@@ -34,7 +35,12 @@ class ClaimRepository extends BaseRepository
|
|
|
|
|
$max = Claim::getConfigTorrentUpLimit();
|
|
|
|
|
$count = Claim::query()->where('uid', $uid)->count();
|
|
|
|
|
if ($count >= $max) {
|
|
|
|
|
throw new \RuntimeException(nexus_trans("torrent.claim_number_reach_maximum"));
|
|
|
|
|
throw new \RuntimeException(nexus_trans("torrent.claim_number_reach_torrent_maximum"));
|
|
|
|
|
}
|
|
|
|
|
$max = Claim::getConfigUserUpLimit();
|
|
|
|
|
$count = Claim::query()->where('torrent_id', $torrentId)->count();
|
|
|
|
|
if ($count >= $max) {
|
|
|
|
|
throw new \RuntimeException(nexus_trans("torrent.claim_number_reach_user_maximum"));
|
|
|
|
|
}
|
|
|
|
|
$snatch = Snatch::query()->where('userid', $uid)->where('torrentid', $torrentId)->first();
|
|
|
|
|
if (!$snatch) {
|
|
|
|
@@ -70,6 +76,10 @@ class ClaimRepository extends BaseRepository
|
|
|
|
|
|
|
|
|
|
public function delete($id, $uid)
|
|
|
|
|
{
|
|
|
|
|
$isEnabled = Claim::getConfigIsEnabled();
|
|
|
|
|
if ($isEnabled) {
|
|
|
|
|
throw new \RuntimeException(nexus_trans("torrent.claim_disabled"));
|
|
|
|
|
}
|
|
|
|
|
$model = Claim::query()->findOrFail($id);
|
|
|
|
|
if ($model->uid != $uid) {
|
|
|
|
|
throw new \RuntimeException("No permission");
|
|
|
|
@@ -93,29 +103,38 @@ class ClaimRepository extends BaseRepository
|
|
|
|
|
|
|
|
|
|
public function settleCronjob(): array
|
|
|
|
|
{
|
|
|
|
|
$query = Claim::query()->select(['uid'])->groupBy('uid');
|
|
|
|
|
$startOfThisMonth = Carbon::now()->startOfMonth();
|
|
|
|
|
$query = Claim::query()
|
|
|
|
|
->select(['uid'])
|
|
|
|
|
->where('last_settle_at', '<', $startOfThisMonth)
|
|
|
|
|
->groupBy('uid')
|
|
|
|
|
;
|
|
|
|
|
$size = 10000;
|
|
|
|
|
$page = 1;
|
|
|
|
|
$successCount = $failCount = 0;
|
|
|
|
|
while (true) {
|
|
|
|
|
$logPrefix = "page: $page, size: $size";
|
|
|
|
|
$result = (clone $query)->forPage($page, $size)->get();
|
|
|
|
|
$logPrefix = "size: $size";
|
|
|
|
|
$result = (clone $query)->take($size)->get();
|
|
|
|
|
if ($result->isEmpty()) {
|
|
|
|
|
do_log("$logPrefix, no more data...");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
do_log("get counts: " . $result->count());
|
|
|
|
|
foreach ($result as $row) {
|
|
|
|
|
$uid = $row->uid;
|
|
|
|
|
do_log("$logPrefix, begin to settle user: $uid...");
|
|
|
|
|
$result = $this->settleUser($row->uid);
|
|
|
|
|
do_log("$logPrefix, settle user: $uid done!, result: " . var_export($result, true));
|
|
|
|
|
if ($result) {
|
|
|
|
|
$successCount++;
|
|
|
|
|
} else {
|
|
|
|
|
try {
|
|
|
|
|
$result = $this->settleUser($uid);
|
|
|
|
|
do_log("$logPrefix, settle user: $uid done!, result: " . var_export($result, true));
|
|
|
|
|
if ($result) {
|
|
|
|
|
$successCount++;
|
|
|
|
|
} else {
|
|
|
|
|
$failCount++;
|
|
|
|
|
}
|
|
|
|
|
} catch (\Throwable $exception) {
|
|
|
|
|
do_log("$logPrefix, settle user: $uid fail!, error: " . $exception->getMessage() . $exception->getTraceAsString(), 'error');
|
|
|
|
|
$failCount++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
$page++;
|
|
|
|
|
}
|
|
|
|
|
return ['success_count' => $successCount, 'fail_count' => $failCount];
|
|
|
|
|
}
|
|
|
|
@@ -185,6 +204,12 @@ class ClaimRepository extends BaseRepository
|
|
|
|
|
$totalDeduct = $bonusDeduct * count($unReachedIdArr);
|
|
|
|
|
do_log("totalDeduct: $totalDeduct", 'alert');
|
|
|
|
|
|
|
|
|
|
$message = $this->buildMessage(
|
|
|
|
|
$user, $reachedTorrentIdArr, $unReachedTorrentIdArr, $remainTorrentIdArr,
|
|
|
|
|
$bonusResult, $bonusFinal, $seedTimeHoursAvg, $bonusDeduct, $totalDeduct
|
|
|
|
|
);
|
|
|
|
|
do_log("message: " . nexus_json_encode($message), 'alert');
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Just do a test, debug from log
|
|
|
|
|
*/
|
|
|
|
@@ -193,35 +218,50 @@ class ClaimRepository extends BaseRepository
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//Increase user bonus
|
|
|
|
|
User::query()->where('id', $uid)->increment('seedbonus', $bonusFinal);
|
|
|
|
|
do_log("Increase user bonus: $bonusFinal", 'alert');
|
|
|
|
|
//Wrap with transaction
|
|
|
|
|
DB::transaction(function () use ($uid, $unReachedIdArr, $toUpdateIdArr, $bonusFinal, $totalDeduct, $uploadedCaseWhen, $seedTimeCaseWhen, $message, $now) {
|
|
|
|
|
//Increase user bonus
|
|
|
|
|
User::query()->where('id', $uid)->increment('seedbonus', $bonusFinal);
|
|
|
|
|
do_log("Increase user bonus: $bonusFinal", 'alert');
|
|
|
|
|
|
|
|
|
|
//Handle unreached
|
|
|
|
|
if (!empty($unReachedIdArr)) {
|
|
|
|
|
Claim::query()->whereIn('id', $unReachedIdArr)->delete();
|
|
|
|
|
User::query()->where('id', $uid)->decrement('seedbonus', $totalDeduct);
|
|
|
|
|
do_log("Deduct user bonus: $totalDeduct", 'alert');
|
|
|
|
|
}
|
|
|
|
|
//Handle unreached
|
|
|
|
|
if (!empty($unReachedIdArr)) {
|
|
|
|
|
Claim::query()->whereIn('id', $unReachedIdArr)->delete();
|
|
|
|
|
User::query()->where('id', $uid)->decrement('seedbonus', $totalDeduct);
|
|
|
|
|
do_log("Deduct user bonus: $totalDeduct", 'alert');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//Update claim `last_settle_at` and init `seed_time_begin` & `uploaded_begin`
|
|
|
|
|
$sql = sprintf(
|
|
|
|
|
"update claims set uploaded_begin = case id %s end, seed_time_begin = case id %s end, last_settle_at = '%s', updated_at = '%s' where id in (%s)",
|
|
|
|
|
implode(' ', $uploadedCaseWhen), implode(' ', $seedTimeCaseWhen), $now->toDateTimeString(), $now->toDateTimeString(), implode(',', $toUpdateIdArr)
|
|
|
|
|
);
|
|
|
|
|
$affectedRows = DB::update($sql);
|
|
|
|
|
do_log("query: $sql, affectedRows: $affectedRows");
|
|
|
|
|
//Update claim `last_settle_at` and init `seed_time_begin` & `uploaded_begin`
|
|
|
|
|
$sql = sprintf(
|
|
|
|
|
"update claims set uploaded_begin = case id %s end, seed_time_begin = case id %s end, last_settle_at = '%s', updated_at = '%s' where id in (%s)",
|
|
|
|
|
implode(' ', $uploadedCaseWhen), implode(' ', $seedTimeCaseWhen), $now->toDateTimeString(), $now->toDateTimeString(), implode(',', $toUpdateIdArr)
|
|
|
|
|
);
|
|
|
|
|
$affectedRows = DB::update($sql);
|
|
|
|
|
do_log("query: $sql, affectedRows: $affectedRows");
|
|
|
|
|
|
|
|
|
|
//Send message
|
|
|
|
|
//Send message
|
|
|
|
|
Message::query()->insert($message);
|
|
|
|
|
});
|
|
|
|
|
do_log("[DONE], cost time: " . (time() - $now->timestamp) . " seconds");
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private function buildMessage(
|
|
|
|
|
User $user, $reachedTorrentIdArr, $unReachedTorrentIdArr, $remainTorrentIdArr,
|
|
|
|
|
$bonusResult, $bonusFinal, $seedTimeHoursAvg, $deductPerTorrent, $deductTotal
|
|
|
|
|
) {
|
|
|
|
|
$now = Carbon::now();
|
|
|
|
|
$allTorrentIdArr = array_merge($reachedTorrentIdArr, $unReachedTorrentIdArr, $remainTorrentIdArr);
|
|
|
|
|
$torrentInfo = Torrent::query()
|
|
|
|
|
->whereIn('id', array_merge($reachedTorrentIdArr, $unReachedTorrentIdArr, $remainTorrentIdArr))
|
|
|
|
|
->whereIn('id', $allTorrentIdArr)
|
|
|
|
|
->get(Torrent::$commentFields)
|
|
|
|
|
->keyBy('id')
|
|
|
|
|
;
|
|
|
|
|
$msg = [];
|
|
|
|
|
$locale = $user->locale;
|
|
|
|
|
do_log("build message, user: {$user->id}, locale: $locale");
|
|
|
|
|
$msg[] = nexus_trans('claim.msg_title', ['month' => $now->clone()->subMonths(1)->format('Y-m')], $locale);
|
|
|
|
|
$msg[] = nexus_trans('claim.claim_total', [ 'total' => $list->count()], $locale);
|
|
|
|
|
$msg[] = nexus_trans('claim.claim_total', [ 'total' => count($allTorrentIdArr)], $locale);
|
|
|
|
|
|
|
|
|
|
$reachList = collect($reachedTorrentIdArr)->map(
|
|
|
|
|
fn($item) => sprintf("[url=details.php?id=%s]%s[/url]", $item, $torrentInfo->get($item)->name)
|
|
|
|
@@ -229,10 +269,10 @@ class ClaimRepository extends BaseRepository
|
|
|
|
|
$msg[] = nexus_trans("claim.claim_reached_counts", ['counts' => count($reachedTorrentIdArr)], $locale) . "\n$reachList";
|
|
|
|
|
$msg[] = nexus_trans(
|
|
|
|
|
"claim.claim_reached_summary", [
|
|
|
|
|
'bonus_per_hour' => number_format($bonusResult['seed_bonus'], 2),
|
|
|
|
|
'hours'=> number_format($seedTimeHoursAvg, 2),
|
|
|
|
|
'bonus_total'=> number_format($bonusFinal, 2)
|
|
|
|
|
], $locale
|
|
|
|
|
'bonus_per_hour' => number_format($bonusResult['seed_bonus'], 2),
|
|
|
|
|
'hours'=> number_format($seedTimeHoursAvg, 2),
|
|
|
|
|
'bonus_total'=> number_format($bonusFinal, 2)
|
|
|
|
|
], $locale
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
$remainList = collect($remainTorrentIdArr)->map(
|
|
|
|
@@ -244,24 +284,19 @@ class ClaimRepository extends BaseRepository
|
|
|
|
|
fn($item) => sprintf("[url=details.php?id=%s]%s[/url]", $item, $torrentInfo->get($item)->name)
|
|
|
|
|
)->implode("\n");
|
|
|
|
|
$msg[] = nexus_trans("claim.claim_unreached_remove_counts", ['counts' => count($unReachedTorrentIdArr)], $locale) . "\n$unReachList";
|
|
|
|
|
if ($totalDeduct) {
|
|
|
|
|
if ($deductTotal) {
|
|
|
|
|
$msg[] = nexus_trans(
|
|
|
|
|
"claim.claim_unreached_summary", [
|
|
|
|
|
'deduct_per_torrent '=> number_format($bonusDeduct, 2),
|
|
|
|
|
'deduct_total' => number_format($totalDeduct, 2)
|
|
|
|
|
], $locale
|
|
|
|
|
'deduct_per_torrent '=> number_format($deductPerTorrent, 2),
|
|
|
|
|
'deduct_total' => number_format($deductTotal, 2)
|
|
|
|
|
], $locale
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$message = [
|
|
|
|
|
'receiver' => $uid,
|
|
|
|
|
return [
|
|
|
|
|
'receiver' => $user->id,
|
|
|
|
|
'added' => $now,
|
|
|
|
|
'subject' => nexus_trans('claim.msg_subject', ['month' => $now->clone()->subMonths(1)->format('Y-m')], $locale),
|
|
|
|
|
'msg' => implode("\n\n", $msg),
|
|
|
|
|
];
|
|
|
|
|
Message::query()->insert($message);
|
|
|
|
|
|
|
|
|
|
do_log("[DONE], cost time: " . (time() - $now->timestamp) . " seconds");
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|