From 791c617bc0b721c18506ca93b86cf8d3673ca8f2 Mon Sep 17 00:00:00 2001
From: xiaomlove <1939737565@qq.com>
Date: Tue, 30 Dec 2025 12:56:56 +0700
Subject: [PATCH 1/6] token permission cache load from db when not exists
---
app/Models/TrackerUrl.php | 22 ++++++++++++++++------
app/Models/User.php | 27 +++++++++++++++++++++++++--
2 files changed, 41 insertions(+), 8 deletions(-)
diff --git a/app/Models/TrackerUrl.php b/app/Models/TrackerUrl.php
index 9d5f7c4c..b2afbf75 100644
--- a/app/Models/TrackerUrl.php
+++ b/app/Models/TrackerUrl.php
@@ -82,13 +82,23 @@ class TrackerUrl extends NexusModel
if ($redis->exists($notFoundFlagKey)) {
return false;
}
- self::saveUrlCache();
- $result = call_user_func_array([$redis, $command], $params);
- if ($result !== false) {
- return $result;
+ $lockKey = "$notFoundFlagKey:lock";
+ if (!$redis->set($lockKey, 1, ["nx", "ex" => 5])) {
+ return false;
+ }
+ try {
+ self::saveUrlCache();
+ $result = call_user_func_array([$redis, $command], $params);
+ if ($result !== false) {
+ return $result;
+ }
+ //只从 db 拉取一次,仍然没有即标记不存在, 有效期 15 分钟
+ $redis->setex($notFoundFlagKey, 900, date("Y-m-d H:i:s"));
+ } catch (\Throwable $throwable) {
+ do_log($throwable->getMessage(), 'error');
+ } finally {
+ $redis->del($lockKey);
}
- //只从 db 拉取一次,仍然没有即标记不存在, 有效期 15 分钟
- $redis->setex($notFoundFlagKey, 900, date("Y-m-d H:i:s"));
do_log(sprintf("redis command %s with args %s no result", $command, json_encode($params)), 'error');
return false;
}
diff --git a/app/Models/User.php b/app/Models/User.php
index f311115e..a07b5c8b 100644
--- a/app/Models/User.php
+++ b/app/Models/User.php
@@ -5,6 +5,7 @@ namespace App\Models;
use App\Exceptions\NexusException;
use App\Http\Middleware\Locale;
use App\Repositories\ExamRepository;
+use App\Repositories\TokenRepository;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Casts\Attribute;
@@ -626,10 +627,32 @@ class User extends Authenticatable implements FilamentUser, HasName
return is_null($this->original['notifs']) || str_contains($this->notifs, "[{$name}]");
}
- public function tokenCan(string $ability)
+ public function tokenCan(string $ability): bool
{
$redis = NexusDB::redis();
- return $redis->sismember(Setting::USER_TOKEN_PERMISSION_ALLOWED_CACHE_KRY, $ability)
+ $cacheKey = Setting::USER_TOKEN_PERMISSION_ALLOWED_CACHE_KRY;
+ if (!$redis->exists($cacheKey)) {
+ $lockKey = "$cacheKey:lock";
+ if ($redis->set($lockKey, 1, ['nx', 'ex' => 5])) {
+ try {
+ if (!$redis->exists($cacheKey)) {
+ $abilities = TokenRepository::listUserTokenPermissions(false);
+ do_log("load user token permissions: " . json_encode($abilities), 'alert');
+ if (!empty($abilities)) {
+ $redis->sadd($cacheKey, ...$abilities);
+ } else {
+ $redis->sadd($cacheKey, "__NO_USER_TOKEN_PERMISSION__");
+ $redis->expire($cacheKey, 900);
+ }
+ }
+ } catch (\Throwable $throwable) {
+ do_log($throwable->getMessage(), 'error');
+ } finally {
+ $redis->del($lockKey);
+ }
+ }
+ }
+ return $redis->sismember($cacheKey, $ability)
&& $this->accessToken && $this->accessToken->can($ability);
}
From 5f37d5c59ad7cc9f7c1cb92f543883a453cb4774 Mon Sep 17 00:00:00 2001
From: xiaomlove <1939737565@qq.com>
Date: Tue, 30 Dec 2025 15:39:15 +0700
Subject: [PATCH 2/6] usercp add seedbox cancel ip help text
---
public/usercp.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/public/usercp.php b/public/usercp.php
index 11ebbd2b..af64d697 100644
--- a/public/usercp.php
+++ b/public/usercp.php
@@ -1059,7 +1059,7 @@ if (get_setting('seed_box.enabled') == 'yes') {
{$columnComment}
From 0351f92bf467b76605d6d215ced4f22219731547 Mon Sep 17 00:00:00 2001
From: xiaomlove <1939737565@qq.com>
Date: Tue, 30 Dec 2025 17:49:56 +0700
Subject: [PATCH 3/6] [API] comments list
---
app/Http/Controllers/CommentController.php | 11 +----------
app/Http/Resources/CommentResource.php | 10 ++++------
app/Repositories/CommentRepository.php | 21 +++++++++++----------
include/functions.php | 3 +++
routes/api.php | 3 +--
5 files changed, 20 insertions(+), 28 deletions(-)
diff --git a/app/Http/Controllers/CommentController.php b/app/Http/Controllers/CommentController.php
index 866f2694..db282faf 100644
--- a/app/Http/Controllers/CommentController.php
+++ b/app/Http/Controllers/CommentController.php
@@ -25,17 +25,8 @@ class CommentController extends Controller
*/
public function index(Request $request)
{
- $torrentId = $request->torrent_id;
- $with = ['create_user', 'update_user'];
- $comments = Comment::query()
- ->with($with)
- ->where('torrent', $torrentId)
- ->paginate();
+ $comments = $this->repository->getList($request, Auth::user());
$resource = CommentResource::collection($comments);
-// $resource->additional([
-// 'page_title' => nexus_trans('comment.index.page_title'),
-// ]);
-
return $this->success($resource);
}
diff --git a/app/Http/Resources/CommentResource.php b/app/Http/Resources/CommentResource.php
index 4ecaec39..b29e5886 100644
--- a/app/Http/Resources/CommentResource.php
+++ b/app/Http/Resources/CommentResource.php
@@ -15,15 +15,13 @@ class CommentResource extends JsonResource
*/
public function toArray($request)
{
- $descriptionArr = format_description($this->text);
return [
'id' => $this->id,
- 'description' => $descriptionArr,
- 'images' => get_image_from_description($descriptionArr),
- 'updated_at_human' => format_datetime($this->editdate),
- 'created_at_human' => $this->added->format('Y-m-d H:i'),
+ 'text' => $this->text,
+ 'updated_at' => format_datetime($this->editdate),
+ 'created_at' => format_datetime($this->added),
'create_user' => new UserResource($this->whenLoaded('create_user')),
- 'update_user' => new UserResource($this->whenLoaded('update_user')),
+ 'update_user' => $this->when($this->editedby > 0, new UserResource($this->whenLoaded('update_user'))),
];
}
}
diff --git a/app/Repositories/CommentRepository.php b/app/Repositories/CommentRepository.php
index 76722c50..b81195a1 100644
--- a/app/Repositories/CommentRepository.php
+++ b/app/Repositories/CommentRepository.php
@@ -9,26 +9,27 @@ use App\Models\Torrent;
use App\Models\User;
use Carbon\Carbon;
use Hamcrest\Core\Set;
+use Illuminate\Contracts\Auth\Authenticatable;
+use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Nexus\Database\NexusDB;
class CommentRepository extends BaseRepository
{
- public function getList(array $params)
+ public function getList(Request $request, Authenticatable $user)
{
$query = Comment::query()->with(['create_user', 'update_user']);
- if (!empty($params['torrent_id'])) {
- $query->where('torrent', $params['torrent_id']);
+ if (!empty($request->torrent_id)) {
+ $query->where('torrent', $request->torrent_id);
}
- if (!empty($params['offer_id'])) {
- $query->where('offer', $params['offer_id']);
+ if (!empty($request->offer_id)) {
+ $query->where('offer', $request->offer_id);
}
- if (!empty($params['request_id'])) {
- $query->where('request', $params['request_id']);
+ if (!empty($request->request_id)) {
+ $query->where('request', $request->request_id);
}
- list($sortField, $sortType) = $this->getSortFieldAndType($params);
- $query->orderBy($sortField, $sortType);
- return $query->paginate();
+ $query->orderBy('id', 'desc');
+ return $query->paginate($this->getPerPageFromRequest($request));
}
public function store(array $params, User $user)
diff --git a/include/functions.php b/include/functions.php
index 2145b447..948c2cb3 100644
--- a/include/functions.php
+++ b/include/functions.php
@@ -4946,6 +4946,9 @@ function get_searchbox_value($mode = 1, $item = 'showsubcat'){
function get_ratio($userid, $html = true){
$row = get_user_row($userid);
+ if (empty($row)) {
+ return "---";
+ }
$uped = $row['uploaded'];
$downed = $row['downloaded'];
if ($html == true){
diff --git a/routes/api.php b/routes/api.php
index 3f0f2195..ea3d2c1b 100644
--- a/routes/api.php
+++ b/routes/api.php
@@ -29,7 +29,6 @@ Route::group(['middleware' => ['auth:sanctum']], function () {
// Route::resource('messages', \App\Http\Controllers\MessageController::class);
// Route::get('messages-unread', [\App\Http\Controllers\MessageController::class, 'listUnread']);
// Route::resource('torrents', \App\Http\Controllers\TorrentController::class);
-// Route::resource('comments', \App\Http\Controllers\CommentController::class);
// Route::resource('peers', \App\Http\Controllers\PeerController::class);
// Route::resource('files', \App\Http\Controllers\FileController::class);
// Route::resource('thanks', \App\Http\Controllers\ThankController::class);
@@ -56,7 +55,7 @@ Route::group(['middleware' => ['auth:sanctum']], function () {
Route::post('bookmarks', [\App\Http\Controllers\BookmarkController::class, 'store'])->middleware(ability(RoutePermissionEnum::BOOKMARK_STORE));
Route::post('bookmarks/delete', [\App\Http\Controllers\BookmarkController::class, 'destroy'])->middleware(ability(RoutePermissionEnum::BOOKMARK_DELETE));
-
+ Route::get('comments', [\App\Http\Controllers\CommentController::class, 'index'])->middleware(ability(RoutePermissionEnum::TORRENT_VIEW));
});
From 8d98a7dd8b34b4649b4303463ec7dc0a23c65bc4 Mon Sep 17 00:00:00 2001
From: xiaomlove <1939737565@qq.com>
Date: Wed, 31 Dec 2025 02:39:07 +0700
Subject: [PATCH 4/6] ptgen fill small title add field: chinese_title
---
public/js/ptgen.js | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/public/js/ptgen.js b/public/js/ptgen.js
index 99d57a71..73c75f09 100644
--- a/public/js/ptgen.js
+++ b/public/js/ptgen.js
@@ -20,7 +20,11 @@ jQuery('.btn-get-pt-gen').on('click', function () {
}
doInsert(response.data.format, '', false)
if (response.data.aka && response.data.site === 'douban') {
- form.find("input[name=small_descr]").val(response.data.aka.join("/"))
+ let aka = response.data.aka
+ if (response.data.chinese_title) {
+ aka.unshift(response.data.chinese_title)
+ }
+ form.find("input[name=small_descr]").val(aka.join("/"))
}
if (response.data.imdb_link) {
form.find("input[data-pt-gen=url]").val(response.data.imdb_link)
From da4a609ef72d6f04a43b47bb346b3476034773a3 Mon Sep 17 00:00:00 2001
From: xiaomlove <1939737565@qq.com>
Date: Wed, 7 Jan 2026 01:20:44 +0700
Subject: [PATCH 5/6] claim settle add bonus log
---
app/Models/BonusLogs.php | 2 ++
app/Repositories/ClaimRepository.php | 17 +++++++++++++----
resources/lang/en/bonus-log.php | 2 ++
resources/lang/zh_CN/bonus-log.php | 2 ++
resources/lang/zh_TW/bonus-log.php | 2 ++
5 files changed, 21 insertions(+), 4 deletions(-)
diff --git a/app/Models/BonusLogs.php b/app/Models/BonusLogs.php
index 4bfd1019..edb99715 100644
--- a/app/Models/BonusLogs.php
+++ b/app/Models/BonusLogs.php
@@ -42,6 +42,7 @@ class BonusLogs extends NexusModel
const BUSINESS_TYPE_TASK_NOT_PASS_DEDUCT = 20;
const BUSINESS_TYPE_TASK_PASS_REWARD = 21;
const BUSINESS_TYPE_REWARD_TORRENT = 22;
+ const BUSINESS_TYPE_CLAIMED_UNREACHED = 23;
//获得类,普通获得,1000 起步
const BUSINESS_TYPE_ROLE_WORK_SALARY = 1000;
@@ -50,6 +51,7 @@ class BonusLogs extends NexusModel
const BUSINESS_TYPE_RECEIVE_GIFT = 1003;
const BUSINESS_TYPE_UPLOAD_TORRENT = 1004;
const BUSINESS_TYPE_TORRENT_BE_REWARD = 1005;
+ const BUSINESS_TYPE_CLAIMED_REACHED = 1006;
//获得类,做种获得,10000 起
const BUSINESS_TYPE_SEEDING_BASIC = 10000;
diff --git a/app/Repositories/ClaimRepository.php b/app/Repositories/ClaimRepository.php
index ff19b7ca..1aa53e5a 100644
--- a/app/Repositories/ClaimRepository.php
+++ b/app/Repositories/ClaimRepository.php
@@ -2,6 +2,7 @@
namespace App\Repositories;
use App\Jobs\SettleClaim;
+use App\Models\BonusLogs;
use App\Models\Claim;
use App\Models\Message;
use App\Models\Snatch;
@@ -260,16 +261,24 @@ class ClaimRepository extends BaseRepository
//Wrap with transaction
DB::transaction(function () use ($uid, $unReachedIdArr, $toUpdateIdArr, $bonusFinal, $totalDeduct, $uploadedCaseWhen, $seedTimeCaseWhen, $message, $now) {
+ //get latest
+ $oldBonus = User::query()->find($uid, ['seedbonus'])->seedbonus;
+ $delta = 0;
//Increase user bonus
- User::query()->where('id', $uid)->increment('seedbonus', $bonusFinal);
- do_log("Increase user bonus: $bonusFinal", 'alert');
+ $delta += $bonusFinal;
+ do_log("Increase user: $uid bonus: $bonusFinal", 'alert');
+ BonusLogs::add($uid, $oldBonus, $bonusFinal, $oldBonus + $bonusFinal, "", BonusLogs::BUSINESS_TYPE_CLAIMED_REACHED);
+ $oldBonus += $bonusFinal;
//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');
+ $delta -= $totalDeduct;
+ do_log("Deduct user: $uid bonus: $totalDeduct", 'alert');
+ BonusLogs::add($uid, $oldBonus, $totalDeduct, $oldBonus - $totalDeduct, "", BonusLogs::BUSINESS_TYPE_CLAIMED_UNREACHED);
+ $oldBonus -= $totalDeduct;
}
+ User::query()->where('id', $uid)->increment('seedbonus', $delta);
//Update claim `last_settle_at` and init `seed_time_begin` & `uploaded_begin`
if (!empty($toUpdateIdArr)) {
diff --git a/resources/lang/en/bonus-log.php b/resources/lang/en/bonus-log.php
index 93770f59..7b0ff6ce 100644
--- a/resources/lang/en/bonus-log.php
+++ b/resources/lang/en/bonus-log.php
@@ -22,6 +22,7 @@ return [
\App\Models\BonusLogs::BUSINESS_TYPE_GIFT_MEDAL => 'Gift medal',
\App\Models\BonusLogs::BUSINESS_TYPE_BUY_TORRENT => 'Buy torrent',
\App\Models\BonusLogs::BUSINESS_TYPE_REWARD_TORRENT => 'Reward torrent',
+ \App\Models\BonusLogs::BUSINESS_TYPE_CLAIMED_UNREACHED => 'Claimed torrent unreached',
\App\Models\BonusLogs::BUSINESS_TYPE_ROLE_WORK_SALARY => 'Role work salary',
\App\Models\BonusLogs::BUSINESS_TYPE_TORRENT_BE_DOWNLOADED => 'Torrent be downloaded',
@@ -29,6 +30,7 @@ return [
\App\Models\BonusLogs::BUSINESS_TYPE_RECEIVE_GIFT => 'Receive gift',
\App\Models\BonusLogs::BUSINESS_TYPE_UPLOAD_TORRENT => 'Upload torrent',
\App\Models\BonusLogs::BUSINESS_TYPE_TORRENT_BE_REWARD => 'Torrent receive reward',
+ \App\Models\BonusLogs::BUSINESS_TYPE_CLAIMED_REACHED => 'Claimed torrent reached reward',
\App\Models\BonusLogs::BUSINESS_TYPE_SEEDING_BASIC => 'Seeding basic',
\App\Models\BonusLogs::BUSINESS_TYPE_SEEDING_DONOR_ADDITION => 'Seeding donor addition',
diff --git a/resources/lang/zh_CN/bonus-log.php b/resources/lang/zh_CN/bonus-log.php
index cce264fe..e82d3875 100644
--- a/resources/lang/zh_CN/bonus-log.php
+++ b/resources/lang/zh_CN/bonus-log.php
@@ -24,6 +24,7 @@ return [
\App\Models\BonusLogs::BUSINESS_TYPE_TASK_PASS_REWARD => '任务完成奖励',
\App\Models\BonusLogs::BUSINESS_TYPE_TASK_NOT_PASS_DEDUCT => '任务未完成扣除',
\App\Models\BonusLogs::BUSINESS_TYPE_REWARD_TORRENT => '奖励种子',
+ \App\Models\BonusLogs::BUSINESS_TYPE_CLAIMED_UNREACHED => '认领种子未达标扣除',
\App\Models\BonusLogs::BUSINESS_TYPE_ROLE_WORK_SALARY => '工作组工资',
\App\Models\BonusLogs::BUSINESS_TYPE_TORRENT_BE_DOWNLOADED => '种子被下载',
@@ -31,6 +32,7 @@ return [
\App\Models\BonusLogs::BUSINESS_TYPE_RECEIVE_GIFT => '收到礼物',
\App\Models\BonusLogs::BUSINESS_TYPE_UPLOAD_TORRENT => '发布种子',
\App\Models\BonusLogs::BUSINESS_TYPE_TORRENT_BE_REWARD => '种子收到奖励',
+ \App\Models\BonusLogs::BUSINESS_TYPE_CLAIMED_REACHED => '认领种子达标奖励',
\App\Models\BonusLogs::BUSINESS_TYPE_SEEDING_BASIC => '做种基础魔力',
\App\Models\BonusLogs::BUSINESS_TYPE_SEEDING_DONOR_ADDITION => '做种捐赠加成',
diff --git a/resources/lang/zh_TW/bonus-log.php b/resources/lang/zh_TW/bonus-log.php
index ebba6191..6c8bd0f4 100644
--- a/resources/lang/zh_TW/bonus-log.php
+++ b/resources/lang/zh_TW/bonus-log.php
@@ -22,6 +22,7 @@ return [
\App\Models\BonusLogs::BUSINESS_TYPE_GIFT_MEDAL => '贈送勛章',
\App\Models\BonusLogs::BUSINESS_TYPE_BUY_TORRENT => '購買種子',
\App\Models\BonusLogs::BUSINESS_TYPE_REWARD_TORRENT => '獎勵種子',
+ \App\Models\BonusLogs::BUSINESS_TYPE_CLAIMED_UNREACHED => '認領種子未達標扣除',
\App\Models\BonusLogs::BUSINESS_TYPE_ROLE_WORK_SALARY => '工作組工資',
\App\Models\BonusLogs::BUSINESS_TYPE_TORRENT_BE_DOWNLOADED => '種子被下載',
@@ -29,6 +30,7 @@ return [
\App\Models\BonusLogs::BUSINESS_TYPE_RECEIVE_GIFT => '收到禮物',
\App\Models\BonusLogs::BUSINESS_TYPE_UPLOAD_TORRENT => '發布種子',
\App\Models\BonusLogs::BUSINESS_TYPE_TORRENT_BE_REWARD => '種子收到獎勵',
+ \App\Models\BonusLogs::BUSINESS_TYPE_CLAIMED_REACHED => '認領種子達標獎勵',
\App\Models\BonusLogs::BUSINESS_TYPE_SEEDING_BASIC => '做種基礎魔力',
\App\Models\BonusLogs::BUSINESS_TYPE_SEEDING_DONOR_ADDITION => '做種捐贈加成',
From f20771353e2432766b8b80d693a63ae305144a4f Mon Sep 17 00:00:00 2001
From: xiaomlove <1939737565@qq.com>
Date: Wed, 7 Jan 2026 01:30:21 +0700
Subject: [PATCH 6/6] new bonus type serchable
---
app/Filament/Resources/User/BonusLogResource.php | 1 +
app/Models/BonusLogs.php | 2 ++
2 files changed, 3 insertions(+)
diff --git a/app/Filament/Resources/User/BonusLogResource.php b/app/Filament/Resources/User/BonusLogResource.php
index fa949bfb..6b18fccd 100644
--- a/app/Filament/Resources/User/BonusLogResource.php
+++ b/app/Filament/Resources/User/BonusLogResource.php
@@ -89,6 +89,7 @@ class BonusLogResource extends Resource
Tables\Filters\SelectFilter::make('business_type')
->options(BonusLogs::listStaticProps(Arr::except(BonusLogs::$businessTypes, BonusLogs::$businessTypeBonus), 'bonus-log.business_types', true))
->label(__('bonus-log.fields.business_type'))
+ ->searchable(true)
,
// Tables\Filters\Filter::make('exclude_seeding_bonus')
// ->toggle()
diff --git a/app/Models/BonusLogs.php b/app/Models/BonusLogs.php
index edb99715..d7e916cb 100644
--- a/app/Models/BonusLogs.php
+++ b/app/Models/BonusLogs.php
@@ -83,6 +83,7 @@ class BonusLogs extends NexusModel
self::BUSINESS_TYPE_TASK_NOT_PASS_DEDUCT => ['text' => 'Task failure penalty'],
self::BUSINESS_TYPE_TASK_PASS_REWARD => ['text' => 'Task success reward'],
self::BUSINESS_TYPE_REWARD_TORRENT => ['text' => 'Reward torrent'],
+ self::BUSINESS_TYPE_CLAIMED_UNREACHED => ['text' => 'Claimed torrent unreached'],
self::BUSINESS_TYPE_ROLE_WORK_SALARY => ['text' => 'Role work salary'],
self::BUSINESS_TYPE_TORRENT_BE_DOWNLOADED => ['text' => 'Torrent be downloaded'],
@@ -90,6 +91,7 @@ class BonusLogs extends NexusModel
self::BUSINESS_TYPE_RECEIVE_GIFT => ['text' => 'Receive gift'],
self::BUSINESS_TYPE_UPLOAD_TORRENT => ['text' => 'Upload torrent'],
self::BUSINESS_TYPE_TORRENT_BE_REWARD => ['text' => 'Torrent be reward'],
+ self::BUSINESS_TYPE_CLAIMED_REACHED => ['text' => 'Claimed torrent reached'],
self::BUSINESS_TYPE_SEEDING_BASIC => ['text' => 'Seeding basic'],
self::BUSINESS_TYPE_SEEDING_DONOR_ADDITION => ['text' => 'Seeding donor addition'],