feat(admin): pending shipment board with immediate ship actions
Add paid-but-unshipped order queue on the shipping page (zibll-style), repository query via NOT EXISTS on order_shipping, overview pending card, and create-shipping redirect back to the pending tab.
This commit is contained in:
1 parent
d1697c19d9
commit
4c5e4ab222
3 files changed
+180
-6
No files matched your search
@@ -348,6 +348,63 @@ class AKSRT_Order_Repository {
|
||||
/**
|
||||
* 管理后台订单列表 — 支持 search(order_number / product_type 模糊匹配)
|
||||
*/
|
||||
/**
|
||||
* Paid orders that still need shipping (no shipping row yet).
|
||||
*
|
||||
* @return array{items: array<int,array<string,mixed>>, total: int, page: int, max_pages: int}
|
||||
*/
|
||||
public function get_pending_shipment_orders(array $args = []): array {
|
||||
global $wpdb;
|
||||
|
||||
$limit = max(1, min(100, (int) ($args['limit'] ?? 20)));
|
||||
$offset = max(0, (int) ($args['offset'] ?? 0));
|
||||
$search = sanitize_text_field((string) ($args['search'] ?? $args['s'] ?? ''));
|
||||
|
||||
$order_table = $this->table();
|
||||
// Must match AKSRT_Shipping::table() key.
|
||||
$shipping_table = class_exists('AKSRT_DB_Migrator')
|
||||
? AKSRT_DB_Migrator::table('order_shipping')
|
||||
: $wpdb->prefix . 'aksrt_order_shipping';
|
||||
|
||||
$where = ["o.status = %s"];
|
||||
$params = ['paid'];
|
||||
|
||||
if ($search !== '') {
|
||||
$where[] = '(o.order_number LIKE %s OR o.product_type LIKE %s)';
|
||||
$like = '%' . $wpdb->esc_like($search) . '%';
|
||||
$params[] = $like;
|
||||
$params[] = $like;
|
||||
}
|
||||
|
||||
// NOT EXISTS avoids ONLY_FULL_GROUP_BY issues from LEFT JOIN + GROUP BY.
|
||||
$where[] = "NOT EXISTS (
|
||||
SELECT 1 FROM {$shipping_table} s
|
||||
WHERE s.order_number = o.order_number
|
||||
)";
|
||||
$where_sql = 'WHERE ' . implode(' AND ', $where);
|
||||
|
||||
$count_sql = "SELECT COUNT(*) FROM {$order_table} o {$where_sql}";
|
||||
$total = (int) $wpdb->get_var($wpdb->prepare($count_sql, $params));
|
||||
|
||||
$sql = "SELECT o.*
|
||||
FROM {$order_table} o
|
||||
{$where_sql}
|
||||
ORDER BY COALESCE(o.paid_at, o.created_at) DESC, o.id DESC
|
||||
LIMIT %d OFFSET %d";
|
||||
$query_params = $params;
|
||||
$query_params[] = $limit;
|
||||
$query_params[] = $offset;
|
||||
$rows = $wpdb->get_results($wpdb->prepare($sql, $query_params), ARRAY_A);
|
||||
$items = array_map([$this, 'normalize_row'], (array) $rows);
|
||||
|
||||
return [
|
||||
'items' => $items,
|
||||
'total' => $total,
|
||||
'page' => (int) floor($offset / $limit) + 1,
|
||||
'max_pages' => (int) ceil(max(1, $total) / $limit),
|
||||
];
|
||||
}
|
||||
|
||||
public function get_orders_admin(array $args = [], string $search = ''): array {
|
||||
global $wpdb;
|
||||
|
||||
|
||||
Reference in new issue
Block a user