feat(pay): zibll-style pay_modo/points/pay_limit, VIP quota, and local speed stream
Expand post pay meta with cash/points modes and member purchase limits, enforce free-download daily quotas, and stream local files with VIP speed caps while keeping remote links on redirect.
This commit is contained in:
1 parent
8b50687e9d
commit
1c8e4d3919
6 files changed
+311
-33
No files matched your search
@@ -107,10 +107,15 @@ class AKSRT_Domain_Model {
|
||||
public static function default_pay_meta(): array {
|
||||
return [
|
||||
'pay_type' => self::PAY_TYPE_NO,
|
||||
'pay_modo' => '0', // '0' cash | 'points' credits (Zibll)
|
||||
'price' => 0.0,
|
||||
'points_price' => 0,
|
||||
'original_price' => 0.0,
|
||||
'vip1_price' => 0.0,
|
||||
'vip2_price' => 0.0,
|
||||
'vip1_points' => 0,
|
||||
'vip2_points' => 0,
|
||||
'pay_limit' => 0, // 0 all | 1 VIP1+ | 2 VIP2 only (Zibll)
|
||||
'version' => '',
|
||||
'size' => '',
|
||||
'license' => '',
|
||||
@@ -298,10 +303,17 @@ class AKSRT_Domain_Model {
|
||||
public static function sanitize_pay_meta(array $raw): array {
|
||||
$meta = self::default_pay_meta();
|
||||
$meta['pay_type'] = self::normalize_pay_type((string) ($raw['pay_type'] ?? $meta['pay_type']));
|
||||
$pay_modo = sanitize_key((string) ($raw['pay_modo'] ?? '0'));
|
||||
$meta['pay_modo'] = $pay_modo === 'points' ? 'points' : '0';
|
||||
$meta['price'] = max(0, (float) ($raw['price'] ?? 0));
|
||||
$meta['points_price'] = max(0, (int) ($raw['points_price'] ?? $raw['price'] ?? 0));
|
||||
$meta['original_price'] = max(0, (float) ($raw['original_price'] ?? 0));
|
||||
$meta['vip1_price'] = max(0, (float) ($raw['vip1_price'] ?? 0));
|
||||
$meta['vip2_price'] = max(0, (float) ($raw['vip2_price'] ?? 0));
|
||||
$meta['vip1_points'] = max(0, (int) ($raw['vip1_points'] ?? $raw['vip1_price'] ?? 0));
|
||||
$meta['vip2_points'] = max(0, (int) ($raw['vip2_points'] ?? $raw['vip2_price'] ?? 0));
|
||||
$pay_limit = (int) ($raw['pay_limit'] ?? 0);
|
||||
$meta['pay_limit'] = in_array($pay_limit, [0, 1, 2], true) ? $pay_limit : 0;
|
||||
$meta['version'] = sanitize_text_field((string) ($raw['version'] ?? ''));
|
||||
$meta['size'] = sanitize_text_field((string) ($raw['size'] ?? ''));
|
||||
$meta['license'] = sanitize_text_field((string) ($raw['license'] ?? ''));
|
||||
|
||||
@@ -374,19 +374,45 @@ if (!function_exists('aksrt_is_download_alone_page_enabled')) {
|
||||
if (!function_exists('aksrt_get_pay_price_label')) {
|
||||
function aksrt_get_pay_price_label($post = null): array {
|
||||
$meta = aksrt_get_pay_meta($post);
|
||||
$price = (float) $meta['price'];
|
||||
$pay_modo = (($meta['pay_modo'] ?? '0') === 'points') ? 'points' : '0';
|
||||
$pay_limit = (int) ($meta['pay_limit'] ?? 0);
|
||||
$currency = class_exists('AKSRT_Settings') ? AKSRT_Settings::get_currency_name() : __('积分', 'aksrt');
|
||||
|
||||
if ($meta['pay_type'] === AKSRT_PAY_TYPE_VIP) {
|
||||
return ['text' => __('VIP 专属', 'aksrt'), 'free' => false, 'amount' => 0];
|
||||
$cash_symbol = '¥';
|
||||
if (class_exists('AKSRT_Settings')) {
|
||||
$paid = AKSRT_Settings::get_paid_content_settings();
|
||||
$cash_symbol = (string) ($paid['display']['currency_symbol'] ?? '¥');
|
||||
}
|
||||
|
||||
if ($meta['pay_type'] === AKSRT_PAY_TYPE_VIP || $pay_limit > 0) {
|
||||
return ['text' => __('会员专属', 'aksrt'), 'free' => false, 'amount' => 0, 'modo' => $pay_modo, 'pay_limit' => $pay_limit];
|
||||
}
|
||||
|
||||
if ($pay_modo === 'points') {
|
||||
$price = (int) ($meta['points_price'] ?? 0);
|
||||
if ($price <= 0) {
|
||||
return ['text' => __('免费', 'aksrt'), 'free' => true, 'amount' => 0, 'modo' => 'points', 'pay_limit' => 0];
|
||||
}
|
||||
return [
|
||||
'text' => sprintf(__('%s %s', 'aksrt'), aksrt_format_price((float) $price), $currency),
|
||||
'free' => false,
|
||||
'amount' => (float) $price,
|
||||
'modo' => 'points',
|
||||
'pay_limit' => 0,
|
||||
];
|
||||
}
|
||||
|
||||
$price = (float) $meta['price'];
|
||||
if ($price <= 0) {
|
||||
return ['text' => __('免费', 'aksrt'), 'free' => true, 'amount' => 0];
|
||||
return ['text' => __('免费', 'aksrt'), 'free' => true, 'amount' => 0, 'modo' => '0', 'pay_limit' => 0];
|
||||
}
|
||||
|
||||
$amount = aksrt_format_price($price);
|
||||
return ['text' => sprintf(__('%s %s', 'aksrt'), $amount, $currency), 'free' => false, 'amount' => $price];
|
||||
return [
|
||||
'text' => $cash_symbol . aksrt_format_price($price),
|
||||
'free' => false,
|
||||
'amount' => $price,
|
||||
'modo' => '0',
|
||||
'pay_limit' => 0,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -169,30 +169,44 @@ if (!function_exists('aksrt_resource_card_badge_text')) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$price = (float) ($meta['price'] ?? 0);
|
||||
$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');
|
||||
|
||||
// VIP-only posts.
|
||||
if ($pay_type === 'vip') {
|
||||
// VIP-only / purchase limit (Zibll pay_limit).
|
||||
if ($pay_type === 'vip' || $pay_limit > 0) {
|
||||
return __('会员专属', 'aksrt');
|
||||
}
|
||||
|
||||
// Free paid-type (price 0): Zibll shows "免费资源" / free type name.
|
||||
// Free paid-type (price 0).
|
||||
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');
|
||||
$amount = function_exists('aksrt_resource_price_amount')
|
||||
? aksrt_resource_price_amount($price)
|
||||
: (string) $price;
|
||||
if ($pay_modo === 'points') {
|
||||
$currency = class_exists('AKSRT_Settings') ? AKSRT_Settings::get_currency_name() : __('积分', 'aksrt');
|
||||
$amount = function_exists('aksrt_resource_price_amount')
|
||||
? aksrt_resource_price_amount($price)
|
||||
: (string) (int) $price;
|
||||
return sprintf('%s %s%s', $type_name, $amount, $currency);
|
||||
}
|
||||
|
||||
return sprintf('%s %s%s', $type_name, $amount, $currency);
|
||||
$symbol = '¥';
|
||||
if (class_exists('AKSRT_Settings')) {
|
||||
$paid = AKSRT_Settings::get_paid_content_settings();
|
||||
$symbol = (string) ($paid['display']['currency_symbol'] ?? '¥');
|
||||
}
|
||||
$amount = function_exists('aksrt_format_price')
|
||||
? aksrt_format_price($price)
|
||||
: (string) $price;
|
||||
return sprintf('%s %s%s', $type_name, $symbol, $amount);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -417,21 +431,44 @@ if (!function_exists('aksrt_resource_download_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);
|
||||
}
|
||||
}
|
||||
$paid_settings = class_exists('AKSRT_Settings')
|
||||
? AKSRT_Settings::get_paid_content_settings()
|
||||
: [
|
||||
'download_credit' => true,
|
||||
'default_cost' => 0,
|
||||
];
|
||||
if (empty($paid_settings['download_credit'])) return 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.
|
||||
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.
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (function_exists('get_current_user_id') && aksrt_is_download_credit_exempt_user((int) get_current_user_id())) {
|
||||
return 0;
|
||||
}
|
||||
$price = (float) $meta['price'];
|
||||
|
||||
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) {
|
||||
return (int) ceil($price);
|
||||
}
|
||||
// 单条未设价格 → 回退到全局默认价
|
||||
return max(0, (int) ($paid_settings['default_cost'] ?? 0));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user