diff --git a/app/api/controller/Search.php b/app/api/controller/Search.php index 52067b2ae..ae12fc9df 100755 --- a/app/api/controller/Search.php +++ b/app/api/controller/Search.php @@ -46,6 +46,10 @@ class Search extends Common */ public function Index() { + // 搜素条件 + $map = SearchService::SearchWhereHandle($this->data_post); + + // 返回数据 $result = [ // 指定数据 'search_map_info' => SearchService::SearchMapInfo($this->data_request), @@ -56,9 +60,9 @@ class Search extends Common // 筛选价格区间 'screening_price_list' => SearchService::ScreeningPriceList($this->data_request), // 商品参数 - 'goods_params_list' => SearchService::SearchGoodsParamsValueList($this->data_request), + 'goods_params_list' => SearchService::SearchGoodsParamsValueList($map, $this->data_request), // 商品规格 - 'goods_spec_list' => SearchService::SearchGoodsSpecValueList($this->data_request), + 'goods_spec_list' => SearchService::SearchGoodsSpecValueList($map, $this->data_request), ]; return ApiService::ApiDataReturn(SystemBaseService::DataReturn($result)); } @@ -77,8 +81,11 @@ class Search extends Common $this->data_post['user_id'] = isset($this->user['id']) ? $this->user['id'] : 0; SearchService::SearchAdd($this->data_post); + // 搜素条件 + $map = SearchService::SearchWhereHandle($this->data_post); + // 获取数据 - $ret = SearchService::GoodsList($this->data_post); + $ret = SearchService::GoodsList($map, $this->data_post); return ApiService::ApiDataReturn(SystemBaseService::DataReturn($ret['data'])); } } diff --git a/app/index/controller/Search.php b/app/index/controller/Search.php index 99d4323fb..4860e53cb 100755 --- a/app/index/controller/Search.php +++ b/app/index/controller/Search.php @@ -35,22 +35,6 @@ class Search extends Common parent::__construct(); } - /** - * 参数初始化 - * @author Devil - * @blog http://gong.gg/ - * @version 1.0.0 - * @datetime 2019-06-02T01:38:27+0800 - */ - private function ParamsInit() - { - // 当前用户id - $this->data_request['user_id'] = empty($this->user) ? 0 : $this->user['id']; - - // 搜索关键字 - $this->data_request['wd'] = empty($this->data_request['wd']) ? '' : (IS_POST ? trim($this->data_request['wd']) : AsciiToStr($this->data_request['wd'])); - } - /** * 首页 * @author Devil @@ -66,11 +50,39 @@ class Search extends Common return MyRedirect(MyUrl('index/search/index', ['wd'=>StrToAscii($keywords)])); } - // 参数初始化 - $this->ParamsInit(); + // 搜素条件 + $map = SearchService::SearchWhereHandle($this->data_request); + + // 获取商品列表 + $ret = SearchService::GoodsList($map, $this->data_request); + + // 分页 + $page_params = [ + 'number' => $ret['data']['page_size'], + 'total' => $ret['data']['total'], + 'where' => $this->data_request, + 'page' => $ret['data']['page'], + 'url' => MyUrl('index/search/index'), + 'bt_number' => IsMobile() ? 2 : 4, + ]; + $page = new \base\Page($page_params); + $page_html = $page->GetPageHtml(); + + // 关键字处理 + $params = $this->data_request; + if(!empty($params['wd'])) + { + $params['wd'] = AsciiToStr($params['wd']); + } + + // 基础参数赋值 + MyViewAssign('params', $params); + MyViewAssign('page_html', $page_html); + MyViewAssign('data_total', $ret['data']['total']); + MyViewAssign('data_list', $ret['data']['data']); // 品牌列表 - $brand_list = SearchService::CategoryBrandList($this->data_request); + $brand_list = SearchService::SearchMapHandle(SearchService::CategoryBrandList($this->data_request), 'bid', 'id', $this->data_request); MyViewAssign('brand_list', $brand_list); // 指定数据 @@ -78,30 +90,34 @@ class Search extends Common MyViewAssign('search_map_info', $search_map_info); // 商品分类 - $category_list = SearchService::GoodsCategoryList($this->data_request); + $category_list = SearchService::SearchMapHandle(SearchService::GoodsCategoryList($this->data_request), 'cid', 'id', $this->data_request); MyViewAssign('category_list', $category_list); // 筛选价格区间 - $screening_price_list = SearchService::ScreeningPriceList($this->data_request); + $screening_price_list = SearchService::SearchMapHandle(SearchService::ScreeningPriceList($this->data_request), 'peid', 'id', $this->data_request); MyViewAssign('screening_price_list', $screening_price_list); // 商品参数 - $goods_params_list = SearchService::SearchGoodsParamsValueList($this->data_request); + $goods_params_list = SearchService::SearchMapHandle(SearchService::SearchGoodsParamsValueList($map, $this->data_request), 'psid', 'id', $this->data_request, ['is_ascii'=>true, 'field'=>'value']); MyViewAssign('goods_params_list', $goods_params_list); // 商品规格 - $goods_spec_list = SearchService::SearchGoodsSpecValueList($this->data_request); + $goods_spec_list = SearchService::SearchMapHandle(SearchService::SearchGoodsSpecValueList($map, $this->data_request), 'scid', 'id', $this->data_request, ['is_ascii'=>true, 'field'=>'value']); MyViewAssign('goods_spec_list', $goods_spec_list); - // 参数 - MyViewAssign('params', $this->data_request); + // 排序方式 + MyViewAssign('map_order_by_list', SearchService::SearchMapOrderByList($this->data_request)); + + // 搜索记录 + $params['user_id'] = empty($this->user) ? 0 : $this->user['id']; + $params['search_result_data'] = $ret['data']; + SearchService::SearchAdd($params); // seo - $this->SetSeo($search_map_info); + $this->SetSeo($search_map_info, $params); // 钩子 $this->PluginsHook(); - return MyView(); } @@ -112,12 +128,13 @@ class Search extends Common * @version 1.0.0 * @date 2021-01-11 * @desc description - * @param [array] $data [条件基础数据] + * @param [array] $data [条件基础数据] + * @param [array] $params [输入参数] */ - private function SetSeo($data = []) + private function SetSeo($data = [], $params = []) { // 默认关键字 - $seo_title = empty($this->data_request['wd']) ? '' : $this->data_request['wd']; + $seo_title = empty($params['wd']) ? '' : $params['wd']; // 分类、品牌 $seo_data = empty($data['category']) ? (empty($data['brand']) ? [] : $data['brand']) : $data['category']; @@ -138,44 +155,6 @@ class Search extends Common MyViewAssign('home_seo_site_title', SeoService::BrowserSeoTitle(empty($seo_title) ? '商品搜索' : $seo_title, 1)); } - /** - * 获取商品列表 - * @author Devil - * @blog http://gong.gg/ - * @version 1.0.0 - * @date 2018-09-07 - * @desc description - */ - public function GoodsList() - { - // 是否ajax请求 - if(!IS_AJAX) - { - $this->error('非法访问'); - } - - // 参数初始化 - $this->ParamsInit(); - - // 获取商品列表 - $ret = SearchService::GoodsList($this->data_request); - - // 搜索记录 - $this->data_request['search_result_data'] = $ret['data']; - SearchService::SearchAdd($this->data_request); - - // 无数据直接返回 - if($ret['code'] != 0 || empty($ret['data']['data'])) - { - return DataReturn('没有更多数据啦', -100); - } - - // 返回数据html - MyViewAssign('data', $ret['data']['data']); - $ret['data']['data'] = MyView('content'); - return $ret; - } - /** * 钩子处理 * @author Devil diff --git a/app/index/view/default/public/goods_category.html b/app/index/view/default/public/goods_category.html index 7acc5f883..2168f377f 100755 --- a/app/index/view/default/public/goods_category.html +++ b/app/index/view/default/public/goods_category.html @@ -12,7 +12,7 @@ {{if !empty($goods_category_list) and is_array($goods_category_list)}} {{foreach $goods_category_list as $v}}
  • - +

    {{if !empty($v['icon'])}} @@ -34,20 +34,20 @@
    {{if $category_show_level eq 2}}
    - + {{$vs.name}}
    {{elseif $category_show_level eq 3}}
    - + {{$vs.name}}
    {{if !empty($vs['items'])}} {{foreach $vs.items as $vss}}
    - + {{$vss.name}}
    diff --git a/app/index/view/default/search/content.html b/app/index/view/default/search/content.html index 54113efe5..8207ea838 100644 --- a/app/index/view/default/search/content.html +++ b/app/index/view/default/search/content.html @@ -1,16 +1,50 @@ -{{if !empty($data)}} - {{foreach $data as $v}} -
  • -
    - - +{{if !empty($data_list)}} +
      + {{foreach $data_list as $v}} +
    • +
      + + + {{if isset($shopxo_is_develop) and $shopxo_is_develop eq true}} +
      + plugins_view_search_goods_inside_top +
      + {{/if}} + {{php}} + $hook_name = 'plugins_view_search_goods_inside_top'; + $hook_data = MyEventTrigger($hook_name, ['hook_name'=>$hook_name, 'is_backend'=>false, 'goods_id'=>$v['id'], 'goods'=>$v]); + if(!empty($hook_data) && is_array($hook_data)) + { + foreach($hook_data as $hook) + { + if(is_string($hook) || is_int($hook)) + { + echo htmlspecialchars_decode($hook); + } + } + } + {{/php}} + + {{$v.title}} +
      +

      {{$v.title}}

      +
      +
      +

      + {{if isset($v['original_price']) and $v['original_price'] gt 0}} + {{$currency_symbol}}{{$v.original_price}} + {{/if}} + 销量 {{$v.sales_count}} +

      + + {{if isset($shopxo_is_develop) and $shopxo_is_develop eq true}}
      - plugins_view_search_goods_inside_top + plugins_view_search_goods_inside_price_top
      {{/if}} {{php}} - $hook_name = 'plugins_view_search_goods_inside_top'; + $hook_name = 'plugins_view_search_goods_inside_price_top'; $hook_data = MyEventTrigger($hook_name, ['hook_name'=>$hook_name, 'is_backend'=>false, 'goods_id'=>$v['id'], 'goods'=>$v]); if(!empty($hook_data) && is_array($hook_data)) { @@ -24,64 +58,34 @@ } {{/php}} - {{$v.title}} -
      -

      {{$v.title}}

      -
      - -

      - {{if isset($v['original_price']) and $v['original_price'] gt 0}} - {{$currency_symbol}}{{$v.original_price}} +

      + {{$currency_symbol}}{{$v.price}} +

      + + + {{if isset($shopxo_is_develop) and $shopxo_is_develop eq true}} +
      + plugins_view_search_goods_inside_bottom +
      {{/if}} - 销量 {{$v.sales_count}} -

      - - - {{if isset($shopxo_is_develop) and $shopxo_is_develop eq true}} -
      - plugins_view_search_goods_inside_price_top -
      - {{/if}} - {{php}} - $hook_name = 'plugins_view_search_goods_inside_price_top'; - $hook_data = MyEventTrigger($hook_name, ['hook_name'=>$hook_name, 'is_backend'=>false, 'goods_id'=>$v['id'], 'goods'=>$v]); - if(!empty($hook_data) && is_array($hook_data)) - { - foreach($hook_data as $hook) + {{php}} + $hook_name = 'plugins_view_search_goods_inside_bottom'; + $hook_data = MyEventTrigger($hook_name, ['hook_name'=>$hook_name, 'is_backend'=>false, 'goods_id'=>$v['id'], 'goods'=>$v]); + if(!empty($hook_data) && is_array($hook_data)) { - if(is_string($hook) || is_int($hook)) + foreach($hook_data as $hook) { - echo htmlspecialchars_decode($hook); + if(is_string($hook) || is_int($hook)) + { + echo htmlspecialchars_decode($hook); + } } } - } - {{/php}} - -

      - {{$currency_symbol}}{{$v.price}} -

      - - - {{if isset($shopxo_is_develop) and $shopxo_is_develop eq true}} -
      - plugins_view_search_goods_inside_bottom -
      - {{/if}} - {{php}} - $hook_name = 'plugins_view_search_goods_inside_bottom'; - $hook_data = MyEventTrigger($hook_name, ['hook_name'=>$hook_name, 'is_backend'=>false, 'goods_id'=>$v['id'], 'goods'=>$v]); - if(!empty($hook_data) && is_array($hook_data)) - { - foreach($hook_data as $hook) - { - if(is_string($hook) || is_int($hook)) - { - echo htmlspecialchars_decode($hook); - } - } - } - {{/php}} -
      -
    • - {{/foreach}} + {{/php}} +
    +
  • + {{/foreach}} + +{{else /}} + {{include file="public/not_data" /}} {{/if}} \ No newline at end of file diff --git a/app/index/view/default/search/index.html b/app/index/view/default/search/index.html index ef41b1405..2f6164160 100755 --- a/app/index/view/default/search/index.html +++ b/app/index/view/default/search/index.html @@ -47,7 +47,7 @@

    筛选出 - ... + {{$data_total}} 条数据

    @@ -90,7 +90,7 @@
  • 筛选出 - ... + {{$data_total}} 条数据

    清除 @@ -118,19 +118,17 @@
    -
    - 更多 - -
    {{else /}}
    @@ -163,13 +161,11 @@
      {{foreach $category_list as $v}} -
    • {{$v.name}}
    • +
    • + {{$v.name}} +
    • {{/foreach}}
    -
    - 更多 - -
  • {{/if}} @@ -181,13 +177,11 @@
      {{foreach $screening_price_list as $v}} -
    • {{$v.name}}
    • +
    • + {{$v.name}} +
    • {{/foreach}}
    -
    - 更多 - -

  • {{/if}} @@ -199,13 +193,11 @@
    -
    - 更多 - -
    {{/if}} @@ -217,13 +209,11 @@
    -
    - 更多 - -
    {{/if}} @@ -277,35 +267,19 @@ {{/foreach}} {{/if}} -
  • - - 综合 - -
  • -
  • - - 销量 - - -
  • -
  • - - 热度 - - -
  • -
  • - - 价格 - - -
  • -
  • - - 最新 - - -
  • + + {{if !empty($map_order_by_list)}} + {{foreach $map_order_by_list as $k=>$v}} +
  • + + {{$v.name}} + {{if $v['type'] neq 'default'}} + + {{/if}} + +
  • + {{/foreach}} + {{/if}} {{if isset($shopxo_is_develop) and $shopxo_is_develop eq true}} @@ -337,8 +311,8 @@ {{/foreach}} {{/if}} - - + + {{include file="search/content" /}} {{if isset($shopxo_is_develop) and $shopxo_is_develop eq true}} @@ -354,17 +328,10 @@ {{/foreach}} {{/if}} - -
    - - 加载中... -
    - - - - - +
    + {{$page_html|raw}} +
    diff --git a/app/route/route.config b/app/route/route.config index 28cea961a..1fa4d9bdc 100644 --- a/app/route/route.config +++ b/app/route/route.config @@ -21,9 +21,6 @@ $ds = MyC('common_route_separator', '-', true); Route::get('goods'.$ds.':id', 'index/goods/index'); // 搜索 -Route::get('search'.$ds.'c'.$ds.':category_id', 'index/search/index'); -Route::get('search'.$ds.'b'.$ds.':brand_id', 'index/search/index'); -Route::get('search'.$ds.'k'.$ds.':wd', 'index/search/index'); Route::rule('search', 'index/search/index', 'GET|POST'); Route::post('search-goods', 'index/search/goodslist'); diff --git a/app/service/SearchService.php b/app/service/SearchService.php index b90d558c3..fc24804b2 100755 --- a/app/service/SearchService.php +++ b/app/service/SearchService.php @@ -25,6 +25,113 @@ use app\service\ResourcesService; */ class SearchService { + // 筛选排序规则列表 + public static $map_order_by_list = [ + [ + 'name' => '综合', + 'type' => 'default', + 'value' => 'desc', + ], + [ + 'name' => '销量', + 'type' => 'sales', + 'value' => 'desc', + ], + [ + 'name' => '热度', + 'type' => 'access', + 'value' => 'desc', + ], + [ + 'name' => '价格', + 'type' => 'price', + 'value' => 'desc', + ], + [ + 'name' => '最新', + 'type' => 'new', + 'value' => 'desc', + ], + ]; + + /** + * 排序列表 + * @author Devil + * @blog http://gong.gg/ + * @version 1.0.0 + * @date 2021-11-01 + * @desc description + * @param [array] $params [输入参数] + */ + public static function SearchMapOrderByList($params = []) + { + $ov = empty($params['ov']) ? ['default'] : explode('-', $params['ov']); + $data = self::$map_order_by_list; + foreach($data as &$v) + { + // 是否选中 + $v['is_active'] = ($ov[0] == $v['type']) ? 1 : 0; + + // url + $temp_ov = ''; + if($v['type'] == 'default') + { + $temp_params = $params; + unset($temp_params['ov']); + } else { + // 类型 + if($ov[0] == $v['type']) + { + $v['value'] = ($ov[1] == 'desc') ? 'asc' : 'desc'; + } + + // 参数值 + $temp_ov = $v['type'].'-'.$v['value']; + $temp_params = array_merge($params, ['ov'=>$temp_ov]); + } + $v['url'] = MyUrl('index/search/index', $temp_params); + } + return $data; + } + + /** + * 搜素条件处理 + * @author Devil + * @blog http://gong.gg/ + * @version 1.0.0 + * @date 2022-06-30 + * @desc description + * @param [array] $data [数据列表] + * @param [string] $pid [参数字段] + * @param [string] $did [数据字段] + * @param [array] $params [输入参数] + * @param [array] $ext [扩展数据] + */ + public static function SearchMapHandle($data, $pid, $did, $params, $ext = []) + { + // ascii字段处理 + $is_ascii = isset($ext['is_ascii']) && $ext['is_ascii'] == true; + $field = empty($ext['field']) ? 'value' : $ext['field']; + foreach($data as &$v) + { + // 是否转ascii处理主键字段 + if($is_ascii && !empty($field) && isset($v[$field])) + { + $v[$did] = StrToAscii(($v[$field])); + } + if((isset($params[$pid]) && $params[$pid] == $v[$did])) + { + $temp_params = $params; + unset($temp_params[$pid]); + } else { + $temp_params = array_merge($params, [$pid=>$v[$did]]); + } + $v['url'] = MyUrl('index/search/index', $temp_params); + $v['is_active'] = (isset($params[$pid]) && $params[$pid] == $v[$did]) ? 1 : 0; + } + return $data; + } + /** * 获取商品列表 * @author Devil @@ -32,36 +139,32 @@ class SearchService * @version 1.0.0 * @date 2018-09-07 * @desc description + * @param [array] $map [搜素条件] * @param [array] $params [输入参数] */ - public static function GoodsList($params = []) + public static function GoodsList($map, $params = []) { // 返回格式 $result = [ + 'page_start' => 0, + 'page_size' => 0, + 'page' => 1, 'page_total' => 0, 'total' => 0, 'data' => [], ]; // 搜索条件 - $where = self::SearchWhereHandle($params); - $where_base = $where['base']; - $where_keywords = $where['keywords']; - $where_screening_price = $where['screening_price']; - - // 排序 - if(!empty($params['order_by_field']) && !empty($params['order_by_type']) && $params['order_by_field'] != 'default') - { - $order_by = 'g.'.$params['order_by_field'].' '.$params['order_by_type']; - } else { - $order_by = 'g.access_count desc, g.sales_count desc, g.id desc'; - } + $order_by = $map['order_by']; + $where_base = $map['base']; + $where_keywords = $map['keywords']; + $where_screening_price = $map['screening_price']; // 分页计算 $field = 'g.*'; - $page = max(1, isset($params['page']) ? intval($params['page']) : 1); - $n = MyC('home_search_limit_number', 20, true); - $m = intval(($page-1)*$n); + $result['page'] = max(1, isset($params['page']) ? intval($params['page']) : 1); + $result['page_size'] = empty($params['page_size']) ? MyC('home_search_limit_number', 20, true) : intval($params['page_size']); + $result['page_start'] = intval(($result['page']-1)*$result['page_size']); // 搜索商品列表读取前钩子 $hook_name = 'plugins_service_search_goods_list_begin'; @@ -74,9 +177,9 @@ class SearchService 'where_screening_price' => &$where_screening_price, 'field' => &$field, 'order_by' => &$order_by, - 'page' => &$page, - 'm' => &$m, - 'n' => &$n, + 'page' => &$result['page'], + 'page_start' => &$result['page_start'], + 'page_size' => &$result['page_size'], ]); // 获取商品总数 @@ -94,14 +197,14 @@ class SearchService self::SearchKeywordsWhereJoinType($query, $where_keywords); })->where(function($query) use($where_screening_price) { $query->whereOr($where_screening_price); - })->group('g.id')->order($order_by)->limit($m, $n)->select()->toArray(); + })->group('g.id')->order($order_by)->limit($result['page_start'], $result['page_size'])->select()->toArray(); // 数据处理 $goods = GoodsService::GoodsDataHandle($data); // 返回数据 $result['data'] = $goods['data']; - $result['page_total'] = ceil($result['total']/$n); + $result['page_total'] = ceil($result['total']/$result['page_size']); } return DataReturn('处理成功', 0, $result); } @@ -160,6 +263,11 @@ class SearchService $where_keywords = []; if(!empty($params['wd'])) { + // WEB端则处理关键字 + if(APPLICATION_CLIENT_TYPE == 'pc') + { + $params['wd'] = AsciiToStr($params['wd']); + } $keywords_fields = 'g.title|g.simple_desc|g.model'; if(MyC('home_search_is_keywords_seo_fields') == 1) { @@ -187,9 +295,14 @@ class SearchService } else { if(!empty($params['brand_id'])) { - $where_base[] = ['g.brand_id', 'in', [$params['brand_id']]]; + $where_base[] = ['g.brand_id', 'in', [intval($params['brand_id'])]]; } } + // web端 + if(!empty($params['bid'])) + { + $where_base[] = ['g.brand_id', 'in', [intval($params['bid'])]]; + } // 分类id // 不存在搜索分类的时候则看是否指定分类 @@ -211,81 +324,132 @@ class SearchService $where_base[] = ['gci.category_id', 'in', $ids]; } } + // web端 + if(!empty($params['cid'])) + { + $ids = GoodsService::GoodsCategoryItemsIds([intval($params['cid'])], 1); + $where_base[] = ['gci.category_id', 'in', $ids]; + } // 筛选价格 + $map_price = []; $where_screening_price = []; if(!empty($params['screening_price_values'])) { if(!is_array($params['screening_price_values'])) { - $params['screening_price_values'] = (substr($params['screening_price_values'], 0, 1) == '{') ? json_decode(htmlspecialchars_decode($params['screening_price_values']), true) : explode(',', $params['screening_price_values']); + $map_price = (substr($params['screening_price_values'], 0, 1) == '{') ? json_decode(htmlspecialchars_decode($params['screening_price_values']), true) : explode(',', $params['screening_price_values']); } - if(!empty($params['screening_price_values'])) + } + // web端 + if(!empty($params['peid'])) + { + $temp_price = Db::name('ScreeningPrice')->where(['is_enable'=>1, 'id'=>intval($params['peid'])])->field('min_price,max_price')->find(); + if(!empty($temp_price)) { - foreach($params['screening_price_values'] as $v) + $map_price[] = implode('-', $temp_price); + } + } + if(!empty($map_price)) + { + foreach($map_price as $v) + { + $temp = explode('-', $v); + if(count($temp) == 2) { - $temp = explode('-', $v); - if(count($temp) == 2) + // 最小金额等于0、最大金额大于0 + if(empty($temp[0]) && !empty($temp[1])) { - // 最小金额等于0、最大金额大于0 - if(empty($temp[0]) && !empty($temp[1])) - { - $where_screening_price[] = [ - ['min_price', '<=', $temp[1]], - ]; + $where_screening_price[] = [ + ['min_price', '<=', $temp[1]], + ]; - // 最小金额大于0、最大金额大于0 - // 最小金额等于0、最大金额等于0 - } elseif((!empty($temp[0]) && !empty($temp[1])) || (empty($temp[0]) && empty($temp[1]))) - { - $where_screening_price[] = [ - ['min_price', '>=', $temp[0]], - ['min_price', '<=', $temp[1]], - ]; + // 最小金额大于0、最大金额大于0 + // 最小金额等于0、最大金额等于0 + } elseif((!empty($temp[0]) && !empty($temp[1])) || (empty($temp[0]) && empty($temp[1]))) + { + $where_screening_price[] = [ + ['min_price', '>=', $temp[0]], + ['min_price', '<=', $temp[1]], + ]; - // 最小金额大于0、最大金额等于0 - } elseif(!empty($temp[0]) && empty($temp[1])) - { - $where_screening_price[] = [ - ['min_price', '>=', $temp[0]], - ]; - } + // 最小金额大于0、最大金额等于0 + } elseif(!empty($temp[0]) && empty($temp[1])) + { + $where_screening_price[] = [ + ['min_price', '>=', $temp[0]], + ]; } } } } // 商品参数、属性 + $map_params = []; if(!empty($params['goods_params_values'])) { if(!is_array($params['goods_params_values'])) { - $params['goods_params_values'] = (substr($params['goods_params_values'], 0, 1) == '{') ? json_decode(htmlspecialchars_decode($params['goods_params_values']), true) : explode(',', $params['goods_params_values']); + $map_params = (substr($params['goods_params_values'], 0, 1) == '{') ? json_decode(htmlspecialchars_decode($params['goods_params_values']), true) : explode(',', $params['goods_params_values']); } - if(!empty($params['goods_params_values'])) + } + if(!empty($params['psid'])) + { + $map_params[] = AsciiToStr($params['psid']); + } + if(!empty($map_params)) + { + $ids = Db::name('GoodsParams')->where(['value'=>$map_params, 'type'=>self::SearchParamsWhereTypeValue()])->column('goods_id'); + if(!empty($ids)) { - $ids = Db::name('GoodsParams')->where(['value'=>$params['goods_params_values'], 'type'=>self::SearchParamsWhereTypeValue()])->column('goods_id'); - if(!empty($ids)) - { - $where_base[] = ['g.id', 'in', $ids]; - } + $where_base[] = ['g.id', 'in', $ids]; } } // 商品规格 + $map_spec = []; if(!empty($params['goods_spec_values'])) { if(!is_array($params['goods_spec_values'])) { - $params['goods_spec_values'] = (substr($params['goods_spec_values'], 0, 1) == '{') ? json_decode(htmlspecialchars_decode($params['goods_spec_values']), true) : explode(',', $params['goods_spec_values']); + $map_spec = (substr($params['goods_spec_values'], 0, 1) == '{') ? json_decode(htmlspecialchars_decode($params['goods_spec_values']), true) : explode(',', $params['goods_spec_values']); } - if(!empty($params['goods_spec_values'])) + } + if(!empty($params['scid'])) + { + $map_spec[] = AsciiToStr($params['scid']); + } + if(!empty($map_spec)) + { + $ids = Db::name('GoodsSpecValue')->where(['value'=>$map_spec])->column('goods_id'); + if(!empty($ids)) { - $ids = Db::name('GoodsSpecValue')->where(['value'=>$params['goods_spec_values']])->column('goods_id'); - if(!empty($ids)) - { - $where_base[] = ['g.id', 'in', $ids]; - } + $where_base[] = ['g.id', 'in', $ids]; + } + } + + // 排序 + $order_by = 'g.access_count desc, g.sales_count desc, g.id desc'; + if(!empty($params['ov'])) + { + // 数据库字段映射关系 + $fields = [ + 'sales' => 'g.sales_count', + 'access' => 'g.access_count', + 'price' => 'g.min_price', + 'new' => 'g.id', + ]; + + // 参数判断 + $temp = explode('-', $params['ov']); + if(count($temp) == 2 && $temp[0] != 'default' && array_key_exists($temp[0], $fields) && in_array($temp[1], ['desc', 'asc'])) + { + $order_by = $fields[$temp[0]].' '.$temp[1]; + } + } else { + if(!empty($params['order_by_type']) && !empty($params['order_by_field']) && $params['order_by_field'] != 'default') + { + $order_by = 'g.'.$params['order_by_field'].' '.$params['order_by_type']; } } @@ -293,6 +457,7 @@ class SearchService 'base' => $where_base, 'keywords' => $where_keywords, 'screening_price' => $where_screening_price, + 'order_by' => $order_by, ]; } @@ -332,39 +497,61 @@ class SearchService */ public static function SearchAdd($params = []) { - // 搜索数据结果 - if(!empty($params['search_result_data'])) + // 排序 + $ov_arr = empty($params['ov']) ? '' : explode('-', $params['ov']); + if(empty($ov_arr) && !empty($params['order_by_type']) && !empty($params['order_by_field'])) { - $search_result = [ - 'total' => empty($params['search_result_data']['total']) ? 0 : $params['search_result_data']['total'], - 'data_count' => empty($params['search_result_data']['data']) ? 0 : count($params['search_result_data']['data']), - 'page' => empty($params['page']) ? 1 : intval($params['page']), - 'page_total' => empty($params['search_result_data']['page_total']) ? 0 : $params['search_result_data']['page_total'], - ]; + $ov_arr = [$params['order_by_field'], $params['order_by_type']]; } // 日志数据 $data = [ 'user_id' => isset($params['user_id']) ? intval($params['user_id']) : 0, 'keywords' => empty($params['wd']) ? '' : $params['wd'], - 'order_by_field' => empty($params['order_by_field']) ? '' : $params['order_by_field'], - 'order_by_type' => empty($params['order_by_type']) ? '' : $params['order_by_type'], - 'search_result' => empty($search_result) ? '' : json_encode($search_result, JSON_UNESCAPED_UNICODE), + 'order_by_field' => empty($ov_arr) ? '' : $ov_arr[0], + 'order_by_type' => empty($ov_arr) ? '' : $ov_arr[1], + 'search_result' => empty($params['search_result_data']) ? '' : json_encode($params['search_result_data'], JSON_UNESCAPED_UNICODE), 'ymd' => date('Ymd'), 'add_time' => time(), ]; // 参数处理 $field_arr = [ - 'brand_ids', - 'category_ids', - 'screening_price_values', - 'goods_params_values', - 'goods_spec_values', + 'brand_ids' => ['brand_ids', 'brand_id', 'bid'], + 'category_ids' => ['category_ids', 'category_id', 'cid'], + 'screening_price_values'=> ['screening_price_values', 'peid'], + 'goods_params_values' => ['goods_params_values', 'psid'], + 'goods_spec_values' => ['goods_spec_values', 'scid'], ]; - foreach($field_arr as $v) + foreach($field_arr as $k=>$v) { - $data[$v] = empty($params[$v]) ? '' : (is_array($params[$v]) ? json_encode($params[$v], JSON_UNESCAPED_UNICODE) : $params[$v]); + $item = []; + foreach($v as $vs) + { + if(!empty($params[$vs])) + { + // 价格区间 + if($vs == 'peid') + { + $temp_price = Db::name('ScreeningPrice')->where(['is_enable'=>1, 'id'=>intval($params[$vs])])->field('min_price,max_price')->find(); + $params[$vs] = empty($temp_price) ? '' : implode('-', $temp_price); + } + + // Ascii处理 + if(in_array($vs, ['psid', 'scid'])) + { + $params[$vs] = AsciiToStr($params[$vs]); + } + + // 合并参数 + $tv = (substr($params[$vs], 0, 1) == '{') ? json_decode(htmlspecialchars_decode($params[$vs]), true) : $params[$vs]; + if($tv !== '' && $tv !== null) + { + $item = array_merge($item, is_array($tv) ? $tv : [$tv]); + } + } + } + $data[$k] = empty($item) ? '' : (is_array($item) ? json_encode($item, JSON_UNESCAPED_UNICODE) : $item); } Db::name('SearchHistory')->insert($data); @@ -430,24 +617,16 @@ class SearchService ['is_enable', '=', 1], ]; - // 搜索条件 - $where = self::SearchWhereHandle($params); - $where_base = $where['base']; - $where_keywords = $where['keywords']; - $where_screening_price = $where['screening_price']; - - // 一维数组、参数值去重 - if(!empty($where_base) || !empty($where_keywords) || !empty($where_screening_price)) + // 仅获取已关联商品的品牌 + $where = [ + ['is_shelves', '=', 1], + ['is_delete_time', '=', 0], + ['brand_id', '>', 0], + ]; + $ids = Db::name('Goods')->where($where)->column('distinct brand_id'); + if(!empty($ids)) { - $ids = Db::name('Goods')->alias('g')->join('goods_category_join gci', 'g.id=gci.goods_id')->where($where_base)->where(function($query) use($where_keywords) { - self::SearchKeywordsWhereJoinType($query, $where_keywords); - })->where(function($query) use($where_screening_price) { - $query->whereOr($where_screening_price); - })->group('g.brand_id')->column('g.brand_id'); - if(!empty($ids)) - { - $brand_where[] = ['id', 'in', array_unique($ids)]; - } + $brand_where[] = ['id', 'in', $ids]; } // 获取品牌列表 @@ -475,20 +654,12 @@ class SearchService public static function GoodsCategoryList($params = []) { $data = []; - - // 查询分类条件处理钩子 - $hook_name = 'plugins_service_search_category_list_where'; - MyEventTrigger($hook_name, [ - 'hook_name' => $hook_name, - 'is_backend' => true, - 'params' => &$params, - ]); - if(MyC('home_search_is_category', 0) == 1) { - $pid = empty($params['category_id']) ? 0 : intval($params['category_id']); + $cid = empty($params['category_id']) ? (empty($params['cid']) ? 0 : intval($params['cid'])) : intval($params['category_id']); + $pid = empty($cid) ? 0 : Db::name('GoodsCategory')->where(['id'=>$cid])->value('pid'); $where = [ - ['pid', '=', $pid], + ['pid', '=', intval($pid)], ]; $data = GoodsService::GoodsCategoryList(['where'=>$where, 'field'=>'id,name']); } @@ -521,18 +692,18 @@ class SearchService * @version 1.0.0 * @date 2021-01-08 * @desc description - * @param [array] $params [输入参数] + * @param [array] $map [搜素条件] + * @param [array] $params [输入参数] */ - public static function SearchGoodsParamsValueList($params = []) + public static function SearchGoodsParamsValueList($map, $params = []) { $data = []; if(MyC('home_search_is_params', 0) == 1) { // 搜索条件 - $where = self::SearchWhereHandle($params); - $where_base = $where['base']; - $where_keywords = $where['keywords']; - $where_screening_price = $where['screening_price']; + $where_base = $map['base']; + $where_keywords = $map['keywords']; + $where_screening_price = $map['screening_price']; // 仅搜索基础参数 $where_base[] = ['gp.type', 'in', self::SearchParamsWhereTypeValue()]; @@ -554,18 +725,18 @@ class SearchService * @version 1.0.0 * @date 2021-01-08 * @desc description + * @param [array] $map [搜素条件] * @param [array] $params [输入参数] */ - public static function SearchGoodsSpecValueList($params = []) + public static function SearchGoodsSpecValueList($map, $params = []) { $data = []; if(MyC('home_search_is_spec', 0) == 1) { // 搜索条件 - $where = self::SearchWhereHandle($params); - $where_base = $where['base']; - $where_keywords = $where['keywords']; - $where_screening_price = $where['screening_price']; + $where_base = $map['base']; + $where_keywords = $map['keywords']; + $where_screening_price = $map['screening_price']; // 一维数组、参数值去重 $data = Db::name('Goods')->alias('g')->join('goods_category_join gci', 'g.id=gci.goods_id')->join('goods_spec_value gsv', 'g.id=gsv.goods_id')->where($where_base)->where(function($query) use($where_keywords) { @@ -589,7 +760,12 @@ class SearchService public static function SearchMapInfo($params = []) { // 分类 - $category = empty($params['category_id']) ? [] : GoodsService::GoodsCategoryRow(['id'=>intval($params['category_id']), 'field'=>'name,vice_name,describe,seo_title,seo_keywords,seo_desc']); + $category = null; + $cid = empty($params['category_id']) ? (empty($params['cid']) ? 0 : intval($params['cid'])) : intval($params['category_id']); + if(!empty($cid)) + { + $category = GoodsService::GoodsCategoryRow(['id'=>$cid, 'field'=>'name,vice_name,describe,seo_title,seo_keywords,seo_desc']); + } // 品牌 $brand = null; diff --git a/public/static/common/css/common.css b/public/static/common/css/common.css index 5ef0a1b04..763623285 100755 --- a/public/static/common/css/common.css +++ b/public/static/common/css/common.css @@ -8,6 +8,7 @@ ul { list-style: none; } .vertical-middle { vertical-align: middle !important; } .text-deco-none { text-decoration: none !important; } .text-deco-line { text-decoration: underline !important; } +button[disabled], html input[disabled] { cursor: default !important; color: #b1b1b1 !important; background: #e6e6e6 !important; } /** * 表单组件 diff --git a/public/static/index/default/css/search.css b/public/static/index/default/css/search.css index 3367d63f4..1204aa94c 100755 --- a/public/static/index/default/css/search.css +++ b/public/static/index/default/css/search.css @@ -10,7 +10,7 @@ font-weight: bold; line-height: 50px; } -.map-item > li, +.map-item > li > a, .map-item .map-left { line-height: 50px; } @@ -36,51 +36,49 @@ .map-images-text-items ul, .map-text-items ul { - padding: 15px 48px 0 15px; + padding: 15px 0 0 15px; overflow-y: hidden; } -.map-images-text-items { - height: 66px; -} -.map-text-items { - height: 56px; -} -.map-images-text-items ul li { +.map-images-text-items ul > li { float: left; vertical-align: middle; text-align: center; - border: 1px solid #eee; - width: 124px; - height: 36px; - margin: 0 15px 15px 0; line-height: 36px; + height: 36px; + width: 124px; + margin: 0 15px 15px 0; } -.map-images-text-items ul li, -.map-text-items ul li { +.map-images-text-items ul > li > a { + border: 1px solid #eee; +} +.map-images-text-items ul > li > a, +.map-text-items ul > li > a { + display: block; border-radius: 2px; cursor: pointer; } -.map-images-text-items ul li img { - height: calc(100% - 4px); +.map-images-text-items ul > li > a img { display: block; margin: 0 auto; - margin-top: 2px; max-width: 100%; + max-height: 36px; } -.map-text-items ul li { +.map-text-items ul > li { float: left; margin: 0 15px 15px 0; line-height: 20px; - padding: 2px 10px; +} +.map-text-items ul > li > a { + padding: 2px 10px !important; border: 1px solid transparent; } -.map-images-text-items ul li.active, -.map-text-items ul li.active { +.map-images-text-items ul > li.active > a, +.map-text-items ul > li.active a { border: 1px solid #e23f36; } -.map-images-text-items ul li.active, -.map-text-items ul li.active { - color: #e23f36; +.map-images-text-items ul > li.active > a, +.map-text-items ul li.active a { + color: #e23f36 !important; font-weight: bold; } .map-item > li:first-child { @@ -107,14 +105,14 @@ color: #333; } @media only screen and (min-width: 640px) { - .map-images-text-items ul li:hover, - .map-text-items ul li:hover { + .map-images-text-items ul > li > a:hover, + .map-text-items ul > li > a:hover { border: 1px solid #e23f36; } - .map-images-text-items ul li:hover, - .map-text-items ul li:hover, + .map-images-text-items ul > li > a:hover, + .map-text-items ul > li > a:hover, .map-remove-submit:hover { - color: #e23f36; + color: #e23f36 !important; font-weight: bold; } .map-item .map-more-submit:hover { @@ -149,7 +147,7 @@ .map-item { margin-top: 0; } - .map-item > li { + .map-item > li > a { border: 0; background: #f0f0f0; } @@ -164,7 +162,7 @@ .map-item .map-left { line-height: 36px !important; } - .map-item > li:first-child { + .map-item > li > a:first-child { border-bottom: 2px solid #e1e1e1; } .map-images-text-items ul, .map-text-items ul { @@ -273,11 +271,11 @@ display: inline; border-right: 1px solid #eee; width: auto; - padding:0px 20px; } .sort-nav li a { font-size: 12px; text-decoration: none; + padding: 6px 20px; } .sort-nav li.active { background: #d2354c; @@ -321,14 +319,15 @@ } @media only screen and (min-width: 640px) { .search-container ul li:hover .items { - -webkit-box-shadow: 0px 12px 12px -10px rgba(0,0,0,.4); - box-shadow: 0px 12px 12px -10px rgba(0,0,0,.4); - border: 4px solid #d2364c; + -webkit-box-shadow: 0px 12px 12px -10px rgb(0 0 0 / 40%); + box-shadow: 0px 12px 12px -10px rgb(0 0 0 / 40%); + border: 1px solid #d2364c; -webkit-transition: border-color .2s ease-in; -moz-transition: border-color .2s ease-in; -ms-transition: border-color .2s ease-in; -o-transition: border-color .2s ease-in; transition: border-color .2s ease-in; + box-shadow: 0px 0 0px 3px #e23f36; } } @media only screen and (min-width: 1025px) { diff --git a/public/static/index/default/js/search.js b/public/static/index/default/js/search.js deleted file mode 100755 index 9638de5fe..000000000 --- a/public/static/index/default/js/search.js +++ /dev/null @@ -1,206 +0,0 @@ -/** - * 获取商品列表 - * @author Devil - * @blog http://gong.gg/ - * @version 1.0.0 - * @date 2021-01-08 - * @desc description - * @param {[int]} page [分页值] - */ -function GetGoodsList(page) -{ - // 清除条件显隐 - if($('.map-item>li>.map-right>ul>li.active').length > 0) - { - $('.map-remove-submit').removeClass('am-hide'); - } else { - $('.map-remove-submit').addClass('am-hide'); - } - - // 请求参数处理 - var data = { - "wd": $('#search-input').val() || '', - "category_id": $('.search-container').data('category-id') || 0, - "brand_id": $('.search-container').data('brand-id') || 0, - "page": page || parseInt($('.search-pages-submit').attr('data-page')) || 1, - "order_by_field": $('.sort-nav li.active').attr('data-field') || 'default', - "order_by_type": $('.sort-nav li.active').attr('data-type') == 'asc' ? 'desc' : 'asc', - }; - var index = 0; - $('.map-item>li>.map-right>ul>li.active').each(function(k, v) - { - var field = $(this).parents('.map-item>li').data('field') || null; - var value = $(this).data('value') || null; - if(field != null && value != null) - { - if((data[field] || null) == null) - { - data[field] = {}; - index = 0; - } - data[field][index] = value; - index++; - } - }); - - // 清空数据 - if(data.page == 1) - { - $('.search-list').html(''); - } - - // 页面提示处理 - $('.loding-view').show(); - $('.search-pages-submit').hide(); - $('.table-no').hide(); - - // 请求数据 - $.ajax({ - url: RequestUrlHandle($('.search-pages-submit').data('url')), - type: 'POST', - dataType: 'json', - timeout: 30000, - data: data, - success:function(result) - { - $('.loding-view').hide(); - if(result.code == 0) - { - $('.search-list').append(result.data.data); - $('.search-pages-submit').attr('data-page', data.page+1); - $('.search-pages-submit').attr('disabled', (result.data.page_total <= 1)); - $('.search-pages-submit').show(); - $('.table-no').hide(); - } else if(result.code == -100) { - if($('.search-list li').length == 0) - { - $('.table-no').show(); - $('.search-pages-submit').hide(); - } else { - $('.table-no').hide(); - $('.search-pages-submit').show(); - $('.search-pages-submit').attr('disabled', true); - } - Prompt(result.msg); - } else { - Prompt(result.msg); - } - - // 总数处理 - var total = result.data.total || 0; - if(total > 0 || $('.search-list li').length == 0) - { - $('.map-result-count').text(total); - } - }, - error:function(xhr, type) - { - $('.loding-view').hide(); - $('.search-pages-submit').hide(); - $('.table-no').show(); - Prompt(HtmlToString(xhr.responseText) || '异常错误', null, 30); - } - }); -} - -/** - * 更多条件展开处理 - * @author Devil - * @blog http://gong.gg/ - * @version 1.0.0 - * @date 2021-01-10 - * @desc description - */ -function MapMoreSubmitHandle() -{ - $('.map-images-text-items,.map-text-items').each(function(k, v) - { - var height = $(this).find('>ul').innerHeight(); - var max_height = $(this).hasClass('map-images-text-items') ? 66 : 56; - if(height > max_height) - { - $(this).find('.map-more-submit').removeClass('am-hide'); - } - }); -} - -$(function() -{ - // 更多条件展开处理 - MapMoreSubmitHandle(); - - // 默认加载数据 - GetGoodsList(1); - - // 手机模式下更多条件开启 - $(document).on('click', '.map-offcanvas-submit', function() - { - MapMoreSubmitHandle(); - }); - - // 筛选操作 - $(document).on('click', '.map-item>li>.map-right>ul>li', function() - { - if(!$(this).hasClass('disabled')) - { - if($(this).hasClass('active')) - { - $(this).removeClass('active'); - } else { - $(this).addClass('active'); - } - GetGoodsList(1); - } - }); - - // 清除条件 - $(document).on('click', '.map-remove-submit', function() - { - $('.map-item>li>.map-right>ul>li').removeClass('active'); - GetGoodsList(1); - }); - - // 条件展开/隐藏 - $(document).on('click', '.map-item .map-more-submit', function() - { - var $parents = $(this).parents('.map-right'); - var height = $parents.hasClass('map-images-text-items') ? '66px' : '56px'; - if($parents.css('height') == height) - { - $parents.css('height', 'auto'); - } else { - $parents.css('height', height); - } - }); - - // 排序 - $(document).on('click', '.sort-nav li', function() - { - var type = $(this).attr('data-type'); - $('.sort-nav li').attr('data-type', 'desc'); - $('.sort-nav li a i').removeClass('am-icon-long-arrow-up').addClass('am-icon-long-arrow-down'); - - if($(this).hasClass('active')) - { - if(type == 'asc') - { - $(this).attr('data-type', 'desc'); - $(this).find('a i').removeClass('am-icon-long-arrow-down').addClass('am-icon-long-arrow-up'); - } else { - $(this).attr('data-type', 'asc'); - $(this).find('a i').removeClass('am-icon-long-arrow-up').addClass('am-icon-long-arrow-down'); - } - } else { - $('.sort-nav li').removeClass('active'); - $(this).addClass('active'); - $(this).attr('data-type', 'asc'); - } - GetGoodsList(1); - }); - - // 加载更多数据 - $(document).on('click', '.search-pages-submit', function() - { - GetGoodsList(); - }); -}); \ No newline at end of file