model = new \app\common\model\MallPlayxOrder(); } /** * 查看 * @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); } list($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 = intval($data['id'] ?? 0); $shippingCompany = strval($data['shipping_company'] ?? ''); $shippingNo = strval($data['shipping_no'] ?? ''); if ($id <= 0 || $shippingCompany === '' || $shippingNo === '') { return $this->error(__('Missing required fields')); } $order = MallPlayxOrder::where('id', $id)->find(); if (!$order) { return $this->error(__('Record not found')); } if ($order->type !== MallPlayxOrder::TYPE_PHYSICAL) { return $this->error(__('Order type not PHYSICAL')); } if ($order->status !== MallPlayxOrder::STATUS_PENDING) { return $this->error(__('Order status must be PENDING')); } Db::startTrans(); try { $order->shipping_company = $shippingCompany; $order->shipping_no = $shippingNo; $order->status = MallPlayxOrder::STATUS_SHIPPED; $order->save(); Db::commit(); } catch (Throwable $e) { Db::rollback(); return $this->error($e->getMessage()); } return $this->success(__('Shipped successfully')); } /** * PHYSICAL 驳回:更新状态为 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 = intval($data['id'] ?? 0); $rejectReason = strval($data['reject_reason'] ?? ''); if ($id <= 0 || $rejectReason === '') { return $this->error(__('Missing required fields')); } $order = MallPlayxOrder::where('id', $id)->find(); if (!$order) { return $this->error(__('Record not found')); } if ($order->type !== MallPlayxOrder::TYPE_PHYSICAL) { return $this->error(__('Order type not PHYSICAL')); } if ($order->status !== MallPlayxOrder::STATUS_PENDING) { return $this->error(__('Order status must be PENDING')); } Db::startTrans(); try { $asset = MallPlayxUserAsset::where('playx_user_id', strval($order->user_id ?? ''))->find(); if (!$asset) { throw new \RuntimeException('User asset not found'); } $refund = intval($order->points_cost ?? 0); if ($refund > 0) { $asset->available_points += $refund; $asset->save(); } $order->status = MallPlayxOrder::STATUS_REJECTED; $order->reject_reason = $rejectReason; $order->grant_status = MallPlayxOrder::GRANT_FAILED_FINAL; $order->save(); Db::commit(); } catch (Throwable $e) { Db::rollback(); return $this->error($e->getMessage()); } return $this->success(__('Rejected successfully')); } /** * 手动重试(仅红利/提现,且必须 FAILED_RETRYABLE) */ 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 = intval($request->post('id', 0)); if ($id <= 0) { return $this->error(__('Missing required fields')); } $order = MallPlayxOrder::where('id', $id)->find(); if (!$order) { return $this->error(__('Record not found')); } if (!in_array($order->type, [MallPlayxOrder::TYPE_BONUS, MallPlayxOrder::TYPE_WITHDRAW], true)) { return $this->error(__('Only BONUS/WITHDRAW can retry')); } if ($order->grant_status !== MallPlayxOrder::GRANT_FAILED_RETRYABLE) { return $this->error(__('Only FAILED_RETRYABLE can retry')); } if (intval($order->retry_count) >= 3) { return $this->error(__('Retry count exceeded')); } $order->grant_status = MallPlayxOrder::GRANT_NOT_SENT; $order->save(); return $this->success(__('Retry queued')); } }