Files
wordpress-theme-aksrt/inc/classes/admin/class-aksrt-admin-shop-controller.php
T
kate522 f3db6c89cc feat(shop): complete storefront archive, seller edit, revenue
Wire product cat/tag archives to settings-driven sort and AJAX paging,
seller product options/video/params editing, revenue withdraw form and
order review submit — finishing remaining shop frontend gaps after buy-path.
2026-07-12 10:38:02 +08:00

420 lines
18 KiB
PHP

<?php
/**
* AKSRT Admin — Shop Controller
*
* Owns REST routes for the "商城&商品" domain.
* Provides product CRUD, order management, and shop overview.
*
* @package AKSRT
*/
defined('ABSPATH') || exit;
class AKSRT_Admin_Shop_Controller extends AKSRT_Admin_Controller_Base {
use AKSRT_Admin_Shop_Controller_Product_Admin_Columns;
use AKSRT_Admin_Shop_Controller_Frontend_Flow_Operations;
use AKSRT_Admin_Shop_Controller_Product_Operations;
use AKSRT_Admin_Shop_Controller_Order_Operations;
use AKSRT_Admin_Shop_Controller_Fulfillment_Operations;
use AKSRT_Admin_Shop_Controller_Coupon_Gateway_Operations;
use AKSRT_Admin_Shop_Controller_Variant_Export_Operations;
private static $instance = null;
private $admin;
public static function get_instance(): self {
if (null === self::$instance) self::$instance = new self();
return self::$instance;
}
public function set_admin(AKSRT_Admin $admin): void {
$this->admin = $admin;
}
public function register_routes(): void {
register_rest_route(self::API_NAMESPACE, '/shop/frontend/checkout/preview', [
'methods' => 'POST',
'callback' => [$this, 'preview_checkout'],
'permission_callback' => [$this, 'check_logged_in_permission'],
]);
register_rest_route(self::API_NAMESPACE, '/shop/frontend/orders', [
'methods' => 'POST',
'callback' => [$this, 'create_frontend_order'],
'permission_callback' => [$this, 'check_logged_in_permission'],
]);
register_rest_route(self::API_NAMESPACE, '/shop/frontend/orders', [
'methods' => 'GET',
'callback' => [$this, 'get_frontend_orders'],
'permission_callback' => [$this, 'check_logged_in_permission'],
]);
register_rest_route(self::API_NAMESPACE, '/shop/frontend/orders/(?P<order_number>[A-Za-z0-9]+)/pay', [
'methods' => 'POST',
'callback' => [$this, 'pay_frontend_order'],
'permission_callback' => [$this, 'check_logged_in_permission'],
]);
register_rest_route(self::API_NAMESPACE, '/shop/frontend/orders/(?P<order_number>[A-Za-z0-9]+)/cancel', [
'methods' => 'POST',
'callback' => [$this, 'cancel_frontend_order'],
'permission_callback' => [$this, 'check_logged_in_permission'],
]);
register_rest_route(self::API_NAMESPACE, '/shop/frontend/orders/(?P<order_number>[A-Za-z0-9]+)', [
'methods' => 'GET',
'callback' => [$this, 'get_frontend_order'],
'permission_callback' => [$this, 'check_logged_in_permission'],
]);
register_rest_route(self::API_NAMESPACE, '/shop/frontend/orders/(?P<order_number>[A-Za-z0-9]+)/after-sale', [
'methods' => 'POST',
'callback' => [$this, 'create_frontend_after_sale'],
'permission_callback' => [$this, 'check_logged_in_permission'],
]);
// ── Address book CRUD (frontend) ──
register_rest_route(self::API_NAMESPACE, '/shop/frontend/address', [
'methods' => 'GET',
'callback' => [$this, 'get_frontend_addresses'],
'permission_callback' => [$this, 'check_logged_in_permission'],
]);
register_rest_route(self::API_NAMESPACE, '/shop/frontend/address', [
'methods' => 'POST',
'callback' => [$this, 'create_frontend_address'],
'permission_callback' => [$this, 'check_logged_in_permission'],
]);
register_rest_route(self::API_NAMESPACE, '/shop/frontend/address/(?P<id>\d+)', [
'methods' => 'POST',
'callback' => [$this, 'update_frontend_address'],
'permission_callback' => [$this, 'check_logged_in_permission'],
]);
register_rest_route(self::API_NAMESPACE, '/shop/frontend/address/(?P<id>\d+)', [
'methods' => 'DELETE',
'callback' => [$this, 'delete_frontend_address'],
'permission_callback' => [$this, 'check_logged_in_permission'],
]);
register_rest_route(self::API_NAMESPACE, '/shop/frontend/address/(?P<id>\d+)/default', [
'methods' => 'POST',
'callback' => [$this, 'set_default_frontend_address'],
'permission_callback' => [$this, 'check_logged_in_permission'],
]);
register_rest_route(self::API_NAMESPACE, '/shop/frontend/products', [
'methods' => 'POST',
'callback' => [$this, 'create_frontend_product'],
'permission_callback' => [$this, 'check_logged_in_permission'],
]);
register_rest_route(self::API_NAMESPACE, '/shop/frontend/products/(?P<id>\d+)', [
'methods' => 'POST',
'callback' => [$this, 'update_frontend_product'],
'permission_callback' => [$this, 'check_logged_in_permission'],
]);
// Cart endpoints (§6.4)
register_rest_route(self::API_NAMESPACE, '/shop/frontend/cart', [
'methods' => 'GET',
'callback' => [$this, 'get_cart'],
'permission_callback' => [$this, 'check_logged_in_permission'],
]);
register_rest_route(self::API_NAMESPACE, '/shop/frontend/cart/add', [
'methods' => 'POST',
'callback' => [$this, 'handle_add_to_cart'],
'permission_callback' => [$this, 'check_logged_in_permission'],
]);
register_rest_route(self::API_NAMESPACE, '/shop/frontend/cart/reduce', [
'methods' => 'POST',
'callback' => [$this, 'handle_reduce_from_cart'],
'permission_callback' => [$this, 'check_logged_in_permission'],
]);
register_rest_route(self::API_NAMESPACE, '/shop/frontend/cart/remove', [
'methods' => 'POST',
'callback' => [$this, 'handle_remove_from_cart'],
'permission_callback' => [$this, 'check_logged_in_permission'],
]);
register_rest_route(self::API_NAMESPACE, '/shop/frontend/cart/remove-multi', [
'methods' => 'POST',
'callback' => [$this, 'handle_remove_multi_from_cart'],
'permission_callback' => [$this, 'check_logged_in_permission'],
]);
register_rest_route(self::API_NAMESPACE, '/shop/frontend/cart/empty', [
'methods' => 'POST',
'callback' => [$this, 'handle_empty_cart'],
'permission_callback' => [$this, 'check_logged_in_permission'],
]);
register_rest_route(self::API_NAMESPACE, '/shop/frontend/cart/count', [
'methods' => 'GET',
'callback' => [$this, 'get_cart_count'],
'permission_callback' => [$this, 'check_logged_in_permission'],
]);
// Shop overview / dashboard
register_rest_route(self::API_NAMESPACE, '/shop/overview', [
'methods' => 'GET',
'callback' => [$this, 'get_overview'],
'permission_callback' => [$this, 'check_permission'],
]);
// Product taxonomy options used by the product editor.
register_rest_route(self::API_NAMESPACE, '/shop/products/taxonomy', [
'methods' => 'GET',
'callback' => [$this, 'get_product_taxonomy'],
'permission_callback' => [$this, 'check_permission'],
]);
// Create product category or tag term for the product editor.
register_rest_route(self::API_NAMESPACE, '/shop/products/taxonomy', [
'methods' => 'POST',
'callback' => [$this, 'create_product_taxonomy_term'],
'permission_callback' => [$this, 'check_permission'],
]);
// Product list
register_rest_route(self::API_NAMESPACE, '/shop/products', [
'methods' => 'GET',
'callback' => [$this, 'get_products'],
'permission_callback' => [$this, 'check_permission'],
]);
// Product create
register_rest_route(self::API_NAMESPACE, '/shop/products', [
'methods' => 'POST',
'callback' => [$this, 'create_product'],
'permission_callback' => [$this, 'check_permission'],
]);
// Product update
register_rest_route(self::API_NAMESPACE, '/shop/products/(?P<id>\d+)', [
'methods' => 'POST',
'callback' => [$this, 'update_product'],
'permission_callback' => [$this, 'check_permission'],
]);
// Product single read
register_rest_route(self::API_NAMESPACE, '/shop/products/(?P<id>\d+)', [
'methods' => 'GET',
'callback' => [$this, 'get_product'],
'permission_callback' => [$this, 'check_permission'],
]);
// Order list
register_rest_route(self::API_NAMESPACE, '/shop/orders', [
'methods' => 'GET',
'callback' => [$this, 'get_orders'],
'permission_callback' => [$this, 'check_permission'],
]);
// Order single read
register_rest_route(self::API_NAMESPACE, '/shop/orders/(?P<order_number>[A-Za-z0-9]+)', [
'methods' => 'GET',
'callback' => [$this, 'get_order'],
'permission_callback' => [$this, 'check_permission'],
]);
// Order status update — canonical field is order_number
register_rest_route(self::API_NAMESPACE, '/shop/orders/update-status', [
'methods' => 'POST',
'callback' => [$this, 'update_order_status'],
'permission_callback' => [$this, 'check_permission'],
]);
// Gateway status
register_rest_route(self::API_NAMESPACE, '/shop/gateways', [
'methods' => 'GET',
'callback' => [$this, 'get_gateways'],
'permission_callback' => [$this, 'check_permission'],
]);
// Coupon list (admin)
register_rest_route(self::API_NAMESPACE, '/shop/coupons', [
'methods' => 'GET',
'callback' => [$this, 'get_coupons'],
'permission_callback' => [$this, 'check_permission'],
]);
// Coupon create (admin)
register_rest_route(self::API_NAMESPACE, '/shop/coupons', [
'methods' => 'POST',
'callback' => [$this, 'create_coupon'],
'permission_callback' => [$this, 'check_permission'],
]);
// Coupon disable (admin)
register_rest_route(self::API_NAMESPACE, '/shop/coupons/(?P<id>\d+)/disable', [
'methods' => 'POST',
'callback' => [$this, 'disable_coupon'],
'permission_callback' => [$this, 'check_permission'],
]);
// ── After Sale ──
// After-sale list (admin)
register_rest_route(self::API_NAMESPACE, '/shop/after-sale', [
'methods' => 'GET',
'callback' => [$this, 'get_after_sale_list'],
'permission_callback' => [$this, 'check_permission'],
]);
// After-sale create (admin)
register_rest_route(self::API_NAMESPACE, '/shop/after-sale', [
'methods' => 'POST',
'callback' => [$this, 'create_after_sale'],
'permission_callback' => [$this, 'check_permission'],
]);
// After-sale status update (admin)
register_rest_route(self::API_NAMESPACE, '/shop/after-sale/(?P<id>\d+)/update-status', [
'methods' => 'POST',
'callback' => [$this, 'update_after_sale_status'],
'permission_callback' => [$this, 'check_permission'],
]);
register_rest_route(self::API_NAMESPACE, '/shop/after-sale/(?P<id>\d+)', [
'methods' => 'GET',
'callback' => [$this, 'get_after_sale_detail'],
'permission_callback' => [$this, 'check_permission'],
]);
// ── Shipping ──
// Shipping list (admin)
register_rest_route(self::API_NAMESPACE, '/shop/shipping', [
'methods' => 'GET',
'callback' => [$this, 'get_shipping_list'],
'permission_callback' => [$this, 'check_permission'],
]);
// Shipping create (admin)
register_rest_route(self::API_NAMESPACE, '/shop/shipping', [
'methods' => 'POST',
'callback' => [$this, 'create_shipping'],
'permission_callback' => [$this, 'check_permission'],
]);
// Shipping status update (admin)
register_rest_route(self::API_NAMESPACE, '/shop/shipping/(?P<id>\d+)/update-status', [
'methods' => 'POST',
'callback' => [$this, 'update_shipping_status'],
'permission_callback' => [$this, 'check_permission'],
]);
register_rest_route(self::API_NAMESPACE, '/shop/shipping/(?P<id>\d+)', [
'methods' => 'GET',
'callback' => [$this, 'get_shipping_detail'],
'permission_callback' => [$this, 'check_permission'],
]);
register_rest_route(self::API_NAMESPACE, '/shop/shipping/batch-update-status', [
'methods' => 'POST',
'callback' => [$this, 'batch_update_shipping_status'],
'permission_callback' => [$this, 'check_permission'],
]);
// ── R68: Order export + confirm receipt + after-sale reasons ──
register_rest_route(self::API_NAMESPACE, '/shop/orders/export', [
'methods' => 'GET',
'callback' => [$this, 'export_orders'],
'permission_callback' => [$this, 'check_permission'],
]);
// ── R69: Frontend after-sale reasons (§6.8) ──
register_rest_route(self::API_NAMESPACE, '/shop/frontend/after-sale/reasons', [
'methods' => 'GET',
'callback' => [$this, 'get_frontend_after_sale_reasons'],
'permission_callback' => [$this, 'check_logged_in_permission'],
]);
register_rest_route(self::API_NAMESPACE, '/shop/frontend/orders/(?P<order_number>[A-Za-z0-9]+)/confirm-receipt', [
'methods' => 'POST',
'callback' => [$this, 'confirm_receipt'],
'permission_callback' => [$this, 'check_logged_in_permission'],
]);
register_rest_route(self::API_NAMESPACE, '/shop/frontend/orders/(?P<order_number>[A-Za-z0-9]+)/rebuy', [
'methods' => 'POST',
'callback' => [$this, 'rebuy_frontend_order'],
'permission_callback' => [$this, 'check_logged_in_permission'],
]);
register_rest_route(self::API_NAMESPACE, '/shop/frontend/products/archive', [
'methods' => 'GET',
'callback' => [$this, 'get_frontend_product_archive'],
'permission_callback' => '__return_true',
]);
register_rest_route(self::API_NAMESPACE, '/shop/frontend/revenue', [
'methods' => 'GET',
'callback' => [$this, 'get_frontend_revenue'],
'permission_callback' => [$this, 'check_logged_in_permission'],
]);
register_rest_route(self::API_NAMESPACE, '/shop/frontend/revenue/withdraw', [
'methods' => 'POST',
'callback' => [$this, 'create_frontend_withdraw'],
'permission_callback' => [$this, 'check_logged_in_permission'],
]);
register_rest_route(self::API_NAMESPACE, '/shop/frontend/orders/(?P<order_number>[A-Za-z0-9]+)/review', [
'methods' => 'POST',
'callback' => [$this, 'submit_frontend_product_review'],
'permission_callback' => [$this, 'check_logged_in_permission'],
]);
register_rest_route(self::API_NAMESPACE, '/shop/frontend/products/(?P<id>\d+)/favorite', [
'methods' => 'POST',
'callback' => [$this, 'toggle_frontend_product_favorite'],
'permission_callback' => [$this, 'check_logged_in_permission'],
]);
register_rest_route(self::API_NAMESPACE, '/shop/after-sale/reasons', [
'methods' => 'GET',
'callback' => [$this, 'get_after_sale_reasons'],
'permission_callback' => [$this, 'check_permission'],
]);
// ── Product Variants / SKU ──
// List variants for a product
register_rest_route(self::API_NAMESPACE, '/shop/products/(?P<id>\d+)/variants', [
'methods' => 'GET',
'callback' => [$this, 'get_product_variants'],
'permission_callback' => [$this, 'check_permission'],
]);
// Save variants for a product (replace all)
register_rest_route(self::API_NAMESPACE, '/shop/products/(?P<id>\d+)/variants', [
'methods' => 'POST',
'callback' => [$this, 'save_product_variants'],
'permission_callback' => [$this, 'check_permission'],
]);
// Delete a variant
register_rest_route(self::API_NAMESPACE, '/shop/variants/(?P<id>\d+)', [
'methods' => 'DELETE',
'callback' => [$this, 'delete_variant'],
'permission_callback' => [$this, 'check_permission'],
]);
}
public function check_logged_in_permission(): bool {
return is_user_logged_in();
}
}