improve torrent approval

This commit is contained in:
xiaomlove
2022-08-16 18:31:04 +08:00
parent bda12cce03
commit b398c8db3c
21 changed files with 418 additions and 75 deletions

View File

@@ -0,0 +1,73 @@
<?php
namespace App\Filament\Resources\Torrent;
use App\Filament\Resources\Torrent\TorrentDenyReasonResource\Pages;
use App\Filament\Resources\Torrent\TorrentDenyReasonResource\RelationManagers;
use App\Models\TorrentDenyReason;
use Filament\Forms;
use Filament\Resources\Form;
use Filament\Resources\Resource;
use Filament\Resources\Table;
use Filament\Tables;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
class TorrentDenyReasonResource extends Resource
{
protected static ?string $model = TorrentDenyReason::class;
protected static ?string $navigationIcon = 'heroicon-o-ban';
protected static ?string $navigationGroup = 'Torrent';
protected static ?int $navigationSort = 3;
protected static function getNavigationLabel(): string
{
return __('admin.sidebar.torrent_deny_reason');
}
public static function getBreadcrumb(): string
{
return self::getNavigationLabel();
}
public static function form(Form $form): Form
{
return $form
->schema([
Forms\Components\TextInput::make('name')->required()->label(__('label.name')),
Forms\Components\TextInput::make('priority')->integer()->label(__('label.priority'))->default(0),
])->columns(1);
}
public static function table(Table $table): Table
{
return $table
->columns([
Tables\Columns\TextColumn::make('id'),
Tables\Columns\TextColumn::make('name')->label(__('label.name')),
Tables\Columns\TextColumn::make('priority')->label(__('label.priority'))->sortable(),
Tables\Columns\TextColumn::make('created_at')->label(__('label.created_at')),
])
->defaultSort('priority', 'desc')
->filters([
//
])
->actions([
Tables\Actions\EditAction::make(),
Tables\Actions\DeleteAction::make(),
])
->bulkActions([
Tables\Actions\DeleteBulkAction::make(),
]);
}
public static function getPages(): array
{
return [
'index' => Pages\ManageTorrentDenyReasons::route('/'),
];
}
}

View File

@@ -0,0 +1,21 @@
<?php
namespace App\Filament\Resources\Torrent\TorrentDenyReasonResource\Pages;
use App\Filament\Resources\Torrent\TorrentDenyReasonResource;
use Filament\Pages\Actions;
use Filament\Resources\Pages\ManageRecords;
class ManageTorrentDenyReasons extends ManageRecords
{
protected ?string $maxContentWidth = 'full';
protected static string $resource = TorrentDenyReasonResource::class;
protected function getActions(): array
{
return [
Actions\CreateAction::make(),
];
}
}

View File

@@ -3,9 +3,12 @@
namespace App\Http\Controllers;
use App\Http\Resources\RewardResource;
use App\Http\Resources\TorrentOperationLogResource;
use App\Http\Resources\TorrentResource;
use App\Models\Setting;
use App\Models\Torrent;
use App\Models\TorrentDenyReason;
use App\Models\TorrentOperationLog;
use App\Models\User;
use App\Repositories\TorrentRepository;
use Illuminate\Http\Request;
@@ -100,4 +103,45 @@ class TorrentController extends Controller
return $this->success($result);
}
public function approvalPage(Request $request)
{
$request->validate(['torrent_id' => 'required']);
$torrentId = $request->torrent_id;
$torrent = Torrent::query()->findOrFail($torrentId, Torrent::$commentFields);
$denyReasons = TorrentDenyReason::query()->orderBy('priority', 'desc')->get();
return view('torrent/approval', compact('torrent', 'denyReasons'));
}
public function approvalLogs(Request $request)
{
$request->validate(['torrent_id' => 'required']);
$torrentId = $request->torrent_id;
$actionTypes = [
TorrentOperationLog::ACTION_TYPE_APPROVAL_NONE,
TorrentOperationLog::ACTION_TYPE_APPROVAL_ALLOW,
TorrentOperationLog::ACTION_TYPE_APPROVAL_DENY,
];
$records = TorrentOperationLog::query()
->with(['user'])
->where('torrent_id', $torrentId)
->whereIn('action_type', $actionTypes)
->orderBy('id', 'desc')
->paginate($request->limit);
$resource = TorrentOperationLogResource::collection($records);
return $this->success($resource);
}
public function approval(Request $request)
{
$request->validate([
'torrent_id' => 'required',
'approval_status' => 'required',
]);
$params = $request->all();
$this->repository->approval(Auth::user(), $params);
return $this->success($params);
}
}

View File

@@ -0,0 +1,27 @@
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class TorrentOperationLogResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
return [
'id' => $this->id,
'action_type' => $this->action_type,
'action_type_text' => $this->actionTypeText,
'uid' => $this->uid,
'username' => $this->user->username,
'comment' => $this->comment,
'created_at' => format_datetime($this->created_at)
];
}
}

View File

@@ -0,0 +1,15 @@
<?php
namespace App\Models;
use Nexus\Database\NexusDB;
class TorrentDenyReason extends NexusModel
{
protected $table = 'torrent_deny_reasons';
public $timestamps = true;
protected $fillable = ['name', 'hits', 'priority',];
}

View File

@@ -22,6 +22,11 @@ class TorrentOperationLog extends NexusModel
self::ACTION_TYPE_APPROVAL_DENY => ['text' => 'Approval deny'],
];
public function getActionTypeTextAttribute()
{
return nexus_trans("torrent.operation_log.{$this->action_type}.type_text");
}
public function user()
{
return $this->belongsTo(User::class, 'uid')->select(User::$commonFields);

View File

@@ -0,0 +1,34 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('torrent_deny_reasons', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->integer('hits')->default(0);
$table->integer('priority')->default(0);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('torrent_deny_reasons');
}
};

View File

@@ -516,13 +516,30 @@ function api(...$args)
$data = $data['data'];
}
}
return [
'ret' => (int)$ret,
'msg' => (string)$msg,
$time = (float)number_format(microtime(true) - nexus()->getStartTimestamp(), 3);
$count = null;
$resultKey = 'ret';
$msgKey = 'msg';
$format = $_REQUEST['__format'] ?? '';
if ($format == 'layui-table') {
$resultKey = 'code';
$count = $data['meta']['total'] ?? 0;
if (isset($data['data'])) {
$data = $data['data'];
}
}
$results = [
$resultKey => (int)$ret,
$msgKey => (string)$msg,
'data' => $data,
'time' => (float)number_format(microtime(true) - nexus()->getStartTimestamp(), 3),
'time' => $time,
'rid' => nexus()->getRequestId(),
];
if ($format == 'layui-table') {
$results['count'] = $count;
}
return $results;
}
function success(...$args)

View File

@@ -162,45 +162,16 @@ if (!$row) {
'<a href="javascript:;"><b><font id="approval" class="small approval" data-torrent_id="%s">%s&nbsp;%s</font></b></a>',
$row['id'], $approvalIcon, $lang_details['action_approval']
);
$title = nexus_trans('torrent.approval.modal_title');
$js = <<<JS
jQuery('#approval').on("click", function () {
let loadingIndex1 = layer.load()
let torrentId = jQuery(this).attr('data-torrent_id')
let params = {
action: 'approvalModal',
params: {
torrent_id: torrentId
}
}
jQuery.post('ajax.php', params, function (response) {
layer.close(loadingIndex1)
console.log(response)
if (response.ret != 0) {
layer.alert(response.msg)
return
}
let formId = response.data.form_id;
layer.open({
type: 1,
title: response.data.title,
content: response.data.content,
btn: ["OK"],
btnAlign: 'c',
yes: function () {
let loadingIndex2 = layer.load()
let params = jQuery("#" + formId).serialize();
jQuery.post("ajax.php", params + "&action=approval", function (response) {
layer.close(loadingIndex2)
console.log(response)
if (response.ret != 0) {
layer.alert(response.msg)
return
}
window.location.reload()
}, 'json')
}
})
}, 'json')
layer.open({
type: 2,
title: '$title',
area: ['60%', '600px'],
content: '/web/torrent-approval-page?torrent_id=' + torrentId,
})
})
JS;
\Nexus\Nexus::js($js, 'footer', false);

View File

@@ -23,6 +23,7 @@ return [
'isp' => 'ISP',
'menu' => 'Custom menu',
'username_change_log' => 'Username change log',
'torrent_deny_reason' => 'Deny Reasons',
],
'resources' => [
'agent_allow' => [

View File

@@ -29,6 +29,7 @@ return [
'deadline' => 'Deadline',
'permanent' => 'Permanent',
'operator' => 'Operator',
'action' => 'Action',
'setting' => [
'nav_text' => 'Setting',
'backup' => [

View File

@@ -46,32 +46,33 @@ return [
'claim_disabled' => 'Claim is disabled',
'operation_log' => [
\App\Models\TorrentOperationLog::ACTION_TYPE_APPROVAL_DENY => [
'type_text' => 'Banned',
'notify_subject' => 'Torrent was banned',
'notify_msg' => 'Your torrent[url=:detail_url]:torrent_name[/url] was banned by :operator, Reason: :reason',
'type_text' => 'Allowed',
'notify_subject' => 'Torrent was allowed',
'notify_msg' => 'Your torrent[url=:detail_url]:torrent_name[/url] was allowed by :operator, Reason: :reason',
],
\App\Models\TorrentOperationLog::ACTION_TYPE_APPROVAL_ALLOW => [
'type_text' => 'Cancel banned',
'notify_subject' => 'Torrent was unbanned',
'notify_msg' => 'Your torrent: [url=:detail_url]:torrent_name[/url] unbanned by :operator',
'type_text' => 'Denied',
'notify_subject' => 'Torrent was denied',
'notify_msg' => 'Your torrent: [url=:detail_url]:torrent_name[/url] denied by :operator',
],
\App\Models\TorrentOperationLog::ACTION_TYPE_APPROVAL_NONE => [
'type_text' => 'Cancel banned',
'notify_subject' => 'Torrent was unbanned',
'notify_msg' => 'Your torrent: [url=:detail_url]:torrent_name[/url] unbanned by :operator',
'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',
]
],
'owner_update_torrent_subject' => 'Banned torrent have been updated',
'owner_update_torrent_msg' => 'Torrent[url=:detail_url]:torrent_name[/url] has been updated by the owner, you can check if it meets the requirements and cancel the ban',
'owner_update_torrent_subject' => 'Denied torrent have been updated',
'owner_update_torrent_msg' => 'Torrent[url=:detail_url]:torrent_name[/url] has been updated by the owner, you can check if it meets the requirements and allow',
'approval' => [
'modal_title' => 'Torrent approval',
'status_label' => 'Approval status',
'comment_label' => 'Comment(optional)',
'status_text' => [
\App\Models\Torrent::APPROVAL_STATUS_NONE => 'Not reviewed',
\App\Models\Torrent::APPROVAL_STATUS_ALLOW => 'Approved',
\App\Models\Torrent::APPROVAL_STATUS_DENY => 'Not approved',
\App\Models\Torrent::APPROVAL_STATUS_ALLOW => 'Allowed',
\App\Models\Torrent::APPROVAL_STATUS_DENY => 'Denied',
],
'deny_comment_show' => 'Denied, reason: :reason',
'logs_label' => 'Approval logs'
],
];

View File

@@ -23,6 +23,7 @@ return [
'isp' => 'ISP',
'menu' => '自定义菜单',
'username_change_log' => '改名记录',
'torrent_deny_reason' => '拒绝原因',
],
'resources' => [
'agent_allow' => [

View File

@@ -29,6 +29,7 @@ return [
'deadline' => '截止时间',
'permanent' => '永久有效',
'operator' => '操作者',
'action' => '操作',
'setting' => [
'nav_text' => '设置',
'backup' => [

View File

@@ -46,23 +46,23 @@ return [
'claim_disabled' => '认领未启用',
'operation_log' => [
\App\Models\TorrentOperationLog::ACTION_TYPE_APPROVAL_DENY => [
'type_text' => '禁止',
'notify_subject' => '种子被禁止',
'notify_msg' => '你的种子:[url=:detail_url]:torrent_name[/url] 被 :operator 禁止,原因::reason',
'type_text' => '审核拒绝',
'notify_subject' => '种子审核拒绝',
'notify_msg' => '你的种子:[url=:detail_url]:torrent_name[/url] 被 :operator 审核拒绝,原因::reason',
],
\App\Models\TorrentOperationLog::ACTION_TYPE_APPROVAL_ALLOW => [
'type_text' => '取消禁止',
'notify_subject' => '种子取消禁止',
'notify_msg' => '你的种子:[url=:detail_url]:torrent_name[/url] 被 :operator 取消禁止',
'type_text' => '审核通过',
'notify_subject' => '种子审核通过',
'notify_msg' => '你的种子:[url=:detail_url]:torrent_name[/url] 被 :operator 审核通过',
],
\App\Models\TorrentOperationLog::ACTION_TYPE_APPROVAL_NONE => [
'type_text' => '取消禁止',
'notify_subject' => '种子取消禁止',
'notify_msg' => '你的种子:[url=:detail_url]:torrent_name[/url] 被 :operator 取消禁止',
'type_text' => '标记未审核',
'notify_subject' => '种子标记未审核',
'notify_msg' => '你的种子:[url=:detail_url]:torrent_name[/url] 被 :operator 标记未审核',
]
],
'owner_update_torrent_subject' => '被禁种子已更新',
'owner_update_torrent_msg' => '种子:[url=:detail_url]:torrent_name[/url] 已被作者更新,可以检查是否符合要求并取消禁止',
'owner_update_torrent_subject' => '审核拒绝种子已更新',
'owner_update_torrent_msg' => '种子:[url=:detail_url]:torrent_name[/url] 已被作者更新,可以检查是否符合要求并审核通过',
'approval' => [
'modal_title' => '种子审核',
'status_label' => '审核状态',
@@ -73,5 +73,6 @@ return [
\App\Models\Torrent::APPROVAL_STATUS_DENY => '拒绝',
],
'deny_comment_show' => '审核不通过,原因::reason',
'logs_label' => '审核记录',
],
];

View File

@@ -23,6 +23,7 @@ return [
'isp' => 'ISP',
'menu' => '自定義菜單',
'username_change_log' => '改名記錄',
'torrent_deny_reason' => '拒絕原因',
],
'resources' => [
'agent_allow' => [

View File

@@ -29,6 +29,7 @@ return [
'deadline' => '截止時間',
'permanent' => '永久有效',
'operator' => '操作者',
'action' => '操作',
'setting' => [
'nav_text' => '設置',
'backup' => [

View File

@@ -46,23 +46,23 @@ return [
'claim_disabled' => '認領未啟用',
'operation_log' => [
\App\Models\TorrentOperationLog::ACTION_TYPE_APPROVAL_DENY => [
'type_text' => '禁止',
'notify_subject' => '種子被禁止',
'notify_msg' => '的種子:[url=:detail_url]:torrent_name[/url] 被 :operator 禁止,原因::reason',
'type_text' => '審核拒絕',
'notify_subject' => '種子審核拒絕',
'notify_msg' => '的種子:[url=:detail_url]:torrent_name[/url] 被 :operator 審核拒絕,原因::reason',
],
\App\Models\TorrentOperationLog::ACTION_TYPE_APPROVAL_ALLOW => [
'type_text' => '取消禁止',
'notify_subject' => '種子取消禁止',
'notify_msg' => '的種子:[url=:detail_url]:torrent_name[/url] 被 :operator 取消禁止',
'type_text' => '審核通過',
'notify_subject' => '種子審核通過',
'notify_msg' => '的種子:[url=:detail_url]:torrent_name[/url] 被 :operator 審核通過',
],
\App\Models\TorrentOperationLog::ACTION_TYPE_APPROVAL_NONE => [
'type_text' => '取消禁止',
'notify_subject' => '種子取消禁止',
'notify_msg' => '的種子:[url=:detail_url]:torrent_name[/url] 被 :operator 取消禁止',
'type_text' => '標記未審核',
'notify_subject' => '種子標記未審核',
'notify_msg' => '的種子:[url=:detail_url]:torrent_name[/url] 被 :operator 標記未審核',
]
],
'owner_update_torrent_subject' => '被禁種子已更新',
'owner_update_torrent_msg' => '種子:[url=:detail_url]:torrent_name[/url] 已被作者更新,可以檢查是否符合要求並取消禁止',
'owner_update_torrent_subject' => '審核拒絕種子已更新',
'owner_update_torrent_msg' => '種子:[url=:detail_url]:torrent_name[/url] 已被作者更新,可以檢查是否符合要求併審核通過',
'approval' => [
'modal_title' => '種子審核',
'status_label' => '審核狀態',
@@ -73,5 +73,6 @@ return [
\App\Models\Torrent::APPROVAL_STATUS_DENY => '拒絕',
],
'deny_comment_show' => '審核不通過,原因::reason',
'logs_label' => '審核記錄'
],
];

View File

@@ -0,0 +1,14 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link rel="stylesheet" href="/styles/sprites.css">
<link rel="stylesheet" href="/vendor/layui/css/layui.css">
@stack('css')
<script type="text/javascript" src="/js/jquery-1.12.4.min.js"></script>
<script type="text/javascript" src="/vendor/layui/layui.js"></script>
@stack('scripts')
</head>
<body>
@yield('content')
</body>
</html>

View File

@@ -0,0 +1,107 @@
@extends('layui-page')
@push('css')
<style>
.form-comments {
display: flex;
}
.form-comments .form{
flex-basis: 60%;
}
.form-comments .comments{
flex-basis: 40%;
padding: 15px;
}
.form-comments .comments .comment{
padding: 5px 10px;
border: 1px solid #ccc;
border-radius: 10px;
cursor: pointer;
display: inline-block;
margin: 4px 0;
}
.layui-form-label {
width: 120px;
}
.layui-input-block {
margin-left: 150px;
}
</style>
@endpush
@section('content')
<div class="form-comments">
<form class="layui-form form" action="">
@csrf
<input type="hidden" name="torrent_id" value="{{ $torrent->id }}">
<div class="layui-form-item">
<label class="layui-form-label">{{ __('torrent.approval.status_label') }}</label>
<div class="layui-input-block">
@foreach (\App\Models\Torrent::listApprovalStatus(true) as $status => $text)
<input type="radio" name="approval_status" value="{{ $status }}" title="{{ $text }}" @if($status == $torrent->approval_status) checked @endif>
@endforeach
</div>
</div>
<div class="layui-form-item layui-form-text">
<label class="layui-form-label">{{ __('torrent.approval.comment_label') }}</label>
<div class="layui-input-block">
<textarea id="approval-comment" name="comment" placeholder="" class="layui-textarea"></textarea>
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit lay-filter="formDemo">Submit</button>
<button type="reset" class="layui-btn layui-btn-primary">Reset</button>
</div>
</div>
</form>
<div class="comments">
@foreach($denyReasons as $reason)
<span class="comment">{{ $reason->name }}</span>
@endforeach
</div>
</div>
<div style="text-align: center;margin-top: 20px;font-weight: 400">{{ __('torrent.approval.logs_label') }}</div>
<table id="table"></table>
<script>
layui.use('table', function(){
var table = layui.table;
var util = layui.util;
table.render({
elem: '#table'
,size: 'sm' //小尺寸的表格
// ,height: 312
,url: '/web/torrent-approval-logs?__format=layui-table&torrent_id={{ $torrent->id }}' //数据接口
,page: true //开启分页
,cols: [[ //表头
{field: 'id', title: 'ID', }
,{field: 'username', title: '{{ __('label.username') }}', }
,{field: 'action_type_text', title: '{{ __('label.action') }}', }
,{field: 'comment', title: '{{ __('label.comment') }}',}
,{field: 'created_at', title: '{{ __('label.created_at') }}'}
]]
});
});
layui.use('form', function(){
var form = layui.form;
//监听提交
form.on('submit(formDemo)', function(data){
console.log(data)
jQuery.post('/web/torrent-approval', data.field, function (response) {
if (response.ret != 0) {
layer.alert(response.msg)
return
}
parent.window.location.reload()
}, 'json')
return false;
});
});
let approvalComment = jQuery('#approval-comment')
jQuery('.comments').on("click", '.comment', function () {
let text = jQuery(this).text()
let oldText = approvalComment.val()
approvalComment.val(oldText + text)
})
</script>
@endsection

View File

@@ -17,6 +17,12 @@ Route::get('/', function () {
return redirect('index.php');
});
Route::group(['prefix' => 'web', 'middleware' => ['auth.nexus:nexus', 'locale']], function () {
Route::get('torrent-approval-page', [\App\Http\Controllers\TorrentController::class, 'approvalPage']);
Route::get('torrent-approval-logs', [\App\Http\Controllers\TorrentController::class, 'approvalLogs']);
Route::post('torrent-approval', [\App\Http\Controllers\TorrentController::class, 'approval']);
});
if (!isRunningInConsole()) {
$passkeyLoginUri = get_setting('security.login_secret');
if (!empty($passkeyLoginUri) && get_setting('security.login_type') == 'passkey') {