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')); } }