导入 AKSRT 主题开发源码
This commit is contained in:
1 parent
9681dd3d48
commit
1268a55dd0
595 files changed
+127705
No files matched your search
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
/**
|
||||
* Template Name: AKSRT - Archives
|
||||
* Template Post Type: page
|
||||
*
|
||||
* 文章归档页:按年月分组展示全站文章。
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
get_header();
|
||||
global $wpdb;
|
||||
?>
|
||||
|
||||
<main id="main-content" class="container page-content-default" tabindex="-1">
|
||||
<header class="page-header">
|
||||
<h1 class="entry-title"><?php esc_html_e('文章归档', 'aksrt'); ?></h1>
|
||||
</header>
|
||||
|
||||
<div class="content-wrap">
|
||||
<div class="content-layout content-layout--no-sidebar">
|
||||
<div class="content-layout__primary">
|
||||
<div class="aksrt-archives container">
|
||||
<?php
|
||||
$years = $wpdb->get_results(
|
||||
"SELECT DISTINCT YEAR(post_date) AS year, MONTH(post_date) AS month, COUNT(*) AS count
|
||||
FROM {$wpdb->posts}
|
||||
WHERE post_type = 'post' AND post_status = 'publish'
|
||||
GROUP BY YEAR(post_date), MONTH(post_date)
|
||||
ORDER BY year DESC, month DESC"
|
||||
); // phpcs:ignore WordPress.DB.DirectDatabaseQuery
|
||||
|
||||
$current_year = 0;
|
||||
foreach ($years as $row) :
|
||||
if ((int) $row->year !== $current_year) :
|
||||
$current_year = (int) $row->year;
|
||||
?>
|
||||
<h2 class="aksrt-archives__year"><?php echo esc_html($current_year); ?></h2>
|
||||
<?php endif; ?>
|
||||
<h3 class="aksrt-archives__month">
|
||||
<?php echo esc_html(sprintf('%d 月 (%d 篇)', (int) $row->month, (int) $row->count)); ?>
|
||||
</h3>
|
||||
<ul class="aksrt-archives__list">
|
||||
<?php
|
||||
$month_posts = get_posts([
|
||||
'year' => (int) $row->year,
|
||||
'monthnum' => (int) $row->month,
|
||||
'posts_per_page' => -1,
|
||||
'post_status' => 'publish',
|
||||
]);
|
||||
foreach ($month_posts as $mp) :
|
||||
?>
|
||||
<li class="aksrt-archives__item">
|
||||
<span class="aksrt-archives__date"><?php echo esc_html(get_the_date('m-d', $mp)); ?></span>
|
||||
<a href="<?php echo esc_url(get_permalink($mp->ID)); ?>" class="aksrt-archives__link"><?php echo esc_html($mp->post_title); ?></a>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<?php
|
||||
get_footer();
|
||||
@@ -0,0 +1,139 @@
|
||||
<?php
|
||||
/**
|
||||
* Template Name: AKSRT - Bind Account
|
||||
* Template Post Type: page
|
||||
*
|
||||
* Theme auth route template: /bind-account/
|
||||
*
|
||||
* 第三方登录未匹配账号时的绑定页面
|
||||
* 用户输入已有账号密码完成OAuth绑定
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
// ============================================
|
||||
// 处理绑定请求(POST)
|
||||
// ============================================
|
||||
$bind_error = '';
|
||||
$bind_verify_url = '';
|
||||
$oauth_data = null;
|
||||
$provider_name = '';
|
||||
$obk = '';
|
||||
|
||||
if (isset($_GET['obk'])) {
|
||||
$obk = sanitize_text_field($_GET['obk']);
|
||||
$oauth_data = AKSRT_Auth_Service::get_oauth_bind_context($obk);
|
||||
}
|
||||
|
||||
if (! $oauth_data || ! is_array($oauth_data)) {
|
||||
// 无效或已过期的OAuth数据
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$bind_error = __('绑定会话已过期,请重新使用第三方登录', 'aksrt');
|
||||
}
|
||||
} else {
|
||||
$provider_name = AKSRT_Auth_Service::get_oauth_provider_name($oauth_data['provider'] ?? '');
|
||||
}
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['log'], $_POST['pwd']) && empty($bind_error)) {
|
||||
if ($obk === '' && !empty($_POST['obk'])) {
|
||||
$obk = sanitize_text_field($_POST['obk']);
|
||||
}
|
||||
|
||||
if ($oauth_data === null && $obk !== '') {
|
||||
$oauth_data = AKSRT_Auth_Service::get_oauth_bind_context($obk);
|
||||
}
|
||||
|
||||
$result = AKSRT_Auth_Service::bind_oauth_account($_POST, $oauth_data);
|
||||
if (empty($result['success'])) {
|
||||
$bind_error = $result['error'] ?? __('绑定失败,请稍后重试', 'aksrt');
|
||||
$bind_verify_url = $result['verify_url'] ?? '';
|
||||
} else {
|
||||
$user = $result['user'];
|
||||
$provider = $result['provider'];
|
||||
wp_safe_redirect(add_query_arg(['tab' => 'settings', 'oauth_bound' => $provider], aksrt_get_user_center_url()));
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
get_header();
|
||||
?>
|
||||
|
||||
<main id="main-content" class="site-main" tabindex="-1">
|
||||
<div class="auth-shell">
|
||||
<div class="auth-card">
|
||||
|
||||
<?php if (! $oauth_data || ! is_array($oauth_data)) : ?>
|
||||
<!-- 会话过期状态 -->
|
||||
<div class="auth-card__expired">
|
||||
<div class="auth-card__logo" aria-hidden="true">AK</div>
|
||||
<h1 class="auth-card__title"><?php bloginfo('name'); ?></h1>
|
||||
<p><?php echo esc_html(__('绑定会话已过期或无效', 'aksrt')); ?></p>
|
||||
<a href="<?php echo esc_url(aksrt_get_login_url()); ?>" class="btn-primary btn-lg auth-card__expired-action">
|
||||
<?php esc_html_e('返回登录', 'aksrt'); ?>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<?php else : ?>
|
||||
<!-- 正常绑定表单 -->
|
||||
|
||||
<div class="auth-card__logo" aria-hidden="true">AK</div>
|
||||
<h1 class="auth-card__title"><?php bloginfo('name'); ?></h1>
|
||||
<p class="auth-card__subtitle">
|
||||
<?php printf(esc_html__('通过 %s 登录,请绑定你的已有账号', 'aksrt'), '<strong>' . esc_html($provider_name) . '</strong>'); ?>
|
||||
</p>
|
||||
|
||||
<?php if (!empty($bind_error)) : ?>
|
||||
<div class="alert alert--error" role="alert">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="10"/><line x1="12" x2="12" y1="8" y2="12"/><line x1="12" x2="12.01" y1="16" y2="16"/></svg>
|
||||
<span>
|
||||
<?php echo esc_html($bind_error); ?>
|
||||
<?php if (!empty($bind_verify_url)) : ?>
|
||||
<a href="<?php echo esc_url($bind_verify_url); ?>"><?php esc_html_e('前往验证邮箱', 'aksrt'); ?></a>
|
||||
<?php endif; ?>
|
||||
</span>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<form class="auth-form" id="aksrt-bind-form" method="post" action="">
|
||||
<?php wp_nonce_field('aksrt_bind', '_bind_nonce'); ?>
|
||||
<input type="hidden" name="obk" value="<?php echo esc_attr($obk); ?>">
|
||||
<div class="form-field">
|
||||
<label for="bind_user_login"><?php esc_html_e('邮箱 / 用户名', 'aksrt'); ?></label>
|
||||
<div class="input-wrap">
|
||||
<span class="input-icon" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="width:18px;height:18px;"><rect width="20" height="16" x="2" y="4" rx="2"/><path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7"/></svg></span>
|
||||
<input type="text" name="log" id="bind_user_login" autocomplete="username" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-field form-field--pwd">
|
||||
<label for="bind_user_pass"><?php esc_html_e('密码', 'aksrt'); ?></label>
|
||||
<div class="input-wrap">
|
||||
<span class="input-icon" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="width:18px;height:18px;"><rect width="18" height="11" x="3" y="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg></span>
|
||||
<input type="password" name="pwd" id="bind_user_pass" autocomplete="current-password" required>
|
||||
<button type="button" class="toggle-pwd" data-target="bind_user_pass" aria-label="<?php esc_attr_e('显示或隐藏密码', 'aksrt'); ?>"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="width:16px;height:16px;"><path d="M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10 7-10-7Z"/><circle cx="12" cy="12" r="3"/></svg></button>
|
||||
</div>
|
||||
</div>
|
||||
<?php if (function_exists('aksrt_render_captcha')) : ?>
|
||||
<?php aksrt_render_captcha('bind'); ?>
|
||||
<?php endif; ?>
|
||||
<button type="submit" name="wp-submit" class="btn-primary btn-lg" style="width:100%;margin-top:8px;">
|
||||
<?php esc_html_e('绑定并登录', 'aksrt'); ?>
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<?php if (get_option('users_can_register')) :
|
||||
$register_url = aksrt_get_register_url();
|
||||
$register_url = add_query_arg('obk', sanitize_text_field($_GET['obk']), $register_url);
|
||||
?>
|
||||
<p class="auth-footer-link">
|
||||
<?php esc_html_e('还没有账号?', 'aksrt'); ?>
|
||||
<a href="<?php echo esc_url($register_url); ?>"><?php esc_html_e('注册并绑定账号', 'aksrt'); ?></a>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php endif; ?><!-- end 正常绑定表单 -->
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<?php
|
||||
get_footer();
|
||||
@@ -0,0 +1,281 @@
|
||||
<?php
|
||||
/**
|
||||
* Template Name: AKSRT - Cart
|
||||
* Template Post Type: page
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
get_header();
|
||||
|
||||
if (!is_user_logged_in()) {
|
||||
$login_url = function_exists('aksrt_get_login_url') ? aksrt_get_login_url() : wp_login_url(get_permalink());
|
||||
wp_safe_redirect($login_url);
|
||||
exit;
|
||||
}
|
||||
|
||||
$cart_view = function_exists('aksrt_get_cart_page_view')
|
||||
? aksrt_get_cart_page_view(get_current_user_id())
|
||||
: [
|
||||
'payment_methods' => [],
|
||||
'shipping_methods' => [],
|
||||
'address_book' => [],
|
||||
'coupon_enabled' => false,
|
||||
'currency_symbol' => '¥',
|
||||
'pending_orders' => [],
|
||||
];
|
||||
|
||||
$pending_orders = is_array($cart_view['pending_orders'] ?? null) ? $cart_view['pending_orders'] : [];
|
||||
$shipping_methods = is_array($cart_view['shipping_methods'] ?? null) ? array_values($cart_view['shipping_methods']) : [];
|
||||
$payment_methods = is_array($cart_view['payment_methods'] ?? null) ? array_values($cart_view['payment_methods']) : [];
|
||||
$address_book = is_array($cart_view['address_book'] ?? null) ? $cart_view['address_book'] : [];
|
||||
?>
|
||||
|
||||
<main id="main-content" class="site-main content-shell" tabindex="-1">
|
||||
<?php if (function_exists('aksrt_breadcrumbs')) { aksrt_breadcrumbs(); } ?>
|
||||
|
||||
<div
|
||||
class="aksrt-cart-page container"
|
||||
data-aksrt-cart-page
|
||||
data-currency-symbol="<?php echo esc_attr((string) ($cart_view['currency_symbol'] ?? '¥')); ?>"
|
||||
data-coupon-enabled="<?php echo !empty($cart_view['coupon_enabled']) ? '1' : '0'; ?>"
|
||||
>
|
||||
<div class="aksrt-cart-page__header">
|
||||
<div>
|
||||
<h1 class="aksrt-cart-page__title"><?php esc_html_e('购物车', 'aksrt'); ?></h1>
|
||||
<p class="aksrt-cart-page__subtitle"><?php esc_html_e('在下单前确认地址、运费、优惠券和支付方式。', 'aksrt'); ?></p>
|
||||
</div>
|
||||
<?php if (!empty($pending_orders)) : ?>
|
||||
<div class="aksrt-cart-page__pending">
|
||||
<span class="aksrt-cart-page__pending-label"><?php esc_html_e('待支付订单', 'aksrt'); ?></span>
|
||||
<div class="aksrt-cart-page__pending-list">
|
||||
<?php foreach ($pending_orders as $pending_order) : ?>
|
||||
<button
|
||||
type="button"
|
||||
class="aksrt-cart-page__pending-chip"
|
||||
data-aksrt-resume-order="<?php echo esc_attr((string) ($pending_order['order_number'] ?? '')); ?>"
|
||||
>
|
||||
<?php echo esc_html((string) ($pending_order['order_number'] ?? '')); ?>
|
||||
</button>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<div class="aksrt-cart-page__layout">
|
||||
<section class="aksrt-cart-page__main">
|
||||
<div class="aksrt-cart-page__panel">
|
||||
<div class="aksrt-cart-page__panel-head">
|
||||
<h2><?php esc_html_e('商品清单', 'aksrt'); ?></h2>
|
||||
<button type="button" class="btn-ghost btn-sm" data-aksrt-clear-cart><?php esc_html_e('清空购物车', 'aksrt'); ?></button>
|
||||
</div>
|
||||
<div class="aksrt-cart-page__items" data-aksrt-cart-items>
|
||||
<div class="aksrt-cart-page__empty">
|
||||
<i class="fas fa-shopping-cart" aria-hidden="true"></i>
|
||||
<p><?php esc_html_e('购物车为空,去商品页添加想购买的内容。', 'aksrt'); ?></p>
|
||||
<a href="<?php echo esc_url(home_url('/')); ?>" class="btn-outline btn-sm"><?php esc_html_e('继续浏览', 'aksrt'); ?></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="aksrt-cart-page__grid">
|
||||
<section class="aksrt-cart-page__panel">
|
||||
<div class="aksrt-cart-page__panel-head">
|
||||
<h2><?php esc_html_e('收货地址', 'aksrt'); ?></h2>
|
||||
<button type="button" class="btn-ghost btn-sm" data-aksrt-address-add>
|
||||
<i class="fas fa-plus" aria-hidden="true"></i> <?php esc_html_e('新增地址', 'aksrt'); ?>
|
||||
</button>
|
||||
</div>
|
||||
<div class="aksrt-cart-page__option-list" data-aksrt-address-list>
|
||||
<?php if (empty($address_book)) : ?>
|
||||
<div class="aksrt-cart-page__address-empty" data-aksrt-address-empty>
|
||||
<i class="fas fa-map-marker-alt" aria-hidden="true"></i>
|
||||
<p><?php esc_html_e('暂无收货地址,请先新增。', 'aksrt'); ?></p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php foreach ($address_book as $index => $address) : ?>
|
||||
<div class="aksrt-cart-page__option-card aksrt-cart-page__address-card" data-aksrt-address-card="<?php echo esc_attr((string) ($address['id'] ?? 0)); ?>">
|
||||
<label class="aksrt-cart-page__address-label">
|
||||
<input
|
||||
type="radio"
|
||||
name="aksrt_cart_address"
|
||||
value="<?php echo esc_attr((string) ($address['id'] ?? 0)); ?>"
|
||||
<?php checked($index === 0 || !empty($address['is_default'])); ?>
|
||||
>
|
||||
<span class="aksrt-cart-page__option-body">
|
||||
<strong>
|
||||
<?php echo esc_html((string) ($address['name'] ?? '')); ?>
|
||||
<?php if (!empty($address['is_default'])) : ?>
|
||||
<span class="aksrt-cart-page__default-tag"><?php esc_html_e('默认', 'aksrt'); ?></span>
|
||||
<?php endif; ?>
|
||||
</strong>
|
||||
<span><?php echo esc_html((string) ($address['phone'] ?? '')); ?></span>
|
||||
<span><?php echo esc_html((string) ($address['full_text'] ?? '')); ?></span>
|
||||
</span>
|
||||
</label>
|
||||
<div class="aksrt-cart-page__address-actions">
|
||||
<button type="button" class="btn-ghost btn-xs" data-aksrt-address-edit="<?php echo esc_attr((string) ($address['id'] ?? 0)); ?>"><?php esc_html_e('编辑', 'aksrt'); ?></button>
|
||||
<button type="button" class="btn-ghost btn-xs" data-aksrt-address-delete="<?php echo esc_attr((string) ($address['id'] ?? 0)); ?>"><?php esc_html_e('删除', 'aksrt'); ?></button>
|
||||
<?php if (empty($address['is_default'])) : ?>
|
||||
<button type="button" class="btn-ghost btn-xs" data-aksrt-address-set-default="<?php echo esc_attr((string) ($address['id'] ?? 0)); ?>"><?php esc_html_e('设为默认', 'aksrt'); ?></button>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Address Editor Modal -->
|
||||
<div class="aksrt-modal" data-aksrt-address-modal hidden>
|
||||
<div class="aksrt-modal__overlay"></div>
|
||||
<div class="aksrt-modal__dialog">
|
||||
<div class="aksrt-modal__header">
|
||||
<h3 data-aksrt-address-modal-title><?php esc_html_e('新增地址', 'aksrt'); ?></h3>
|
||||
<button type="button" class="aksrt-modal__close" data-aksrt-address-modal-close>×</button>
|
||||
</div>
|
||||
<form class="aksrt-modal__body" data-aksrt-address-form>
|
||||
<input type="hidden" name="address_id" value="">
|
||||
<div class="aksrt-cart-page__field">
|
||||
<label><?php esc_html_e('收货人', 'aksrt'); ?> *</label>
|
||||
<input type="text" name="name" class="aksrt-cart-page__input" required maxlength="50">
|
||||
</div>
|
||||
<div class="aksrt-cart-page__field">
|
||||
<label><?php esc_html_e('手机号', 'aksrt'); ?> *</label>
|
||||
<input type="tel" name="phone" class="aksrt-cart-page__input" required maxlength="20">
|
||||
</div>
|
||||
<div class="aksrt-cart-page__field-row">
|
||||
<div class="aksrt-cart-page__field">
|
||||
<label><?php esc_html_e('省份', 'aksrt'); ?></label>
|
||||
<input type="text" name="province" class="aksrt-cart-page__input" maxlength="50">
|
||||
</div>
|
||||
<div class="aksrt-cart-page__field">
|
||||
<label><?php esc_html_e('城市', 'aksrt'); ?></label>
|
||||
<input type="text" name="city" class="aksrt-cart-page__input" maxlength="50">
|
||||
</div>
|
||||
<div class="aksrt-cart-page__field">
|
||||
<label><?php esc_html_e('区/县', 'aksrt'); ?></label>
|
||||
<input type="text" name="district" class="aksrt-cart-page__input" maxlength="50">
|
||||
</div>
|
||||
</div>
|
||||
<div class="aksrt-cart-page__field">
|
||||
<label><?php esc_html_e('详细地址', 'aksrt'); ?> *</label>
|
||||
<input type="text" name="address" class="aksrt-cart-page__input" required maxlength="200">
|
||||
</div>
|
||||
<label class="aksrt-cart-page__checkbox">
|
||||
<input type="checkbox" name="is_default" value="1">
|
||||
<span><?php esc_html_e('设为默认地址', 'aksrt'); ?></span>
|
||||
</label>
|
||||
<div class="aksrt-modal__footer">
|
||||
<button type="button" class="btn-ghost" data-aksrt-address-modal-close><?php esc_html_e('取消', 'aksrt'); ?></button>
|
||||
<button type="submit" class="btn-primary"><?php esc_html_e('保存地址', 'aksrt'); ?></button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<section class="aksrt-cart-page__panel">
|
||||
<div class="aksrt-cart-page__panel-head">
|
||||
<h2><?php esc_html_e('配送与支付', 'aksrt'); ?></h2>
|
||||
</div>
|
||||
<div class="aksrt-cart-page__option-columns">
|
||||
<div>
|
||||
<h3 class="aksrt-cart-page__mini-title"><?php esc_html_e('配送方式', 'aksrt'); ?></h3>
|
||||
<div class="aksrt-cart-page__option-list" data-aksrt-shipping-list>
|
||||
<?php foreach ($shipping_methods as $index => $method) : ?>
|
||||
<label class="aksrt-cart-page__option-card">
|
||||
<input
|
||||
type="radio"
|
||||
name="aksrt_cart_shipping"
|
||||
value="<?php echo esc_attr((string) ($method['value'] ?? '')); ?>"
|
||||
<?php checked($index === 0); ?>
|
||||
>
|
||||
<span class="aksrt-cart-page__option-body">
|
||||
<strong><?php echo esc_html((string) ($method['label'] ?? '')); ?></strong>
|
||||
<span><?php echo esc_html((string) ($method['description'] ?? '')); ?></span>
|
||||
</span>
|
||||
</label>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 class="aksrt-cart-page__mini-title"><?php esc_html_e('支付方式', 'aksrt'); ?></h3>
|
||||
<div class="aksrt-cart-page__option-list" data-aksrt-payment-list>
|
||||
<?php foreach ($payment_methods as $index => $method) : ?>
|
||||
<label class="aksrt-cart-page__option-card">
|
||||
<input
|
||||
type="radio"
|
||||
name="aksrt_cart_payment"
|
||||
value="<?php echo esc_attr((string) ($method['value'] ?? '')); ?>"
|
||||
<?php checked($index === 0); ?>
|
||||
>
|
||||
<span class="aksrt-cart-page__option-body">
|
||||
<strong><?php echo esc_html((string) ($method['label'] ?? '')); ?></strong>
|
||||
<span><?php echo esc_html((string) ($method['description'] ?? '')); ?></span>
|
||||
</span>
|
||||
</label>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="aksrt-cart-page__panel">
|
||||
<div class="aksrt-cart-page__panel-head">
|
||||
<h2><?php esc_html_e('优惠与备注', 'aksrt'); ?></h2>
|
||||
</div>
|
||||
<div class="aksrt-cart-page__coupon-box">
|
||||
<label class="aksrt-cart-page__field">
|
||||
<span><?php esc_html_e('优惠券', 'aksrt'); ?></span>
|
||||
<div class="aksrt-cart-page__coupon-row">
|
||||
<input type="text" class="aksrt-cart-page__input" data-aksrt-coupon-code placeholder="<?php esc_attr_e('输入优惠码后试算', 'aksrt'); ?>">
|
||||
<button type="button" class="btn-outline btn-sm" data-aksrt-preview-checkout><?php esc_html_e('应用并试算', 'aksrt'); ?></button>
|
||||
</div>
|
||||
</label>
|
||||
<p class="aksrt-cart-page__hint" data-aksrt-preview-message><?php esc_html_e('试算后会展示优惠抵扣、运费和最终应付金额。', 'aksrt'); ?></p>
|
||||
|
||||
<label class="aksrt-cart-page__field">
|
||||
<span><?php esc_html_e('订单备注', 'aksrt'); ?></span>
|
||||
<textarea class="aksrt-cart-page__textarea" data-aksrt-customer-note rows="4" placeholder="<?php esc_attr_e('例如发票要求、发货备注等。', 'aksrt'); ?>"></textarea>
|
||||
</label>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<aside class="aksrt-cart-page__sidebar">
|
||||
<section class="aksrt-cart-page__panel aksrt-cart-page__summary">
|
||||
<div class="aksrt-cart-page__panel-head">
|
||||
<h2><?php esc_html_e('订单摘要', 'aksrt'); ?></h2>
|
||||
</div>
|
||||
<dl class="aksrt-cart-page__summary-list">
|
||||
<div>
|
||||
<dt><?php esc_html_e('商品小计', 'aksrt'); ?></dt>
|
||||
<dd data-aksrt-summary-subtotal>¥0.00</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt><?php esc_html_e('运费', 'aksrt'); ?></dt>
|
||||
<dd data-aksrt-summary-shipping>¥0.00</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt><?php esc_html_e('优惠抵扣', 'aksrt'); ?></dt>
|
||||
<dd data-aksrt-summary-discount>-¥0.00</dd>
|
||||
</div>
|
||||
</dl>
|
||||
<div class="aksrt-cart-page__summary-total">
|
||||
<span><?php esc_html_e('应付总额', 'aksrt'); ?></span>
|
||||
<strong data-aksrt-summary-total>¥0.00</strong>
|
||||
</div>
|
||||
<button type="button" class="btn-primary btn-lg aksrt-cart-page__submit" data-aksrt-create-order disabled>
|
||||
<?php esc_html_e('创建订单', 'aksrt'); ?>
|
||||
</button>
|
||||
</section>
|
||||
</aside>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<?php get_footer(); ?>
|
||||
@@ -0,0 +1,130 @@
|
||||
<?php
|
||||
/**
|
||||
* Template Name: AKSRT - Categories
|
||||
* Template Post Type: page
|
||||
*
|
||||
* 分类汇总页面:列出全站所有分类。
|
||||
*
|
||||
* 用法:在后台新建一个 Page,标题任意(默认显示页面标题,否则用"分类目录"),
|
||||
* 模板选择 "AKSRT - Categories";或将 slug 设为 "categories" 自动匹配。
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
get_header();
|
||||
|
||||
// ─── 数据准备 ─────────────────────────────────────────────
|
||||
$all_terms = get_terms([
|
||||
'taxonomy' => 'category',
|
||||
'hide_empty' => false, // 全部展示,含 0 篇文章的分类
|
||||
'orderby' => 'menu_order name',
|
||||
'order' => 'ASC',
|
||||
]);
|
||||
if (is_wp_error($all_terms)) {
|
||||
$all_terms = [];
|
||||
}
|
||||
|
||||
$top_level = [];
|
||||
$children_by_parent = [];
|
||||
foreach ($all_terms as $term) {
|
||||
if ((int) $term->parent === 0) {
|
||||
$top_level[] = $term;
|
||||
} else {
|
||||
$children_by_parent[(int) $term->parent][] = $term;
|
||||
}
|
||||
}
|
||||
|
||||
$total_cats = count($all_terms);
|
||||
$total_counts = wp_count_posts();
|
||||
$total_posts = $total_counts && isset($total_counts->publish) ? (int) $total_counts->publish : 0;
|
||||
|
||||
$page_title = trim((string) get_the_title());
|
||||
if ($page_title === '') {
|
||||
$page_title = __('分类目录', 'aksrt');
|
||||
}
|
||||
?>
|
||||
|
||||
<main id="main-content" class="site-main content-shell" tabindex="-1">
|
||||
<?php if (function_exists('aksrt_breadcrumbs')) {
|
||||
aksrt_breadcrumbs();
|
||||
} ?>
|
||||
|
||||
<header class="page-header aksrt-cats-header">
|
||||
<h1 class="entry-title"><?php echo esc_html($page_title); ?></h1>
|
||||
<p class="aksrt-cats-header__meta">
|
||||
<?php
|
||||
printf(
|
||||
/* translators: 1: total category count, 2: total published post count */
|
||||
esc_html__('共 %1$d 个分类 · 共 %2$d 篇文章', 'aksrt'),
|
||||
$total_cats,
|
||||
$total_posts
|
||||
);
|
||||
?>
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<?php if (!empty($top_level)) : ?>
|
||||
<section class="aksrt-cats-grid" aria-label="<?php esc_attr_e('分类列表', 'aksrt'); ?>">
|
||||
<?php foreach ($top_level as $cat) :
|
||||
$cat_id = (int) $cat->term_id;
|
||||
$cat_link = get_category_link($cat_id);
|
||||
$cover_url = class_exists('AKSRT_Settings')
|
||||
? AKSRT_Settings::get_category_cover_url($cat_id)
|
||||
: (get_template_directory_uri() . '/assets/img/placeholder.svg');
|
||||
$desc = class_exists('AKSRT_Settings')
|
||||
? AKSRT_Settings::get_category_recommend_desc($cat_id)
|
||||
: (string) $cat->description;
|
||||
$children = $children_by_parent[$cat_id] ?? [];
|
||||
?>
|
||||
<article class="aksrt-cat-card">
|
||||
<a class="aksrt-cat-card__cover"
|
||||
href="<?php echo esc_url($cat_link); ?>"
|
||||
style="background-image: url('<?php echo esc_url($cover_url); ?>');"
|
||||
aria-label="<?php echo esc_attr($cat->name); ?>">
|
||||
<span class="aksrt-cat-card__count-badge">
|
||||
<?php printf(esc_html__('%d 篇', 'aksrt'), (int) $cat->count); ?>
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<div class="aksrt-cat-card__body">
|
||||
<h2 class="aksrt-cat-card__title">
|
||||
<a href="<?php echo esc_url($cat_link); ?>"><?php echo esc_html($cat->name); ?></a>
|
||||
</h2>
|
||||
|
||||
<?php if ($desc !== '') : ?>
|
||||
<p class="aksrt-cat-card__desc"><?php echo esc_html(wp_trim_words(wp_strip_all_tags($desc), 40, '…')); ?></p>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!empty($children)) : ?>
|
||||
<ul class="aksrt-cat-card__children" aria-label="<?php esc_attr_e('子分类', 'aksrt'); ?>">
|
||||
<?php foreach ($children as $child) : ?>
|
||||
<li>
|
||||
<a href="<?php echo esc_url(get_category_link((int) $child->term_id)); ?>">
|
||||
<span class="aksrt-cat-card__child-name"><?php echo esc_html($child->name); ?></span>
|
||||
<span class="aksrt-cat-card__child-count"><?php echo (int) $child->count; ?></span>
|
||||
</a>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</article>
|
||||
<?php endforeach; ?>
|
||||
</section>
|
||||
<?php else : ?>
|
||||
<div class="no-results aksrt-cats-empty">
|
||||
<p><?php esc_html_e('暂无分类。', 'aksrt'); ?></p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<p class="aksrt-cats-footer">
|
||||
<a class="btn-outline" href="<?php echo esc_url(home_url('/')); ?>">
|
||||
<?php esc_html_e('返回首页', 'aksrt'); ?>
|
||||
</a>
|
||||
</p>
|
||||
</main>
|
||||
|
||||
<?php
|
||||
get_footer();
|
||||
@@ -0,0 +1,167 @@
|
||||
<?php
|
||||
/**
|
||||
* Template Name: AKSRT - Document Navigation
|
||||
* Template Post Type: page
|
||||
*
|
||||
* 文档导航页:文档站式导航。
|
||||
* 支持侧边章节树、当前章节高亮、索引卡片、最近更新列表、基础搜索。
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
get_header();
|
||||
|
||||
// Read doc mode settings
|
||||
$doc_settings = class_exists('AKSRT_Settings') ? AKSRT_Settings::get_docs_mode_settings() : [];
|
||||
$default_order = $doc_settings['default_order'] ?? 'menu_order';
|
||||
|
||||
$presenter = class_exists('AKSRT_Docs_Presenter') ? AKSRT_Docs_Presenter::get_instance() : null;
|
||||
|
||||
// Get root-level pages
|
||||
$pages = $presenter
|
||||
? $presenter->get_root_pages($default_order)
|
||||
: get_pages([
|
||||
'sort_column' => $default_order === 'title' ? 'post_title' : ($default_order === 'date' ? 'post_date' : 'menu_order, post_title'),
|
||||
'sort_order' => 'ASC',
|
||||
'parent' => 0,
|
||||
'hierarchical' => 0,
|
||||
'post_status' => 'publish',
|
||||
]);
|
||||
|
||||
// Recent updates
|
||||
$recent_pages = $presenter
|
||||
? $presenter->get_recent_pages(8)
|
||||
: get_pages([
|
||||
'sort_column' => 'post_modified',
|
||||
'sort_order' => 'DESC',
|
||||
'number' => 8,
|
||||
'post_status' => 'publish',
|
||||
]);
|
||||
|
||||
$show_sidebar = !empty($doc_settings['toc_enabled']) || !empty($recent_pages);
|
||||
?>
|
||||
|
||||
<main id="main-content" class="container page-content-default" tabindex="-1">
|
||||
|
||||
<header class="aksrt-doc-nav-header">
|
||||
<h1 class="aksrt-doc-nav-header__title"><?php echo esc_html(get_the_title() ?: __('文档导航', 'aksrt')); ?></h1>
|
||||
<?php $desc = get_the_excerpt(); if ($desc) : ?>
|
||||
<p class="aksrt-doc-nav-header__desc"><?php echo esc_html($desc); ?></p>
|
||||
<?php endif; ?>
|
||||
</header>
|
||||
|
||||
<div class="aksrt-doc-nav container" data-aksrt-doc-page-id="<?php echo (int) get_the_ID(); ?>">
|
||||
<div class="content-wrap">
|
||||
<div class="content-layout<?php echo $show_sidebar && !empty($recent_pages) ? '' : ' content-layout--no-sidebar'; ?>">
|
||||
<div class="content-layout__primary">
|
||||
<!-- Quick search -->
|
||||
<div class="aksrt-doc-nav__search">
|
||||
<input type="text" class="aksrt-doc-nav__search-input" placeholder="<?php esc_attr_e('搜索文档...', 'aksrt'); ?>" id="aksrt-doc-search">
|
||||
<i class="fas fa-search aksrt-doc-nav__search-icon"></i>
|
||||
</div>
|
||||
<div class="aksrt-doc-search__results" data-aksrt-doc-search-results hidden></div>
|
||||
|
||||
<?php if (!empty($pages)) : ?>
|
||||
<!-- Toolbar: category chips -->
|
||||
<div class="aksrt-doc-toolbar">
|
||||
<div class="aksrt-doc-toolbar__chips">
|
||||
<button type="button" class="aksrt-doc-toolbar__chip is-active" data-cat-id="0"><?php esc_html_e('全部', 'aksrt'); ?></button>
|
||||
<?php foreach ($pages as $p) : ?>
|
||||
<button type="button" class="aksrt-doc-toolbar__chip" data-cat-id="<?php echo (int) $p->ID; ?>"><?php echo esc_html($p->post_title); ?></button>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<span class="aksrt-doc-toolbar__meta"><?php printf(esc_html__('%d 篇文档', 'aksrt'), count($pages)); ?></span>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="aksrt-doc-nav__layout">
|
||||
<!-- Document index cards -->
|
||||
<div class="aksrt-doc-nav__main">
|
||||
<?php if (!empty($pages)) : ?>
|
||||
<div class="aksrt-doc-nav__grid">
|
||||
<?php foreach ($pages as $p) :
|
||||
$children = $presenter
|
||||
? $presenter->get_flat_tree($p->ID, 1)
|
||||
: get_pages([
|
||||
'child_of' => $p->ID,
|
||||
'sort_column' => 'menu_order',
|
||||
'sort_order' => 'ASC',
|
||||
'parent' => $p->ID,
|
||||
'post_status' => 'publish',
|
||||
]);
|
||||
$child_count = count($children);
|
||||
$thumb = get_the_post_thumbnail_url($p->ID, 'medium');
|
||||
$excerpt = wp_trim_words($p->post_excerpt, 30, '...');
|
||||
?>
|
||||
<a href="<?php echo esc_url(get_permalink($p->ID)); ?>" class="aksrt-doc-index-card" data-cat-id="<?php echo (int) $p->ID; ?>">
|
||||
<?php if ($thumb) : ?>
|
||||
<div class="aksrt-doc-index-card__thumb">
|
||||
<img src="<?php echo esc_url($thumb); ?>" alt=""<?php echo function_exists('aksrt_lazy_loading') ? aksrt_lazy_loading('other') : ' loading="lazy"'; ?>>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<div class="aksrt-doc-index-card__icon">
|
||||
<i class="fas fa-book-open"></i>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="aksrt-doc-index-card__body">
|
||||
<h3 class="aksrt-doc-index-card__title"><?php echo esc_html($p->post_title); ?></h3>
|
||||
<?php if ($excerpt) : ?>
|
||||
<p class="aksrt-doc-index-card__desc"><?php echo esc_html($excerpt); ?></p>
|
||||
<?php endif; ?>
|
||||
<div class="aksrt-doc-index-card__meta">
|
||||
<?php if ($child_count > 0) : ?>
|
||||
<span class="aksrt-doc-index-card__count">
|
||||
<i class="fas fa-file-alt"></i>
|
||||
<?php printf(esc_html__('%d 篇文章', 'aksrt'), $child_count); ?>
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
<span class="aksrt-doc-index-card__date">
|
||||
<i class="fas fa-clock"></i>
|
||||
<?php echo esc_html(get_the_date('', $p->ID)); ?>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<i class="fas fa-chevron-right aksrt-doc-index-card__arrow"></i>
|
||||
</a>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<div class="aksrt-doc-nav__empty">
|
||||
<i class="fas fa-book-open"></i>
|
||||
<p><?php esc_html_e('暂无文档页面。', 'aksrt'); ?></p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<!-- Sidebar: Recent updates -->
|
||||
<?php if ($show_sidebar && !empty($recent_pages)) : ?>
|
||||
<aside class="aksrt-doc-nav__sidebar sidebar">
|
||||
<div class="aksrt-doc-nav__recent">
|
||||
<h3 class="aksrt-doc-nav__recent-title">
|
||||
<i class="fas fa-clock"></i>
|
||||
<?php esc_html_e('最近更新', 'aksrt'); ?>
|
||||
</h3>
|
||||
<ul class="aksrt-doc-nav__recent-list">
|
||||
<?php foreach ($recent_pages as $rp) : ?>
|
||||
<li class="aksrt-doc-nav__recent-item">
|
||||
<a href="<?php echo esc_url(get_permalink($rp->ID)); ?>">
|
||||
<span class="aksrt-doc-nav__recent-name"><?php echo esc_html($rp->post_title); ?></span>
|
||||
<time class="aksrt-doc-nav__recent-date"><?php echo esc_html(get_the_date('', $rp->ID)); ?></time>
|
||||
</a>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</div>
|
||||
</aside>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<?php
|
||||
get_footer();
|
||||
@@ -0,0 +1,220 @@
|
||||
<?php
|
||||
/**
|
||||
* Template Name: AKSRT - Download Center
|
||||
* Template Post Type: page
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
get_header();
|
||||
|
||||
$paged = max(1, (int) get_query_var('paged'));
|
||||
$per_page = 12;
|
||||
|
||||
$type_filter = isset($_GET['resource_type']) ? sanitize_key((string) $_GET['resource_type']) : '';
|
||||
$resource_type_labels = function_exists('aksrt_get_pay_types') ? aksrt_get_pay_types() : [];
|
||||
unset($resource_type_labels[AKSRT_Domain_Model::PAY_TYPE_READING]);
|
||||
|
||||
if ($type_filter !== '' && !isset($resource_type_labels[$type_filter])) {
|
||||
$type_filter = '';
|
||||
}
|
||||
|
||||
$query_args = [
|
||||
'post_type' => 'post',
|
||||
'post_status' => 'publish',
|
||||
'posts_per_page' => $per_page,
|
||||
'paged' => $paged,
|
||||
'orderby' => 'date',
|
||||
'order' => 'DESC',
|
||||
'ignore_sticky_posts' => true,
|
||||
'meta_query' => [
|
||||
[
|
||||
'key' => AKSRT_Domain_Model::RESOURCE_MARKER_KEY,
|
||||
'value' => '1',
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
if ($type_filter !== '') {
|
||||
$query_args['meta_query'][] = [
|
||||
'key' => AKSRT_Domain_Model::PAY_TYPE_KEY,
|
||||
'value' => $type_filter,
|
||||
];
|
||||
}
|
||||
|
||||
$resource_query = new WP_Query($query_args);
|
||||
|
||||
$is_logged_in = is_user_logged_in();
|
||||
$user_credits = 0;
|
||||
$user_download_count = 0;
|
||||
if ($is_logged_in) {
|
||||
$uid = get_current_user_id();
|
||||
if (class_exists('AKSRT_Credits')) {
|
||||
$user_credits = AKSRT_Credits::balance($uid);
|
||||
}
|
||||
$dl_meta = get_user_meta($uid, '_aksrt_downloaded_resources', true);
|
||||
$user_download_count = is_array($dl_meta) ? count($dl_meta) : 0;
|
||||
}
|
||||
|
||||
$currency_name = class_exists('AKSRT_Settings') ? AKSRT_Settings::get_currency_name() : __('积分', 'aksrt');
|
||||
$dl_settings = class_exists('AKSRT_Settings') ? AKSRT_Settings::get_cms_features() : [];
|
||||
$dl_requires_login = !empty($dl_settings['download_requires_login']);
|
||||
?>
|
||||
|
||||
<main id="main-content" class="site-main container" tabindex="-1">
|
||||
|
||||
<?php get_template_part('templates/parts/download/download-hero'); ?>
|
||||
|
||||
<div class="aksrt-download-center container">
|
||||
<div class="content-wrap">
|
||||
<div class="content-layout">
|
||||
<div class="content-layout__primary">
|
||||
<div class="aksrt-dl-status-bar">
|
||||
<?php if ($is_logged_in) : ?>
|
||||
<div class="aksrt-dl-status-bar__item">
|
||||
<i class="fas fa-coins" aria-hidden="true"></i>
|
||||
<span class="aksrt-dl-status-bar__label"><?php echo esc_html($currency_name); ?></span>
|
||||
<span class="aksrt-dl-status-bar__value"><?php echo esc_html(number_format_i18n($user_credits)); ?></span>
|
||||
</div>
|
||||
<div class="aksrt-dl-status-bar__item">
|
||||
<i class="fas fa-download" aria-hidden="true"></i>
|
||||
<span class="aksrt-dl-status-bar__label"><?php esc_html_e('已下载', 'aksrt'); ?></span>
|
||||
<span class="aksrt-dl-status-bar__value"><?php echo esc_html(number_format_i18n($user_download_count)); ?></span>
|
||||
</div>
|
||||
<div class="aksrt-dl-status-bar__item aksrt-dl-status-bar__item--hint">
|
||||
<i class="fas fa-info-circle" aria-hidden="true"></i>
|
||||
<span><?php esc_html_e('点击资源卡片查看详情和下载状态', 'aksrt'); ?></span>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<div class="aksrt-dl-status-bar__item aksrt-dl-status-bar__item--hint">
|
||||
<i class="fas fa-lock" aria-hidden="true"></i>
|
||||
<span>
|
||||
<?php if ($dl_requires_login) : ?>
|
||||
<?php esc_html_e('登录后可查看下载状态和积分余额', 'aksrt'); ?>
|
||||
<?php else : ?>
|
||||
<?php esc_html_e('登录后可管理下载记录和积分余额', 'aksrt'); ?>
|
||||
<?php endif; ?>
|
||||
</span>
|
||||
</div>
|
||||
<div class="aksrt-dl-status-bar__actions">
|
||||
<a href="<?php echo esc_url(aksrt_get_login_url()); ?>" class="btn-outline btn-sm"><?php esc_html_e('登录', 'aksrt'); ?></a>
|
||||
<?php if (get_option('users_can_register')) : ?>
|
||||
<a href="<?php echo esc_url(aksrt_get_register_url()); ?>" class="btn-primary btn-sm"><?php esc_html_e('注册', 'aksrt'); ?></a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<div class="aksrt-download-center__layout">
|
||||
<div class="aksrt-download-center__main">
|
||||
<?php if ($resource_query->have_posts()) : ?>
|
||||
<div class="aksrt-download-center__grid">
|
||||
<?php while ($resource_query->have_posts()) : $resource_query->the_post(); ?>
|
||||
<article class="aksrt-download-card">
|
||||
<?php if (has_post_thumbnail()) : ?>
|
||||
<div class="aksrt-download-card__thumb">
|
||||
<a href="<?php the_permalink(); ?>">
|
||||
<?php the_post_thumbnail('medium'); ?>
|
||||
</a>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<div class="aksrt-download-card__body">
|
||||
<h3 class="aksrt-download-card__title">
|
||||
<a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
|
||||
</h3>
|
||||
<p class="aksrt-download-card__excerpt"><?php echo esc_html(wp_trim_words(get_the_excerpt(), 20)); ?></p>
|
||||
<div class="aksrt-download-card__meta">
|
||||
<span class="aksrt-download-card__date">
|
||||
<i class="fas fa-clock"></i>
|
||||
<?php echo esc_html(get_the_date()); ?>
|
||||
</span>
|
||||
<?php
|
||||
$dl_count = (int) get_post_meta(get_the_ID(), AKSRT_Domain_Model::RESOURCE_DOWNLOAD_COUNT_KEY, true);
|
||||
if ($dl_count > 0) :
|
||||
?>
|
||||
<span class="aksrt-download-card__downloads">
|
||||
<i class="fas fa-download"></i>
|
||||
<?php echo esc_html(number_format_i18n($dl_count)); ?>
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php
|
||||
$card_meta = function_exists('aksrt_get_resource_meta') ? aksrt_get_resource_meta(get_the_ID()) : [];
|
||||
$card_price = (float) ($card_meta['price'] ?? 0);
|
||||
$price_label = function_exists('aksrt_resource_price_label')
|
||||
? aksrt_resource_price_label($card_price)
|
||||
: ['text' => __('免费', 'aksrt'), 'free' => true];
|
||||
?>
|
||||
<div class="aksrt-download-card__footer">
|
||||
<span class="aksrt-download-card__price<?php echo $price_label['free'] ? ' is-free' : ' is-paid'; ?>">
|
||||
<?php echo esc_html($price_label['text']); ?>
|
||||
</span>
|
||||
<a href="<?php the_permalink(); ?>" class="aksrt-download-card__action">
|
||||
<?php esc_html_e('查看详情', 'aksrt'); ?>
|
||||
<i class="fas fa-arrow-right" aria-hidden="true"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
<?php endwhile; ?>
|
||||
</div>
|
||||
<?php
|
||||
if (function_exists('aksrt_render_pagination')) {
|
||||
aksrt_render_pagination($resource_query);
|
||||
}
|
||||
wp_reset_postdata();
|
||||
?>
|
||||
<?php else : ?>
|
||||
<div class="aksrt-download-center__empty">
|
||||
<i class="fas fa-folder-open"></i>
|
||||
<p><?php esc_html_e('暂无可下载资源。', 'aksrt'); ?></p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<aside class="aksrt-download-center__sidebar sidebar">
|
||||
<?php get_template_part('templates/parts/download/download-permission-card'); ?>
|
||||
|
||||
<div class="aksrt-dl-sidebar-card">
|
||||
<h3 class="aksrt-dl-sidebar-card__title">
|
||||
<i class="fas fa-folder"></i>
|
||||
<?php esc_html_e('资源类型', 'aksrt'); ?>
|
||||
</h3>
|
||||
<?php if (!empty($resource_type_labels)) : ?>
|
||||
<ul class="aksrt-dl-sidebar-card__list">
|
||||
<li class="<?php echo $type_filter === '' ? 'is-active' : ''; ?>">
|
||||
<a href="<?php echo esc_url(get_permalink()); ?>">
|
||||
<?php esc_html_e('全部资源', 'aksrt'); ?>
|
||||
</a>
|
||||
</li>
|
||||
<?php foreach ($resource_type_labels as $type_key => $type_label) : ?>
|
||||
<li class="<?php echo $type_filter === $type_key ? 'is-active' : ''; ?>">
|
||||
<a href="<?php echo esc_url(add_query_arg('resource_type', $type_key, get_permalink())); ?>">
|
||||
<?php echo esc_html($type_label); ?>
|
||||
</a>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<div class="aksrt-dl-sidebar-card">
|
||||
<h3 class="aksrt-dl-sidebar-card__title">
|
||||
<i class="fas fa-lightbulb"></i>
|
||||
<?php esc_html_e('下载须知', 'aksrt'); ?>
|
||||
</h3>
|
||||
<div class="aksrt-dl-sidebar-card__tips">
|
||||
<p><i class="fas fa-shield-alt" aria-hidden="true"></i> <?php esc_html_e('所有资源均经过安全检测', 'aksrt'); ?></p>
|
||||
<p><i class="fas fa-clock" aria-hidden="true"></i> <?php esc_html_e('下载链接 10 分钟内有效', 'aksrt'); ?></p>
|
||||
<p><i class="fas fa-sync-alt" aria-hidden="true"></i> <?php esc_html_e('已下载资源可再次下载', 'aksrt'); ?></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<?php
|
||||
get_footer();
|
||||
@@ -0,0 +1,331 @@
|
||||
<?php
|
||||
/**
|
||||
* Template Name: AKSRT - Forums
|
||||
* Template Post Type: page
|
||||
*
|
||||
* §7.10 — Tab engine + quick post + plate grid + follow/synthesis/pending streams.
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
get_header();
|
||||
|
||||
$forum = class_exists('AKSRT_Forum') ? AKSRT_Forum::get_instance() : null;
|
||||
$current_user_id = get_current_user_id();
|
||||
$view = $forum ? $forum->get_home_view($current_user_id) : [
|
||||
'boards' => [],
|
||||
'recent_topics' => [],
|
||||
'hot_topics' => [],
|
||||
'stats' => [],
|
||||
'permissions' => ['can_compose' => false, 'can_manage' => false],
|
||||
'applications' => [],
|
||||
'home_tabs' => [],
|
||||
'active_index' => 1,
|
||||
'quick_posts' => true,
|
||||
];
|
||||
|
||||
$boards = $view['boards'] ?? [];
|
||||
$recent_topics = $view['recent_topics'] ?? [];
|
||||
$hot_topics = $view['hot_topics'] ?? [];
|
||||
$stats = $view['stats'] ?? [];
|
||||
$permissions = $view['permissions'] ?? [];
|
||||
$applications = $view['applications'] ?? [];
|
||||
$compose_url = home_url('/compose/');
|
||||
|
||||
$forum_settings = class_exists('AKSRT_Settings') ? AKSRT_Settings::get_forum_settings() : [];
|
||||
$forum_names = $forum_settings['names'] ?? [];
|
||||
$name_forum = $forum_names['forum'] ?? __('论坛', 'aksrt');
|
||||
$name_plate = $forum_names['plate'] ?? __('版块', 'aksrt');
|
||||
$name_topic = $forum_names['posts'] ?? __('主题', 'aksrt');
|
||||
$name_reply = $forum_names['comment'] ?? __('回复', 'aksrt');
|
||||
$admin_forum_url = admin_url('admin.php?page=aksrt-theme-admin#/forum');
|
||||
|
||||
$home_tabs = $view['home_tabs'] ?? [];
|
||||
$active_index = max(0, min(count($home_tabs) - 1, (int) ($view['active_index'] ?? 1)));
|
||||
$quick_posts = !empty($view['quick_posts']);
|
||||
$nonce = wp_create_nonce('aksrt_public_nonce');
|
||||
|
||||
// Resolve active tab from query param or default
|
||||
$active_tab_type = isset($_GET['forum_tab']) ? sanitize_key(wp_unslash($_GET['forum_tab'])) : '';
|
||||
if ($active_tab_type === '' && isset($home_tabs[$active_index])) {
|
||||
$active_tab_type = $home_tabs[$active_index]['type'] ?? 'synthesis';
|
||||
}
|
||||
if ($active_tab_type === '') {
|
||||
$active_tab_type = 'synthesis';
|
||||
}
|
||||
?>
|
||||
|
||||
<main id="main-content" class="site-main container" tabindex="-1">
|
||||
|
||||
<header class="aksrt-forum-header">
|
||||
<div class="aksrt-forum-header__content">
|
||||
<h1 class="aksrt-forum-header__title"><?php echo esc_html(get_the_title() ?: __('社区论坛', 'aksrt')); ?></h1>
|
||||
<?php if (get_the_excerpt()) : ?>
|
||||
<p class="aksrt-forum-header__desc"><?php echo esc_html(get_the_excerpt()); ?></p>
|
||||
<?php endif; ?>
|
||||
<div class="aksrt-forum-header__actions">
|
||||
<?php if (!empty($permissions['can_compose'])) : ?>
|
||||
<a class="aksrt-forum-header__action aksrt-forum-header__action--primary" href="<?php echo esc_url($compose_url); ?>">
|
||||
<i class="fas fa-pen"></i> <?php esc_html_e('发布主题', 'aksrt'); ?>
|
||||
</a>
|
||||
<?php else : ?>
|
||||
<a class="aksrt-forum-header__action aksrt-forum-header__action--primary" href="<?php echo esc_url(wp_login_url(get_permalink())); ?>">
|
||||
<i class="fas fa-sign-in-alt"></i> <?php esc_html_e('登录后发帖', 'aksrt'); ?>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
<?php if (!empty($permissions['can_manage'])) : ?>
|
||||
<a class="aksrt-forum-header__action" href="<?php echo esc_url($admin_forum_url); ?>">
|
||||
<i class="fas fa-tools"></i> <?php esc_html_e('进入治理后台', 'aksrt'); ?>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="aksrt-forum-header__stats">
|
||||
<div class="aksrt-forum-header__stat">
|
||||
<span class="aksrt-forum-header__stat-num"><?php echo esc_html(number_format_i18n((int) ($stats['board_count'] ?? 0))); ?></span>
|
||||
<span class="aksrt-forum-header__stat-label"><?php echo esc_html($name_plate); ?></span>
|
||||
</div>
|
||||
<div class="aksrt-forum-header__stat">
|
||||
<span class="aksrt-forum-header__stat-num"><?php echo esc_html(number_format_i18n((int) ($stats['topic_count'] ?? 0))); ?></span>
|
||||
<span class="aksrt-forum-header__stat-label"><?php echo esc_html($name_topic); ?></span>
|
||||
</div>
|
||||
<div class="aksrt-forum-header__stat">
|
||||
<span class="aksrt-forum-header__stat-num"><?php echo esc_html(number_format_i18n((int) ($stats['post_count'] ?? 0))); ?></span>
|
||||
<span class="aksrt-forum-header__stat-label"><?php echo esc_html($name_reply); ?></span>
|
||||
</div>
|
||||
<div class="aksrt-forum-header__stat">
|
||||
<span class="aksrt-forum-header__stat-num"><?php echo esc_html(number_format_i18n((int) ($stats['moderator_count'] ?? 0))); ?></span>
|
||||
<span class="aksrt-forum-header__stat-label"><?php esc_html_e('版主', 'aksrt'); ?></span>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<?php if (isset($_GET['compose_status']) && $_GET['compose_status'] === 'pending') : ?>
|
||||
<div class="aksrt-alert aksrt-alert--info" data-aksrt-flash-query="compose_status">
|
||||
<?php esc_html_e('你的主题已提交审核,审核通过后会在版块中展示。', 'aksrt'); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="aksrt-forum container">
|
||||
<div class="content-wrap">
|
||||
<div class="content-layout content-layout--no-sidebar">
|
||||
<div class="content-layout__primary">
|
||||
<div class="aksrt-forum__layout">
|
||||
<div class="aksrt-forum__main">
|
||||
|
||||
<?php if ($quick_posts && !empty($permissions['can_compose'])) : ?>
|
||||
<div class="aksrt-forum-quick-post">
|
||||
<a class="aksrt-forum-quick-post__input" href="<?php echo esc_url($compose_url); ?>">
|
||||
<?php echo get_avatar($current_user_id, 32); ?>
|
||||
<span><?php esc_html_e('分享你的想法…', 'aksrt'); ?></span>
|
||||
</a>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!empty($home_tabs)) : ?>
|
||||
<nav class="aksrt-forum-home-tabs" id="aksrt-forum-home-tabs"
|
||||
data-nonce="<?php echo esc_attr($nonce); ?>"
|
||||
data-ajax-url="<?php echo esc_attr(admin_url('admin-ajax.php')); ?>">
|
||||
<?php foreach ($home_tabs as $i => $tab) :
|
||||
$tab_type = sanitize_key($tab['type'] ?? 'synthesis');
|
||||
$tab_label = esc_html($tab['label'] ?? $tab_type);
|
||||
$is_active = $tab_type === $active_tab_type;
|
||||
if ($tab_type === 'pending' && empty($permissions['can_manage'])) continue;
|
||||
?>
|
||||
<button type="button"
|
||||
class="aksrt-forum-home-tabs__btn<?php echo $is_active ? ' is-active' : ''; ?>"
|
||||
data-tab-type="<?php echo esc_attr($tab_type); ?>">
|
||||
<?php echo $tab_label; ?>
|
||||
</button>
|
||||
<?php endforeach; ?>
|
||||
<?php if (!empty($permissions['can_manage'])) : ?>
|
||||
<button type="button"
|
||||
class="aksrt-forum-home-tabs__btn<?php echo $active_tab_type === 'pending' ? ' is-active' : ''; ?>"
|
||||
data-tab-type="pending">
|
||||
<?php esc_html_e('待审核', 'aksrt'); ?>
|
||||
<?php if ((int) ($stats['pending_topic_count'] ?? 0) > 0) : ?>
|
||||
<span class="aksrt-forum-home-tabs__badge"><?php echo esc_html((string) ($stats['pending_topic_count'] ?? 0)); ?></span>
|
||||
<?php endif; ?>
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
</nav>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="aksrt-forum-home-content" id="aksrt-forum-home-content">
|
||||
<?php if ($active_tab_type === 'plate') : ?>
|
||||
<?php if (!empty($boards)) : ?>
|
||||
<div class="aksrt-forum-boards__grid">
|
||||
<?php foreach ($boards as $board) :
|
||||
$board_id = (int) ($board['id'] ?? 0);
|
||||
?>
|
||||
<article class="aksrt-forum-board-card">
|
||||
<a class="aksrt-forum-board-card__link" href="<?php echo esc_url((string) ($board['url'] ?? '#')); ?>">
|
||||
<div class="aksrt-forum-board-card__icon">
|
||||
<?php if (!empty($board['thumbnail_url'])) : ?>
|
||||
<img src="<?php echo esc_url((string) $board['thumbnail_url']); ?>" alt="" width="48" height="48">
|
||||
<?php else : ?>
|
||||
<i class="<?php echo esc_attr((string) ($board['icon'] ?: 'fas fa-comments')); ?>"></i>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="aksrt-forum-board-card__body">
|
||||
<div class="aksrt-forum-board-card__head">
|
||||
<h3 class="aksrt-forum-board-card__title"><?php echo esc_html((string) ($board['name'] ?? '')); ?></h3>
|
||||
</div>
|
||||
<?php if (!empty($board['description'])) : ?>
|
||||
<p class="aksrt-forum-board-card__desc"><?php echo esc_html((string) $board['description']); ?></p>
|
||||
<?php endif; ?>
|
||||
<div class="aksrt-forum-board-card__meta">
|
||||
<span><i class="fas fa-file-alt"></i> <?php echo esc_html(number_format_i18n((int) ($board['topic_count'] ?? $board['post_count'] ?? 0))); ?></span>
|
||||
<span><i class="fas fa-comment"></i> <?php echo esc_html(number_format_i18n((int) ($board['reply_count'] ?? 0))); ?></span>
|
||||
<span><i class="fas fa-heart"></i> <?php echo esc_html(number_format_i18n((int) ($board['follow_count'] ?? 0))); ?></span>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</article>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<div class="aksrt-forum__empty">
|
||||
<i class="fas fa-comments"></i>
|
||||
<p><?php esc_html_e('当前还没有论坛版块。', 'aksrt'); ?></p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php elseif ($active_tab_type === 'follow') : ?>
|
||||
<?php
|
||||
$follow_data = $forum ? $forum->get_follow_stream($current_user_id) : ['items' => []];
|
||||
if (!empty($follow_data['items'])) : ?>
|
||||
<div class="aksrt-forum-topics__list js-aksrt-home-topic-list">
|
||||
<?php foreach ($follow_data['items'] as $topic) { $forum->render_topic_row($topic); } ?>
|
||||
</div>
|
||||
<?php if ($follow_data['max_pages'] > 1) : ?>
|
||||
<div class="aksrt-forum-home__load-more">
|
||||
<button type="button" class="aksrt-forum-replies__more-btn js-aksrt-home-load-more"
|
||||
data-page="1" data-max="<?php echo esc_attr((string) $follow_data['max_pages']); ?>"
|
||||
data-tab="follow">
|
||||
<i class="fas fa-chevron-down"></i> <?php esc_html_e('加载更多', 'aksrt'); ?>
|
||||
</button>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php elseif ($current_user_id > 0) : ?>
|
||||
<div class="aksrt-forum__empty">
|
||||
<i class="far fa-heart"></i>
|
||||
<p><?php esc_html_e('你还没有关注任何版块,去看看有哪些版块吧!', 'aksrt'); ?></p>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<div class="aksrt-forum__empty">
|
||||
<i class="fas fa-sign-in-alt"></i>
|
||||
<p><?php esc_html_e('登录后即可看到你关注的版块内容。', 'aksrt'); ?></p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php elseif ($active_tab_type === 'pending') : ?>
|
||||
<?php
|
||||
$pending_data = $forum ? $forum->get_pending_stream($current_user_id) : ['items' => []];
|
||||
if (!empty($pending_data['items'])) : ?>
|
||||
<div class="aksrt-forum-topics__list js-aksrt-home-topic-list">
|
||||
<?php foreach ($pending_data['items'] as $topic) { $forum->render_topic_row($topic); } ?>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<div class="aksrt-forum__empty">
|
||||
<i class="fas fa-check-circle"></i>
|
||||
<p><?php esc_html_e('没有待审核的主题。', 'aksrt'); ?></p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php else : /* synthesis (default) */ ?>
|
||||
<?php if (!empty($recent_topics)) : ?>
|
||||
<div class="aksrt-forum-topics__list js-aksrt-home-topic-list">
|
||||
<?php foreach ($recent_topics as $topic) {
|
||||
if ($forum) { $forum->render_topic_row($topic); }
|
||||
} ?>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<div class="aksrt-forum__empty">
|
||||
<i class="fas fa-feather-alt"></i>
|
||||
<p><?php esc_html_e('还没有公开主题,欢迎创建第一个讨论。', 'aksrt'); ?></p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<aside class="aksrt-forum__sidebar">
|
||||
<div class="aksrt-forum-sidebar-card">
|
||||
<h3 class="aksrt-forum-sidebar-card__title">
|
||||
<i class="fas fa-fire"></i>
|
||||
<?php printf(esc_html__('热门%s', 'aksrt'), esc_html($name_topic)); ?>
|
||||
</h3>
|
||||
<?php if (!empty($hot_topics)) : ?>
|
||||
<ul class="aksrt-forum-sidebar-card__list">
|
||||
<?php foreach ($hot_topics as $index => $topic) : ?>
|
||||
<li class="aksrt-forum-sidebar-card__item">
|
||||
<span class="aksrt-forum-sidebar-card__rank"><?php echo esc_html((string) ($index + 1)); ?></span>
|
||||
<a href="<?php echo esc_url((string) ($topic['permalink'] ?? '#')); ?>" class="aksrt-forum-sidebar-card__link">
|
||||
<?php echo esc_html((string) ($topic['title'] ?? '')); ?>
|
||||
</a>
|
||||
<span class="aksrt-forum-sidebar-card__views"><?php echo esc_html(number_format_i18n((int) ($topic['views'] ?? 0))); ?></span>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
<?php else : ?>
|
||||
<p class="aksrt-forum-sidebar-card__empty"><?php esc_html_e('暂无热门主题', 'aksrt'); ?></p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<?php if (!empty($boards)) : ?>
|
||||
<div class="aksrt-forum-sidebar-card">
|
||||
<h3 class="aksrt-forum-sidebar-card__title">
|
||||
<i class="fas fa-th-list"></i>
|
||||
<?php echo esc_html($name_plate); ?>
|
||||
</h3>
|
||||
<ul class="aksrt-forum-sidebar-card__list">
|
||||
<?php foreach (array_slice($boards, 0, 8) as $board) : ?>
|
||||
<li class="aksrt-forum-sidebar-card__item">
|
||||
<a href="<?php echo esc_url((string) ($board['url'] ?? '#')); ?>" class="aksrt-forum-sidebar-card__link">
|
||||
<?php echo esc_html((string) ($board['name'] ?? '')); ?>
|
||||
</a>
|
||||
<span class="aksrt-forum-sidebar-card__views"><?php echo esc_html(number_format_i18n((int) ($board['topic_count'] ?? $board['post_count'] ?? 0))); ?></span>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!empty($applications)) : ?>
|
||||
<div class="aksrt-forum-sidebar-card">
|
||||
<h3 class="aksrt-forum-sidebar-card__title">
|
||||
<i class="fas fa-shield-alt"></i>
|
||||
<?php esc_html_e('版主申请状态', 'aksrt'); ?>
|
||||
</h3>
|
||||
<ul class="aksrt-forum-sidebar-card__list aksrt-forum-sidebar-card__list--applications">
|
||||
<?php foreach ($applications as $board_id => $application) :
|
||||
if (!$application) continue;
|
||||
$board_name = '';
|
||||
foreach ($boards as $board) {
|
||||
if ((int) ($board['id'] ?? 0) === (int) $board_id) {
|
||||
$board_name = (string) ($board['name'] ?? '');
|
||||
break;
|
||||
}
|
||||
}
|
||||
?>
|
||||
<li class="aksrt-forum-sidebar-card__item aksrt-forum-sidebar-card__item--stack">
|
||||
<strong><?php echo esc_html($board_name); ?></strong>
|
||||
<span><?php echo esc_html((string) ($application['status_label'] ?? '')); ?></span>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</aside>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<?php get_footer(); ?>
|
||||
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
/**
|
||||
* Template Name: 友情链接
|
||||
* Template Post Type: page
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
get_header();
|
||||
|
||||
$links = function_exists('aksrt_get_friend_links') ? aksrt_get_friend_links() : [];
|
||||
?>
|
||||
|
||||
<main id="main-content" class="container page-content-default" tabindex="-1">
|
||||
<header class="page-header">
|
||||
<h1 class="entry-title"><?php esc_html_e('友情链接', 'aksrt'); ?></h1>
|
||||
<p><?php esc_html_e('与这些优秀的站点交换友链', 'aksrt'); ?></p>
|
||||
</header>
|
||||
|
||||
<div class="content-wrap">
|
||||
<div class="content-layout content-layout--no-sidebar">
|
||||
<div class="content-layout__primary">
|
||||
|
||||
<?php if (! empty($links)) : ?>
|
||||
<div class="friends-grid">
|
||||
<?php foreach ($links as $link) : ?>
|
||||
<a class="friend-card" href="<?php echo esc_url($link['url'] ?? '#'); ?>" target="_blank" rel="noopener noreferrer">
|
||||
<?php
|
||||
$logo = $link['logo'] ?? '';
|
||||
if ($logo) {
|
||||
echo '<img class="friend-card__avatar" src="' . esc_url($logo) . '" alt="">';
|
||||
} else {
|
||||
$initial = function_exists('mb_substr') ? mb_substr((string) ($link['name'] ?? 'A'), 0, 1, 'UTF-8') : substr((string) ($link['name'] ?? 'A'), 0, 1);
|
||||
echo '<div class="friend-card__avatar" style="display:flex;align-items:center;justify-content:center;font-weight:800;color:var(--color-primary);font-family:var(--font-heading);">' . esc_html($initial) . '</div>';
|
||||
}
|
||||
?>
|
||||
<div class="friend-card__info">
|
||||
<h3 class="friend-card__name"><?php echo esc_html($link['name'] ?? ''); ?></h3>
|
||||
<p class="friend-card__desc"><?php echo esc_html($link['description'] ?? ''); ?></p>
|
||||
</div>
|
||||
</a>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<div class="no-results">
|
||||
<p><?php esc_html_e('暂无友链,请在主题后台添加。', 'aksrt'); ?></p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<p style="text-align:center;margin-top:32px;">
|
||||
<a class="btn-outline" href="<?php echo esc_url(home_url('/')); ?>"><?php esc_html_e('返回首页', 'aksrt'); ?></a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<?php
|
||||
get_footer();
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
/**
|
||||
* Template Name: AKSRT - Login
|
||||
* Template Post Type: page
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
require AKSRT_DIR . '/templates/pages/page-sign.php';
|
||||
@@ -0,0 +1,236 @@
|
||||
<?php
|
||||
/**
|
||||
* Template Name: 消息中心
|
||||
* Template Post Type: page
|
||||
*
|
||||
* 独立消息中心页面 — 两栏布局(左侧导航 + 右侧消息列表)
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
get_header();
|
||||
|
||||
if ( ! is_user_logged_in() ) {
|
||||
$login_url = function_exists( 'aksrt_get_login_url' ) ? aksrt_get_login_url() : wp_login_url( get_permalink() );
|
||||
wp_safe_redirect( $login_url );
|
||||
exit;
|
||||
}
|
||||
|
||||
$user_id = get_current_user_id();
|
||||
|
||||
// 获取所有通知(持久化 + 即时状态)
|
||||
$all_notifications = function_exists( 'aksrt_get_user_all_notifications' )
|
||||
? aksrt_get_user_all_notifications( $user_id )
|
||||
: [];
|
||||
|
||||
// 筛选类型
|
||||
$current_type = isset( $_GET['msg_type'] ) ? sanitize_key( $_GET['msg_type'] ) : 'all';
|
||||
|
||||
// 按类型过滤
|
||||
$filtered = $all_notifications;
|
||||
if ( $current_type === 'unread' ) {
|
||||
$filtered = array_filter( $filtered, static fn( $n ) => empty( $n['read'] ) );
|
||||
} elseif ( $current_type !== 'all' ) {
|
||||
$filtered = array_filter( $filtered, static fn( $n ) => ( $n['type'] ?? '' ) === $current_type );
|
||||
}
|
||||
$filtered = array_values( $filtered );
|
||||
|
||||
// 分页
|
||||
$per_page = 20;
|
||||
$current_page = max( 1, (int) ( $_GET['msg_page'] ?? 1 ) );
|
||||
$total = count( $filtered );
|
||||
$total_pages = max( 1, (int) ceil( $total / $per_page ) );
|
||||
$offset = ( $current_page - 1 ) * $per_page;
|
||||
$paged_items = array_slice( $filtered, $offset, $per_page );
|
||||
|
||||
// 统计各类型数量
|
||||
$type_counts = [ 'all' => count( $all_notifications ), 'unread' => 0 ];
|
||||
foreach ( $all_notifications as $n ) {
|
||||
$t = $n['type'] ?? 'notice';
|
||||
$type_counts[ $t ] = ( $type_counts[ $t ] ?? 0 ) + 1;
|
||||
if ( empty( $n['read'] ) ) {
|
||||
$type_counts['unread']++;
|
||||
}
|
||||
}
|
||||
|
||||
// 导航定义
|
||||
$nav_items = [
|
||||
'all' => __( '全部消息', 'aksrt' ),
|
||||
'unread' => __( '未读', 'aksrt' ),
|
||||
'conversation' => __( '私信', 'aksrt' ),
|
||||
'comment_reply' => __( '评论回复', 'aksrt' ),
|
||||
'comment_approved' => __( '评论审核', 'aksrt' ),
|
||||
'credits_added' => __( '积分增加', 'aksrt' ),
|
||||
'credits_deducted' => __( '积分扣减', 'aksrt' ),
|
||||
'download_ready' => __( '下载就绪', 'aksrt' ),
|
||||
'upload_moderation'=> __( '图片审核', 'aksrt' ),
|
||||
'notice' => __( '系统通知', 'aksrt' ),
|
||||
];
|
||||
|
||||
// 图标映射
|
||||
$icon_map = [
|
||||
'comment_reply' => 'fas fa-comment-dots',
|
||||
'comment_approved' => 'fas fa-check-circle',
|
||||
'credits_added' => 'fas fa-coins',
|
||||
'credits_deducted' => 'fas fa-coins',
|
||||
'download_ready' => 'fas fa-download',
|
||||
'upload_moderation'=> 'fas fa-image',
|
||||
'verify_email' => 'fas fa-envelope-open-text',
|
||||
'pending_comments' => 'fas fa-clock',
|
||||
'conversation' => 'fas fa-envelope',
|
||||
'notice' => 'fas fa-bell',
|
||||
];
|
||||
?>
|
||||
|
||||
<div class="messages-center container">
|
||||
<aside class="messages-center__nav">
|
||||
<ul class="messages-nav__list">
|
||||
<?php foreach ( $nav_items as $key => $label ) :
|
||||
$count = (int) ( $type_counts[ $key ] ?? 0 );
|
||||
if ( $key !== 'all' && $key !== 'unread' && $count < 1 ) continue;
|
||||
$is_active = $current_type === $key;
|
||||
?>
|
||||
<li>
|
||||
<a href="<?php echo esc_url( add_query_arg( [ 'msg_type' => $key, 'msg_page' => 1 ] ) ); ?>"
|
||||
class="messages-nav__item<?php echo $is_active ? ' is-active' : ''; ?>"
|
||||
data-type="<?php echo esc_attr( $key ); ?>">
|
||||
<span><?php echo esc_html( $label ); ?></span>
|
||||
<?php if ( $count > 0 ) : ?>
|
||||
<span class="messages-nav__badge" data-type="<?php echo esc_attr( $key ); ?>" data-count="<?php echo esc_attr( (string) $count ); ?>"><?php echo esc_html( (string) $count ); ?></span>
|
||||
<?php endif; ?>
|
||||
</a>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
<div class="messages-nav__actions">
|
||||
<button type="button" class="messages-nav__action-btn js-msg-mark-all-read"><?php esc_html_e( '全部已读', 'aksrt' ); ?></button>
|
||||
<button type="button" class="messages-nav__action-btn js-msg-clear-read"><?php esc_html_e( '清除已读', 'aksrt' ); ?></button>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<main class="messages-center__content">
|
||||
<?php if ( $current_type === 'conversation' ) :
|
||||
$pm = class_exists( 'AKSRT_Private_Message' ) ? AKSRT_Private_Message::get_instance() : null;
|
||||
$conversations = $pm ? $pm->get_conversations( $user_id, 30 ) : [];
|
||||
$pm_nonce = wp_create_nonce( 'aksrt_pm' );
|
||||
?>
|
||||
<div class="messages-conversations" id="aksrt-pm-conversations"
|
||||
data-ajax="<?php echo esc_url( admin_url( 'admin-ajax.php' ) ); ?>"
|
||||
data-nonce="<?php echo esc_attr( $pm_nonce ); ?>">
|
||||
<?php if ( ! empty( $conversations ) ) : ?>
|
||||
<div class="aksrt-pm__list">
|
||||
<?php foreach ( $conversations as $conv ) : ?>
|
||||
<div class="aksrt-pm__item<?php echo $conv['unread'] > 0 ? ' is-unread' : ''; ?>"
|
||||
data-conv-id="<?php echo esc_attr( (string) $conv['id'] ); ?>"
|
||||
data-other-id="<?php echo esc_attr( (string) $conv['other_user_id'] ); ?>">
|
||||
<img class="aksrt-pm__avatar" src="<?php echo esc_url( $conv['other_avatar'] ); ?>" alt=""<?php echo function_exists('aksrt_lazy_loading') ? aksrt_lazy_loading('avatar') : ' loading="lazy"'; ?> />
|
||||
<div class="aksrt-pm__info">
|
||||
<div class="aksrt-pm__name">
|
||||
<?php echo esc_html( $conv['other_name'] ); ?>
|
||||
<?php if ( $conv['unread'] > 0 ) : ?>
|
||||
<span class="aksrt-pm__badge"><?php echo esc_html( (string) $conv['unread'] ); ?></span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="aksrt-pm__preview"><?php echo esc_html( mb_substr( $conv['last_message'], 0, 50 ) ); ?></div>
|
||||
</div>
|
||||
<div class="aksrt-pm__time"><?php echo esc_html( $conv['last_message_at'] ? mysql2date( 'm-d H:i', $conv['last_message_at'] ) : '' ); ?></div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<div class="messages-empty">
|
||||
<span class="messages-empty__icon"><i class="fas fa-envelope"></i></span>
|
||||
<p class="messages-empty__text"><?php esc_html_e( '暂无私信', 'aksrt' ); ?></p>
|
||||
<p class="messages-empty__hint"><?php esc_html_e( '你可以在用户主页发起私信。', 'aksrt' ); ?></p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<div class="aksrt-pm__thread" id="aksrt-pm-thread" style="display:none;">
|
||||
<div class="aksrt-pm__thread-header">
|
||||
<button type="button" class="aksrt-pm__back-btn" id="aksrt-pm-back"><i class="fas fa-arrow-left"></i> <?php esc_html_e( '返回', 'aksrt' ); ?></button>
|
||||
<span class="aksrt-pm__thread-name" id="aksrt-pm-thread-name"></span>
|
||||
</div>
|
||||
<div class="aksrt-pm__messages" id="aksrt-pm-messages"></div>
|
||||
<div class="aksrt-pm__compose">
|
||||
<textarea id="aksrt-pm-input" rows="2" placeholder="<?php esc_attr_e( '输入消息...', 'aksrt' ); ?>"></textarea>
|
||||
<button type="button" id="aksrt-pm-send" class="aksrt-pm__send-btn"><i class="fas fa-paper-plane"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php /* conversation.js is enqueued via AKSRT_Scripts */ ?>
|
||||
<?php elseif ( ! empty( $paged_items ) ) : ?>
|
||||
<div class="messages-list">
|
||||
<?php foreach ( $paged_items as $notice ) :
|
||||
$n_type = (string) ( $notice['type'] ?? 'notice' );
|
||||
$n_title = (string) ( $notice['title'] ?? '' );
|
||||
$n_desc = (string) ( $notice['desc'] ?? '' );
|
||||
$n_url = (string) ( $notice['url'] ?? '' );
|
||||
$n_id = (string) ( $notice['id'] ?? '' );
|
||||
$is_read = ! empty( $notice['read'] );
|
||||
$is_state = ! empty( $notice['stateful'] );
|
||||
$created = (string) ( $notice['created_at'] ?? '' );
|
||||
$time_str = $is_state
|
||||
? __( '状态提醒', 'aksrt' )
|
||||
: ( $created !== '' ? get_date_from_gmt( $created, 'Y-m-d H:i' ) : '' );
|
||||
$icon_cls = $icon_map[ $n_type ] ?? 'fas fa-bell';
|
||||
?>
|
||||
<div class="message-item<?php echo ! $is_read ? ' is-unread' : ''; ?>" data-notification-id="<?php echo esc_attr( $n_id ); ?>">
|
||||
<span class="message-item__icon">
|
||||
<i class="<?php echo esc_attr( $icon_cls ); ?>" aria-hidden="true"></i>
|
||||
</span>
|
||||
<div class="message-item__body">
|
||||
<div class="message-item__title">
|
||||
<?php echo esc_html( $n_title ); ?>
|
||||
<?php if ( ! $is_read && ! $is_state ) : ?>
|
||||
<span class="message-item__new-badge">NEW</span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php if ( $n_desc !== '' ) : ?>
|
||||
<div class="message-item__desc"><?php echo esc_html( $n_desc ); ?></div>
|
||||
<?php endif; ?>
|
||||
<?php if ( $time_str !== '' ) : ?>
|
||||
<div class="message-item__time"><?php echo esc_html( $time_str ); ?></div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="message-item__actions">
|
||||
<?php if ( $n_url !== '' ) : ?>
|
||||
<a href="<?php echo esc_url( $n_url ); ?>" class="message-item__action-btn"><?php esc_html_e( '查看', 'aksrt' ); ?></a>
|
||||
<?php endif; ?>
|
||||
<?php if ( ! $is_state && ! $is_read ) : ?>
|
||||
<button type="button" class="message-item__action-btn js-msg-mark-read" data-id="<?php echo esc_attr( $n_id ); ?>"><?php esc_html_e( '已读', 'aksrt' ); ?></button>
|
||||
<?php endif; ?>
|
||||
<?php if ( ! $is_state ) : ?>
|
||||
<button type="button" class="message-item__action-btn message-item__action-btn--danger js-msg-delete" data-id="<?php echo esc_attr( $n_id ); ?>"><?php esc_html_e( '删除', 'aksrt' ); ?></button>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
|
||||
<?php if ( $total_pages > 1 ) : ?>
|
||||
<div class="messages-pagination">
|
||||
<?php for ( $i = 1; $i <= $total_pages; $i++ ) :
|
||||
$page_url = add_query_arg( [ 'msg_type' => $current_type, 'msg_page' => $i ] );
|
||||
?>
|
||||
<?php if ( $i === $current_page ) : ?>
|
||||
<span class="profile-status-chip is-active"><?php echo esc_html( (string) $i ); ?></span>
|
||||
<?php else : ?>
|
||||
<a href="<?php echo esc_url( $page_url ); ?>" class="profile-status-chip"><?php echo esc_html( (string) $i ); ?></a>
|
||||
<?php endif; ?>
|
||||
<?php endfor; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php else : ?>
|
||||
<div class="messages-empty">
|
||||
<span class="messages-empty__icon"><i class="fas fa-bell-slash"></i></span>
|
||||
<p class="messages-empty__text"><?php esc_html_e( '暂无消息', 'aksrt' ); ?></p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<?php get_footer(); ?>
|
||||
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
/**
|
||||
* Template Name: AKSRT - New Posts
|
||||
* Template Post Type: page
|
||||
*
|
||||
* 最新文章页:按时间倒序展示最新发布的文章。
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
get_header();
|
||||
|
||||
$paged = max(1, (int) get_query_var('paged'));
|
||||
$per_page = 20;
|
||||
|
||||
$query = new WP_Query([
|
||||
'post_type' => 'post',
|
||||
'post_status' => 'publish',
|
||||
'posts_per_page' => $per_page,
|
||||
'paged' => $paged,
|
||||
'orderby' => 'date',
|
||||
'order' => 'DESC',
|
||||
]);
|
||||
?>
|
||||
|
||||
<main id="main-content" class="container page-content-default" tabindex="-1">
|
||||
<header class="page-header">
|
||||
<h1 class="entry-title"><?php echo esc_html(get_the_title() ?: __('最新文章', 'aksrt')); ?></h1>
|
||||
</header>
|
||||
|
||||
<div class="content-wrap">
|
||||
<div class="content-layout content-layout--no-sidebar">
|
||||
<div class="content-layout__primary">
|
||||
<div class="aksrt-newposts container">
|
||||
<?php if ($query->have_posts()) : ?>
|
||||
<div class="aksrt-newposts__list">
|
||||
<?php while ($query->have_posts()) : $query->the_post(); ?>
|
||||
<article class="aksrt-newposts__item">
|
||||
<span class="aksrt-newposts__date"><?php echo esc_html(get_the_date()); ?></span>
|
||||
<h3 class="aksrt-newposts__title">
|
||||
<a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
|
||||
</h3>
|
||||
<p class="aksrt-newposts__excerpt"><?php echo esc_html(wp_trim_words(get_the_excerpt(), 30)); ?></p>
|
||||
</article>
|
||||
<?php endwhile; ?>
|
||||
</div>
|
||||
<?php
|
||||
if (function_exists('aksrt_render_pagination')) {
|
||||
aksrt_render_pagination($query);
|
||||
} else {
|
||||
echo '<div class="aksrt-pagination">' . paginate_links(['total' => $query->max_num_pages]) . '</div>';
|
||||
}
|
||||
?>
|
||||
<?php wp_reset_postdata(); ?>
|
||||
<?php else : ?>
|
||||
<p class="aksrt-newposts__empty"><?php esc_html_e('暂无文章。', 'aksrt'); ?></p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<?php
|
||||
get_footer();
|
||||
@@ -0,0 +1,253 @@
|
||||
<?php
|
||||
/**
|
||||
* Template Name: AKSRT - Orders
|
||||
* Template Post Type: page
|
||||
*
|
||||
* Enhanced: 5 tabs, logistics timeline, receipt confirm,
|
||||
* review button, re-purchase, gift/discount details (§6.10).
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
get_header();
|
||||
|
||||
if (!is_user_logged_in()) {
|
||||
$login_url = function_exists('aksrt_get_login_url') ? aksrt_get_login_url() : wp_login_url(get_permalink());
|
||||
wp_safe_redirect($login_url);
|
||||
exit;
|
||||
}
|
||||
|
||||
$user_id = get_current_user_id();
|
||||
$per_page = 20;
|
||||
$paged = max(1, (int) ($_GET['order_page'] ?? 1));
|
||||
$tab = sanitize_key((string) ($_GET['tab'] ?? ''));
|
||||
$status = sanitize_key((string) ($_GET['order_status'] ?? ''));
|
||||
|
||||
$tab_status_map = [
|
||||
'pending' => AKSRT_Order::STATUS_PENDING,
|
||||
'shipped' => AKSRT_Order::STATUS_DELIVERED,
|
||||
'received' => AKSRT_Order::STATUS_COMPLETED,
|
||||
'review' => AKSRT_Order::STATUS_PENDING_REVIEW,
|
||||
'after' => AKSRT_Order::STATUS_REFUNDING,
|
||||
];
|
||||
if ($tab !== '' && isset($tab_status_map[$tab])) {
|
||||
$status = $tab_status_map[$tab];
|
||||
}
|
||||
|
||||
$orders_view = function_exists('aksrt_get_orders_page_view')
|
||||
? aksrt_get_orders_page_view($user_id, $paged, $per_page, $status)
|
||||
: ['items' => [], 'total' => 0, 'total_pages' => 1, 'page' => 1];
|
||||
|
||||
$orders = (array) ($orders_view['items'] ?? []);
|
||||
$total_pages = max(1, (int) ($orders_view['total_pages'] ?? 1));
|
||||
|
||||
$shop = class_exists('AKSRT_Shop') ? AKSRT_Shop::get_instance() : null;
|
||||
$shipping = class_exists('AKSRT_Shipping') ? AKSRT_Shipping::get_instance() : null;
|
||||
|
||||
$tabs = [
|
||||
'' => __('全部', 'aksrt'),
|
||||
'pending' => __('待支付', 'aksrt'),
|
||||
'shipped' => __('待收货', 'aksrt'),
|
||||
'review' => __('待评价', 'aksrt'),
|
||||
'after' => __('售后', 'aksrt'),
|
||||
];
|
||||
?>
|
||||
|
||||
<main id="main-content" class="site-main content-shell" tabindex="-1">
|
||||
<div class="container aksrt-orders-page" data-aksrt-order-center>
|
||||
<div class="aksrt-orders-page__header">
|
||||
<h1><?php esc_html_e('我的订单', 'aksrt'); ?></h1>
|
||||
</div>
|
||||
|
||||
<!-- 5-tab navigation -->
|
||||
<div class="aksrt-orders-page__tabs">
|
||||
<?php foreach ($tabs as $tab_key => $tab_label) :
|
||||
$is_active = $tab === $tab_key;
|
||||
$tab_url = $tab_key !== '' ? add_query_arg(['tab' => $tab_key, 'order_page' => 1]) : remove_query_arg(['tab', 'order_status', 'order_page']);
|
||||
?>
|
||||
<a href="<?php echo esc_url($tab_url); ?>" class="aksrt-orders-page__tab<?php echo $is_active ? ' is-active' : ''; ?>">
|
||||
<?php echo esc_html($tab_label); ?>
|
||||
</a>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
|
||||
<?php if (!empty($orders)) : ?>
|
||||
<div class="aksrt-orders-page__list">
|
||||
<?php foreach ($orders as $order) :
|
||||
$on = (string) ($order['order_number'] ?? '');
|
||||
$os = (string) ($order['status'] ?? '');
|
||||
$items = $order['items'] ?? [];
|
||||
?>
|
||||
<article class="aksrt-orders-page__card" data-aksrt-order-card="<?php echo esc_attr($on); ?>">
|
||||
<!-- Card header -->
|
||||
<div class="aksrt-orders-page__card-head">
|
||||
<span class="aksrt-orders-page__card-number"><?php echo esc_html($on); ?></span>
|
||||
<time class="aksrt-orders-page__card-time"><?php echo esc_html((string) ($order['created_at'] ?? '')); ?></time>
|
||||
<span class="aksrt-orders-page__card-status"><?php echo esc_html((string) ($order['status_label'] ?? '')); ?></span>
|
||||
</div>
|
||||
|
||||
<!-- Order items -->
|
||||
<div class="aksrt-orders-page__card-items">
|
||||
<?php if (!empty($items)) : ?>
|
||||
<?php foreach ($items as $item) : ?>
|
||||
<div class="aksrt-orders-page__card-item">
|
||||
<?php if (!empty($item['image'])) : ?>
|
||||
<img src="<?php echo esc_url((string) $item['image']); ?>" alt="" class="aksrt-orders-page__card-img">
|
||||
<?php endif; ?>
|
||||
<div class="aksrt-orders-page__card-item-info">
|
||||
<span class="aksrt-orders-page__card-item-title"><?php echo esc_html((string) ($item['product_title'] ?? '')); ?></span>
|
||||
<?php if (!empty($item['options_label'])) : ?>
|
||||
<small class="aksrt-orders-page__card-item-opts"><?php echo esc_html((string) $item['options_label']); ?></small>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="aksrt-orders-page__card-item-price">
|
||||
<strong>¥<?php echo esc_html(number_format((float) ($item['pay_price'] ?? $item['unit_price'] ?? 0), 2)); ?></strong>
|
||||
<span>×<?php echo esc_html((string) ($item['quantity'] ?? 1)); ?></span>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
<?php else : ?>
|
||||
<div class="aksrt-orders-page__card-item">
|
||||
<span class="aksrt-orders-page__card-item-title"><?php echo esc_html((string) ($order['product_name'] ?? __('商品订单', 'aksrt'))); ?></span>
|
||||
<strong>¥<?php echo esc_html(number_format((float) ($order['amount'] ?? 0), 2)); ?></strong>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<!-- Price summary -->
|
||||
<div class="aksrt-orders-page__card-summary">
|
||||
<span><?php esc_html_e('合计', 'aksrt'); ?></span>
|
||||
<strong>¥<?php echo esc_html(number_format((float) ($order['amount'] ?? 0), 2)); ?></strong>
|
||||
<?php if ((float) ($order['discount'] ?? 0) > 0) : ?>
|
||||
<small>(<?php printf(esc_html__('已优惠 ¥%s', 'aksrt'), number_format((float) $order['discount'], 2)); ?>)</small>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<!-- Logistics timeline (collapsed) -->
|
||||
<?php if (!empty($order['shipping_records'])) : ?>
|
||||
<div class="aksrt-orders-page__timeline" data-aksrt-timeline>
|
||||
<h4 class="aksrt-orders-page__timeline-toggle" data-aksrt-toggle-timeline>
|
||||
<i class="fas fa-truck"></i> <?php esc_html_e('物流信息', 'aksrt'); ?> <i class="fas fa-chevron-down"></i>
|
||||
</h4>
|
||||
<div class="aksrt-orders-page__timeline-body" hidden>
|
||||
<?php foreach ((array) ($order['timeline'] ?? []) as $tl) : ?>
|
||||
<div class="aksrt-orders-page__timeline-item">
|
||||
<time><?php echo esc_html((string) ($tl['time'] ?? '')); ?></time>
|
||||
<span><?php echo esc_html((string) ($tl['label'] ?? '')); ?></span>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- Actions -->
|
||||
<div class="aksrt-orders-page__card-actions">
|
||||
<?php if (!empty($order['actions']['can_pay'])) : ?>
|
||||
<button type="button" class="btn-primary btn-sm" data-aksrt-order-pay="<?php echo esc_attr($on); ?>"><?php esc_html_e('去支付', 'aksrt'); ?></button>
|
||||
<?php endif; ?>
|
||||
<?php if (!empty($order['actions']['can_receipt'])) : ?>
|
||||
<button type="button" class="btn-primary btn-sm" data-aksrt-order-receipt="<?php echo esc_attr($on); ?>"><?php esc_html_e('确认收货', 'aksrt'); ?></button>
|
||||
<?php endif; ?>
|
||||
<?php if ($os === AKSRT_Order::STATUS_PENDING_REVIEW) : ?>
|
||||
<button type="button" class="btn-primary btn-sm" data-aksrt-order-review="<?php echo esc_attr($on); ?>"><?php esc_html_e('去评价', 'aksrt'); ?></button>
|
||||
<?php endif; ?>
|
||||
<?php if (!empty($order['actions']['can_cancel'])) : ?>
|
||||
<button type="button" class="btn-ghost btn-sm" data-aksrt-order-cancel="<?php echo esc_attr($on); ?>"><?php esc_html_e('取消', 'aksrt'); ?></button>
|
||||
<?php endif; ?>
|
||||
<?php if (in_array($os, [AKSRT_Order::STATUS_COMPLETED, AKSRT_Order::STATUS_PENDING_REVIEW], true)) : ?>
|
||||
<button type="button" class="btn-outline btn-sm" data-aksrt-order-rebuy="<?php echo esc_attr($on); ?>"><?php esc_html_e('再次购买', 'aksrt'); ?></button>
|
||||
<?php endif; ?>
|
||||
<?php if (!empty($order['actions']['can_after_sale'])) : ?>
|
||||
<button type="button" class="btn-outline btn-sm" data-aksrt-order-after-sale="<?php echo esc_attr($on); ?>"><?php esc_html_e('售后', 'aksrt'); ?></button>
|
||||
<?php endif; ?>
|
||||
<?php if (!empty($order['time_left'])) : ?>
|
||||
<span class="aksrt-orders-page__countdown" data-aksrt-order-countdown="<?php echo esc_attr((string) $order['time_left']); ?>">
|
||||
<?php printf(esc_html__('%d秒后关闭', 'aksrt'), (int) $order['time_left']); ?>
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</article>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
|
||||
<?php if ($total_pages > 1) : ?>
|
||||
<div class="aksrt-orders-page__pagination">
|
||||
<?php for ($i = 1; $i <= $total_pages; $i++) :
|
||||
$page_url = add_query_arg(['order_page' => $i]);
|
||||
?>
|
||||
<?php if ($i === $paged) : ?>
|
||||
<span class="aksrt-orders-page__page-chip is-active"><?php echo esc_html((string) $i); ?></span>
|
||||
<?php else : ?>
|
||||
<a href="<?php echo esc_url($page_url); ?>" class="aksrt-orders-page__page-chip"><?php echo esc_html((string) $i); ?></a>
|
||||
<?php endif; ?>
|
||||
<?php endfor; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php else : ?>
|
||||
<div class="aksrt-orders-page__empty">
|
||||
<i class="fas fa-receipt" aria-hidden="true"></i>
|
||||
<p><?php esc_html_e('暂无订单记录。', 'aksrt'); ?></p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- After-sale modal -->
|
||||
<div class="aksrt-modal" data-aksrt-aftersale-modal hidden>
|
||||
<div class="aksrt-modal__overlay"></div>
|
||||
<div class="aksrt-modal__dialog">
|
||||
<div class="aksrt-modal__header">
|
||||
<h3><?php esc_html_e('申请售后', 'aksrt'); ?></h3>
|
||||
<button type="button" class="aksrt-modal__close" data-aksrt-aftersale-modal-close>×</button>
|
||||
</div>
|
||||
<form class="aksrt-modal__body" data-aksrt-aftersale-form>
|
||||
<input type="hidden" name="order_number" value="">
|
||||
<div class="aksrt-orders-page__field">
|
||||
<label><?php esc_html_e('售后类型', 'aksrt'); ?></label>
|
||||
<select name="type" class="aksrt-orders-page__select">
|
||||
<?php foreach (AKSRT_After_Sale::get_valid_types() as $type_key => $type_label) : ?>
|
||||
<option value="<?php echo esc_attr($type_key); ?>"><?php echo esc_html($type_label); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="aksrt-orders-page__field">
|
||||
<label><?php esc_html_e('售后原因', 'aksrt'); ?> *</label>
|
||||
<textarea name="reason" class="aksrt-orders-page__textarea" rows="4" required placeholder="<?php esc_attr_e('请描述问题', 'aksrt'); ?>"></textarea>
|
||||
</div>
|
||||
<div class="aksrt-modal__footer">
|
||||
<button type="button" class="btn-ghost" data-aksrt-aftersale-modal-close><?php esc_html_e('取消', 'aksrt'); ?></button>
|
||||
<button type="submit" class="btn-primary"><?php esc_html_e('提交', 'aksrt'); ?></button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Favorites section -->
|
||||
<?php
|
||||
$fav_tab = sanitize_key((string) ($_GET['section'] ?? ''));
|
||||
if ($fav_tab === 'favorites' && $shop) :
|
||||
$fav_data = $shop->get_user_favorites($user_id);
|
||||
?>
|
||||
<section class="aksrt-orders-page__favorites">
|
||||
<h2><?php esc_html_e('收藏商品', 'aksrt'); ?></h2>
|
||||
<?php if (!empty($fav_data['items'])) : ?>
|
||||
<div class="aksrt-orders-page__fav-grid">
|
||||
<?php foreach ($fav_data['items'] as $fav) : ?>
|
||||
<a href="<?php echo esc_url((string) ($fav['permalink'] ?? '#')); ?>" class="aksrt-orders-page__fav-card">
|
||||
<?php if (!empty($fav['image'])) : ?>
|
||||
<img src="<?php echo esc_url((string) $fav['image']); ?>" alt="" loading="lazy">
|
||||
<?php endif; ?>
|
||||
<h3><?php echo esc_html((string) ($fav['title'] ?? '')); ?></h3>
|
||||
<strong>¥<?php echo esc_html(number_format((float) ($fav['price'] ?? 0), 2)); ?></strong>
|
||||
</a>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<p><?php esc_html_e('暂无收藏商品', 'aksrt'); ?></p>
|
||||
<?php endif; ?>
|
||||
</section>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<?php get_footer(); ?>
|
||||
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
/**
|
||||
* Template Name: AKSRT - Posts Navigation
|
||||
* Template Post Type: page
|
||||
*
|
||||
* 文章导航页:分类+标签的导航聚合页。
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
get_header();
|
||||
|
||||
$categories = get_categories(['hide_empty' => true, 'orderby' => 'count', 'order' => 'DESC', 'number' => 20]);
|
||||
$tags = get_tags(['hide_empty' => true, 'orderby' => 'count', 'order' => 'DESC', 'number' => 40]);
|
||||
?>
|
||||
|
||||
<main id="main-content" class="container page-content-default" tabindex="-1">
|
||||
<header class="page-header">
|
||||
<h1 class="entry-title"><?php echo esc_html(get_the_title() ?: __('文章导航', 'aksrt')); ?></h1>
|
||||
</header>
|
||||
|
||||
<div class="content-wrap">
|
||||
<div class="content-layout content-layout--no-sidebar">
|
||||
<div class="content-layout__primary">
|
||||
<div class="aksrt-posts-navs container">
|
||||
<?php if (!empty($categories)) : ?>
|
||||
<section class="aksrt-posts-navs__section">
|
||||
<h2 class="aksrt-posts-navs__heading"><?php esc_html_e('热门分类', 'aksrt'); ?></h2>
|
||||
<div class="aksrt-posts-navs__cats">
|
||||
<?php foreach ($categories as $cat) : ?>
|
||||
<a href="<?php echo esc_url(get_category_link($cat->term_id)); ?>" class="aksrt-posts-navs__cat-chip">
|
||||
<span class="aksrt-posts-navs__cat-name"><?php echo esc_html($cat->name); ?></span>
|
||||
<span class="aksrt-posts-navs__cat-count"><?php echo esc_html($cat->count); ?></span>
|
||||
</a>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</section>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!empty($tags)) : ?>
|
||||
<section class="aksrt-posts-navs__section">
|
||||
<h2 class="aksrt-posts-navs__heading"><?php esc_html_e('热门标签', 'aksrt'); ?></h2>
|
||||
<div class="aksrt-posts-navs__tags">
|
||||
<?php foreach ($tags as $tag) : ?>
|
||||
<a href="<?php echo esc_url(get_tag_link($tag->term_id)); ?>" class="aksrt-posts-navs__tag"><?php echo esc_html($tag->name); ?></a>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</section>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<?php
|
||||
get_footer();
|
||||
@@ -0,0 +1,170 @@
|
||||
<?php
|
||||
/**
|
||||
* Template Name: AKSRT - Product Edit
|
||||
* Template Post Type: page
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
get_header();
|
||||
|
||||
if (!is_user_logged_in()) {
|
||||
$login_url = function_exists('aksrt_get_login_url') ? aksrt_get_login_url() : wp_login_url(get_permalink());
|
||||
wp_safe_redirect($login_url);
|
||||
exit;
|
||||
}
|
||||
|
||||
$product_id = (int) ($_GET['product_id'] ?? 0);
|
||||
$edit_view = function_exists('aksrt_get_product_edit_page_view')
|
||||
? aksrt_get_product_edit_page_view(get_current_user_id(), $product_id)
|
||||
: ['allowed' => false, 'is_edit' => false, 'product' => [], 'taxonomy' => ['categories' => [], 'tags' => []], 'shipping_modes' => [], 'status_options' => []];
|
||||
|
||||
$product = (array) ($edit_view['product'] ?? []);
|
||||
?>
|
||||
|
||||
<main id="main-content" class="site-main content-shell" tabindex="-1">
|
||||
<?php if (function_exists('aksrt_breadcrumbs')) { aksrt_breadcrumbs(); } ?>
|
||||
|
||||
<div
|
||||
class="aksrt-product-editor container"
|
||||
data-aksrt-product-editor
|
||||
data-product-id="<?php echo esc_attr((string) ($product['id'] ?? 0)); ?>"
|
||||
data-is-edit="<?php echo !empty($edit_view['is_edit']) ? '1' : '0'; ?>"
|
||||
>
|
||||
<?php if (empty($edit_view['allowed'])) : ?>
|
||||
<div class="aksrt-product-editor__empty">
|
||||
<i class="fas fa-lock" aria-hidden="true"></i>
|
||||
<p><?php esc_html_e('你没有权限编辑该商品。', 'aksrt'); ?></p>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<div class="aksrt-product-editor__header">
|
||||
<div>
|
||||
<h1 class="aksrt-product-editor__title">
|
||||
<?php echo !empty($edit_view['is_edit']) ? esc_html__('编辑商品', 'aksrt') : esc_html__('发布商品', 'aksrt'); ?>
|
||||
</h1>
|
||||
<p class="aksrt-product-editor__subtitle"><?php esc_html_e('管理主图、图集、分类标签、发货方式、运费和售后说明。', 'aksrt'); ?></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form class="aksrt-product-editor__layout" data-aksrt-product-form>
|
||||
<section class="aksrt-product-editor__main">
|
||||
<div class="aksrt-product-editor__panel">
|
||||
<h2><?php esc_html_e('基础信息', 'aksrt'); ?></h2>
|
||||
<label class="aksrt-product-editor__field">
|
||||
<span><?php esc_html_e('商品名称', 'aksrt'); ?></span>
|
||||
<input type="text" name="title" class="aksrt-product-editor__input" value="<?php echo esc_attr((string) ($product['title'] ?? '')); ?>" required>
|
||||
</label>
|
||||
|
||||
<div class="aksrt-product-editor__columns">
|
||||
<label class="aksrt-product-editor__field">
|
||||
<span><?php esc_html_e('价格', 'aksrt'); ?></span>
|
||||
<input type="number" name="price" class="aksrt-product-editor__input" min="0" step="0.01" value="<?php echo esc_attr((string) ($product['price'] ?? 0)); ?>" required>
|
||||
</label>
|
||||
<label class="aksrt-product-editor__field">
|
||||
<span><?php esc_html_e('库存', 'aksrt'); ?></span>
|
||||
<input type="number" name="stock" class="aksrt-product-editor__input" min="0" step="1" value="<?php echo esc_attr((string) ($product['stock'] ?? 0)); ?>" required>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<label class="aksrt-product-editor__field">
|
||||
<span><?php esc_html_e('商品简介', 'aksrt'); ?></span>
|
||||
<textarea name="excerpt" class="aksrt-product-editor__textarea" rows="4"><?php echo esc_textarea((string) ($product['excerpt'] ?? '')); ?></textarea>
|
||||
</label>
|
||||
|
||||
<label class="aksrt-product-editor__field">
|
||||
<span><?php esc_html_e('商品详情', 'aksrt'); ?></span>
|
||||
<textarea name="content" class="aksrt-product-editor__textarea" rows="10"><?php echo esc_textarea((string) ($product['content'] ?? '')); ?></textarea>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="aksrt-product-editor__panel">
|
||||
<h2><?php esc_html_e('商品素材', 'aksrt'); ?></h2>
|
||||
<label class="aksrt-product-editor__field">
|
||||
<span><?php esc_html_e('主图 URL', 'aksrt'); ?></span>
|
||||
<input type="url" name="image" class="aksrt-product-editor__input" value="<?php echo esc_attr((string) ($product['image'] ?? '')); ?>" placeholder="https://">
|
||||
</label>
|
||||
<label class="aksrt-product-editor__field">
|
||||
<span><?php esc_html_e('图集 URL(每行一个)', 'aksrt'); ?></span>
|
||||
<textarea name="gallery" class="aksrt-product-editor__textarea" rows="5"><?php echo esc_textarea(implode("\n", (array) ($product['gallery'] ?? []))); ?></textarea>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="aksrt-product-editor__panel">
|
||||
<h2><?php esc_html_e('发货与售后', 'aksrt'); ?></h2>
|
||||
<div class="aksrt-product-editor__columns">
|
||||
<label class="aksrt-product-editor__field">
|
||||
<span><?php esc_html_e('发货方式', 'aksrt'); ?></span>
|
||||
<select name="shipping_mode" class="aksrt-product-editor__input">
|
||||
<?php foreach ((array) ($edit_view['shipping_modes'] ?? []) as $mode) : ?>
|
||||
<option value="<?php echo esc_attr((string) ($mode['value'] ?? '')); ?>" <?php selected((string) ($product['shipping_mode'] ?? ''), (string) ($mode['value'] ?? '')); ?>>
|
||||
<?php echo esc_html((string) ($mode['label'] ?? '')); ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</label>
|
||||
<label class="aksrt-product-editor__field">
|
||||
<span><?php esc_html_e('额外运费', 'aksrt'); ?></span>
|
||||
<input type="number" name="shipping_fee" class="aksrt-product-editor__input" min="0" step="0.01" value="<?php echo esc_attr((string) ($product['shipping_fee'] ?? 0)); ?>">
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<label class="aksrt-product-editor__field">
|
||||
<span><?php esc_html_e('售后说明', 'aksrt'); ?></span>
|
||||
<textarea name="after_sale_policy" class="aksrt-product-editor__textarea" rows="4"><?php echo esc_textarea((string) ($product['after_sale_policy'] ?? '')); ?></textarea>
|
||||
</label>
|
||||
|
||||
<label class="aksrt-product-editor__checkbox">
|
||||
<input type="checkbox" name="support_refund" value="1" <?php checked(!empty($product['support_refund'])); ?>>
|
||||
<span><?php esc_html_e('支持退款/售后入口', 'aksrt'); ?></span>
|
||||
</label>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<aside class="aksrt-product-editor__sidebar">
|
||||
<div class="aksrt-product-editor__panel">
|
||||
<h2><?php esc_html_e('发布设置', 'aksrt'); ?></h2>
|
||||
<label class="aksrt-product-editor__field">
|
||||
<span><?php esc_html_e('状态', 'aksrt'); ?></span>
|
||||
<select name="status" class="aksrt-product-editor__input">
|
||||
<?php foreach ((array) ($edit_view['status_options'] ?? []) as $status_option) : ?>
|
||||
<option value="<?php echo esc_attr((string) ($status_option['value'] ?? 'draft')); ?>" <?php selected((string) ($product['status'] ?? 'draft'), (string) ($status_option['value'] ?? 'draft')); ?>>
|
||||
<?php echo esc_html((string) ($status_option['label'] ?? '')); ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</label>
|
||||
|
||||
<label class="aksrt-product-editor__field">
|
||||
<span><?php esc_html_e('分类(按住 Ctrl 可多选)', 'aksrt'); ?></span>
|
||||
<select name="categories[]" class="aksrt-product-editor__input" multiple size="6">
|
||||
<?php foreach ((array) (($edit_view['taxonomy']['categories'] ?? [])) as $category) : ?>
|
||||
<option value="<?php echo esc_attr((string) ($category['id'] ?? 0)); ?>" <?php echo in_array((int) ($category['id'] ?? 0), (array) ($product['categories'] ?? []), true) ? 'selected' : ''; ?>>
|
||||
<?php echo esc_html((string) ($category['name'] ?? '')); ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</label>
|
||||
|
||||
<label class="aksrt-product-editor__field">
|
||||
<span><?php esc_html_e('标签(英文逗号分隔)', 'aksrt'); ?></span>
|
||||
<input type="text" name="tags" class="aksrt-product-editor__input" value="<?php echo esc_attr(implode(', ', (array) ($product['tags'] ?? []))); ?>">
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="aksrt-product-editor__panel">
|
||||
<h2><?php esc_html_e('动作', 'aksrt'); ?></h2>
|
||||
<div class="aksrt-product-editor__actions">
|
||||
<button type="submit" class="btn-primary btn-lg"><?php echo !empty($edit_view['is_edit']) ? esc_html__('保存修改', 'aksrt') : esc_html__('发布商品', 'aksrt'); ?></button>
|
||||
<a href="<?php echo esc_url(function_exists('aksrt_get_user_center_url') ? aksrt_get_user_center_url() : home_url('/')); ?>" class="btn-ghost btn-lg"><?php esc_html_e('返回中心', 'aksrt'); ?></a>
|
||||
</div>
|
||||
<p class="aksrt-product-editor__hint" data-aksrt-product-editor-message><?php esc_html_e('保存后会回到用户中心,商品信息供订单页和商品详情页复用。', 'aksrt'); ?></p>
|
||||
</div>
|
||||
</aside>
|
||||
</form>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<?php get_footer(); ?>
|
||||
@@ -0,0 +1,413 @@
|
||||
<?php
|
||||
/**
|
||||
* Template Name: AKSRT - Product Detail
|
||||
* Template Post Type: page
|
||||
*
|
||||
* Enhanced: options selector, video gallery, params/services modal,
|
||||
* review tab, favorites, related products, mobile tabbar (§6.10).
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
get_header();
|
||||
|
||||
$product_id = (int) ($_GET['product_id'] ?? 0);
|
||||
if ($product_id <= 0) {
|
||||
$product_id = (int) get_query_var('product_id', 0);
|
||||
}
|
||||
|
||||
$shop = class_exists('AKSRT_Shop') ? AKSRT_Shop::get_instance() : null;
|
||||
$product = function_exists('aksrt_get_product_page_view')
|
||||
? aksrt_get_product_page_view($product_id)
|
||||
: ($shop ? $shop->get_product_detail_view($product_id) : []);
|
||||
|
||||
$user_id = get_current_user_id();
|
||||
$is_fav = $shop && $user_id > 0 ? $shop->is_favorite($user_id, $product_id) : false;
|
||||
$options = $product['options'] ?? [];
|
||||
$has_options = !empty($options);
|
||||
$price_range = $product['price_range'] ?? [];
|
||||
$params = $product['params'] ?? [];
|
||||
$services = $product['services'] ?? [];
|
||||
$pay_modo = $product['pay_modo'] ?? '0';
|
||||
$scores = class_exists('AKSRT_Product_Review') ? AKSRT_Product_Review::get_instance()->get_product_scores($product_id) : [];
|
||||
$reviews = class_exists('AKSRT_Product_Review') ? AKSRT_Product_Review::get_instance()->get_reviews($product_id, ['per_page' => 5]) : ['items' => [], 'total' => 0];
|
||||
$author_id = (int) get_post_field('post_author', $product_id);
|
||||
$author = $author_id > 0 ? get_userdata($author_id) : null;
|
||||
?>
|
||||
|
||||
<main id="main-content" class="site-main content-shell" tabindex="-1">
|
||||
<?php if (function_exists('aksrt_breadcrumbs')) { aksrt_breadcrumbs(); } ?>
|
||||
|
||||
<?php if (!empty($product)) : ?>
|
||||
<div
|
||||
class="aksrt-product-page container"
|
||||
data-aksrt-product-page
|
||||
data-product-id="<?php echo esc_attr((string) $product_id); ?>"
|
||||
data-options='<?php echo esc_attr(wp_json_encode($options, JSON_UNESCAPED_UNICODE)); ?>'
|
||||
>
|
||||
<div class="aksrt-product-page__layout">
|
||||
<!-- Gallery -->
|
||||
<section class="aksrt-product-page__gallery">
|
||||
<?php if (!empty($product['image'])) : ?>
|
||||
<div class="aksrt-product-page__primary-image" data-aksrt-main-image>
|
||||
<img src="<?php echo esc_url((string) $product['image']); ?>" alt="<?php echo esc_attr((string) ($product['title'] ?? '')); ?>" id="product-main-img">
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<div class="aksrt-product-page__placeholder">
|
||||
<i class="fas fa-image" aria-hidden="true"></i>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php
|
||||
$gallery_items = (array) ($product['gallery'] ?? []);
|
||||
$cover_videos = (array) (get_post_meta($product_id, '_aksrt_cover_videos', true) ?: []);
|
||||
?>
|
||||
<?php if (!empty($gallery_items) || !empty($cover_videos)) : ?>
|
||||
<div class="aksrt-product-page__thumbs">
|
||||
<?php foreach ($cover_videos as $video_url) : ?>
|
||||
<button type="button" class="aksrt-product-page__thumb aksrt-product-page__thumb--video" data-aksrt-product-video="<?php echo esc_url($video_url); ?>">
|
||||
<i class="fas fa-play-circle"></i>
|
||||
</button>
|
||||
<?php endforeach; ?>
|
||||
<?php foreach ($gallery_items as $gallery_image) : ?>
|
||||
<button type="button" class="aksrt-product-page__thumb" data-aksrt-product-thumb="<?php echo esc_url($gallery_image); ?>">
|
||||
<img src="<?php echo esc_url($gallery_image); ?>" alt="">
|
||||
</button>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</section>
|
||||
|
||||
<!-- Summary -->
|
||||
<section class="aksrt-product-page__summary">
|
||||
<div class="aksrt-product-page__badges">
|
||||
<?php if ($pay_modo === 'points') : ?>
|
||||
<span class="aksrt-product-page__badge aksrt-product-page__badge--points"><?php esc_html_e('积分商品', 'aksrt'); ?></span>
|
||||
<?php endif; ?>
|
||||
<?php if (!empty($product['marketing']['headline'])) : ?>
|
||||
<span class="aksrt-product-page__badge aksrt-product-page__badge--promo"><?php echo esc_html((string) $product['marketing']['headline']); ?></span>
|
||||
<?php endif; ?>
|
||||
<?php if (!empty($product['after_sale']['support_refund'])) : ?>
|
||||
<span class="aksrt-product-page__badge"><?php esc_html_e('支持售后', 'aksrt'); ?></span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<h1 class="aksrt-product-page__title"><?php echo esc_html((string) ($product['title'] ?? '')); ?></h1>
|
||||
|
||||
<!-- Price row with range support -->
|
||||
<div class="aksrt-product-page__price-row">
|
||||
<?php if ($has_options && !empty($price_range) && $price_range['min'] !== $price_range['max']) : ?>
|
||||
<strong class="aksrt-product-page__price" data-aksrt-dynamic-price>
|
||||
<?php echo $pay_modo === 'points' ? '' : '¥'; ?><?php echo esc_html(number_format($price_range['min'], 2)); ?> - <?php echo $pay_modo === 'points' ? '' : '¥'; ?><?php echo esc_html(number_format($price_range['max'], 2)); ?>
|
||||
<?php if ($pay_modo === 'points') : ?><small><?php esc_html_e('积分', 'aksrt'); ?></small><?php endif; ?>
|
||||
</strong>
|
||||
<?php else : ?>
|
||||
<strong class="aksrt-product-page__price" data-aksrt-dynamic-price>
|
||||
<?php echo $pay_modo === 'points' ? '' : '¥'; ?><?php echo esc_html(number_format((float) ($product['price'] ?? 0), 2)); ?>
|
||||
<?php if ($pay_modo === 'points') : ?><small><?php esc_html_e('积分', 'aksrt'); ?></small><?php endif; ?>
|
||||
</strong>
|
||||
<?php endif; ?>
|
||||
<span class="aksrt-product-page__sales"><?php printf(esc_html__('已售 %d', 'aksrt'), (int) ($product['sales'] ?? 0)); ?></span>
|
||||
<?php if (!empty($scores['average'])) : ?>
|
||||
<span class="aksrt-product-page__rating"><i class="fas fa-star"></i> <?php echo esc_html((string) $scores['average']); ?></span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<?php if (!empty($product['excerpt'])) : ?>
|
||||
<p class="aksrt-product-page__excerpt"><?php echo esc_html((string) $product['excerpt']); ?></p>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- Product options selector -->
|
||||
<?php if ($has_options) : ?>
|
||||
<div class="aksrt-product-page__options" data-aksrt-options-selector>
|
||||
<?php foreach ($options as $group_idx => $group) : ?>
|
||||
<div class="aksrt-product-page__option-group" data-group-index="<?php echo esc_attr((string) $group_idx); ?>">
|
||||
<span class="aksrt-product-page__option-label"><?php echo esc_html((string) ($group['name'] ?? '')); ?></span>
|
||||
<div class="aksrt-product-page__option-values aksrt-product-page__option-values--<?php echo esc_attr($group['view_mode'] ?? 'list'); ?>">
|
||||
<?php foreach ((array) ($group['values'] ?? []) as $val) : ?>
|
||||
<button type="button"
|
||||
class="aksrt-product-page__option-btn"
|
||||
data-option-group="<?php echo esc_attr((string) $group_idx); ?>"
|
||||
data-option-label="<?php echo esc_attr((string) ($val['label'] ?? '')); ?>"
|
||||
data-price-change="<?php echo esc_attr((string) ($val['price_change'] ?? 0)); ?>"
|
||||
<?php if (!empty($val['image'])) : ?>data-option-image="<?php echo esc_url($val['image']); ?>"<?php endif; ?>
|
||||
>
|
||||
<?php if (($group['view_mode'] ?? '') === 'img' && !empty($val['image'])) : ?>
|
||||
<img src="<?php echo esc_url($val['image']); ?>" alt="<?php echo esc_attr($val['label']); ?>">
|
||||
<?php endif; ?>
|
||||
<span><?php echo esc_html((string) ($val['label'] ?? '')); ?></span>
|
||||
<?php if ((float) ($val['price_change'] ?? 0) !== 0.0) : ?>
|
||||
<em><?php echo (float) $val['price_change'] > 0 ? '+' : ''; ?><?php echo esc_html(number_format((float) $val['price_change'], 2)); ?></em>
|
||||
<?php endif; ?>
|
||||
</button>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
<div class="aksrt-product-page__option-result" data-aksrt-option-result hidden>
|
||||
<span data-aksrt-selected-labels></span>
|
||||
<strong data-aksrt-resolved-price></strong>
|
||||
<span data-aksrt-resolved-stock></span>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- Meta info -->
|
||||
<dl class="aksrt-product-page__meta">
|
||||
<div>
|
||||
<dt><?php esc_html_e('库存', 'aksrt'); ?></dt>
|
||||
<dd data-aksrt-stock-display><?php
|
||||
$stock_val = (int) ($product['stock'] ?? 0);
|
||||
echo $stock_val <= -1 ? esc_html__('充足', 'aksrt') : esc_html((string) $stock_val);
|
||||
?></dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt><?php esc_html_e('配送', 'aksrt'); ?></dt>
|
||||
<dd><?php echo esc_html((string) (($product['shipping']['delivery_note'] ?? '') ?: __('标准配送', 'aksrt'))); ?></dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt><?php esc_html_e('运费', 'aksrt'); ?></dt>
|
||||
<dd><?php
|
||||
$ship_fee = (float) ($product['shipping']['fee'] ?? 0);
|
||||
echo $ship_fee > 0 ? '¥' . esc_html(number_format($ship_fee, 2)) : esc_html__('包邮', 'aksrt');
|
||||
?></dd>
|
||||
</div>
|
||||
</dl>
|
||||
|
||||
<!-- Params & Services quick links -->
|
||||
<?php if (!empty($params)) : ?>
|
||||
<button type="button" class="aksrt-product-page__info-trigger" data-aksrt-show-params>
|
||||
<i class="fas fa-list-ul"></i> <?php esc_html_e('商品参数', 'aksrt'); ?> <i class="fas fa-chevron-right"></i>
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
<?php if (!empty($services)) : ?>
|
||||
<button type="button" class="aksrt-product-page__info-trigger" data-aksrt-show-services>
|
||||
<i class="fas fa-shield-alt"></i> <?php esc_html_e('服务保障', 'aksrt'); ?> <i class="fas fa-chevron-right"></i>
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- Purchase box -->
|
||||
<div class="aksrt-product-page__purchase-box">
|
||||
<label class="aksrt-product-page__field">
|
||||
<span><?php esc_html_e('购买数量', 'aksrt'); ?></span>
|
||||
<div class="aksrt-product-page__quantity">
|
||||
<button type="button" class="aksrt-product-page__qty-btn" data-aksrt-qty-action="dec">-</button>
|
||||
<input type="number" min="1" max="<?php echo esc_attr((string) max(1, $stock_val > 0 ? $stock_val : 999)); ?>" value="1" class="aksrt-product-page__qty-input" data-aksrt-quantity>
|
||||
<button type="button" class="aksrt-product-page__qty-btn" data-aksrt-qty-action="inc">+</button>
|
||||
</div>
|
||||
</label>
|
||||
|
||||
<div class="aksrt-product-page__actions">
|
||||
<?php if (is_user_logged_in() && !empty($product['purchase_enabled'])) : ?>
|
||||
<button type="button" class="btn-outline btn-lg" data-aksrt-add-cart><?php esc_html_e('加入购物车', 'aksrt'); ?></button>
|
||||
<button type="button" class="btn-primary btn-lg" data-aksrt-buy-now>
|
||||
<?php echo $pay_modo === 'points' ? esc_html__('积分兑换', 'aksrt') : esc_html__('立即下单', 'aksrt'); ?>
|
||||
</button>
|
||||
<?php elseif (!is_user_logged_in()) : ?>
|
||||
<a href="<?php echo esc_url(function_exists('aksrt_get_login_url') ? aksrt_get_login_url() : wp_login_url(get_permalink())); ?>" class="btn-primary btn-lg">
|
||||
<?php esc_html_e('登录后购买', 'aksrt'); ?>
|
||||
</a>
|
||||
<?php else : ?>
|
||||
<button type="button" class="btn-primary btn-lg" disabled><?php esc_html_e('暂不可购买', 'aksrt'); ?></button>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<!-- Auxiliary actions -->
|
||||
<div class="aksrt-product-page__aux-actions">
|
||||
<button type="button" class="aksrt-product-page__aux-btn<?php echo $is_fav ? ' is-active' : ''; ?>" data-aksrt-toggle-fav="<?php echo esc_attr((string) $product_id); ?>">
|
||||
<i class="<?php echo $is_fav ? 'fas' : 'far'; ?> fa-heart"></i>
|
||||
<?php esc_html_e('收藏', 'aksrt'); ?>
|
||||
</button>
|
||||
<button type="button" class="aksrt-product-page__aux-btn" data-aksrt-share>
|
||||
<i class="fas fa-share-alt"></i> <?php esc_html_e('分享', 'aksrt'); ?>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Merchant info -->
|
||||
<?php if ($author) : ?>
|
||||
<div class="aksrt-product-page__merchant">
|
||||
<img src="<?php echo esc_url(function_exists('aksrt_get_avatar_url') ? aksrt_get_avatar_url($author_id) : get_avatar_url($author_id)); ?>" alt="" class="aksrt-product-page__merchant-avatar">
|
||||
<div>
|
||||
<strong><?php echo esc_html($author->display_name); ?></strong>
|
||||
<a href="<?php echo esc_url(get_author_posts_url($author_id)); ?>?tab=products" class="aksrt-product-page__merchant-link"><?php esc_html_e('进入店铺', 'aksrt'); ?></a>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<!-- Tabs: detail / reviews / custom -->
|
||||
<div class="aksrt-product-page__tabs">
|
||||
<nav class="aksrt-product-page__tab-nav">
|
||||
<button class="aksrt-product-page__tab-btn is-active" data-aksrt-tab="detail"><?php esc_html_e('商品详情', 'aksrt'); ?></button>
|
||||
<button class="aksrt-product-page__tab-btn" data-aksrt-tab="reviews">
|
||||
<?php esc_html_e('评价', 'aksrt'); ?>
|
||||
<?php if (($scores['total'] ?? 0) > 0) : ?>
|
||||
<em>(<?php echo esc_html((string) $scores['total']); ?>)</em>
|
||||
<?php endif; ?>
|
||||
</button>
|
||||
</nav>
|
||||
|
||||
<div class="aksrt-product-page__tab-panel is-active" data-aksrt-tab-panel="detail">
|
||||
<div class="aksrt-product-page__content">
|
||||
<?php echo wp_kses_post((string) ($product['content'] ?? '')); ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="aksrt-product-page__tab-panel" data-aksrt-tab-panel="reviews">
|
||||
<?php if (!empty($scores['total'])) : ?>
|
||||
<div class="aksrt-product-page__review-summary">
|
||||
<strong class="aksrt-product-page__review-avg"><?php echo esc_html((string) ($scores['average'] ?? '0')); ?></strong>
|
||||
<span class="aksrt-product-page__review-level"><?php echo esc_html((string) ($scores['level'] ?? '')); ?></span>
|
||||
<div class="aksrt-product-page__review-counts">
|
||||
<span><?php printf(esc_html__('好评 %d', 'aksrt'), (int) ($scores['good'] ?? 0)); ?></span>
|
||||
<span><?php printf(esc_html__('差评 %d', 'aksrt'), (int) ($scores['bad'] ?? 0)); ?></span>
|
||||
<span><?php printf(esc_html__('有图 %d', 'aksrt'), (int) ($scores['has_image'] ?? 0)); ?></span>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="aksrt-product-page__review-list" data-aksrt-review-list>
|
||||
<?php foreach (($reviews['items'] ?? []) as $review) : ?>
|
||||
<div class="aksrt-product-page__review-item">
|
||||
<div class="aksrt-product-page__review-header">
|
||||
<img src="<?php echo esc_url((string) ($review['user_avatar'] ?? '')); ?>" alt="" class="aksrt-product-page__review-avatar">
|
||||
<span class="aksrt-product-page__review-name"><?php echo esc_html((string) ($review['user_name'] ?? '')); ?></span>
|
||||
<span class="aksrt-product-page__review-date"><?php echo esc_html((string) ($review['date'] ?? '')); ?></span>
|
||||
<span class="aksrt-product-page__review-stars">
|
||||
<?php for ($s = 0; $s < 5; $s++) : ?>
|
||||
<i class="<?php echo $s < (int) ($review['rating_average'] ?? 0) ? 'fas' : 'far'; ?> fa-star"></i>
|
||||
<?php endfor; ?>
|
||||
</span>
|
||||
</div>
|
||||
<p class="aksrt-product-page__review-text"><?php echo esc_html((string) ($review['content'] ?? '')); ?></p>
|
||||
<?php if (!empty($review['images'])) : ?>
|
||||
<div class="aksrt-product-page__review-images">
|
||||
<?php foreach ((array) $review['images'] as $rimg) : ?>
|
||||
<img src="<?php echo esc_url($rimg); ?>" alt="" class="aksrt-product-page__review-img">
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
|
||||
<?php if (empty($reviews['items'])) : ?>
|
||||
<p class="aksrt-product-page__review-empty"><?php esc_html_e('暂无评价', 'aksrt'); ?></p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Related products -->
|
||||
<?php
|
||||
$related_query = new WP_Query([
|
||||
'post_type' => 'aksrt_product',
|
||||
'posts_per_page' => 6,
|
||||
'post_status' => 'publish',
|
||||
'post__not_in' => [$product_id],
|
||||
'tax_query' => !empty($product['categories']) ? [[
|
||||
'taxonomy' => 'aksrt_product_cat',
|
||||
'field' => 'term_id',
|
||||
'terms' => wp_list_pluck($product['categories'], 'term_id'),
|
||||
]] : [],
|
||||
'orderby' => 'rand',
|
||||
]);
|
||||
?>
|
||||
<?php if ($related_query->have_posts()) : ?>
|
||||
<section class="aksrt-product-page__related">
|
||||
<h2><?php esc_html_e('相关推荐', 'aksrt'); ?></h2>
|
||||
<div class="aksrt-product-page__related-grid">
|
||||
<?php while ($related_query->have_posts()) : $related_query->the_post(); ?>
|
||||
<a href="<?php echo esc_url(get_permalink()); ?>" class="aksrt-product-page__related-card">
|
||||
<?php $thumb = $shop ? $shop->resolve_main_image(get_the_ID()) : get_the_post_thumbnail_url(get_the_ID(), 'medium'); ?>
|
||||
<?php if ($thumb) : ?>
|
||||
<img src="<?php echo esc_url($thumb); ?>" alt="<?php the_title_attribute(); ?>" loading="lazy">
|
||||
<?php endif; ?>
|
||||
<h3><?php the_title(); ?></h3>
|
||||
<strong>¥<?php echo esc_html(number_format((float) get_post_meta(get_the_ID(), '_aksrt_price', true), 2)); ?></strong>
|
||||
</a>
|
||||
<?php endwhile; wp_reset_postdata(); ?>
|
||||
</div>
|
||||
</section>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<!-- Params modal -->
|
||||
<?php if (!empty($params)) : ?>
|
||||
<div class="aksrt-modal" data-aksrt-params-modal hidden>
|
||||
<div class="aksrt-modal__overlay"></div>
|
||||
<div class="aksrt-modal__dialog">
|
||||
<div class="aksrt-modal__header">
|
||||
<h3><?php esc_html_e('商品参数', 'aksrt'); ?></h3>
|
||||
<button type="button" class="aksrt-modal__close" data-aksrt-modal-close>×</button>
|
||||
</div>
|
||||
<div class="aksrt-modal__body">
|
||||
<table class="aksrt-product-page__params-table">
|
||||
<?php foreach ($params as $param) : ?>
|
||||
<tr>
|
||||
<th><?php echo esc_html((string) ($param['name'] ?? '')); ?></th>
|
||||
<td><?php echo esc_html((string) ($param['value'] ?? '')); ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- Services modal -->
|
||||
<?php if (!empty($services)) : ?>
|
||||
<div class="aksrt-modal" data-aksrt-services-modal hidden>
|
||||
<div class="aksrt-modal__overlay"></div>
|
||||
<div class="aksrt-modal__dialog">
|
||||
<div class="aksrt-modal__header">
|
||||
<h3><?php esc_html_e('服务保障', 'aksrt'); ?></h3>
|
||||
<button type="button" class="aksrt-modal__close" data-aksrt-modal-close>×</button>
|
||||
</div>
|
||||
<div class="aksrt-modal__body">
|
||||
<?php foreach ($services as $service) : ?>
|
||||
<div class="aksrt-product-page__service-item">
|
||||
<?php if (!empty($service['icon'])) : ?>
|
||||
<img src="<?php echo esc_url($service['icon']); ?>" alt="" class="aksrt-product-page__service-icon">
|
||||
<?php else : ?>
|
||||
<i class="fas fa-check-circle"></i>
|
||||
<?php endif; ?>
|
||||
<div>
|
||||
<strong><?php echo esc_html((string) ($service['name'] ?? '')); ?></strong>
|
||||
<?php if (!empty($service['desc'])) : ?>
|
||||
<p><?php echo esc_html((string) $service['desc']); ?></p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- Mobile purchase tabbar -->
|
||||
<div class="aksrt-product-page__mobile-bar" data-aksrt-mobile-purchase>
|
||||
<button type="button" class="aksrt-product-page__mobile-btn" data-aksrt-toggle-fav="<?php echo esc_attr((string) $product_id); ?>">
|
||||
<i class="<?php echo $is_fav ? 'fas' : 'far'; ?> fa-heart"></i>
|
||||
</button>
|
||||
<button type="button" class="aksrt-product-page__mobile-btn" data-aksrt-add-cart>
|
||||
<i class="fas fa-shopping-cart"></i>
|
||||
</button>
|
||||
<button type="button" class="aksrt-product-page__mobile-buy btn-primary" data-aksrt-buy-now>
|
||||
<?php echo $pay_modo === 'points' ? esc_html__('积分兑换', 'aksrt') : esc_html__('立即购买', 'aksrt'); ?>
|
||||
</button>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<div class="aksrt-product-page container">
|
||||
<div class="aksrt-product-page__empty">
|
||||
<i class="fas fa-box-open" aria-hidden="true"></i>
|
||||
<p><?php esc_html_e('商品不存在或已下架。', 'aksrt'); ?></p>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</main>
|
||||
|
||||
<?php get_footer(); ?>
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
/**
|
||||
* Template Name: AKSRT - Register
|
||||
* Template Post Type: page
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
require AKSRT_DIR . '/templates/pages/page-sign.php';
|
||||
@@ -0,0 +1,172 @@
|
||||
<?php
|
||||
/**
|
||||
* Template Name: AKSRT - Reset Password
|
||||
* Template Post Type: page
|
||||
*
|
||||
* Theme auth route template: /reset-password/
|
||||
*
|
||||
* 统一处理:
|
||||
* 1. 忘记密码(无 token 参数)— 输入邮箱/用户名请求重置
|
||||
* 2. 设置密码(有 token+uid 参数)— 邮件链接进入后设置新密码
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
// ============================================
|
||||
// 检测当前模式:设置密码 or 请求重置
|
||||
// ============================================
|
||||
$context = AKSRT_Auth_Service::get_reset_context($_GET);
|
||||
$mode = $context['mode'];
|
||||
$errors = [];
|
||||
$success = '';
|
||||
$token = $context['token'];
|
||||
$user_id = $context['user_id'];
|
||||
|
||||
if (!empty($context['error'])) {
|
||||
$errors[] = $context['error'];
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// 处理表单提交
|
||||
// ============================================
|
||||
|
||||
// 模式1:请求重置密码(忘记密码表单提交)
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['aksrt_action']) && $_POST['aksrt_action'] === 'request_reset') {
|
||||
$result = AKSRT_Auth_Service::request_password_reset($_POST);
|
||||
if (!empty($result['success'])) {
|
||||
$success = $result['message'] ?? __('如果该账号存在,重置邮件已发送到注册邮箱', 'aksrt');
|
||||
} else {
|
||||
$errors[] = $result['error'] ?? __('重置请求失败,请稍后重试', 'aksrt');
|
||||
}
|
||||
}
|
||||
|
||||
// 模式2:设置新密码(从邮件链接进入)
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['aksrt_action']) && $_POST['aksrt_action'] === 'set_password') {
|
||||
$result = AKSRT_Auth_Service::reset_password_with_token($_POST);
|
||||
if (!empty($result['success'])) {
|
||||
$mode = 'success';
|
||||
$success = $result['message'] ?? __('密码已设置成功!', 'aksrt');
|
||||
} else {
|
||||
$errors[] = $result['error'] ?? __('重置密码失败,请稍后重试', 'aksrt');
|
||||
$mode = $result['mode'] ?? 'invalid';
|
||||
}
|
||||
}
|
||||
|
||||
get_header();
|
||||
?>
|
||||
|
||||
<main id="main-content" class="site-main" tabindex="-1">
|
||||
<div class="auth-shell">
|
||||
<div class="auth-card">
|
||||
<div class="auth-card__logo" aria-hidden="true">AK</div>
|
||||
<h1 class="auth-card__title"><?php bloginfo('name'); ?></h1>
|
||||
|
||||
<?php if ($mode === 'success') : ?>
|
||||
<!-- 密码设置成功 -->
|
||||
<p class="auth-card__subtitle"><?php esc_html_e('密码设置成功!', 'aksrt'); ?></p>
|
||||
<div class="alert alert--success" role="alert">
|
||||
<span><?php echo esc_html($success); ?></span>
|
||||
</div>
|
||||
<a href="<?php echo esc_url(aksrt_get_login_url()); ?>" class="btn-primary btn-lg" style="width:100%;display:block;text-align:center;text-decoration:none;margin-top:16px;">
|
||||
<?php esc_html_e('立即登录', 'aksrt'); ?>
|
||||
</a>
|
||||
|
||||
<?php elseif ($mode === 'invalid') : ?>
|
||||
<!-- 链接无效或已过期 -->
|
||||
<p class="auth-card__subtitle"><?php esc_html_e('重置链接无效或已过期', 'aksrt'); ?></p>
|
||||
<?php if (!empty($errors)) : ?>
|
||||
<div class="alert alert--error" role="alert">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="10"/><line x1="12" x2="12" y1="8" y2="12"/><line x1="12" x2="12.01" y1="16" y2="16"/></svg>
|
||||
<span><?php echo esc_html($errors[0]); ?></span>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<a href="<?php echo esc_url(aksrt_get_reset_password_url()); ?>" class="btn-primary btn-lg" style="width:100%;display:block;text-align:center;text-decoration:none;margin-top:16px;">
|
||||
<?php esc_html_e('重新申请重置密码', 'aksrt'); ?>
|
||||
</a>
|
||||
|
||||
<?php elseif ($mode === 'reset') : ?>
|
||||
<!-- 设置新密码表单 -->
|
||||
<p class="auth-card__subtitle"><?php esc_html_e('请设置你的新密码', 'aksrt'); ?></p>
|
||||
|
||||
<?php if (!empty($errors)) : ?>
|
||||
<div class="alert alert--error" role="alert">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="10"/><line x1="12" x2="12" y1="8" y2="12"/><line x1="12" x2="12.01" y1="16" y2="16"/></svg>
|
||||
<span><?php echo esc_html($errors[0]); ?></span>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<form class="auth-form" id="aksrt-set-password-form" method="post" action="">
|
||||
<?php wp_nonce_field('aksrt_set_password', '_setpw_nonce'); ?>
|
||||
<input type="hidden" name="aksrt_action" value="set_password">
|
||||
<input type="hidden" name="reset_token" value="<?php echo esc_attr($token); ?>">
|
||||
<input type="hidden" name="reset_uid" value="<?php echo esc_attr((string) $user_id); ?>">
|
||||
|
||||
<div class="form-field form-field--pwd">
|
||||
<label for="pass1"><?php esc_html_e('新密码', 'aksrt'); ?></label>
|
||||
<div class="input-wrap">
|
||||
<span class="input-icon" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="width:18px;height:18px;"><rect width="18" height="11" x="3" y="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg></span>
|
||||
<input type="password" name="pass1" id="pass1" autocomplete="new-password" required minlength="6">
|
||||
<button type="button" class="toggle-pwd" data-target="pass1" aria-label="<?php esc_attr_e('显示或隐藏密码', 'aksrt'); ?>"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="width:16px;height:16px;"><path d="M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7Z"/><circle cx="12" cy="12" r="3"/></svg></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-field form-field--pwd">
|
||||
<label for="pass2"><?php esc_html_e('确认新密码', 'aksrt'); ?></label>
|
||||
<div class="input-wrap">
|
||||
<span class="input-icon" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="width:18px;height:18px;"><rect width="18" height="11" x="3" y="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg></span>
|
||||
<input type="password" name="pass2" id="pass2" autocomplete="new-password" required minlength="6">
|
||||
<button type="button" class="toggle-pwd" data-target="pass2" aria-label="<?php esc_attr_e('显示或隐藏密码', 'aksrt'); ?>"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="width:16px;height:16px;"><path d="M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7Z"/><circle cx="12" cy="12" r="3"/></svg></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn-primary btn-lg btn-block"><?php esc_html_e('设置新密码', 'aksrt'); ?></button>
|
||||
</form>
|
||||
|
||||
<?php else : ?>
|
||||
<!-- 请求重置密码表单(忘记密码) -->
|
||||
<p class="auth-card__subtitle"><?php esc_html_e('输入邮箱或用户名,我们将发送重置链接', 'aksrt'); ?></p>
|
||||
|
||||
<?php if (!empty($errors)) : ?>
|
||||
<div class="alert alert--error" role="alert">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="10"/><line x1="12" x2="12" y1="8" y2="12"/><line x1="12" x2="12.01" y1="16" y2="16"/></svg>
|
||||
<span><?php echo esc_html($errors[0]); ?></span>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!empty($success)) : ?>
|
||||
<div class="alert alert--success" role="alert">
|
||||
<span><?php echo esc_html($success); ?></span>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<form class="auth-form" id="aksrt-request-reset-form" method="post" action="">
|
||||
<?php wp_nonce_field('aksrt_reset_password', '_reset_nonce'); ?>
|
||||
<input type="hidden" name="aksrt_action" value="request_reset">
|
||||
|
||||
<div class="form-field">
|
||||
<label for="user_login"><?php esc_html_e('邮箱 / 用户名', 'aksrt'); ?></label>
|
||||
<div class="input-wrap">
|
||||
<span class="input-icon" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="width:18px;height:18px;"><rect width="20" height="16" x="2" y="4" rx="2"/><path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7"/></svg></span>
|
||||
<input type="text" name="user_login" id="user_login" autocomplete="username" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php aksrt_render_captcha('lostpassword'); ?>
|
||||
|
||||
<button type="submit" class="btn-primary btn-lg btn-block"><?php esc_html_e('发送重置链接', 'aksrt'); ?></button>
|
||||
</form>
|
||||
|
||||
<p class="auth-footer-link">
|
||||
<?php esc_html_e('想起密码了?', 'aksrt'); ?>
|
||||
<a href="<?php echo esc_url(aksrt_get_login_url()); ?>"><?php esc_html_e('返回登录', 'aksrt'); ?></a>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<?php
|
||||
get_footer();
|
||||
@@ -0,0 +1,127 @@
|
||||
<?php
|
||||
/**
|
||||
* Template Name: AKSRT - Revenue
|
||||
* Template Post Type: page
|
||||
*
|
||||
* 创作者收益中心页面 — 显示收益概览、分成记录和提现入口
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
get_header();
|
||||
|
||||
if (!is_user_logged_in()) {
|
||||
$login_url = function_exists('aksrt_get_login_url') ? aksrt_get_login_url() : wp_login_url(get_permalink());
|
||||
wp_safe_redirect($login_url);
|
||||
exit;
|
||||
}
|
||||
|
||||
$user_id = get_current_user_id();
|
||||
|
||||
// 通过 helper 获取收益视图模型
|
||||
$revenue_view = function_exists('aksrt_get_revenue_page_view')
|
||||
? aksrt_get_revenue_page_view($user_id)
|
||||
: ['balance' => 0, 'total_earned' => 0, 'total_withdrawn' => 0, 'records' => []];
|
||||
|
||||
$balance = (float) ($revenue_view['balance'] ?? 0);
|
||||
$total_earned = (float) ($revenue_view['total_earned'] ?? 0);
|
||||
$total_withdrawn = (float) ($revenue_view['total_withdrawn'] ?? 0);
|
||||
$records = $revenue_view['records'] ?? [];
|
||||
|
||||
$per_page = 20;
|
||||
$paged = max(1, (int) ($_GET['rev_page'] ?? 1));
|
||||
$total_records = count($records);
|
||||
$total_pages = max(1, (int) ceil($total_records / $per_page));
|
||||
$paged_records = array_slice($records, ($paged - 1) * $per_page, $per_page);
|
||||
?>
|
||||
|
||||
<div class="container aksrt-revenue-page">
|
||||
<div class="aksrt-revenue-page__header">
|
||||
<h2><?php esc_html_e('创作收益', 'aksrt'); ?></h2>
|
||||
</div>
|
||||
|
||||
<!-- 收益概览 -->
|
||||
<div class="aksrt-revenue-page__stats">
|
||||
<div class="aksrt-revenue-page__stat-card">
|
||||
<div class="aksrt-revenue-page__stat-icon"><i class="fas fa-wallet"></i></div>
|
||||
<div class="aksrt-revenue-page__stat-info">
|
||||
<span class="aksrt-revenue-page__stat-value">¥<?php echo esc_html(number_format($balance, 2)); ?></span>
|
||||
<span class="aksrt-revenue-page__stat-label"><?php esc_html_e('可提现余额', 'aksrt'); ?></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="aksrt-revenue-page__stat-card">
|
||||
<div class="aksrt-revenue-page__stat-icon"><i class="fas fa-chart-line"></i></div>
|
||||
<div class="aksrt-revenue-page__stat-info">
|
||||
<span class="aksrt-revenue-page__stat-value">¥<?php echo esc_html(number_format($total_earned, 2)); ?></span>
|
||||
<span class="aksrt-revenue-page__stat-label"><?php esc_html_e('累计收益', 'aksrt'); ?></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="aksrt-revenue-page__stat-card">
|
||||
<div class="aksrt-revenue-page__stat-icon"><i class="fas fa-money-check-alt"></i></div>
|
||||
<div class="aksrt-revenue-page__stat-info">
|
||||
<span class="aksrt-revenue-page__stat-value">¥<?php echo esc_html(number_format($total_withdrawn, 2)); ?></span>
|
||||
<span class="aksrt-revenue-page__stat-label"><?php esc_html_e('已提现', 'aksrt'); ?></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 提现按钮 -->
|
||||
<?php if ($balance > 0) : ?>
|
||||
<div class="aksrt-revenue-page__actions">
|
||||
<a href="<?php echo esc_url(add_query_arg(['action' => 'withdraw'])); ?>" class="aksrt-revenue-page__withdraw-btn">
|
||||
<i class="fas fa-hand-holding-usd"></i> <?php esc_html_e('申请提现', 'aksrt'); ?>
|
||||
</a>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- 分成记录 -->
|
||||
<div class="aksrt-revenue-page__section">
|
||||
<h3><?php esc_html_e('收益明细', 'aksrt'); ?></h3>
|
||||
|
||||
<?php if (!empty($paged_records)) : ?>
|
||||
<div class="aksrt-revenue-page__list">
|
||||
<?php foreach ($paged_records as $record) :
|
||||
$r_type = (string) ($record['type'] ?? 'earning');
|
||||
?>
|
||||
<div class="aksrt-revenue-page__item">
|
||||
<div class="aksrt-revenue-page__item-icon">
|
||||
<i class="<?php echo $r_type === 'withdrawal' ? 'fas fa-arrow-up' : 'fas fa-arrow-down'; ?>"
|
||||
style="color: <?php echo $r_type === 'withdrawal' ? '#f5222d' : '#52c41a'; ?>;"></i>
|
||||
</div>
|
||||
<div class="aksrt-revenue-page__item-info">
|
||||
<span class="aksrt-revenue-page__item-title"><?php echo esc_html($record['title'] ?? ''); ?></span>
|
||||
<span class="aksrt-revenue-page__item-time"><?php echo esc_html($record['created_at'] ?? ''); ?></span>
|
||||
</div>
|
||||
<div class="aksrt-revenue-page__item-amount" style="color: <?php echo $r_type === 'withdrawal' ? '#f5222d' : '#52c41a'; ?>;">
|
||||
<?php echo $r_type === 'withdrawal' ? '-' : '+'; ?>¥<?php echo esc_html(number_format((float) ($record['amount'] ?? 0), 2)); ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
|
||||
<?php if ($total_pages > 1) : ?>
|
||||
<div class="aksrt-revenue-page__pagination">
|
||||
<?php for ($i = 1; $i <= $total_pages; $i++) :
|
||||
$page_url = add_query_arg(['rev_page' => $i]);
|
||||
?>
|
||||
<?php if ($i === $paged) : ?>
|
||||
<span class="aksrt-revenue-page__page-chip is-active"><?php echo esc_html((string) $i); ?></span>
|
||||
<?php else : ?>
|
||||
<a href="<?php echo esc_url($page_url); ?>" class="aksrt-revenue-page__page-chip"><?php echo esc_html((string) $i); ?></a>
|
||||
<?php endif; ?>
|
||||
<?php endfor; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php else : ?>
|
||||
<div class="aksrt-revenue-page__empty">
|
||||
<i class="fas fa-chart-pie"></i>
|
||||
<p><?php esc_html_e('暂无收益记录', 'aksrt'); ?></p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php get_footer(); ?>
|
||||
@@ -0,0 +1,345 @@
|
||||
<?php
|
||||
/**
|
||||
* Template Name: AKSRT - 登录/注册
|
||||
* Template Post Type: page
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
@session_start();
|
||||
|
||||
$route_tab = function_exists('aksrt_get_auth_tab') ? aksrt_get_auth_tab() : 'login';
|
||||
$requested_tab = isset($_GET['tab']) ? sanitize_text_field(wp_unslash((string) $_GET['tab'])) : '';
|
||||
$tab_aliases = [
|
||||
'login' => 'signin',
|
||||
'signin' => 'signin',
|
||||
'register' => 'signup',
|
||||
'signup' => 'signup',
|
||||
];
|
||||
$tab_source = $requested_tab !== '' ? $requested_tab : $route_tab;
|
||||
$tab = $tab_aliases[$tab_source] ?? 'signin';
|
||||
$redirect_to = !empty($_GET['redirect_to']) ? esc_url_raw(wp_unslash((string) $_GET['redirect_to'])) : home_url();
|
||||
$registration_open = class_exists('AKSRT_Settings') && AKSRT_Settings::registration_enabled();
|
||||
|
||||
$titles = [
|
||||
'signin' => __('用户登录', 'aksrt'),
|
||||
'signup' => __('用户注册', 'aksrt'),
|
||||
];
|
||||
$page_title = ($titles[$tab] ?? __('登录 / 注册', 'aksrt')) . ' - ' . get_bloginfo('name');
|
||||
|
||||
$interim = isset($_REQUEST['interim-login']);
|
||||
|
||||
// 搂4.1 Defense-in-depth: redirect out when close_sign is active (backup of auth router gate)
|
||||
if (class_exists('AKSRT_Settings') && AKSRT_Settings::close_sign() && !is_user_logged_in() && !$interim) {
|
||||
wp_safe_redirect(home_url('/'), 302);
|
||||
exit;
|
||||
}
|
||||
|
||||
// §4.1 close_signin: password login disabled — force signin tab to show social-only message
|
||||
$close_signin = class_exists('AKSRT_Settings') ? AKSRT_Settings::close_signin() : false;
|
||||
if ($close_signin && $tab === 'signin') {
|
||||
// Don't allow password form submission
|
||||
$_SERVER['REQUEST_METHOD'] = 'GET';
|
||||
}
|
||||
|
||||
$user_id = get_current_user_id();
|
||||
if ($user_id) {
|
||||
if ($interim && is_super_admin()) {
|
||||
echo '<!DOCTYPE HTML><html><body class="login interim-login-success"><div style="padding:60px 0;text-align:center;color:#1a88fd;">' . esc_html__('登录成功', 'aksrt') . '</div></body></html>';
|
||||
exit;
|
||||
}
|
||||
wp_safe_redirect($redirect_to);
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($tab === 'signup' && !$registration_open) {
|
||||
$tab = 'signin';
|
||||
}
|
||||
|
||||
remove_action('wp_footer', 'aksrt_render_footer_tabbar', 20);
|
||||
remove_action('wp_footer', 'aksrt_render_float_buttons', 30);
|
||||
|
||||
$background_html = '';
|
||||
$sign_ui = class_exists('AKSRT_Settings') ? AKSRT_Settings::sign_page_ui() : [];
|
||||
$card_position = $sign_ui['card_position'] ?? 'center';
|
||||
$sign_show_logo = $sign_ui['show_logo'] ?? true;
|
||||
$sign_show_header = $sign_ui['show_header'] ?? true;
|
||||
$sign_theme_mode = $sign_ui['theme_mode'] ?? 'default';
|
||||
if (class_exists('AKSRT_Settings')) {
|
||||
$bg_ids = $sign_ui['background'] ?? [];
|
||||
if (is_array($bg_ids) && !empty($bg_ids)) {
|
||||
$bg_url = wp_get_attachment_url((int) $bg_ids[array_rand($bg_ids)]);
|
||||
if ($bg_url) {
|
||||
$background_html = '<div class="sign-bg" style="background-image:url(' . esc_url($bg_url) . ');"></div>';
|
||||
}
|
||||
} elseif (is_string($bg_ids) && $bg_ids !== '') {
|
||||
// BC: comma-separated string from old storage
|
||||
$ids = array_filter(array_map('absint', explode(',', $bg_ids)));
|
||||
if (!empty($ids)) {
|
||||
$bg_url = wp_get_attachment_url($ids[array_rand($ids)]);
|
||||
if ($bg_url) {
|
||||
$background_html = '<div class="sign-bg" style="background-image:url(' . esc_url($bg_url) . ');"></div>';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$login_error = '';
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['log'], $_POST['pwd']) && $tab === 'signin') {
|
||||
if (class_exists('AKSRT_Auth_Service')) {
|
||||
$result = AKSRT_Auth_Service::login_user($_POST, false);
|
||||
if (empty($result['success'])) {
|
||||
$login_error = $result['error'] ?? __('登录失败', 'aksrt');
|
||||
} else {
|
||||
wp_safe_redirect($result['redirect'] ?? home_url('/'));
|
||||
exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$register_error = '';
|
||||
$register_success = '';
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['user_login'], $_POST['user_email']) && $tab === 'signup') {
|
||||
if (class_exists('AKSRT_Auth_Service')) {
|
||||
$result = AKSRT_Auth_Service::register_user($_POST, ['oauth_bind_data' => null, 'obk' => '']);
|
||||
if (!empty($result['success'])) {
|
||||
if (!empty($result['verification_required'])) {
|
||||
$register_success = sprintf(
|
||||
'%s <a href="%s">%s</a>',
|
||||
esc_html($result['message'] ?? __('Registration successful. Please complete email verification.', 'aksrt')),
|
||||
esc_url($result['verify_url'] ?? ''),
|
||||
esc_html__('前往验证', 'aksrt')
|
||||
);
|
||||
} else {
|
||||
$register_success = sprintf(
|
||||
__('Registration successful. Please continue on the <a href="%s">login page</a>.', 'aksrt'),
|
||||
esc_url(aksrt_get_login_url())
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$register_error = $result['error'] ?? __('注册失败', 'aksrt');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$invite_prefill = '';
|
||||
if (!empty($_GET['invite'])) {
|
||||
$invite_prefill = sanitize_key(wp_unslash($_GET['invite']));
|
||||
} elseif (!empty($_COOKIE['aksrt_invite'])) {
|
||||
$invite_prefill = sanitize_key(wp_unslash($_COOKIE['aksrt_invite']));
|
||||
}
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="<?php echo esc_attr(str_replace('_', '-', get_bloginfo('language'))); ?>">
|
||||
<head>
|
||||
<meta charset="<?php bloginfo('charset'); ?>">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0">
|
||||
<meta name="robots" content="noindex, nofollow">
|
||||
<title><?php echo esc_html($page_title); ?></title>
|
||||
<?php wp_head(); ?>
|
||||
<style>
|
||||
.sign-page{min-height:100vh;display:flex;align-items:center;justify-content:center;position:relative;padding:70px 16px 40px}
|
||||
.sign-bg{position:fixed;inset:0;background-repeat:no-repeat;background-size:cover;background-position:center;z-index:0}
|
||||
.sign-card{position:relative;z-index:1;width:100%;max-width:420px;background:var(--main-bg-color,#fff);border-radius:var(--main-radius,8px);box-shadow:0 0 10px var(--main-shadow,rgba(116,116,116,0.08));padding:30px 35px}
|
||||
.sign-card--left{margin-right:auto}
|
||||
.sign-card--right{margin-left:auto}
|
||||
.sign-card--center{margin:0 auto}
|
||||
.sign-logo{text-align:center;margin-bottom:20px}
|
||||
.sign-logo img{height:36px}
|
||||
.sign-logo__text{display:inline-flex;align-items:center;justify-content:center;width:48px;height:48px;border-radius:12px;background:var(--focus-color,#f04494);color:#fff;font-size:18px;font-weight:700;text-decoration:none}
|
||||
.sign-tabs{display:flex;border-bottom:2px solid var(--main-border-color,rgba(50,50,50,0.06));margin-bottom:20px}
|
||||
.sign-tab{flex:1;padding:10px 0;border:none;background:none;font-size:15px;cursor:pointer;color:var(--muted-color,#777);border-bottom:2px solid transparent;margin-bottom:-2px;transition:all .2s;text-align:center;font-weight:500}
|
||||
.sign-tab.is-active{color:var(--focus-color,#f04494);border-bottom-color:var(--focus-color,#f04494);font-weight:600}
|
||||
.sign-tab:hover{color:var(--focus-color,#f04494)}
|
||||
.sign-panel{display:none}
|
||||
.sign-panel.is-active{display:block}
|
||||
.sign-error{background:rgba(239,68,68,0.08);border:1px solid rgba(239,68,68,0.2);border-radius:var(--main-radius,8px);padding:10px 14px;font-size:13px;color:#ef4444;margin-bottom:16px}
|
||||
.sign-success{background:rgba(16,185,129,0.08);border:1px solid rgba(16,185,129,0.2);border-radius:var(--main-radius,8px);padding:10px 14px;font-size:13px;color:#10b981;margin-bottom:16px}
|
||||
.sign-form{display:flex;flex-direction:column;gap:16px}
|
||||
.sign-form .form-field{display:flex;flex-direction:column;gap:6px}
|
||||
.sign-form label{font-size:14px;font-weight:500;color:var(--main-color,#4e5358)}
|
||||
.sign-form .input-wrap{position:relative}
|
||||
.sign-form .input-wrap input{width:100%;height:44px;padding:0 14px;border:1px solid transparent;background:var(--body-bg-color,#f5f6f7);border-radius:var(--main-radius,8px);font-size:14px;color:var(--key-color,#333);transition:border-color .15s}
|
||||
.sign-form .input-wrap input:focus{outline:none;border-color:var(--focus-color,#f04494);box-shadow:0 0 2px 3px var(--focus-shadow-color,rgba(253,83,161,0.4))}
|
||||
.sign-form .toggle-pwd{position:absolute;right:10px;top:50%;transform:translateY(-50%);background:none;border:none;cursor:pointer;color:var(--muted-2-color,#999);padding:4px}
|
||||
.sign-form .form-row-between{display:flex;align-items:center;justify-content:space-between;font-size:13px}
|
||||
.sign-form .form-row-between a{color:var(--focus-color,#f04494)}
|
||||
.sign-form .form-row-between label{display:flex;align-items:center;gap:6px;cursor:pointer;font-size:13px;color:var(--muted-color,#777)}
|
||||
.sign-form .btn-submit{width:100%;height:44px;border:none;border-radius:var(--main-radius,8px);background:var(--focus-color,#f04494);color:#fff;font-size:15px;font-weight:600;cursor:pointer;transition:opacity .15s}
|
||||
.sign-form .btn-submit:hover{opacity:.85}
|
||||
.sign-form .btn-submit:disabled{opacity:.5;cursor:not-allowed}
|
||||
.sign-hint{margin:0;font-size:13px;color:var(--muted-color,#777)}
|
||||
.sign-terms{display:flex;align-items:flex-start;gap:8px;font-size:13px;cursor:pointer;color:var(--muted-color,#777)}
|
||||
.sign-footer{text-align:center;margin-top:20px;font-size:14px;color:var(--muted-color,#777)}
|
||||
.sign-footer a{color:var(--focus-color,#f04494)}
|
||||
.sign-footer-bar{position:fixed;bottom:0;left:0;right:0;text-align:center;padding:10px;font-size:12px;color:var(--muted-2-color,#999);z-index:1}
|
||||
@media(max-width:480px){.sign-card{padding:24px 20px}}
|
||||
</style>
|
||||
</head>
|
||||
<body <?php body_class('page-template-user-sign' . ($sign_theme_mode !== 'default' ? ' sign-theme-' . esc_attr($sign_theme_mode) : '')); ?>>
|
||||
<?php echo $background_html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||||
<main class="sign-page">
|
||||
<div class="sign-card sign-card--<?php echo esc_attr($card_position); ?>">
|
||||
<?php if ($sign_show_logo) : ?>
|
||||
<div class="sign-logo">
|
||||
<?php $logo_url = class_exists('AKSRT_Settings') ? AKSRT_Settings::user_logo_url() : ''; ?>
|
||||
<?php if ($logo_url) : ?>
|
||||
<a href="<?php echo esc_url(home_url('/')); ?>"><img src="<?php echo esc_url($logo_url); ?>" alt="<?php echo esc_attr(get_bloginfo('name')); ?>"></a>
|
||||
<?php else : ?>
|
||||
<a href="<?php echo esc_url(home_url('/')); ?>" class="sign-logo__text"><?php echo esc_html(mb_substr(get_bloginfo('name'), 0, 2)); ?></a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($sign_show_header) : ?>
|
||||
<div class="sign-tabs">
|
||||
<button type="button" class="sign-tab<?php echo $tab === 'signin' ? ' is-active' : ''; ?>" data-sign-tab="signin"><?php esc_html_e('登录', 'aksrt'); ?></button>
|
||||
<?php if ($registration_open) : ?>
|
||||
<button type="button" class="sign-tab<?php echo $tab === 'signup' ? ' is-active' : ''; ?>" data-sign-tab="signup"><?php esc_html_e('注册', 'aksrt'); ?></button>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="sign-panel<?php echo $tab === 'signin' ? ' is-active' : ''; ?>" data-sign-panel="signin">
|
||||
<?php if ($login_error) : ?><div class="sign-error"><?php echo esc_html($login_error); ?></div><?php endif; ?>
|
||||
<?php if ($close_signin) : ?>
|
||||
<div class="sign-notice" style="padding:16px;text-align:center;color:var(--muted-2-color,#666);">
|
||||
<?php esc_html_e('This site currently supports third-party account sign-in only. Please use one of the social login buttons below.', 'aksrt'); ?>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<form class="sign-form" id="sign-login-form" method="post" action="">
|
||||
<?php wp_nonce_field('aksrt_login', '_login_nonce'); ?>
|
||||
<div class="form-field">
|
||||
<label for="sign-user-login"><?php esc_html_e('Email / Username', 'aksrt'); ?></label>
|
||||
<div class="input-wrap"><input type="text" name="log" id="sign-user-login" autocomplete="username" required placeholder="<?php esc_attr_e('Please enter your email or username', 'aksrt'); ?>"></div>
|
||||
</div>
|
||||
<div class="form-field">
|
||||
<label for="sign-user-pass"><?php esc_html_e('密码', 'aksrt'); ?></label>
|
||||
<div class="input-wrap">
|
||||
<input type="password" name="pwd" id="sign-user-pass" autocomplete="current-password" required>
|
||||
<button type="button" class="toggle-pwd" data-target="sign-user-pass"><i class="fas fa-eye"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row-between">
|
||||
<label><input type="checkbox" name="rememberme" value="forever"> <?php esc_html_e('Remember me', 'aksrt'); ?></label>
|
||||
<a href="<?php echo esc_url(aksrt_get_reset_password_url()); ?>"><?php esc_html_e('Forgot password?', 'aksrt'); ?></a>
|
||||
</div>
|
||||
<?php if (function_exists('aksrt_render_captcha')) aksrt_render_captcha('login'); ?>
|
||||
<input type="hidden" name="redirect_to" value="<?php echo esc_url($redirect_to); ?>">
|
||||
<button type="submit" class="btn-submit"><?php esc_html_e('登录', 'aksrt'); ?></button>
|
||||
</form>
|
||||
<?php endif; // close_signin gate ?>
|
||||
<?php if (class_exists('AKSRT_OAuth')) : ?>
|
||||
<?php $social = AKSRT_OAuth::get_instance()->render_social_buttons(); ?>
|
||||
<?php if ($social) echo '<div style="margin-top:20px;">' . $social . '</div>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||||
<?php endif; ?>
|
||||
<?php if ($registration_open) : ?>
|
||||
<div class="sign-footer"><?php esc_html_e('Don\'t have an account yet?', 'aksrt'); ?> <a href="#" data-sign-switch="signup"><?php esc_html_e('Register now', 'aksrt'); ?></a></div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<?php if ($registration_open) : ?>
|
||||
<div class="sign-panel<?php echo $tab === 'signup' ? ' is-active' : ''; ?>" data-sign-panel="signup">
|
||||
<?php if ($register_error) : ?><div class="sign-error"><?php echo esc_html($register_error); ?></div><?php endif; ?>
|
||||
<?php if ($register_success) : ?><div class="sign-success"><?php echo wp_kses($register_success, ['a' => ['href' => []]]); ?></div><?php endif; ?>
|
||||
<form class="sign-form" id="sign-register-form" method="post" action="" novalidate>
|
||||
<?php wp_nonce_field('aksrt_register', '_register_nonce'); ?>
|
||||
<div class="form-field">
|
||||
<label for="sign-reg-login"><?php esc_html_e('Username', 'aksrt'); ?></label>
|
||||
<div class="input-wrap"><input type="text" name="user_login" id="sign-reg-login" autocomplete="username" required placeholder="<?php esc_attr_e('请输入用户名', 'aksrt'); ?>"></div>
|
||||
</div>
|
||||
<div class="form-field">
|
||||
<label for="sign-reg-email"><?php esc_html_e('Email Address', 'aksrt'); ?></label>
|
||||
<div class="input-wrap"><input type="email" name="user_email" id="sign-reg-email" autocomplete="email" required placeholder="<?php esc_attr_e('Please enter your email', 'aksrt'); ?>"></div>
|
||||
</div>
|
||||
<div class="form-field">
|
||||
<label for="sign-reg-pass"><?php esc_html_e('登录密码', 'aksrt'); ?></label>
|
||||
<div class="input-wrap">
|
||||
<input type="password" name="user_pass" id="sign-reg-pass" autocomplete="new-password" required minlength="6">
|
||||
<button type="button" class="toggle-pwd" data-target="sign-reg-pass"><i class="fas fa-eye"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-field">
|
||||
<label for="sign-reg-pass2"><?php esc_html_e('确认密码', 'aksrt'); ?></label>
|
||||
<div class="input-wrap">
|
||||
<input type="password" name="user_pass_confirm" id="sign-reg-pass2" autocomplete="new-password" required minlength="6">
|
||||
<button type="button" class="toggle-pwd" data-target="sign-reg-pass2"><i class="fas fa-eye"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
$invite_cfg = class_exists('AKSRT_Settings') ? AKSRT_Settings::get_invite_registration_config() : null;
|
||||
if ($invite_cfg && ($invite_cfg['register_field'] ?? 'hidden') !== 'hidden') {
|
||||
$mode = (string) $invite_cfg['register_field'];
|
||||
$invit_hint = $mode === 'required'
|
||||
? (string) ($invite_cfg['must_desc'] ?? '')
|
||||
: (string) ($invite_cfg['open_desc'] ?? '');
|
||||
?>
|
||||
<div class="form-field">
|
||||
<label for="sign-invite"><?php esc_html_e('邀请码', 'aksrt'); ?><?php echo $mode === 'optional' ? ' <small style="color:var(--muted-color);">(' . esc_html__('选填', 'aksrt') . ')</small>' : ''; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></label>
|
||||
<div class="input-wrap"><input type="text" name="invite_code" id="sign-invite" maxlength="32" autocomplete="off" value="<?php echo esc_attr($invite_prefill); ?>" <?php echo $mode === 'required' ? 'required' : ''; ?>></div>
|
||||
<?php if ($invit_hint !== '') : ?>
|
||||
<p class="sign-hint"><?php echo wp_kses_post($invit_hint); ?></p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php } ?>
|
||||
<label class="sign-terms">
|
||||
<input type="checkbox" name="agree_terms" value="1" required>
|
||||
<span><?php esc_html_e('I agree to the Terms of Service', 'aksrt'); ?></span>
|
||||
</label>
|
||||
<?php if (class_exists('AKSRT_Settings') && AKSRT_Settings::registration_requires_email_verification()) : ?>
|
||||
<p class="sign-hint"><?php esc_html_e('Email verification is required after registration.', 'aksrt'); ?></p>
|
||||
<?php endif; ?>
|
||||
<?php if (function_exists('aksrt_render_captcha')) aksrt_render_captcha('register'); ?>
|
||||
<button type="submit" class="btn-submit"><?php esc_html_e('注册', 'aksrt'); ?></button>
|
||||
</form>
|
||||
<div class="sign-footer"><?php esc_html_e('Already have an account?', 'aksrt'); ?> <a href="#" data-sign-switch="signin"><?php esc_html_e('Sign in now', 'aksrt'); ?></a></div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<script>
|
||||
(function(){
|
||||
document.querySelectorAll('[data-sign-tab]').forEach(function(tab){
|
||||
tab.addEventListener('click',function(){
|
||||
var target=this.getAttribute('data-sign-tab');
|
||||
this.parentElement.querySelectorAll('.sign-tab').forEach(function(t){t.classList.remove('is-active');});
|
||||
this.classList.add('is-active');
|
||||
var card=this.closest('.sign-card');
|
||||
card.querySelectorAll('.sign-panel[data-sign-panel]').forEach(function(p){p.classList.remove('is-active');});
|
||||
var panel=card.querySelector('[data-sign-panel="'+target+'"]');
|
||||
if(panel)panel.classList.add('is-active');
|
||||
});
|
||||
});
|
||||
document.querySelectorAll('[data-sign-switch]').forEach(function(link){
|
||||
link.addEventListener('click',function(e){
|
||||
e.preventDefault();
|
||||
var target=this.getAttribute('data-sign-switch');
|
||||
var btn=document.querySelector('[data-sign-tab="'+target+'"]');
|
||||
if(btn)btn.click();
|
||||
});
|
||||
});
|
||||
document.querySelectorAll('.toggle-pwd').forEach(function(btn){
|
||||
btn.addEventListener('click',function(){
|
||||
var input=document.getElementById(this.getAttribute('data-target'));
|
||||
if(!input)return;
|
||||
var isPw=input.type==='password';
|
||||
input.type=isPw?'text':'password';
|
||||
this.querySelector('i').className=isPw?'fas fa-eye-slash':'fas fa-eye';
|
||||
});
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
<?php if (!$interim) : ?>
|
||||
<div class="sign-footer-bar">
|
||||
<?php
|
||||
$footer_text = $sign_ui['footer'] ?? '';
|
||||
echo $footer_text ? wp_kses_post($footer_text) : '© ' . date('Y') . ' ' . esc_html(get_bloginfo('name'));
|
||||
?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php wp_footer(); ?>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,148 @@
|
||||
<?php
|
||||
/**
|
||||
* Template Name: AKSRT - Special Page
|
||||
*
|
||||
* 专题聚合页模板 — 用于内容专题、活动页、产品介绍页等。
|
||||
* 读取 AKSRT_Settings 中的 page_display.special 配置,支持 per-page meta 覆盖。
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
get_header();
|
||||
|
||||
$post_id = get_the_ID();
|
||||
|
||||
// 从门面 getter 读取专题页设置(validated & sanitized)
|
||||
$special = class_exists('AKSRT_Settings')
|
||||
? AKSRT_Settings::get_special_page_settings()
|
||||
: [];
|
||||
|
||||
$defaults = [
|
||||
'cover_enabled' => true,
|
||||
'summary_enabled' => true,
|
||||
'summary_length' => 200,
|
||||
'default_cover' => '',
|
||||
'layout' => 'grid',
|
||||
'columns' => 2,
|
||||
'source_type' => 'category',
|
||||
'source_ids' => '',
|
||||
'subpage_display' => 'cards',
|
||||
'subpage_count' => 6,
|
||||
'sidebar' => true,
|
||||
'pagination' => 'numeric',
|
||||
'per_page' => 12,
|
||||
'post_count' => false,
|
||||
'orderby' => 'date',
|
||||
];
|
||||
$settings = array_merge($defaults, $special);
|
||||
|
||||
// Per-page meta override
|
||||
$meta_layout = get_post_meta($post_id, '_aksrt_special_layout', true);
|
||||
$meta_columns = get_post_meta($post_id, '_aksrt_special_columns', true);
|
||||
$meta_source = get_post_meta($post_id, '_aksrt_special_source_type', true);
|
||||
$meta_ids = get_post_meta($post_id, '_aksrt_special_source_ids', true);
|
||||
if ($meta_layout) $settings['layout'] = sanitize_key($meta_layout);
|
||||
if ($meta_columns) $settings['columns'] = max(1, min(4, (int) $meta_columns));
|
||||
if ($meta_source) $settings['source_type'] = sanitize_key($meta_source);
|
||||
if ($meta_ids !== '' && $meta_ids !== false) $settings['source_ids'] = $meta_ids;
|
||||
|
||||
$layout = in_array($settings['layout'], ['grid', 'list', 'masonry'], true) ? $settings['layout'] : 'grid';
|
||||
$columns = max(1, min(4, (int) $settings['columns']));
|
||||
$show_cover = !empty($settings['cover_enabled']);
|
||||
$show_summary = !empty($settings['summary_enabled']);
|
||||
$summary_len = max(50, min(500, (int) $settings['summary_length']));
|
||||
$subpage_style = in_array($settings['subpage_display'], ['cards', 'list', 'timeline'], true) ? $settings['subpage_display'] : 'cards';
|
||||
$per_page = max(4, min(48, (int) $settings['per_page']));
|
||||
$orderby = in_array($settings['orderby'], ['date', 'modified', 'views', 'comments'], true) ? $settings['orderby'] : 'date';
|
||||
|
||||
// 聚合内容源
|
||||
$source_type = sanitize_key($settings['source_type']);
|
||||
$source_ids = array_filter(array_map('absint', explode(',', (string) $settings['source_ids'])));
|
||||
$aggregated_posts = [];
|
||||
|
||||
if (!empty($source_ids)) {
|
||||
$args = [
|
||||
'posts_per_page' => $per_page,
|
||||
'post_status' => 'publish',
|
||||
'orderby' => ($orderby === 'modified') ? 'modified' : 'date',
|
||||
'order' => 'DESC',
|
||||
];
|
||||
if ($source_type === 'category') {
|
||||
$args['category__in'] = $source_ids;
|
||||
} elseif ($source_type === 'tag') {
|
||||
$args['tag__in'] = $source_ids;
|
||||
}
|
||||
$aggregated_query = new WP_Query($args);
|
||||
$aggregated_posts = $aggregated_query->posts;
|
||||
}
|
||||
|
||||
// 子页面列表
|
||||
$children_per_page = max(1, min(20, (int) $settings['subpage_count']));
|
||||
$children = get_pages([
|
||||
'child_of' => $post_id,
|
||||
'sort_column' => 'menu_order',
|
||||
'sort_order' => 'ASC',
|
||||
'parent' => $post_id,
|
||||
'number' => $children_per_page,
|
||||
]);
|
||||
?>
|
||||
|
||||
<main id="main-content" class="site-main content-shell content-shell--page aksrt-special--<?php echo esc_attr($layout); ?>" tabindex="-1">
|
||||
<?php if (function_exists('aksrt_breadcrumbs')) { aksrt_breadcrumbs(); } ?>
|
||||
|
||||
<?php if ($show_cover) :
|
||||
$default_cover = $settings['default_cover'] ?? '';
|
||||
$show_post_count = !empty($settings['post_count']);
|
||||
include get_template_directory() . '/templates/parts/special/special-cover.php';
|
||||
endif; ?>
|
||||
|
||||
<div class="aksrt-special-content container">
|
||||
<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
|
||||
<div class="aksrt-special-content__body">
|
||||
<?php the_content(); ?>
|
||||
</div>
|
||||
<?php endwhile; endif; ?>
|
||||
</div>
|
||||
|
||||
<?php if (!empty($aggregated_posts)) : ?>
|
||||
<section class="aksrt-special-aggregated container">
|
||||
<h2 class="aksrt-special-aggregated__title"><?php esc_html_e('相关内容', 'aksrt'); ?></h2>
|
||||
<?php
|
||||
// Use the special-grid part
|
||||
$grid_posts = $aggregated_posts;
|
||||
$show_dates = true;
|
||||
include get_template_directory() . '/templates/parts/special/special-grid.php';
|
||||
?>
|
||||
</section>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!empty($children)) : ?>
|
||||
<section class="aksrt-special-children container">
|
||||
<h2 class="aksrt-special-children__title"><?php esc_html_e('子页面', 'aksrt'); ?></h2>
|
||||
<div class="aksrt-special-children__grid aksrt-special-children__grid--<?php echo esc_attr($subpage_style); ?>" style="--aksrt-cols:<?php echo esc_attr((string) $columns); ?>">
|
||||
<?php foreach ($children as $child) :
|
||||
$child_img = get_the_post_thumbnail_url($child->ID, 'medium');
|
||||
?>
|
||||
<a href="<?php echo esc_url(get_permalink($child->ID)); ?>" class="aksrt-special-child-card">
|
||||
<?php if ($child_img) : ?>
|
||||
<div class="aksrt-special-child-card__image">
|
||||
<img src="<?php echo esc_url($child_img); ?>" alt=""<?php echo function_exists('aksrt_lazy_loading') ? aksrt_lazy_loading('other') : ' loading="lazy"'; ?>>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<div class="aksrt-special-child-card__body">
|
||||
<h3 class="aksrt-special-child-card__title"><?php echo esc_html($child->post_title); ?></h3>
|
||||
<?php if ($child->post_excerpt !== '') : ?>
|
||||
<p class="aksrt-special-child-card__desc"><?php echo esc_html(wp_trim_words($child->post_excerpt, 30)); ?></p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</a>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</section>
|
||||
<?php endif; ?>
|
||||
</main>
|
||||
|
||||
<?php
|
||||
get_footer();
|
||||
@@ -0,0 +1,292 @@
|
||||
<?php
|
||||
/**
|
||||
* Template Name: AKSRT - Submit
|
||||
*
|
||||
* 前台投稿页面模板。
|
||||
* 支持标题、摘要、分类、标签、正文、封面、草稿保存。
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
if (!is_user_logged_in()) {
|
||||
wp_redirect(aksrt_get_login_url(get_permalink()));
|
||||
exit;
|
||||
}
|
||||
|
||||
$user_id = get_current_user_id();
|
||||
$can_submit = class_exists('AKSRT_Front_Submit') && AKSRT_Front_Submit::get_instance()->can_submit($user_id);
|
||||
|
||||
if (!$can_submit) {
|
||||
wp_redirect(home_url('/'));
|
||||
exit;
|
||||
}
|
||||
|
||||
// Check if editing existing draft
|
||||
$edit_id = isset($_GET['edit']) ? absint($_GET['edit']) : 0;
|
||||
$edit_post = null;
|
||||
if ($edit_id > 0) {
|
||||
$edit_post = get_post($edit_id);
|
||||
if (!$edit_post || (int) $edit_post->post_author !== $user_id || $edit_post->post_status !== 'draft') {
|
||||
$edit_post = null;
|
||||
$edit_id = 0;
|
||||
}
|
||||
}
|
||||
|
||||
get_header();
|
||||
|
||||
// Submit settings
|
||||
$submit_settings = [];
|
||||
if (class_exists('AKSRT_Settings')) {
|
||||
$all = AKSRT_Settings::get_all();
|
||||
$submit_settings = [
|
||||
'enabled' => !empty($all['front_submit_enabled']),
|
||||
'review_mode' => $all['front_submit_review_mode'] ?? 'pending',
|
||||
'allow_cover' => !isset($all['front_submit_cover']) || !empty($all['front_submit_cover']),
|
||||
'allow_excerpt' => !isset($all['front_submit_excerpt']) || !empty($all['front_submit_excerpt']),
|
||||
'allow_category' => !isset($all['front_submit_category']) || !empty($all['front_submit_category']),
|
||||
'allow_tags' => !isset($all['front_submit_tags']) || !empty($all['front_submit_tags']),
|
||||
'max_images' => (int) ($all['front_submit_max_images'] ?? 5),
|
||||
'allowed_cat_ids' => is_array($all['post_article_cat'] ?? null) ? array_map('intval', $all['post_article_cat']) : [],
|
||||
'topics_s' => !empty($all['post_article_topics_s']),
|
||||
'custom_filter_s' => !isset($all['post_article_custom_filter_s']) || !empty($all['post_article_custom_filter_s']),
|
||||
];
|
||||
}
|
||||
|
||||
// §3.7 topics: load topics taxonomy terms
|
||||
$topics_terms = [];
|
||||
if (!empty($submit_settings['topics_s']) && taxonomy_exists('topics')) {
|
||||
$topics_terms = get_terms(['taxonomy' => 'topics', 'hide_empty' => false, 'orderby' => 'name', 'order' => 'ASC']);
|
||||
if (is_wp_error($topics_terms)) $topics_terms = [];
|
||||
}
|
||||
$current_topics = [];
|
||||
if ($edit_post && taxonomy_exists('topics')) {
|
||||
$terms = wp_get_object_terms($edit_post->ID, 'topics', ['fields' => 'ids']);
|
||||
if (!is_wp_error($terms)) $current_topics = $terms;
|
||||
}
|
||||
|
||||
// §3.4 custom_filter: load dimension definitions for submit form
|
||||
$custom_dimensions = [];
|
||||
if (!empty($submit_settings['custom_filter_s']) && class_exists('AKSRT_Settings')) {
|
||||
$filter_all = AKSRT_Settings::get_post_filter_settings();
|
||||
$custom_dimensions = $filter_all['custom_filter'];
|
||||
}
|
||||
|
||||
// §3.4 custom_filter: load current values for edit mode
|
||||
$current_cf = [];
|
||||
if ($edit_post && !empty($custom_dimensions)) {
|
||||
foreach ($custom_dimensions as $dim) {
|
||||
$current_cf[$dim['key']] = get_post_meta($edit_post->ID, '_aksrt_cf_' . $dim['key'], true);
|
||||
}
|
||||
}
|
||||
|
||||
// §3.7 post_article_cat: filter categories by allowed list
|
||||
$cat_args = [
|
||||
'taxonomy' => 'category',
|
||||
'hide_empty' => false,
|
||||
'orderby' => 'name',
|
||||
'order' => 'ASC',
|
||||
];
|
||||
if (!empty($submit_settings['allowed_cat_ids'])) {
|
||||
$cat_args['include'] = $submit_settings['allowed_cat_ids'];
|
||||
}
|
||||
$categories = get_categories($cat_args);
|
||||
|
||||
// Current values for edit mode
|
||||
$current_title = $edit_post ? $edit_post->post_title : '';
|
||||
$current_content = $edit_post ? $edit_post->post_content : '';
|
||||
$current_excerpt = $edit_post ? $edit_post->post_excerpt : '';
|
||||
$current_cats = $edit_post ? wp_get_post_categories($edit_post->ID) : [];
|
||||
$current_tags = $edit_post ? implode(', ', wp_get_post_tags($edit_post->ID, ['fields' => 'names'])) : '';
|
||||
$current_thumb = $edit_post ? get_the_post_thumbnail_url($edit_post->ID, 'large') : '';
|
||||
?>
|
||||
|
||||
<main id="main-content" class="site-main content-shell content-shell--page" tabindex="-1">
|
||||
<div class="aksrt-submit-page container">
|
||||
<header class="aksrt-submit-page__header">
|
||||
<h1 class="aksrt-submit-page__title">
|
||||
<?php echo $edit_post ? esc_html__('编辑草稿', 'aksrt') : esc_html__('投稿', 'aksrt'); ?>
|
||||
</h1>
|
||||
<p class="aksrt-submit-page__desc">
|
||||
<?php echo $edit_post
|
||||
? esc_html__('继续编辑你的草稿,完成后提交审核。', 'aksrt')
|
||||
: esc_html__('分享你的内容,提交后将进入审核流程。', 'aksrt'); ?>
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<form class="aksrt-submit-form" id="aksrt-submit-form" data-aksrt-submit-form data-dirty="false">
|
||||
<?php if ($edit_id > 0) : ?>
|
||||
<input type="hidden" name="edit_id" value="<?php echo esc_attr((string) $edit_id); ?>">
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="aksrt-form-group">
|
||||
<label for="submit-title"><?php esc_html_e('标题', 'aksrt'); ?> *</label>
|
||||
<input type="text" id="submit-title" name="title" class="aksrt-form-input" required maxlength="200" placeholder="<?php esc_attr_e('请输入文章标题', 'aksrt'); ?>" value="<?php echo esc_attr($current_title); ?>">
|
||||
</div>
|
||||
|
||||
<?php if (!empty($submit_settings['allow_excerpt'])) : ?>
|
||||
<div class="aksrt-form-group">
|
||||
<label for="submit-excerpt"><?php esc_html_e('摘要', 'aksrt'); ?></label>
|
||||
<textarea id="submit-excerpt" name="excerpt" class="aksrt-form-input" rows="3" maxlength="300" placeholder="<?php esc_attr_e('可选:文章摘要', 'aksrt'); ?>"><?php echo esc_textarea($current_excerpt); ?></textarea>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="aksrt-submit-form__row">
|
||||
<?php if (!empty($submit_settings['allow_category'])) : ?>
|
||||
<div class="aksrt-form-group aksrt-submit-form__col">
|
||||
<label for="submit-category"><?php esc_html_e('分类', 'aksrt'); ?></label>
|
||||
<select id="submit-category" name="category" class="aksrt-form-input">
|
||||
<option value=""><?php esc_html_e('选择分类', 'aksrt'); ?></option>
|
||||
<?php foreach ($categories as $cat) : ?>
|
||||
<option value="<?php echo esc_attr((string) $cat->term_id); ?>" <?php selected(in_array($cat->term_id, $current_cats)); ?>><?php echo esc_html($cat->name); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!empty($submit_settings['allow_tags'])) : ?>
|
||||
<div class="aksrt-form-group aksrt-submit-form__col">
|
||||
<label for="submit-tags"><?php esc_html_e('标签', 'aksrt'); ?></label>
|
||||
<input type="text" id="submit-tags" name="tags" class="aksrt-form-input" placeholder="<?php esc_attr_e('多个标签用逗号分隔', 'aksrt'); ?>" value="<?php echo esc_attr($current_tags); ?>">
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<?php if (!empty($submit_settings['topics_s']) && !empty($topics_terms)) : ?>
|
||||
<div class="aksrt-form-group">
|
||||
<label for="submit-topics"><?php esc_html_e('专题', 'aksrt'); ?></label>
|
||||
<select id="submit-topics" name="topics[]" class="aksrt-form-input" multiple>
|
||||
<?php foreach ($topics_terms as $topic) : ?>
|
||||
<option value="<?php echo esc_attr((string) $topic->term_id); ?>" <?php selected(in_array($topic->term_id, $current_topics)); ?>><?php echo esc_html($topic->name); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!empty($submit_settings['custom_filter_s']) && !empty($custom_dimensions)) : ?>
|
||||
<?php foreach ($custom_dimensions as $dim) : ?>
|
||||
<div class="aksrt-form-group">
|
||||
<label for="submit-cf-<?php echo esc_attr($dim['key']); ?>"><?php echo esc_html($dim['name']); ?></label>
|
||||
<select id="submit-cf-<?php echo esc_attr($dim['key']); ?>" name="cf_<?php echo esc_attr($dim['key']); ?>" class="aksrt-form-input">
|
||||
<option value=""><?php printf(esc_html__('选择%s', 'aksrt'), esc_html($dim['name'])); ?></option>
|
||||
<?php foreach ($dim['vals'] as $val) : ?>
|
||||
<option value="<?php echo esc_attr($val['key']); ?>" <?php selected(!empty($current_cf[$dim['key']]) && $current_cf[$dim['key']] === $val['key']); ?>><?php echo esc_html($val['name']); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="aksrt-form-group">
|
||||
<label for="submit-content"><?php esc_html_e('内容', 'aksrt'); ?> *</label>
|
||||
<div class="aksrt-submit-form__editor-toolbar">
|
||||
<button type="button" class="aksrt-submit-form__toolbar-btn" data-action="bold" title="<?php esc_attr_e('加粗', 'aksrt'); ?>"><i class="fas fa-bold"></i></button>
|
||||
<button type="button" class="aksrt-submit-form__toolbar-btn" data-action="italic" title="<?php esc_attr_e('斜体', 'aksrt'); ?>"><i class="fas fa-italic"></i></button>
|
||||
<button type="button" class="aksrt-submit-form__toolbar-btn" data-action="code" title="<?php esc_attr_e('代码', 'aksrt'); ?>"><i class="fas fa-code"></i></button>
|
||||
<button type="button" class="aksrt-submit-form__toolbar-btn" data-action="link" title="<?php esc_attr_e('链接', 'aksrt'); ?>"><i class="fas fa-link"></i></button>
|
||||
<button type="button" class="aksrt-submit-form__toolbar-btn" data-action="image" title="<?php esc_attr_e('图片', 'aksrt'); ?>"><i class="fas fa-image"></i></button>
|
||||
<button type="button" class="aksrt-submit-form__toolbar-btn" data-action="quote" title="<?php esc_attr_e('引用', 'aksrt'); ?>"><i class="fas fa-quote-left"></i></button>
|
||||
<button type="button" class="aksrt-submit-form__toolbar-btn" data-action="heading" title="<?php esc_attr_e('标题', 'aksrt'); ?>"><i class="fas fa-heading"></i></button>
|
||||
<button type="button" class="aksrt-submit-form__toolbar-btn" data-action="list" title="<?php esc_attr_e('列表', 'aksrt'); ?>"><i class="fas fa-list-ul"></i></button>
|
||||
</div>
|
||||
<textarea id="submit-content" name="content" class="aksrt-form-input aksrt-submit-form__textarea" rows="16" required placeholder="<?php esc_attr_e('请输入文章内容(支持 HTML)', 'aksrt'); ?>"><?php echo esc_textarea($current_content); ?></textarea>
|
||||
<div class="aksrt-submit-form__word-count" id="submit-word-count"></div>
|
||||
</div>
|
||||
|
||||
<?php if (!empty($submit_settings['allow_cover'])) : ?>
|
||||
<div class="aksrt-form-group">
|
||||
<label for="submit-thumbnail"><?php esc_html_e('封面图', 'aksrt'); ?></label>
|
||||
<div class="aksrt-submit-form__cover-input">
|
||||
<input type="url" id="submit-thumbnail" name="thumbnail" class="aksrt-form-input" placeholder="<?php esc_attr_e('输入封面图地址', 'aksrt'); ?>" value="<?php echo esc_url($current_thumb); ?>">
|
||||
<button type="button" class="aksrt-submit-form__cover-btn" id="aksrt-pick-cover">
|
||||
<i class="fas fa-image"></i>
|
||||
<?php esc_html_e('选择图片', 'aksrt'); ?>
|
||||
</button>
|
||||
</div>
|
||||
<div class="aksrt-submit-form__cover-preview" id="cover-preview" <?php echo $current_thumb ? '' : 'style="display:none"'; ?>>
|
||||
<img id="cover-preview-img" src="<?php echo esc_url($current_thumb); ?>" alt="">
|
||||
<button type="button" class="aksrt-submit-form__cover-remove" id="cover-remove" title="<?php esc_attr_e('移除封面', 'aksrt'); ?>">
|
||||
<i class="fas fa-times"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="aksrt-submit-form__actions">
|
||||
<button type="submit" class="aksrt-auth-submit" id="aksrt-submit-btn">
|
||||
<i class="fas fa-paper-plane"></i>
|
||||
<?php echo $edit_post ? esc_html__('更新投稿', 'aksrt') : esc_html__('提交投稿', 'aksrt'); ?>
|
||||
</button>
|
||||
<button type="button" class="btn-outline" id="aksrt-save-draft">
|
||||
<i class="fas fa-save"></i>
|
||||
<?php esc_html_e('保存草稿', 'aksrt'); ?>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<input type="hidden" name="_nonce" value="<?php echo esc_attr(wp_create_nonce('aksrt_submit')); ?>">
|
||||
<input type="hidden" name="status" id="submit-status" value="pending">
|
||||
</form>
|
||||
|
||||
<!-- Draft list -->
|
||||
<?php
|
||||
$user_drafts = get_posts([
|
||||
'post_type' => 'post',
|
||||
'post_status' => 'draft',
|
||||
'author' => $user_id,
|
||||
'numberposts' => 10,
|
||||
'orderby' => 'modified',
|
||||
'order' => 'DESC',
|
||||
]);
|
||||
if (!empty($user_drafts)) :
|
||||
?>
|
||||
<div class="aksrt-submit-drafts">
|
||||
<h3 class="aksrt-submit-drafts__title">
|
||||
<i class="fas fa-file-alt"></i>
|
||||
<?php esc_html_e('我的草稿', 'aksrt'); ?>
|
||||
</h3>
|
||||
<div class="aksrt-submit-drafts__list">
|
||||
<?php foreach ($user_drafts as $draft) : ?>
|
||||
<div class="aksrt-submit-drafts__item">
|
||||
<a href="<?php echo esc_url(add_query_arg('edit', $draft->ID, get_permalink())); ?>" class="aksrt-submit-drafts__link">
|
||||
<span class="aksrt-submit-drafts__name"><?php echo esc_html($draft->post_title ?: __('无标题', 'aksrt')); ?></span>
|
||||
<time class="aksrt-submit-drafts__date"><?php echo esc_html(get_the_date('Y-m-d H:i', $draft->ID)); ?></time>
|
||||
</a>
|
||||
<button type="button" class="aksrt-submit-drafts__delete" data-draft-id="<?php echo esc_attr((string) $draft->ID); ?>" title="<?php esc_attr_e('删除草稿', 'aksrt'); ?>">
|
||||
<i class="fas fa-trash"></i>
|
||||
</button>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<?php
|
||||
// Enqueue the front-submit script
|
||||
$front_submit_path = get_template_directory() . '/assets/js/front-submit.js';
|
||||
if (file_exists($front_submit_path)) {
|
||||
wp_enqueue_script(
|
||||
'aksrt-front-submit',
|
||||
get_template_directory_uri() . '/assets/js/front-submit.js',
|
||||
['aksrt-script'],
|
||||
(string) filemtime($front_submit_path),
|
||||
true
|
||||
);
|
||||
wp_localize_script('aksrt-front-submit', 'aksrtSubmitData', [
|
||||
'ajaxUrl' => admin_url('admin-ajax.php'),
|
||||
'nonce' => wp_create_nonce('aksrt_submit_nonce'),
|
||||
'i18n' => [
|
||||
'confirmLeave' => __('你有未保存的更改,确定要离开吗?', 'aksrt'),
|
||||
'saving' => __('保存中...', 'aksrt'),
|
||||
'saved' => __('草稿已保存', 'aksrt'),
|
||||
'submitting' => __('提交中...', 'aksrt'),
|
||||
'submitted' => __('投稿已提交', 'aksrt'),
|
||||
'error' => __('操作失败,请重试', 'aksrt'),
|
||||
'confirmDelete' => __('确定要删除这个草稿吗?', 'aksrt'),
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
get_footer();
|
||||
@@ -0,0 +1,556 @@
|
||||
<?php
|
||||
/**
|
||||
* Public user homepage template.
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
get_header();
|
||||
|
||||
$target_user_nicename = get_query_var('user_nicename');
|
||||
$user = $target_user_nicename ? get_user_by('slug', $target_user_nicename) : null;
|
||||
|
||||
if (!$user) {
|
||||
wp_safe_redirect(home_url('/'));
|
||||
exit;
|
||||
}
|
||||
|
||||
$user_id = (int) $user->ID;
|
||||
|
||||
// 数据聚合:复用共享 helper
|
||||
$dashboard = function_exists('aksrt_get_user_dashboard_view')
|
||||
? aksrt_get_user_dashboard_view($user_id, ['viewer_id' => get_current_user_id()])
|
||||
: [];
|
||||
|
||||
$is_own_profile = !empty($dashboard['is_own_profile']);
|
||||
$user_home_settings = class_exists('AKSRT_Settings')
|
||||
? AKSRT_Settings::get_user_home_settings()
|
||||
: [
|
||||
'tabs' => ['posts', 'comments', 'favorites'],
|
||||
'sidebar' => true,
|
||||
'cover' => true,
|
||||
'follow' => true,
|
||||
'posts_per_page' => 10,
|
||||
];
|
||||
|
||||
$post_count = (int) ($dashboard['post_count'] ?? 0);
|
||||
$comment_count = (int) ($dashboard['comment_count'] ?? 0);
|
||||
$favorite_post_ids = $dashboard['favorite_post_ids'] ?? [];
|
||||
$favorite_count = (int) ($dashboard['favorite_count'] ?? 0);
|
||||
$user_contacts = $dashboard['user_contacts'] ?? [];
|
||||
$user_center_settings = class_exists('AKSRT_Settings')
|
||||
? AKSRT_Settings::get_user_center_settings()
|
||||
: ['social_links' => true];
|
||||
$per_page = (int) $user_home_settings['posts_per_page'];
|
||||
$credits_enabled = !empty($dashboard['credits_enabled']);
|
||||
$credit_balance = $dashboard['credit_balance'] ?? 0.0;
|
||||
$currency_name = $dashboard['currency_name'] ?? __('积分', 'aksrt');
|
||||
$user_home_manager = class_exists('AKSRT_User_Home') ? AKSRT_User_Home::get_instance() : null;
|
||||
$visible_tabs = $user_home_manager ? $user_home_manager->get_visible_tabs($is_own_profile) : [];
|
||||
$profile_signals = $dashboard['profile_signals'] ?? [];
|
||||
$profile_notice = $dashboard['profile_notice'] ?? null;
|
||||
$show_report_button = !empty($dashboard['show_report']);
|
||||
|
||||
$enabled_tabs = array_keys($visible_tabs);
|
||||
if (empty($enabled_tabs)) {
|
||||
$enabled_tabs = ['posts', 'comments', 'favorites'];
|
||||
}
|
||||
|
||||
// Apply admin-configured display order
|
||||
$_uh_order = $user_home_settings['tabs_order'] ?? [];
|
||||
$_uh_ordered = [];
|
||||
foreach ($_uh_order as $_t) {
|
||||
if (in_array($_t, $enabled_tabs, true)) {
|
||||
$_uh_ordered[] = $_t;
|
||||
}
|
||||
}
|
||||
foreach ($enabled_tabs as $_t) {
|
||||
if (!in_array($_t, $_uh_ordered, true)) {
|
||||
$_uh_ordered[] = $_t;
|
||||
}
|
||||
}
|
||||
$enabled_tabs = $_uh_ordered;
|
||||
|
||||
// Device visibility: build PC/mobile tab arrays
|
||||
$_uh_pc_hide = $user_home_settings['tabs_pc_hide'] ?? [];
|
||||
$_uh_mobile_hide = $user_home_settings['tabs_mobile_hide'] ?? [];
|
||||
$enabled_tabs_pc = array_values(array_diff($enabled_tabs, $_uh_pc_hide));
|
||||
$enabled_tabs_mobile = array_values(array_diff($enabled_tabs, $_uh_mobile_hide));
|
||||
$_uh_is_mobile = function_exists('wp_is_mobile') && wp_is_mobile();
|
||||
$display_tabs = $_uh_is_mobile ? $enabled_tabs_mobile : $enabled_tabs_pc;
|
||||
$_uh_default_tab = !empty($display_tabs) ? $display_tabs[0] : $enabled_tabs[0];
|
||||
|
||||
$forum_instance = class_exists('AKSRT_Forum') ? AKSRT_Forum::get_instance() : null;
|
||||
$forum_stats = $forum_instance ? $forum_instance->get_user_forum_stats($user_id) : [];
|
||||
$forum_topic_count = (int) ($forum_stats['topic_count'] ?? 0);
|
||||
$forum_followed_count = (int) ($forum_stats['followed_plate_count'] ?? 0);
|
||||
|
||||
$tab_counts = [
|
||||
'posts' => $post_count,
|
||||
'comments' => $comment_count,
|
||||
'favorites' => $favorite_count,
|
||||
'credits' => $credits_enabled && $is_own_profile ? (int) round($credit_balance) : 0,
|
||||
'product' => 0,
|
||||
'plate' => 0,
|
||||
'forum' => $forum_topic_count,
|
||||
'follow' => $forum_followed_count,
|
||||
];
|
||||
$tab_labels = [
|
||||
'posts' => __('文章', 'aksrt'),
|
||||
'comments' => __('评论', 'aksrt'),
|
||||
'favorites' => __('收藏', 'aksrt'),
|
||||
'credits' => sprintf(__('我的%s', 'aksrt'), $currency_name),
|
||||
'product' => __('商品', 'aksrt'),
|
||||
'plate' => __('圈子', 'aksrt'),
|
||||
'forum' => __('论坛', 'aksrt'),
|
||||
'follow' => __('关注', 'aksrt'),
|
||||
];
|
||||
foreach ($visible_tabs as $tab_key => $tab_config) {
|
||||
if (!empty($tab_config['label'])) {
|
||||
$tab_labels[$tab_key] = (string) $tab_config['label'];
|
||||
}
|
||||
}
|
||||
|
||||
$active_tab = isset($_GET['tab']) ? sanitize_key(wp_unslash($_GET['tab'])) : $_uh_default_tab;
|
||||
if (!in_array($active_tab, $enabled_tabs, true)) {
|
||||
$active_tab = $_uh_default_tab;
|
||||
}
|
||||
$posts_page = max(1, isset($_GET['posts_page']) ? (int) $_GET['posts_page'] : 1);
|
||||
$comments_page = max(1, isset($_GET['comments_page']) ? (int) $_GET['comments_page'] : 1);
|
||||
$favorites_page = max(1, isset($_GET['favorites_page']) ? (int) $_GET['favorites_page'] : 1);
|
||||
|
||||
require_once AKSRT_DIR . '/templates/parts/user-shared-helpers.php';
|
||||
|
||||
$svg_empty_post = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><path d="M14 2v6h6"/><path d="M9 13h6M9 17h6M9 9h1"/></svg>';
|
||||
$svg_empty_comment = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>';
|
||||
$svg_empty_favorite = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/></svg>';
|
||||
$home_url = function_exists('aksrt_get_user_home_url') ? aksrt_get_user_home_url($user) : home_url('/');
|
||||
?>
|
||||
|
||||
<main id="main-content" class="site-main content-shell" tabindex="-1">
|
||||
<div class="content-layout<?php echo !empty($user_home_settings['sidebar']) ? '' : ' content-layout--no-sidebar'; ?> aksrt-user-home__layout">
|
||||
<div class="content-layout__primary">
|
||||
<?php
|
||||
// 作者 Hero 区:共享 partial
|
||||
set_query_var('user', $user);
|
||||
set_query_var('dashboard', $dashboard);
|
||||
set_query_var('user_home_settings', $user_home_settings);
|
||||
set_query_var('is_author_page', false);
|
||||
get_template_part('templates/parts/user/author-hero');
|
||||
?>
|
||||
|
||||
<div class="dashboard dashboard--public" data-default-tab="<?php echo esc_attr($_uh_default_tab); ?>">
|
||||
<div class="dashboard-tabs" role="tablist">
|
||||
<?php foreach ($enabled_tabs as $tab_key) :
|
||||
$_tab_class = $tab_key === $active_tab ? 'is-active' : '';
|
||||
$_pc_hidden = in_array($tab_key, $_uh_pc_hide, true);
|
||||
$_mobile_hidden = in_array($tab_key, $_uh_mobile_hide, true);
|
||||
if ($_pc_hidden) $_tab_class .= ' tab-hide-pc';
|
||||
if ($_mobile_hidden) $_tab_class .= ' tab-hide-mobile';
|
||||
?>
|
||||
<button type="button" class="<?php echo esc_attr(trim($_tab_class)); ?>" data-tab="<?php echo esc_attr($tab_key); ?>" role="tab">
|
||||
<?php echo esc_html($tab_labels[$tab_key] ?? ucfirst($tab_key)); ?>
|
||||
<span class="dashboard-tabs__count"><?php echo esc_html((string) ($tab_counts[$tab_key] ?? 0)); ?></span>
|
||||
</button>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
|
||||
<?php if (in_array('posts', $enabled_tabs, true)) : ?>
|
||||
<div id="panel-posts" class="dashboard-panel<?php echo $active_tab === 'posts' ? ' is-active' : ''; ?>" role="tabpanel"<?php echo $active_tab !== 'posts' ? ' hidden' : ''; ?>>
|
||||
<?php
|
||||
$author_posts = new WP_Query([
|
||||
'author' => $user_id,
|
||||
'posts_per_page' => $per_page,
|
||||
'post_status' => 'publish',
|
||||
'paged' => $posts_page,
|
||||
'no_found_rows' => false,
|
||||
'update_post_meta_cache' => false,
|
||||
]);
|
||||
if ($author_posts->have_posts()) :
|
||||
?>
|
||||
<div class="profile-list">
|
||||
<?php while ($author_posts->have_posts()) : $author_posts->the_post(); ?>
|
||||
<?php
|
||||
set_query_var('aksrt_profile_item_action', [
|
||||
'type' => 'view',
|
||||
'url' => get_permalink(),
|
||||
'label' => __('阅读', 'aksrt'),
|
||||
]);
|
||||
set_query_var('aksrt_profile_item_status', '');
|
||||
get_template_part('templates/parts/content', 'profile-list-item');
|
||||
?>
|
||||
<?php endwhile; ?>
|
||||
</div>
|
||||
<?php
|
||||
aksrt_render_profile_pagination((int) $author_posts->max_num_pages, $posts_page, 'posts_page');
|
||||
wp_reset_postdata();
|
||||
set_query_var('aksrt_profile_item_action', []);
|
||||
else :
|
||||
aksrt_render_profile_empty($svg_empty_post, __('TA 还没有发布文章', 'aksrt'));
|
||||
endif;
|
||||
?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (in_array('comments', $enabled_tabs, true)) : ?>
|
||||
<div id="panel-comments" class="dashboard-panel<?php echo $active_tab === 'comments' ? ' is-active' : ''; ?>" role="tabpanel"<?php echo $active_tab !== 'comments' ? ' hidden' : ''; ?>>
|
||||
<?php
|
||||
$user_comments = get_comments([
|
||||
'user_id' => $user_id,
|
||||
'status' => 'approve',
|
||||
'number' => $per_page,
|
||||
'offset' => ($comments_page - 1) * $per_page,
|
||||
'type' => 'comment',
|
||||
'update_comment_meta_cache' => false,
|
||||
]);
|
||||
if ($user_comments) :
|
||||
?>
|
||||
<div class="profile-comment-list">
|
||||
<?php foreach ($user_comments as $c) : ?>
|
||||
<?php
|
||||
set_query_var('aksrt_profile_comment', $c);
|
||||
get_template_part('templates/parts/content', 'profile-comment-item');
|
||||
?>
|
||||
<?php endforeach; ?>
|
||||
<?php set_query_var('aksrt_profile_comment', null); ?>
|
||||
</div>
|
||||
<?php
|
||||
$cm_total_pages = (int) ceil($comment_count / $per_page);
|
||||
aksrt_render_profile_pagination($cm_total_pages, $comments_page, 'comments_page');
|
||||
else :
|
||||
aksrt_render_profile_empty($svg_empty_comment, __('TA 还没有发表评论', 'aksrt'));
|
||||
endif;
|
||||
?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (in_array('favorites', $enabled_tabs, true)) : ?>
|
||||
<div id="panel-favorites" class="dashboard-panel<?php echo $active_tab === 'favorites' ? ' is-active' : ''; ?>" role="tabpanel"<?php echo $active_tab !== 'favorites' ? ' hidden' : ''; ?>>
|
||||
<?php if (!empty($favorite_post_ids)) : ?>
|
||||
<?php
|
||||
$favorites_query = new WP_Query([
|
||||
'post_type' => 'post',
|
||||
'post_status' => 'publish',
|
||||
'post__in' => $favorite_post_ids,
|
||||
'orderby' => 'post__in',
|
||||
'posts_per_page' => $per_page,
|
||||
'paged' => $favorites_page,
|
||||
'ignore_sticky_posts' => true,
|
||||
'no_found_rows' => false,
|
||||
'update_post_meta_cache' => false,
|
||||
]);
|
||||
if ($favorites_query->have_posts()) :
|
||||
?>
|
||||
<div class="profile-list">
|
||||
<?php while ($favorites_query->have_posts()) : $favorites_query->the_post(); ?>
|
||||
<?php
|
||||
set_query_var('aksrt_profile_item_action', [
|
||||
'type' => 'view',
|
||||
'url' => get_permalink(),
|
||||
'label' => __('阅读', 'aksrt'),
|
||||
]);
|
||||
set_query_var('aksrt_profile_item_status', '');
|
||||
get_template_part('templates/parts/content', 'profile-list-item');
|
||||
?>
|
||||
<?php endwhile; ?>
|
||||
</div>
|
||||
<?php
|
||||
aksrt_render_profile_pagination((int) $favorites_query->max_num_pages, $favorites_page, 'favorites_page');
|
||||
wp_reset_postdata();
|
||||
set_query_var('aksrt_profile_item_action', []);
|
||||
else :
|
||||
aksrt_render_profile_empty($svg_empty_favorite, __('TA 还没有收藏文章', 'aksrt'));
|
||||
endif;
|
||||
?>
|
||||
<?php else : ?>
|
||||
<?php aksrt_render_profile_empty($svg_empty_favorite, __('TA 还没有收藏文章', 'aksrt')); ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (in_array('credits', $enabled_tabs, true) && $credits_enabled && $is_own_profile) : ?>
|
||||
<div id="panel-credits" class="dashboard-panel<?php echo $active_tab === 'credits' ? ' is-active' : ''; ?>" role="tabpanel"<?php echo $active_tab !== 'credits' ? ' hidden' : ''; ?>>
|
||||
<div class="user-home-balance-card">
|
||||
<p class="user-home-balance-card__label"><?php echo esc_html(sprintf(__('当前%s余额', 'aksrt'), $currency_name)); ?></p>
|
||||
<div class="user-home-balance-card__value"><?php echo esc_html(aksrt_format_credits($credit_balance)); ?></div>
|
||||
<p class="user-home-balance-card__hint"><?php esc_html_e('完整账单和赚取/消费记录请在个人中心查看。', 'aksrt'); ?></p>
|
||||
<a href="<?php echo esc_url(aksrt_get_user_center_url('credits')); ?>" class="btn-outline btn-sm"><?php esc_html_e('进入个人中心', 'aksrt'); ?></a>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php
|
||||
// Placeholder panels for extended tabs (product, plate)
|
||||
$_uh_extended_tabs = ['product', 'plate'];
|
||||
$_uh_placeholder_msgs = [
|
||||
'product' => __('暂无商品内容', 'aksrt'),
|
||||
'plate' => __('暂无圈子内容', 'aksrt'),
|
||||
];
|
||||
foreach ($_uh_extended_tabs as $_uh_ext) :
|
||||
if (!in_array($_uh_ext, $enabled_tabs, true)) continue;
|
||||
?>
|
||||
<div id="panel-<?php echo esc_attr($_uh_ext); ?>" class="dashboard-panel<?php echo $active_tab === $_uh_ext ? ' is-active' : ''; ?>" role="tabpanel"<?php echo $active_tab !== $_uh_ext ? ' hidden' : ''; ?>>
|
||||
<?php aksrt_render_profile_empty($svg_empty_post, $_uh_placeholder_msgs[$_uh_ext]); ?>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
|
||||
<?php if (in_array('forum', $enabled_tabs, true)) : ?>
|
||||
<div id="panel-forum" class="dashboard-panel<?php echo $active_tab === 'forum' ? ' is-active' : ''; ?>" role="tabpanel"<?php echo $active_tab !== 'forum' ? ' hidden' : ''; ?>>
|
||||
<?php
|
||||
$forum_page = max(1, isset($_GET['forum_page']) ? (int) $_GET['forum_page'] : 1);
|
||||
$forum_sub = isset($_GET['forum_sub']) ? sanitize_key(wp_unslash($_GET['forum_sub'])) : 'topics';
|
||||
$forum_sub = in_array($forum_sub, ['topics', 'favorites', 'plates'], true) ? $forum_sub : 'topics';
|
||||
?>
|
||||
<div class="uh-forum__subtabs">
|
||||
<a class="uh-forum__subtab<?php echo $forum_sub === 'topics' ? ' is-active' : ''; ?>"
|
||||
href="<?php echo esc_url(add_query_arg(['tab' => 'forum', 'forum_sub' => 'topics', 'forum_page' => 1], $home_url)); ?>">
|
||||
<i class="fas fa-file-alt"></i> <?php esc_html_e('帖子', 'aksrt'); ?>
|
||||
<span class="uh-forum__subtab-count"><?php echo esc_html((string) $forum_topic_count); ?></span>
|
||||
</a>
|
||||
<a class="uh-forum__subtab<?php echo $forum_sub === 'favorites' ? ' is-active' : ''; ?>"
|
||||
href="<?php echo esc_url(add_query_arg(['tab' => 'forum', 'forum_sub' => 'favorites', 'forum_page' => 1], $home_url)); ?>">
|
||||
<i class="fas fa-star"></i> <?php esc_html_e('收藏帖子', 'aksrt'); ?>
|
||||
<span class="uh-forum__subtab-count"><?php echo esc_html((string) ($forum_stats['favorite_count'] ?? 0)); ?></span>
|
||||
</a>
|
||||
<a class="uh-forum__subtab<?php echo $forum_sub === 'plates' ? ' is-active' : ''; ?>"
|
||||
href="<?php echo esc_url(add_query_arg(['tab' => 'forum', 'forum_sub' => 'plates', 'forum_page' => 1], $home_url)); ?>">
|
||||
<i class="fas fa-th-large"></i> <?php esc_html_e('版块', 'aksrt'); ?>
|
||||
<span class="uh-forum__subtab-count"><?php echo esc_html((string) ($forum_stats['managed_plate_count'] ?? 0)); ?></span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<?php if ($forum_sub === 'topics' && $forum_instance) :
|
||||
$forum_topics = $forum_instance->get_user_forum_topics($user_id, ['page' => $forum_page, 'limit' => $per_page]);
|
||||
if (!empty($forum_topics['items'])) : ?>
|
||||
<div class="uh-forum__list">
|
||||
<?php foreach ($forum_topics['items'] as $ft) : ?>
|
||||
<div class="uh-forum__item">
|
||||
<div class="uh-forum__item-body">
|
||||
<a class="uh-forum__item-title" href="<?php echo esc_url(get_permalink((int) ($ft['id'] ?? 0))); ?>">
|
||||
<?php echo esc_html((string) ($ft['title'] ?? '')); ?>
|
||||
</a>
|
||||
<div class="uh-forum__item-meta">
|
||||
<span><i class="far fa-eye"></i> <?php echo esc_html((string) ($ft['views'] ?? 0)); ?></span>
|
||||
<span><i class="far fa-comment"></i> <?php echo esc_html((string) ($ft['comment_count'] ?? 0)); ?></span>
|
||||
<time><?php echo esc_html((string) ($ft['date'] ?? '')); ?></time>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php if ($forum_topics['max_pages'] > 1) : ?>
|
||||
<div class="uh-forum__pagination">
|
||||
<?php
|
||||
echo paginate_links([
|
||||
'base' => add_query_arg('forum_page', '%#%', $home_url),
|
||||
'format' => '',
|
||||
'current' => $forum_page,
|
||||
'total' => $forum_topics['max_pages'],
|
||||
'add_args' => ['tab' => 'forum', 'forum_sub' => 'topics'],
|
||||
]);
|
||||
?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php else : ?>
|
||||
<?php aksrt_render_profile_empty($svg_empty_post, __('暂无论坛帖子', 'aksrt')); ?>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php elseif ($forum_sub === 'favorites' && $forum_instance) :
|
||||
$fav_topics = $forum_instance->get_user_favorite_topics($user_id, $forum_page, $per_page);
|
||||
if (!empty($fav_topics['items'])) : ?>
|
||||
<div class="uh-forum__list">
|
||||
<?php foreach ($fav_topics['items'] as $ft) : ?>
|
||||
<div class="uh-forum__item">
|
||||
<div class="uh-forum__item-body">
|
||||
<a class="uh-forum__item-title" href="<?php echo esc_url(get_permalink((int) ($ft['id'] ?? 0))); ?>">
|
||||
<?php echo esc_html((string) ($ft['title'] ?? '')); ?>
|
||||
</a>
|
||||
<div class="uh-forum__item-meta">
|
||||
<span><i class="far fa-eye"></i> <?php echo esc_html((string) ($ft['views'] ?? 0)); ?></span>
|
||||
<span><i class="far fa-comment"></i> <?php echo esc_html((string) ($ft['comment_count'] ?? 0)); ?></span>
|
||||
<time><?php echo esc_html((string) ($ft['date'] ?? '')); ?></time>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php if ($fav_topics['max_pages'] > 1) : ?>
|
||||
<div class="uh-forum__pagination">
|
||||
<?php
|
||||
echo paginate_links([
|
||||
'base' => add_query_arg('forum_page', '%#%', $home_url),
|
||||
'format' => '',
|
||||
'current' => $forum_page,
|
||||
'total' => $fav_topics['max_pages'],
|
||||
'add_args' => ['tab' => 'forum', 'forum_sub' => 'favorites'],
|
||||
]);
|
||||
?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php else : ?>
|
||||
<?php aksrt_render_profile_empty($svg_empty_favorite, __('暂无收藏帖子', 'aksrt')); ?>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php elseif ($forum_sub === 'plates' && $forum_instance) :
|
||||
$managed_plates = $forum_instance->get_user_managed_plates($user_id);
|
||||
$followed_plates = $forum_instance->get_user_followed_plates($user_id);
|
||||
$has_plates = !empty($managed_plates['owned']) || !empty($managed_plates['moderating']) || !empty($followed_plates);
|
||||
if ($has_plates) : ?>
|
||||
<?php if (!empty($managed_plates['owned'])) : ?>
|
||||
<h3 class="uh-forum__section-title"><i class="fas fa-crown"></i> <?php esc_html_e('创建的版块', 'aksrt'); ?></h3>
|
||||
<div class="uh-forum__plate-grid">
|
||||
<?php foreach ($managed_plates['owned'] as $plate) : ?>
|
||||
<a class="uh-forum__plate-card" href="<?php echo esc_url(get_permalink((int) ($plate['id'] ?? 0))); ?>">
|
||||
<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'] ?? 0)); ?></span>
|
||||
<span><?php printf(esc_html__('%d 关注', 'aksrt'), (int) ($plate['follow_count'] ?? 0)); ?></span>
|
||||
</div>
|
||||
</a>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php if (!empty($managed_plates['moderating'])) : ?>
|
||||
<h3 class="uh-forum__section-title"><i class="fas fa-shield-alt"></i> <?php esc_html_e('管理的版块', 'aksrt'); ?></h3>
|
||||
<div class="uh-forum__plate-grid">
|
||||
<?php foreach ($managed_plates['moderating'] as $plate) : ?>
|
||||
<a class="uh-forum__plate-card" href="<?php echo esc_url(get_permalink((int) ($plate['id'] ?? 0))); ?>">
|
||||
<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'] ?? 0)); ?></span>
|
||||
</div>
|
||||
</a>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php if (!empty($followed_plates)) : ?>
|
||||
<h3 class="uh-forum__section-title"><i class="fas fa-heart"></i> <?php esc_html_e('关注的版块', 'aksrt'); ?></h3>
|
||||
<div class="uh-forum__plate-grid">
|
||||
<?php foreach ($followed_plates as $plate) : ?>
|
||||
<a class="uh-forum__plate-card" href="<?php echo esc_url(get_permalink((int) ($plate['id'] ?? 0))); ?>">
|
||||
<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'] ?? 0)); ?></span>
|
||||
<span><?php printf(esc_html__('%d 关注', 'aksrt'), (int) ($plate['follow_count'] ?? 0)); ?></span>
|
||||
</div>
|
||||
</a>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php else : ?>
|
||||
<?php aksrt_render_profile_empty($svg_empty_post, __('暂无版块数据', 'aksrt')); ?>
|
||||
<?php endif; ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (in_array('follow', $enabled_tabs, true)) : ?>
|
||||
<div id="panel-follow" class="dashboard-panel<?php echo $active_tab === 'follow' ? ' is-active' : ''; ?>" role="tabpanel"<?php echo $active_tab !== 'follow' ? ' hidden' : ''; ?>>
|
||||
<?php
|
||||
if ($forum_instance) :
|
||||
$followed = $forum_instance->get_user_followed_plates($user_id);
|
||||
if (!empty($followed)) : ?>
|
||||
<div class="uh-forum__plate-grid">
|
||||
<?php foreach ($followed as $plate) : ?>
|
||||
<a class="uh-forum__plate-card" href="<?php echo esc_url(get_permalink((int) ($plate['id'] ?? 0))); ?>">
|
||||
<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'] ?? 0)); ?></span>
|
||||
<span><?php printf(esc_html__('%d 关注', 'aksrt'), (int) ($plate['follow_count'] ?? 0)); ?></span>
|
||||
</div>
|
||||
</a>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<?php aksrt_render_profile_empty($svg_empty_post, __('暂未关注任何版块', 'aksrt')); ?>
|
||||
<?php endif;
|
||||
else :
|
||||
aksrt_render_profile_empty($svg_empty_post, __('暂无关注内容', 'aksrt'));
|
||||
endif;
|
||||
?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if (!empty($user_home_settings['sidebar'])) : ?>
|
||||
<div class="sidebar uc-sidebar aksrt-user-home__aside" role="complementary" aria-label="<?php esc_attr_e('用户主页侧栏', 'aksrt'); ?>">
|
||||
<div class="uc-sidebar__section">
|
||||
<div class="uc-sidebar__title"><?php esc_html_e('主页概览', 'aksrt'); ?></div>
|
||||
<div class="uc-stats">
|
||||
<?php foreach ($enabled_tabs as $tab_key) : ?>
|
||||
<a class="uc-stats__item" href="<?php echo esc_url(add_query_arg('tab', $tab_key, $home_url)); ?>">
|
||||
<span class="uc-stats__value"><?php echo esc_html((string) ($tab_counts[$tab_key] ?? 0)); ?></span>
|
||||
<span class="uc-stats__label"><?php echo esc_html($tab_labels[$tab_key] ?? ucfirst($tab_key)); ?></span>
|
||||
</a>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if (!empty($user_contacts) && !empty($user_center_settings['social_links'])) : ?>
|
||||
<div class="uc-sidebar__section">
|
||||
<div class="uc-sidebar__title"><?php esc_html_e('公开联系', 'aksrt'); ?></div>
|
||||
<div class="aksrt-user-home__contacts">
|
||||
<?php if (function_exists('aksrt_render_social_links')) : ?>
|
||||
<?php aksrt_render_social_links($user_contacts); ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="uc-sidebar__section">
|
||||
<div class="uc-sidebar__title"><?php esc_html_e('快捷入口', 'aksrt'); ?></div>
|
||||
<div class="uc-sidebar__buttons">
|
||||
<a href="<?php echo esc_url($home_url); ?>" class="uc-sidebar__btn">
|
||||
<i class="fas fa-user" aria-hidden="true"></i>
|
||||
<span><?php esc_html_e('主页首页', 'aksrt'); ?></span>
|
||||
</a>
|
||||
<?php if ($is_own_profile) : ?>
|
||||
<a href="<?php echo esc_url(aksrt_get_user_center_url()); ?>" class="uc-sidebar__btn">
|
||||
<i class="fas fa-cog" aria-hidden="true"></i>
|
||||
<span><?php esc_html_e('个人中心', 'aksrt'); ?></span>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if ($is_own_profile) : ?>
|
||||
<?php
|
||||
$orders_url = function_exists('aksrt_get_orders_page_url') ? aksrt_get_orders_page_url() : '';
|
||||
$show_vip = class_exists('AKSRT_Settings') && !empty(AKSRT_Settings::get_all()['payment_vip_enabled']);
|
||||
$credits_enabled = class_exists('AKSRT_Settings') && AKSRT_Settings::credits_enabled();
|
||||
?>
|
||||
<?php if ($orders_url || $show_vip || $credits_enabled) : ?>
|
||||
<div class="uc-sidebar__section">
|
||||
<div class="uc-sidebar__title"><?php esc_html_e('交易服务', 'aksrt'); ?></div>
|
||||
<div class="uc-sidebar__buttons">
|
||||
<?php if ($orders_url) : ?>
|
||||
<a href="<?php echo esc_url($orders_url); ?>" class="uc-sidebar__btn">
|
||||
<i class="fas fa-receipt" aria-hidden="true"></i>
|
||||
<span><?php esc_html_e('我的订单', 'aksrt'); ?></span>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
<?php if ($show_vip) : ?>
|
||||
<a href="<?php echo esc_url(aksrt_get_user_center_url()); ?>" class="uc-sidebar__btn">
|
||||
<i class="fas fa-crown" aria-hidden="true"></i>
|
||||
<span><?php esc_html_e('VIP 会员', 'aksrt'); ?></span>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
<?php if ($credits_enabled) : ?>
|
||||
<a href="<?php echo esc_url(aksrt_get_user_center_url()); ?>" class="uc-sidebar__btn">
|
||||
<i class="fas fa-coins" aria-hidden="true"></i>
|
||||
<span><?php echo esc_html(AKSRT_Settings::get_currency_name()); ?></span>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php endif; ?>
|
||||
</aside>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<?php get_footer(); ?>
|
||||
@@ -0,0 +1,149 @@
|
||||
<?php
|
||||
/**
|
||||
* Template Name: AKSRT - Verify Email
|
||||
* Template Post Type: page
|
||||
*
|
||||
* Theme auth route template: /verify-email/
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
$verify_error = '';
|
||||
$verify_success = '';
|
||||
$redirect_url = '';
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
if (isset($_POST['verify_email_resend'])) {
|
||||
$result = AKSRT_Auth_Service::resend_email_verification($_POST);
|
||||
if (!empty($result['success'])) {
|
||||
$verify_success = $result['message'] ?? __('验证邮件已重新发送,请注意查收。', 'aksrt');
|
||||
} else {
|
||||
$verify_error = $result['error'] ?? __('验证邮件发送失败,请稍后重试。', 'aksrt');
|
||||
}
|
||||
} elseif (isset($_POST['verify_email_submit'])) {
|
||||
$result = AKSRT_Auth_Service::verify_email_code_submission($_POST);
|
||||
if (!empty($result['success'])) {
|
||||
$verify_success = $result['message'] ?? __('邮箱验证成功,即将进入你的账号。', 'aksrt');
|
||||
$redirect_url = $result['redirect'] ?? '';
|
||||
} else {
|
||||
$verify_error = $result['error'] ?? __('邮箱验证码错误或已过期。', 'aksrt');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$verify_context = AKSRT_Auth_Service::get_email_verification_context($_GET);
|
||||
if ($verify_error === '' && !empty($verify_context['error'])) {
|
||||
$verify_error = $verify_context['error'];
|
||||
}
|
||||
if ($verify_success === '' && !empty($verify_context['message'])) {
|
||||
$verify_success = $verify_context['message'];
|
||||
}
|
||||
if ($redirect_url === '' && !empty($verify_context['redirect'])) {
|
||||
$redirect_url = $verify_context['redirect'];
|
||||
}
|
||||
|
||||
$verify_user = $verify_context['user'] ?? null;
|
||||
$verify_uid = (int) ($verify_context['uid'] ?? 0);
|
||||
$verify_email = (string) ($verify_context['email'] ?? '');
|
||||
$verify_mode = (string) ($verify_context['mode'] ?? 'invalid');
|
||||
$verify_method= (string) ($verify_context['method'] ?? '');
|
||||
$verify_vk = (string) ($verify_context['access_key'] ?? '');
|
||||
|
||||
get_header();
|
||||
?>
|
||||
|
||||
<main id="main-content" class="site-main" tabindex="-1">
|
||||
<div class="auth-shell">
|
||||
<div class="auth-card">
|
||||
<div class="auth-card__logo" aria-hidden="true">AK</div>
|
||||
<h1 class="auth-card__title"><?php bloginfo('name'); ?></h1>
|
||||
|
||||
<?php if ($verify_mode === 'completed' || $verify_mode === 'verified') : ?>
|
||||
<p class="auth-card__subtitle"><?php esc_html_e('邮箱验证成功', 'aksrt'); ?></p>
|
||||
<?php elseif ($verify_mode === 'code') : ?>
|
||||
<p class="auth-card__subtitle"><?php esc_html_e('请输入邮箱验证码完成验证', 'aksrt'); ?></p>
|
||||
<?php elseif ($verify_mode === 'pending') : ?>
|
||||
<p class="auth-card__subtitle"><?php esc_html_e('验证邮件已经发出,请点击邮箱中的链接完成验证', 'aksrt'); ?></p>
|
||||
<?php else : ?>
|
||||
<p class="auth-card__subtitle"><?php esc_html_e('邮箱验证状态异常,请重新检查链接或重新发送验证邮件', 'aksrt'); ?></p>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($verify_error !== '') : ?>
|
||||
<div class="alert alert--error" role="alert">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="10"/><line x1="12" x2="12" y1="8" y2="12"/><line x1="12" x2="12.01" y1="16" y2="16"/></svg>
|
||||
<span><?php echo esc_html($verify_error); ?></span>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($verify_success !== '') : ?>
|
||||
<div class="alert alert--success" role="alert">
|
||||
<span><?php echo esc_html($verify_success); ?></span>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (($verify_mode === 'completed' || $verify_mode === 'verified') && $redirect_url !== '') : ?>
|
||||
<p class="auth-footer-link">
|
||||
<a href="<?php echo esc_url($redirect_url); ?>"><?php esc_html_e('立即进入账号', 'aksrt'); ?></a>
|
||||
</p>
|
||||
<script>
|
||||
setTimeout(function(){ window.location.href = <?php echo wp_json_encode($redirect_url); ?>; }, 1800);
|
||||
</script>
|
||||
<?php elseif ($verify_mode === 'code') : ?>
|
||||
<form class="auth-form" method="post" action="">
|
||||
<?php wp_nonce_field('aksrt_verify_email', '_verify_email_nonce'); ?>
|
||||
<input type="hidden" name="verify_uid" value="<?php echo esc_attr((string) $verify_uid); ?>">
|
||||
<input type="hidden" name="vk" value="<?php echo esc_attr($verify_vk); ?>">
|
||||
<div class="form-field">
|
||||
<label for="verify_email_code"><?php esc_html_e('邮箱验证码', 'aksrt'); ?></label>
|
||||
<div class="input-wrap">
|
||||
<span class="input-icon" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="width:18px;height:18px;"><rect width="20" height="16" x="2" y="4" rx="2"/><path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7"/></svg></span>
|
||||
<input type="text" name="email_code" id="verify_email_code" inputmode="numeric" maxlength="6" pattern="[0-9]*" autocomplete="one-time-code" required>
|
||||
</div>
|
||||
</div>
|
||||
<?php if ($verify_email !== '') : ?>
|
||||
<p class="auth-card__subtitle" style="margin-top:-8px;"><?php echo esc_html(sprintf(__('验证码已发送到 %s', 'aksrt'), $verify_email)); ?></p>
|
||||
<?php endif; ?>
|
||||
<?php if (function_exists('aksrt_render_captcha')) : ?>
|
||||
<?php aksrt_render_captcha('verify_email'); ?>
|
||||
<?php endif; ?>
|
||||
<button type="submit" name="verify_email_submit" class="btn-primary btn-lg btn-block"><?php esc_html_e('验证并登录', 'aksrt'); ?></button>
|
||||
</form>
|
||||
<form method="post" action="" style="margin-top:12px;">
|
||||
<?php wp_nonce_field('aksrt_verify_email', '_verify_email_nonce'); ?>
|
||||
<input type="hidden" name="verify_uid" value="<?php echo esc_attr((string) $verify_uid); ?>">
|
||||
<input type="hidden" name="vk" value="<?php echo esc_attr($verify_vk); ?>">
|
||||
<?php if (function_exists('aksrt_render_captcha')) : ?>
|
||||
<?php aksrt_render_captcha('verify_email'); ?>
|
||||
<?php endif; ?>
|
||||
<button type="submit" name="verify_email_resend" class="btn-primary btn-lg" style="width:100%;background:transparent;color:var(--color-primary);border:1px solid var(--color-primary);"><?php esc_html_e('重新发送验证码', 'aksrt'); ?></button>
|
||||
</form>
|
||||
<?php elseif ($verify_mode === 'pending' && $verify_uid > 0 && $verify_vk !== '') : ?>
|
||||
<?php
|
||||
// method 缺失(历史账号 / meta 被外部清理)→ 回退到设置默认值
|
||||
$resend_method = in_array($verify_method, ['link', 'code'], true)
|
||||
? $verify_method
|
||||
: (class_exists('AKSRT_Settings') ? AKSRT_Settings::registration_verification_method() : 'link');
|
||||
?>
|
||||
<?php if ($verify_email !== '') : ?>
|
||||
<p class="auth-card__subtitle"><?php echo esc_html(sprintf(__('当前待验证邮箱:%s', 'aksrt'), $verify_email)); ?></p>
|
||||
<?php endif; ?>
|
||||
<form method="post" action="">
|
||||
<?php wp_nonce_field('aksrt_verify_email', '_verify_email_nonce'); ?>
|
||||
<input type="hidden" name="verify_uid" value="<?php echo esc_attr((string) $verify_uid); ?>">
|
||||
<input type="hidden" name="vk" value="<?php echo esc_attr($verify_vk); ?>">
|
||||
<?php if (function_exists('aksrt_render_captcha')) : ?>
|
||||
<?php aksrt_render_captcha('verify_email'); ?>
|
||||
<?php endif; ?>
|
||||
<button type="submit" name="verify_email_resend" class="btn-primary btn-lg" style="width:100%;"><?php echo esc_html($resend_method === 'code' ? __('重新发送验证码', 'aksrt') : __('重新发送验证邮件', 'aksrt')); ?></button>
|
||||
</form>
|
||||
<?php endif; ?>
|
||||
|
||||
<p class="auth-footer-link">
|
||||
<a href="<?php echo esc_url(aksrt_get_login_url()); ?>"><?php esc_html_e('返回登录', 'aksrt'); ?></a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<?php
|
||||
get_footer();
|
||||
Reference in new issue
Block a user