model = new \app\common\model\MallOrder(); } /** * 查看 * @throws Throwable */ public function index(Request $request): Response { $response = $this->initializeBackend($request); if ($response !== null) { return $response; } if ($request->get('select') || $request->post('select')) { return $this->select($request); } [$where, $alias, $limit, $order] = $this->queryBuilder(); $res = $this->model ->with(['mallItem' => function ($query) { $query->field('id,title'); }]) ->visible(['mallItem' => ['title']]) ->alias($alias) ->where($where) ->order($order) ->paginate($limit); return $this->success('', [ 'list' => $res->items(), 'total' => $res->total(), 'remark' => get_route_remark(), ]); } /** * PHYSICAL 发货:更新 shipping_company/shipping_no,并将状态置为 SHIPPED */ public function ship(Request $request): Response { $response = $this->initializeBackend($request); if ($response !== null) { return $response; } if ($request->method() !== 'POST') { return $this->error(__('Parameter error')); } $data = $request->post(); $id = $data['id'] ?? 0; $shippingCompany = $data['shipping_company'] ?? ''; $shippingNo = $data['shipping_no'] ?? ''; if (!$id || $shippingCompany === '' || $shippingNo === '') { return $this->error(__('Missing required fields')); } $order = MallOrder::where('id', $id)->find(); if (!$order) { return $this->error(__('Record not found')); } if ($order->type !== MallOrder::TYPE_PHYSICAL) { return $this->error(__('Order type not PHYSICAL')); } if ($order->status !== MallOrder::STATUS_PENDING) { return $this->error(__('Order status must be PENDING')); } Db::startTrans(); try { $order->shipping_company = $shippingCompany; $order->shipping_no = $shippingNo; $order->status = MallOrder::STATUS_SHIPPED; $order->save(); Db::commit(); } catch (Throwable $e) { Db::rollback(); return $this->error($e->getMessage()); } return $this->success(__('Shipped successfully')); } /** * 审核通过(非 PHYSICAL):更新状态为 COMPLETED */ public function approve(Request $request): Response { $response = $this->initializeBackend($request); if ($response !== null) { return $response; } if ($request->method() !== 'POST') { return $this->error(__('Parameter error')); } $id = $request->post('id', 0); if (!$id) { return $this->error(__('Missing required fields')); } $order = MallOrder::where('id', $id)->find(); if (!$order) { return $this->error(__('Record not found')); } if ($order->status !== MallOrder::STATUS_PENDING) { return $this->error(__('Order status must be PENDING')); } if ($order->type === MallOrder::TYPE_PHYSICAL) { return $this->error(__('Order type not supported')); } Db::startTrans(); try { $order->status = MallOrder::STATUS_COMPLETED; $order->update_time = time(); $order->save(); Db::commit(); } catch (Throwable $e) { Db::rollback(); return $this->error($e->getMessage()); } return $this->success(__('Approved successfully')); } /** * 审核驳回:更新状态为 REJECTED,并退回积分到 available_points(所有类型通用) */ public function reject(Request $request): Response { $response = $this->initializeBackend($request); if ($response !== null) { return $response; } if ($request->method() !== 'POST') { return $this->error(__('Parameter error')); } $data = $request->post(); $id = $data['id'] ?? 0; $rejectReason = $data['reject_reason'] ?? ''; if (!$id) { return $this->error(__('Missing required fields')); } $order = MallOrder::where('id', $id)->find(); if (!$order) { return $this->error(__('Record not found')); } if ($order->status !== MallOrder::STATUS_PENDING) { return $this->error(__('Order status must be PENDING')); } if ($order->type === MallOrder::TYPE_PHYSICAL && $rejectReason === '') { return $this->error(__('Missing required fields')); } Db::startTrans(); try { $asset = MallUserAsset::where('playx_user_id', $order->user_id ?? '')->find(); if (!$asset) { throw new \RuntimeException('User asset not found'); } $refund = $order->points_cost ?? 0; if ($refund > 0) { $asset->available_points += $refund; $asset->save(); } $order->status = MallOrder::STATUS_REJECTED; $order->reject_reason = $rejectReason; if ($order->type === MallOrder::TYPE_BONUS) { $order->grant_status = MallOrder::GRANT_FAILED_FINAL; } else { $order->grant_status = MallOrder::GRANT_NOT_APPLICABLE; } $order->update_time = time(); $order->save(); Db::commit(); } catch (Throwable $e) { Db::rollback(); return $this->error($e->getMessage()); } return $this->success(__('Rejected successfully')); } /** * 手动重试(仅红利推送失败可重试) */ public function retry(Request $request): Response { $response = $this->initializeBackend($request); if ($response !== null) { return $response; } if ($request->method() !== 'POST') { return $this->error(__('Parameter error')); } $id = $request->post('id', 0); if (!$id) { return $this->error(__('Missing required fields')); } $order = MallOrder::where('id', $id)->find(); if (!$order) { return $this->error(__('Record not found')); } if ($order->type !== MallOrder::TYPE_BONUS) { return $this->error(__('Only BONUS can retry')); } if ($order->grant_status !== MallOrder::GRANT_FAILED_RETRYABLE) { return $this->error(__('Only FAILED_RETRYABLE can retry')); } if (($order->retry_count ?? 0) >= 3) { return $this->error(__('Retry count exceeded')); } $order->grant_status = MallOrder::GRANT_NOT_SENT; $order->save(); return $this->success(__('Retry queued')); } }