用户功能设置收口与废弃后台链路清理
This commit is contained in:
@@ -17,8 +17,6 @@ class SchemaTools {
|
||||
'import-export' => SchemaToolsImportExport::build(),
|
||||
'health' => SchemaToolsHealth::build(),
|
||||
'backup' => SchemaToolsBackup::build(),
|
||||
'email-rollback' => SchemaToolsEmailRollback::build(),
|
||||
'frontend-modal-rollout' => SchemaToolsFrontendModalRollout::build(),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
namespace AKSRT\Admin\Schema;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
class SchemaToolsEmailRollback {
|
||||
|
||||
public static function build(): array {
|
||||
return [
|
||||
'key' => 'email-rollback',
|
||||
'title' => '邮件回滚',
|
||||
'version' => '1.0.0',
|
||||
'option_key' => 'aksrt_settings',
|
||||
'groups' => [
|
||||
['key' => 'rollback', 'title' => '邮件回滚', 'fields' => [
|
||||
['key' => 'rollback_type', 'label' => '回滚类型', 'type' => 'select', 'options' => [
|
||||
['label' => '按时间范围', 'value' => 'date_range'],
|
||||
['label' => '按邮件类型', 'value' => 'email_type'],
|
||||
['label' => '全部回滚', 'value' => 'all'],
|
||||
]],
|
||||
['key' => 'rollback_date_from', 'label' => '开始日期', 'type' => 'date'],
|
||||
['key' => 'rollback_date_to', 'label' => '结束日期', 'type' => 'date'],
|
||||
['key' => 'rollback_execute', 'label' => '执行回滚', 'type' => 'button', 'danger' => true, 'help' => '此操作不可逆'],
|
||||
]],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
namespace AKSRT\Admin\Schema;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
class SchemaToolsFrontendModalRollout {
|
||||
|
||||
public static function build(): array {
|
||||
return [
|
||||
'key' => 'frontend-modal-rollout',
|
||||
'title' => '前台弹窗灰度',
|
||||
'version' => '1.0.0',
|
||||
'option_key' => 'aksrt_settings',
|
||||
'groups' => [
|
||||
[
|
||||
'key' => 'rollout',
|
||||
'title' => '弹窗新流程开关',
|
||||
'fields' => [
|
||||
[
|
||||
'key' => 'frontend_modal_rollout_identity',
|
||||
'label' => '官方认证新流程',
|
||||
'type' => 'switch',
|
||||
'default' => true,
|
||||
'help' => '启用统一弹窗运行时与认证快照流程。',
|
||||
],
|
||||
[
|
||||
'key' => 'frontend_modal_rollout_order',
|
||||
'label' => '订单新流程',
|
||||
'type' => 'switch',
|
||||
'default' => true,
|
||||
'help' => '启用订单详情快速开壳与状态同步流程。',
|
||||
],
|
||||
[
|
||||
'key' => 'frontend_modal_rollout_vip',
|
||||
'label' => '会员支付新流程',
|
||||
'type' => 'switch',
|
||||
'default' => true,
|
||||
'help' => '启用统一会员购买、支付和结果同步流程。',
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -475,26 +475,6 @@ class SchemaUsers {
|
||||
]],
|
||||
],
|
||||
],
|
||||
'signin' => [
|
||||
'key' => 'signin',
|
||||
'title' => '签到奖励',
|
||||
'version' => '1.0.0',
|
||||
'option_key' => 'aksrt_settings',
|
||||
'groups' => [
|
||||
['key' => 'rules', 'title' => '签到规则', 'fields' => [
|
||||
['key' => 'signin_enabled', 'label' => '启用签到', 'type' => 'switch', 'default' => true],
|
||||
['key' => 'signin_reward', 'label' => '每日签到奖励', 'type' => 'number', 'default' => 1, 'min' => 0, 'max' => 100],
|
||||
['key' => 'signin_consecutive_bonus', 'label' => '连续签到加成', 'type' => 'switch', 'default' => true],
|
||||
['key' => 'signin_consecutive_days', 'label' => '加成周期', 'type' => 'number', 'default' => 7, 'min' => 2, 'max' => 30],
|
||||
['key' => 'signin_bonus_reward', 'label' => '周期奖励', 'type' => 'number', 'default' => 5, 'min' => 1, 'max' => 100],
|
||||
]],
|
||||
['key' => 'display', 'title' => '签到展示', 'fields' => [
|
||||
['key' => 'signin_header_user_show', 'label' => '导航栏显示签到', 'type' => 'switch', 'default' => true],
|
||||
['key' => 'signin_modal_auto_s', 'label' => '自动弹出签到', 'type' => 'switch', 'default' => false],
|
||||
['key' => 'signin_modal_auto_expires', 'label' => '弹出间隔(天)', 'type' => 'number', 'default' => 1, 'min' => 1, 'max' => 30],
|
||||
]],
|
||||
],
|
||||
],
|
||||
'credits' => [
|
||||
'key' => 'credits',
|
||||
'title' => '积分设置',
|
||||
@@ -551,72 +531,23 @@ class SchemaUsers {
|
||||
'version' => '1.0.0',
|
||||
'option_key' => 'aksrt_settings',
|
||||
'groups' => [
|
||||
['key' => 'center', 'title' => '用户中心', 'fields' => [
|
||||
['key' => 'user_center_tabs', 'label' => '用户中心 Tab', 'type' => 'input', 'default' => 'profile,level,comments,favorites,vip,credits,revenue,auth', 'help' => '逗号分隔。level=我的等级;creator=创作中心;revenue=推广收益中心;auth=官方认证;等级、VIP、订单、创作中心、收益中心和认证会按功能开关自动注入'],
|
||||
['key' => 'user_desc_std', 'label' => '默认签名', 'type' => 'input', 'default' => '这家伙很懒…', 'desc' => '用户未设置个人简介时显示的默认文案'],
|
||||
['key' => 'user_city_s', 'label' => '显示城市(IP 归属地)', 'type' => 'switch', 'default' => true],
|
||||
['key' => 'user_city_type', 'label' => '位置精度', 'type' => 'radio', 'default' => 'province', 'options' => [
|
||||
['label' => '省份', 'value' => 'province'],
|
||||
['label' => '省份+城市', 'value' => 'province_city'],
|
||||
['label' => '国家+省份', 'value' => 'country_province'],
|
||||
]],
|
||||
['key' => 'user_join_day_my_name', 'label' => '站名', 'type' => 'input', 'default' => '本站', 'desc' => '用于「已加入 X 天」显示中的站点名称'],
|
||||
['key' => 'user_cover_img', 'label' => '默认封面', 'type' => 'media', 'default' => ''],
|
||||
['key' => 'user_rewrite_slug', 'label' => '用户页slug', 'type' => 'input', 'default' => 'user'],
|
||||
['key' => 'user_follow_s', 'label' => '启用关注功能', 'type' => 'switch', 'default' => true],
|
||||
['key' => 'user_online_s', 'label' => '显示在线状态', 'type' => 'switch', 'default' => true],
|
||||
['key' => 'user_last_active_s', 'label' => '显示最后活跃', 'type' => 'switch', 'default' => true],
|
||||
['key' => 'profile-media', 'title' => '用户资料', 'fields' => [
|
||||
['key' => 'avatar_upload_s', 'label' => '允许用户上传头像', 'type' => 'switch', 'default' => true],
|
||||
['key' => 'avatar_external', 'label' => '外部头像源', 'type' => 'radio', 'default' => '', 'options' => [
|
||||
['label' => '关闭', 'value' => ''],
|
||||
['label' => 'Gravatar', 'value' => 'gravatar'],
|
||||
['label' => 'WeAvatar', 'value' => 'weavatar'],
|
||||
['label' => 'Cravatar', 'value' => 'cravatar'],
|
||||
['label' => '极客族 Gravatar 服务', 'value' => 'geekzu'],
|
||||
['label' => 'loli Gravatar 服务', 'value' => 'loli'],
|
||||
['label' => 'sep.cc Gravatar 服务', 'value' => 'sep'],
|
||||
['label' => 'v2ex Gravatar 服务', 'value' => 'v2ex'],
|
||||
], 'help' => '启用后,用户没有自定义头像时按邮箱获取外部头像。'],
|
||||
['key' => 'avatar_default_img', 'label' => '用户默认头像', 'type' => 'media', 'default' => get_theme_file_uri('assets/img/avatar-default.png'), 'help' => '建议尺寸 100×100。'],
|
||||
['key' => 'user_cover_upload_s', 'label' => '允许用户上传封面', 'type' => 'switch', 'default' => true],
|
||||
['key' => 'user_cover_img', 'label' => '用户默认封面', 'type' => 'media', 'default' => get_theme_file_uri('assets/img/user_t.jpg'), 'help' => '建议尺寸 1000×400;用户未设置封面时显示此图。'],
|
||||
['key' => 'user_desc_std', 'label' => '用户默认签名', 'type' => 'input', 'default' => '这家伙很懒,什么都没有写...', 'help' => '用户未设置个人简介时显示的默认文案。'],
|
||||
]],
|
||||
['key' => 'profile', 'title' => '资料页字段', 'fields' => [
|
||||
['key' => 'user_profile_nickname', 'label' => '昵称', 'type' => 'switch', 'default' => true],
|
||||
['key' => 'user_profile_email', 'label' => '邮箱', 'type' => 'switch', 'default' => true],
|
||||
['key' => 'user_profile_url', 'label' => '个人主页', 'type' => 'switch', 'default' => true],
|
||||
['key' => 'user_profile_desc', 'label' => '个人简介', 'type' => 'switch', 'default' => true],
|
||||
['key' => 'user_profile_avatar', 'label' => '头像', 'type' => 'switch', 'default' => true],
|
||||
['key' => 'user_profile_cover', 'label' => '封面图', 'type' => 'switch', 'default' => true],
|
||||
['key' => 'user_profile_qq', 'label' => 'QQ', 'type' => 'switch', 'default' => false],
|
||||
['key' => 'user_profile_wechat', 'label' => '微信', 'type' => 'switch', 'default' => false],
|
||||
['key' => 'user_profile_weibo', 'label' => '微博', 'type' => 'switch', 'default' => false],
|
||||
['key' => 'user_profile_github', 'label' => 'GitHub', 'type' => 'switch', 'default' => false],
|
||||
['key' => 'user_profile_bilibili', 'label' => 'B站', 'type' => 'switch', 'default' => false],
|
||||
['key' => 'user_profile_twitter', 'label' => 'Twitter', 'type' => 'switch', 'default' => false],
|
||||
['key' => 'user_profile_linkedin', 'label' => 'LinkedIn', 'type' => 'switch', 'default' => false],
|
||||
['key' => 'user_profile_facebook', 'label' => 'Facebook', 'type' => 'switch', 'default' => false],
|
||||
['key' => 'user_profile_telegram', 'label' => 'Telegram', 'type' => 'switch', 'default' => false],
|
||||
['key' => 'user_profile_douyin', 'label' => '抖音', 'type' => 'switch', 'default' => false],
|
||||
['key' => 'user_profile_zhihu', 'label' => '知乎', 'type' => 'switch', 'default' => false],
|
||||
]],
|
||||
['key' => 'card', 'title' => '用户卡片', 'fields' => [
|
||||
['key' => 'user_card_avatar', 'label' => '显示头像', 'type' => 'switch', 'default' => true],
|
||||
['key' => 'user_card_name', 'label' => '显示用户名', 'type' => 'switch', 'default' => true],
|
||||
['key' => 'user_card_desc', 'label' => '显示简介', 'type' => 'switch', 'default' => true],
|
||||
['key' => 'user_card_count', 'label' => '显示统计', 'type' => 'switch', 'default' => true],
|
||||
['key' => 'user_card_follow', 'label' => '显示关注按钮', 'type' => 'switch', 'default' => true],
|
||||
['key' => 'user_card_position', 'label' => '卡片位置', 'type' => 'radio', 'default' => 'right', 'options' => [
|
||||
['label' => '右侧', 'value' => 'right'],
|
||||
['label' => '左侧', 'value' => 'left'],
|
||||
['label' => '顶部', 'value' => 'top'],
|
||||
]],
|
||||
['key' => 'user_card_style', 'label' => '卡片样式', 'type' => 'radio', 'default' => 'default', 'options' => [
|
||||
['label' => '默认', 'value' => 'default'],
|
||||
['label' => '简洁', 'value' => 'simple'],
|
||||
['label' => '详细', 'value' => 'detail'],
|
||||
]],
|
||||
['key' => 'user_card_bg', 'label' => '卡片背景', 'type' => 'media', 'default' => ''],
|
||||
['key' => 'user_card_avatar_size', 'label' => '头像大小', 'type' => 'number', 'default' => 80, 'min' => 40, 'max' => 200],
|
||||
]],
|
||||
['key' => 'privacy', 'title' => '隐私设置', 'fields' => [
|
||||
['key' => 'user_privacy_posts', 'label' => '隐藏文章', 'type' => 'switch', 'default' => false],
|
||||
['key' => 'user_privacy_comments', 'label' => '隐藏评论', 'type' => 'switch', 'default' => false],
|
||||
['key' => 'user_privacy_favorites', 'label' => '隐藏收藏', 'type' => 'switch', 'default' => false],
|
||||
['key' => 'user_privacy_credits', 'label' => '隐藏积分', 'type' => 'switch', 'default' => false],
|
||||
['key' => 'user_privacy_badge', 'label' => '隐藏徽章', 'type' => 'switch', 'default' => false],
|
||||
['key' => 'user_privacy_online', 'label' => '隐藏在线状态', 'type' => 'switch', 'default' => false],
|
||||
['key' => 'user_privacy_last_active', 'label' => '隐藏最后活跃', 'type' => 'switch', 'default' => false],
|
||||
['key' => 'user_privacy_ip', 'label' => '隐藏IP归属地', 'type' => 'switch', 'default' => false],
|
||||
['key' => 'user_privacy_location', 'label' => '隐藏位置', 'type' => 'switch', 'default' => false],
|
||||
]],
|
||||
|
||||
],
|
||||
],
|
||||
'verify' => [
|
||||
|
||||
@@ -17,34 +17,6 @@ class ToolsController extends ControllerBase {
|
||||
}
|
||||
|
||||
public function register_routes(): void {
|
||||
// Email rollback: list users with recent email changes
|
||||
register_rest_route(self::API_NAMESPACE, '/email-rollback/users', [
|
||||
'methods' => 'GET',
|
||||
'callback' => [$this, 'rest_email_rollback_list'],
|
||||
'permission_callback' => [$this, 'check_permission'],
|
||||
]);
|
||||
|
||||
// Email rollback: execute rollback
|
||||
register_rest_route(self::API_NAMESPACE, '/email-rollback/users/(?P<id>\d+)/rollback', [
|
||||
'methods' => 'POST',
|
||||
'callback' => [$this, 'rest_email_rollback_execute'],
|
||||
'permission_callback' => [$this, 'check_permission'],
|
||||
]);
|
||||
|
||||
// Tools: system health (compact format for ExtensionTools.vue)
|
||||
register_rest_route(self::API_NAMESPACE, '/tools/health', [
|
||||
'methods' => 'GET',
|
||||
'callback' => [$this, 'get_tools_health'],
|
||||
'permission_callback' => [$this, 'check_permission'],
|
||||
]);
|
||||
|
||||
// Tools: maintenance actions
|
||||
register_rest_route(self::API_NAMESPACE, '/tools/maintenance', [
|
||||
'methods' => 'POST',
|
||||
'callback' => [$this, 'run_maintenance'],
|
||||
'permission_callback' => [$this, 'check_permission'],
|
||||
]);
|
||||
|
||||
// Tools: update center
|
||||
register_rest_route(self::API_NAMESPACE, '/tools/update-info', [
|
||||
'methods' => 'GET',
|
||||
@@ -65,85 +37,6 @@ class ToolsController extends ControllerBase {
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* GET /tools/health — compact health data for the tools page.
|
||||
*/
|
||||
public function get_tools_health(): \WP_REST_Response {
|
||||
global $wpdb;
|
||||
|
||||
$upload_dir = wp_upload_dir();
|
||||
$upload_ok = !empty($upload_dir['error']) === false && is_dir($upload_dir['basedir']);
|
||||
|
||||
$db_ok = true;
|
||||
$db_status = '正常';
|
||||
$expected_tables = [
|
||||
$wpdb->prefix . 'aksrt_credit_log',
|
||||
$wpdb->prefix . 'aksrt_signin_log',
|
||||
$wpdb->prefix . 'aksrt_dl_token',
|
||||
$wpdb->prefix . 'aksrt_notification',
|
||||
];
|
||||
$missing = [];
|
||||
foreach ($expected_tables as $table) {
|
||||
if ($wpdb->get_var($wpdb->prepare('SHOW TABLES LIKE %s', $table)) !== $table) {
|
||||
$missing[] = str_replace($wpdb->prefix, '', $table);
|
||||
}
|
||||
}
|
||||
if (!empty($missing)) {
|
||||
$db_ok = false;
|
||||
$db_status = '缺少: ' . implode(', ', $missing);
|
||||
}
|
||||
|
||||
return $this->success([
|
||||
'data' => [
|
||||
'php_version' => PHP_VERSION,
|
||||
'wp_version' => get_bloginfo('version'),
|
||||
'db_status' => $db_status,
|
||||
'db_ok' => $db_ok,
|
||||
'upload_dir' => $upload_dir['basedir'],
|
||||
'upload_ok' => $upload_ok,
|
||||
'theme_version' => wp_get_theme()->get('Version') ?? 'unknown',
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* POST /tools/maintenance — run a maintenance action.
|
||||
*/
|
||||
public function run_maintenance(\WP_REST_Request $request): \WP_REST_Response {
|
||||
$params = $this->get_json_params($request);
|
||||
$action = sanitize_key((string) ($params['action'] ?? ''));
|
||||
|
||||
switch ($action) {
|
||||
case 'flush_cache':
|
||||
// Flush WordPress object cache
|
||||
wp_cache_flush();
|
||||
// Clear transients
|
||||
global $wpdb;
|
||||
$wpdb->query("DELETE FROM {$wpdb->options} WHERE option_name LIKE '_transient_aksrt_%' OR option_name LIKE '_transient_timeout_aksrt_%'");
|
||||
return $this->success(['message' => __('缓存已清除', 'aksrt')]);
|
||||
|
||||
case 'optimize_db':
|
||||
global $wpdb;
|
||||
$tables = [
|
||||
$wpdb->prefix . 'aksrt_credit_log',
|
||||
$wpdb->prefix . 'aksrt_signin_log',
|
||||
$wpdb->prefix . 'aksrt_dl_token',
|
||||
$wpdb->prefix . 'aksrt_notification',
|
||||
];
|
||||
$optimized = 0;
|
||||
foreach ($tables as $table) {
|
||||
if ($wpdb->get_var($wpdb->prepare('SHOW TABLES LIKE %s', $table)) === $table) {
|
||||
$wpdb->query("OPTIMIZE TABLE {$table}");
|
||||
$optimized++;
|
||||
}
|
||||
}
|
||||
return $this->success(['message' => sprintf(__('已优化 %d 个数据表', 'aksrt'), $optimized)]);
|
||||
|
||||
default:
|
||||
return $this->error('未知的维护操作: ' . esc_html($action));
|
||||
}
|
||||
}
|
||||
|
||||
public function get_update_info(): \WP_REST_Response {
|
||||
$theme = wp_get_theme();
|
||||
$info = [
|
||||
@@ -199,32 +92,4 @@ class ToolsController extends ControllerBase {
|
||||
]);
|
||||
}
|
||||
|
||||
public function rest_email_rollback_list(\WP_REST_Request $request): \WP_REST_Response {
|
||||
if (!class_exists('\AKSRT\Auth\EmailRollback')) {
|
||||
return $this->success(['data' => ['items' => [], 'total' => 0, 'page' => 1, 'per_page' => 20]]);
|
||||
}
|
||||
|
||||
$page = max(1, (int) $request->get_param('page'));
|
||||
$per_page = min(100, max(1, (int) $request->get_param('per_page')));
|
||||
$data = \AKSRT\Auth\EmailRollback::list_pending($page, $per_page);
|
||||
|
||||
return $this->success(['data' => $data]);
|
||||
}
|
||||
|
||||
public function rest_email_rollback_execute(\WP_REST_Request $request): \WP_REST_Response {
|
||||
if (!class_exists('\AKSRT\Auth\EmailRollback')) {
|
||||
return $this->error(__('邮箱回滚功能不可用', 'aksrt'), 500);
|
||||
}
|
||||
|
||||
$user_id = (int) $request->get_param('id');
|
||||
$result = \AKSRT\Auth\EmailRollback::rollback($user_id, get_current_user_id());
|
||||
if (empty($result['success'])) {
|
||||
return $this->error((string) ($result['error'] ?? __('邮箱回滚失败', 'aksrt')), 422);
|
||||
}
|
||||
|
||||
return $this->success([
|
||||
'message' => (string) ($result['message'] ?? __('邮箱已回滚', 'aksrt')),
|
||||
'data' => $result,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,8 +54,10 @@ trait UserControllerProfileMediaOperations {
|
||||
return $this->error(__('请先登录', 'aksrt'), 401);
|
||||
}
|
||||
|
||||
$capability = $is_avatar ? 'upload_avatar' : 'upload_profile_background';
|
||||
if (!function_exists('aksrt_user_can') || !aksrt_user_can($capability, $user_id)) {
|
||||
$upload_enabled = $is_avatar
|
||||
? function_exists('aksrt_is_avatar_upload_enabled') && aksrt_is_avatar_upload_enabled()
|
||||
: function_exists('aksrt_is_user_cover_upload_enabled') && aksrt_is_user_cover_upload_enabled();
|
||||
if (!$upload_enabled) {
|
||||
return $this->error($is_avatar
|
||||
? __('当前账号没有上传头像的权限', 'aksrt')
|
||||
: __('当前账号没有上传用户资料卡背景图的权限', 'aksrt'), 403);
|
||||
|
||||
Reference in New Issue
Block a user