refactor(autoload): migrate theme classes to Composer PSR-4
Move 288 types from global AKSRT_* + inc/classes manual requires into
namespace AKSRT\{Domain} under src/AKSRT/, wire composer.json psr-4,
and slim bootstrap to helpers/modules/hooks only. Split multi-class
widget/gateway files, update admin contract audit paths, and document
the layout in ADR/README.
This commit is contained in:
@@ -0,0 +1,354 @@
|
||||
<?php
|
||||
/**
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
namespace AKSRT\Admin;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
trait ShopControllerFulfillmentOperations {
|
||||
|
||||
/**
|
||||
* GET /shop/after-sale — 售后工单列表
|
||||
*/
|
||||
public function get_after_sale_list(\WP_REST_Request $request): \WP_REST_Response {
|
||||
if (!class_exists('\AKSRT\Payment\AfterSale')) {
|
||||
return $this->success(['data' => ['items' => [], 'total' => 0, 'page' => 1, 'max_pages' => 1]]);
|
||||
}
|
||||
|
||||
$page = max(1, (int) $request->get_param('page'));
|
||||
$per_page = max(1, min(100, (int) $request->get_param('per_page'))) ?: 20;
|
||||
$status = sanitize_key((string) $request->get_param('status'));
|
||||
$stage = sanitize_key((string) $request->get_param('stage'));
|
||||
$order = sanitize_text_field((string) $request->get_param('order_number'));
|
||||
$type = sanitize_key((string) $request->get_param('type'));
|
||||
$date_from = sanitize_text_field((string) $request->get_param('date_from'));
|
||||
$date_to = sanitize_text_field((string) $request->get_param('date_to'));
|
||||
|
||||
$result = \AKSRT\Payment\AfterSale::get_instance()->get_list([
|
||||
'limit' => $per_page,
|
||||
'offset' => ($page - 1) * $per_page,
|
||||
'status' => $status,
|
||||
'stage' => $stage,
|
||||
'order_number' => $order,
|
||||
'type' => $type,
|
||||
'date_from' => $date_from,
|
||||
'date_to' => $date_to,
|
||||
'include_order_context' => true,
|
||||
]);
|
||||
|
||||
$stats = \AKSRT\Payment\AfterSale::get_instance()->get_stats();
|
||||
|
||||
return $this->success(['data' => array_merge($result, [
|
||||
'stats' => $stats,
|
||||
'filters' => [
|
||||
'status' => $status,
|
||||
'stage' => $stage,
|
||||
'order_number' => $order,
|
||||
'type' => $type,
|
||||
'date_from' => $date_from,
|
||||
'date_to' => $date_to,
|
||||
],
|
||||
'options' => [
|
||||
'status' => \AKSRT\Payment\AfterSale::get_status_options(),
|
||||
'stage' => \AKSRT\Payment\AfterSale::get_stage_options(),
|
||||
'type' => \AKSRT\Payment\AfterSale::get_type_options(),
|
||||
],
|
||||
])]);
|
||||
}
|
||||
|
||||
/**
|
||||
* POST /shop/after-sale — 创建售后工单
|
||||
*/
|
||||
public function create_after_sale(\WP_REST_Request $request): \WP_REST_Response {
|
||||
if (!class_exists('\AKSRT\Payment\AfterSale')) {
|
||||
return $this->error('售后系统未启用', 500);
|
||||
}
|
||||
|
||||
$params = $this->get_json_params($request);
|
||||
$order_number = sanitize_text_field((string) ($params['order_number'] ?? ''));
|
||||
$reason = sanitize_textarea_field((string) ($params['reason'] ?? ''));
|
||||
|
||||
if ($order_number === '' || $reason === '') {
|
||||
return $this->error('订单号和原因不能为空');
|
||||
}
|
||||
|
||||
$order = class_exists('\AKSRT\Payment\OrderRepository')
|
||||
? \AKSRT\Payment\OrderRepository::get_instance()->get($order_number)
|
||||
: null;
|
||||
|
||||
if (!$order) {
|
||||
return $this->error(__('订单不存在', 'aksrt'), 404);
|
||||
}
|
||||
|
||||
$params['user_id'] = (int) ($params['user_id'] ?? ($order['user_id'] ?? 0));
|
||||
if ($params['user_id'] <= 0) {
|
||||
return $this->error(__('订单未绑定有效用户', 'aksrt'));
|
||||
}
|
||||
|
||||
$id = \AKSRT\Payment\AfterSale::get_instance()->create($params);
|
||||
|
||||
if ($id > 0) {
|
||||
return $this->success([
|
||||
'message' => __('售后工单已创建', 'aksrt'),
|
||||
'data' => ['id' => $id],
|
||||
], 201);
|
||||
}
|
||||
|
||||
return $this->error(__('创建失败', 'aksrt'));
|
||||
}
|
||||
|
||||
/**
|
||||
* POST /shop/after-sale/{id}/update-status — 更新售后工单状态
|
||||
*/
|
||||
public function update_after_sale_status(\WP_REST_Request $request): \WP_REST_Response {
|
||||
if (!class_exists('\AKSRT\Payment\AfterSale')) {
|
||||
return $this->error('售后系统未启用', 500);
|
||||
}
|
||||
|
||||
$id = (int) $request->get_param('id');
|
||||
$params = $this->get_json_params($request);
|
||||
$new_status = sanitize_key((string) ($params['status'] ?? ''));
|
||||
$note = sanitize_textarea_field((string) ($params['operator_note'] ?? ''));
|
||||
|
||||
if ($id <= 0 || $new_status === '') {
|
||||
return $this->error('参数无效');
|
||||
}
|
||||
|
||||
$success = \AKSRT\Payment\AfterSale::get_instance()->update_status(
|
||||
$id,
|
||||
$new_status,
|
||||
get_current_user_id(),
|
||||
$note
|
||||
);
|
||||
|
||||
if ($success) {
|
||||
return $this->success(['message' => __('状态已更新', 'aksrt')]);
|
||||
}
|
||||
return $this->error(__('更新失败', 'aksrt'));
|
||||
}
|
||||
|
||||
/**
|
||||
* GET /shop/shipping — 发货记录列表
|
||||
*/
|
||||
public function get_shipping_list(\WP_REST_Request $request): \WP_REST_Response {
|
||||
if (!class_exists('\AKSRT\Payment\Shipping')) {
|
||||
return $this->success(['data' => ['items' => [], 'total' => 0, 'page' => 1, 'max_pages' => 1]]);
|
||||
}
|
||||
|
||||
$page = max(1, (int) $request->get_param('page'));
|
||||
$per_page = max(1, min(100, (int) $request->get_param('per_page'))) ?: 20;
|
||||
$status = sanitize_key((string) $request->get_param('status'));
|
||||
$order = sanitize_text_field((string) $request->get_param('order_number'));
|
||||
$date_from = sanitize_text_field((string) $request->get_param('date_from'));
|
||||
$date_to = sanitize_text_field((string) $request->get_param('date_to'));
|
||||
$tracking_no = sanitize_text_field((string) $request->get_param('tracking_no'));
|
||||
|
||||
$result = \AKSRT\Payment\Shipping::get_instance()->get_list([
|
||||
'limit' => $per_page,
|
||||
'offset' => ($page - 1) * $per_page,
|
||||
'status' => $status,
|
||||
'order_number' => $order,
|
||||
'date_from' => $date_from,
|
||||
'date_to' => $date_to,
|
||||
'tracking_no' => $tracking_no,
|
||||
'include_order_context' => true,
|
||||
]);
|
||||
|
||||
$stats = \AKSRT\Payment\Shipping::get_instance()->get_stats();
|
||||
|
||||
return $this->success(['data' => array_merge($result, [
|
||||
'stats' => $stats,
|
||||
'filters' => [
|
||||
'status' => $status,
|
||||
'order_number' => $order,
|
||||
'date_from' => $date_from,
|
||||
'date_to' => $date_to,
|
||||
'tracking_no' => $tracking_no,
|
||||
],
|
||||
'options' => [
|
||||
'status' => \AKSRT\Payment\Shipping::get_status_options(),
|
||||
'carrier' => \AKSRT\Payment\Shipping::get_carrier_options(),
|
||||
],
|
||||
])]);
|
||||
}
|
||||
|
||||
/**
|
||||
* POST /shop/shipping — 创建发货记录
|
||||
*/
|
||||
public function create_shipping(\WP_REST_Request $request): \WP_REST_Response {
|
||||
if (!class_exists('\AKSRT\Payment\Shipping')) {
|
||||
return $this->error('物流系统未启用', 500);
|
||||
}
|
||||
|
||||
$params = $this->get_json_params($request);
|
||||
$order_number = sanitize_text_field((string) ($params['order_number'] ?? ''));
|
||||
$carrier = sanitize_text_field((string) ($params['carrier'] ?? ''));
|
||||
$tracking_no = sanitize_text_field((string) ($params['tracking_no'] ?? ''));
|
||||
|
||||
if ($order_number === '' || $carrier === '' || $tracking_no === '') {
|
||||
return $this->error('订单号、快递公司和物流单号不能为空');
|
||||
}
|
||||
|
||||
$order = class_exists('\AKSRT\Payment\OrderRepository')
|
||||
? \AKSRT\Payment\OrderRepository::get_instance()->get($order_number)
|
||||
: null;
|
||||
|
||||
if (!$order) {
|
||||
return $this->error(__('订单不存在', 'aksrt'), 404);
|
||||
}
|
||||
|
||||
$params['operator_id'] = get_current_user_id();
|
||||
|
||||
$id = \AKSRT\Payment\Shipping::get_instance()->create($params);
|
||||
|
||||
if ($id > 0) {
|
||||
return $this->success([
|
||||
'message' => __('发货记录已创建', 'aksrt'),
|
||||
'data' => ['id' => $id],
|
||||
], 201);
|
||||
}
|
||||
|
||||
return $this->error(__('创建失败', 'aksrt'));
|
||||
}
|
||||
|
||||
/**
|
||||
* POST /shop/shipping/{id}/update-status — 更新发货状态
|
||||
*/
|
||||
public function update_shipping_status(\WP_REST_Request $request): \WP_REST_Response {
|
||||
if (!class_exists('\AKSRT\Payment\Shipping')) {
|
||||
return $this->error('物流系统未启用', 500);
|
||||
}
|
||||
|
||||
$id = (int) $request->get_param('id');
|
||||
$params = $this->get_json_params($request);
|
||||
$new_status = sanitize_key((string) ($params['status'] ?? ''));
|
||||
$note = sanitize_textarea_field((string) ($params['note'] ?? ''));
|
||||
|
||||
if ($id <= 0 || $new_status === '') {
|
||||
return $this->error('参数无效');
|
||||
}
|
||||
|
||||
$success = \AKSRT\Payment\Shipping::get_instance()->update_status($id, $new_status, $note, get_current_user_id());
|
||||
|
||||
if ($success) {
|
||||
return $this->success(['message' => __('状态已更新', 'aksrt')]);
|
||||
}
|
||||
return $this->error(__('更新失败', 'aksrt'));
|
||||
}
|
||||
|
||||
public function get_after_sale_detail(\WP_REST_Request $request): \WP_REST_Response {
|
||||
if (!class_exists('\AKSRT\Payment\AfterSale')) {
|
||||
return $this->error('售后系统未启用', 500);
|
||||
}
|
||||
|
||||
$id = (int) $request->get_param('id');
|
||||
if ($id <= 0) {
|
||||
return $this->error('参数无效');
|
||||
}
|
||||
|
||||
$record = \AKSRT\Payment\AfterSale::get_instance()->get_with_order_context($id);
|
||||
if (!$record) {
|
||||
return $this->error(__('售后工单不存在', 'aksrt'), 404);
|
||||
}
|
||||
|
||||
return $this->success([
|
||||
'data' => [
|
||||
'record' => $record,
|
||||
'timeline' => $this->build_after_sale_timeline($record),
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public function get_shipping_detail(\WP_REST_Request $request): \WP_REST_Response {
|
||||
if (!class_exists('\AKSRT\Payment\Shipping')) {
|
||||
return $this->error('物流系统未启用', 500);
|
||||
}
|
||||
|
||||
$id = (int) $request->get_param('id');
|
||||
if ($id <= 0) {
|
||||
return $this->error('参数无效');
|
||||
}
|
||||
|
||||
$record = \AKSRT\Payment\Shipping::get_instance()->get_with_order_context($id);
|
||||
if (!$record) {
|
||||
return $this->error(__('发货记录不存在', 'aksrt'), 404);
|
||||
}
|
||||
|
||||
return $this->success([
|
||||
'data' => [
|
||||
'record' => $record,
|
||||
'timeline' => $this->build_shipping_timeline($record),
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public function batch_update_shipping_status(\WP_REST_Request $request): \WP_REST_Response {
|
||||
if (!class_exists('\AKSRT\Payment\Shipping')) {
|
||||
return $this->error('物流系统未启用', 500);
|
||||
}
|
||||
|
||||
$params = $this->get_json_params($request);
|
||||
$ids = is_array($params['ids'] ?? null) ? $params['ids'] : [];
|
||||
$status = sanitize_key((string) ($params['status'] ?? ''));
|
||||
$note = sanitize_textarea_field((string) ($params['note'] ?? ''));
|
||||
|
||||
if (empty($ids) || $status === '') {
|
||||
return $this->error('参数无效');
|
||||
}
|
||||
|
||||
$result = \AKSRT\Payment\Shipping::get_instance()->batch_update_status($ids, $status, $note, get_current_user_id());
|
||||
|
||||
return $this->success([
|
||||
'message' => __('批量状态更新已执行', 'aksrt'),
|
||||
'data' => $result,
|
||||
]);
|
||||
}
|
||||
|
||||
private function build_shipping_timeline(array $record): array {
|
||||
$timeline = [];
|
||||
|
||||
foreach ([
|
||||
'created_at' => __('创建发货记录', 'aksrt'),
|
||||
'updated_at' => __('更新物流状态', 'aksrt'),
|
||||
'delivered_at' => __('确认签收', 'aksrt'),
|
||||
] as $field => $label) {
|
||||
if (!empty($record[$field])) {
|
||||
$timeline[] = [
|
||||
'time' => (string) $record[$field],
|
||||
'label' => $label,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
usort($timeline, static function ($a, $b) {
|
||||
return strcmp((string) ($a['time'] ?? ''), (string) ($b['time'] ?? ''));
|
||||
});
|
||||
|
||||
return $timeline;
|
||||
}
|
||||
|
||||
private function build_after_sale_timeline(array $record): array {
|
||||
$timeline = [];
|
||||
|
||||
foreach ([
|
||||
'created_at' => __('提交售后申请', 'aksrt'),
|
||||
'updated_at' => __('更新售后状态', 'aksrt'),
|
||||
'resolved_at' => __('售后处理结束', 'aksrt'),
|
||||
] as $field => $label) {
|
||||
if (!empty($record[$field])) {
|
||||
$timeline[] = [
|
||||
'time' => (string) $record[$field],
|
||||
'label' => $label,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
usort($timeline, static function ($a, $b) {
|
||||
return strcmp((string) ($a['time'] ?? ''), (string) ($b['time'] ?? ''));
|
||||
});
|
||||
|
||||
return $timeline;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user