feat(admin): review reports and ban appeals in dialogs
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
32ac2112b0
commit
59ddf677b6
13 files changed
+2122
-704
No files matched your search
@@ -12,7 +12,7 @@ class UsersMenus {
|
||||
use UsersMenusVerify;
|
||||
use UsersMenusVip;
|
||||
use UsersMenusInviteCode;
|
||||
use UsersMenusTickets;
|
||||
use UsersMenusBan;
|
||||
use UsersMenusTicketsCenter;
|
||||
use UsersMenusMessages;
|
||||
|
||||
@@ -47,6 +47,7 @@ class UsersMenus {
|
||||
add_action('admin_enqueue_scripts', [$this, 'enqueue_message_assets']);
|
||||
add_action('admin_enqueue_scripts', [$this, 'enqueue_invite_assets']);
|
||||
add_action('admin_enqueue_scripts', [$this, 'enqueue_verify_assets']);
|
||||
add_action('admin_enqueue_scripts', [$this, 'enqueue_ban_assets']);
|
||||
add_action('admin_enqueue_scripts', [$this, 'enqueue_vip_assets']);
|
||||
}
|
||||
|
||||
@@ -202,6 +203,9 @@ class UsersMenus {
|
||||
if ($code === 'verify_failed' && isset($_GET['aksrt_verify_error'])) {
|
||||
$message = sanitize_text_field((string) wp_unslash($_GET['aksrt_verify_error']));
|
||||
}
|
||||
if (in_array($code, ['report_failed', 'appeal_failed'], true) && isset($_GET['aksrt_ban_error'])) {
|
||||
$message = sanitize_text_field((string) wp_unslash($_GET['aksrt_ban_error']));
|
||||
}
|
||||
if ($code === 'vip_failed' && isset($_GET['aksrt_vip_error'])) {
|
||||
$message = sanitize_text_field((string) wp_unslash($_GET['aksrt_vip_error']));
|
||||
}
|
||||
@@ -221,101 +225,6 @@ class UsersMenus {
|
||||
exit;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------
|
||||
* Ban / reports
|
||||
* ----------------------------------------------------------------*/
|
||||
|
||||
public function render_ban_page(): void {
|
||||
$this->ensure_cap();
|
||||
NativeUi::page_open('aksrt-native-ban');
|
||||
NativeUi::header(
|
||||
__('用户禁封申诉及用户举报管理', 'aksrt'),
|
||||
__('处理用户举报与禁封申诉工单。禁封 / 解封操作在前台封禁弹窗完成。', 'aksrt'),
|
||||
'dashicons-shield'
|
||||
);
|
||||
$this->flash();
|
||||
|
||||
// 与参考主题一致:后台仅承载「申诉&举报」工单处理;禁封/解封操作
|
||||
// 全部在前台完成(用户主页封面 / 评论区 / 文章作者栏三点菜单 →
|
||||
// 封禁弹窗,REST /user-ban/modal + /user-ban/set)。
|
||||
// render_tickets_tab() 自带筛选控件 + 表格 + 分页,直接交给 .aksrt-native
|
||||
// 作用域下的共享样式(.subsubsub / .widefat / .button / .tablenav)接管。
|
||||
$this->render_tickets_tab();
|
||||
|
||||
NativeUi::page_close();
|
||||
}
|
||||
|
||||
|
||||
public function handle_update_report(): void {
|
||||
if (!current_user_can(self::CAPABILITY)) {
|
||||
wp_die(esc_html__('权限不足', 'aksrt'));
|
||||
}
|
||||
$id = isset($_POST['report_id']) ? (int) $_POST['report_id'] : 0;
|
||||
$new_status = isset($_POST['new_status']) ? sanitize_key((string) wp_unslash($_POST['new_status'])) : '';
|
||||
$note = isset($_POST['note']) ? sanitize_textarea_field((string) wp_unslash($_POST['note'])) : '';
|
||||
check_admin_referer('aksrt_users_update_report_' . $id);
|
||||
$ok = $id > 0 && class_exists('\AKSRT\Messages\ReportCenter') && \AKSRT\Messages\ReportCenter::get_instance()->update_status($id, $new_status, $note);
|
||||
$this->redirect('aksrt_user_ban', $ok ? 'report_updated' : 'report_failed', ['tab' => 'tickets']);
|
||||
}
|
||||
|
||||
public function handle_process_appeal(): void {
|
||||
if (!current_user_can(self::CAPABILITY)) {
|
||||
wp_die(esc_html__('权限不足', 'aksrt'));
|
||||
}
|
||||
$user_id = isset($_POST['user_id']) ? (int) $_POST['user_id'] : 0;
|
||||
$decision = isset($_POST['decision']) ? sanitize_key((string) wp_unslash($_POST['decision'])) : '';
|
||||
$note = isset($_POST['note']) ? sanitize_textarea_field((string) wp_unslash($_POST['note'])) : '';
|
||||
check_admin_referer('aksrt_users_process_appeal_' . $user_id);
|
||||
|
||||
if ($user_id <= 0 || !in_array($decision, ['approve', 'reject'], true) || !class_exists('\AKSRT\User\BanAppeal')) {
|
||||
$this->redirect('aksrt_user_ban', 'appeal_failed', ['tab' => 'tickets', 'type' => 'appeal']);
|
||||
}
|
||||
|
||||
$status = $decision === 'approve' ? 'approved' : 'rejected';
|
||||
update_user_meta($user_id, \AKSRT\User\BanAppeal::META_STATUS, $status);
|
||||
|
||||
$payload = \AKSRT\User\BanAppeal::get_payload($user_id);
|
||||
$payload['admin_note'] = $note;
|
||||
$payload['handled_at'] = current_time('Y-m-d H:i');
|
||||
$payload['handled_by'] = get_current_user_id();
|
||||
$payload['decision'] = $status;
|
||||
update_user_meta($user_id, \AKSRT\User\BanAppeal::META_PAYLOAD, $payload);
|
||||
|
||||
$history = get_user_meta($user_id, \AKSRT\User\BanAppeal::META_HISTORY, true);
|
||||
$history = is_array($history) ? $history : [];
|
||||
$history[] = $payload;
|
||||
update_user_meta($user_id, \AKSRT\User\BanAppeal::META_HISTORY, array_slice($history, -30));
|
||||
|
||||
if ($decision === 'approve' && class_exists('\AKSRT\User\Restriction')) {
|
||||
\AKSRT\User\Restriction::get_instance()->lift_user_restriction($user_id);
|
||||
}
|
||||
|
||||
if (class_exists('\AKSRT\Messages\Message')) {
|
||||
$msg = $decision === 'approve'
|
||||
? __('你的禁封申诉已通过,限制已解除。', 'aksrt')
|
||||
: __('你的禁封申诉未通过,可修改后重新提交。', 'aksrt');
|
||||
if ($note !== '') {
|
||||
$msg .= ' ' . sprintf(__('备注:%s', 'aksrt'), $note);
|
||||
}
|
||||
\AKSRT\Messages\Message::get_instance()->send(
|
||||
$user_id,
|
||||
'ban_appeal',
|
||||
$msg,
|
||||
[
|
||||
'title' => $decision === 'approve' ? __('申诉通过', 'aksrt') : __('申诉驳回', 'aksrt'),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
do_action('aksrt_ban_appeal_processed', $user_id, $decision, $note);
|
||||
|
||||
$this->redirect(
|
||||
'aksrt_user_ban',
|
||||
$decision === 'approve' ? 'appeal_approved' : 'appeal_rejected',
|
||||
['tab' => 'tickets', 'type' => 'appeal']
|
||||
);
|
||||
}
|
||||
|
||||
private function pagination(int $pages, int $page_num): void {
|
||||
if ($pages <= 1) {
|
||||
return;
|
||||
|
||||
Reference in new issue
Block a user