fix(pay): render paid reading as fragments
This commit is contained in:
1 parent
4cc1f2b2ea
commit
f040a680d6
9 files changed
+316
-65
No files matched your search
@@ -119,3 +119,117 @@
|
|||||||
opacity: .85;
|
opacity: .85;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ---- Paid fragment purchase card ---- */
|
||||||
|
.aksrt-paywall {
|
||||||
|
position: relative;
|
||||||
|
margin: 24px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.aksrt-paywall__card {
|
||||||
|
position: relative;
|
||||||
|
z-index: 0;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: auto minmax(0, 1fr) auto;
|
||||||
|
align-items: center;
|
||||||
|
gap: 18px;
|
||||||
|
padding: 22px 24px;
|
||||||
|
background: linear-gradient(135deg, var(--surface-1, #fff) 0%, var(--surface-2, #f8fafc) 100%);
|
||||||
|
border: 1px solid var(--color-line, #e5e7eb);
|
||||||
|
border-radius: var(--radius-lg, 14px);
|
||||||
|
box-shadow: 0 10px 28px rgba(15, 23, 42, .08);
|
||||||
|
}
|
||||||
|
|
||||||
|
.aksrt-paywall--fragment .aksrt-paywall__card {
|
||||||
|
border-style: dashed;
|
||||||
|
border-color: color-mix(in srgb, var(--color-primary, #f04494) 42%, var(--color-line, #e5e7eb));
|
||||||
|
}
|
||||||
|
|
||||||
|
.aksrt-paywall__icon {
|
||||||
|
display: grid;
|
||||||
|
place-items: center;
|
||||||
|
width: 44px;
|
||||||
|
height: 44px;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
border-radius: 50%;
|
||||||
|
color: var(--color-primary, #f04494);
|
||||||
|
background: color-mix(in srgb, var(--color-primary, #f04494) 12%, transparent);
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.aksrt-paywall__body { min-width: 0; }
|
||||||
|
|
||||||
|
.aksrt-paywall__title {
|
||||||
|
margin: 0 0 4px;
|
||||||
|
color: var(--color-ink, #15171a);
|
||||||
|
font-size: 17px;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.aksrt-paywall__desc {
|
||||||
|
margin: 0;
|
||||||
|
color: var(--color-ink-3, #525866);
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.aksrt-paywall__price { margin-top: 8px; }
|
||||||
|
.aksrt-paywall__price-amount { color: var(--color-error, #ef4444); font-size: 20px; font-weight: 700; }
|
||||||
|
.aksrt-paywall__price-member { color: var(--color-primary, #f04494); font-size: 16px; font-weight: 700; }
|
||||||
|
.aksrt-paywall__price-free { color: var(--color-success, #10b981); font-size: 16px; font-weight: 700; }
|
||||||
|
.aksrt-paywall__price-original { margin-left: 8px; color: var(--color-ink-4, #8a8f98); font-size: 13px; text-decoration: line-through; }
|
||||||
|
|
||||||
|
.aksrt-paywall__actions {
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
display: flex;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.aksrt-paywall__btn {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 8px;
|
||||||
|
min-height: 40px;
|
||||||
|
white-space: nowrap;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.aksrt-paywall__btn:focus-visible,
|
||||||
|
.aksrt-paywall__login-link:focus-visible {
|
||||||
|
outline: 3px solid color-mix(in srgb, var(--color-primary, #f04494) 35%, transparent);
|
||||||
|
outline-offset: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.aksrt-paywall__hint,
|
||||||
|
.aksrt-paywall__login-link {
|
||||||
|
margin: 0;
|
||||||
|
color: var(--color-ink-4, #8a8f98);
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.aksrt-paywall__login-link { text-decoration: underline; }
|
||||||
|
.aksrt-gallery-locked { filter: blur(8px); pointer-events: none; user-select: none; }
|
||||||
|
.aksrt-paywall-preview { margin: 0 0 16px; padding: 14px 16px; border-left: 3px solid var(--color-primary, #f04494); background: var(--surface-2, #f8fafc); border-radius: 0 10px 10px 0; color: var(--color-ink-2, #374151); line-height: 1.7; }
|
||||||
|
.aksrt-paywall-preview p:last-child { margin-bottom: 0; }
|
||||||
|
.aksrt-paid-gallery__overlay .but, .aksrt-paid-video__placeholder .but { margin-top: 10px; }
|
||||||
|
|
||||||
|
@media (max-width: 680px) {
|
||||||
|
.aksrt-paywall__card {
|
||||||
|
grid-template-columns: auto minmax(0, 1fr);
|
||||||
|
padding: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.aksrt-paywall__actions {
|
||||||
|
grid-column: 1 / -1;
|
||||||
|
align-items: stretch;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.aksrt-paywall__btn { width: 100%; }
|
||||||
|
}
|
||||||
@@ -363,6 +363,37 @@
|
|||||||
background: var(--surface-2, #f8fafc);
|
background: var(--surface-2, #f8fafc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ---- Paid Fragment ---- */
|
||||||
|
|
||||||
|
.aksrt-paid-fragment-block {
|
||||||
|
margin: 16px 0;
|
||||||
|
border: 1px dashed #ec4899;
|
||||||
|
border-radius: 12px;
|
||||||
|
overflow: hidden;
|
||||||
|
background: #fff7fb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.aksrt-paid-fragment-block .components-notice {
|
||||||
|
margin: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.aksrt-paid-fragment-block__label {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 9px 14px;
|
||||||
|
color: #9d174d;
|
||||||
|
background: #fce7f3;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.aksrt-paid-fragment-block__content {
|
||||||
|
min-height: 72px;
|
||||||
|
padding: 16px;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
/* ── Responsive ── */
|
/* ── Responsive ── */
|
||||||
|
|
||||||
@media (max-width: 767px) {
|
@media (max-width: 767px) {
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
var el = wp.element.createElement;
|
var el = wp.element.createElement;
|
||||||
var Fragment = wp.element.Fragment;
|
var Fragment = wp.element.Fragment;
|
||||||
|
var RawHTML = wp.element.RawHTML;
|
||||||
var registerBlockTypeRaw = wp.blocks.registerBlockType;
|
var registerBlockTypeRaw = wp.blocks.registerBlockType;
|
||||||
var blockEditor = wp.blockEditor || wp.editor || {};
|
var blockEditor = wp.blockEditor || wp.editor || {};
|
||||||
var InspectorControls = blockEditor.InspectorControls || null;
|
var InspectorControls = blockEditor.InspectorControls || null;
|
||||||
@@ -28,6 +29,8 @@
|
|||||||
var TextControl = wp.components.TextControl;
|
var TextControl = wp.components.TextControl;
|
||||||
var ToggleControl = wp.components.ToggleControl;
|
var ToggleControl = wp.components.ToggleControl;
|
||||||
var RangeControl = wp.components.RangeControl;
|
var RangeControl = wp.components.RangeControl;
|
||||||
|
var Notice = wp.components.Notice;
|
||||||
|
var useSelect = window.wp.data && window.wp.data.useSelect;
|
||||||
|
|
||||||
if (!registerBlockTypeRaw || !el) return;
|
if (!registerBlockTypeRaw || !el) return;
|
||||||
|
|
||||||
@@ -750,4 +753,58 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ================================================================
|
||||||
|
// 9. Paid Fragment Block
|
||||||
|
// ================================================================
|
||||||
|
|
||||||
|
function usePaidReadingConfigured() {
|
||||||
|
if (!useSelect) return true;
|
||||||
|
return useSelect(function (select) {
|
||||||
|
var editor = select('core/editor');
|
||||||
|
if (!editor || !editor.getEditedPostAttribute) return true;
|
||||||
|
|
||||||
|
var meta = editor.getEditedPostAttribute('meta') || {};
|
||||||
|
var pay = meta._aksrt_pay || {};
|
||||||
|
if (pay.pay_type !== 'reading') return false;
|
||||||
|
return pay.pay_modo === 'points'
|
||||||
|
? Number(pay.points_price || 0) > 0
|
||||||
|
: Number(pay.price || 0) > 0;
|
||||||
|
}, []);
|
||||||
|
}
|
||||||
|
|
||||||
|
registerBlockType('aksrt/paid-fragment', {
|
||||||
|
title: '付费可见',
|
||||||
|
icon: 'lock',
|
||||||
|
category: CATEGORY,
|
||||||
|
description: '仅购买文章付费阅读后可见的片段。',
|
||||||
|
attributes: {
|
||||||
|
content: { type: 'string', default: '' },
|
||||||
|
},
|
||||||
|
edit: function (props) {
|
||||||
|
var configured = usePaidReadingConfigured();
|
||||||
|
return h('div', { className: 'aksrt-paid-fragment-block' },
|
||||||
|
!configured && Notice ? h(Notice, { status: 'warning', isDismissible: false },
|
||||||
|
'请在“付费内容设置”中选择“付费阅读”并设置有效价格;未配置时此片段会公开显示。'
|
||||||
|
) : null,
|
||||||
|
h('div', { className: 'aksrt-paid-fragment-block__label' },
|
||||||
|
h('span', { className: 'dashicons dashicons-lock', 'aria-hidden': true }),
|
||||||
|
'付费可见片段'
|
||||||
|
),
|
||||||
|
h(RichText, {
|
||||||
|
tagName: 'div',
|
||||||
|
className: 'aksrt-paid-fragment-block__content',
|
||||||
|
value: props.attributes.content,
|
||||||
|
onChange: function (value) { props.setAttributes({ content: value }); },
|
||||||
|
placeholder: '输入购买后可见的内容…',
|
||||||
|
})
|
||||||
|
);
|
||||||
|
},
|
||||||
|
save: function (props) {
|
||||||
|
// Save a single canonical shortcode so hand-written and block-authored
|
||||||
|
// content use the identical server-side rendering path.
|
||||||
|
var shortcode = '[hidecontent type="payshow"]' + props.attributes.content + '[/hidecontent]';
|
||||||
|
return RawHTML ? h(RawHTML, null, shortcode) : shortcode;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
})();
|
})();
|
||||||
@@ -139,7 +139,7 @@ add_action('enqueue_block_editor_assets', function () {
|
|||||||
'aksrt-gutenberg-blocks',
|
'aksrt-gutenberg-blocks',
|
||||||
$base_uri . '/assets/js/gutenberg-blocks.js',
|
$base_uri . '/assets/js/gutenberg-blocks.js',
|
||||||
// wp-media-utils: MediaUpload for carousel block
|
// wp-media-utils: MediaUpload for carousel block
|
||||||
['wp-blocks', 'wp-element', 'wp-components', 'wp-block-editor', 'wp-hooks', 'wp-media-utils'],
|
['wp-blocks', 'wp-element', 'wp-components', 'wp-block-editor', 'wp-hooks', 'wp-media-utils', 'wp-data'],
|
||||||
(string) filemtime($blocks_js),
|
(string) filemtime($blocks_js),
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
|||||||
+72
-51
@@ -675,6 +675,53 @@ if (!function_exists('aksrt_is_paid_reading')) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detect the canonical paid-fragment shortcode in a post's raw content.
|
||||||
|
*
|
||||||
|
* The editor writes this exact shortcode format, so this is the single
|
||||||
|
* source of truth for whether a reading price has any protected fragment to
|
||||||
|
* apply to. It deliberately does not inspect rendered content.
|
||||||
|
*/
|
||||||
|
if (!function_exists('aksrt_post_has_payshow_shortcode')) {
|
||||||
|
function aksrt_post_has_payshow_shortcode($post = null): bool {
|
||||||
|
$p = get_post($post);
|
||||||
|
if (!($p instanceof WP_Post)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return preg_match(
|
||||||
|
'/\[hidecontent\b[^\]]*\btype\s*=\s*(?:"payshow"|\'payshow\'|payshow)[^\]]*\]/i',
|
||||||
|
(string) $p->post_content
|
||||||
|
) === 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A paid fragment is active only for an explicitly priced paid-reading post.
|
||||||
|
*
|
||||||
|
* A zero-price reading configuration is intentionally public: authors can
|
||||||
|
* save content before setting a price without accidentally hiding it.
|
||||||
|
*/
|
||||||
|
if (!function_exists('aksrt_is_payshow_purchase_enabled')) {
|
||||||
|
function aksrt_is_payshow_purchase_enabled($post = null): bool {
|
||||||
|
if (!aksrt_post_has_payshow_shortcode($post)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$meta = aksrt_get_pay_meta($post);
|
||||||
|
if (($meta['pay_type'] ?? AKSRT_PAY_TYPE_NO) !== AKSRT_PAY_TYPE_READING) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$pay_modo = ($meta['pay_modo'] ?? '0') === 'points' ? 'points' : '0';
|
||||||
|
$price = $pay_modo === 'points'
|
||||||
|
? (float) ($meta['points_price'] ?? 0)
|
||||||
|
: (float) ($meta['price'] ?? 0);
|
||||||
|
|
||||||
|
return $price > 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!function_exists('aksrt_is_paid_download')) {
|
if (!function_exists('aksrt_is_paid_download')) {
|
||||||
function aksrt_is_paid_download($post = null): bool {
|
function aksrt_is_paid_download($post = null): bool {
|
||||||
return aksrt_get_pay_meta($post)['pay_type'] === AKSRT_PAY_TYPE_DOWNLOAD;
|
return aksrt_get_pay_meta($post)['pay_type'] === AKSRT_PAY_TYPE_DOWNLOAD;
|
||||||
@@ -1093,7 +1140,7 @@ if (!function_exists('aksrt_get_pay_attributes_html')) {
|
|||||||
// ============================================================
|
// ============================================================
|
||||||
|
|
||||||
if (!function_exists('aksrt_get_paywall_html')) {
|
if (!function_exists('aksrt_get_paywall_html')) {
|
||||||
function aksrt_get_paywall_html(WP_Post $post): string {
|
function aksrt_get_paywall_html(WP_Post $post, bool $is_fragment = false): string {
|
||||||
$meta = aksrt_get_pay_meta($post);
|
$meta = aksrt_get_pay_meta($post);
|
||||||
$pay_type = $meta['pay_type'];
|
$pay_type = $meta['pay_type'];
|
||||||
$priced = function_exists('aksrt_get_user_pay_price') ? aksrt_get_user_pay_price($post) : null;
|
$priced = function_exists('aksrt_get_user_pay_price') ? aksrt_get_user_pay_price($post) : null;
|
||||||
@@ -1117,6 +1164,9 @@ if (!function_exists('aksrt_get_paywall_html')) {
|
|||||||
];
|
];
|
||||||
|
|
||||||
$type_info = $type_labels[$pay_type] ?? $type_labels[AKSRT_PAY_TYPE_READING];
|
$type_info = $type_labels[$pay_type] ?? $type_labels[AKSRT_PAY_TYPE_READING];
|
||||||
|
if ($is_fragment && $pay_type === AKSRT_PAY_TYPE_READING) {
|
||||||
|
$type_info['desc'] = __('付费后即可查看此片段内容', 'aksrt');
|
||||||
|
}
|
||||||
$login_url = function_exists('aksrt_get_login_url') ? aksrt_get_login_url() : wp_login_url(get_permalink($post));
|
$login_url = function_exists('aksrt_get_login_url') ? aksrt_get_login_url() : wp_login_url(get_permalink($post));
|
||||||
$is_logged_in = is_user_logged_in();
|
$is_logged_in = is_user_logged_in();
|
||||||
$original_price = (float) ($meta['original_price'] ?? 0);
|
$original_price = (float) ($meta['original_price'] ?? 0);
|
||||||
@@ -1129,13 +1179,12 @@ if (!function_exists('aksrt_get_paywall_html')) {
|
|||||||
|
|
||||||
ob_start();
|
ob_start();
|
||||||
?>
|
?>
|
||||||
<div class="aksrt-paywall" data-post-id="<?php echo esc_attr((string) $post->ID); ?>" data-pay-type="<?php echo esc_attr($pay_type); ?>" data-pay-modo="<?php echo esc_attr($pay_modo); ?>">
|
<div class="aksrt-paywall<?php echo $is_fragment ? ' aksrt-paywall--fragment' : ''; ?>" data-post-id="<?php echo esc_attr((string) $post->ID); ?>" data-pay-type="<?php echo esc_attr($pay_type); ?>" data-pay-modo="<?php echo esc_attr($pay_modo); ?>">
|
||||||
<div class="aksrt-paywall__overlay">
|
<div class="aksrt-paywall__card" role="group" aria-label="<?php esc_attr_e('付费内容购买', 'aksrt'); ?>">
|
||||||
<div class="aksrt-paywall__blur"></div>
|
<div class="aksrt-paywall__icon">
|
||||||
<div class="aksrt-paywall__card">
|
<i class="fas <?php echo esc_attr($type_info['icon']); ?>" aria-hidden="true"></i>
|
||||||
<div class="aksrt-paywall__icon">
|
</div>
|
||||||
<i class="fas <?php echo esc_attr($type_info['icon']); ?>" aria-hidden="true"></i>
|
<div class="aksrt-paywall__body">
|
||||||
</div>
|
|
||||||
<h3 class="aksrt-paywall__title"><?php echo esc_html($type_info['label']); ?></h3>
|
<h3 class="aksrt-paywall__title"><?php echo esc_html($type_info['label']); ?></h3>
|
||||||
<p class="aksrt-paywall__desc"><?php echo esc_html($type_info['desc']); ?></p>
|
<p class="aksrt-paywall__desc"><?php echo esc_html($type_info['desc']); ?></p>
|
||||||
<div class="aksrt-paywall__price">
|
<div class="aksrt-paywall__price">
|
||||||
@@ -1150,18 +1199,18 @@ if (!function_exists('aksrt_get_paywall_html')) {
|
|||||||
<span class="aksrt-paywall__price-free"><?php esc_html_e('免费', 'aksrt'); ?></span>
|
<span class="aksrt-paywall__price-free"><?php esc_html_e('免费', 'aksrt'); ?></span>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="aksrt-paywall__actions">
|
||||||
<?php if (!$is_logged_in) : ?>
|
<?php if (!$is_logged_in) : ?>
|
||||||
<?php if ($pay_limit <= 0 && $price > 0 && $pay_modo !== 'points' && function_exists('aksrt_allow_guest_content_pay') && aksrt_allow_guest_content_pay($post)) : ?>
|
<?php if ($pay_limit <= 0 && $price > 0 && $pay_modo !== 'points' && function_exists('aksrt_allow_guest_content_pay') && aksrt_allow_guest_content_pay($post)) : ?>
|
||||||
<button type="button" class="but <?php echo $pay_modo === 'points' ? 'jb-yellow' : 'jb-red'; ?> padding-lg cashier-link aksrt-paywall__btn" data-aksrt-pay-content="<?php echo esc_attr((string) $post->ID); ?>">
|
<button type="button" class="but <?php echo $pay_modo === 'points' ? 'jb-yellow' : 'jb-red'; ?> padding-lg cashier-link aksrt-paywall__btn" data-aksrt-pay-content="<?php echo esc_attr((string) $post->ID); ?>">
|
||||||
<i class="fa fa-shopping-cart" aria-hidden="true"></i> <?php printf(esc_html__('游客购买(%s)', 'aksrt'), $price_text); ?>
|
<i class="fa fa-shopping-cart" aria-hidden="true"></i> <?php printf(esc_html__('游客购买(%s)', 'aksrt'), $price_text); ?>
|
||||||
</button>
|
</button>
|
||||||
<p class="aksrt-paywall__hint" style="margin-top:10px;">
|
<a href="<?php echo esc_url($login_url); ?>" class="aksrt-paywall__login-link"><?php esc_html_e('已有账号?登录后购买', 'aksrt'); ?></a>
|
||||||
<a href="<?php echo esc_url($login_url); ?>"><?php esc_html_e('已有账号?登录后购买', 'aksrt'); ?></a>
|
|
||||||
</p>
|
|
||||||
<?php else : ?>
|
<?php else : ?>
|
||||||
<a href="<?php echo esc_url($login_url); ?>" class="but jb-red padding-lg aksrt-paywall__btn">
|
<a href="<?php echo esc_url($login_url); ?>" class="but jb-red padding-lg aksrt-paywall__btn">
|
||||||
<i class="fa fa-sign-in" aria-hidden="true"></i> <?php esc_html_e('登录后购买', 'aksrt'); ?>
|
<i class="fa fa-sign-in" aria-hidden="true"></i> <?php esc_html_e('登录后购买', 'aksrt'); ?>
|
||||||
</a>
|
</a>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
<?php elseif ($member_blocked) : ?>
|
<?php elseif ($member_blocked) : ?>
|
||||||
<a href="<?php echo esc_url($vip_url); ?>" class="but jb-vip padding-lg aksrt-paywall__btn">
|
<a href="<?php echo esc_url($vip_url); ?>" class="but jb-vip padding-lg aksrt-paywall__btn">
|
||||||
@@ -1173,7 +1222,7 @@ if (!function_exists('aksrt_get_paywall_html')) {
|
|||||||
</button>
|
</button>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
<p class="aksrt-paywall__hint">
|
<p class="aksrt-paywall__hint">
|
||||||
<i class="fas fa-shield-alt"></i> <?php esc_html_e('购买后永久有效,支持重复查看', 'aksrt'); ?>
|
<i class="fas fa-shield-alt" aria-hidden="true"></i> <?php esc_html_e('购买后永久有效,支持重复查看', 'aksrt'); ?>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -1183,38 +1232,6 @@ if (!function_exists('aksrt_get_paywall_html')) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================
|
|
||||||
// 付费墙样式注入
|
|
||||||
// ============================================================
|
|
||||||
|
|
||||||
add_action('wp_head', function (): void {
|
|
||||||
if (is_admin() || !is_singular()) return;
|
|
||||||
global $post;
|
|
||||||
if (!($post instanceof WP_Post)) return;
|
|
||||||
if (!function_exists('aksrt_can_access_content') || aksrt_can_access_content($post)) return;
|
|
||||||
?>
|
|
||||||
<style>
|
|
||||||
.aksrt-paywall{position:relative;margin:24px 0}
|
|
||||||
.aksrt-paywall__overlay{position:relative}
|
|
||||||
.aksrt-paywall__blur{filter:blur(12px);pointer-events:none;user-select:none;max-height:200px;overflow:hidden;opacity:.3}
|
|
||||||
.aksrt-paywall__card{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);background:var(--surface-1,#fff);border:1px solid var(--color-line,#e5e7eb);border-radius:var(--radius-lg,14px);padding:40px;text-align:center;box-shadow:0 12px 40px rgba(0,0,0,.12);min-width:320px;max-width:420px}
|
|
||||||
.aksrt-paywall__icon{font-size:48px;color:var(--color-primary,#f04494);margin-bottom:16px}
|
|
||||||
.aksrt-paywall__title{font-size:20px;font-weight:700;margin:0 0 8px;color:var(--color-ink,#15171A)}
|
|
||||||
.aksrt-paywall__desc{font-size:14px;color:var(--color-ink-3,#525866);margin:0 0 20px}
|
|
||||||
.aksrt-paywall__price{margin-bottom:20px}
|
|
||||||
.aksrt-paywall__price-amount{font-size:28px;font-weight:700;color:var(--color-error,#EF4444)}
|
|
||||||
.aksrt-paywall__price-original{font-size:14px;color:var(--color-ink-4,#8A8F98);text-decoration:line-through;margin-left:8px}
|
|
||||||
.aksrt-paywall__price-free{font-size:20px;font-weight:600;color:var(--color-success,#10B981)}
|
|
||||||
.aksrt-paywall__btn{display:inline-flex;align-items:center;gap:8px}
|
|
||||||
.aksrt-paywall__hint{font-size:12px;color:var(--color-ink-4,#8A8F98);margin:16px 0 0}
|
|
||||||
.aksrt-gallery-locked{filter:blur(8px);pointer-events:none;user-select:none}
|
|
||||||
.aksrt-paywall-preview{margin:0 0 16px;padding:14px 16px;border-left:3px solid var(--color-primary,#f04494);background:var(--surface-2,#f8fafc);border-radius:0 10px 10px 0;color:var(--color-ink-2,#374151);line-height:1.7}
|
|
||||||
.aksrt-paywall-preview p:last-child{margin-bottom:0}
|
|
||||||
.aksrt-paid-gallery__overlay .but,.aksrt-paid-video__placeholder .but{margin-top:10px}
|
|
||||||
</style>
|
|
||||||
<?php
|
|
||||||
});
|
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
// 付费图库轮播(Swiper)
|
// 付费图库轮播(Swiper)
|
||||||
// ============================================================
|
// ============================================================
|
||||||
@@ -1362,13 +1379,17 @@ if (!function_exists('aksrt_paid_content_filter')) {
|
|||||||
if (!($post instanceof WP_Post)) {
|
if (!($post instanceof WP_Post)) {
|
||||||
return $content;
|
return $content;
|
||||||
}
|
}
|
||||||
|
$meta = aksrt_get_pay_meta($post);
|
||||||
|
$pay_type = (string) ($meta['pay_type'] ?? AKSRT_PAY_TYPE_NO);
|
||||||
|
// Reading is protected only by the payshow shortcode. Never replace
|
||||||
|
// the entire article body with a post-level purchase wall.
|
||||||
|
if ($pay_type === AKSRT_PAY_TYPE_READING) {
|
||||||
|
return $content;
|
||||||
|
}
|
||||||
if (aksrt_can_access_content($post)) {
|
if (aksrt_can_access_content($post)) {
|
||||||
return $content;
|
return $content;
|
||||||
}
|
}
|
||||||
|
if (!in_array($pay_type, [AKSRT_PAY_TYPE_GALLERY, AKSRT_PAY_TYPE_VIDEO], true)) {
|
||||||
$meta = aksrt_get_pay_meta($post);
|
|
||||||
$pay_type = (string) ($meta['pay_type'] ?? AKSRT_PAY_TYPE_NO);
|
|
||||||
if (!in_array($pay_type, [AKSRT_PAY_TYPE_READING, AKSRT_PAY_TYPE_GALLERY, AKSRT_PAY_TYPE_VIDEO], true)) {
|
|
||||||
return $content;
|
return $content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -74,8 +74,9 @@ if (!function_exists('aksrt_single_build_context')) :
|
|||||||
$pay_meta = function_exists('aksrt_get_pay_meta') ? aksrt_get_pay_meta($post_id) : ['pay_type' => 'no'];
|
$pay_meta = function_exists('aksrt_get_pay_meta') ? aksrt_get_pay_meta($post_id) : ['pay_type' => 'no'];
|
||||||
$pay_type = (string) ($pay_meta['pay_type'] ?? 'no');
|
$pay_type = (string) ($pay_meta['pay_type'] ?? 'no');
|
||||||
$is_paid_post = function_exists('aksrt_is_paid_post') && aksrt_is_paid_post($post_id);
|
$is_paid_post = function_exists('aksrt_is_paid_post') && aksrt_is_paid_post($post_id);
|
||||||
// Pay module: download box OR non-download paid types (reading/gallery/video/vip).
|
// Paid-reading purchase is rendered inline by each payshow shortcode.
|
||||||
$show_pay_box = $has_download || ($is_paid_post && $pay_type !== 'no' && $pay_type !== 'download');
|
// Keep the article-level module for download, gallery, video and VIP only.
|
||||||
|
$show_pay_box = $has_download || ($is_paid_post && !in_array($pay_type, ['no', 'download', 'reading'], true));
|
||||||
|
|
||||||
$breadcrumbs_html = '';
|
$breadcrumbs_html = '';
|
||||||
if (!empty($settings['breadcrumbs']) && function_exists('aksrt_breadcrumbs')) {
|
if (!empty($settings['breadcrumbs']) && function_exists('aksrt_breadcrumbs')) {
|
||||||
|
|||||||
@@ -89,6 +89,10 @@ class ResourceMetaBox {
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<p class="aksrt-pmb__hint" id="aksrt-pmb-reading-hint" hidden>
|
||||||
|
<?php esc_html_e('付费阅读价格只作用于正文中的“付费可见”片段;未插入片段时,正文保持公开。', 'aksrt'); ?>
|
||||||
|
</p>
|
||||||
|
|
||||||
<div class="aksrt-pmb__fields" id="aksrt-pmb-fields" data-disabled="<?php echo $is_paid ? '0' : '1'; ?>">
|
<div class="aksrt-pmb__fields" id="aksrt-pmb-fields" data-disabled="<?php echo $is_paid ? '0' : '1'; ?>">
|
||||||
|
|
||||||
<!-- 基础价格 -->
|
<!-- 基础价格 -->
|
||||||
@@ -378,6 +382,9 @@ class ResourceMetaBox {
|
|||||||
var isPaid = t !== 'no';
|
var isPaid = t !== 'no';
|
||||||
fields.setAttribute('data-disabled', isPaid ? '0' : '1');
|
fields.setAttribute('data-disabled', isPaid ? '0' : '1');
|
||||||
|
|
||||||
|
var readingHint = document.getElementById('aksrt-pmb-reading-hint');
|
||||||
|
if (readingHint) readingHint.hidden = t !== 'reading';
|
||||||
|
|
||||||
// 根据付费类型显示/隐藏相关字段
|
// 根据付费类型显示/隐藏相关字段
|
||||||
if (dlFields) dlFields.style.display = (t === 'download') ? '' : 'none';
|
if (dlFields) dlFields.style.display = (t === 'download') ? '' : 'none';
|
||||||
if (galleryFields) galleryFields.style.display = (t === 'gallery') ? '' : 'none';
|
if (galleryFields) galleryFields.style.display = (t === 'gallery') ? '' : 'none';
|
||||||
|
|||||||
@@ -163,10 +163,15 @@ class Setup {
|
|||||||
'type' => 'string',
|
'type' => 'string',
|
||||||
'enum' => array_keys(DomainModel::pay_type_labels()),
|
'enum' => array_keys(DomainModel::pay_type_labels()),
|
||||||
],
|
],
|
||||||
|
'pay_modo' => ['type' => 'string', 'enum' => ['0', 'points']],
|
||||||
'price' => ['type' => 'number'],
|
'price' => ['type' => 'number'],
|
||||||
|
'points_price' => ['type' => 'integer'],
|
||||||
'original_price' => ['type' => 'number'],
|
'original_price' => ['type' => 'number'],
|
||||||
'vip1_price' => ['type' => 'number'],
|
'vip1_price' => ['type' => 'number'],
|
||||||
'vip2_price' => ['type' => 'number'],
|
'vip2_price' => ['type' => 'number'],
|
||||||
|
'vip1_points' => ['type' => 'integer'],
|
||||||
|
'vip2_points' => ['type' => 'integer'],
|
||||||
|
'pay_limit' => ['type' => 'integer', 'enum' => [0, 1, 2]],
|
||||||
'version' => ['type' => 'string'],
|
'version' => ['type' => 'string'],
|
||||||
'size' => ['type' => 'string'],
|
'size' => ['type' => 'string'],
|
||||||
'license' => ['type' => 'string'],
|
'license' => ['type' => 'string'],
|
||||||
|
|||||||
+26
-11
@@ -101,6 +101,17 @@ class Shortcodes {
|
|||||||
$atts = shortcode_atts(['message' => ''], $atts, 'payshow');
|
$atts = shortcode_atts(['message' => ''], $atts, 'payshow');
|
||||||
$pid = get_the_ID();
|
$pid = get_the_ID();
|
||||||
|
|
||||||
|
$post = $pid > 0 ? get_post($pid) : null;
|
||||||
|
// Payshow is a paid-reading fragment, not a generic hide mechanism.
|
||||||
|
// Until the post has an active reading price, keep its content public
|
||||||
|
// so authors can compose and publish before completing price setup.
|
||||||
|
if (!($post instanceof \WP_Post)
|
||||||
|
|| !function_exists('aksrt_is_payshow_purchase_enabled')
|
||||||
|
|| !aksrt_is_payshow_purchase_enabled($post)) {
|
||||||
|
return '<div class="aksrt-hidden-content aksrt-hidden-content--unlocked aksrt-hidden-content--payshow">'
|
||||||
|
. do_shortcode($content) . '</div>';
|
||||||
|
}
|
||||||
|
|
||||||
$can_view = $this->viewer_can_see_paid_block($pid);
|
$can_view = $this->viewer_can_see_paid_block($pid);
|
||||||
|
|
||||||
if ($can_view) {
|
if ($can_view) {
|
||||||
@@ -109,18 +120,22 @@ class Shortcodes {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$message = $atts['message'] ?: __('此内容需付费后查看', 'aksrt');
|
$message = $atts['message'] ?: __('此内容需付费后查看', 'aksrt');
|
||||||
$uid = get_current_user_id();
|
if (function_exists('aksrt_get_paywall_html')) {
|
||||||
$html = '<div class="aksrt-hidden-content aksrt-hidden-content--locked aksrt-hidden-content--payshow">';
|
$paywall = aksrt_get_paywall_html($post, true);
|
||||||
$html .= '<div class="aksrt-hidden-content__message">';
|
if ($message !== '') {
|
||||||
$html .= '<i class="fas fa-lock" aria-hidden="true"></i> ';
|
$paywall = str_replace(
|
||||||
$html .= '<span>' . esc_html($message) . '</span>';
|
'<p class="aksrt-paywall__desc">',
|
||||||
$html .= '</div>';
|
'<p class="aksrt-paywall__desc">' . esc_html($message) . ' ',
|
||||||
if ($uid <= 0) {
|
$paywall
|
||||||
$html .= '<a href="' . esc_url(wp_login_url(get_permalink())) . '" class="aksrt-hidden-content__login-btn btn-primary btn-sm">';
|
);
|
||||||
$html .= esc_html__('登录后购买查看', 'aksrt') . '</a>';
|
}
|
||||||
|
return $paywall;
|
||||||
}
|
}
|
||||||
$html .= '</div>';
|
|
||||||
return $html;
|
return '<div class="aksrt-hidden-content aksrt-hidden-content--locked aksrt-hidden-content--payshow">'
|
||||||
|
. '<div class="aksrt-hidden-content__message"><i class="fas fa-lock" aria-hidden="true"></i><span>'
|
||||||
|
. esc_html($message)
|
||||||
|
. '</span></div></div>';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in new issue
Block a user