diff --git a/app/Console/Commands/Test.php b/app/Console/Commands/Test.php index 5650c025..42e90efa 100644 --- a/app/Console/Commands/Test.php +++ b/app/Console/Commands/Test.php @@ -95,7 +95,7 @@ class Test extends Command public function handle() { $rep = new WorkRepository(); - $rep->settleRole(5); + $rep->settleRole(4); } diff --git a/app/Filament/Resources/Torrent/TorrentOperationLogResource.php b/app/Filament/Resources/Torrent/TorrentOperationLogResource.php new file mode 100644 index 00000000..253786a3 --- /dev/null +++ b/app/Filament/Resources/Torrent/TorrentOperationLogResource.php @@ -0,0 +1,110 @@ +schema([ + // + ]); + } + + public static function table(Table $table): Table + { + return $table + ->columns([ + Tables\Columns\TextColumn::make('id')->sortable(), + Tables\Columns\TextColumn::make('user.username') + ->formatStateUsing(fn ($record) => username_for_admin($record->uid)) + ->label(__('label.user.label')) + , + Tables\Columns\TextColumn::make('torrent.name') + ->formatStateUsing(fn ($record) => torrent_name_for_admin($record->torrent)) + ->label(__('label.torrent.label')) + , + Tables\Columns\TextColumn::make('action_type_text') + ->label(__('torrent-operation-log.fields.action_type')) + , + Tables\Columns\TextColumn::make('comment') + ->label(__('label.comment')) + , + + Tables\Columns\TextColumn::make('created_at') + ->formatStateUsing(fn ($state) => format_datetime($state)) + ->label(__('label.created_at')) + , + ]) + ->filters([ + Tables\Filters\Filter::make('uid') + ->form([ + Forms\Components\TextInput::make('uid') + ->placeholder('UID') + , + ])->query(function (Builder $query, array $data) { + return $query->when($data['uid'], fn (Builder $query, $value) => $query->where("uid", $value)); + }) + , + Tables\Filters\Filter::make('torrent_id') + ->form([ + Forms\Components\TextInput::make('torrent_id') + ->placeholder('Torrent ID') + , + ])->query(function (Builder $query, array $data) { + return $query->when($data['torrent_id'], fn (Builder $query, $value) => $query->where("torrent_id", $value)); + }) + , + Tables\Filters\SelectFilter::make('action_type') + ->options(TorrentOperationLog::listStaticProps(TorrentOperationLog::$actionTypes, 'torrent.operation_log.%s.type_text', true)) + ->label(__('torrent-operation-log.fields.action_type')) + ->multiple() + , + ]) + ->actions([ +// Tables\Actions\EditAction::make(), +// Tables\Actions\DeleteAction::make(), + ]) + ->bulkActions([ +// Tables\Actions\DeleteBulkAction::make(), + ]); + } + + public static function getPages(): array + { + return [ + 'index' => Pages\ManageTorrentOperationLogs::route('/'), + ]; + } +} diff --git a/app/Filament/Resources/Torrent/TorrentOperationLogResource/Pages/ManageTorrentOperationLogs.php b/app/Filament/Resources/Torrent/TorrentOperationLogResource/Pages/ManageTorrentOperationLogs.php new file mode 100644 index 00000000..e3006574 --- /dev/null +++ b/app/Filament/Resources/Torrent/TorrentOperationLogResource/Pages/ManageTorrentOperationLogs.php @@ -0,0 +1,27 @@ +with(['torrent', 'user']); + } +} diff --git a/app/Filament/Resources/Torrent/TorrentResource.php b/app/Filament/Resources/Torrent/TorrentResource.php index 6d8e913e..bc3dc405 100644 --- a/app/Filament/Resources/Torrent/TorrentResource.php +++ b/app/Filament/Resources/Torrent/TorrentResource.php @@ -6,6 +6,7 @@ use App\Filament\OptionsTrait; use App\Filament\Resources\Torrent\TorrentResource\Pages; use App\Filament\Resources\Torrent\TorrentResource\RelationManagers; use App\Models\Category; +use App\Models\SearchBox; use App\Models\Setting; use App\Models\Tag; use App\Models\Torrent; @@ -27,6 +28,7 @@ use Illuminate\Support\Facades\Auth; use Illuminate\Support\HtmlString; use Illuminate\Support\Str; use Illuminate\Validation\Rule; +use Nexus\Database\NexusDB; class TorrentResource extends Resource { @@ -75,23 +77,18 @@ class TorrentResource extends Resource ->columns([ Tables\Columns\TextColumn::make('id')->sortable(), Tables\Columns\TextColumn::make('basic_category.name')->label(__('label.torrent.category')), - Tables\Columns\TextColumn::make('name')->formatStateUsing(function (Torrent $record) { - $name = sprintf( - '
%s
', - $record->id, $record->name, Str::limit($record->name, 40) - ); - $tags = sprintf(' 
%s
', $record->tagsFormatted); - - return new HtmlString('
' . $name . $tags . '
'); - })->label(__('label.name'))->searchable(), + Tables\Columns\TextColumn::make('name')->formatStateUsing(fn ($record) => torrent_name_for_admin($record, true)) + ->label(__('label.name')) + ->searchable(), Tables\Columns\TextColumn::make('posStateText')->label(__('label.torrent.pos_state')), Tables\Columns\TextColumn::make('spStateText')->label(__('label.torrent.sp_state')), Tables\Columns\TextColumn::make('pickInfoText') ->label(__('label.torrent.picktype')) ->formatStateUsing(fn ($record) => $record->pickInfo['text']) , - Tables\Columns\BooleanColumn::make('hr') + Tables\Columns\IconColumn::make('hr') ->label(__('label.torrent.hr')) + ->boolean() , Tables\Columns\TextColumn::make('size') ->label(__('label.torrent.size')) @@ -108,55 +105,11 @@ class TorrentResource extends Resource Tables\Columns\TextColumn::make('added')->label(__('label.added'))->dateTime(), Tables\Columns\TextColumn::make('user.username') ->label(__('label.torrent.owner')) - ->formatStateUsing(fn ($record) => new HtmlString(get_username($record->owner, false, true, true, true))) + ->formatStateUsing(fn ($record) => username_for_admin($record->owner)) , ]) ->defaultSort('id', 'desc') - ->filters([ - Tables\Filters\Filter::make('owner') - ->form([ - Forms\Components\TextInput::make('owner') - ->label(__('label.torrent.owner')) - ->placeholder('UID') - , - ])->query(function (Builder $query, array $data) { - return $query->when($data['owner'], fn (Builder $query, $owner) => $query->where("owner", $owner)); - }) - , - Tables\Filters\SelectFilter::make('category') - ->options(Category::query()->pluck('name', 'id')->toArray()) - ->label(__('label.torrent.category')), - - Tables\Filters\SelectFilter::make('visible') - ->options(self::$yesOrNo) - ->label(__('label.torrent.visible')), - - Tables\Filters\SelectFilter::make('pos_state') - ->options(Torrent::listPosStates(true)) - ->label(__('label.torrent.pos_state')), - - Tables\Filters\SelectFilter::make('sp_state') - ->options(Torrent::listPromotionTypes(true)) - ->label(__('label.torrent.sp_state')), - - Tables\Filters\SelectFilter::make('picktype') - ->options(Torrent::listPickInfo(true)) - ->label(__('label.torrent.picktype')), - - Tables\Filters\SelectFilter::make('approval_status') - ->options(Torrent::listApprovalStatus(true)) - ->visible($showApproval) - ->label(__('label.torrent.approval_status')), - - Tables\Filters\SelectFilter::make('hr') - ->options(self::getYesNoOptions()) - ->label(__('label.torrent.hr')), - - Tables\Filters\SelectFilter::make('tags') - ->relationship('tags', 'name') - ->label(__('label.tag.label')) - , - ]) + ->filters(self::getFilters()) ->actions(self::getActions()) ->bulkActions(self::getBulkActions()); @@ -394,4 +347,117 @@ class TorrentResource extends Resource // return Setting::get('torrent.approval_status_none_visible') == 'no' || Setting::get('torrent.approval_status_icon_enabled') == 'yes'; } + private static function getFilters() + { + $filters = [ + Tables\Filters\Filter::make('owner') + ->form([ + Forms\Components\TextInput::make('owner') + ->label(__('label.torrent.owner')) + ->placeholder('UID') + , + ])->query(function (Builder $query, array $data) { + return $query->when($data['owner'], fn (Builder $query, $owner) => $query->where("owner", $owner)); + }) + , + + Tables\Filters\SelectFilter::make('visible') + ->options(self::$yesOrNo) + ->label(__('label.torrent.visible')) + , + Tables\Filters\SelectFilter::make('hr') + ->options(self::getYesNoOptions()) + ->label(__('label.torrent.hr')) + , + + Tables\Filters\SelectFilter::make('pos_state') + ->options(Torrent::listPosStates(true)) + ->label(__('label.torrent.pos_state')) + ->multiple() + , + + Tables\Filters\SelectFilter::make('sp_state') + ->options(Torrent::listPromotionTypes(true)) + ->label(__('label.torrent.sp_state')) + ->multiple() + , + + Tables\Filters\SelectFilter::make('picktype') + ->options(Torrent::listPickInfo(true)) + ->label(__('label.torrent.picktype')) + ->multiple() + , + + Tables\Filters\SelectFilter::make('approval_status') + ->options(Torrent::listApprovalStatus(true)) + ->label(__('label.torrent.approval_status')) + ->multiple() + , + + Tables\Filters\SelectFilter::make('tags') + ->relationship('tags', 'name') + ->label(__('label.tag.label')) + ->multiple() + , + Tables\Filters\SelectFilter::make('category') + ->options(Category::query()->pluck('name', 'id')->toArray()) + ->label(__('label.torrent.category')) + ->multiple() + , + ]; + foreach (SearchBox::$taxonomies as $torrentField => $tableModel) { + $filters[] = Tables\Filters\SelectFilter::make($torrentField) + ->options(NexusDB::table($tableModel['table'])->orderBy('sort_index')->orderBy('id')->pluck('name', 'id')) + ->multiple() + ; + } + + $filters[] = Tables\Filters\Filter::make('added_begin') + ->form([ + Forms\Components\DatePicker::make('added_begin') + ->maxDate(now()) + ->label(__('label.torrent.added_begin')) + , + ])->query(function (Builder $query, array $data) { + return $query->when($data['added_begin'], fn (Builder $query, $value) => $query->where("added", '>=', $value)); + }) + ; + $filters[] = Tables\Filters\Filter::make('added_end') + ->form([ + Forms\Components\DatePicker::make('added_end') + ->maxDate(now()) + ->label(__('label.torrent.added_end')) + , + ])->query(function (Builder $query, array $data) { + return $query->when($data['added_end'], fn (Builder $query, $value) => $query->where("added", '<=', $value)); + }) + ; + $filters[] = Tables\Filters\Filter::make('size_begin') + ->form([ + Forms\Components\TextInput::make('size_begin') + ->numeric() + ->placeholder('GB') + ->label(__('label.torrent.size_begin')) + , + ])->query(function (Builder $query, array $data) { + return $query->when($data['size_begin'], fn (Builder $query, $value) => $query->where("size", '>=', $value * 1024 * 1024 * 1024)); + }) + ; + $filters[] = Tables\Filters\Filter::make('size_end') + ->form([ + Forms\Components\TextInput::make('size_end') + ->numeric() + ->placeholder('GB') + ->label(__('label.torrent.size_end')) + , + ])->query(function (Builder $query, array $data) { + return $query->when($data['size_end'], fn (Builder $query, $value) => $query->where("size", '<=', $value * 1024 * 1024 * 1024)); + }) + ; + + + return $filters; + + } + } diff --git a/app/Models/NexusModel.php b/app/Models/NexusModel.php index 75248fe4..7ab1fce9 100644 --- a/app/Models/NexusModel.php +++ b/app/Models/NexusModel.php @@ -56,7 +56,12 @@ class NexusModel extends Model $result = $dataSource; $keyValue = []; foreach ($result as $key => &$info) { - $text = $textTransPrefix ? nexus_trans("$textTransPrefix.$key") : $info['text']; + if (str_contains($textTransPrefix, '%s')) { + $transKey = sprintf($textTransPrefix, $key); + } else { + $transKey = "$textTransPrefix.$key"; + } + $text = $textTransPrefix ? nexus_trans($transKey) : $info['text']; $info['text'] = $text; $keyValue[$key] = $info[$valueField]; } diff --git a/app/Models/TorrentOperationLog.php b/app/Models/TorrentOperationLog.php index 62ccb2d9..1b1c8905 100644 --- a/app/Models/TorrentOperationLog.php +++ b/app/Models/TorrentOperationLog.php @@ -15,11 +15,15 @@ class TorrentOperationLog extends NexusModel const ACTION_TYPE_APPROVAL_NONE = 'approval_none'; const ACTION_TYPE_APPROVAL_ALLOW = 'approval_allow'; const ACTION_TYPE_APPROVAL_DENY = 'approval_deny'; + const ACTION_TYPE_EDIT = 'edit'; + const ACTION_TYPE_DELETE = 'delete'; public static array $actionTypes = [ self::ACTION_TYPE_APPROVAL_NONE => ['text' => 'Approval none'], self::ACTION_TYPE_APPROVAL_ALLOW => ['text' => 'Approval allow'], self::ACTION_TYPE_APPROVAL_DENY => ['text' => 'Approval deny'], + self::ACTION_TYPE_EDIT => ['text' => 'Edit'], + self::ACTION_TYPE_DELETE => ['text' => 'Delete'], ]; public function getActionTypeTextAttribute() diff --git a/app/Repositories/ClaimRepository.php b/app/Repositories/ClaimRepository.php index dec738d2..85716836 100644 --- a/app/Repositories/ClaimRepository.php +++ b/app/Repositories/ClaimRepository.php @@ -154,7 +154,7 @@ class ClaimRepository extends BaseRepository public function settleUser($uid, $force = false, $test = false): bool { $user = User::query()->with('language')->findOrFail($uid); - $list = Claim::query()->where('uid', $uid)->with(['snatch'])->get(); + $list = Claim::query()->where('uid', $uid)->with(['snatch', 'torrent' => fn ($query) => $query->select(Torrent::$commentFields)])->get(); $now = Carbon::now(); $startOfThisMonth = $now->clone()->startOfMonth(); $seedTimeRequiredHours = Claim::getConfigStandardSeedTimeHours(); @@ -210,7 +210,7 @@ class ClaimRepository extends BaseRepository "reachedTorrentIdArr: %s, unReachedIdArr: %s, bonusResult: %s, seedTimeHours: %s", json_encode($reachedTorrentIdArr), json_encode($unReachedIdArr), json_encode($bonusResult), $seedTimeHoursAvg ), 'alert'); - $bonusFinal = $bonusResult['seed_bonus'] * $seedTimeHoursAvg * $bonusMultiplier; + $bonusFinal = $bonusResult['seed_points'] * $seedTimeHoursAvg * $bonusMultiplier; do_log("bonus final: $bonusFinal", 'alert'); $totalDeduct = $bonusDeduct * count($unReachedIdArr); diff --git a/include/constants.php b/include/constants.php index 2cf73f3c..d7a096a5 100644 --- a/include/constants.php +++ b/include/constants.php @@ -1,6 +1,6 @@ $_id, + 'uid' => get_user_id(), + 'action_type' => \App\Models\TorrentOperationLog::ACTION_TYPE_DELETE, + 'comment' => '', + ], $notify); } } @@ -6316,4 +6323,23 @@ function build_search_area($searchArea, array $options = []) $result .= ''; return $result; } + +function torrent_name_for_admin(\App\Models\Torrent $torrent, $withTags = false) +{ + $name = sprintf( + '
%s
', + $torrent->id, $torrent->name, Str::limit($torrent->name, 40) + ); + $tags = ''; + if ($withTags) { + $tags = sprintf(' 
%s
', $torrent->tagsFormatted); + } + return new HtmlString('
' . $name . $tags . '
'); +} + +function username_for_admin(int $id) +{ + return new HtmlString(get_username($id, false, true, true, true)); +} + ?> diff --git a/public/takeedit.php b/public/takeedit.php index b7d9aa63..85afc3aa 100644 --- a/public/takeedit.php +++ b/public/takeedit.php @@ -258,16 +258,27 @@ else $searchRep = new \App\Repositories\SearchRepository(); $searchRep->updateTorrent($id); -if ($affectedRows == 1 && $row['banned'] == 'yes' && $row['owner'] == $CURUSER['id']) { +if ($affectedRows == 1) { $torrentUrl = sprintf('details.php?id=%s', $row['id']); - \App\Models\StaffMessage::query()->insert([ - 'sender' => $CURUSER['id'], - 'subject' => nexus_trans('torrent.owner_update_torrent_subject', ['detail_url' => $torrentUrl, 'torrent_name' => $_POST['name']]), - 'msg' => nexus_trans('torrent.owner_update_torrent_msg', ['detail_url' => $torrentUrl, 'torrent_name' => $_POST['name']]), - 'added' => now(), - 'permission' => 'torrent-approval', - ]); - clear_staff_message_cache(); + if ($row['banned'] == 'yes' && $row['owner'] == $CURUSER['id']) { + \App\Models\StaffMessage::query()->insert([ + 'sender' => $CURUSER['id'], + 'subject' => nexus_trans('torrent.owner_update_torrent_subject', ['detail_url' => $torrentUrl, 'torrent_name' => $_POST['name']]), + 'msg' => nexus_trans('torrent.owner_update_torrent_msg', ['detail_url' => $torrentUrl, 'torrent_name' => $_POST['name']]), + 'added' => now(), + 'permission' => 'torrent-approval', + ]); + clear_staff_message_cache(); + } + if ($row['owner'] != $CURUSER['id']) { + \App\Models\TorrentOperationLog::add([ + 'torrent_id' => $row['id'], + 'uid' => $CURUSER['id'], + 'action_type' => \App\Models\TorrentOperationLog::ACTION_TYPE_EDIT, + 'comment' => '', + ], true); + } + } $returl = "details.php?id=$id&edited=1"; diff --git a/resources/lang/en/admin.php b/resources/lang/en/admin.php index 8f2f74b4..408fab56 100644 --- a/resources/lang/en/admin.php +++ b/resources/lang/en/admin.php @@ -31,6 +31,7 @@ return [ 'plugin' => 'Plugins', 'category' => 'Categories', 'second_icon' => 'Second icons', + 'torrent_operation_log' => 'Torrent operation logs', ], 'resources' => [ 'agent_allow' => [ diff --git a/resources/lang/en/label.php b/resources/lang/en/label.php index c299cb31..56490bdd 100644 --- a/resources/lang/en/label.php +++ b/resources/lang/en/label.php @@ -163,6 +163,10 @@ return [ 'picktype' => 'Recommend', 'promotion_time_type' => 'Promotion type time', 'hr' => 'H&R', + 'added_begin' => 'Added greater than', + 'added_end' => 'Added less than', + 'size_begin' => 'Size greater than', + 'size_end' => 'Size less than', ], 'hit_and_run' => [ 'label' => 'User H&R', diff --git a/resources/lang/en/torrent-operation-log.php b/resources/lang/en/torrent-operation-log.php new file mode 100644 index 00000000..f6567ea7 --- /dev/null +++ b/resources/lang/en/torrent-operation-log.php @@ -0,0 +1,7 @@ + [ + 'action_type' => 'Action type', + ], +]; diff --git a/resources/lang/en/torrent.php b/resources/lang/en/torrent.php index f30409bd..4bc2704e 100644 --- a/resources/lang/en/torrent.php +++ b/resources/lang/en/torrent.php @@ -59,6 +59,16 @@ return [ 'type_text' => 'Not reviewed', 'notify_subject' => 'Torrent was mark as not reviewed', 'notify_msg' => 'Your torrent: [url=:detail_url]:torrent_name[/url] was mark as not reviewed by :operator', + ], + \App\Models\TorrentOperationLog::ACTION_TYPE_EDIT => [ + 'type_text' => 'Edit', + 'notify_subject' => 'Torrent was edited', + 'notify_msg' => 'Your torrent: [url=:detail_url]:torrent_name[/url] was edited by :operator', + ], + \App\Models\TorrentOperationLog::ACTION_TYPE_DELETE => [ + 'type_text' => 'Delete', + 'notify_subject' => 'Torrent was deleted', + 'notify_msg' => 'Your torrent: :torrent_name was deleted by :operator', ] ], 'owner_update_torrent_subject' => 'Denied torrent have been updated', diff --git a/resources/lang/zh_CN/admin.php b/resources/lang/zh_CN/admin.php index b8a258d4..4b53c6d3 100644 --- a/resources/lang/zh_CN/admin.php +++ b/resources/lang/zh_CN/admin.php @@ -29,6 +29,7 @@ return [ 'plugin' => '插件', 'category' => '主分类', 'second_icon' => '第二图标', + 'torrent_operation_log' => '种子操作记录', ], 'resources' => [ 'agent_allow' => [ diff --git a/resources/lang/zh_CN/label.php b/resources/lang/zh_CN/label.php index 91c44f06..f4968b80 100644 --- a/resources/lang/zh_CN/label.php +++ b/resources/lang/zh_CN/label.php @@ -163,6 +163,10 @@ return [ 'picktype' => '推荐', 'promotion_time_type' => '优惠时间类型', 'hr' => 'H&R', + 'added_begin' => '发布时间大于', + 'added_end' => '发布时间小于', + 'size_begin' => '体积大于', + 'size_end' => '体积小于', ], 'hit_and_run' => [ 'label' => '用户 H&R', diff --git a/resources/lang/zh_CN/torrent-operation-log.php b/resources/lang/zh_CN/torrent-operation-log.php new file mode 100644 index 00000000..5966b83b --- /dev/null +++ b/resources/lang/zh_CN/torrent-operation-log.php @@ -0,0 +1,7 @@ + [ + 'action_type' => '操作类型', + ], +]; diff --git a/resources/lang/zh_CN/torrent.php b/resources/lang/zh_CN/torrent.php index 7740eb33..616d904f 100644 --- a/resources/lang/zh_CN/torrent.php +++ b/resources/lang/zh_CN/torrent.php @@ -59,6 +59,16 @@ return [ 'type_text' => '标记未审核', 'notify_subject' => '种子标记未审核', 'notify_msg' => '你的种子:[url=:detail_url]:torrent_name[/url] 被 :operator 标记未审核', + ], + \App\Models\TorrentOperationLog::ACTION_TYPE_EDIT => [ + 'type_text' => '编辑', + 'notify_subject' => '种子被编辑', + 'notify_msg' => '你的种子:[url=:detail_url]:torrent_name[/url] 被 :operator 编辑', + ], + \App\Models\TorrentOperationLog::ACTION_TYPE_DELETE => [ + 'type_text' => '删除', + 'notify_subject' => '种子被删除', + 'notify_msg' => '你的种子::torrent_name 被 :operator 删除', ] ], 'owner_update_torrent_subject' => '审核拒绝种子已更新', diff --git a/resources/lang/zh_TW/admin.php b/resources/lang/zh_TW/admin.php index 134366d6..ba39b69c 100644 --- a/resources/lang/zh_TW/admin.php +++ b/resources/lang/zh_TW/admin.php @@ -31,6 +31,7 @@ return [ 'plugin' => '插件', 'category' => '主分類', 'second_icon' => '第二圖標', + 'torrent_operation_log' => '種子操作記錄', ], 'resources' => [ 'agent_allow' => [ diff --git a/resources/lang/zh_TW/label.php b/resources/lang/zh_TW/label.php index 965727b8..7c6b348d 100644 --- a/resources/lang/zh_TW/label.php +++ b/resources/lang/zh_TW/label.php @@ -163,6 +163,10 @@ return [ 'picktype' => '推薦', 'promotion_time_type' => '優惠時間類型', 'hr' => 'H&R', + 'added_begin' => '發布時間大於', + 'added_end' => '發布時間小於', + 'size_begin' => '體積大於', + 'size_end' => '體積小於', ], 'hit_and_run' => [ 'label' => '用戶 H&R', diff --git a/resources/lang/zh_TW/torrent-operation-log.php b/resources/lang/zh_TW/torrent-operation-log.php new file mode 100644 index 00000000..19e82435 --- /dev/null +++ b/resources/lang/zh_TW/torrent-operation-log.php @@ -0,0 +1,7 @@ + [ + 'action_type' => '操作類型', + ], +]; diff --git a/resources/lang/zh_TW/torrent.php b/resources/lang/zh_TW/torrent.php index 790c82e0..008bb2f2 100644 --- a/resources/lang/zh_TW/torrent.php +++ b/resources/lang/zh_TW/torrent.php @@ -59,6 +59,16 @@ return [ 'type_text' => '標記未審核', 'notify_subject' => '種子標記未審核', 'notify_msg' => '妳的種子:[url=:detail_url]:torrent_name[/url] 被 :operator 標記未審核', + ], + \App\Models\TorrentOperationLog::ACTION_TYPE_EDIT => [ + 'type_text' => '編輯', + 'notify_subject' => '種子被編輯', + 'notify_msg' => '你的種子:[url=:detail_url]:torrent_name[/url] 被 :operator 編輯', + ], + \App\Models\TorrentOperationLog::ACTION_TYPE_DELETE => [ + 'type_text' => '刪除', + 'notify_subject' => '種子被刪除', + 'notify_msg' => '你的種子::torrent_name 被 :operator 刪除', ] ], 'owner_update_torrent_subject' => '審核拒絕種子已更新',