feat(pay): wire VIP-tier pricing into cost, gates, and download box

Resolve user-facing pay amounts via aksrt_get_user_pay_price (cash/points +
VIP1/2 tiers), surface pay_modo/pay_limit through download meta and REST policy,
and tighten content-visibility / download-box UX for member-only and purchase
gates while improving local stream throttle math.
This commit is contained in:
kate522 committed 2026-07-14 11:13:17 +08:00
1 parent 1c8e4d3919
commit abe2f57417
5 files changed
+459 -127

No files matched your search

+60 -16
View File
@@ -61,13 +61,21 @@ if (!function_exists('aksrt_get_resource_meta')) {
return $row;
}, $downloads)));
$virtual_sales = max(0, (int) ($pay_meta['virtual_sales'] ?? 0));
$show_sales = !isset($pay_meta['show_sales']) || !empty($pay_meta['show_sales']);
return [
'version' => (string) ($pay_meta['version'] ?? ''),
'size' => (string) ($pay_meta['size'] ?? ''),
'price' => (float) ($pay_meta['price'] ?? 0),
'points_price' => (int) ($pay_meta['points_price'] ?? 0),
'pay_modo' => (($pay_meta['pay_modo'] ?? '0') === 'points') ? 'points' : '0',
'pay_limit' => in_array((int) ($pay_meta['pay_limit'] ?? 0), [0, 1, 2], true) ? (int) $pay_meta['pay_limit'] : 0,
'original_price' => (float) ($pay_meta['original_price'] ?? 0),
'vip1_price' => (float) ($pay_meta['vip1_price'] ?? 0),
'vip2_price' => (float) ($pay_meta['vip2_price'] ?? 0),
'vip1_points' => (int) ($pay_meta['vip1_points'] ?? 0),
'vip2_points' => (int) ($pay_meta['vip2_points'] ?? 0),
'pay_type' => (string) ($pay_meta['pay_type'] ?? AKSRT_Domain_Model::PAY_TYPE_DOWNLOAD),
'license' => (string) ($pay_meta['license'] ?? ''),
'compat' => (string) ($pay_meta['compat'] ?? ''),
@@ -75,6 +83,9 @@ if (!function_exists('aksrt_get_resource_meta')) {
'downloads' => $downloads,
'download_count' => max(0, max($download_count, $legacy_download_count)),
'view_count' => max(0, max($resource_view_count, $common_view_count)),
'virtual_sales' => $virtual_sales,
'sales_count' => $show_sales ? ($virtual_sales + max(0, max($download_count, $legacy_download_count))) : 0,
'show_sales' => $show_sales,
'require_login' => !empty($pay_meta['require_login']),
'require_captcha' => !empty($pay_meta['require_captcha']),
];
@@ -89,9 +100,14 @@ if (!function_exists('aksrt_default_resource_meta')) {
'version' => (string) ($meta['version'] ?? ''),
'size' => (string) ($meta['size'] ?? ''),
'price' => (float) ($meta['price'] ?? 0),
'points_price' => (int) ($meta['points_price'] ?? 0),
'pay_modo' => (($meta['pay_modo'] ?? '0') === 'points') ? 'points' : '0',
'pay_limit' => in_array((int) ($meta['pay_limit'] ?? 0), [0, 1, 2], true) ? (int) $meta['pay_limit'] : 0,
'original_price' => (float) ($meta['original_price'] ?? 0),
'vip1_price' => (float) ($meta['vip1_price'] ?? 0),
'vip2_price' => (float) ($meta['vip2_price'] ?? 0),
'vip1_points' => (int) ($meta['vip1_points'] ?? 0),
'vip2_points' => (int) ($meta['vip2_points'] ?? 0),
'pay_type' => AKSRT_Domain_Model::PAY_TYPE_DOWNLOAD,
'license' => (string) ($meta['license'] ?? ''),
'compat' => (string) ($meta['compat'] ?? ''),
@@ -99,6 +115,9 @@ if (!function_exists('aksrt_default_resource_meta')) {
'downloads' => [],
'download_count' => 0,
'view_count' => 0,
'virtual_sales' => 0,
'sales_count' => 0,
'show_sales' => true,
'require_login' => !empty($meta['require_login']),
'require_captcha' => !empty($meta['require_captcha']),
];
@@ -171,9 +190,6 @@ if (!function_exists('aksrt_resource_card_badge_text')) {
$pay_modo = (($meta['pay_modo'] ?? '0') === 'points') ? 'points' : '0';
$pay_limit = (int) ($meta['pay_limit'] ?? 0);
$price = $pay_modo === 'points'
? (float) ($meta['points_price'] ?? 0)
: (float) ($meta['price'] ?? 0);
$type_labels = function_exists('aksrt_get_pay_types') ? aksrt_get_pay_types() : [];
$type_name = $type_labels[$pay_type] ?? __('付费内容', 'aksrt');
@@ -182,6 +198,15 @@ if (!function_exists('aksrt_resource_card_badge_text')) {
return __('会员专属', 'aksrt');
}
$priced = function_exists('aksrt_get_user_pay_price')
? aksrt_get_user_pay_price($p)
: [
'amount' => $pay_modo === 'points' ? (float) ($meta['points_price'] ?? 0) : (float) ($meta['price'] ?? 0),
'modo' => $pay_modo,
];
$price = (float) ($priced['amount'] ?? 0);
$pay_modo = (($priced['modo'] ?? $pay_modo) === 'points') ? 'points' : '0';
// Free paid-type (price 0).
if ($price <= 0) {
if ($pay_type === 'download') {
@@ -430,14 +455,20 @@ if (!function_exists('aksrt_resource_download_cost')) {
* 优先级:单条 _aksrt_res_price > 全局 download_default_cost。
*/
function aksrt_resource_download_cost($post = null): int {
$meta = aksrt_get_resource_meta($post);
// Prefer unified pay meta when available (pay_modo / points_price).
if (function_exists('aksrt_get_pay_meta')) {
$pay = aksrt_get_pay_meta($post);
if (is_array($pay) && (($pay['pay_type'] ?? '') === 'download' || !empty($pay['downloads']))) {
$meta = array_merge($meta, $pay);
$p = get_post($post);
$uid = function_exists('get_current_user_id') ? (int) get_current_user_id() : 0;
// Paid order → no further credit deduct. Avoid has_paid_access() here (recursion via access state).
if ($p instanceof WP_Post && $uid > 0 && class_exists('AKSRT_Order')) {
if (AKSRT_Order::get_instance()->has_paid_access(
$uid,
AKSRT_Domain_Model::ORDER_PRODUCT_RESOURCE,
(int) $p->ID
)) {
return 0;
}
}
$paid_settings = class_exists('AKSRT_Settings')
? AKSRT_Settings::get_paid_content_settings()
: [
@@ -445,25 +476,38 @@ if (!function_exists('aksrt_resource_download_cost')) {
'default_cost' => 0,
];
$pay_modo = (($meta['pay_modo'] ?? '0') === 'points') ? 'points' : '0';
// Cash mode: do not deduct credits for download unlock (order/cash checkout path).
// Points mode or legacy credit gate: use points_price / price.
$priced = function_exists('aksrt_get_user_pay_price')
? aksrt_get_user_pay_price($post, $uid)
: null;
$pay_modo = is_array($priced) && (($priced['modo'] ?? '0') === 'points') ? 'points' : '0';
if (!is_array($priced) && function_exists('aksrt_get_pay_meta')) {
$pay = aksrt_get_pay_meta($post);
$pay_modo = (($pay['pay_modo'] ?? '0') === 'points') ? 'points' : '0';
}
// Cash mode: order/checkout path unless legacy download_credit is on.
if ($pay_modo !== 'points' && empty($paid_settings['download_credit'])) {
return 0;
}
if ($pay_modo === '0' && empty($paid_settings['download_credit'])) {
// Cash purchase path — cost handled by orders, not credit deduct.
if ($uid > 0 && function_exists('aksrt_is_download_credit_exempt_user') && aksrt_is_download_credit_exempt_user($uid)) {
return 0;
}
if (function_exists('get_current_user_id') && aksrt_is_download_credit_exempt_user((int) get_current_user_id())) {
if (is_array($priced)) {
$price = (float) ($priced['amount'] ?? 0);
if ($price > 0) {
return (int) ceil($price);
}
return 0;
}
// Fallback without helper.
$meta = function_exists('aksrt_get_pay_meta') ? aksrt_get_pay_meta($post) : aksrt_get_resource_meta($post);
if ($pay_modo === 'points') {
$price = (float) ($meta['points_price'] ?? $meta['price'] ?? 0);
} else {
// When download_credit is on, treat price as credit cost (legacy AKSRT).
$price = (float) ($meta['price'] ?? 0);
}
if ($price > 0) {