进行了一些小优化

This commit is contained in:
2026-08-25 06:20:16 +08:00
parent 8ddbfdd7b7
commit eef73ee9e7
8 changed files with 232 additions and 76 deletions
+181 -11
View File
@@ -29,6 +29,9 @@ class AuthApply {
add_filter('manage_users_custom_column', [$this, 'render_admin_user_column'], 10, 3);
add_action('show_user_profile', [$this, 'render_admin_profile_status']);
add_action('edit_user_profile', [$this, 'render_admin_profile_status']);
add_action('personal_options_update', [$this, 'handle_admin_profile_update']);
add_action('edit_user_profile_update', [$this, 'handle_admin_profile_update']);
add_action('admin_notices', [$this, 'render_admin_profile_notice']);
}
}
@@ -243,10 +246,12 @@ class AuthApply {
return $history;
}
public static function review(int $user_id, string $status, string $note, int $reviewer_id) {
/** @param array<string,string> $profile_fields */
public static function review(int $user_id, string $application_uuid, string $status, string $note, int $reviewer_id, array $profile_fields) {
$repo = new ApplicationRepository();
$application = $repo->latest_for_user($user_id);
if (!$application) {
$application_uuid = sanitize_text_field($application_uuid);
$application = wp_is_uuid($application_uuid) ? $repo->find_by_uuid($application_uuid) : null;
if (!$application || (int) $application['user_id'] !== $user_id) {
return new \WP_Error('aksrt_verify_missing', __('认证申请不存在', 'aksrt'));
}
$status = sanitize_key($status);
@@ -257,10 +262,19 @@ class AuthApply {
if (in_array($status, ['rejected', 'cancelled'], true) && $note === '') {
return new \WP_Error('aksrt_verify_note', __('请填写处理原因', 'aksrt'));
}
$result = (new TransitionService($repo))->transition($application, $status, [
'review_note' => $note,
'reviewer_id' => $reviewer_id,
], ['source' => 'admin', 'event_type' => 'manual_review', 'actor_user_id' => $reviewer_id]);
$fields = [];
foreach (['public_name', 'public_desc'] as $key) {
if (array_key_exists($key, $profile_fields)) {
$fields[$key] = (string) $profile_fields[$key];
}
}
$fields['review_note'] = $note;
$fields['reviewer_id'] = $reviewer_id;
$result = (new TransitionService($repo))->transition($application, $status, $fields, [
'source' => 'admin',
'event_type' => 'manual_review',
'actor_user_id' => $reviewer_id,
]);
return is_wp_error($result) ? $result : ['status' => $status, 'reviewed_at' => (string) $result['completed_at']];
}
@@ -279,14 +293,170 @@ class AuthApply {
}
public function render_admin_profile_status(\WP_User $user): void {
$status = self::get_status((int) $user->ID);
$info = self::get_auth_info((int) $user->ID);
$user_id = (int) $user->ID;
$snapshot = self::snapshot($user_id);
$application = is_array($snapshot['verified'] ?? null)
? $snapshot['verified']
: (is_array($snapshot['latest'] ?? null) ? $snapshot['latest'] : null);
$raw_status = (string) ($application['status'] ?? '');
$can_manage = $application !== null
&& current_user_can('aksrt_review_identity')
&& current_user_can('edit_user', $user_id);
$allowed_actions = array_values(array_intersect(
TransitionService::allowed_targets($raw_status),
['verified', 'rejected', 'cancelled']
));
$public_name = (string) ($application['public_name'] ?? '');
$public_desc = (string) ($application['public_desc'] ?? '');
?>
<h2><?php esc_html_e('身份认证(AKSRT)', 'aksrt'); ?></h2>
<table class="form-table" role="presentation">
<tr><th><?php esc_html_e('认证状态', 'aksrt'); ?></th><td><?php echo esc_html($status ?: __('未认证', 'aksrt')); ?></td></tr>
<?php if (!empty($info['name'])) : ?><tr><th><?php esc_html_e('认证身份', 'aksrt'); ?></th><td><?php echo esc_html((string) $info['name']); ?></td></tr><?php endif; ?>
<tr>
<th><?php esc_html_e('认证状态', 'aksrt'); ?></th>
<td><strong><?php echo esc_html($raw_status === '' ? __('未认证', 'aksrt') : self::admin_status_label($raw_status)); ?></strong></td>
</tr>
<?php if ($application !== null && $can_manage) : ?>
<tr>
<th><label for="aksrt_identity_public_name"><?php esc_html_e('认证身份', 'aksrt'); ?></label></th>
<td>
<input type="text" class="regular-text" id="aksrt_identity_public_name" name="aksrt_identity_public_name" maxlength="64" value="<?php echo esc_attr($public_name); ?>">
<input type="hidden" name="aksrt_identity_application_uuid" value="<?php echo esc_attr((string) $application['application_uuid']); ?>">
<?php wp_nonce_field('aksrt_identity_profile_' . $user_id, 'aksrt_identity_profile_nonce'); ?>
</td>
</tr>
<tr>
<th><label for="aksrt_identity_public_desc"><?php esc_html_e('认证公开说明', 'aksrt'); ?></label></th>
<td>
<textarea class="large-text" id="aksrt_identity_public_desc" name="aksrt_identity_public_desc" rows="3" maxlength="300"><?php echo esc_textarea($public_desc); ?></textarea>
</td>
</tr>
<?php if ($allowed_actions !== []) : ?>
<tr>
<th><label for="aksrt_identity_action"><?php esc_html_e('更改认证状态', 'aksrt'); ?></label></th>
<td>
<select id="aksrt_identity_action" name="aksrt_identity_action">
<option value=""><?php esc_html_e('保持当前状态', 'aksrt'); ?></option>
<?php foreach ($allowed_actions as $action) : ?>
<option value="<?php echo esc_attr($action); ?>"><?php echo esc_html(self::admin_action_label($action)); ?></option>
<?php endforeach; ?>
</select>
<p><label for="aksrt_identity_review_note"><?php esc_html_e('处理说明', 'aksrt'); ?></label></p>
<textarea class="large-text" id="aksrt_identity_review_note" name="aksrt_identity_review_note" rows="2"></textarea>
<p class="description"><?php esc_html_e('驳回或取消认证时必须填写处理说明。', 'aksrt'); ?></p>
</td>
</tr>
<?php endif; ?>
<?php elseif ($application !== null) : ?>
<?php if ($public_name !== '') : ?><tr><th><?php esc_html_e('认证身份', 'aksrt'); ?></th><td><?php echo esc_html($public_name); ?></td></tr><?php endif; ?>
<?php if ($public_desc !== '') : ?><tr><th><?php esc_html_e('认证公开说明', 'aksrt'); ?></th><td><?php echo nl2br(esc_html($public_desc)); ?></td></tr><?php endif; ?>
<?php endif; ?>
</table>
<?php
}
public function handle_admin_profile_update(int $user_id): void {
if (
!current_user_can('aksrt_review_identity')
|| !current_user_can('edit_user', $user_id)
|| !isset($_POST['aksrt_identity_profile_nonce'])
) {
return;
}
$nonce = sanitize_text_field((string) wp_unslash($_POST['aksrt_identity_profile_nonce']));
if (!wp_verify_nonce($nonce, 'aksrt_identity_profile_' . $user_id)) {
return;
}
$repo = new ApplicationRepository();
$snapshot = $repo->snapshot_for_user($user_id);
$application = is_array($snapshot['verified'] ?? null)
? $snapshot['verified']
: (is_array($snapshot['latest'] ?? null) ? $snapshot['latest'] : null);
if ($application === null) {
return;
}
$application_uuid = sanitize_text_field((string) wp_unslash($_POST['aksrt_identity_application_uuid'] ?? ''));
if ($application_uuid === '' || !hash_equals((string) $application['application_uuid'], $application_uuid)) {
$this->set_admin_profile_notice('error', __('身份认证记录已变化,请刷新后重试。', 'aksrt'));
return;
}
$public_name = wp_html_excerpt(sanitize_text_field((string) wp_unslash($_POST['aksrt_identity_public_name'] ?? '')), 64, '');
$public_desc = wp_html_excerpt(sanitize_textarea_field((string) wp_unslash($_POST['aksrt_identity_public_desc'] ?? '')), 300, '');
$action = sanitize_key((string) wp_unslash($_POST['aksrt_identity_action'] ?? ''));
$note = sanitize_textarea_field((string) wp_unslash($_POST['aksrt_identity_review_note'] ?? ''));
$fields = [
'public_name' => $public_name,
'public_desc' => $public_desc,
];
if ($action === '') {
$updated = $repo->update((int) $application['id'], $fields);
$this->set_admin_profile_notice($updated ? 'success' : 'error', $updated ? __('身份认证资料已更新。', 'aksrt') : __('身份认证资料更新失败。', 'aksrt'));
return;
}
$allowed = TransitionService::allowed_targets((string) $application['status']);
if (!in_array($action, $allowed, true) || !in_array($action, ['verified', 'rejected', 'cancelled'], true)) {
$this->set_admin_profile_notice('error', __('当前认证状态不能执行该操作。', 'aksrt'));
return;
}
if ($action === 'verified' && $public_name === '') {
$this->set_admin_profile_notice('error', __('通过认证时请填写认证身份。', 'aksrt'));
return;
}
if (in_array($action, ['rejected', 'cancelled'], true) && $note === '') {
$this->set_admin_profile_notice('error', __('驳回或取消认证时请填写处理说明。', 'aksrt'));
return;
}
$result = self::review($user_id, $application_uuid, $action, $note, get_current_user_id(), $fields);
$this->set_admin_profile_notice(
is_wp_error($result) ? 'error' : 'success',
is_wp_error($result) ? $result->get_error_message() : __('身份认证已更新。', 'aksrt')
);
}
public function render_admin_profile_notice(): void {
$key = 'aksrt_identity_profile_notice_' . get_current_user_id();
$notice = get_transient($key);
if (!is_array($notice) || empty($notice['message'])) {
return;
}
delete_transient($key);
$type = ($notice['type'] ?? '') === 'success' ? 'success' : 'error';
echo '<div class="notice notice-' . esc_attr($type) . ' is-dismissible"><p>' . esc_html((string) $notice['message']) . '</p></div>';
}
private function set_admin_profile_notice(string $type, string $message): void {
set_transient('aksrt_identity_profile_notice_' . get_current_user_id(), [
'type' => $type,
'message' => $message,
], 60);
}
private static function admin_status_label(string $status): string {
$labels = [
'created' => __('已创建', 'aksrt'),
'provider_pending' => __('等待核身', 'aksrt'),
'provider_processing' => __('云端处理中', 'aksrt'),
'provider_failed' => __('云认证失败', 'aksrt'),
'provider_unsupported' => __('云端不支持', 'aksrt'),
'provider_expired' => __('会话已过期', 'aksrt'),
'manual_pending' => __('人工待审', 'aksrt'),
'verified' => __('已认证', 'aksrt'),
'rejected' => __('已驳回', 'aksrt'),
'cancelled' => __('已取消', 'aksrt'),
];
return $labels[$status] ?? $status;
}
private static function admin_action_label(string $action): string {
$labels = [
'verified' => __('通过认证', 'aksrt'),
'rejected' => __('驳回申请', 'aksrt'),
'cancelled' => __('取消认证', 'aksrt'),
];
return $labels[$action] ?? $action;
}
}