Files
lgp-admin-plus-api/app/Service/wx/WxProductService.php

104 lines
3.9 KiB
PHP
Raw Normal View History

<?php
namespace App\Service\wx;
use App\BaseApp\BaseWxService;
use App\Models\business\CatalogueModel;
use App\Models\business\CategoryModel;
use App\Models\business\ImageModel;
use App\Service\business\PriceService;
2026-08-20 19:16:49 +08:00
use App\Service\common\MediaUrlService;
/**
* 小程序商品列表与详情
*
* 价格倍率与可见性统一走 PriceService后台与小程序共用同一套规则
* 避免出现「后台看原价、小程序看倍率价」对不上账的老问题。
*/
class WxProductService extends BaseWxService
{
2026-08-20 19:16:49 +08:00
protected bool $needLogin = false;
/**
* 商品列表:分类点到二级时按父分类下的所有子分类查
*/
public function list(): array
{
$title = (string) request()->get('title', '');
$categoryId = request()->get('category_id');
$childIds = [];
if (!empty($categoryId)) {
$childIds = CategoryModel::where('pid', $categoryId)->where('deleted_at', 0)->pluck('id')->all();
}
// 小程序前端发的是 size见 pages/product|search getProductList老接口曾用 pageSize
// 这里两者都接,避免改一边漏一边
$pageSize = (int) (request()->get('pageSize') ?: request()->get('size') ?: 10);
$result = CatalogueModel::when($title !== '', function ($query) use ($title) {
$query->where('title', 'like', '%' . $title . '%');
})->when(!empty($categoryId) && empty($childIds), function ($query) use ($categoryId) {
$query->where('category_id', $categoryId);
})->when(!empty($childIds), function ($query) use ($childIds) {
$query->whereIn('category_id', $childIds);
})->where('deleted_at', 0)
->orderBy('id', 'desc')
->paginate($pageSize)
->toArray();
return [
'page' => $result['current_page'],
'size' => $result['per_page'],
'page_count' => $result['last_page'],
// 小程序 productWaterfall / product.vue 读的是 last_page不是 page_count两个键都给
'last_page' => $result['last_page'],
'total' => $result['total'],
'items' => $result['data'],
'data' => $result['data'],
];
}
/**
* 商品详情
*
* p_user_id 说明是代理商分享进来的:普通新用户会被绑到该代理商名下并继承其倍率,
* 这是老项目的既有行为,不能改,否则代理商体系的价格会全部失效。
*/
public function detail(int $id, int $shareUserId = 0): array
{
if ($shareUserId > 0) {
$this->inheritAgentPrice($shareUserId);
}
$info = CatalogueModel::with([
'category',
'images' => fn ($query) => $query->where('deleted_at', 0),
'priceSheet' => fn ($query) => $query->where('deleted_at', 0),
])->where('deleted_at', 0)->find($id);
if (empty($info)) {
$this->utils->errorThrow('商品不存在');
}
$info = $info->toArray();
2026-08-20 19:16:49 +08:00
$media = MediaUrlService::getInstance();
$info['cover'] = $media->toPublic($info['cover'] ?? '');
$info['video'] = $media->toPublic($info['video'] ?? '');
// 渲染图作为详情轮播
$info['carousel'] = [];
foreach ($info['images'] ?? [] as $image) {
if ((int) $image['type'] === ImageModel::TYPE_RENDER) {
2026-08-20 19:16:49 +08:00
$info['carousel'][] = $media->toPublic($image['url'] ?? '');
}
}
$showPrice = $this->canSeePrice();
$applied = PriceService::getInstance()->applyToRows($info['price_sheet'] ?? [], $showPrice, $this->priceMultiplier());
$info['price_sheet'] = $applied['rows'];
$info['is_show_price'] = $applied['is_show_price'];
2026-08-20 19:16:49 +08:00
$info['favorited'] = $this->userId > 0
? WxFavoriteService::getInstance()->isFavorited((int) $id)
: false;
return $info;
}
}