refactor(after-sale): replace review decisions with direct status panel
售后面板改为状态下拉(待审核/处理中/已完成/已拒绝/已取消)加确认/取消按钮:取消仅收起手风琴,确认为纯状态更新;删除已通过状态、review() 决策机制及其专用退款流水线,无双路无迁移;举证图片并入申请说明列与详情整行。
This commit is contained in:
+56
-108
@@ -30,8 +30,7 @@ class PayOrders {
|
||||
add_action('admin_post_aksrt_pay_update_order_note', [$this, 'handle_update_order_note']);
|
||||
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']);
|
||||
add_action('admin_post_aksrt_after_sale_update', [$this, 'handle_after_sale_status']);
|
||||
}
|
||||
|
||||
public function render_orders_page(): void {
|
||||
@@ -359,7 +358,7 @@ class PayOrders {
|
||||
$after_sales = \AKSRT\Payment\AfterSaleService::get_instance()->list_for_order($order_number);
|
||||
if ($after_sales) {
|
||||
echo '<tr><th>' . esc_html__('售后记录', 'aksrt') . '</th><td>';
|
||||
$status_labels = ['pending' => '待审核', 'processing' => '处理中', 'approved' => '已通过', 'rejected' => '已拒绝', 'cancelled' => '已取消', 'completed' => '已完成'];
|
||||
$status_labels = ['pending' => '待审核', 'processing' => '处理中', 'completed' => '已完成', 'rejected' => '已拒绝', 'cancelled' => '已取消'];
|
||||
foreach ($after_sales as $application) {
|
||||
echo '<p><strong>' . esc_html($status_labels[(string) ($application['status'] ?? '')] ?? (string) ($application['status'] ?? '')) . '</strong> · ' . esc_html((string) ($application['refund_amount'] ?? '')) . '<br>' . esc_html((string) ($application['reason'] ?? ''));
|
||||
if (!empty($application['admin_note'])) echo '<br>' . esc_html__('处理备注:', 'aksrt') . esc_html((string) $application['admin_note']);
|
||||
@@ -399,7 +398,7 @@ class PayOrders {
|
||||
$items = $service->admin_list($filter_args + ['limit' => 100]);
|
||||
echo '<form method="get"><input type="hidden" name="page" value="' . esc_attr(self::PAGE_AFTER_SALES_SLUG) . '" />';
|
||||
echo '<select name="after_sale_status"><option value="">' . esc_html__('全部售后状态', 'aksrt') . '</option>';
|
||||
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 '<option value="' . esc_attr($key) . '"' . selected($status, $key, false) . '>' . esc_html($label) . '</option>';
|
||||
foreach ([\AKSRT\Payment\AfterSaleService::STATUS_PENDING => '待审核', \AKSRT\Payment\AfterSaleService::STATUS_PROCESSING => '处理中', \AKSRT\Payment\AfterSaleService::STATUS_COMPLETED => '已完成', \AKSRT\Payment\AfterSaleService::STATUS_REJECTED => '已拒绝', \AKSRT\Payment\AfterSaleService::STATUS_CANCELLED => '已取消'] as $key => $label) echo '<option value="' . esc_attr($key) . '"' . selected($status, $key, false) . '>' . esc_html($label) . '</option>';
|
||||
echo '</select> <label>' . esc_html__('开始日期', 'aksrt') . ' <input type="date" name="date_from" value="' . esc_attr($date_from) . '" /></label> <label>' . esc_html__('结束日期', 'aksrt') . ' <input type="date" name="date_to" value="' . esc_attr($date_to) . '" /></label> ';
|
||||
submit_button(__('筛选', 'aksrt'), 'secondary', '', false);
|
||||
echo '</form>';
|
||||
@@ -414,18 +413,12 @@ class PayOrders {
|
||||
. '.aksrt-as-detail .aksrt-as-thumb{width:80px;height:80px;}'
|
||||
. '.aksrt-as-review{margin-top:12px;padding-top:10px;border-top:1px solid #dcdcde;max-width:720px;}'
|
||||
. '.aksrt-as-review textarea{width:100%;box-sizing:border-box;margin:4px 0 8px;}'
|
||||
. '.aksrt-as-review-actions{display:flex;gap:8px;flex-wrap:wrap;}'
|
||||
. '.aksrt-qa-danger{color:#b32d2e;border-color:#b32d2e;}'
|
||||
. '.aksrt-as-review-actions{display:flex;gap:8px;flex-wrap:wrap;justify-content:flex-end;}'
|
||||
. '.aksrt-as-field--wide{grid-column:1/-1;}'
|
||||
. '</style>';
|
||||
echo '<form method="post" action="' . esc_url(admin_url('admin-post.php')) . '" id="aksrt-after-sale-bulk-form">';
|
||||
echo '<input type="hidden" name="action" value="aksrt_after_sale_bulk" />'; wp_nonce_field('aksrt_after_sale_bulk');
|
||||
echo '<input type="hidden" name="bulk_note" id="aksrt-bulk-note" value="" />';
|
||||
echo '<div class="tablenav top"><div class="alignleft actions bulkactions">';
|
||||
echo '<select name="bulk_decision" id="aksrt-bulk-decision"><option value="">' . esc_html__('批量操作', 'aksrt') . '</option><option value="approve">' . esc_html__('批量通过', 'aksrt') . '</option><option value="reject">' . esc_html__('批量拒绝', 'aksrt') . '</option></select> ';
|
||||
echo '<button type="submit" class="button action">' . esc_html__('应用', 'aksrt') . '</button></div><div class="tablenav-spacer" style="clear:both;"></div></div>';
|
||||
echo '<table class="widefat striped"><thead><tr><th class="check-column"><input type="checkbox" class="aksrt-select-all" /></th><th>ID</th><th>订单号</th><th>用户</th><th>原因</th><th>申请资料</th><th>申请说明</th><th>举证图片</th><th>退款金额</th><th>状态</th><th>操作 / 处理记录</th></tr></thead><tbody>';
|
||||
if (!$items) echo '<tr><td colspan="11">' . esc_html__('暂无售后申请', 'aksrt') . '</td></tr>';
|
||||
$status_labels = [\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 => '已完成'];
|
||||
echo '<table class="widefat striped"><thead><tr><th>ID</th><th>订单号</th><th>用户</th><th>原因</th><th>申请资料</th><th>申请说明</th><th>退款金额</th><th>状态</th><th>操作 / 处理记录</th></tr></thead><tbody>';
|
||||
if (!$items) echo '<tr><td colspan="9">' . esc_html__('暂无售后申请', 'aksrt') . '</td></tr>';
|
||||
$status_labels = [\AKSRT\Payment\AfterSaleService::STATUS_PENDING => '待审核', \AKSRT\Payment\AfterSaleService::STATUS_PROCESSING => '处理中', \AKSRT\Payment\AfterSaleService::STATUS_COMPLETED => '已完成', \AKSRT\Payment\AfterSaleService::STATUS_REJECTED => '已拒绝', \AKSRT\Payment\AfterSaleService::STATUS_CANCELLED => '已取消'];
|
||||
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;
|
||||
@@ -446,19 +439,20 @@ class PayOrders {
|
||||
}
|
||||
$materials_cell = $material_lines ? implode('<br>', $material_lines) : '—';
|
||||
$desc_text = trim((string) ($apply_form['description'] ?? ''));
|
||||
$desc_cell = $desc_text !== '' ? nl2br(esc_html($desc_text)) : '—';
|
||||
} else {
|
||||
// 老数据:融合串原样展示在原因列
|
||||
$reason_cell = nl2br(esc_html((string) $item['reason']));
|
||||
$materials_cell = '—';
|
||||
$desc_cell = '—';
|
||||
$desc_text = '';
|
||||
}
|
||||
$image_urls = array_values(array_filter((array) ($item['images'] ?? []), 'is_string'));
|
||||
$thumbs = [];
|
||||
foreach ($image_urls as $url) {
|
||||
$thumbs[] = '<a href="' . esc_url($url) . '" target="_blank" rel="noopener"><img src="' . esc_url($url) . '" alt="" class="aksrt-as-thumb" loading="lazy" /></a>';
|
||||
}
|
||||
$images_cell = $thumbs ? implode('', $thumbs) : '—';
|
||||
// 举证图片并入申请说明:缩略图展示在描述文字下方,不再单独成列。
|
||||
$desc_cell = ($desc_text !== '' ? nl2br(esc_html($desc_text)) : '') . ($thumbs ? '<div class="aksrt-as-desc-thumbs" style="margin-top:6px;">' . implode('', $thumbs) . '</div>' : '');
|
||||
if ($desc_cell === '') $desc_cell = '—';
|
||||
$status_label = $status_labels[(string) $item['status']] ?? (string) $item['status'];
|
||||
$admin_note = (string) ($item['admin_note'] ?? '');
|
||||
$gateway_text = '';
|
||||
@@ -466,32 +460,19 @@ class PayOrders {
|
||||
$result_data = json_decode((string) $item['gateway_result'], true);
|
||||
$gateway_text = is_array($result_data) ? implode(' · ', array_filter([(string) ($result_data['status'] ?? ''), (string) ($result_data['message'] ?? ''), !empty($result_data['refund_id']) ? '退款单号 ' . (string) $result_data['refund_id'] : ''])) : (string) $item['gateway_result'];
|
||||
}
|
||||
// 按状态决定该记录可执行的审核动作(经 JS 以 POST 提交)
|
||||
$quick_actions = [];
|
||||
if ((string) $item['status'] === 'pending') {
|
||||
$quick_actions = ['approve' => __('通过', 'aksrt'), 'reject' => __('拒绝', 'aksrt')];
|
||||
} elseif ((string) $item['status'] === 'processing') {
|
||||
$gateway_result = json_decode((string) ($item['gateway_result'] ?? ''), true);
|
||||
$manual_refund = is_array($gateway_result) && sanitize_key((string) ($gateway_result['status'] ?? '')) === 'manual';
|
||||
$quick_actions = $manual_refund
|
||||
? ['complete' => __('确认线下退款完成', 'aksrt'), 'reject' => __('确认未退款并拒绝', 'aksrt')]
|
||||
: ['approve' => __('同步退款状态', 'aksrt')];
|
||||
}
|
||||
// 摘要行 + 手风琴详情行:点击「操作」展开整条记录的完整信息与审核表单
|
||||
// 摘要行 + 手风琴详情行:点击「操作」展开整条记录的完整信息与状态面板
|
||||
echo '<tr class="aksrt-as-row">';
|
||||
echo '<td class="check-column"><input type="checkbox" class="aksrt-row-check" name="after_sale_ids[]" value="' . esc_attr((string) $id) . '" /></td>';
|
||||
echo '<td>' . esc_html((string) $id) . '<br><small>' . esc_html((string) ($item['created_at'] ?? '')) . '</small></td>';
|
||||
echo '<td><a href="' . esc_url($this->page_url(self::PAGE_SLUG, ['order' => $number])) . '"><code>' . esc_html($number) . '</code></a><br><span class="description">' . esc_html($type_label) . ($product_name !== '' ? ' · ' . esc_html($product_name) : '') . '</span></td>';
|
||||
echo '<td>' . esc_html($user ? $user->display_name . ' (#' . $uid . ')' : '#' . $uid) . '</td>';
|
||||
echo '<td>' . $reason_cell . '</td>';
|
||||
echo '<td>' . $materials_cell . '</td>';
|
||||
echo '<td>' . $desc_cell . '</td>';
|
||||
echo '<td>' . $images_cell . '</td>';
|
||||
echo '<td>' . esc_html($refund_amount) . '</td>';
|
||||
echo '<td>' . esc_html($status_label) . '</td>';
|
||||
echo '<td><a href="#" class="aksrt-toggle-row-actions" data-target="aksrt-as-detail-' . esc_attr((string) $id) . '" aria-expanded="false" aria-controls="aksrt-as-detail-' . esc_attr((string) $id) . '">' . esc_html__('操作', 'aksrt') . '</a></td>';
|
||||
echo '</tr>';
|
||||
echo '<tr class="aksrt-as-detail-row" id="aksrt-as-detail-' . esc_attr((string) $id) . '" hidden><td colspan="11">';
|
||||
echo '<tr class="aksrt-as-detail-row" id="aksrt-as-detail-' . esc_attr((string) $id) . '" hidden><td colspan="9">';
|
||||
$detail_fields = [
|
||||
__('订单号', 'aksrt') => '<a href="' . esc_url($this->page_url(self::PAGE_SLUG, ['order' => $number])) . '"><code>' . esc_html($number) . '</code></a>',
|
||||
__('商品', 'aksrt') => esc_html($type_label . ($product_name !== '' ? ' · ' . $product_name : '')),
|
||||
@@ -501,8 +482,6 @@ class PayOrders {
|
||||
__('当前状态', 'aksrt') => esc_html($status_label),
|
||||
__('售后原因', 'aksrt') => $reason_cell,
|
||||
__('申请资料', 'aksrt') => $materials_cell,
|
||||
__('申请说明', 'aksrt') => $desc_cell,
|
||||
__('举证图片', 'aksrt') => $images_cell,
|
||||
__('处理备注', 'aksrt') => $admin_note !== '' ? esc_html($admin_note) : '—',
|
||||
__('渠道结果', 'aksrt') => $gateway_text !== '' ? '<code>' . esc_html($gateway_text) . '</code>' : '—',
|
||||
__('审核时间', 'aksrt') => !empty($item['reviewed_at']) ? esc_html((string) $item['reviewed_at']) : '—',
|
||||
@@ -511,110 +490,79 @@ class PayOrders {
|
||||
foreach ($detail_fields as $field_label => $field_value) {
|
||||
echo '<span class="aksrt-as-field"><span class="aksrt-as-label">' . esc_html($field_label) . '</span><span class="aksrt-as-value">' . $field_value . '</span></span>';
|
||||
}
|
||||
// 举证图片并入申请说明,单独占整行展示。
|
||||
echo '<span class="aksrt-as-field aksrt-as-field--wide"><span class="aksrt-as-label">' . esc_html__('申请说明', 'aksrt') . '</span><span class="aksrt-as-value">' . $desc_cell . '</span></span>';
|
||||
echo '</div>';
|
||||
if ($quick_actions) {
|
||||
echo '<div class="aksrt-as-review">';
|
||||
echo '<p style="margin:0;"><strong>' . esc_html__('审核操作', 'aksrt') . '</strong> <span class="description">' . esc_html__('处理备注可留空,将记为管理员备注。', 'aksrt') . '</span></p>';
|
||||
echo '<textarea class="aksrt-review-note" rows="2" placeholder="' . esc_attr__('填写处理备注(可留空)', 'aksrt') . '"></textarea>';
|
||||
echo '<div class="aksrt-as-review-actions">';
|
||||
foreach ($quick_actions as $decision => $label) {
|
||||
echo '<button type="button" class="button button-small aksrt-after-sale-quick-action' . ($decision === 'reject' ? ' aksrt-qa-danger' : ' button-primary') . '"'
|
||||
. ' data-id="' . esc_attr((string) $id) . '"'
|
||||
. ' data-decision="' . esc_attr($decision) . '"'
|
||||
. ' data-label="' . esc_attr($label) . '"'
|
||||
. ' data-nonce="' . esc_attr(wp_create_nonce('aksrt_after_sale_review_' . $id)) . '">'
|
||||
. esc_html($label) . '</button>';
|
||||
}
|
||||
echo '</div></div>';
|
||||
} else {
|
||||
echo '<p class="description" style="margin:12px 0 0;">' . esc_html__('该售后申请已处理完毕,无需再审核。', 'aksrt') . '</p>';
|
||||
$status_options = '';
|
||||
$current_status = (string) $item['status'];
|
||||
foreach ($status_labels as $key => $label) {
|
||||
$status_options .= '<option value="' . esc_attr($key) . '"' . selected($current_status, $key, false) . '>' . esc_html($label) . '</option>';
|
||||
}
|
||||
if (!isset($status_labels[$current_status])) {
|
||||
// 历史状态(如已删除的 approved)不在可选项内:如实呈现且禁用,防止误提交。
|
||||
$status_options .= '<option value="' . esc_attr($current_status) . '" selected="selected" disabled>' . esc_html($current_status) . '</option>';
|
||||
}
|
||||
echo '<div class="aksrt-as-review">';
|
||||
echo '<p style="margin:0;"><strong>' . esc_html__('售后状态', 'aksrt') . '</strong> <span class="description">' . esc_html__('选择目标状态后点击确认;取消仅收起面板。', 'aksrt') . '</span></p>';
|
||||
echo '<p style="margin:4px 0;"><select class="aksrt-status-select">' . $status_options . '</select></p>';
|
||||
echo '<textarea class="aksrt-review-note" rows="2" placeholder="' . esc_attr__('填写处理备注(可留空)', 'aksrt') . '"></textarea>';
|
||||
echo '<div class="aksrt-as-review-actions">';
|
||||
echo '<button type="button" class="button aksrt-after-sale-cancel">' . esc_html__('取消', 'aksrt') . '</button>';
|
||||
echo '<button type="button" class="button button-primary aksrt-after-sale-confirm"'
|
||||
. ' data-id="' . esc_attr((string) $id) . '"'
|
||||
. ' data-nonce="' . esc_attr(wp_create_nonce('aksrt_after_sale_status_' . $id)) . '">'
|
||||
. esc_html__('确认', 'aksrt') . '</button>';
|
||||
echo '</div></div>';
|
||||
echo '</div></td></tr>';
|
||||
}
|
||||
echo '</tbody></table>';
|
||||
echo '</form>';
|
||||
// 事件委托:点击「操作」切换手风琴详情;点击审核按钮经 JS 以 POST 提交(详情行在批量表单内,禁止嵌套 form)
|
||||
// 事件委托:点击「操作」切换手风琴详情;「取消」仅收起面板;「确认」以 POST 提交选中的售后状态
|
||||
echo '<script>(function(){'
|
||||
. 'var postUrl=' . wp_json_encode(esc_url_raw(admin_url('admin-post.php'))) . ';'
|
||||
. 'var tReject=' . wp_json_encode(__('请填写原因(将记为管理员备注,可留空):', 'aksrt')) . ';'
|
||||
. 'var tConfirmA=' . wp_json_encode(__('确认执行', 'aksrt')) . ';'
|
||||
. 'var tConfirmB=' . wp_json_encode(__('吗?', 'aksrt')) . ';'
|
||||
. 'var tConfirmStatus=' . wp_json_encode(__('确认将售后状态设置为', 'aksrt')) . ';'
|
||||
. 'function closeAllDetails(){'
|
||||
. 'document.querySelectorAll(".aksrt-as-detail-row").forEach(function(x){x.setAttribute("hidden","");});'
|
||||
. 'document.querySelectorAll(".aksrt-toggle-row-actions").forEach(function(t){t.setAttribute("aria-expanded","false");});'
|
||||
. '}'
|
||||
. 'document.addEventListener("click",function(e){'
|
||||
. 'var el=e.target,t=el&&el.closest?el.closest(".aksrt-toggle-row-actions"):null;'
|
||||
. 'var el=e.target;'
|
||||
. 'var t=el&&el.closest?el.closest(".aksrt-toggle-row-actions"):null;'
|
||||
. 'if(t){e.preventDefault();'
|
||||
. 'var p=document.getElementById(t.getAttribute("data-target"));if(!p)return;'
|
||||
. 'var willOpen=p.hasAttribute("hidden");closeAllDetails();'
|
||||
. 'if(willOpen){p.removeAttribute("hidden");t.setAttribute("aria-expanded","true");'
|
||||
. 'var n=p.querySelector(".aksrt-review-note");if(n)n.focus();}'
|
||||
. 'var s=p.querySelector(".aksrt-status-select");if(s)s.focus();}'
|
||||
. 'return;}'
|
||||
. 'var a=el&&el.closest?el.closest(".aksrt-after-sale-quick-action"):null;'
|
||||
. 'var c=el&&el.closest?el.closest(".aksrt-after-sale-cancel"):null;'
|
||||
. 'if(c){e.preventDefault();closeAllDetails();return;}'
|
||||
. 'var a=el&&el.closest?el.closest(".aksrt-after-sale-confirm"):null;'
|
||||
. 'if(!a)return;e.preventDefault();'
|
||||
. 'var panel=a.closest(".aksrt-as-detail-row");'
|
||||
. 'var sel=panel?panel.querySelector(".aksrt-status-select"):null;'
|
||||
. 'var noteEl=panel?panel.querySelector(".aksrt-review-note"):null;'
|
||||
. 'var note=noteEl?noteEl.value:"";'
|
||||
. 'if(!confirm(tConfirmA+"「"+a.getAttribute("data-label")+"」"+tConfirmB))return;'
|
||||
. 'var opt=sel?sel.options[sel.selectedIndex]:null;'
|
||||
. 'if(!sel||!opt||opt.disabled){alert(' . wp_json_encode(__('请选择售后状态。', 'aksrt')) . ');return;}'
|
||||
. 'if(!confirm(tConfirmStatus+"「"+opt.text+"」?"))return;'
|
||||
. 'var f=document.createElement("form");f.method="post";f.action=postUrl;'
|
||||
. 'var fields={action:"aksrt_after_sale_review",after_sale_id:a.getAttribute("data-id"),decision:a.getAttribute("data-decision"),_wpnonce:a.getAttribute("data-nonce"),admin_note:note};'
|
||||
. 'var fields={action:"aksrt_after_sale_update",after_sale_id:a.getAttribute("data-id"),after_sale_status:sel.value,_wpnonce:a.getAttribute("data-nonce"),admin_note:noteEl?noteEl.value:""};'
|
||||
. 'Object.keys(fields).forEach(function(k){var i=document.createElement("input");i.type="hidden";i.name=k;i.value=fields[k];f.appendChild(i);});'
|
||||
. 'document.body.appendChild(f);f.submit();'
|
||||
. '});'
|
||||
. '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;});});}'
|
||||
. 'document.addEventListener("submit",function(e){'
|
||||
. 'if(!e.target||e.target.id!=="aksrt-after-sale-bulk-form")return;'
|
||||
. 'var checked=document.querySelectorAll(".aksrt-row-check:checked");'
|
||||
. 'var decisionEl=document.getElementById("aksrt-bulk-decision");'
|
||||
. 'var decision=decisionEl?decisionEl.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;}'
|
||||
. '},true);'
|
||||
. '})();</script>';
|
||||
}
|
||||
|
||||
public function handle_after_sale_review(): void {
|
||||
public function handle_after_sale_status(): void {
|
||||
if (!current_user_can(self::CAPABILITY)) wp_die(esc_html__('权限不足', 'aksrt'));
|
||||
$id = isset($_POST['after_sale_id']) ? absint($_POST['after_sale_id']) : 0;
|
||||
check_admin_referer('aksrt_after_sale_review_' . $id);
|
||||
$decision = isset($_POST['decision']) ? sanitize_key((string) wp_unslash($_POST['decision'])) : '';
|
||||
check_admin_referer('aksrt_after_sale_status_' . $id);
|
||||
$status = isset($_POST['after_sale_status']) ? sanitize_key((string) wp_unslash($_POST['after_sale_status'])) : '';
|
||||
$note = isset($_POST['admin_note']) ? sanitize_textarea_field((string) wp_unslash($_POST['admin_note'])) : '';
|
||||
$result = \AKSRT\Payment\AfterSaleService::get_instance()->review($id, $decision, $note);
|
||||
$args = ['aksrt_pay_msg' => is_wp_error($result) ? 'after_sale_review_failed' : 'after_sale_reviewed'];
|
||||
$result = \AKSRT\Payment\AfterSaleService::get_instance()->set_status($id, $status, $note);
|
||||
$args = ['aksrt_pay_msg' => is_wp_error($result) ? 'after_sale_update_failed' : 'after_sale_updated'];
|
||||
if (is_wp_error($result)) $args['after_sale_error'] = substr($result->get_error_message(), 0, 240);
|
||||
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'));
|
||||
@@ -793,15 +741,15 @@ class PayOrders {
|
||||
'shipping_create_failed' => __('发货记录创建失败。', 'aksrt'),
|
||||
'after_sale_created' => __('售后工单已创建。', 'aksrt'),
|
||||
'after_sale_create_failed' => __('售后工单创建失败。', 'aksrt'),
|
||||
'after_sale_reviewed' => __('售后审核已处理。', 'aksrt'),
|
||||
'after_sale_review_failed' => __('售后审核失败,请查看申请状态和错误原因。', 'aksrt'),
|
||||
'after_sale_updated' => __('售后状态已更新。', 'aksrt'),
|
||||
'after_sale_update_failed' => __('售后状态更新失败,请查看申请状态和错误原因。', 'aksrt'),
|
||||
];
|
||||
if (!isset($map[$code])) {
|
||||
return;
|
||||
}
|
||||
$class = str_contains($code, 'failed') ? 'notice-error' : 'notice-success';
|
||||
echo '<div class="notice ' . esc_attr($class) . ' is-dismissible"><p>' . esc_html($map[$code]) . '</p></div>';
|
||||
if ($code === 'after_sale_review_failed' && isset($_GET['after_sale_error'])) {
|
||||
if ($code === 'after_sale_update_failed' && isset($_GET['after_sale_error'])) {
|
||||
echo '<div class="notice notice-error"><p>' . esc_html(sanitize_text_field((string) wp_unslash($_GET['after_sale_error']))) . '</p></div>';
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user