diff --git a/assets/admin/src/schema/sections/payment/paid.js b/assets/admin/src/schema/sections/payment/paid.js
index dddb4c88..0112c630 100644
--- a/assets/admin/src/schema/sections/payment/paid.js
+++ b/assets/admin/src/schema/sections/payment/paid.js
@@ -15,6 +15,8 @@ export const paidSchema = {
pay_show_paycount: true,
pay_box_position: 'top',
payment_download_enable: false,
+ payment_down_alone_page: false,
+ pay_free_logged_show: false,
payment_download_remote_s: true,
payment_download_verify_nonce: true,
payment_download_user_log: 50,
@@ -52,6 +54,7 @@ export const paidSchema = {
{ key: 'pay_show_user', label: '显示购买用户', type: 'switch', default: true },
{ key: 'pay_show_paycount', label: '显示购买次数', type: 'switch', default: true },
{ key: 'pay_box_position', label: '付费框位置', type: 'radio', default: 'top', options: [{ label: '文章框顶部(封面后)', value: 'box_top' }, { label: '正文顶部', value: 'top' }, { label: '正文底部', value: 'bottom' }, { label: '文章框底部(相关前)', value: 'box_bottom' }] },
+ { key: 'pay_free_logged_show', label: '免费资源需登录后下载', type: 'switch', default: false, help: '开启后,价格为 0 的下载资源也要求登录才可下载(对齐 zibll pay_free_logged_show)。' },
],
},
{
@@ -60,6 +63,7 @@ export const paidSchema = {
icon: 'fas fa-cloud-download-alt',
fields: [
{ key: 'payment_download_enable', label: '启用下载功能', type: 'switch', default: false },
+ { key: 'payment_down_alone_page', label: '独立下载页面', type: 'switch', default: false, help: '开启后,已获权限的下载入口跳转到独立下载页(模板:单篇资源下载),而不是在正文内联显示全部下载按钮。', dependsOn: { key: 'payment_download_enable', value: true } },
{ key: 'payment_download_remote_s', label: '远程文件下载', type: 'switch', default: true, dependsOn: { key: 'payment_download_enable', value: true } },
{ key: 'payment_download_verify_nonce', label: '下载鉴权', type: 'switch', default: true, dependsOn: { key: 'payment_download_enable', value: true } },
{ key: 'payment_download_user_log', label: '用户下载记录条数', type: 'number', default: 50, min: 0, max: 9999, help: '0 为不保存', dependsOn: { key: 'payment_download_enable', value: true } },
diff --git a/inc/classes/admin/schema/class-aksrt-admin-schema-payment.php b/inc/classes/admin/schema/class-aksrt-admin-schema-payment.php
index d2c102c0..9b652a40 100644
--- a/inc/classes/admin/schema/class-aksrt-admin-schema-payment.php
+++ b/inc/classes/admin/schema/class-aksrt-admin-schema-payment.php
@@ -40,9 +40,11 @@ class AKSRT_Admin_Schema_Payment {
['label' => '正文底部', 'value' => 'bottom'],
['label' => '文章框底部', 'value' => 'box_bottom'],
]],
+ ['key' => 'pay_free_logged_show', 'label' => '免费资源需登录后下载', 'type' => 'switch', 'default' => false],
]],
['key' => 'download', 'title' => '下载能力', 'fields' => [
['key' => 'payment_download_enable', 'label' => '启用下载能力', 'type' => 'switch', 'default' => false],
+ ['key' => 'payment_down_alone_page', 'label' => '独立下载页面', 'type' => 'switch', 'default' => false],
['key' => 'payment_download_remote_s', 'label' => '远程文件下载', 'type' => 'switch', 'default' => true],
['key' => 'payment_download_verify_nonce', 'label' => '下载鉴权', 'type' => 'switch', 'default' => true],
['key' => 'payment_download_user_log', 'label' => '用户下载记录条数', 'type' => 'number', 'default' => 50, 'min' => 0, 'max' => 9999],
diff --git a/inc/classes/settings/class-aksrt-settings-payment-runtime.php b/inc/classes/settings/class-aksrt-settings-payment-runtime.php
index bd805076..bb25cd25 100644
--- a/inc/classes/settings/class-aksrt-settings-payment-runtime.php
+++ b/inc/classes/settings/class-aksrt-settings-payment-runtime.php
@@ -53,6 +53,8 @@ class AKSRT_Settings_Payment_Runtime {
'catalog_note' => $catalog_note,
'manual_delivery_note' => $manual_note !== '' ? $manual_note : __('付费或人工确认内容请在订单备注中记录交付方式。', 'aksrt'),
'no_logged_in' => !isset($settings['pay_no_logged_in']) || !empty($settings['pay_no_logged_in']),
+ 'free_logged_show' => !empty($settings['pay_free_logged_show']),
+ 'down_alone_page' => !empty($settings['payment_down_alone_page']),
'display' => [
'mark' => sanitize_text_field((string) ($settings['pay_mark'] ?? '付费')),
'currency_symbol' => sanitize_text_field((string) ($settings['payment_currency_symbol'] ?? '¥')),
@@ -68,6 +70,7 @@ class AKSRT_Settings_Payment_Runtime {
'post_log' => max(0, min(9999, (int) ($settings['payment_download_post_log'] ?? 50))),
'remote_size' => max(1, (int) ($settings['payment_download_remote_size'] ?? 2048)),
'remote_ext' => sanitize_text_field((string) ($settings['payment_download_remote_ext'] ?? 'zip,rar,7z')),
+ 'alone_page' => !empty($settings['payment_down_alone_page']),
],
];
}
diff --git a/inc/helpers/aksrt-pay.php b/inc/helpers/aksrt-pay.php
index 59bb9d02..83da69da 100644
--- a/inc/helpers/aksrt-pay.php
+++ b/inc/helpers/aksrt-pay.php
@@ -328,6 +328,45 @@ if (!function_exists('aksrt_get_download_cost')) {
}
}
+/**
+ * URL of the Zibll-style single-post download page (page template + ?post=ID).
+ */
+if (!function_exists('aksrt_get_single_download_page_url')) {
+ function aksrt_get_single_download_page_url($post = null): string {
+ $p = get_post($post);
+ if (!($p instanceof WP_Post)) {
+ return '';
+ }
+
+ $page_url = '';
+ if (function_exists('aksrt_find_template_page')) {
+ $page = aksrt_find_template_page('templates/pages/page-download-file.php');
+ if ($page instanceof WP_Post) {
+ $page_url = get_permalink($page);
+ }
+ }
+ if ($page_url === '') {
+ // Fallback: look for any page using the template via slug convention.
+ $page_url = home_url('/download-file/');
+ }
+
+ return add_query_arg('post', (int) $p->ID, $page_url);
+ }
+}
+
+/**
+ * Whether independent download page mode is enabled (Zibll down_alone_page).
+ */
+if (!function_exists('aksrt_is_download_alone_page_enabled')) {
+ function aksrt_is_download_alone_page_enabled(): bool {
+ if (!class_exists('AKSRT_Settings')) {
+ return false;
+ }
+ $paid = AKSRT_Settings::get_paid_content_settings();
+ return !empty($paid['down_alone_page']) || !empty($paid['download']['alone_page']);
+ }
+}
+
// ============================================================
// 价格显示
// ============================================================
diff --git a/inc/helpers/aksrt-resource.php b/inc/helpers/aksrt-resource.php
index f3d6798c..102ea911 100644
--- a/inc/helpers/aksrt-resource.php
+++ b/inc/helpers/aksrt-resource.php
@@ -145,28 +145,54 @@ if (!function_exists('aksrt_resource_price_amount')) {
if (!function_exists('aksrt_resource_card_badge_text')) {
/**
- * Resource badge text used in mixed post cards.
+ * List-card pay badge (Zibll zib_get_posts_list_pay_tags equivalent).
*
- * Only resource-type posts should render this badge.
+ * Renders for any paid post type, not only download resources.
+ * Returns plain text; card template wraps with link + class.
*
* @param int|WP_Post|null $post
* @return string
*/
function aksrt_resource_card_badge_text($post = null): string {
- if (!function_exists('aksrt_is_resource_post') || !aksrt_is_resource_post($post)) {
+ $p = get_post($post);
+ if (!($p instanceof WP_Post)) {
return '';
}
- $meta = aksrt_get_resource_meta($post);
- $price = (float) $meta['price'];
-
- if ($price <= 0) {
- // 免费资源不在卡片上显示价格 chip。
+ $meta = function_exists('aksrt_get_pay_meta') ? aksrt_get_pay_meta($p) : null;
+ if (!is_array($meta)) {
return '';
}
+ $pay_type = (string) ($meta['pay_type'] ?? 'no');
+ if ($pay_type === '' || $pay_type === 'no') {
+ return '';
+ }
+
+ $price = (float) ($meta['price'] ?? 0);
+ $type_labels = function_exists('aksrt_get_pay_types') ? aksrt_get_pay_types() : [];
+ $type_name = $type_labels[$pay_type] ?? __('付费内容', 'aksrt');
+
+ // VIP-only posts.
+ if ($pay_type === 'vip') {
+ return __('会员专属', 'aksrt');
+ }
+
+ // Free paid-type (price 0): Zibll shows "免费资源" / free type name.
+ if ($price <= 0) {
+ if ($pay_type === 'download') {
+ return __('免费资源', 'aksrt');
+ }
+ // e.g. 付费阅读 → 免费阅读
+ return str_replace(__('付费', 'aksrt'), __('免费', 'aksrt'), (string) $type_name);
+ }
+
$currency = class_exists('AKSRT_Settings') ? AKSRT_Settings::get_currency_name() : __('积分', 'aksrt');
- return sprintf(__('付费 %s %s', 'aksrt'), aksrt_resource_price_amount($price), $currency);
+ $amount = function_exists('aksrt_resource_price_amount')
+ ? aksrt_resource_price_amount($price)
+ : (string) $price;
+
+ return sprintf('%s %s%s', $type_name, $amount, $currency);
}
}
diff --git a/templates/pages/page-download-file.php b/templates/pages/page-download-file.php
new file mode 100644
index 00000000..50a02c44
--- /dev/null
+++ b/templates/pages/page-download-file.php
@@ -0,0 +1,154 @@
+ 0 ? get_post($post_id) : null;
+
+if (!$post instanceof WP_Post || $post->post_status !== 'publish') {
+ get_header();
+ echo '
- +