Files
wordpress-theme-aksrt/inc/classes/admin/class-aksrt-admin-shop-controller-order-operations.php
T

137 lines
5.2 KiB
PHP

<?php
/**
* AKSRT admin shop order operations.
*
* @package AKSRT
*/
defined('ABSPATH') || exit;
trait AKSRT_Admin_Shop_Controller_Order_Operations {
/**
* GET /shop/orders — 订单列表,支持 search、status、page、per_page
*/
public function get_orders(WP_REST_Request $request): WP_REST_Response {
$page = max(1, (int) $request->get_param('page'));
$per_page = max(1, min(50, (int) $request->get_param('per_page'))) ?: 20;
$search = sanitize_text_field((string) $request->get_param('search'));
$status = sanitize_key((string) $request->get_param('status'));
if (class_exists('AKSRT_Order_Repository')) {
$repo = AKSRT_Order_Repository::get_instance();
$args = [
'limit' => $per_page,
'offset' => ($page - 1) * $per_page,
];
if ($status !== '' && $status !== 'all') {
$args['status'] = $status;
}
$orders = $repo->get_orders_admin($args, $search);
$total = $repo->get_orders_count($args, $search);
return $this->success([
'data' => [
'items' => $orders,
'total' => $total,
'page' => $page,
'total_pages' => max(1, (int) ceil($total / $per_page)),
],
]);
}
return $this->error('订单仓库不可用', 500);
}
/**
* GET /shop/orders/{order_number} — 单个订单详情(含上下文)
*/
public function get_order(WP_REST_Request $request): WP_REST_Response {
$order_number = sanitize_text_field((string) $request->get_param('order_number'));
if (!class_exists('AKSRT_Order_Repository')) {
return $this->error('订单服务不可用', 500);
}
$repo = AKSRT_Order_Repository::get_instance();
$order = $repo->get($order_number);
if (!$order) {
return $this->error('订单不存在', 404);
}
$context = $repo->get_admin_order_context($order_number);
$timeline = [];
if (class_exists('AKSRT_Shop')) {
$shipping_records = class_exists('AKSRT_Shipping') ? AKSRT_Shipping::get_instance()->get_by_order($order_number) : [];
$after_sale_result = class_exists('AKSRT_After_Sale') ? AKSRT_After_Sale::get_instance()->get_list(['order_number' => $order_number, 'limit' => 20]) : ['items' => []];
$after_sale_items = $after_sale_result['items'] ?? [];
$timeline = [];
$date_fields = [
'created_at' => '订单创建',
'paid_at' => '完成支付',
];
foreach ($date_fields as $field => $label) {
if (!empty($order[$field])) {
$timeline[] = ['time' => $order[$field], 'title' => $label, 'type' => 'order'];
}
}
foreach ($shipping_records as $record) {
$timeline[] = [
'time' => $record['created_at'] ?? '',
'title' => '物流更新:' . ($record['status_label'] ?? $record['status'] ?? ''),
'detail' => ($record['carrier_label'] ?? '') . ' / ' . ($record['tracking_no'] ?? ''),
'type' => 'shipping',
];
}
foreach ($after_sale_items as $record) {
$timeline[] = [
'time' => $record['created_at'] ?? '',
'title' => '售后:' . ($record['type_label'] ?? '') . ' — ' . ($record['status_label'] ?? ''),
'detail' => $record['reason'] ?? '',
'type' => 'after_sale',
];
}
usort($timeline, static function ($a, $b) {
return strcmp((string) ($b['time'] ?? ''), (string) ($a['time'] ?? ''));
});
}
return $this->success([
'data' => $order,
'context' => $context,
'timeline' => $timeline,
]);
}
/**
* POST /shop/orders/update-status — 更新订单状态
* Canonical field: order_number (前端必须发送 order_number)
*/
public function update_order_status(WP_REST_Request $request): WP_REST_Response {
$params = $this->get_json_params($request);
$order_number = sanitize_text_field((string) ($params['order_number'] ?? ''));
$new_status = sanitize_key((string) ($params['status'] ?? ''));
$note = sanitize_textarea_field((string) ($params['note'] ?? ''));
if ($order_number === '' || $new_status === '') {
return $this->error('参数无效');
}
$success = false;
if (class_exists('AKSRT_Order_Repository')) {
$success = AKSRT_Order_Repository::get_instance()->update_status($order_number, $new_status, [
'note' => $note,
'force' => true,
]);
}
if ($success) {
return $this->success(['message' => __('订单状态已更新', 'aksrt')]);
}
return $this->error(__('更新失败', 'aksrt'));
}
}