diff --git a/src/Admin/Native/UsersMenusTickets.php b/src/Admin/Native/UsersMenusTickets.php index db5213ff..76f86198 100644 --- a/src/Admin/Native/UsersMenusTickets.php +++ b/src/Admin/Native/UsersMenusTickets.php @@ -186,29 +186,7 @@ trait UsersMenusTickets { $process_id = isset($_GET['id']) ? (string) wp_unslash($_GET['id']) : ''; if ($process_action === 'process') { - // 独立处理视图:只渲染目标工单的处理表单(参考主题同构)。 - // 列表与分页不得出现在“确认提交”下方——此前表单被当作 - // 追加进列表表格,属于无效 HTML 嵌套,浏览器重排后工单列表 - // 全部堆到表单下方。 - $processing = null; - foreach (array_merge($tickets, $rows) as $row) { - if ($process_id === (string) $row['kind'] . '-' . (string) $row['id']) { - $processing = $row; - break; - } - } - echo '' . esc_html__('查看全部', 'aksrt') . ''; - - if ($processing === null) { - echo '

' . esc_html__('工单不存在或已被删除', 'aksrt') . '

'; - return; - } - - echo '
'; - $this->render_ticket_process_form($processing, $action_url); - echo '
'; - return; } echo '
'; @@ -242,7 +220,19 @@ trait UsersMenusTickets { } foreach ($tickets as $row) { - $this->render_ticket_row($row, $page_url); + $is_processing = $process_action === 'process' + && $process_id === (string) $row['kind'] . '-' . (string) $row['id']; + if ($is_processing) { + // 被处理工单:行信息由处理表单承载,不再重复渲染列表行—— + // 此前 row + 表单把同一工单信息展示两次,且表单裸嵌 + // 属无效 HTML,被浏览器 foster-parent 后那次多余的行信息 + // 错位到“确认提交”下方。合法包裹为 colspan=6 单元格。 + echo ''; + $this->render_ticket_process_form($row, $action_url); + echo ''; + } else { + $this->render_ticket_row($row, $page_url); + } } echo '
'; diff --git a/tests/widget-system/report-ban-contract.test.cjs b/tests/widget-system/report-ban-contract.test.cjs index a0efed96..98f1e215 100644 --- a/tests/widget-system/report-ban-contract.test.cjs +++ b/tests/widget-system/report-ban-contract.test.cjs @@ -179,10 +179,11 @@ test('native ban page mirrors the reference theme layout', () => { assert.match(tickets, /name="action" value="' \. esc_attr\(\$kind === 'report' \? 'aksrt_users_update_report' : 'aksrt_users_process_appeal'\)/) assert.match(usersMenus, /admin_post_aksrt_users_update_report/) assert.match(usersMenus, /admin_post_aksrt_users_process_appeal/) - // 独立处理视图:action=process 时只渲染目标工单的处理表单(提前 return), - // 列表循环不得再注入表单——无效 嵌套曾把工单列表挤到“确认提交”下方。 - assert.match(tickets, /if \(\$process_action === 'process'\) \{[\s\S]*?render_ticket_process_form\(\$processing, \$action_url\)[\s\S]*?return;/) - assert.doesNotMatch(tickets, /foreach \(\$tickets as \$row\) \{\s*\$this->render_ticket_row[\s\S]{0,400}?render_ticket_process_form/) + // 内联处理视图(参考主题方向):被处理工单以 colspan=6 合法单元格展开 + // 表单,且不再渲染其列表行——此前 row + 表单重复展示同一工单信息, + // 表单裸嵌 tbody 被 foster-parent 后多余行信息错位到“确认提交”下方。 + assert.match(tickets, /';\s*\$this->render_ticket_process_form/) + assert.match(tickets, /if \(\$is_processing\) \{[\s\S]*?render_ticket_process_form\(\$row, \$action_url\)[\s\S]*?\} else \{\s*\$this->render_ticket_row/) // 分页对齐参考主题 zibpay_admin_pagenavi(每页 20 条) assert.match(tickets, /TICKETS_PER_PAGE = 20/)