'待汇总', StoreOrderModel::STATUS_SUMMARIZED => '已汇总', StoreOrderModel::STATUS_DELIVERING => '配送中', StoreOrderModel::STATUS_COMPLETED => '已完成', StoreOrderModel::STATUS_CANCELLED => '已取消', ]; protected array $searchField = [ 'store_id' => '=', 'status' => '=', 'order_no' => 'like', 'order_date' => 'betweenDate', ]; /** 订单列表 */ #[GetRoute(authorize: 'query')] public function query(Request $request): JsonResponse { $params = $request->all(); $pageSize = $params['pageSize'] ?? 10; $data = $this->buildSearch($params, StoreOrderModel::query()->with('store:id,name')) ->orderBy('order_date', 'desc') ->orderBy('id', 'desc') ->paginate($pageSize) ->toArray(); return $this->success($data); } /** * 待汇总预览:聚合所有待汇总订单明细(按商品分组), * 供生成采购单前确认(C1 前置) */ #[GetRoute('/summary', 'query')] public function summary(): JsonResponse { $rows = StoreOrderItemModel::query() ->select('product_id') ->selectRaw('MAX(product_name) as product_name') ->selectRaw('MAX(product_spec) as product_spec') ->selectRaw('SUM(quantity) as total_quantity') ->selectRaw('COUNT(DISTINCT store_id) as store_count') ->whereHas('order', function ($query) { $query->where('status', StoreOrderModel::STATUS_PENDING); }) ->groupBy('product_id') ->orderBy('product_id') ->get() ->toArray(); // 补充计价单位(商品档案,含已下架/软删除) $units = ProductModel::withTrashed() ->whereIn('id', array_column($rows, 'product_id')) ->pluck('unit', 'id'); foreach ($rows as &$row) { $row['unit'] = $units[$row['product_id']] ?? ''; } return $this->success($rows); } /** 订单详情:订单头 + 明细(含商品快照) */ #[GetRoute(route: '/{id}', authorize: 'query', where: ['id' => '[0-9]+'])] public function detail(int $id): JsonResponse { $order = StoreOrderModel::with(['store:id,name', 'items'])->find($id); if (empty($order)) { throw new RepositoryException('订单不存在'); } return $this->success($order->toArray()); } /** * 状态流转(待汇总→配送中→完成;待汇总可取消;已汇总可转配送中) */ #[PutRoute(route: '/{id}/status', authorize: 'update', where: ['id' => '[0-9]+'])] public function status(int $id, Request $request): JsonResponse { $data = $request->validate([ 'status' => 'required|integer|in:2,3,9', ], [ 'status.required' => '目标状态不能为空', 'status.in' => '目标状态值不正确', ]); $order = StoreOrderModel::find($id); if (empty($order)) { throw new RepositoryException('订单不存在'); } $target = (int) $data['status']; $allowed = match ($order->status) { StoreOrderModel::STATUS_PENDING => [ StoreOrderModel::STATUS_DELIVERING, StoreOrderModel::STATUS_CANCELLED, ], StoreOrderModel::STATUS_SUMMARIZED => [ StoreOrderModel::STATUS_DELIVERING, ], StoreOrderModel::STATUS_DELIVERING => [ StoreOrderModel::STATUS_COMPLETED, ], default => [], }; if (! in_array($target, $allowed, true)) { throw new RepositoryException( '订单当前状态为「' . (self::STATUS_NAMES[$order->status] ?? $order->status) . '」,不允许该操作' ); } $order->status = $target; $order->save(); $this->notifyStore($order); return $this->success(); } /** * 状态流转后通知门店用户 */ private function notifyStore(StoreOrderModel $order): void { $userIds = UserModel::query() ->where('type', UserModel::TYPE_STORE) ->where('store_id', $order->store_id) ->where('status', UserModel::STATUS_NORMAL) ->pluck('id'); $statusName = self::STATUS_NAMES[$order->status] ?? (string) $order->status; foreach ($userIds as $userId) { NoticeModel::create([ 'user_id' => $userId, 'type' => NoticeModel::TYPE_ORDER, 'title' => '订单状态更新', 'content' => mb_substr("您的订单 {$order->order_no} 状态已更新为「{$statusName}」", 0, 500), 'data' => ['order_id' => $order->id], 'is_read' => NoticeModel::UNREAD, ]); } } }