fix(payment): 卡密兑换开关收敛为唯一总开关
- 问题:积分卡密兑换报「积分卡密兑换未开启」,因 asset_points_card_enabled 与总开关并存为双重闸门;会员卡同样存在隐藏的第二开关 pay_vip_pass_charge_s。 - 修复:ChargeCard 类型闸门统一只消费后台「余额充值 → 卡密兑换」总开关; 积分卡仅额外要求积分系统可用(系统级依赖,非独立开关)。 - 死代码清理:PaymentRuntime 删除 benefit.pass_charge/pass_charge_desc 映射; 后台 schema 删除「卡密兑换会员」独立开关组与「启用积分卡密兑换」开关(双源同步); vip options 收敛为仅 only_password 展示配置。 - 验证:php -l 4 文件无错;契约测试 59/59 通过;容器内探针实测 credits 类型闸门放行;SPA 已重建并同步运行副本。
This commit is contained in:
@@ -241,10 +241,8 @@ class SchemaPayment {
|
||||
]],
|
||||
]],
|
||||
]],
|
||||
['key' => 'pass-charge', 'title' => '卡密兑换会员', 'fields' => [
|
||||
['key' => 'pay_vip_pass_charge_s', 'label' => '启用卡密兑换会员功能', 'type' => 'switch', 'default' => false],
|
||||
['key' => 'pay_vip_pass_charge_desc', 'label' => '卡密兑换说明', 'type' => 'textarea', 'default' => '', 'dependsOn' => ['key' => 'pay_vip_pass_charge_s', 'value' => true], 'help' => '用户使用卡密兑换时显示的内容,建议为提醒事项、充值协议等,支持HTML代码'],
|
||||
['key' => 'pay_vip_pass_charge_only_password', 'label' => '单密码模式', 'type' => 'switch', 'default' => true, 'dependsOn' => ['key' => 'pay_vip_pass_charge_s', 'value' => true], 'help' => '仅需输入密码,不需要卡号'],
|
||||
['key' => 'pass-charge', 'title' => '会员卡密', 'fields' => [
|
||||
['key' => 'pay_vip_pass_charge_only_password', 'label' => '单密码模式', 'type' => 'switch', 'default' => true, 'help' => '会员卡密核销是否仅需卡密;关闭后,带卡号的会员卡必须同时输入卡号。会员/积分卡密无独立开关,统一受「余额充值 → 卡密兑换 → 启用卡密兑换功能」控制'],
|
||||
]],
|
||||
['key' => 'points-exchange', 'title' => '积分兑换会员', 'fields' => [
|
||||
['key' => 'pay_vip_points_exchange_s', 'label' => '启用积分兑换', 'type' => 'switch', 'default' => false],
|
||||
|
||||
@@ -486,9 +486,6 @@ class SchemaUsers {
|
||||
['key' => 'points_deduction_rate', 'label' => '积分换算比例', 'type' => 'number', 'default' => 100, 'min' => 1, 'max' => 10000, 'help' => '多少积分抵 1 元(legacy points_deduction_rate)。当前未参与下单。'],
|
||||
['key' => 'points_deduction_max', 'label' => '最大抵扣比例(%)', 'type' => 'number', 'default' => 50, 'min' => 1, 'max' => 100, 'help' => '预留:最多可抵订单金额百分比。当前未参与下单。'],
|
||||
]],
|
||||
['key' => 'card_pass', 'title' => '积分卡密兑换', 'fields' => [
|
||||
['key' => 'asset_points_card_enabled', 'label' => '启用积分卡密兑换', 'type' => 'switch', 'default' => false, 'help' => '开启后积分卡密可在用户中心「卡密兑换」弹窗兑换入账'],
|
||||
]],
|
||||
['key' => 'display', 'title' => '展示设置', 'fields' => [
|
||||
['key' => 'points_show_balance', 'label' => '导航栏显示余额', 'type' => 'switch', 'default' => true],
|
||||
['key' => 'points_show_log', 'label' => '显示积分记录', 'type' => 'switch', 'default' => true],
|
||||
|
||||
+24
-41
@@ -112,35 +112,31 @@ class ChargeCard {
|
||||
}
|
||||
|
||||
/**
|
||||
* 前台卡密兑换开关视图(按类型拆分)。
|
||||
* 前台卡密兑换开关视图。
|
||||
*
|
||||
* balance.enabled 语义为「启用卡密兑换功能」总开关(后台 余额充值 → 卡密兑换),
|
||||
* 与收款接口 card_pass 主开关共同决定前台兑换入口是否展示。
|
||||
* 唯一类型闸门:balance.enabled =「启用卡密兑换功能」总开关
|
||||
* (后台 余额充值 → 卡密兑换),并与收款接口 card_pass 主开关共同生效;
|
||||
* 会员/积分卡密不再有独立开关。积分卡额外要求积分系统可用(系统级依赖)。
|
||||
*
|
||||
* @return array<string,mixed>
|
||||
*/
|
||||
public function get_public_options(): array {
|
||||
// Master kill-switch on 收款接口 → 卡密充值.
|
||||
// 收款接口 card_pass 主开关;关闭时所有卡密兑换一并失效。
|
||||
$channel_on = !class_exists('\AKSRT\Settings\PaymentRuntime')
|
||||
|| \AKSRT\Settings\PaymentRuntime::is_gateway_enabled('card_pass');
|
||||
if (!$channel_on) {
|
||||
$off = ['enabled' => false, 'desc' => '', 'only_password' => true];
|
||||
return [
|
||||
'balance' => $off,
|
||||
'vip' => $off,
|
||||
'credits' => ['enabled' => false],
|
||||
];
|
||||
}
|
||||
|
||||
$balance = ['enabled' => false, 'desc' => '', 'only_password' => true];
|
||||
$vip = ['enabled' => false, 'desc' => '', 'only_password' => true];
|
||||
$master_on = false;
|
||||
$balance = ['enabled' => false, 'desc' => '', 'only_password' => true];
|
||||
$vip_only_password = true;
|
||||
$credits_on = false;
|
||||
|
||||
if (class_exists('\AKSRT\Settings\Settings')) {
|
||||
if ($channel_on && class_exists('\AKSRT\Settings\Settings')) {
|
||||
if (method_exists('\AKSRT\Settings\Settings', 'get_payment_recharge_settings')) {
|
||||
$recharge = \AKSRT\Settings\Settings::get_payment_recharge_settings();
|
||||
$pc = is_array($recharge['pass_charge'] ?? null) ? $recharge['pass_charge'] : [];
|
||||
$master_on = !empty($pc['enabled']);
|
||||
$balance = [
|
||||
'enabled' => !empty($pc['enabled']),
|
||||
'enabled' => $master_on,
|
||||
'desc' => (string) ($pc['desc'] ?? ''),
|
||||
'only_password' => !isset($pc['only_password']) || !empty($pc['only_password']),
|
||||
];
|
||||
@@ -148,30 +144,18 @@ class ChargeCard {
|
||||
if (method_exists('\AKSRT\Settings\Settings', 'get_payment_vip_settings')) {
|
||||
$vip_s = \AKSRT\Settings\Settings::get_payment_vip_settings();
|
||||
$benefit = is_array($vip_s['benefit'] ?? null) ? $vip_s['benefit'] : [];
|
||||
$vip = [
|
||||
'enabled' => !empty($benefit['pass_charge']),
|
||||
'desc' => (string) ($benefit['pass_charge_desc'] ?? ''),
|
||||
'only_password' => !isset($benefit['pass_charge_only_password']) || !empty($benefit['pass_charge_only_password']),
|
||||
];
|
||||
$vip_only_password = !isset($benefit['pass_charge_only_password']) || !empty($benefit['pass_charge_only_password']);
|
||||
}
|
||||
if ($master_on) {
|
||||
// 积分卡随总开关生效,仅要求积分系统可用(系统级依赖,非独立开关)。
|
||||
$credits_on = !method_exists('\AKSRT\Settings\Settings', 'credits_enabled') || \AKSRT\Settings\Settings::credits_enabled();
|
||||
}
|
||||
}
|
||||
|
||||
$credits = ['enabled' => false];
|
||||
$all = class_exists('\AKSRT\Settings\Settings') && method_exists('\AKSRT\Settings\Settings', 'get_all')
|
||||
? \AKSRT\Settings\Settings::get_all()
|
||||
: (array) get_option('aksrt_settings', []);
|
||||
if (!empty($all['asset_points_card_enabled'])) {
|
||||
// 积分卡仅作为后端类型闸门(assert_type_enabled);前台兑换统一走
|
||||
// 通用「卡密兑换」弹窗,无独立入口与说明/单密码配置。
|
||||
$credits = [
|
||||
'enabled' => !class_exists('\AKSRT\Settings\Settings') || !method_exists('\AKSRT\Settings\Settings', 'credits_enabled') || \AKSRT\Settings\Settings::credits_enabled(),
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
'balance' => $balance,
|
||||
'vip' => $vip,
|
||||
'credits' => $credits,
|
||||
'vip' => ['only_password' => $vip_only_password],
|
||||
'credits' => ['enabled' => $credits_on],
|
||||
];
|
||||
}
|
||||
|
||||
@@ -835,14 +819,13 @@ class ChargeCard {
|
||||
*/
|
||||
private function assert_type_enabled(string $type) {
|
||||
$opts = $this->get_public_options();
|
||||
if ($type === self::TYPE_BALANCE && empty($opts['balance']['enabled'])) {
|
||||
return new \WP_Error('aksrt_card_disabled', __('余额卡密兑换未开启', 'aksrt'), ['status' => 403]);
|
||||
}
|
||||
if ($type === self::TYPE_VIP && empty($opts['vip']['enabled'])) {
|
||||
return new \WP_Error('aksrt_card_disabled', __('会员卡密兑换未开启', 'aksrt'), ['status' => 403]);
|
||||
// 唯一类型闸门:后台「余额充值 → 卡密兑换」总开关(已含收款接口 card_pass 主开关)。
|
||||
if (empty($opts['balance']['enabled'])) {
|
||||
return new \WP_Error('aksrt_card_disabled', __('卡密兑换功能未开启', 'aksrt'), ['status' => 403]);
|
||||
}
|
||||
// 积分卡额外要求积分系统可用(系统级依赖,非独立开关)。
|
||||
if ($type === self::TYPE_CREDITS && empty($opts['credits']['enabled'])) {
|
||||
return new \WP_Error('aksrt_card_disabled', __('积分卡密兑换未开启', 'aksrt'), ['status' => 403]);
|
||||
return new \WP_Error('aksrt_card_disabled', __('积分系统未开启,无法兑换积分卡密', 'aksrt'), ['status' => 403]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -229,8 +229,7 @@ class PaymentRuntime {
|
||||
],
|
||||
'benefit' => [
|
||||
'download_limit' => max(0, min(9999, (int) ($settings['pay_download_limit'] ?? 0))),
|
||||
'pass_charge' => !empty($settings['pay_vip_pass_charge_s']),
|
||||
'pass_charge_desc' => sanitize_textarea_field((string) ($settings['pay_vip_pass_charge_desc'] ?? '')),
|
||||
// 会员卡密无独立开关(随「启用卡密兑换功能」总开关),仅保留单密码模式。
|
||||
'pass_charge_only_password' => !isset($settings['pay_vip_pass_charge_only_password']) || !empty($settings['pay_vip_pass_charge_only_password']),
|
||||
],
|
||||
'renew' => [
|
||||
|
||||
Reference in New Issue
Block a user