diff --git a/app/controller/frontend/SearchController.php b/app/controller/frontend/SearchController.php index 0e064e1..1c2deb1 100644 --- a/app/controller/frontend/SearchController.php +++ b/app/controller/frontend/SearchController.php @@ -12,18 +12,28 @@ use app\model\SysSetting; class SearchController extends BaseController { /** - * 获取栏目自身及全部子栏目 ID + * 内容所在站点(子站用父站栏目数据) + */ + private function contentWebsiteId(): int + { + return (int)($this->realSiteId ?: $this->siteId); + } + + /** + * 获取栏目自身及全部子栏目 ID(限定当前语言 + 真实站点) */ private function getCategoryTreeIds(int $rootId): array { if ($rootId <= 0) { return []; } + $websiteId = $this->contentWebsiteId(); $category = new Category(); $root = $category->where([ 'id' => $rootId, 'seller_id' => $this->sellerId, - 'website_id' => $this->siteId, + 'website_id' => $websiteId, + 'lang' => $this->lang, ])->find(); if (empty($root)) { return [$rootId]; @@ -32,7 +42,8 @@ class SearchController extends BaseController $parentPath = ($root['path'] ?? '') . $root['id'] . '-'; $childIds = $category->where([ ['seller_id', '=', $this->sellerId], - ['website_id', '=', $this->siteId], + ['website_id', '=', $websiteId], + ['lang', '=', $this->lang], ['path', 'like', $parentPath . '%'], ])->column('id'); @@ -43,7 +54,7 @@ class SearchController extends BaseController } /** - * 按栏目 ID 取关联内容 ID + * 按栏目 ID 取关联内容 ID(中间表 seller_id 存的是商户 ID) */ private function getContentIdsByCategoryIds(array $cateIds): array { @@ -52,7 +63,7 @@ class SearchController extends BaseController } $cateSub = new CategorySubContent(); $ids = $cateSub->where([ - ['seller_id', '=', $this->siteId], + ['seller_id', '=', $this->sellerId], ['category_id', 'in', $cateIds], ])->column('sub_content_id'); @@ -91,31 +102,46 @@ class SearchController extends BaseController return $ts ? date('Y-m-d', $ts) : substr((string)$time, 0, 10); } + private function cateIdsHit(array $cateIds, array $cateSet): bool + { + foreach ($cateIds as $cid) { + if ($cid > 0 && isset($cateSet[$cid])) { + return true; + } + } + return false; + } + /** * 解析搜索结果类型 + * @param int $contentId 内容 ID + * @param array $sets content / cate 集合(array_flip 后的 isset 表) + * @param array $cateIds 该内容关联的栏目 ID */ - private function resolveSearchKind(int $contentId, array $sets): array + private function resolveSearchKind(int $contentId, array $sets, array $cateIds = []): array { - if (isset($sets['product'][$contentId])) { + // 产品:内容命中 或 关联栏目落在产品树 + if (isset($sets['product'][$contentId]) || $this->cateIdsHit($cateIds, $sets['product_cates'] ?? [])) { return ['product', '产品']; } - // 企业视频优先于新闻:交互同视频教程,类型仍显示新闻 - if (isset($sets['news_video'][$contentId])) { + // 企业视频:交互同视频,类型名显示新闻 + if (isset($sets['news_video'][$contentId]) || $this->cateIdsHit($cateIds, $sets['news_video_cates'] ?? [])) { return ['video', '新闻']; } - if (isset($sets['news'][$contentId])) { + if (isset($sets['news'][$contentId]) || $this->cateIdsHit($cateIds, $sets['news_cates'] ?? [])) { return ['news', '新闻']; } - if (isset($sets['faq'][$contentId])) { + if (isset($sets['faq'][$contentId]) || $this->cateIdsHit($cateIds, $sets['faq_cates'] ?? [])) { return ['faq', '常见问题']; } - if (isset($sets['download'][$contentId])) { + // 下载中心(含社会责任报告子栏目) + if (isset($sets['download'][$contentId]) || $this->cateIdsHit($cateIds, $sets['download_cates'] ?? [])) { return ['download', '下载中心']; } - if (isset($sets['video'][$contentId])) { + if (isset($sets['video'][$contentId]) || $this->cateIdsHit($cateIds, $sets['video_cates'] ?? [])) { return ['video', '视频教程']; } - if (isset($sets['announce'][$contentId])) { + if (isset($sets['announce'][$contentId]) || $this->cateIdsHit($cateIds, $sets['announce_cates'] ?? [])) { return ['announce', '产品公告']; } return ['content', '内容']; @@ -128,6 +154,8 @@ class SearchController extends BaseController */ public function index(Category $Category) { + $websiteId = $this->contentWebsiteId(); + //拿到搜索页数据,主要为了拿seo数据 $with=['thumbnail'=>function($q){ $q->field('id,name,url,type'); @@ -135,7 +163,12 @@ class SearchController extends BaseController $q->field('id,name,url,type'); } ]; - $category = $Category->getCategory(['seller_id' => $this->sellerId, 'website_id' => $this->siteId ,'is_search' => 1],$with)['data']->toArray(); + $category = $Category->getCategory([ + 'seller_id' => $this->sellerId, + 'website_id' => $websiteId, + 'lang' => $this->lang, + 'is_search' => 1, + ],$with)['data']->toArray(); $settingWhere = [ 'group' => 'company', 'title' => 'huocms_powerby', @@ -159,29 +192,54 @@ class SearchController extends BaseController $this->assign('keywords', $keywords); $this->assign('sr_type', $type); - // 全部:可搜索栏目(is_search=1) + // 全部:当前语言下可搜索栏目(必须带 lang,避免中英栏目混入) $categoryModel = new Category(); - $searchCategories = $categoryModel->getAllCustomArrayData(['is_search' => 1], 'id desc', 'id')['data']; - $searchCateIds = array_column($searchCategories, 'id'); + $searchCategories = $categoryModel->getAllCustomArrayData([ + 'is_search' => 1, + 'seller_id' => $this->sellerId, + 'website_id' => $websiteId, + 'lang' => $this->lang, + ], 'id desc', 'id')['data']; + $searchCateIds = array_column($searchCategories ?: [], 'id'); $cateSub = new CategorySubContent(); $searchSubIds = array_column($cateSub->getAllCategorySubContent([ - ['seller_id', '=', $this->siteId], + ['seller_id', '=', $this->sellerId], ['category_id', 'in', $searchCateIds ?: [0]], ])['data'], 'sub_content_id'); // 各 Tab 固定根栏目(含子栏目,按当前语言 uiId) - $productContentIds = $this->getContentIdsByCategoryIds($this->getCategoryTreeIds(uiId('product'))); - $newsContentIds = $this->getContentIdsByCategoryIds($this->getCategoryTreeIds(uiId('news'))); - $faqContentIds = $this->getContentIdsByCategoryIds($this->getCategoryTreeIds(uiId('faq'))); + $productCateIds = $this->getCategoryTreeIds(uiId('product')); + $newsCateIds = $this->getCategoryTreeIds(uiId('news')); + $faqCateIds = $this->getCategoryTreeIds(uiId('faq')); + $downloadCateIds = $this->getCategoryTreeIds(uiId('download')); + $videoCateIds = $this->getCategoryTreeIds(uiId('video')); + $announceCateIds = $this->getCategoryTreeIds(uiId('announce')); + $newsVideoCateId = uiId('news_video'); - $newsVideoContentIds = $newsVideoCateId > 0 - ? $this->getContentIdsByCategoryIds($this->getCategoryTreeIds($newsVideoCateId)) - : []; + $newsVideoCateIds = $newsVideoCateId > 0 ? $this->getCategoryTreeIds($newsVideoCateId) : []; + // 企业视频并入新闻树(path 未挂在新闻下时仍按新闻识别) + if (!empty($newsVideoCateIds)) { + $newsCateIds = array_values(array_unique(array_merge($newsCateIds, $newsVideoCateIds))); + } + + // 社会责任报告并入下载中心树 + $downloadCsrId = uiId('download_csr'); + if ($downloadCsrId > 0) { + $downloadCateIds = array_values(array_unique(array_merge( + $downloadCateIds, + $this->getCategoryTreeIds($downloadCsrId) + ))); + } + + $productContentIds = $this->getContentIdsByCategoryIds($productCateIds); + $newsContentIds = $this->getContentIdsByCategoryIds($newsCateIds); + $faqContentIds = $this->getContentIdsByCategoryIds($faqCateIds); + $newsVideoContentIds = $this->getContentIdsByCategoryIds($newsVideoCateIds); // 其他 = 下载中心 + 视频 + 公告 - $downloadContentIds = $this->getContentIdsByCategoryIds($this->getCategoryTreeIds(uiId('download'))); - $videoContentIds = $this->getContentIdsByCategoryIds($this->getCategoryTreeIds(uiId('video'))); - $announceContentIds = $this->getContentIdsByCategoryIds($this->getCategoryTreeIds(uiId('announce'))); + $downloadContentIds = $this->getContentIdsByCategoryIds($downloadCateIds); + $videoContentIds = $this->getContentIdsByCategoryIds($videoCateIds); + $announceContentIds = $this->getContentIdsByCategoryIds($announceCateIds); $otherContentIds = array_values(array_unique(array_merge( $downloadContentIds, $videoContentIds, @@ -223,38 +281,55 @@ class SearchController extends BaseController $q->field('id,name,url,type'); }])->where($baseWhere)->whereIn('id', $listSubIds ?: [0]); - $productIdSet = array_flip($productContentIds); - $newsIdSet = array_flip($newsContentIds); - $faqIdSet = array_flip($faqContentIds); - $downloadIdSet = array_flip($downloadContentIds); - $videoIdSet = array_flip($videoContentIds); - $announceIdSet = array_flip($announceContentIds); - $newsVideoIdSet = array_flip($newsVideoContentIds); $kindSets = [ - 'product' => $productIdSet, - 'news_video' => $newsVideoIdSet, - 'news' => $newsIdSet, - 'faq' => $faqIdSet, - 'download' => $downloadIdSet, - 'video' => $videoIdSet, - 'announce' => $announceIdSet, + 'product' => array_flip($productContentIds), + 'product_cates' => array_flip($productCateIds), + 'news_video' => array_flip($newsVideoContentIds), + 'news_video_cates' => array_flip($newsVideoCateIds), + 'news' => array_flip($newsContentIds), + 'news_cates' => array_flip($newsCateIds), + 'faq' => array_flip($faqContentIds), + 'faq_cates' => array_flip($faqCateIds), + 'download' => array_flip($downloadContentIds), + 'download_cates' => array_flip($downloadCateIds), + 'video' => array_flip($videoContentIds), + 'video_cates' => array_flip($videoCateIds), + 'announce' => array_flip($announceContentIds), + 'announce_cates' => array_flip($announceCateIds), ]; $tabKindMap = [ 'product' => ['product', '产品'], 'news' => ['news', '新闻'], 'faq' => ['faq', '常见问题'], ]; + $newsVideoIdSet = $kindSets['news_video']; + $currentLang = $this->lang; $data = $content ->order('id','desc') ->paginate([ 'page' => $param['page'] ?? 1, 'list_rows' => $param['limit'] ?? 10, - ])->each(function (&$item) use ($type, $tabKindMap, $kindSets, $newsVideoIdSet) { + ])->each(function (&$item) use ($type, $tabKindMap, $kindSets, $newsVideoIdSet, $currentLang) { $row = $item->toArray(); - if (!empty($row['category'])) { - $item['category'] = $row['category']; - $item['category_id'] = $row['category'][0]['id'] ?? 0; + $categories = []; + if (!empty($row['category']) && is_array($row['category'])) { + // 只认当前语言栏目,避免中英关联串台 + foreach ($row['category'] as $cate) { + $cateLang = (string)($cate['lang'] ?? ''); + if ($cateLang !== '' && $cateLang !== $currentLang) { + continue; + } + $categories[] = $cate; + } + // 若过滤后为空,回退全部关联(兼容无 lang 字段的脏数据) + if (empty($categories)) { + $categories = $row['category']; + } + } + if (!empty($categories)) { + $item['category'] = $categories; + $item['category_id'] = $categories[0]['id'] ?? 0; } $item['thumbnail'] = $row['thumbnail'] ?? null; $item['cover'] = $row['cover'] ?? null; @@ -265,19 +340,22 @@ class SearchController extends BaseController $item['sr_date'] = $this->formatSearchDate($row['publish_time'] ?? ($row['create_time'] ?? '')); $contentId = (int)($row['id'] ?? 0); + $cateIds = []; + foreach ($categories as $cate) { + $cateIds[] = (int)($cate['id'] ?? 0); + } if (isset($tabKindMap[$type])) { [$kind, $name] = $tabKindMap[$type]; + // 新闻 Tab 内企业视频仍用视频交互 + if ($type === 'news' && (isset($newsVideoIdSet[$contentId]) || $this->cateIdsHit($cateIds, $kindSets['news_video_cates'] ?? []))) { + $kind = 'video'; + } } else { - [$kind, $name] = $this->resolveSearchKind($contentId, $kindSets); - if ($kind === 'content' && !empty($row['category'][0]['title'])) { - $name = $row['category'][0]['title']; + [$kind, $name] = $this->resolveSearchKind($contentId, $kindSets, $cateIds); + if ($kind === 'content' && !empty($categories[0]['title'])) { + $name = $categories[0]['title']; } } - // 企业视频:交互同视频教程,类型名仍为新闻 - if (isset($newsVideoIdSet[$contentId])) { - $kind = 'video'; - $name = '新闻'; - } $item['sr_kind'] = $kind; $item['sr_tab_name'] = $name; });