Browse Source

refactor(search): enhance category and content ID retrieval with language and site context

master
peijunlei 2 weeks ago
parent
commit
e569d0ce52
  1. 186
      app/controller/frontend/SearchController.php

186
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,18 +340,21 @@ 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];
} else {
[$kind, $name] = $this->resolveSearchKind($contentId, $kindSets);
if ($kind === 'content' && !empty($row['category'][0]['title'])) {
$name = $row['category'][0]['title'];
// 新闻 Tab 内企业视频仍用视频交互
if ($type === 'news' && (isset($newsVideoIdSet[$contentId]) || $this->cateIdsHit($cateIds, $kindSets['news_video_cates'] ?? []))) {
$kind = 'video';
}
} else {
[$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;

Loading…
Cancel
Save