diff --git a/addons/shopro/controller/Goods.php b/addons/shopro/controller/Goods.php index 10d7255..4ae01ff 100644 --- a/addons/shopro/controller/Goods.php +++ b/addons/shopro/controller/Goods.php @@ -82,6 +82,10 @@ class Goods extends Base { $params = $this->request->get(); $params['platform'] = $this->request->header('platform'); + $params = \addons\shopro\model\Decorate::normalizeHomeGoodsListParams( + $params, + $params['platform'] ?? '' + ); $data = \addons\shopro\model\Goods::getGoodsList($params)->toArray(); // 获取vip价格 diff --git a/addons/shopro/model/Decorate.php b/addons/shopro/model/Decorate.php index c08c7e6..c10b312 100644 --- a/addons/shopro/model/Decorate.php +++ b/addons/shopro/model/Decorate.php @@ -2,7 +2,6 @@ namespace addons\shopro\model; -use addons\shopro\model\DecorateContent; use think\Model; use addons\shopro\exception\Exception; @@ -81,9 +80,183 @@ class Decorate extends Model $v['content'] = self::getDecorateContentByType($v); $template[$v->category][] = $v; } + if (!empty($template['home'])) { + $template['home'] = self::enrichHomeGoodsBlocks($template['home']); + } return $template; } + /** + * 首页「精选好酒」模块:API 侧补齐 goods_ids,避免小程序仅带 category_id 时少显示装修选中的 hidden 商品。 + * + * @return array [category_id => goods_ids] + */ + public static function resolveHomeGoodsListContext($platform = '') + { + try { + $template = self::getCurrentPlatformDecorate($platform ?: 'wxMiniProgram'); + } catch (\Throwable $e) { + return ['category_id' => 0, 'goods_ids' => '']; + } + $home = $template['home'] ?? []; + if (!$home) { + return ['category_id' => 0, 'goods_ids' => '']; + } + $ctx = self::extractHomeGoodsContextFromBlocks($home); + return [ + 'category_id' => (int) ($ctx['category_id'] ?? 0), + 'goods_ids' => (string) ($ctx['goods_ids'] ?? ''), + ]; + } + + /** + * 与首页 sh-hot-goods 请求对齐:无筛选时用装修商品;首页分类与全部分类列表一致。 + */ + public static function normalizeHomeGoodsListParams(array $params, $platform = '') + { + $keywords = trim((string) ($params['keywords'] ?? '')); + if ($keywords !== '') { + return $params; + } + if (!empty($params['goods_ids'])) { + return $params; + } + + $ctx = self::resolveHomeGoodsListContext($platform); + $homeIds = trim((string) ($ctx['goods_ids'] ?? '')); + $homeCat = (int) ($ctx['category_id'] ?? 0); + if ($homeIds === '') { + return $params; + } + + $categoryId = isset($params['category_id']) ? (int) $params['category_id'] : 0; + $scoped = $categoryId > 0; + + if (!$scoped) { + $params['goods_ids'] = $homeIds; + unset($params['category_id']); + return $params; + } + + if ($homeCat > 0 && $categoryId === $homeCat) { + $params['goods_ids'] = $homeIds; + unset($params['category_id']); + } + + return $params; + } + + protected static function enrichHomeGoodsBlocks(array $home) + { + $ctx = self::extractHomeGoodsContextFromBlocks($home); + if (($ctx['goods_ids'] ?? '') === '') { + return $home; + } + $targetIdx = null; + foreach ($home as $idx => $block) { + if (in_array($block['type'] ?? '', ['goods-list', 'goods-group'], true)) { + $targetIdx = $idx; + break; + } + } + if ($targetIdx === null) { + $targetIdx = self::findLastCategoryTabsIndex($home); + } + if ($targetIdx === null || $targetIdx < 0) { + return $home; + } + $content = $home[$targetIdx]['content'] ?? []; + $content['ids'] = $ctx['goods_ids']; + unset($content['id']); + $home[$targetIdx]['content'] = $content; + return $home; + } + + protected static function findLastCategoryTabsIndex(array $home) + { + for ($i = count($home) - 1; $i >= 0; $i--) { + if (($home[$i]['type'] ?? '') === 'category-tabs') { + return $i; + } + } + return -1; + } + + protected static function extractHomeGoodsContextFromBlocks(array $home) + { + $categoryId = 0; + foreach ($home as $block) { + $type = $block['type'] ?? ''; + if (!in_array($type, ['goods-list', 'goods-group'], true)) { + continue; + } + $content = $block['content'] ?? []; + if (!empty($content['ids'])) { + return [ + 'category_id' => (int) ($content['id'] ?? 0), + 'goods_ids' => self::normalizeGoodsIdsString($content['ids']), + ]; + } + if (!empty($content['id'])) { + $categoryId = (int) $content['id']; + return [ + 'category_id' => $categoryId, + 'goods_ids' => self::goodsIdsFromCategoryId($categoryId), + ]; + } + } + + for ($i = count($home) - 1; $i >= 0; $i--) { + if (($home[$i]['type'] ?? '') !== 'category-tabs') { + continue; + } + $content = $home[$i]['content'] ?? []; + if (!empty($content['ids'])) { + return [ + 'category_id' => (int) ($content['id'] ?? ($content['category_arr'][0]['id'] ?? 0)), + 'goods_ids' => self::normalizeGoodsIdsString($content['ids']), + ]; + } + $categoryId = (int) ($content['id'] ?? ($content['category_arr'][0]['id'] ?? 0)); + if ($categoryId > 0) { + return [ + 'category_id' => $categoryId, + 'goods_ids' => self::goodsIdsFromCategoryId($categoryId), + ]; + } + break; + } + + return ['category_id' => 0, 'goods_ids' => '']; + } + + protected static function normalizeGoodsIdsString($ids) + { + $ids = is_array($ids) ? implode(',', $ids) : (string) $ids; + $parts = array_filter(array_map('intval', explode(',', $ids))); + return implode(',', array_unique($parts)); + } + + protected static function goodsIdsFromCategoryId($categoryId) + { + $categoryId = (int) $categoryId; + if ($categoryId <= 0) { + return ''; + } + $categoryIds = Category::getCategoryIds($categoryId); + if (!$categoryIds) { + return ''; + } + $query = Goods::where('status', 'in', ['up', 'hidden']); + $query->where(function ($q) use ($categoryIds) { + foreach ($categoryIds as $cid) { + $q->whereOrRaw("find_in_set($cid, category_ids)"); + } + }); + $ids = $query->order('weigh asc, id desc')->column('id'); + return self::normalizeGoodsIdsString(implode(',', $ids)); + } + public static function getDecorateContentByType($templateValue) { $content = json_decode($templateValue->content, true); diff --git a/addons/shopro/model/Goods.php b/addons/shopro/model/Goods.php index 5492487..00274be 100644 --- a/addons/shopro/model/Goods.php +++ b/addons/shopro/model/Goods.php @@ -60,6 +60,8 @@ class Goods extends Model $order = 'field(id, ' . $goods_ids . ')'; // 如果传了 goods_ids 就按照里面的 id 进行排序 $goodsIdsArray = explode(',', $goods_ids); $where['id'] = ['in', $goodsIdsArray]; + // 装修/首页指定 id 时允许 hidden(如招商礼盒),仍不展示 down + $where['status'] = ['in', ['up', 'hidden']]; } $category_ids = [];