feat(creator-studio): full pay settings and paid resources in the publish drawer
The drawer only had a pay toggle and one bare price field, so several options from the front-submit pay card could not be set at all. - New PayPanel mirrors the front-submit card: cash / points segment (points only when the site has credits enabled), price or points with the currency suffix, and VIP prices. VIP fields render only when the site asks for manual VIP pricing and the level is enabled, and now submit vip1_points / vip2_points as well. - New ResourceDialog restores "添加资源": download URL with an attachment picker, resource note (extraction code), copy name / value, custom button label and button style swatches. Pasting a net-disk share link splits the URL and the extraction code. - pay.ts sends every download display field and tags net-disk links. - CreatorRest exposes vipManual / vip*Enabled / vip names / pointsEnabled / downloadClasses / currencySymbol, and the readback carries extractCode / copyKey / copyVal / class / attachmentId. - Fixes an existing data loss: snapshot_from_payload dropped copy_key, copy_val, class and attachment_id, so approving a revision erased them. Files split to stay within budget: publish-drawer 332 lines, pay-panel 343, resource-dialog 254. 886 widget-system tests pass.
This commit is contained in:
1 parent
c5bdbc0457
commit
0e4e4670dd
12 files changed
+1022
-224
No files matched your search
@@ -482,29 +482,36 @@ final class CreatorRest {
|
||||
if (!is_array($row)) {
|
||||
continue;
|
||||
}
|
||||
// 资源行里的展示字段与前台投稿的资源编辑器一一对应,缺一个就会在
|
||||
// 审核应用后丢掉提取码 / 复制内容 / 按钮样式。
|
||||
$display = [
|
||||
'label' => (string) ($row['label'] ?? ''),
|
||||
'extract_code' => (string) ($row['extract_code'] ?? ''),
|
||||
'copy_key' => (string) ($row['copy_key'] ?? ''),
|
||||
'copy_val' => (string) ($row['copy_val'] ?? ''),
|
||||
'class' => (string) ($row['class'] ?? ''),
|
||||
'attachment_id' => max(0, (int) ($row['attachment_id'] ?? 0)),
|
||||
];
|
||||
$key = PrivateAssets::sanitize_asset_key((string) ($row['asset_key'] ?? ''));
|
||||
if ($key !== '') {
|
||||
$asset = PrivateAssets::get($key);
|
||||
if ($asset === null || $asset['owner_id'] !== get_current_user_id()) {
|
||||
continue;
|
||||
}
|
||||
$downloads[] = [
|
||||
$downloads[] = array_merge($display, [
|
||||
'type' => 'protected',
|
||||
'asset_key' => $key,
|
||||
'file_name' => $asset['file_name'],
|
||||
'size_bytes' => $asset['size_bytes'],
|
||||
'label' => (string) ($row['label'] ?? ''),
|
||||
];
|
||||
]);
|
||||
continue;
|
||||
}
|
||||
$url = esc_url_raw((string) ($row['url'] ?? ''));
|
||||
if ($url !== '') {
|
||||
$downloads[] = [
|
||||
'type' => 'direct',
|
||||
'url' => $url,
|
||||
'label' => (string) ($row['label'] ?? ''),
|
||||
'extract_code' => (string) ($row['extract_code'] ?? ''),
|
||||
];
|
||||
$downloads[] = array_merge($display, [
|
||||
'type' => (string) ($row['type'] ?? 'direct') === 'net_disk' ? 'net_disk' : 'direct',
|
||||
'url' => $url,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -653,9 +660,17 @@ final class CreatorRest {
|
||||
'label' => (string) ($row['label'] ?? ''),
|
||||
'fileName' => (string) ($row['file_name'] ?? ''),
|
||||
'sizeBytes' => (int) ($row['size_bytes'] ?? 0),
|
||||
// 前台投稿的资源编辑器字段,缺一个就会在再次编辑时丢配置。
|
||||
'extractCode' => (string) ($row['extract_code'] ?? ''),
|
||||
'copyKey' => (string) ($row['copy_key'] ?? ''),
|
||||
'copyVal' => (string) ($row['copy_val'] ?? ''),
|
||||
'class' => (string) ($row['class'] ?? ''),
|
||||
'attachmentId' => (int) ($row['attachment_id'] ?? 0),
|
||||
];
|
||||
}
|
||||
|
||||
$vip = $this->vip_labels();
|
||||
|
||||
return [
|
||||
'enabled' => (bool) $enabled,
|
||||
'canPay' => $front->user_can_cap('new_post_pay', $user),
|
||||
@@ -665,9 +680,21 @@ final class CreatorRest {
|
||||
'points' => (int) ($pay['points_price'] ?? 0),
|
||||
'vip1Price' => (string) ($pay['vip1_price'] ?? '0.00'),
|
||||
'vip2Price' => (string) ($pay['vip2_price'] ?? '0.00'),
|
||||
'vip1Points' => (int) ($pay['vip1_points'] ?? 0),
|
||||
'vip2Points' => (int) ($pay['vip2_points'] ?? 0),
|
||||
'payLimit' => (int) ($pay['pay_limit'] ?? 0),
|
||||
'downloads' => $downloads,
|
||||
'freeAllowed' => !empty($settings['pay_free_s']),
|
||||
// 会员价:手动填写或按折扣自动计算,决定前端是否渲染会员价输入框。
|
||||
'vipManual' => !empty($settings['pay_vip_price_s']),
|
||||
'vip1Enabled' => !empty($settings['pay_vip_1_enabled']),
|
||||
'vip2Enabled' => !empty($settings['pay_vip_2_enabled']),
|
||||
'vip1Name' => $vip[1],
|
||||
'vip2Name' => $vip[2],
|
||||
// 积分支付只有站点开启积分体系时才可选。
|
||||
'pointsEnabled' => class_exists('\Jio\Settings\Settings') && \Jio\Settings\Settings::credits_enabled(),
|
||||
'downloadClasses' => DomainModel::DOWNLOAD_BUTTON_CLASSES,
|
||||
'currencySymbol' => $this->currency_symbol(),
|
||||
'priceMin' => (int) ($settings['pay_price_min'] ?? 0),
|
||||
'priceMax' => (int) ($settings['pay_price_max'] ?? 0),
|
||||
'pointsMin' => (int) ($settings['pay_points_min'] ?? 0),
|
||||
@@ -676,6 +703,36 @@ final class CreatorRest {
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 会员等级名称:与前台付费卡片保持同一来源。
|
||||
*
|
||||
* @return array{1:string,2:string}
|
||||
*/
|
||||
private function vip_labels(): array {
|
||||
$names = [1 => __('VIP1', 'jio'), 2 => __('VIP2', 'jio')];
|
||||
if (!class_exists('\Jio\Settings\PaymentRuntime')) {
|
||||
return $names;
|
||||
}
|
||||
$vip = \Jio\Settings\PaymentRuntime::get_payment_vip_settings();
|
||||
foreach ([1, 2] as $level) {
|
||||
$name = trim((string) ($vip['levels'][$level]['name'] ?? ''));
|
||||
if ($name !== '') {
|
||||
$names[$level] = $name;
|
||||
}
|
||||
}
|
||||
return $names;
|
||||
}
|
||||
|
||||
/** 站点货币符号,用于价格输入框的前缀。 */
|
||||
private function currency_symbol(): string {
|
||||
if (!class_exists('\Jio\Settings\PaymentRuntime')) {
|
||||
return '¥';
|
||||
}
|
||||
$paid = \Jio\Settings\PaymentRuntime::get_paid_content_settings();
|
||||
$symbol = trim((string) ($paid['display']['currency_symbol'] ?? ''));
|
||||
return $symbol !== '' ? $symbol : '¥';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, bool>
|
||||
*/
|
||||
|
||||
Reference in new issue
Block a user