Browse Source

Merge branch 'master' of https://git-online.zhco.com/wjd/rui-neng

# Conflicts:
#	app/controller/frontend/SearchController.php
master
xiaodong 2 weeks ago
parent
commit
696dccbb67
  1. 98
      app/controller/frontend/SearchController.php
  2. 5
      public/themes/dist_static/static/css/search.css
  3. 30
      public/themes/dist_static/static/js/search.js
  4. 15
      public/themes/website/1/zh/demo/components/footer.html
  5. 65
      public/themes/website/1/zh/demo/single_search.html

98
app/controller/frontend/SearchController.php

@ -18,6 +18,29 @@ use think\facade\Db;
class SearchController extends BaseController
{
/**
* 按栏目标题映射搜索 Tab 类型
*/
private function resolveSearchType(string $title): string
{
if ($title === '') {
return 'other';
}
if (mb_strpos($title, '产品') !== false) {
return 'product';
}
if (mb_strpos($title, '解决方案') !== false || mb_strpos($title, '方案') !== false) {
return 'solution';
}
if (mb_strpos($title, '新闻') !== false) {
return 'news';
}
if (mb_strpos($title, '常见问题') !== false || mb_stripos($title, 'FAQ') !== false || mb_strpos($title, '问题') !== false) {
return 'faq';
}
return 'other';
}
/**
* @throws \app\exception\ModelEmptyException
* @throws \app\exception\ModelException
* @throws \think\db\exception\DbException
@ -47,16 +70,27 @@ class SearchController extends BaseController
//搜索
$param = $this->request->param();
$keywords = $param['q'] ?? '';
$this->assign('keywords',$keywords);
$type = $param['type'] ?? 'all';
if (!in_array($type, ['all', 'product', 'solution', 'news', 'faq'], true)) {
$type = 'all';
}
$this->assign('keywords', $keywords);
$this->assign('sr_type', $type);
// 获取可以查询的栏目
$category = new Category();
$categories = $category -> getAllCustomArrayData(['is_search' => 1],'id desc','id')['data'];
// status: 1 正常 2 禁用
// $categories = $category -> getAllCustomArrayData(['status' => 1],'id desc','id')['data'];
// $categories = $category -> getAllCustomArrayData(['status' => 1],'id desc','id')['data'];
$cateIds = array_column($categories,'id');
$cateTypeMap = [];
foreach ($categories as $cate) {
$cateTypeMap[(int)$cate['id']] = $this->resolveSearchType((string)($cate['title'] ?? ''));
}
$cateSub = new CategorySubContent();
$cateSubWhere = [
['seller_id','=',$this->siteId],
@ -65,16 +99,60 @@ class SearchController extends BaseController
$cateSubCon = $cateSub->getAllCategorySubContent($cateSubWhere)['data'];
$subIds = array_column($cateSubCon,'sub_content_id');
// 内容 -> 首个栏目(与列表展示 category[0] 一致)
$contentCateMap = [];
foreach ($cateSubCon as $row) {
$sid = (int)$row['sub_content_id'];
if (!isset($contentCateMap[$sid])) {
$contentCateMap[$sid] = (int)$row['category_id'];
}
}
$SubContent = new SubContent();
$content = $SubContent->with(['thumbnail'=>function($q){
$q->field('id,name,url,type');
},'category'])->where(['seller_id'=>$this->sellerId,'is_del'=>1]);
if(!empty($param['q'])){
$content = $content -> whereLike('title|description|sub_title','%' . $keywords . '%');
$baseWhere = ['seller_id' => $this->sellerId, 'is_del' => 1];
// 关键词命中的全量 ID(用于 Tab 全量统计)
$countQuery = (new SubContent())->where($baseWhere)->whereIn('id', $subIds ?: [0]);
if (!empty($param['q'])) {
$countQuery = $countQuery->whereLike('title|description|sub_title', '%' . $keywords . '%');
}
$matchedIds = $countQuery->column('id');
$srCounts = [
'all' => count($matchedIds),
'product' => 0,
'solution' => 0,
'news' => 0,
'faq' => 0,
];
foreach ($matchedIds as $mid) {
$cid = $contentCateMap[(int)$mid] ?? 0;
$itemType = $cateTypeMap[$cid] ?? 'other';
if (isset($srCounts[$itemType])) {
$srCounts[$itemType]++;
}
}
$this->assign('sr_counts', $srCounts);
// 按 Tab 类型筛选列表用的内容 ID
$listSubIds = $matchedIds;
if ($type !== 'all') {
$listSubIds = [];
foreach ($matchedIds as $mid) {
$cid = $contentCateMap[(int)$mid] ?? 0;
if (($cateTypeMap[$cid] ?? 'other') === $type) {
$listSubIds[] = (int)$mid;
}
}
}
$content = (new SubContent())->with(['thumbnail'=>function($q){
$q->field('id,name,url,type');
},'category'])->where($baseWhere)->whereIn('id', $listSubIds ?: [0]);
$param['siteId'] = $this->siteId;
$param['sellerId'] = $this->sellerId;
$data = $content->whereIn('id',$subIds)
$data = $content
->order('id','desc')
->paginate([
'page' => $param['page'] ?? 1,
@ -86,7 +164,11 @@ class SearchController extends BaseController
}
$item['thumbnail'] = $item->toArray()['thumbnail'];
});
$data->appends(['q' => $keywords]);
$append = ['q' => $keywords];
if ($type !== 'all') {
$append['type'] = $type;
}
$data->appends($append);
$this->assign('list', $data->items());
$this->assign('list_page', $data->render());
return $this->fetch(config('view.view_search_page_name'));

5
public/themes/dist_static/static/css/search.css

@ -93,6 +93,7 @@
font-size: var(--font-18);
font-weight: 400;
line-height: var(--font-24);
text-decoration: none;
cursor: pointer;
transition: color var(--duration-fast) var(--easing);
}
@ -127,13 +128,15 @@
aspect-ratio: 300/200;
overflow: hidden;
border-radius: 1rem;
/* padding: 24px; */
padding: 1.5rem;
background: rgba(175, 181, 185, 0.15);
}
.sr-item__media img {
display: block;
width: 100%;
height: 100%;
object-fit: cover;
object-fit: contain;
transition: transform var(--duration-normal) var(--easing);
}
.sr-item__media:hover img {

30
public/themes/dist_static/static/js/search.js

@ -1,43 +1,13 @@
import "./common.js";
import "./pagination.js";
//#region js/search.js
function matchItem($item, type) {
const itemType = $item.attr("data-type") || "";
return type === "all" || itemType === type;
}
function updateCounts($items) {
["all", "product", "solution", "news", "faq"].forEach((type) => {
const count = $items.filter((_, el) => matchItem($(el), type)).length;
$(`[data-count="${type}"]`).text(String(count));
});
}
function applyFilter() {
const type = $(".sr-tabs__item.is-active").attr("data-type") || "all";
const $items = $(".sr-item");
let visible = 0;
$items.each(function() {
const show = matchItem($(this), type);
this.hidden = !show;
if (show) visible += 1;
});
updateCounts($items);
const $empty = $(".sr-tabs-empty");
if ($empty.length) $empty.prop("hidden", visible > 0 || !$items.length);
}
$(function() {
const q = new URLSearchParams(window.location.search).get("q")?.trim() || "";
if (q) $(".sr-search .s-search__input").val(q);
$(".sr-tabs__item").on("click", function() {
const $btn = $(this);
$btn.addClass("is-active").attr("aria-selected", "true");
$btn.siblings(".sr-tabs__item").removeClass("is-active").attr("aria-selected", "false");
applyFilter();
});
$(".sr-hot__tag").on("click", function() {
const keyword = $(this).attr("data-keyword") || $(this).text().trim();
$(".sr-search .s-search__input").val(keyword);
$(".sr-search").trigger("submit");
});
if ($(".sr-tabs").length) applyFilter();
});
//#endregion

15
public/themes/website/1/zh/demo/components/footer.html

@ -4,7 +4,7 @@
<div class="site-footer__main">
<div class="site-footer__brand">
<div class="site-footer__logo" aria-label="睿能科技">
<img src="/themes/dist_static/static/images/logo-2-Ek-18nmQ.svg" alt="RAYNEN 睿能科技" width="252" height="26" />
<img src="{hcTaglib:setting name='logo' type='2' /}" alt="RAYNEN 睿能科技" width="252" height="26" />
</div>
<p class="site-footer__stock">股票代码: 603933</p>
<p class="site-footer__quote" aria-label="股票行情占位">
@ -15,11 +15,11 @@
<p class="site-footer__follow">关注我们:</p>
<div class="site-footer__qrs">
<div class="site-footer__qr">
<img src="/themes/dist_static/static/images/qrcode-1-C2aXBr_4.png" alt="官方微信" />
<img src="{hcTaglib:setting name='wechat_code' type='2' /}" alt="官方微信" />
<span>官方微信</span>
</div>
<div class="site-footer__qr">
<img src="/themes/dist_static/static/images/qrcode-2-Baljjv3Z.png" alt="官方视频号" />
<img src="{hcTaglib:setting name='dark_logo' type='2' /}" alt="官方视频号" />
<span>官方视频号</span>
</div>
</div>
@ -38,12 +38,11 @@
</nav>
</div>
<div class="site-footer__bottom">
<p class="site-footer__copyright">Copyright 2026 福建睿能科技股份有限公司 版权所有 | 闽ICP备09044485号 | <img
class="site-footer__gongan" src="/themes/dist_static/static/images/gongan-DdFBmJbc.png" alt="" /> 闽公网安备
35010202000576号</p>
<p class="site-footer__copyright">Copyright 2026 {hcTaglib:setting name="company_name" type="1" /} 版权所有 | {hcTaglib:setting name="icp" type="2" /} | <img
class="site-footer__gongan" src="/themes/dist_static/static/images/gongan-DdFBmJbc.png" alt="" /> {hcTaglib:setting name="gwa" type="2" /}</p>
<div class="site-footer__legal">
<a href="#">网站地图</a>
<a href="#">隐私声明</a>
<a href="/sitemap.html">网站地图</a>
<a href="/privacy.html">隐私声明</a>
</div>
</div>
</div>

65
public/themes/website/1/zh/demo/single_search.html

@ -86,22 +86,40 @@
</div>
</div>
{php}
$sr_type_cur = $sr_type ?? 'all';
$sr_q = $keywords ?? '';
$sr_counts = $sr_counts ?? ['all' => 0, 'product' => 0, 'solution' => 0, 'news' => 0, 'faq' => 0];
$sr_tabs = [];
foreach (['all', 'product', 'solution', 'news', 'faq'] as $tabType) {
$query = ['type' => $tabType];
if ($sr_q !== '') {
$query['q'] = $sr_q;
}
$sr_tabs[$tabType] = '/search.html?' . http_build_query($query);
}
{/php}
<div class="sr-tabs" role="tablist" aria-label="结果分类">
<button type="button" class="sr-tabs__item is-active" role="tab" aria-selected="true" data-type="all">
全部 ( <span data-count="all">0</span> )
</button>
<button type="button" class="sr-tabs__item" role="tab" aria-selected="false" data-type="product">
产品 ( <span data-count="product">0</span> )
</button>
<button type="button" class="sr-tabs__item" role="tab" aria-selected="false" data-type="solution">
解决方案 ( <span data-count="solution">0</span> )
</button>
<button type="button" class="sr-tabs__item" role="tab" aria-selected="false" data-type="news">
新闻 ( <span data-count="news">0</span> )
</button>
<button type="button" class="sr-tabs__item" role="tab" aria-selected="false" data-type="faq">
常见问题 ( <span data-count="faq">0</span> )
</button>
<a class="sr-tabs__item {if $sr_type_cur=='all'}is-active{/if}" role="tab" aria-selected="{if $sr_type_cur=='all'}true{else /}false{/if}"
href="{$sr_tabs.all}">
全部 ( <span data-count="all">{$sr_counts.all}</span> )
</a>
<a class="sr-tabs__item {if $sr_type_cur=='product'}is-active{/if}" role="tab" aria-selected="{if $sr_type_cur=='product'}true{else /}false{/if}"
href="{$sr_tabs.product}">
产品 ( <span data-count="product">{$sr_counts.product}</span> )
</a>
<a class="sr-tabs__item {if $sr_type_cur=='solution'}is-active{/if}" role="tab" aria-selected="{if $sr_type_cur=='solution'}true{else /}false{/if}"
href="{$sr_tabs.solution}">
解决方案 ( <span data-count="solution">{$sr_counts.solution}</span> )
</a>
<a class="sr-tabs__item {if $sr_type_cur=='news'}is-active{/if}" role="tab" aria-selected="{if $sr_type_cur=='news'}true{else /}false{/if}"
href="{$sr_tabs.news}">
新闻 ( <span data-count="news">{$sr_counts.news}</span> )
</a>
<a class="sr-tabs__item {if $sr_type_cur=='faq'}is-active{/if}" role="tab" aria-selected="{if $sr_type_cur=='faq'}true{else /}false{/if}"
href="{$sr_tabs.faq}">
常见问题 ( <span data-count="faq">{$sr_counts.faq}</span> )
</a>
</div>
<div class="sr-list">
@ -115,19 +133,8 @@
$sr_cid = $vo['category_id'] ?? ($vo['category'][0]['id'] ?? 0);
$sr_thumb = is_array($vo['thumbnail'] ?? null) ? ($vo['thumbnail']['url'] ?? '') : '';
$sr_url = hcUrl('detail/index', ['id' => $vo['id'], 'cid' => $sr_cid]);
$sr_cate_title = $vo['category'][0]['title'] ?? '';
$sr_type = 'other';
if (mb_strpos($sr_cate_title, '产品') !== false) {
$sr_type = 'product';
} elseif (mb_strpos($sr_cate_title, '解决方案') !== false || mb_strpos($sr_cate_title, '方案') !== false) {
$sr_type = 'solution';
} elseif (mb_strpos($sr_cate_title, '新闻') !== false) {
$sr_type = 'news';
} elseif (mb_strpos($sr_cate_title, '常见问题') !== false || mb_strpos($sr_cate_title, 'FAQ') !== false || mb_strpos($sr_cate_title, '问题') !== false) {
$sr_type = 'faq';
}
{/php}
<article class="sr-item" data-type="{$sr_type}" data-keywords="{$vo.title}">
<article class="sr-item" data-keywords="{$vo.title}">
<a class="sr-item__media" href="{$sr_url}">
<img src="{$sr_thumb}" alt="" width="300" height="200" loading="lazy" />
</a>
@ -157,10 +164,6 @@
{/volist}
</div>
<div class="s-empty sr-tabs-empty" hidden>
<p class="s-empty__text">当前分类下暂无结果</p>
</div>
{php}
$list_empty = isHcListEmpty($list ?? null);
if ($list_empty) {

Loading…
Cancel
Save