Merge pull request 'feat(identity): close free-task progress, level card, hot threshold' (#183) from worktree-identity-close-p2 into main
Reviewed-on: CYL/wordpress-theme-aksrt#183
This commit is contained in:
@@ -11,6 +11,7 @@ export const creditsSchema = {
|
|||||||
bbs_credits_score_extra: 3,
|
bbs_credits_score_extra: 3,
|
||||||
bbs_credits_essence: 10,
|
bbs_credits_essence: 10,
|
||||||
bbs_credits_posts_hot: 5,
|
bbs_credits_posts_hot: 5,
|
||||||
|
bbs_hot_recommend_threshold: 500,
|
||||||
bbs_credits_adopted: 20,
|
bbs_credits_adopted: 20,
|
||||||
bbs_credits_daily_max: 50,
|
bbs_credits_daily_max: 50,
|
||||||
},
|
},
|
||||||
@@ -27,6 +28,7 @@ export const creditsSchema = {
|
|||||||
{ key: 'bbs_credits_score_extra', label: '被加分', type: 'number', default: 3, min: 0 },
|
{ key: 'bbs_credits_score_extra', label: '被加分', type: 'number', default: 3, min: 0 },
|
||||||
{ key: 'bbs_credits_essence', label: '被设精华', type: 'number', default: 10, min: 0 },
|
{ key: 'bbs_credits_essence', label: '被设精华', type: 'number', default: 10, min: 0 },
|
||||||
{ key: 'bbs_credits_posts_hot', label: '成为热帖', type: 'number', default: 5, min: 0 },
|
{ key: 'bbs_credits_posts_hot', label: '成为热帖', type: 'number', default: 5, min: 0 },
|
||||||
|
{ key: 'bbs_hot_recommend_threshold', label: '热帖推荐分阈值', type: 'number', default: 500, min: 1, help: '推荐分达到该值触发热帖奖励与勋章累计' },
|
||||||
{ key: 'bbs_credits_adopted', label: '被采纳', type: 'number', default: 20, min: 0 },
|
{ key: 'bbs_credits_adopted', label: '被采纳', type: 'number', default: 20, min: 0 },
|
||||||
{ key: 'bbs_credits_daily_max', label: '每日积分上限', type: 'number', default: 50, min: 0, help: '0 = 不限' },
|
{ key: 'bbs_credits_daily_max', label: '每日积分上限', type: 'number', default: 50, min: 0, help: '0 = 不限' },
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -993,3 +993,49 @@ body.uc-modal-open {
|
|||||||
.uc-badges-item .medal-icon { width: 28px; height: 28px; object-fit: contain; }
|
.uc-badges-item .medal-icon { width: 28px; height: 28px; object-fit: contain; }
|
||||||
.uc-badges-wear-tag { margin-left: 6px; }
|
.uc-badges-wear-tag { margin-left: 6px; }
|
||||||
.uc-badges-empty { padding: 16px 0; text-align: center; }
|
.uc-badges-empty { padding: 16px 0; text-align: center; }
|
||||||
|
|
||||||
|
|
||||||
|
/* Level / integral card */
|
||||||
|
.uc-level-card {
|
||||||
|
margin: 16px 0;
|
||||||
|
padding: 16px;
|
||||||
|
border-radius: 12px;
|
||||||
|
background: linear-gradient(135deg, rgba(240,68,148,.12), rgba(99,102,241,.10));
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.uc-level-card__badge { margin-top: 12px; }
|
||||||
|
.uc-level-card .progress,
|
||||||
|
.integral-progress.progress {
|
||||||
|
height: 8px;
|
||||||
|
border-radius: 999px;
|
||||||
|
background: rgba(127,127,127,.18);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.uc-level-card .progress-bar {
|
||||||
|
height: 100%;
|
||||||
|
border-radius: 999px;
|
||||||
|
background: linear-gradient(90deg, #f04494, #6366f1);
|
||||||
|
}
|
||||||
|
.uc-level-growth__row {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 56px 1fr auto;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 6px 0;
|
||||||
|
border-bottom: 1px solid rgba(127,127,127,.12);
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
.uc-level-growth__row.is-done { opacity: .7; }
|
||||||
|
.uc-level-growth__row.is-next { font-weight: 700; color: var(--focus-color, #f04494); }
|
||||||
|
.uc-points-tasks__row.is-done { opacity: .72; }
|
||||||
|
.uc-points-tasks__progress-bar {
|
||||||
|
height: 6px;
|
||||||
|
border-radius: 999px;
|
||||||
|
background: rgba(127,127,127,.16);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.uc-points-tasks__progress-bar > span {
|
||||||
|
display: block;
|
||||||
|
height: 100%;
|
||||||
|
background: linear-gradient(90deg, #22c55e, #16a34a);
|
||||||
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ class AKSRT_Admin_Schema_Forum_Credits {
|
|||||||
['key' => 'bbs_credits_score_extra', 'label' => '被加分', 'type' => 'number', 'default' => 3, 'min' => 0],
|
['key' => 'bbs_credits_score_extra', 'label' => '被加分', 'type' => 'number', 'default' => 3, 'min' => 0],
|
||||||
['key' => 'bbs_credits_essence', 'label' => '被设精华', 'type' => 'number', 'default' => 10, 'min' => 0],
|
['key' => 'bbs_credits_essence', 'label' => '被设精华', 'type' => 'number', 'default' => 10, 'min' => 0],
|
||||||
['key' => 'bbs_credits_posts_hot', 'label' => '成为热帖', 'type' => 'number', 'default' => 5, 'min' => 0],
|
['key' => 'bbs_credits_posts_hot', 'label' => '成为热帖', 'type' => 'number', 'default' => 5, 'min' => 0],
|
||||||
|
['key' => 'bbs_hot_recommend_threshold', 'label' => '热帖推荐分阈值', 'type' => 'number', 'default' => 500, 'min' => 1, 'help' => '推荐分达到该值触发热帖奖励与勋章累计'],
|
||||||
['key' => 'bbs_credits_adopted', 'label' => '被采纳', 'type' => 'number', 'default' => 20, 'min' => 0],
|
['key' => 'bbs_credits_adopted', 'label' => '被采纳', 'type' => 'number', 'default' => 20, 'min' => 0],
|
||||||
['key' => 'bbs_credits_daily_max', 'label' => '每日积分上限', 'type' => 'number', 'default' => 50, 'min' => 0, 'help' => '0 = 不限'],
|
['key' => 'bbs_credits_daily_max', 'label' => '每日积分上限', 'type' => 'number', 'default' => 50, 'min' => 0, 'help' => '0 = 不限'],
|
||||||
]],
|
]],
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ class AKSRT_Points_Free {
|
|||||||
|
|
||||||
public const META_DETAIL = 'aksrt_free_points_detail';
|
public const META_DETAIL = 'aksrt_free_points_detail';
|
||||||
public const META_LOGIN = 'aksrt_free_points_login_date';
|
public const META_LOGIN = 'aksrt_free_points_login_date';
|
||||||
|
public const META_SIGNIN = 'aksrt_free_points_signin_date';
|
||||||
|
public const META_TASKS = 'aksrt_free_points_task_dates';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Task catalog: key => [label, short_desc, default_points]
|
* Task catalog: key => [label, short_desc, default_points]
|
||||||
@@ -162,6 +164,7 @@ class AKSRT_Points_Free {
|
|||||||
}
|
}
|
||||||
|
|
||||||
self::bump_detail($user_id, $points);
|
self::bump_detail($user_id, $points);
|
||||||
|
self::mark_task_done_today($user_id, $task_key);
|
||||||
return $points;
|
return $points;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -182,13 +185,22 @@ class AKSRT_Points_Free {
|
|||||||
public static function task_list_for_user(int $user_id = 0): array {
|
public static function task_list_for_user(int $user_id = 0): array {
|
||||||
$cfg = self::settings();
|
$cfg = self::settings();
|
||||||
$list = [];
|
$list = [];
|
||||||
|
$today = self::today_key();
|
||||||
$login_done = false;
|
$login_done = false;
|
||||||
|
$signin_done = false;
|
||||||
|
$task_dates = [];
|
||||||
if ($user_id > 0) {
|
if ($user_id > 0) {
|
||||||
$login_done = (string) get_user_meta($user_id, self::META_LOGIN, true) === self::today_key();
|
$login_done = (string) get_user_meta($user_id, self::META_LOGIN, true) === $today;
|
||||||
|
$signin_done = (string) get_user_meta($user_id, self::META_SIGNIN, true) === $today;
|
||||||
|
$raw = get_user_meta($user_id, self::META_TASKS, true);
|
||||||
|
$task_dates = is_array($raw) ? $raw : [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$passive = ['post_like', 'post_favorite', 'followed', 'comment_like', 'bbs_essence', 'bbs_adopt', 'bbs_posts_hot', 'bbs_comment_hot', 'bbs_score_extra'];
|
||||||
|
$active_once = ['post_new', 'comment_new', 'bbs_posts_new', 'bbs_reply'];
|
||||||
|
|
||||||
foreach (self::catalog() as $key => $meta) {
|
foreach (self::catalog() as $key => $meta) {
|
||||||
$pts = (int) ($cfg['tasks'][$key] ?? 0);
|
$pts = (int) ($cfg['tasks'][$key] ?? 0);
|
||||||
// Hide sign_up from daily task list (one-time); still grant on register.
|
|
||||||
if ($key === 'sign_up') {
|
if ($key === 'sign_up') {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -196,10 +208,27 @@ class AKSRT_Points_Free {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$status = 'todo';
|
$status = 'todo';
|
||||||
if (in_array($key, ['login', 'sign_in'], true) && $login_done) {
|
$progress = null;
|
||||||
|
$target = null;
|
||||||
|
if ($key === 'login' && $login_done) {
|
||||||
$status = 'done_today';
|
$status = 'done_today';
|
||||||
} elseif (in_array($key, ['post_like', 'post_favorite', 'followed', 'comment_like', 'bbs_essence', 'bbs_adopt', 'bbs_posts_hot', 'bbs_comment_hot', 'bbs_score_extra'], true)) {
|
$progress = 1;
|
||||||
|
$target = 1;
|
||||||
|
} elseif ($key === 'sign_in' && $signin_done) {
|
||||||
|
$status = 'done_today';
|
||||||
|
$progress = 1;
|
||||||
|
$target = 1;
|
||||||
|
} elseif (in_array($key, $passive, true)) {
|
||||||
$status = 'passive';
|
$status = 'passive';
|
||||||
|
} elseif (in_array($key, $active_once, true)) {
|
||||||
|
$target = 1;
|
||||||
|
$done_day = is_array($task_dates[$key] ?? null) ? (string) ($task_dates[$key]['day'] ?? '') : (string) ($task_dates[$key] ?? '');
|
||||||
|
if ($done_day === $today) {
|
||||||
|
$status = 'done_today';
|
||||||
|
$progress = 1;
|
||||||
|
} else {
|
||||||
|
$progress = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
$list[] = [
|
$list[] = [
|
||||||
'key' => $key,
|
'key' => $key,
|
||||||
@@ -208,13 +237,39 @@ class AKSRT_Points_Free {
|
|||||||
'points' => $pts,
|
'points' => $pts,
|
||||||
'enabled' => true,
|
'enabled' => true,
|
||||||
'status' => $status,
|
'status' => $status,
|
||||||
'progress' => null,
|
'progress' => $progress,
|
||||||
'target' => null,
|
'target' => $target,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
return $list;
|
return $list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mark a free-task as completed today (for progress DTO).
|
||||||
|
*/
|
||||||
|
public static function mark_task_done_today(int $user_id, string $task_key): void {
|
||||||
|
if ($user_id <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$task_key = sanitize_key($task_key);
|
||||||
|
$today = self::today_key();
|
||||||
|
if ($task_key === 'login') {
|
||||||
|
update_user_meta($user_id, self::META_LOGIN, $today);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ($task_key === 'sign_in') {
|
||||||
|
update_user_meta($user_id, self::META_SIGNIN, $today);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$raw = get_user_meta($user_id, self::META_TASKS, true);
|
||||||
|
$map = is_array($raw) ? $raw : [];
|
||||||
|
$map[$task_key] = ['day' => $today, 'ts' => time()];
|
||||||
|
if (count($map) > 40) {
|
||||||
|
$map = array_slice($map, -40, null, true);
|
||||||
|
}
|
||||||
|
update_user_meta($user_id, self::META_TASKS, $map);
|
||||||
|
}
|
||||||
|
|
||||||
private static function today_key(): string {
|
private static function today_key(): string {
|
||||||
return (new DateTimeImmutable('today', wp_timezone()))->format('Y-m-d');
|
return (new DateTimeImmutable('today', wp_timezone()))->format('Y-m-d');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -222,7 +222,14 @@ class AKSRT_Forum_Score_Service {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private function maybe_reward_hot_topic(int $topic_id, float $score): void {
|
private function maybe_reward_hot_topic(int $topic_id, float $score): void {
|
||||||
$hot_threshold = 500.0;
|
$config = $this->forum->get_config();
|
||||||
|
$hot_threshold = (float) ($config['post_page']['hot_recommend_threshold']
|
||||||
|
?? $config['credits']['hot_recommend_threshold']
|
||||||
|
?? $config['other']['hot_topic_threshold']
|
||||||
|
?? 500);
|
||||||
|
if ($hot_threshold <= 0) {
|
||||||
|
$hot_threshold = 500.0;
|
||||||
|
}
|
||||||
if ($score < $hot_threshold) {
|
if ($score < $hot_threshold) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -239,7 +246,6 @@ class AKSRT_Forum_Score_Service {
|
|||||||
}
|
}
|
||||||
do_action('aksrt_forum_topic_hot', $topic_id, (int) $author_id);
|
do_action('aksrt_forum_topic_hot', $topic_id, (int) $author_id);
|
||||||
update_post_meta($topic_id, '_aksrt_hot_rewarded', '1');
|
update_post_meta($topic_id, '_aksrt_hot_rewarded', '1');
|
||||||
$config = $this->forum->get_config();
|
|
||||||
$amount = (int) ($config['credits']['posts_hot'] ?? 5);
|
$amount = (int) ($config['credits']['posts_hot'] ?? 5);
|
||||||
if ($amount > 0) {
|
if ($amount > 0) {
|
||||||
if (class_exists('AKSRT_Points_Free')) {
|
if (class_exists('AKSRT_Points_Free')) {
|
||||||
|
|||||||
@@ -263,6 +263,7 @@ class AKSRT_Settings_Forum_Shop {
|
|||||||
'breadcrumbs_bbs_home_name' => $str('bbs_breadcrumbs_bbs_home_name', '论坛'),
|
'breadcrumbs_bbs_home_name' => $str('bbs_breadcrumbs_bbs_home_name', '论坛'),
|
||||||
'breadcrumbs_plate_cat' => $bool('bbs_breadcrumbs_plate_cat', true),
|
'breadcrumbs_plate_cat' => $bool('bbs_breadcrumbs_plate_cat', true),
|
||||||
'score_extra_max' => $int('bbs_score_extra_max', 5),
|
'score_extra_max' => $int('bbs_score_extra_max', 5),
|
||||||
|
'hot_recommend_threshold' => $int('bbs_hot_recommend_threshold', 500),
|
||||||
'score_deduct_max' => $int('bbs_score_deduct_max', 3),
|
'score_deduct_max' => $int('bbs_score_deduct_max', 3),
|
||||||
'maxheight_enabled' => $bool('bbs_posts_maxheight_s'),
|
'maxheight_enabled' => $bool('bbs_posts_maxheight_s'),
|
||||||
'maxheight' => $int('bbs_posts_maxheight', 800),
|
'maxheight' => $int('bbs_posts_maxheight', 800),
|
||||||
@@ -337,6 +338,7 @@ class AKSRT_Settings_Forum_Shop {
|
|||||||
'score_extra' => $int('bbs_credits_score_extra', 3),
|
'score_extra' => $int('bbs_credits_score_extra', 3),
|
||||||
'essence' => $int('bbs_credits_essence', 10),
|
'essence' => $int('bbs_credits_essence', 10),
|
||||||
'posts_hot' => $int('bbs_credits_posts_hot', 5),
|
'posts_hot' => $int('bbs_credits_posts_hot', 5),
|
||||||
|
'hot_recommend_threshold' => $int('bbs_hot_recommend_threshold', 500),
|
||||||
'adopted' => $int('bbs_credits_adopted', 20),
|
'adopted' => $int('bbs_credits_adopted', 20),
|
||||||
'daily_max' => $int('bbs_credits_daily_max', 50),
|
'daily_max' => $int('bbs_credits_daily_max', 50),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -0,0 +1,107 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* User center: my level + integral growth (Zibll level card parity).
|
||||||
|
*
|
||||||
|
* Expects $user_id from profile-credits context when required.
|
||||||
|
*
|
||||||
|
* @package AKSRT
|
||||||
|
*/
|
||||||
|
|
||||||
|
defined('ABSPATH') || exit;
|
||||||
|
|
||||||
|
if (!class_exists('AKSRT_User_Level')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$cfg = AKSRT_User_Level::settings();
|
||||||
|
if (empty($cfg['enabled'])) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$user_id = (int) ($user_id ?? get_current_user_id());
|
||||||
|
if ($user_id <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$level = AKSRT_User_Level::get_level($user_id);
|
||||||
|
$integral = AKSRT_User_Level::get_integral($user_id);
|
||||||
|
$max = max(1, (int) ($cfg['max'] ?? 10));
|
||||||
|
$prefix = (string) ($cfg['prefix'] ?? 'Lv.');
|
||||||
|
$opt = is_array($cfg['level_opt'] ?? null) ? $cfg['level_opt'] : [];
|
||||||
|
$name = (string) ($opt['name_' . $level] ?? ($prefix . $level));
|
||||||
|
|
||||||
|
$next_need = 0;
|
||||||
|
$is_max = $level >= $max;
|
||||||
|
if (!$is_max) {
|
||||||
|
$next_need = (int) ($opt['upgrade_integral_' . ($level + 1)] ?? 0);
|
||||||
|
if ($next_need <= $integral) {
|
||||||
|
// Resolve again in case meta lag.
|
||||||
|
$level = AKSRT_User_Level::resolve_level($integral, $cfg);
|
||||||
|
$is_max = $level >= $max;
|
||||||
|
$next_need = $is_max ? $integral : (int) ($opt['upgrade_integral_' . ($level + 1)] ?? $integral);
|
||||||
|
$name = (string) ($opt['name_' . $level] ?? ($prefix . $level));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($is_max) {
|
||||||
|
$proportion = 100;
|
||||||
|
$need_html = esc_html__('已为最高等级', 'aksrt');
|
||||||
|
$frac_html = esc_html((string) $integral) . '/' . esc_html((string) $integral);
|
||||||
|
} else {
|
||||||
|
$den = max(1, $next_need);
|
||||||
|
$proportion = (int) min(100, max(0, ($integral / $den) * 100));
|
||||||
|
$need_left = max(0, $next_need - $integral);
|
||||||
|
$need_html = sprintf(
|
||||||
|
/* translators: %s: remaining XP */
|
||||||
|
esc_html__('升级还需%s经验', 'aksrt'),
|
||||||
|
'<span class="em14 font-bold ml3 mr3">' . esc_html((string) $need_left) . '</span>'
|
||||||
|
);
|
||||||
|
$frac_html = esc_html((string) $integral) . '/' . esc_html((string) $next_need);
|
||||||
|
}
|
||||||
|
|
||||||
|
$avatar = function_exists('aksrt_get_avatar_html')
|
||||||
|
? aksrt_get_avatar_html($user_id, 42, ['class' => 'avatar avatar-mini'])
|
||||||
|
: get_avatar($user_id, 42);
|
||||||
|
|
||||||
|
// Growth rows (next few levels).
|
||||||
|
$growth = '';
|
||||||
|
$from = max(1, $level);
|
||||||
|
$to = min($max, $level + 5);
|
||||||
|
for ($i = $from; $i <= $to; $i++) {
|
||||||
|
$need_i = (int) ($opt['upgrade_integral_' . $i] ?? 0);
|
||||||
|
$nm = (string) ($opt['name_' . $i] ?? ($prefix . $i));
|
||||||
|
$state = $integral >= $need_i ? 'is-done' : ($i === $level + 1 ? 'is-next' : '');
|
||||||
|
$growth .= '<div class="uc-level-growth__row ' . esc_attr($state) . '">';
|
||||||
|
$growth .= '<span class="uc-level-growth__lv">' . esc_html($prefix . $i) . '</span>';
|
||||||
|
$growth .= '<span class="uc-level-growth__name">' . esc_html($nm) . '</span>';
|
||||||
|
$growth .= '<span class="uc-level-growth__need">' . esc_html((string) $need_i) . '</span>';
|
||||||
|
$growth .= '</div>';
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<div class="uc-level-card zib-widget">
|
||||||
|
<div class="uc-level-card__head flex ac">
|
||||||
|
<div class="avatar-mini mr10"><?php echo $avatar; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></div>
|
||||||
|
<div class="font-bold"><?php esc_html_e('我的等级', 'aksrt'); ?></div>
|
||||||
|
</div>
|
||||||
|
<div class="uc-level-card__body">
|
||||||
|
<div class="uc-level-card__badge flex ac em14">
|
||||||
|
<span class="badg badg-sm mr10 aksrt-identity-chip aksrt-identity-chip--info"><?php echo esc_html($prefix . $level); ?></span>
|
||||||
|
<span class="font-bold"><?php echo esc_html($name); ?></span>
|
||||||
|
</div>
|
||||||
|
<div class="uc-level-card__progress mt10">
|
||||||
|
<div class="flex jsb mb6 ab">
|
||||||
|
<div class="em12 font-bold"><?php echo $frac_html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></div>
|
||||||
|
<div class="opacity8 em09"><?php echo $need_html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></div>
|
||||||
|
</div>
|
||||||
|
<div class="integral-progress progress">
|
||||||
|
<div class="progress-bar" style="width: <?php echo (int) $proportion; ?>%;"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php if ($growth !== '') : ?>
|
||||||
|
<div class="uc-level-growth mt12">
|
||||||
|
<div class="uc-level-growth__title muted-2-color em09 mb6"><?php esc_html_e('成长路线', 'aksrt'); ?></div>
|
||||||
|
<?php echo $growth; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
@@ -201,6 +201,19 @@ $pane = isset($points_tasks_pane) ? sanitize_key((string) $points_tasks_pane)
|
|||||||
<div class="flex1 mr20">
|
<div class="flex1 mr20">
|
||||||
<div class="font-bold mb6"><?php echo esc_html((string) $task['title']); ?></div>
|
<div class="font-bold mb6"><?php echo esc_html((string) $task['title']); ?></div>
|
||||||
<div class="muted-2-color em09"><?php echo esc_html((string) $task['desc']); ?></div>
|
<div class="muted-2-color em09"><?php echo esc_html((string) $task['desc']); ?></div>
|
||||||
|
<?php
|
||||||
|
$progress = $task['progress'] ?? null;
|
||||||
|
$target = $task['target'] ?? null;
|
||||||
|
if ($target !== null && (int) $target > 0) :
|
||||||
|
$pv = max(0, (int) $progress);
|
||||||
|
$tv = max(1, (int) $target);
|
||||||
|
$pct = (int) min(100, round(($pv / $tv) * 100));
|
||||||
|
?>
|
||||||
|
<div class="uc-points-tasks__progress mt6">
|
||||||
|
<div class="uc-points-tasks__progress-bar"><span style="width:<?php echo (int) $pct; ?>%"></span></div>
|
||||||
|
<div class="muted-2-color em09 mt3"><?php echo esc_html($pv . '/' . $tv); ?></div>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
<div class="uc-points-tasks__meta shrink0 text-right">
|
<div class="uc-points-tasks__meta shrink0 text-right">
|
||||||
<div class="focus-color em14">
|
<div class="focus-color em14">
|
||||||
|
|||||||
@@ -44,6 +44,9 @@ if (!empty($show_vip)) {
|
|||||||
if ($show_credits) {
|
if ($show_credits) {
|
||||||
require $dir . '/credits-signin.php';
|
require $dir . '/credits-signin.php';
|
||||||
}
|
}
|
||||||
|
if (class_exists('AKSRT_User_Level')) {
|
||||||
|
require $dir . '/credits-level.php';
|
||||||
|
}
|
||||||
|
|
||||||
// Tabbed ledgers (Zibll record tabs).
|
// Tabbed ledgers (Zibll record tabs).
|
||||||
if ($show_wallet || $show_credits) :
|
if ($show_wallet || $show_credits) :
|
||||||
|
|||||||
Reference in New Issue
Block a user