Files
wordpress-theme-aksrt/inc/helpers/user-center-renderers/profile-level.php
T
kate522andClaude Opus 5 35bb96e82f refactor: rename the theme brand and every identifier from AKSRT to Jio
Full-project rename. `git grep -i aksrt` is now empty apart from the
DBMigrator 3.3.0 changelog note that documents the rename itself.

Code identifiers
- PHP namespace AKSRT\ -> Jio\ (composer PSR-4 + 378 declarations)
- global constants AKSRT_* -> JIO_* (VERSION/DIR/URI, PAY_TYPE_*, CAPTCHA_*)
- procedural functions, hooks, options, meta keys, table names,
  cookies, query vars, ajax actions and nonces: aksrt_ -> jio_
- text domain aksrt -> jio; Theme Name -> Jio
- JS globals: aksrtData/aksrtAdminData/... -> jioData/jioAdminData/...,
  window.AKSRTCaptcha & friends -> window.JioCaptcha, Aksrt* -> Jio*
- Vue components Aks*.vue -> Jio*.vue (15 files renamed + imports)
- CSS classes/data-attrs/custom properties: aksrt- -> jio-
- REST namespace aksrt/v1 -> jio/v1 (incl. payment gateway callbacks)

Storage layer
- DB tables {prefix}aksrt_* -> {prefix}jio_*; SCHEMA_VERSION 3.2.0 -> 3.3.0
  so dbDelta creates the new names on install
- widget id_base aksrt_widget_* -> jio_widget_*
- uninstall.php drop list rebuilt from the actual migrator tables
  (dropped 3 stale entries, added the 17 missing ones)

Removed
- hardcoded https://api.aksrt.com/version.json default update endpoint;
  get_endpoint() now reads the 「更新端点」 setting and do_check() no-ops
  when it is empty

Files renamed: inc/helpers/aksrt-*.php -> jio-*.php (54),
assets/admin/src/components/form/Aks*.vue -> Jio*.vue (15).
Build artifacts regenerated: assets/css/build, assets/js/runtime,
assets/admin/build.

Verified: audit-psr4-paths errors=0, audit-admin-contracts errors=0
(warnings=56, unchanged baseline), 813/813 widget-system tests,
44/44 phpunit, php -l clean across all PHP.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-11-01 20:05:04 +08:00

171 lines
11 KiB
PHP

<?php
/**
* User center: level summary, growth path and experience history.
*
* @package Jio
*/
defined('ABSPATH') || exit;
$context = is_array($args['context'] ?? null) ? $args['context'] : [];
$user_id = (int) ($context['user_id'] ?? get_current_user_id());
if ($user_id <= 0 || !class_exists('\\Jio\\User\\Level')) {
return;
}
$cfg = \Jio\User\Level::settings();
if (empty($cfg['enabled'])) {
return;
}
$progress = \Jio\User\Level::get_progress($user_id);
$details = array_slice(\Jio\User\Level::get_details($user_id), 0, 50);
$date_details = array_slice(\Jio\User\Level::get_date_details($user_id), 0, 30, true);
$labels = \Jio\User\Level::integral_labels();
$level_opt = is_array($cfg['level_opt'] ?? null) ? $cfg['level_opt'] : [];
$today = current_time('Y-m-d');
$today_integral = max(0, (int) ($date_details[$today] ?? 0));
$day_max = \Jio\User\Level::day_max();
$current_level = max(1, (int) ($progress['level'] ?? 1));
$max_level = max(1, (int) ($cfg['max'] ?? 10));
$level_icon = (string) ($progress['icon'] ?? '');
$level_name = (string) ($progress['name'] ?? \Jio\User\Level::get_level_name($current_level));
$badge_html = '';
if ($level_icon !== '') {
$badge_html = '<img' . jio_get_lazy_attr('lazy_other', $level_icon, 'jio-level-card__badge img-icon') . ' alt="' . esc_attr($level_name) . '" title="' . esc_attr($level_name) . '" decoding="async">';
} else {
$badge_html = '<span class="jio-level-card__badge-text" title="' . esc_attr($level_name) . '">LV' . esc_html((string) $current_level) . '</span>';
}
$avatar_html = function_exists('jio_get_avatar_html')
? jio_get_avatar_html($user_id, 48, ['class' => 'avatar-mini'])
: get_avatar($user_id, 48);
$next_need = max(0, (int) ($progress['next_need'] ?? 0));
$integral = max(0, (int) ($progress['integral'] ?? 0));
$remaining = max(0, (int) ($progress['remaining'] ?? 0));
$percentage = max(0, min(100, (int) ($progress['progress'] ?? 0)));
?>
<div class="jio-level-page">
<div class="row jio-level-page__summary">
<div class="col-md-5">
<section class="zib-widget colorful-bg jb-vip1 jio-level-card jio-level-card--summary">
<div class="colorful-make" aria-hidden="true"></div>
<div class="jio-level-card__summary-inner">
<div class="jio-level-card__identity">
<div class="avatar-mini jio-level-card__avatar"><?php echo $avatar_html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></div>
<strong><?php esc_html_e('我的等级', 'jio'); ?></strong>
</div>
<div class="jio-level-card__current">
<?php echo $badge_html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
<span><?php echo esc_html($level_name); ?></span>
</div>
<div class="jio-level-card__progress-copy">
<?php if (!empty($progress['is_max'])) : ?>
<div class="flex jsb mb6 ab"><strong><?php echo esc_html((string) $integral); ?>/<?php echo esc_html((string) $integral); ?></strong><span><?php esc_html_e('已为最高等级', 'jio'); ?></span></div>
<?php else : ?>
<div class="flex jsb mb6 ab"><strong><?php echo esc_html((string) $integral); ?>/<?php echo esc_html((string) $next_need); ?></strong><span><?php printf(esc_html__('升级还需 %d 经验', 'jio'), $remaining); ?></span></div>
<?php endif; ?>
<div class="jio-level-progress" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="<?php echo esc_attr((string) $percentage); ?>" aria-label="<?php esc_attr_e('等级进度', 'jio'); ?>"><span style="width:<?php echo esc_attr((string) $percentage); ?>%;"></span></div>
</div>
</div>
</section>
</div>
<div class="col-md-7">
<section class="zib-widget colorful-bg c-gray jio-level-card jio-level-card--growth">
<div class="colorful-make" aria-hidden="true"></div>
<div class="jio-level-card__growth-inner">
<div class="jio-level-card__growth-head">
<div>
<strong><i class="fa fas fa-chart-line" aria-hidden="true"></i><?php esc_html_e('成长体系', 'jio'); ?></strong>
<a class="muted-2-color" data-jio-level-tab="tab_integral_my" href="#tab_integral_my"><?php printf(esc_html__('我的经验值:%d', 'jio'), $integral); ?></a>
</div>
<a id="tab-integral-date-link" class="muted-2-color" data-jio-level-tab="tab_integral_date" href="#tab_integral_date"><?php echo $today_integral > 0 ? esc_html(sprintf(__('今日 +%d', 'jio'), $today_integral)) : esc_html__('查看详情', 'jio'); ?><i class="fa fas fa-angle-right ml6" aria-hidden="true"></i></a>
</div>
<div class="swiper-container swiper-scroll pillar-box jio-level-growth" scroll-nogroup="1">
<div class="swiper-wrapper">
<?php for ($level = 1; $level <= $max_level; $level++) :
$need = $level === 1 ? 0 : max(0, (int) ($level_opt['upgrade_integral_' . $level] ?? (($level - 1) * 500 * $level)));
$name = \Jio\User\Level::get_level_name($level);
$icon = \Jio\User\Level::get_level_icon_url($level);
$height = $level === 1 ? 0 : (int) round(86 * ($level / $max_level));
$state = $level === $current_level ? ' active' : ($level > $current_level ? ' is-future' : '');
?>
<div class="swiper-slide pillar-item<?php echo esc_attr($state); ?>" title="<?php echo esc_attr($name); ?>">
<div class="value"><?php echo esc_html((string) $need); ?></div>
<div class="pillar" style="height:<?php echo esc_attr((string) $height); ?>px;"></div>
<div class="level-name">
<?php if ($icon !== '') : ?><img<?php echo jio_get_lazy_attr('lazy_other', $icon, 'jio-level-growth__badge img-icon'); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> alt="<?php echo esc_attr($name); ?>" title="<?php echo esc_attr($name); ?>" decoding="async"><?php else : ?><span>LV<?php echo esc_html((string) $level); ?></span><?php endif; ?>
</div>
</div>
<?php endfor; ?>
</div>
</div>
</div>
</section>
</div>
</div>
<section class="zib-widget jio-level-experience">
<div class="box-body">
<div class="jio-level-tabs" role="tablist" aria-label="<?php esc_attr_e('经验记录', 'jio'); ?>">
<a id="tab-integral-get" class="but mr6 is-active" data-jio-level-tab="tab_integral_get" href="#tab_integral_get" role="tab" aria-controls="tab_integral_get" aria-selected="true"><?php esc_html_e('获取经验值', 'jio'); ?></a>
<a id="tab-integral-my" class="but" data-jio-level-tab="tab_integral_my" href="#tab_integral_my" role="tab" aria-controls="tab_integral_my" aria-selected="false"><?php esc_html_e('我的经验值', 'jio'); ?></a>
</div>
<div class="tab-content mt20">
<div class="tab-pane fade active in" id="tab_integral_get" role="tabpanel" aria-labelledby="tab-integral-get">
<?php
$methods = \Jio\User\Level::integral_defaults();
$methods['checkin'] = 0;
$methods['referral'] = 0;
$methods['shop_gift'] = 0;
$referral_settings = class_exists('\\Jio\\Settings\\Settings') ? \Jio\Settings\Settings::get_referral_reward_settings() : [];
$methods['referral'] = max(0, (int) ($referral_settings['level_points'] ?? 0));
foreach ($methods as $key => $default_value) :
if ($key === 'day_max') {
continue;
}
$value = in_array($key, ['checkin', 'shop_gift'], true) ? 0 : ($key === 'referral' ? (int) $default_value : \Jio\User\Level::task_points($key));
if ($value <= 0 && !in_array($key, ['checkin', 'shop_gift'], true)) {
continue;
}
?>
<div class="border-bottom padding-h10 jio-level-list-row">
<div class="flex jsb ac">
<div class="flex1 mr20"><div class="font-bold mb6"><?php echo esc_html($labels[$key] ?? $key); ?></div><div class="muted-2-color em09"><?php echo in_array($key, ['checkin', 'shop_gift'], true) ? esc_html__('按活动或商品配置发放', 'jio') : esc_html__('完成后自动计入经验', 'jio'); ?></div></div>
<span class="focus-color em14 shrink0"><i class="fa fas fa-bolt mr6" aria-hidden="true"></i><?php echo $value > 0 ? '+' . esc_html((string) $value) : esc_html__('动态', 'jio'); ?></span>
</div>
</div>
<?php endforeach; ?>
</div>
<div class="tab-pane fade" id="tab_integral_my" role="tabpanel" aria-labelledby="tab-integral-my" hidden>
<?php if ($today_integral > 0) : ?>
<div class="border-bottom padding-h10 jio-level-list-row"><div class="flex jsb ac"><div class="flex1 mr20"><div class="font-bold mb6"><?php printf(esc_html__('今日累计 +%d', 'jio'), $today_integral); ?></div><div class="muted-2-color em09"><?php echo $day_max > $today_integral ? esc_html(sprintf(__('每日最多获得 %d 经验', 'jio'), $day_max)) : esc_html__('今日累计已达到上限', 'jio'); ?></div></div><a class="muted-2-color shrink0" data-jio-level-tab="tab_integral_date" href="#tab_integral_date" role="tab" aria-controls="tab_integral_date"><?php esc_html_e('每日详情', 'jio'); ?><i class="fa fas fa-angle-right ml6" aria-hidden="true"></i></a></div></div>
<?php endif; ?>
<?php if ($details) : ?>
<?php foreach ($details as $row) :
$key = sanitize_key((string) ($row['key'] ?? ''));
$value = max(0, (int) ($row['value'] ?? 0));
$detail_integral = max(0, (int) ($row['integral'] ?? 0));
?>
<div class="border-bottom padding-h10 jio-level-list-row"><div class="flex jsb ac"><div class="flex1 mr20"><div class="font-bold mb6"><?php echo esc_html($labels[$key] ?? $key); ?></div><div class="muted-2-color em09"><?php echo esc_html((string) ($row['time'] ?? '')); ?></div></div><div class="text-right shrink0"><div class="focus-color em14 mb6">+ <?php echo esc_html((string) $value); ?></div><div class="muted-2-color em09"><?php printf(esc_html__('累计:%d', 'jio'), $detail_integral); ?></div></div></div></div>
<?php endforeach; ?>
<?php else : ?>
<p class="jio-level-empty"><?php esc_html_e('暂无经验值获取明细', 'jio'); ?></p>
<?php endif; ?>
<?php if ($details) : ?><div class="text-center mt20 muted-3-color"><?php esc_html_e('最多显示近50条记录', 'jio'); ?></div><?php endif; ?>
</div>
<div class="tab-pane fade" id="tab_integral_date" role="tabpanel" aria-labelledby="tab-integral-date-link" hidden>
<?php if ($date_details) : ?>
<?php foreach ($date_details as $date => $value) : ?><div class="border-bottom padding-h6 flex jsb ac jio-level-date-row"><div class="em12"><?php echo esc_html((string) $date); ?></div><div class="text-right shrink0 focus-color em14 font-bold">+ <?php echo esc_html((string) max(0, (int) $value)); ?></div></div><?php endforeach; ?>
<div class="text-center mt20 muted-3-color"><?php esc_html_e('最多显示近30条记录', 'jio'); ?></div>
<?php else : ?>
<p class="jio-level-empty"><?php esc_html_e('暂无经验值获取明细', 'jio'); ?></p>
<?php endif; ?>
</div>
</div>
</div>
</section>
</div>