From ad2290cbb7cf1621e87fb769e85457cf027fd0df Mon Sep 17 00:00:00 2001 From: kate522 Date: Wed, 7 Oct 2026 08:46:41 +0000 Subject: [PATCH] =?UTF-8?q?feat(admin):=20=E5=94=AE=E5=90=8E=E6=93=8D?= =?UTF-8?q?=E4=BD=9C=E5=88=97=E6=94=B9=E4=B8=BA=E7=82=B9=E5=87=BB=E3=80=8C?= =?UTF-8?q?=E6=93=8D=E4=BD=9C=E3=80=8D=E5=B1=95=E5=BC=80=E5=BF=AB=E6=8D=B7?= =?UTF-8?q?=E9=9D=A2=E6=9D=BF=EF=BC=9B=E6=96=B0=E5=A2=9E=E9=A1=B6=E9=83=A8?= =?UTF-8?q?=E6=89=B9=E9=87=8F=E9=80=9A=E8=BF=87/=E6=89=B9=E9=87=8F?= =?UTF-8?q?=E6=8B=92=E7=BB=9D=EF=BC=88=E5=90=AB=E5=A4=8D=E9=80=89=E6=A1=86?= =?UTF-8?q?=E4=B8=8E=E5=85=A8=E9=80=89=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Admin/Native/PayOrders.php | 66 ++++++++++++++++++++++++++++++---- 1 file changed, 60 insertions(+), 6 deletions(-) diff --git a/src/Admin/Native/PayOrders.php b/src/Admin/Native/PayOrders.php index 0bd290d7..f77d0e79 100644 --- a/src/Admin/Native/PayOrders.php +++ b/src/Admin/Native/PayOrders.php @@ -31,6 +31,7 @@ class PayOrders { add_action('admin_post_aksrt_pay_clear_closed_orders', [$this, 'handle_clear_closed_orders']); add_action('admin_post_aksrt_pay_delete_order', [$this, 'handle_delete_order']); add_action('admin_post_aksrt_after_sale_review', [$this, 'handle_after_sale_review']); + add_action('admin_post_aksrt_after_sale_bulk', [$this, 'handle_after_sale_bulk']); } public function render_orders_page(): void { @@ -401,8 +402,15 @@ class PayOrders { foreach ([\AKSRT\Payment\AfterSaleService::STATUS_PENDING => '待审核', \AKSRT\Payment\AfterSaleService::STATUS_PROCESSING => '处理中', \AKSRT\Payment\AfterSaleService::STATUS_APPROVED => '已通过', \AKSRT\Payment\AfterSaleService::STATUS_REJECTED => '已拒绝', \AKSRT\Payment\AfterSaleService::STATUS_CANCELLED => '已取消', \AKSRT\Payment\AfterSaleService::STATUS_COMPLETED => '已完成'] as $key => $label) echo ''; echo ' '; submit_button(__('筛选', 'aksrt'), 'secondary', '', false); - echo ''; - if (!$items) echo ''; + echo ''; + echo ''; + echo ''; wp_nonce_field('aksrt_after_sale_bulk'); + echo ''; + echo '
'; + echo ' '; + echo '
'; + echo '
ID订单号用户原因申请资料申请说明举证图片退款金额状态操作 / 处理记录
' . esc_html__('暂无售后申请', 'aksrt') . '
'; + if (!$items) echo ''; foreach ($items as $item) { $id = (int) $item['id']; $number = (string) $item['order_number']; $uid = (int) $item['user_id']; $user = $uid > 0 ? get_userdata($uid) : null; @@ -436,8 +444,8 @@ class PayOrders { $thumbs[] = ''; } $images_cell = $thumbs ? implode('', $thumbs) : '—'; - echo ''; } echo '
ID订单号用户原因申请资料申请说明举证图片退款金额状态操作 / 处理记录
' . esc_html__('暂无售后申请', 'aksrt') . '
' . esc_html((string) $id) . '
' . esc_html((string) ($item['created_at'] ?? '')) . '
' . esc_html($number) . '
' . esc_html($type_label) . ($order ? ' · ' . esc_html(\AKSRT\Payment\UserOrders::get_instance()->decorate_order_view($order, false)['product_name'] ?? '') : '') . '
' . esc_html($user ? $user->display_name . ' (#' . $uid . ')' : '#' . $uid) . '' . $reason_cell . '' . $materials_cell . '' . $desc_cell . '' . $images_cell . '' . esc_html($refund_amount) . '' . esc_html($status_labels[(string) $item['status']] ?? (string) $item['status']) . ''; - // 快捷操作:仿 WP 文章列表 row-actions(悬停显示),点击经 JS 以 POST 提交 + echo '
' . esc_html((string) $id) . '
' . esc_html((string) ($item['created_at'] ?? '')) . '
' . esc_html($number) . '
' . esc_html($type_label) . ($order ? ' · ' . esc_html(\AKSRT\Payment\UserOrders::get_instance()->decorate_order_view($order, false)['product_name'] ?? '') : '') . '
' . esc_html($user ? $user->display_name . ' (#' . $uid . ')' : '#' . $uid) . '' . $reason_cell . '' . $materials_cell . '' . $desc_cell . '' . $images_cell . '' . esc_html($refund_amount) . '' . esc_html($status_labels[(string) $item['status']] ?? (string) $item['status']) . ''; + // 快捷操作:点击「操作」展开面板,点击链接经 JS 以 POST 提交 $quick_actions = []; if ((string) $item['status'] === 'pending') { $quick_actions = ['approve' => __('通过', 'aksrt'), 'reject' => __('拒绝', 'aksrt')]; @@ -458,7 +466,8 @@ class PayOrders { . ' data-nonce="' . esc_attr(wp_create_nonce('aksrt_after_sale_review_' . $id)) . '"' . '>' . esc_html($label) . ''; } - echo '
' . implode(' | ', $links) . '
'; + echo '' . esc_html__('操作', 'aksrt') . ''; + echo ''; } if (!empty($item['admin_note'])) echo '' . esc_html__('备注:', 'aksrt') . esc_html((string) $item['admin_note']) . '
'; if (!empty($item['gateway_result'])) { @@ -469,11 +478,18 @@ class PayOrders { echo '
'; + echo ''; echo ''; + . '});});' + . 'var selAll=document.querySelector(".aksrt-select-all");' + . 'if(selAll){selAll.addEventListener("change",function(){' + . 'document.querySelectorAll(".aksrt-row-check").forEach(function(c){c.checked=selAll.checked;});});}' + . 'var bulkForm=document.getElementById("aksrt-after-sale-bulk-form");' + . 'if(bulkForm){bulkForm.addEventListener("submit",function(e){' + . 'var checked=document.querySelectorAll(".aksrt-row-check:checked");' + . 'var decision=document.getElementById("aksrt-bulk-decision").value;' + . 'if(!checked.length){e.preventDefault();alert(' . wp_json_encode(__('请先勾选要操作的售后记录。', 'aksrt')) . ');return;}' + . 'if(!decision){e.preventDefault();alert(' . wp_json_encode(__('请选择批量操作。', 'aksrt')) . ');return;}' + . 'if(decision==="reject"){var note=prompt(tReject,"");if(note===null){e.preventDefault();return;}document.getElementById("aksrt-bulk-note").value=note;}' + . 'else if(!confirm(' . wp_json_encode(__('确认批量通过选中的记录吗?', 'aksrt')) . ')){e.preventDefault();return;}' + . '});}' + . '})();'; } public function handle_after_sale_review(): void { @@ -498,6 +527,31 @@ class PayOrders { wp_safe_redirect($this->page_url(self::PAGE_AFTER_SALES_SLUG, $args)); exit; } + /** + * 批量审核售后申请(仅对待审核/处理中有效,其余由 review() 校验拒绝并计入失败)。 + */ + public function handle_after_sale_bulk(): void { + if (!current_user_can(self::CAPABILITY)) wp_die(esc_html__('权限不足', 'aksrt')); + check_admin_referer('aksrt_after_sale_bulk'); + $decision = isset($_POST['bulk_decision']) ? sanitize_key((string) wp_unslash($_POST['bulk_decision'])) : ''; + if (!in_array($decision, ['approve', 'reject'], true)) { + wp_safe_redirect($this->page_url(self::PAGE_AFTER_SALES_SLUG, ['aksrt_pay_msg' => 'after_sale_review_failed'])); exit; + } + $note = isset($_POST['bulk_note']) ? sanitize_textarea_field((string) wp_unslash($_POST['bulk_note'])) : ''; + $ids = array_values(array_unique(array_map('absint', (array) ($_POST['after_sale_ids'] ?? [])))); + $service = \AKSRT\Payment\AfterSaleService::get_instance(); + $done = 0; $failed = 0; + foreach ($ids as $id) { + if ($id <= 0) continue; + $result = $service->review($id, $decision, $note); + if (is_wp_error($result)) $failed++; else $done++; + } + $args = ['aksrt_pay_msg' => $failed > 0 ? 'after_sale_review_failed' : 'after_sale_reviewed']; + if ($done > 0) $args['aksrt_bulk_done'] = $done; + if ($failed > 0) $args['aksrt_bulk_failed'] = $failed; + wp_safe_redirect($this->page_url(self::PAGE_AFTER_SALES_SLUG, $args)); exit; + } + public function handle_update_order_status(): void { if (!current_user_can(self::CAPABILITY)) { wp_die(esc_html__('权限不足', 'aksrt'));