浏览代码

店铺搜索合并代码

yangc 8 年之前
父节点
当前提交
3a3132a69e

+ 13 - 0
assets/scss/common.scss

@@ -626,3 +626,16 @@ a {
   cursor: pointer;
   transition: color .2s ease;
 }
+.select-adder {
+  background:url("../../static/images/all/xiala.png") right no-repeat #fff !important;
+  background-position-x: 100% !important;
+  /*将默认的select选择框样式清除*/
+  appearance:none;
+  -moz-appearance:none;
+  -webkit-appearance:none;
+  -ms-appearance:none;
+
+}
+.select-adder::-ms-expand {
+  display: none;
+}

+ 35 - 8
components/main/Search.vue

@@ -1,6 +1,10 @@
 <template>
   <div class="search-box">
     <div class="input-group">
+      <select @change="onSelectTypeChange" class="form-control select-type select-adder">
+        <option value="">产品</option>
+        <option value="">店铺</option>
+      </select>
       <input v-model="keyword" type="text" class="search-input form-control input-primary"
              placeholder="型号/类目/品牌"
              @focus.stop.prevent="onFocus()"
@@ -12,7 +16,7 @@
         <button class="btn btn-primary search-btn" type="button">搜&nbsp;索</button>
       </span>
     </div>
-    <ul class="association" v-show="showAssociate"
+    <ul class="association" v-show="showAssociate && searchType == 'product'"
         @mouseenter="associate.focus=true" @mouseleave="associate.focus=false">
       <li v-for="(k, index) in similarKeywords.data" :key="k" class="item"
           :class="{'active': index==associate.activeIndex}"
@@ -40,7 +44,8 @@
           show: false,
           activeIndex: null
         },
-        click_flag: false
+        click_flag: false,
+        searchType: 'product'
       }
     },
     computed: {
@@ -82,6 +87,14 @@
       }
     },
     methods: {
+      onSelectTypeChange: function (e) {
+        let type = e.target[e.target.selectedIndex].innerHTML
+        if (type === '产品') {
+          this.searchType = 'product'
+        } else if (type === '店铺') {
+          this.searchType = 'store'
+        }
+      },
       onFocus () {
         this.associate.show = true
       },
@@ -126,7 +139,11 @@
         if (this.keyword) {
           this.associate.show = false
           this.$store.dispatch('resetSearchKeywords')
-          this.$router.push({path: '/search?w=' + encodeURIComponent(this.keyword)})
+          if (this.searchType === 'product') {
+            this.$router.push({path: '/search?w=' + encodeURIComponent(this.keyword)})
+          } else if (this.searchType === 'store') {
+            this.$router.push({path: '/searchStore?w=' + encodeURIComponent(this.keyword)})
+          }
         }
       },
       onAssociateClick (word) {
@@ -146,18 +163,28 @@
     border-radius: 0;
   }
   .search-box {
-    width: 470px;
+    width: 520px;
     height: 40px;
     position: relative;
-
+    .search-input{
+      width: 372px;
+      float: left;
+    }
     .search-input, .search-btn {
       height: 40px;
       border-width: 2px;
     }
-
+    .select-type{
+      width: 70px;
+      float: left;
+      border: #5078cb 2px solid;
+      height: 40px;
+      border-right: none;
+      margin-right: -1px;
+    }
     .search-btn {
       font-size: 16px;
-      width: 78px;
+      width: 79px;
       border-radius: 0;
     }
     .search-hot ul li a{
@@ -177,7 +204,7 @@
 
     .association {
       position: absolute;
-      left: 0;
+      left: 78px;
       top: 100%;
       right: 79px;
       background: $white;

+ 179 - 0
components/searchStore/SearchTitle.vue

@@ -0,0 +1,179 @@
+<template>
+  <div class="search-store-title">
+    <span class="search-result">
+      搜索 "
+      <span style="color: #ff0101">{{keyword}}</span>
+      ",为您找到
+      <span v-text="goodsCount">1000</span>
+      家店铺:
+    </span>
+    <div class="tab-filter" >
+      <div class="fr">
+        <div :class="activeType == 0?'active':''" @click="defaultSearch"><a >综合排序</a></div>
+        <!--<div :class="activeType == 1?'active':''"><a >库存</a></div>-->
+        <!--<div :class="activeType == 2?'active':''"><a >销量</a></div>-->
+        <!--<div :class="activeType == 3?'active':''"><a >信用</a></div>-->
+        <div :class="activeType == 4?'active':''">
+          <select @change="onSelectTypeChange" class="form-control select-type select-adder">
+            <option value="">店铺类型</option>
+            <option value="">原厂</option>
+            <option value="">代理</option>
+            <option value="">经销</option>
+            <!--<option value="">寄售</option>-->
+          </select>
+        </div>
+        <!--<div class=""><a >所在地</a></div>-->
+    </div>
+      <div class="off">
+        <a @click="showClick">
+          <span v-text="show?'收起':'展开'" style="margin-right: 10px;"></span>
+          <i v-show="!show" class="fa fa-angle-down"></i>
+          <i v-show="show" class="fa fa-angle-up"></i>
+        </a>
+      </div>
+  </div>
+  </div>
+</template>
+<script>
+  export default {
+    props: ['keyword'],
+    data () {
+      return {
+        activeType: 0,
+        paramType: 'AGENCY-DISTRIBUTION-ORIGINAL_FACTORY-CONSIGNMENT',
+        show: true
+      }
+    },
+    computed: {
+      goodsCount () {
+        if (this.$store.state.searchStore.searchStoreDetail.detail.data[0].stores) {
+          return this.$store.state.searchStore.searchStoreDetail.detail.data[0].stores.totalElements || 0
+        } else {
+          return 0
+        }
+      }
+    },
+    methods: {
+      defaultSearch: function () {
+        this.activeType = 0
+        this.paramType = 'AGENCY-DISTRIBUTION-ORIGINAL_FACTORY'
+        this.$store.dispatch('searchStore/searchStoreDetail',
+          {
+            page: 1,
+            count: 4,
+            keyword: this.$route.query.w,
+            types: this.paramType,
+            op: 'pageByType'})
+      },
+      onSelectTypeChange: function (e) {
+        let type = e.target[e.target.selectedIndex].innerHTML
+        if (type === '原厂') {
+          this.paramType = 'ORIGINAL_FACTORY'
+        } else if (type === '代理') {
+          this.paramType = 'AGENCY'
+        } else if (type === '经销') {
+          this.paramType = 'DISTRIBUTION'
+        } else if (type === '店铺类型') {
+          this.paramType = 'AGENCY-DISTRIBUTION-ORIGINAL_FACTORY'
+        }
+        this.$emit('typeAction', this.paramType)
+        this.$store.dispatch('searchStore/searchStoreDetail',
+          {
+            page: 1,
+            count: 4,
+            keyword: this.$route.query.w,
+            types: this.paramType,
+            op: 'pageByType'})
+        this.activeType = 4
+      },
+      showClick: function () {
+        this.show = !this.show
+        this.$emit('showAction', this.show)
+      }
+    }
+  }
+</script>
+<style>
+  .search-store-title {
+    margin-top: 22px;
+  }
+  .search-store-title .select-type {
+    min-width: 87px;
+  }
+  .tab-filter{
+    width: 1190px;
+    height: 40px;
+    margin-top: 14px;
+    line-height: 40px;
+    background: #f4f8ff;
+    border: 1px solid rgb( 231, 231, 231 );
+    border-bottom: none;
+  }
+  .tab-filter .fl,.tab-filter .fr{
+    float: left;
+  }
+  .tab-filter .fl{
+    font-size: 14px;
+  }
+  .tab-filter .fr{
+    max-width: 1050px;
+    margin-left: 10px;
+  }
+  .tab-filter .fl span{
+    font-size: 14px;
+  }
+  .tab-filter .fr div{
+    float: left;
+    margin-right: 10px;
+  }
+  .tab-filter .fr div.active a, .tab-filter .fr div.active select{
+    border: #5078cb 1px solid;
+    color: #5078cb;
+  }
+  .tab-filter .fr div.active select option {
+    color: #000;
+  }
+  .tab-filter .fr a{
+    display: inline-block;
+    padding: 0 10px;
+    border: #ccc 1px solid;
+    line-height: 30px;
+    font-size: 14px;
+    text-align: center;
+    color: #333;
+    height: 30px;
+    background: #fff;
+  }
+  .tab-filter .fr a i{
+    /*margin-left: 5px;*/
+  }
+  .tab-filter .fr a:hover{
+    border: #5078cb 1px solid;
+    color: #5078cb;
+  }
+  .tab-filter .off{
+    float: right;
+    margin-right: 20px;
+    color: black;
+  }
+  .tab-filter .off a:hover{
+    border: none;
+    color: #5078cb;
+  }
+  .tab-filter .off a{
+    border: none;
+    text-align: right;
+    background: none;
+    color: #333;
+  }
+  .tab-filter .off a i{
+    font-size: 16px;
+  }
+  .tab-filter .fr .form-control{
+    width: 85px;
+    height: 30px;
+    line-height: 30px;
+    border-radius: 0;
+    padding: 0 5px;
+  }
+</style>

+ 313 - 0
components/searchStore/StoreContent.vue

@@ -0,0 +1,313 @@
+<template>
+  <div>
+  <ul class="store-list" v-if="storeData.content && storeData.content.length > 0">
+    <li v-for="(store, index) in storeData.content">
+      <div class="store-content-left">
+        <a :href="'/store/' + store.uuid" target="_blank">
+          <img :src="store.logoUrl?store.logoUrl:'/images/all/default.png'" class="storeImg" alt="">
+        </a>
+        <div class="store-detail">
+          <a :href="'/store/' + store.uuid" target="_blank" :title="store.storeName">{{store.storeName}}</a>
+          <span style="position: relative;" class="call-seller">
+            <img src="static/img/common/songguo.png?_v=1503050008623">
+							<a name="21059" href="javascript:void(0)" class="contact_btn">联系卖家</a>
+          </span>
+          <span class="main-product">
+             <a :href="'/store/' + store.uuid" target="_blank" v-text="'店铺简介:' + store.description"></a>
+          </span>
+        </div>
+        <div class="component-count">
+          <span style="margin-right: 30px">销量:<span v-text="salesData[index]"></span></span>
+          <span>库存量:<span v-text="store.totalReserve"></span></span>
+        </div>
+        <div class="btn-content">
+          <a class="focus-store store-btn" @click="focusStore(store, index)" v-text="focusData[index] === 'true'?'已关注':'关注店铺'"></a>
+          <a :href="'/store/' + store.uuid" target="_blank" class="enter-store store-btn">进入店铺</a>
+        </div>
+      </div>
+      <ul class="store-component-list" v-if="componentData">
+        <li v-for="(item, index2) in componentData[index].content" @click="goStore(index, index2)">
+          <!--<a :href="`/product/component/${item.uuid}`" style="display: block"><img :src="item.img?item.img:'/images/all/default.png'" alt=""></a>
+          <div class="describe-list">
+            <a style="margin-bottom: 8px" :href="`/product/component/${item.uuid}`" class="store-component-code" v-text="item.code" :title="item.code"></a>
+            <a style="margin-bottom: 8px" :href="`/product/brand/${item.branduuid}`" v-text="item.brandNameEn"></a>
+            <a :href="`/product/kind/${item.kindUuid}`" v-text="item.kindNameCn"></a>
+          </div>-->
+          <a style="display: block"><img :src="item.img?item.img:'/images/all/default.png'" alt=""></a>
+          <div class="describe-list">
+            <a class="store-component-code" v-text="item.code" :title="item.code"></a>
+            <a v-text="item.brandNameEn" :title="item.brandNameEn"></a>
+            <a v-text="item.kindNameCn" :title="item.kindNameCn"></a>
+          </div>
+        </li>
+      </ul>
+    </li>
+  </ul>
+    <page :total="storeData.totalElements" :page-size="pageSize"
+          :current="nowPage" v-on:childEvent="listenPage"></page>
+    <el-dialog
+      :visible.sync="dialogVisible"
+      size="tiny"
+    >
+      <h3 class="header-text">关注成功!</h3>
+      <div class="focus modal-body">
+        <button type="button" @click="dialogVisible = false" class="btn" style="margin-left:25px;">关&nbsp;&nbsp;闭</button>
+        <button type="button" @click="dialogVisible = false" class="focus-btn btn btn btn-info" style="margin-left:35px;">
+          <a href="/user#/storeFocus" target="_blank">查看我的店铺关注</a>
+        </button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+<script>
+  import Page from '~components/common/page/pageComponent.vue'
+  export default {
+    data () {
+      return {
+        dialogVisible: false,
+        pageSize: 8,
+        nowPage: 1
+      }
+    },
+    components: {
+      Page
+    },
+    computed: {
+      user () {
+        return this.$store.state.option.user
+      },
+      storeDetail () {
+        return this.$store.state.searchStore.searchStoreDetail.detail.data
+      },
+      storeData () {
+        return this.storeDetail[0].stores
+      },
+      focusData () {
+        return this.storeDetail[1].isFocus
+      },
+      componentData () {
+        return this.storeDetail[1].image
+      },
+      salesData () {
+        return this.storeDetail[1].sales
+      }
+    },
+    methods: {
+      focusStore: function (store, index) {
+        if (!this.user.logged) {
+          this.$http.get('/login/page').then(response => {
+            if (response.data) {
+              this.$router.push('/auth/login')
+            }
+          })
+        } else {
+          if (this.focusData[index] === 'true') {
+            // 已关注
+            this.$message.error('店铺已关注,不能重复关注')
+          } else {
+            // 未关注
+            this.$http.post('/trade/storeFocus/save', {storeName: store.storeName, storeid: store.id})
+              .then(response => {
+                if (response.data === 'success') {
+                  // 关注成功
+                  this.dialogVisible = true
+                  this.focusData[index] = 'true'
+                } else {
+                  // 关注失败
+                  this.$message.error('关注失败')
+                }
+              })
+          }
+        }
+      },
+      listenPage: function (page) {
+        this.$emit('pageAction', page)
+      },
+      goStore: function (index, compIndex) {
+        window.open('/product/component/' + this.componentData[index].content[compIndex].uuid)
+      }
+    }
+  }
+</script>
+<style scoped>
+  .store-list {
+    border-right: 1px solid rgb( 231, 231, 231 );
+    border-left: 1px solid rgb( 231, 231, 231 );
+  }
+  .store-list >li{
+    border-bottom: 1px solid rgb( 231, 231, 231 );
+    padding: 20px 0;
+  }
+  .store-content-left {
+    display: inline-block;
+    margin-right: 27px;
+  }
+  .store-content-left .component-count{
+    display: block;
+    margin-left: 10px;
+    margin-top: 20px;
+  }
+  .store-content-left >div {
+    display: inline-block;
+  }
+  .store-content-left >a {
+    color: black;
+    float: left;
+    width: 100px;
+    height: 100px;
+    line-height: 100px;
+    display: inline-block;
+    border: 1px solid rgb( 231, 231, 231 );
+    overflow: hidden;
+    margin-left: 10px;
+  }
+  .store-content-left >a >img.storeImg {
+    max-width: 100px;
+    max-height: 100px;
+  }
+  .btn-content {
+    display: block!important;
+    margin-top: 20px;
+  }
+  .btn-content >span {
+    display: block;
+  }
+  .btn-content >span:hover {
+    cursor: pointer;
+  }
+  .store-detail {
+    margin-left: 20px;
+  }
+  .store-detail >a {
+    font-size: 14px;
+    font-weight: 700;
+    color: black;
+    display: block;
+    overflow: hidden;
+    width: 175px;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+  }
+  .store-detail >span{
+    display: block;
+    font-size: 12px;
+    width: 190px;
+  }
+  .store-detail .call-seller {
+    margin-top: 14px;
+  }
+  .store-detail .call-seller .contact_btn {
+    width: 62px;
+    height: 18px;
+    line-height: 18px;
+    background: #ef7f03;
+    display: inline-block;
+    text-align: center;
+    color: #fff;
+    font-size: 12px;
+    border-radius: 5px;
+    margin-left: 5px;
+  }
+  .store-detail .main-product {
+    margin-top: 12px;
+  }
+  .store-detail .main-product a:hover {
+    cursor: pointer;
+    color: #5078cb!important;
+  }
+  .store-detail .main-product a {
+    color: #333;
+    width: 126px;
+    display: inline-block;
+    float: left;
+    overflow: hidden;
+    word-break: break-all;
+    height: 35px;
+    line-height: 16px;
+    text-overflow: ellipsis;
+    /*-webkit-line-clamp: 2;
+    -moz-line-clamp: 2;
+    -o-line-clamp: 2;
+    -ms-line-clamp: 2;
+    -webkit-box-orient: vertical;
+    -moz-box-orient: vertical;
+    -o-box-orient: vertical;
+    -ms-box-orient: vertical;*/
+  }
+  .btn-content .store-btn {
+    padding: 4px 14px;
+    color: white;
+    display: inline-block;
+  }
+  .btn-content .focus-store {
+    margin-right: 30px;
+    margin-left: 10px;
+    background: #5078cb;
+    border: 1px solid #5078cb;
+  }
+  .btn-content .enter-store {
+    background: #ff8522;
+    border: 1px solid #ff8522;
+  }
+  .store-component-list {
+    display: inline-block;
+    margin-right: 6px;
+    width: 834px;
+    float: right;
+  }
+  .store-component-list >li {
+    display: inline-block;
+    text-align: center;
+    border: 1px solid rgb( 231, 231, 231 );
+    margin-right: 14px;
+    width: 152px;
+    height: 178px;
+  }
+  .store-component-list >li:hover {
+    cursor: pointer;
+    color: #fff!important;
+    border: 1px solid #5078cb;
+  }
+  .store-component-list >li:hover .describe-list {
+    background: #5078cb;
+  }
+  .store-component-list >li:hover div a {
+    color: #fff;
+  }
+  .store-component-list >li img {
+    width: 149px;
+    height:114px;
+  }
+  .store-component-list >li .describe-list {
+    padding: 2px 10px;
+    background: #dee0e5;
+    height: 64px;
+  }
+  .store-component-list >li div a {
+    display: block;
+    font-size: 14px;
+    text-align: left;
+    color: #333;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    line-height: 20px;
+    white-space: nowrap;
+  }
+ /* .store-component-list >li a:hover {
+    color: #f39801;
+  }*/
+  /*.store-component-list .store-component-code {
+  }*/
+  .header-text {
+    text-align: center;
+    font-size: 20px;
+    color: #008B00;
+    margin-top: 0;
+  }
+  .el-dialog__body{
+    padding: 20px !important;
+  }
+  .focus button.focus-btn a{
+    color: #fff;
+  }
+</style>

+ 4 - 0
components/searchStore/index.js

@@ -0,0 +1,4 @@
+import SearchTitle from './SearchTitle.vue'
+import StoreContent from './StoreContent.vue'
+
+export { SearchTitle, StoreContent }

+ 40 - 0
pages/searchStore/_keyword.vue

@@ -0,0 +1,40 @@
+<template>
+  <div class="container" id="searchResult">
+    <search-title :keyword="key" @showAction="showAction" @typeAction="onTypeChanged"></search-title>
+    <store-content v-show="show" @pageAction="onPageChanged"></store-content>
+  </div>
+</template>
+<script>
+  import { SearchTitle, StoreContent } from '~components/searchStore'
+  export default {
+    layout: 'main',
+    components: {
+      SearchTitle,
+      StoreContent
+    },
+    data () {
+      return {
+        key: this.$route.query.w,
+        show: true,
+        type: 'AGENCY-DISTRIBUTION-ORIGINAL_FACTORY'
+      }
+    },
+    fetch ({store, route}) {
+      return Promise.all([
+        store.dispatch('searchStore/searchStoreDetail', {page: 1, count: 8, keyword: route.query.w, types: 'AGENCY-DISTRIBUTION-ORIGINAL_FACTORY', op: 'pageByType'})
+      ])
+    },
+    methods: {
+      showAction: function (show) {
+        this.show = show
+      },
+      onPageChanged: function (page) {
+        this.$store.dispatch('searchStore/searchStoreDetail', {page: page, count: 8, keyword: this.$route.query.w, types: this.type, op: 'pageByType'})
+      },
+      onTypeChanged: function (type) {
+        this.type = type
+      }
+    }
+  }
+</script>
+

二进制
static/images/all/xiala.png


+ 15 - 0
store/searchStore.js

@@ -0,0 +1,15 @@
+import axios from '~plugins/axios'
+
+export const actions = {
+  // 获取搜索店铺数据
+  searchStoreDetail ({ commit }, params = {}) {
+    commit('searchStoreDetail/REQUEST_STORE', params)
+    return axios.get(`/search/stores`, {params})
+      .then(response => {
+        commit('searchStoreDetail/GET_STORE_SUCCESS', response.data)
+      }, err => {
+        commit('searchStoreDetail/GET_STORE_FAILURE', err)
+      })
+  }
+}
+

+ 19 - 0
store/searchStore/searchStoreDetail.js

@@ -0,0 +1,19 @@
+export const state = () => ({
+  detail: {
+    fetching: false,
+    data: []
+  }
+})
+
+export const mutations = {
+  REQUEST_STORE (state) {
+    state.detail.fetching = true
+  },
+  GET_STORE_FAILURE (state) {
+    state.detail.fetching = false
+  },
+  GET_STORE_SUCCESS (state, result) {
+    state.detail.fetching = false
+    state.detail.data = result
+  }
+}