fix(pay): 会员卡密单密码默认关闭,卡密盒与其他弹窗一致显示卡号+密码

会员购买/续费弹窗卡密盒此前仅显示卡密输入,与其他两个弹窗(卡号+密码)
不一致。根因是 pay_vip_pass_charge_only_password 的默认值偏离参考主题:

- PaymentRuntime:vip 类型 only_password 由「未设置即视为开启」改为
  !empty(),与其他两类型同构(参考主题 default false)
- ChargeCard:get_public_options 的 vip 回退值 only_password true→false
- SchemaPayment + recharge.js:会员卡密单密码模式开关 default true→false
- 契约测试同步锁定默认关闭与无 isset 回退
- admin SPA 重新构建

已保存过设置且该键被持久化为开启的站点,需在后台「余额充值 → 卡密
兑换 → 会员卡密单密码模式」手动关闭一次。
This commit is contained in:
2026-09-18 17:26:50 +08:00
parent b3b21df409
commit db0d63b99f
5 changed files with 10 additions and 5 deletions
@@ -112,7 +112,7 @@ export const rechargeSchema = {
{ key: 'points_pass_exchange_only_password', label: '积分卡密单密码模式', type: 'switch', default: false, dependsOn: { key: 'points_pass_exchange_s', value: true }, help: '积分卡密仅需输入密码,不需要卡号' },
{ key: 'pay_vip_pass_charge_s', label: '启用卡密兑换会员功能', type: 'switch', default: false, help: '开启后用户可在会员购买/续费弹窗选择「卡密」渠道,使用会员卡密直接兑换会员' },
{ key: 'pay_vip_pass_charge_desc', label: '卡密兑换会员说明', type: 'textarea', default: '', rows: 2, 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: 'pay_vip_pass_charge_only_password', label: '会员卡密单密码模式', type: 'switch', default: false, dependsOn: { key: 'pay_vip_pass_charge_s', value: true }, help: '会员卡密仅需输入密码,不需要卡号;默认关闭,会员卡需输入卡号和密码(与其他卡密兑换一致)' },
],
},
{
+1 -1
View File
@@ -163,7 +163,7 @@ class SchemaPayment {
['key' => 'points_pass_exchange_only_password', 'label' => '积分卡密单密码模式', 'type' => 'switch', 'default' => false, 'dependsOn' => ['key' => 'points_pass_exchange_s', 'value' => true], 'help' => '积分卡密仅需输入密码,不需要卡号'],
['key' => 'pay_vip_pass_charge_s', 'label' => '启用卡密兑换会员功能', 'type' => 'switch', 'default' => false, 'help' => '开启后用户可在会员购买/续费弹窗选择「卡密」渠道,使用会员卡密直接兑换会员'],
['key' => 'pay_vip_pass_charge_desc', 'label' => '卡密兑换会员说明', 'type' => 'textarea', 'default' => '', 'rows' => 2, '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' => 'pay_vip_pass_charge_only_password', 'label' => '会员卡密单密码模式', 'type' => 'switch', 'default' => false, 'dependsOn' => ['key' => 'pay_vip_pass_charge_s', 'value' => true], 'help' => '会员卡密仅需输入密码,不需要卡号;默认关闭,会员卡需输入卡号和密码(与其他卡密兑换一致)'],
]],
['key' => 'points-exchange', 'title' => '余额兑换积分', 'fields' => [
['key' => 'pay_balance_points_exchange_s', 'label' => '启用余额兑换积分', 'type' => 'switch', 'default' => false, 'dependsOn' => ['key' => 'pay_balance_s', 'value' => true]],
+1 -1
View File
@@ -131,7 +131,7 @@ class ChargeCard {
$types = [
'balance' => ['enabled' => false, 'desc' => '', 'only_password' => false],
'credits' => ['enabled' => false, 'desc' => '', 'only_password' => false],
'vip' => ['enabled' => false, 'desc' => '', 'only_password' => true],
'vip' => ['enabled' => false, 'desc' => '', 'only_password' => false],
];
if ($channel_on && class_exists('\AKSRT\Settings\Settings')) {
+2 -1
View File
@@ -124,7 +124,8 @@ class PaymentRuntime {
'vip' => [
'enabled' => !empty($settings['pay_vip_pass_charge_s']),
'desc' => sanitize_textarea_field((string) ($settings['pay_vip_pass_charge_desc'] ?? '')),
'only_password' => !isset($settings['pay_vip_pass_charge_only_password']) || !empty($settings['pay_vip_pass_charge_only_password']),
// 默认非单密码(卡号+密码),对齐参考主题 pay_vip_pass_charge_only_password 默认 false。
'only_password' => !empty($settings['pay_vip_pass_charge_only_password']),
],
],
'points_exchange' => [
@@ -146,7 +146,11 @@ test('REST 契约:type 必填(balance/vip/credits),无空类型自动识
test('后端类型闸门:三个独立开关各约束自己的类型', () => {
assert.match(chargeCard, /'balance' => \['enabled' => false, 'desc' => '', 'only_password' => false\]/);
assert.match(chargeCard, /'credits' => \['enabled' => false, 'desc' => '', 'only_password' => false\]/);
assert.match(chargeCard, /'vip'\s+=> \['enabled' => false, 'desc' => '', 'only_password' => true\]/);
assert.match(chargeCard, /'vip'\s+=> \['enabled' => false, 'desc' => '', 'only_password' => false\]/);
// 会员单密码默认关闭(对齐参考主题 default false):未显式开启时卡密盒显示卡号+密码。
assert.doesNotMatch(chargeCard, /'only_password' => true/);
assert.match(read('src', 'Settings', 'PaymentRuntime.php'), /'only_password' => !empty\(\$settings\['pay_vip_pass_charge_only_password'\]\),/);
assert.doesNotMatch(read('src', 'Settings', 'PaymentRuntime.php'), /!isset\(\$settings\['pay_vip_pass_charge_only_password'\]\)/);
assert.match(chargeCard, /卡密兑换余额功能未开启/);
assert.match(chargeCard, /卡密兑换积分功能未开启/);
assert.match(chargeCard, /卡密兑换会员功能未开启/);