get('page'); $paged = $page !== null && $page !== ''; $page = max(1, (int) $page); $pageSize = max(1, (int) (request()->get('pageSize') ?? 20)); $base = ListModel::with([ 'items' => fn ($query) => $query->where('deleted_at', 0)->select(['id', 'list_id']), ])->where('user_id', $this->userId) ->where('deleted_at', 0) ->orderBy('id', 'desc'); // 不分页:一次拿全,保持老结构 if (!$paged) { $rows = $base->get(); if ($rows->isEmpty()) { return []; } $rows = $rows->toArray(); foreach ($rows as &$row) { $row['count'] = count($row['items'] ?? []); } unset($row); return $rows; } // 分页:拿当前页 + 总数,前端按 has_more 决定是否继续 loadMore $total = (clone $base)->count(); $rows = $base->forPage($page, $pageSize)->get(); $items = $rows->isEmpty() ? [] : $rows->toArray(); foreach ($items as &$row) { $row['count'] = count($row['items'] ?? []); } unset($row); return [ 'items' => $items, 'total' => $total, 'page' => $page, 'pageSize' => $pageSize, 'has_more' => ($page * $pageSize) < $total, ]; } /** * 清单详情:带商品与规格,价格按当前用户的可见性与倍率处理 */ public function detail(int $id): array { $info = ListModel::with([ 'items' => fn ($query) => $query->where('deleted_at', 0), 'items.catalogue', 'items.catalogue.priceSheet' => fn ($query) => $query->where('deleted_at', 0), ])->where('id', $id) ->where('user_id', $this->userId) ->where('deleted_at', 0) ->first(); if (empty($info)) { $this->utils->errorThrow('清单不存在'); } $info = $info->toArray(); $price = PriceService::getInstance(); $showPrice = $this->canSeePrice(); $multiplier = $this->priceMultiplier(); foreach ($info['items'] as &$item) { $sheet = $item['catalogue']['price_sheet'] ?? []; if (!empty($sheet)) { $applied = $price->applyToRows($sheet, $showPrice, $multiplier); $item['catalogue']['price_sheet'] = $applied['rows']; } // 老前端读的是 product 这个键名,保留别名避免小程序改字段 $item['product'] = $item['catalogue'] ?? null; } unset($item); $info['is_show_price'] = $showPrice; return $info; } public function create(array $params): mixed { $name = trim((string) ($params['name'] ?? '')); if ($name === '') { $this->utils->errorThrow('请填写清单名称'); } return ListModel::insertGetId([ 'list_no' => SerialNoService::getInstance()->generate(SerialNoService::PREFIX_LIST, 'list', 'list_no'), 'user_id' => $this->userId, 'name' => $name, 'remark' => (string) ($params['remark'] ?? ''), 'created_at' => time(), ]); } public function update(int $id, array $params): mixed { return ListModel::where('id', $id)->where('user_id', $this->userId)->update([ 'name' => (string) ($params['name'] ?? ''), 'remark' => (string) ($params['remark'] ?? ''), 'updated_at' => time(), ]); } public function delete(array|int $ids): mixed { return ListModel::whereIn('id', (array) $ids) ->where('user_id', $this->userId) ->update(['deleted_at' => time(), 'updated_at' => time()]); } /** * 删清单明细:先确认这些明细属于当前用户的清单 */ public function deleteItem(array|int $ids): mixed { $ids = (array) $ids; $listIds = ListModel::where('user_id', $this->userId)->where('deleted_at', 0)->pluck('id'); return ListItemModel::whereIn('id', $ids) ->whereIn('list_id', $listIds) ->update(['deleted_at' => time(), 'updated_at' => time()]); } /** * 加入清单;同一清单同一商品同一规格只留一条,重复则累加数量 */ public function toCart(array $params): mixed { $listId = (int) ($params['list_id'] ?? 0); $catalogueId = (int) ($params['product_id'] ?? $params['catalogue_id'] ?? 0); if ($listId <= 0 || $catalogueId <= 0) { $this->utils->errorThrow('参数错误'); } $list = ListModel::where('id', $listId)->where('user_id', $this->userId)->where('deleted_at', 0)->first(); if (empty($list)) { $this->utils->errorThrow('清单不存在'); } $priceSheetId = (int) ($params['price_sheet_id'] ?? 0); $quantity = max(1, (int) ($params['quantity'] ?? 1)); $exists = ListItemModel::where('list_id', $listId) ->where('catalogue_id', $catalogueId) ->where('price_sheet_id', $priceSheetId) ->where('deleted_at', 0) ->first(); if (!empty($exists)) { return ListItemModel::where('id', $exists['id'])->update([ 'quantity' => (int) $exists['quantity'] + $quantity, 'updated_at' => time(), ]); } return ListItemModel::insertGetId([ 'list_id' => $listId, 'catalogue_id' => $catalogueId, 'price_sheet_id' => $priceSheetId, 'material_key' => (string) ($params['material_key'] ?? 'routine'), 'quantity' => $quantity, 'remark' => (string) ($params['remark'] ?? ''), 'created_at' => time(), ]); } /** * 改明细的规格与数量:转订单前用户要能在清单里补齐这些信息 */ public function updateItem(array $params): mixed { $itemId = (int) ($params['id'] ?? 0); if ($itemId <= 0) { $this->utils->errorThrow('参数错误'); } $listIds = ListModel::where('user_id', $this->userId)->where('deleted_at', 0)->pluck('id'); $update = ['updated_at' => time()]; if (array_key_exists('quantity', $params)) { $update['quantity'] = max(1, (int) $params['quantity']); } if (array_key_exists('price_sheet_id', $params)) { $update['price_sheet_id'] = (int) $params['price_sheet_id']; } if (array_key_exists('material_key', $params)) { $update['material_key'] = (string) $params['material_key']; } if (array_key_exists('remark', $params)) { $update['remark'] = (string) $params['remark']; } return ListItemModel::where('id', $itemId)->whereIn('list_id', $listIds)->update($update); } }