fix(payment): 添加卡密页依赖字段初始状态按默认值隐藏

- 渲染期按表单默认值预判依赖可见性(deps_visible/default_form_value),不满足项直接输出 display:none,消除导入提醒首帧全部显示的问题
- 行内 JS 在 DOMContentLoaded 兜底执行一次依赖求值,交互前后状态与服务端一致
This commit is contained in:
2026-09-16 22:40:35 +08:00
parent 678143e7b9
commit ef9409cee6
+74 -2
View File
@@ -839,7 +839,8 @@ class PayChargeCards {
*/
private function field_row(string $title, string $html, array $deps = [], string $desc = ''): void {
$dep_attr = $deps ? ' data-dep="' . esc_attr((string) wp_json_encode($deps)) . '"' : '';
echo '<tr' . $dep_attr . '><th scope="row">' . esc_html($title) . '</th><td>' . $html; // phpcs:ignore WordPress.Security.EscapeOutput -- 内部构造,已转义。
$hidden = ($deps && !$this->deps_visible($deps)) ? ' style="display:none;"' : '';
echo '<tr' . $dep_attr . $hidden . '><th scope="row">' . esc_html($title) . '</th><td>' . $html; // phpcs:ignore WordPress.Security.EscapeOutput -- 内部构造,已转义。
if ($desc !== '') {
echo '<p class="description">' . wp_kses_post($desc) . '</p>';
}
@@ -850,7 +851,72 @@ class PayChargeCards {
* @param array<int,array{key:string,op:string,val:string}> $deps
*/
private function submessage_row(array $deps, string $content): void {
echo '<tr data-dep="' . esc_attr((string) wp_json_encode($deps)) . '"><td colspan="2"><div class="aksrt-submsg notice notice-warning" style="margin:6px 0;padding:6px 12px;">' . $content . '</div></td></tr>'; // phpcs:ignore WordPress.Security.EscapeOutput -- 文案已转义。
$hidden = $this->deps_visible($deps) ? '' : ' style="display:none;"';
echo '<tr data-dep="' . esc_attr((string) wp_json_encode($deps)) . '"' . $hidden . '><td colspan="2"><div class="aksrt-submsg notice notice-warning" style="margin:6px 0;padding:6px 12px;">' . $content . '</div></td></tr>'; // phpcs:ignore WordPress.Security.EscapeOutput -- 文案已转义。
}
/**
* 服务端按表单默认值预判依赖可见性(求值规则与行内 JS 一致)。
* 参考主题 CSF 的 dependency 在 DOM ready 后才隐藏不满足项,首帧会闪现全部字段;
* 此处在渲染期直接置 display:none,修正「导入提醒初始全部显示」的问题。
*
* @param array<int,array{key:string,op:string,val:string}> $deps
*/
private function deps_visible(array $deps): bool {
foreach ($deps as $dep) {
$v = (string) $this->default_form_value((string) ($dep['key'] ?? ''));
$val = (string) ($dep['val'] ?? '');
switch ((string) ($dep['op'] ?? '')) {
case '==':
if ($v !== $val) {
return false;
}
break;
case '!=':
if ($v === $val) {
return false;
}
break;
case 'any':
if (!in_array($v, explode(',', $val), true)) {
return false;
}
break;
case 'checked':
if ($v === '') {
return false;
}
break;
case 'unchecked':
if ($v !== '') {
return false;
}
break;
}
}
return true;
}
/**
* 表单字段的初始默认值(须与 field_row/button_set/spinner 渲染的默认值保持同步)。
* 未列出的键按空字符串处理,与行内 JS formVal 找不到元素时返回 '' 的行为一致。
*/
private function default_form_value(string $key): string {
switch ($key) {
case 'add_type':
return 'auto';
case 'type':
return 'balance';
case 'auto_top_s':
case 'only_pass_s':
return '';
case 'vip_exchange[time]':
return '';
case 'vip_exchange[unit]':
return 'month';
default:
return '';
}
}
/**
@@ -980,6 +1046,12 @@ class PayChargeCards {
document.addEventListener('change', function (e) {
if (e.target.closest('.aksrt-cardpass-form')) evalDeps();
});
// 初始按默认值求值一次:服务端已预隐藏,这里兜底校正。
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', evalDeps);
} else {
evalDeps();
}
document.addEventListener('click', function (e) {
var el = e.target.closest('[data-clipboard-text]');
if (!el) return;