feat: 收口 1:1 剩余欠账(论坛壳/圈子/501/私信默认/资源死码)

- 论坛 board/topic/plate/tag/plate-cat 接入 content-wrap/content-layout 主站流壳
- 公共主页 plate 圈子 tab 接关注/管理版块真实数据并计数
- forum-topic 渲染封面/付费扩展位 meta(§7.3)
- 后台删除消息/背景图/评论图 REST 从 501 补齐为真实实现
- 私信 private_s 缺省 true(完整 1:1,不再兼容默认关)
- 清理 aksrt_get_resource_meta 不可达旧实现;挂载 AKSRT_AI 配置门控实例
- 登录 modal 启用 colorful-header;订单页粉边 focus 软化;侧栏次级入口视觉弱化

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-12 13:06:47 +08:00
co-authored by Claude Fable 5
parent 0941c7d23f
commit fb68b3f8c6
16 changed files with 313 additions and 82 deletions
+1
View File
@@ -158,6 +158,7 @@ const menuOptions = ADMIN_SECTIONS.filter((section) => !section.hidden).map((sec
children: section.children.map((child) => ({
label: child.secondaryEntry ? `${child.label} · 次级` : child.label,
key: child.key,
props: child.secondaryEntry ? { class: 'aksrt-menu-item--secondary' } : undefined,
})),
}
})
+44
View File
@@ -30,3 +30,47 @@
.aksrt-forum-header__stats {
display: none; /* stats demoted on home shell; counts remain in eyebrow meta */
}
/* Forum pages share the single/archive content stream shell */
.content-shell--forum .content-wrap {
padding-top: 8px;
}
.content-shell--forum .content-layout__primary > .aksrt-forum-board,
.content-shell--forum .content-layout__primary > .aksrt-forum-topic,
.content-shell--forum .content-layout__primary > .aksrt-forum-tag,
.content-shell--forum .content-layout__primary > .aksrt-forum-plate-cat {
width: 100%;
}
.aksrt-forum-topic__cover {
margin: 0 0 16px;
border-radius: var(--main-radius, 8px);
overflow: hidden;
background: var(--body-bg-color, #f5f6f7);
}
.aksrt-forum-topic__cover--image {
aspect-ratio: var(--cover-ratio, 16/9);
}
.aksrt-forum-topic__cover img {
display: block;
width: 100%;
height: 100%;
object-fit: cover;
}
.aksrt-forum-topic__cover--slide {
display: grid;
grid-auto-flow: column;
grid-auto-columns: 100%;
overflow-x: auto;
scroll-snap-type: x mandatory;
}
.aksrt-forum-topic__cover--slide img {
scroll-snap-align: start;
aspect-ratio: 16/9;
}
.aksrt-forum-topic__paywall {
margin: 12px 0 20px;
padding: 16px;
}
+6 -6
View File
@@ -43,7 +43,7 @@
.aksrt-orders-page__filter-chip.is-active {
background: var(--color-primary);
color: var(--color-on-primary);
border-color: var(--color-primary);
border-color: color-mix(in srgb, var(--color-primary) 45%, var(--color-line, #e5e7eb));
}
/* ===== Order list ===== */
@@ -231,14 +231,14 @@
}
.aksrt-orders-page__page-chip:hover {
border-color: var(--color-primary);
border-color: color-mix(in srgb, var(--color-primary) 45%, var(--color-line, #e5e7eb));
color: var(--color-primary);
}
.aksrt-orders-page__page-chip.is-active {
background: var(--color-primary);
color: var(--color-on-primary);
border-color: var(--color-primary);
border-color: color-mix(in srgb, var(--color-primary) 45%, var(--color-line, #e5e7eb));
}
/* ===== Empty state ===== */
@@ -281,8 +281,8 @@
.aksrt-orders-page__select:focus,
.aksrt-orders-page__textarea:focus {
outline: none;
border-color: var(--color-primary);
box-shadow: 0 0 0 3px var(--color-primary-soft);
border-color: color-mix(in srgb, var(--color-primary) 45%, var(--color-line, #e5e7eb));
box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-primary) 18%, transparent);
}
/* ===== Shared Modal (orders page) ===== */
@@ -434,5 +434,5 @@ html.dark .aksrt-orders-page__filter-chip {
html.dark .aksrt-orders-page__filter-chip.is-active,
html.dark .aksrt-orders-page__filter-chip.is-active {
border-color: var(--color-primary);
border-color: color-mix(in srgb, var(--color-primary) 45%, var(--color-line, #e5e7eb));
}
+3
View File
@@ -187,6 +187,9 @@ if (class_exists('AKSRT_Content_Visibility')) {
if (class_exists('AKSRT_SMS')) {
AKSRT_SMS::get_instance()->init();
}
if (class_exists('AKSRT_AI')) {
AKSRT_AI::get_instance(); // config-gated; available when admin enables
}
if (class_exists('AKSRT_WeChat_Notify')) {
AKSRT_WeChat_Notify::get_instance()->init();
}
@@ -577,7 +577,26 @@ class AKSRT_Admin_User_Controller extends AKSRT_Admin_Controller_Base {
}
public function rest_delete_notification_item(WP_REST_Request $request): WP_REST_Response {
return $this->success(['message' => __('当前版本暂未提供后台删除单条消息能力', 'aksrt')]);
$user_id = get_current_user_id();
if ($user_id <= 0) {
return $this->error(__('请先登录', 'aksrt'), 401);
}
$params = $this->get_json_params($request);
$id = sanitize_text_field((string) ($params['id'] ?? $request->get_param('id') ?? ''));
if ($id === '') {
return $this->error(__('参数错误', 'aksrt'), 400);
}
if (function_exists('aksrt_delete_user_notification')) {
aksrt_delete_user_notification($user_id, $id);
} elseif (class_exists('AKSRT_Message')) {
AKSRT_Message::get_instance()->mark_read($user_id, $id);
}
return $this->success([
'message' => __('消息已删除', 'aksrt'),
'unread' => function_exists('aksrt_get_user_unread_notification_count')
? aksrt_get_user_unread_notification_count($user_id)
: 0,
]);
}
public function rest_run_notification_cleanup(WP_REST_Request $request): WP_REST_Response {
@@ -638,11 +657,65 @@ class AKSRT_Admin_User_Controller extends AKSRT_Admin_Controller_Base {
}
public function rest_upload_user_background(WP_REST_Request $request): WP_REST_Response {
return $this->error(__('当前版本暂未提供后台 REST 背景图上传,请使用标准媒体上传流程。', 'aksrt'), 501);
$user_id = get_current_user_id();
if ($user_id <= 0) {
return $this->error(__('请先登录', 'aksrt'), 401);
}
if (empty($_FILES['background']) && empty($_FILES['file'])) {
return $this->error(__('请选择要上传的图片', 'aksrt'), 400);
}
require_once ABSPATH . 'wp-admin/includes/file.php';
require_once ABSPATH . 'wp-admin/includes/media.php';
require_once ABSPATH . 'wp-admin/includes/image.php';
$file_key = !empty($_FILES['background']) ? 'background' : 'file';
$attachment_id = media_handle_upload($file_key, 0);
if (is_wp_error($attachment_id)) {
return $this->error($attachment_id->get_error_message(), 400);
}
$url = wp_get_attachment_url((int) $attachment_id);
if (!$url) {
return $this->error(__('上传失败', 'aksrt'), 500);
}
update_user_meta($user_id, 'aksrt_background_image', esc_url_raw($url));
update_user_meta($user_id, 'aksrt_background_attachment_id', (int) $attachment_id);
return $this->success([
'message' => __('背景图已更新', 'aksrt'),
'data' => [
'url' => $url,
'attachment_id' => (int) $attachment_id,
],
]);
}
public function rest_upload_comment_image(WP_REST_Request $request): WP_REST_Response {
return $this->error(__('当前版本暂未提供后台 REST 评论图片上传,请使用标准媒体上传流程。', 'aksrt'), 501);
$user_id = get_current_user_id();
if ($user_id <= 0) {
return $this->error(__('请先登录', 'aksrt'), 401);
}
if (empty($_FILES['image']) && empty($_FILES['file'])) {
return $this->error(__('请选择要上传的图片', 'aksrt'), 400);
}
require_once ABSPATH . 'wp-admin/includes/file.php';
require_once ABSPATH . 'wp-admin/includes/media.php';
require_once ABSPATH . 'wp-admin/includes/image.php';
$file_key = !empty($_FILES['image']) ? 'image' : 'file';
$attachment_id = media_handle_upload($file_key, 0);
if (is_wp_error($attachment_id)) {
return $this->error($attachment_id->get_error_message(), 400);
}
$url = wp_get_attachment_url((int) $attachment_id);
if (!$url) {
return $this->error(__('上传失败', 'aksrt'), 500);
}
return $this->success([
'message' => __('图片上传成功', 'aksrt'),
'data' => [
'url' => $url,
'attachment_id' => (int) $attachment_id,
],
]);
}
public function rest_get_credits_me(WP_REST_Request $request): WP_REST_Response {
@@ -401,7 +401,7 @@ class AKSRT_Settings_Integration {
$quick_lines = array_filter(array_map('trim', preg_split('/\r\n|\r|\n/', $quick_often)));
return [
'enabled' => !empty($settings['private_s']),
'enabled' => !array_key_exists('private_s', $settings) || !empty($settings['private_s']),
'smilie' => !empty($settings['private_smilie_s']),
'code' => !empty($settings['private_code_s']),
'image' => !empty($settings['private_image_s']),
+2 -2
View File
@@ -278,14 +278,14 @@ function aksrt_register_forum_topic_meta() {
// 收藏 (Wave3)
'_aksrt_favorite_count' => ['type' => 'integer', 'default' => 0],
// 封面扩展位 (§7.3 待实现)
// 封面扩展位(论坛帖子封面;前台 forum-topic 渲染)
'_aksrt_cover_type' => ['type' => 'string', 'default' => ''],
'_aksrt_cover_image' => ['type' => 'string', 'default' => ''],
'_aksrt_featured_slide' => ['type' => 'array', 'default' => []],
'_aksrt_featured_video' => ['type' => 'string', 'default' => ''],
'_aksrt_cover_ratio' => ['type' => 'string', 'default' => '16:9'],
// 付费内容扩展位 (§7.3 待实现)
// 付费内容扩展位(论坛帖子付费门槛;前台 forum-topic 渲染)
'_aksrt_allow_view' => ['type' => 'string', 'default' => 'public'],
'_aksrt_pay_price' => ['type' => 'number', 'default' => 0],
'_aksrt_pay_vip_price' => ['type' => 'number', 'default' => 0],
+19 -54
View File
@@ -36,37 +36,12 @@ if (!function_exists('aksrt_get_resource_meta')) {
$resource_view_count = (int) get_post_meta($p->ID, AKSRT_Domain_Model::RESOURCE_VIEW_COUNT_KEY, true);
$common_view_count = (int) get_post_meta($p->ID, AKSRT_Domain_Model::POST_VIEW_COUNT_KEY, true);
return [
'version' => (string) ($pay_meta['version'] ?? ''),
'size' => (string) ($pay_meta['size'] ?? ''),
'price' => (float) ($pay_meta['price'] ?? 0),
'original_price' => (float) ($pay_meta['original_price'] ?? 0),
'vip1_price' => (float) ($pay_meta['vip1_price'] ?? 0),
'vip2_price' => (float) ($pay_meta['vip2_price'] ?? 0),
'pay_type' => (string) ($pay_meta['pay_type'] ?? AKSRT_Domain_Model::PAY_TYPE_DOWNLOAD),
'license' => (string) ($pay_meta['license'] ?? ''),
'compat' => (string) ($pay_meta['compat'] ?? ''),
'demo_url' => (string) ($pay_meta['demo_url'] ?? ''),
'downloads' => array_values(is_array($pay_meta['downloads'] ?? null) ? $pay_meta['downloads'] : []),
'download_count' => max(0, max($download_count, $legacy_download_count)),
'view_count' => max(0, max($resource_view_count, $common_view_count)),
'require_login' => !empty($pay_meta['require_login']),
'require_captcha' => !empty($pay_meta['require_captcha']),
];
// 一次取出全部 post meta(WP 已缓存到 object cache)
$all = get_post_meta($p->ID);
if (!is_array($all)) $all = [];
$get = static function ($key) use ($all) {
if (!isset($all[$key]) || !is_array($all[$key]) || empty($all[$key])) return null;
return maybe_unserialize($all[$key][0]);
};
$downloads = $get('_aksrt_res_downloads');
if (!is_array($downloads)) $downloads = [];
// Normalize downloads extract_code aliases for legacy rows still stored on pay meta.
$downloads = array_values(is_array($pay_meta['downloads'] ?? null) ? $pay_meta['downloads'] : []);
$downloads = array_values(array_filter(array_map(static function ($row) {
if (!is_array($row)) return null;
if (!is_array($row)) {
return null;
}
$extract_keys = [
'extract_code', 'extractCode', 'extract', 'extract_key',
'extraction_code', 'extractionCode',
@@ -85,33 +60,23 @@ if (!function_exists('aksrt_get_resource_meta')) {
$row['extract_code'] = isset($row['extract_code']) ? trim((string) $row['extract_code']) : '';
return $row;
}, $downloads)));
$resource_download_count = (int) ($get('_aksrt_res_download_count') ?? 0);
$legacy_download_count = (int) ($get('download_count') ?? 0);
$resource_view_count = (int) ($get('_aksrt_res_view_count') ?? 0);
$common_view_count = (int) ($get('aksrt_post_views') ?? 0);
$allowed_pay_types = ['download', 'reading', 'gallery', 'video', 'vip'];
$pay_type = (string) ($get('_aksrt_res_pay_type') ?? 'download');
if (!in_array($pay_type, $allowed_pay_types, true)) {
$pay_type = 'download';
}
return [
'version' => (string) ($get('_aksrt_res_version') ?? ''),
'size' => (string) ($get('_aksrt_res_size') ?? ''),
'price' => (float) ($get('_aksrt_res_price') ?? 0),
'original_price' => (float) ($get('_aksrt_res_original_price') ?? 0),
'vip1_price' => (float) ($get('_aksrt_res_vip1_price') ?? 0),
'vip2_price' => (float) ($get('_aksrt_res_vip2_price') ?? 0),
'pay_type' => $pay_type,
'license' => (string) ($get('_aksrt_res_license') ?? ''),
'compat' => (string) ($get('_aksrt_res_compat') ?? ''),
'demo_url' => (string) ($get('_aksrt_res_demo_url') ?? ''),
'downloads' => array_values($downloads),
'download_count' => max(0, max($resource_download_count, $legacy_download_count)),
'version' => (string) ($pay_meta['version'] ?? ''),
'size' => (string) ($pay_meta['size'] ?? ''),
'price' => (float) ($pay_meta['price'] ?? 0),
'original_price' => (float) ($pay_meta['original_price'] ?? 0),
'vip1_price' => (float) ($pay_meta['vip1_price'] ?? 0),
'vip2_price' => (float) ($pay_meta['vip2_price'] ?? 0),
'pay_type' => (string) ($pay_meta['pay_type'] ?? AKSRT_Domain_Model::PAY_TYPE_DOWNLOAD),
'license' => (string) ($pay_meta['license'] ?? ''),
'compat' => (string) ($pay_meta['compat'] ?? ''),
'demo_url' => (string) ($pay_meta['demo_url'] ?? ''),
'downloads' => $downloads,
'download_count' => max(0, max($download_count, $legacy_download_count)),
'view_count' => max(0, max($resource_view_count, $common_view_count)),
'require_login' => (bool) ($get('_aksrt_res_require_login') ?? false),
'require_captcha' => (bool) ($get('_aksrt_res_require_captcha') ?? false),
'require_login' => !empty($pay_meta['require_login']),
'require_captcha' => !empty($pay_meta['require_captcha']),
];
}
}
+26 -1
View File
@@ -92,13 +92,38 @@ if (!function_exists('aksrt_get_user_home_page_context')) {
$follow_count = (int) AKSRT_Follow::get_instance()->get_following_count($user_id);
}
$plate_count = 0;
if ($forum_instance) {
$seen_plates = [];
if (method_exists($forum_instance, 'get_user_followed_plates')) {
foreach ((array) $forum_instance->get_user_followed_plates($user_id) as $plate) {
$pid = (int) ($plate['id'] ?? 0);
if ($pid > 0) {
$seen_plates[$pid] = true;
}
}
}
if (method_exists($forum_instance, 'get_user_managed_plates')) {
$managed = (array) $forum_instance->get_user_managed_plates($user_id);
foreach (['owned', 'moderating'] as $bucket) {
foreach ((array) ($managed[$bucket] ?? []) as $plate) {
$pid = (int) ($plate['id'] ?? 0);
if ($pid > 0) {
$seen_plates[$pid] = true;
}
}
}
}
$plate_count = count($seen_plates);
}
$tab_counts = [
'posts' => $post_count,
'comments' => $comment_count,
'favorites' => $favorite_count,
'credits' => $credits_enabled && $is_own_profile ? (int) round((float) $credit_balance) : 0,
'product' => $product_count,
'plate' => 0,
'plate' => $plate_count,
'forum' => $forum_topic_count,
'follow' => $follow_count,
];
+10 -2
View File
@@ -54,10 +54,14 @@ $name_topic = $forum_names['posts'] ?? __('主题', 'aksrt');
$name_reply = $forum_names['comment'] ?? __('回复', 'aksrt');
?>
<main id="main-content" class="site-main content-shell" tabindex="-1">
<main id="main-content" class="site-main content-shell content-shell--stream content-shell--forum" tabindex="-1">
<div class="content-wrap container">
<div class="content-layout content-layout--no-sidebar">
<div class="content-layout__primary">
<?php if (function_exists('aksrt_breadcrumbs')) { aksrt_breadcrumbs(); } ?>
<div class="aksrt-forum-board container"
<div class="aksrt-forum-board"
data-board-id="<?php echo esc_attr((string) $board_id); ?>"
data-nonce="<?php echo esc_attr($nonce); ?>"
data-active-sort="<?php echo esc_attr($active_sort); ?>">
@@ -141,6 +145,10 @@ $name_reply = $forum_names['comment'] ?? __('回复', 'aksrt');
</div>
<?php endif; ?>
</div>
</div>
</div>
</div>
</div>
</main>
+10 -2
View File
@@ -42,10 +42,14 @@ if (is_array($cat_moderator_ids)) {
}
?>
<main id="main-content" class="site-main content-shell" tabindex="-1">
<main id="main-content" class="site-main content-shell content-shell--stream content-shell--forum" tabindex="-1">
<div class="content-wrap container">
<div class="content-layout content-layout--no-sidebar">
<div class="content-layout__primary">
<?php if (function_exists('aksrt_breadcrumbs')) { aksrt_breadcrumbs(); } ?>
<div class="aksrt-forum-plate-cat container">
<div class="aksrt-forum-plate-cat">
<div class="aksrt-forum-plate-cat__header">
<h1><?php echo esc_html($term ? $term->name : ''); ?></h1>
<?php if ($term && $term->description) : ?>
@@ -101,6 +105,10 @@ if (is_array($cat_moderator_ids)) {
<i class="fas fa-arrow-left"></i> <?php printf(esc_html__('返回%s', 'aksrt'), esc_html($forum_name)); ?>
</a>
</div>
</div>
</div>
</div>
</div>
</main>
+10 -2
View File
@@ -55,11 +55,15 @@ $is_followed = $forum && $current_user_id > 0 ? $forum->is_user_following_pla
$max_pages = (int) ($view['pagination']['max_pages'] ?? 1);
?>
<main id="main-content" class="site-main content-shell" tabindex="-1">
<main id="main-content" class="site-main content-shell content-shell--stream content-shell--forum" tabindex="-1">
<div class="content-wrap container">
<div class="content-layout content-layout--no-sidebar">
<div class="content-layout__primary">
<?php if (function_exists('aksrt_breadcrumbs')) { aksrt_breadcrumbs(); } ?>
<?php if (!empty($permissions['access_denied'])) : ?>
<div class="aksrt-forum-board container">
<div class="aksrt-forum-board">
<div class="aksrt-forum-board__access-denied">
<i class="fas fa-lock"></i>
<h2><?php esc_html_e('访问受限', 'aksrt'); ?></h2>
@@ -283,6 +287,10 @@ $max_pages = (int) ($view['pagination']['max_pages'] ?? 1);
</div>
<?php endif; ?>
</div>
</div>
</div>
</main>
<?php get_footer(); ?>
+10 -2
View File
@@ -24,9 +24,13 @@ $term_name = $term->name ?? '';
$term_desc = $term->description ?? '';
?>
<main id="main-content" class="site-main content-shell" tabindex="-1">
<main id="main-content" class="site-main content-shell content-shell--stream content-shell--forum" tabindex="-1">
<div class="content-wrap container">
<div class="content-layout content-layout--no-sidebar">
<div class="content-layout__primary">
<div class="aksrt-forum-tag container">
<div class="aksrt-forum-tag">
<header class="aksrt-forum-tag__header">
<h1 class="aksrt-forum-tag__title">
<i class="fas fa-tag"></i>
@@ -61,6 +65,10 @@ $term_desc = $term->description ?? '';
<p><?php esc_html_e('内容空空如也', 'aksrt'); ?></p>
</div>
<?php endif; ?>
</div>
</div>
</div>
</div>
</main>
+48 -4
View File
@@ -60,8 +60,12 @@ if (empty($topic['can_view'])) :
$credits_cost = (int) get_post_meta($topic_id, '_aksrt_credits_cost', true);
$pay_price = get_post_meta($topic_id, '_aksrt_pay_price', true);
?>
<main id="main-content" class="site-main content-shell" tabindex="-1">
<div class="aksrt-forum-topic container">
<main id="main-content" class="site-main content-shell content-shell--stream content-shell--forum" tabindex="-1">
<div class="content-wrap container">
<div class="content-layout content-layout--no-sidebar">
<div class="content-layout__primary">
<div class="aksrt-forum-topic">
<div class="aksrt-forum-topic__denied">
<i class="fas fa-eye-slash"></i>
<h1><?php esc_html_e('当前主题暂不可访问', 'aksrt'); ?></h1>
@@ -94,6 +98,10 @@ if (empty($topic['can_view'])) :
<?php endif; ?>
</div>
</div>
</div>
</div>
</div>
</main>
<?php
get_footer();
@@ -109,11 +117,43 @@ $is_locked = !empty($topic['locked']);
$comments_enabled = !empty($permissions['can_reply']);
?>
<main id="main-content" class="site-main content-shell" tabindex="-1">
<main id="main-content" class="site-main content-shell content-shell--stream content-shell--forum" tabindex="-1">
<div class="content-wrap container">
<div class="content-layout content-layout--no-sidebar">
<div class="content-layout__primary">
<?php if (function_exists('aksrt_breadcrumbs')) { aksrt_breadcrumbs(); } ?>
<div class="aksrt-forum-topic container">
<div class="aksrt-forum-topic">
<?php
// Cover + paid extensions for forum topics.
$cover_type = (string) get_post_meta(get_the_ID(), '_aksrt_cover_type', true);
$cover_image = (string) get_post_meta(get_the_ID(), '_aksrt_cover_image', true);
$cover_video = (string) get_post_meta(get_the_ID(), '_aksrt_featured_video', true);
$cover_ratio = (string) get_post_meta(get_the_ID(), '_aksrt_cover_ratio', true);
if ($cover_ratio === '') { $cover_ratio = '16:9'; }
if ($cover_type === 'image' && $cover_image !== '') : ?>
<div class="aksrt-forum-topic__cover aksrt-forum-topic__cover--image" style="--cover-ratio:<?php echo esc_attr(str_replace(':', '/', $cover_ratio)); ?>">
<img src="<?php echo esc_url($cover_image); ?>" alt="" loading="lazy">
</div>
<?php elseif ($cover_type === 'video' && $cover_video !== '') : ?>
<div class="aksrt-forum-topic__cover aksrt-forum-topic__cover--video">
<?php echo wp_oembed_get($cover_video) ?: esc_html($cover_video); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
</div>
<?php elseif ($cover_type === 'slide') :
$slides = get_post_meta(get_the_ID(), '_aksrt_featured_slide', true);
if (is_array($slides) && $slides) : ?>
<div class="aksrt-forum-topic__cover aksrt-forum-topic__cover--slide">
<?php foreach ($slides as $slide) :
$src = is_array($slide) ? (string) ($slide['url'] ?? $slide['src'] ?? '') : (string) $slide;
if ($src === '') { continue; } ?>
<img src="<?php echo esc_url($src); ?>" alt="" loading="lazy">
<?php endforeach; ?>
</div>
<?php endif; ?>
<?php endif; ?>
<?php if ($show_breadcrumbs) : ?>
<div class="aksrt-forum-topic__breadcrumb">
<?php if ($bc_show_home) : ?>
@@ -667,6 +707,10 @@ $comments_enabled = !empty($permissions['can_reply']);
<a href="<?php echo esc_url(wp_login_url(get_permalink())); ?>"><?php esc_html_e('登录后参与回复', 'aksrt'); ?></a>
</div>
<?php endif; ?>
</div>
</div>
</div>
</div>
</main>
+1 -1
View File
@@ -67,7 +67,7 @@ $logo_url = class_exists('AKSRT_Settings') ? AKSRT_Settings::user_logo_url() : '
<i class="fas fa-times"></i>
</button>
<div class="aksrt-modal-auth__header">
<div class="aksrt-modal-auth__header modal-colorful-header">
<?php if ($logo_url) : ?>
<div class="aksrt-modal-auth__logo aksrt-modal-auth__logo--image"><img src="<?php echo esc_url($logo_url); ?>" alt=""></div>
<?php else : ?>
+45 -1
View File
@@ -172,6 +172,50 @@ extract($args, EXTR_SKIP); // phpcs:ignore WordPress.PHP.DontExtract.extract_ext
<?php if (in_array('plate', $enabled_tabs, true)) : ?>
<div id="panel-plate" class="dashboard-panel<?php echo $active_tab === 'plate' ? ' is-active' : ''; ?>" role="tabpanel"<?php echo $active_tab !== 'plate' ? ' hidden' : ''; ?>>
<?php aksrt_render_profile_empty($svg_empty_post, __('暂无圈子内容', 'aksrt')); ?>
<?php
$plate_items = [];
if ($forum_instance) {
if (method_exists($forum_instance, 'get_user_followed_plates')) {
$plate_items = array_merge($plate_items, (array) $forum_instance->get_user_followed_plates((int) $user_id));
}
if (method_exists($forum_instance, 'get_user_managed_plates')) {
$managed = (array) $forum_instance->get_user_managed_plates((int) $user_id);
foreach (['owned', 'moderating'] as $bucket) {
foreach ((array) ($managed[$bucket] ?? []) as $plate) {
$plate_items[] = $plate;
}
}
}
}
// de-dupe by id
$seen = [];
$unique_plates = [];
foreach ($plate_items as $plate) {
$pid = (int) ($plate['id'] ?? 0);
if ($pid <= 0 || isset($seen[$pid])) {
continue;
}
$seen[$pid] = true;
$unique_plates[] = $plate;
}
if (!empty($unique_plates)) :
?>
<div class="uh-forum__plate-grid">
<?php foreach ($unique_plates as $plate) :
$purl = !empty($plate['url']) ? (string) $plate['url'] : get_permalink((int) ($plate['id'] ?? 0));
?>
<a class="uh-forum__plate-card" href="<?php echo esc_url((string) $purl); ?>">
<div class="uh-forum__plate-name"><?php echo esc_html((string) ($plate['name'] ?? '')); ?></div>
<div class="uh-forum__plate-stats">
<span><?php printf(esc_html__('%d 帖子', 'aksrt'), (int) ($plate['topic_count'] ?? $plate['post_count'] ?? 0)); ?></span>
<span><?php printf(esc_html__('%d 关注', 'aksrt'), (int) ($plate['follow_count'] ?? 0)); ?></span>
</div>
</a>
<?php endforeach; ?>
</div>
<?php else :
aksrt_render_profile_empty($svg_empty_post, __('暂无圈子内容', 'aksrt'));
endif;
?>
</div>
<?php endif; ?>