浏览代码

pcd代码添加

yangc 7 年之前
父节点
当前提交
9c4632387a

+ 28 - 0
components/pcb/Nav.vue

@@ -0,0 +1,28 @@
+<template>
+  <div class="pcb-nav">
+    <span>
+      <a href="">pcb商城</a>
+    </span>
+    <span>
+      <i class="iconfont icon-arrow-right"></i><a href="">半固化片</a>
+    </span>
+    <span><i class="iconfont icon-arrow-right"></i><span>sdfkljalsfjasld</span></span>
+  </div>
+</template>
+<style lang="scss" scoped>
+  .pcb-nav {
+    width: 1190px;
+    margin: 18px auto 0;
+    height: 30px;
+    line-height: 30px;
+    font-size: 12px;
+    > span {
+      a {
+        color: #418cf6;
+      }
+      span {
+        color: #999;
+      }
+    }
+  }
+</style>

+ 208 - 0
components/pcb/PcbNavSearch.vue

@@ -0,0 +1,208 @@
+<template>
+  <div class="input-group">
+    <input v-model="keyword" type="text" class="search-input form-control"
+           @focus.stop.prevent="onFocus()"
+           @blur.stop.prevent="onBlur()"
+           @keyup.40="onSelectChange(1)"
+           @keyup.38="onSelectChange(-1)"
+           @keyup.13="onSearch()"/>
+    <span @click="onSearch()">
+          <button class="btn search-btn" type="button"><span class="glyphicon glyphicon-search" aria-hidden="true"></span> </button>
+       </span>
+    <div class="angle"></div>
+    <a class="close" @click="close"><img src="/images/search/search-close.png"></a>
+    <ul class="association" v-show="showAssociate">
+      <li v-for="(k, index) in similarKeywords.data" class="item"
+          :class="{'active': index==associate.activeIndex}"
+          @click.stop.prevent="onAssociateClick(k)">{{ k }}
+      </li>
+    </ul>
+  </div>
+</template>
+<script>
+  export default {
+    name: 'search',
+    data () {
+      return {
+        keyword: '',
+        inputValue: '',
+        select: 'product',
+        searchType: 'product',
+        associate: {
+          show: false,
+          activeIndex: null
+        }
+      }
+    },
+    computed: {
+      similarKeywords () {
+        return this.$store.state.search.keywords
+      },
+      showAssociate () {
+        return this.associate.show && this.similarKeywords.data && this.similarKeywords.data.length
+      },
+      floors () {
+        return this.$store.state.floor.list.data
+      },
+      bgUrl () {
+        return this.background && this.background !== '' ? this.background : this.floors[1].items[0].pictureUrl
+      }
+    },
+    watch: {
+      'keyword': {
+        handler (val, oldVal) {
+          let keywords = this.similarKeywords.data
+          if (!keywords || !keywords.length || this.associate.activeIndex === null || val !== keywords[this.associate.activeIndex]) {
+            this.onChange()
+          }
+        }
+      }
+    },
+    methods: {
+      close: function () {
+        this.keyword = ''
+      },
+      onFocus () {
+        this.associate.show = true
+      },
+      onBlur () {
+        this.associate.show = false
+      },
+      onSelectChange (count) {
+        let keywords = this.similarKeywords.data
+        if (keywords && keywords.length) {
+          let index = this.associate.activeIndex
+          if (index === null) {
+            index = -1
+          }
+          index += count
+          if (index >= keywords.length) {
+            index = 0
+          } else if (index < 0) {
+            index = keywords.length - 1
+          }
+          this.associate.activeIndex = index
+          this.keyword = keywords[index]
+        }
+      },
+      onChange () {
+        this.associate.activeIndex = null
+        if (!this.keyword) {
+          this.associate.show = false
+          this.$store.dispatch('resetSearchKeywords')
+        } else {
+          this.searchKeywords()
+        }
+      },
+      searchKeywords () {
+        this.associate.show = true
+        this.$store.dispatch('searchKeywords', { keyword: this.keyword })
+      },
+      onSearch () {
+        document.getElementsByClassName('search-input')[0].blur()
+        if (this.keyword) {
+          this.associate.show = false
+          this.$store.dispatch('resetSearchKeywords')
+          this.$router.push({path: '/pcb/search?w=' + encodeURIComponent(this.keyword)})
+        }
+      },
+      onAssociateClick (word) {
+        this.keyword = word
+        this.onSearch()
+      }
+    }
+  }
+</script>
+<style lang="scss" scoped>
+  @import '~assets/scss/variables';
+  .input-group {
+    width: 540px;
+    position: relative;
+  }
+  .select {
+    font-size: 16px;
+    color: #333;
+    width: 70px;
+    height: 30px;
+    border-radius: 25px 0 0 25px;
+    border: 1px solid #fff;
+    float: left;
+    padding-left: 2%;
+    line-height: 30px;
+  }
+  .close {
+    position: absolute;
+    top: 3px;
+    right: 55px;
+    z-index: 1000;
+    color: #000;
+  }
+  .angle {
+    position: absolute;
+    top: 13px;
+    left: 52px;
+    width: 0;
+    height: 0;
+    border-left: 5px solid transparent;
+    border-right: 5px solid transparent;
+    border-top: 5px solid #3c7cf5;
+    &:after{
+      content:'';
+      position: relative;
+      display: block;
+      width: 3px;
+      height: 24px;
+      top: -15px;
+      left: 9px;
+      border-right: 2px solid #3c7cf5;
+    }
+  }
+  .search-input {
+    font-size: 16px;
+    height: 30px;
+    border-radius: 25px 0 0 25px;
+    width: 488px !important;
+    border: 1px solid #fff;
+    padding-right: 25px;
+  }
+  .btn:focus,.btn:active:focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn.active.focus {
+    outline: none;
+    border-color: transparent;
+    box-shadow:none;
+  }
+  .search-btn {
+    height: 30px;
+    font-size: 22px;
+    width: 50px;
+    margin-left: 0;
+    background: #fff;
+    border: 1px solid #fff;
+    border-radius: 0 25px 25px 0;
+  }
+  .glyphicon-search{
+    color: #3c7cf5;
+  }
+  .association {
+    position: absolute;
+    background: $white;
+    border: $border;
+    border-top-width: 0;
+    z-index: 21;
+    width: 606px;
+    top: 214px;
+    left: 2px;
+    .item {
+      padding: 0 15px;
+      line-height: 30px;
+      cursor: pointer;
+      text-align: left;
+
+      &.active {
+        background-color: $dark-bg;
+      }
+      &:hover {
+        background-color: $grey-bg;
+      }
+    }
+  }
+</style>

+ 267 - 0
components/pcb/brand/BrandList.vue

@@ -0,0 +1,267 @@
+<template>
+  <div class="component-list container">
+    <nuxt-link to="/product/brand/_code"><div class="type-list">产品列表</div></nuxt-link>
+    <div class="input-group">
+      <input  type="search" class="input-sm form-control" placeholder="请输入型号" title="code"
+              v-model="searchCode" @search="goodsSearch(searchCode)"/>
+      <span class="input-group-btn">
+					<button class="search btn btn-default" type="button" @click="goodsSearch(searchCode)">搜索</button>
+			</span>
+    </div>
+    <table class="table">
+      <thead>
+      <tr class="bgf7">
+        <th width="330">产品名称</th>
+        <th width="330">价格</th>
+        <th width="330">操作</th>
+      </tr>
+      </thead>
+      <tbody>
+      <tr class="text-center" v-for="item in list.content">
+        <td><nuxt-link :to="`/pcb/product/${item.productid}/${item.batchCode}`"><span>{{item.code}}</span></nuxt-link></td>
+        <td>
+          <div v-if="item.prices" v-text="item.currencyName === 'RMB' ? '¥' + item.prices[0].rMBPrice : '$' + item.prices[0].uSDPrice"></div>
+          <div v-else>-</div>
+        </td>
+        <!--<td><a :href="item.attach" target="_blank"><button class="btn btn-default"  :disabled="!item.attach" :class="{'disabledbtn':!item.attach}">Datasheet手册</button></a></td>-->
+        <td>
+          <button class="btn btn-default applay" @click="addToCar(item)">加入购物车</button>
+        </td>
+      </tr>
+      <tr v-if="!list.content || list.content.length === 0">
+        <td colspan="10" class="text-center">
+          <div class="empty">
+            <div class="empty-img">
+              <img src="/images/brandList/empty-cart.png">
+            </div>
+            <div class="empty-info">
+              <p class="grey f16"> 暂无器件信息 </p>
+              <i class="fa fa-mail-reply fa-xs"></i>&nbsp;<a href="javascript:history.go(-1)">返回上一页</a>
+            </div>
+          </div>
+        </td>
+      </tr>
+      </tbody>
+    </table>
+    <div style="float: right;">
+      <page :total="list.totalElements" :page-size="pageParams.count"
+            :current="pageParams.page" @childEvent="handleCurrentChange"></page>
+    </div>
+  </div>
+</template>
+<script>
+  import Page from '~components/common/page/pageComponent.vue'
+  import { buyOrCar } from '~utils/baseUtils'
+  export default {
+    name: 'BrandComponent',
+    data () {
+      return {
+        pageParams: {
+          page: 1,
+          count: 10,
+          filter: {}
+        },
+        searchCode: ''
+      }
+    },
+    props: ['kindid'],
+    components: {
+      Page
+    },
+    computed: {
+      lists () {
+        return this.$store.state.brandComponent.component
+      },
+      list () {
+        return this.lists.data
+      },
+      brand () {
+        return this.$store.state.brandDetail.detail.data
+      }
+    },
+    methods: {
+      goodsSearch (keyword) {
+        this.pageParams.page = 1
+        this.pageParams.filter.code = keyword
+        this.pageCmpGoods(this.pageParams)
+      },
+      handlerCurrentNode () {
+        this.searchCode = ''
+        this.pageParams.page = 1
+        this.pageCmpGoods(this.pageParams)
+      },
+      async pageCmpGoods (params) {
+//      pageCmpGoods (params) {
+//        params.filter.brandid = this.brand.id
+        let param = {
+          branduuid: this.brand.uuid,
+          count: this.pageParams.count,
+          page: this.pageParams.page,
+          kindid: this.kindid,
+          keyword: this.searchCode || null
+        }
+        let { data } = await this.$http.get('/api/product/goods', {params: param})
+        this.$store.commit('brandComponent/GET_COMPONENT_SUCCESS', data)
+//        this.$http.get('/api/product/component/list', { params }).then(response => {
+//          this.$store.commit('brandComponent/GET_COMPONENT_SUCCESS', response)
+//        })
+      },
+      handleCurrentChange (page) {
+        this.pageParams.page = page
+        this.pageParams.filter.brandid = this.brand.id
+        this.pageCmpGoods(this.pageParams)
+      },
+      toAttach: function (url) {
+        if (url === '1') {
+          this.$http.get('/login/page', {params: {returnUrl: window.location.href}}).then(response => {
+            if (response.data) {
+              window.location.href = response.data.content + '&baseUrl=' + encodeURIComponent(window.location.protocol + '//' + window.location.host + response.data.baseUrl)
+            }
+          })
+        } else {
+          window.open(url)
+        }
+      },
+      addToCar: function (item) {
+        buyOrCar(false, null, this, item)
+      }
+    }
+  }
+</script>
+<style lang="scss" scoped>
+  .component-list {
+    float: left;
+    margin-left: 20px;
+    width: 970px;
+    .type-list{
+      height: 34px;
+      width: 150px;
+      border: 1px solid #3a75f5;
+      background-color: #3a75f5;
+      float: left;
+      color: #fff;
+      line-height: 34px;
+      text-align: center;
+      font-size: 14px;
+    }
+    .agency {
+      height: 34px;
+      width: 150px;
+      border: 1px solid #3a75f5;
+      background-color: #fff;
+      float: left;
+      color: #3a75f5;
+      line-height: 34px;
+      text-align: center;
+      font-size: 14px;
+    }
+    .input-group {
+      width: 300px;
+      float: right;
+      border-radius: 3px;
+      .form-control{
+        border-radius: 3px;
+        height: 34px;
+      }
+      .input-group-btn .search{
+        background: #3a75f5;
+        color: #fff;
+        height: 34px;
+        border-radius: 3px;
+        padding: 3px 24px;
+      }
+    }
+  }
+
+  .component-list table {
+    margin-top: 10px;
+    width: 970px;
+    border: 1px solid #e8e8e8;
+  }
+  .component-list table>thead {
+    height: 40px;
+  }
+  .component-list table>thead>th {
+    text-align: center;
+  }
+  .component-list table tbody tr{
+    text-align: center;
+    height: 60px;
+  }
+  .component-list table tbody tr:hover{
+    background-color: #f6f9ff;
+  }
+  .component-list .table>tbody>tr>td{
+    vertical-align: middle;
+    border-top: #e8e8e8 1px solid;
+  }
+  .component-list table tbody tr td a{
+    color: #333;
+    font-size: 14px;
+    &:hover{
+      color: #5078cb;
+    }
+  }
+  .component-list .btn-default {
+    color: #214797;
+    font-size: 12px;
+    line-height: 12px;
+    height: 30px;
+  }
+  .component-list .disabledbtn {
+    color: #A0A0A0;
+  }
+  .component-list .applay {
+    color: #3a75f5;
+    font-size: 12px;
+    line-height: 12px;
+    height: 30px;
+    width: 80px;
+    padding: 0;
+    border: 1px solid #3a75f5;
+    border-radius: 0;
+  }
+  .component-list td.text-center{
+    padding: 30px 0;
+    font-size: 20px;
+    line-height: 40px;
+  }
+  .bgf7{
+    height: 40px;
+    th{
+      background: #f7f7f7;
+      border-bottom: none !important;
+      font-size: 14px;
+      text-align: center;
+      color: #333;
+      vertical-align: middle;
+    }
+  }
+  .component-list .empty{
+    overflow: hidden;
+    text-align: center;
+    margin: 0 auto;
+  }
+  .component-list .empty-img{
+    float: left;
+    margin-left: 335px;
+  }
+  .component-list .empty-info{
+    float: left;
+    line-height: 10px;
+    width: 143px;
+    margin-top: 30px;
+  }
+  .empty-info .grey{
+    color: #999;
+    font-size: 14px;
+  }
+  .component-list .empty-info a{
+    font-size: 14px;
+    color: #5078cb;
+  }
+  .component-list .empty-info i{
+    font-size: 14px;
+    color: #5078cb;
+  }
+</style>

+ 93 - 0
components/pcb/home/Intro.vue

@@ -0,0 +1,93 @@
+<template>
+  <div class="pcb-intro">
+    <p class="intro-title">PCB商家介绍<span>PCB Business Introduction</span></p>
+    <div class="item name">
+      <a href="">
+        <img src="/images/pcb/test-logo.png" alt="">
+      </a>
+      <p>深圳市英唐致盈供应链管理有限公司</p>
+    </div>
+    <div class="item intro">
+      深圳市英唐致盈供应链管理有限公司经营范围: 供应链管理及其相关的信息咨询;受托资产管理(不含证券、保险、基金、金融业务及其它限制项目);企业管理咨询(不含人才中介服务);经营电子商务(涉及前置行政许可的,须取得前置性行政许可文件后方可经营);国内贸易、货物及技术进出口。
+    </div>
+  </div>
+</template>
+<style lang="scss" scoped>
+  .pcb-intro {
+    background: url('/images/pcb/intro-bg.png') no-repeat;
+    background-size: cover;
+    margin-top: 58px;
+    height: 274px;
+    text-align: center;
+    .intro-title {
+      height: 68px;
+      line-height: 68px;
+      font-size: 30px;
+      text-align: center;
+      font-weight: bold;
+      span {
+        margin-left: 10px;
+        font-size: 12px;
+      }
+    }
+    .item {
+      display: inline-block;
+      height: 157px;
+      vertical-align: middle;
+    }
+    .name {
+      width: 183px;
+      margin-right: 63px;
+      margin-top: 14px;
+      a {
+        width: 183px;
+        height: 94px;
+        line-height: 88px;
+        background: #fff;
+        border-radius: 3px;
+        border: 2px solid #d8c7b3;
+        display: block;
+        img {
+          max-width: 183px;
+          max-height: 88px;
+        }
+      }
+      p {
+        font-size: 18px;
+        font-weight: bold;
+        margin-top: 26px;
+      }
+    }
+    .intro {
+      position: relative;
+      width: 842px;
+      background: #fff;
+      /*-webkit-box-shadow: 0 0 10px 3px #dacab6;
+      -moz-box-shadow: 0 0 10px 3px #dacab6;
+      box-shadow: 0 0 10px 3px #dacab6;*/
+      padding: 24px 18px 20px 25px;
+      text-align: left;
+      line-height: 25px;
+      &::before {
+        content: '';
+        position: absolute;
+        border: {
+          top: 34px solid #f0e7de;
+          right: 34px solid transparent;
+        };
+        left: 0;
+        top: 0;
+      }
+      &::after {
+        content: '';
+        position: absolute;
+        border: {
+          right: 34px solid #fbf9f7;
+          top: 34px solid transparent;
+        };
+        right: 0;
+        bottom: 0;
+      }
+    }
+  }
+</style>

+ 53 - 0
components/pcb/home/Kinds.vue

@@ -0,0 +1,53 @@
+<template>
+  <div class="pcb-kinds">
+    <ul class="pk-list">
+      <li class="pk-item" v-for="kind in kinds">
+        <nuxt-link :to="`/pcb/search/?w=${kind.nameCn}`">{{kind.nameCn}}<i class="icon-arrow-right iconfont"></i></nuxt-link>
+      </li>
+    </ul>
+    <img class="fr" src="/images/pcb/banner.png" alt="">
+  </div>
+</template>
+<script>
+  export default {
+    computed: {
+      kinds () {
+        return this.$store.state.pcb.kindsData.kinds.data
+      }
+    }
+  }
+</script>
+<style lang="scss" scoped>
+  $height: 300px;
+    .pcb-kinds {
+      width: 1184px;
+      margin: 1px auto 0;
+      .pk-list {
+        width: 230px;
+        height: $height;
+        overflow-y: hidden;
+        border-radius: 4px;
+        border: 1px solid #376ff3;
+        margin-right: 2px;
+        display: inline-block;
+        .pk-item {
+          height: 50px;
+          line-height: 50px;
+          border-bottom: 1px solid rgba(153, 153, 153, .32);
+          text-align: center;
+          a {
+            color: #666;
+          }
+          .iconfont {
+            float: right;
+            margin-right: 18px;
+          }
+        }
+      }
+      .fr {
+        width: 952px;
+        height: $height;
+        border-radius: 4px;
+      }
+    }
+</style>

+ 86 - 0
components/pcb/home/RecommendBrand.vue

@@ -0,0 +1,86 @@
+<template>
+  <div class="recommend-brand">
+    <ul>
+      <li>
+        <div>
+          <img src="/images/pcb/test-logo.png" alt="">
+        </div>
+        <p>Panasonic(松下)</p>
+      </li>
+      <li>
+        <div>
+          <img src="/images/pcb/test-logo.png" alt="">
+        </div>
+        <p>Panasonic(松下)</p>
+      </li>
+      <li>
+        <div>
+          <img src="/images/pcb/test-logo.png" alt="">
+        </div>
+        <p>Panasonic(松下)</p>
+      </li>
+      <li>
+        <div>
+          <img src="/images/pcb/test-logo.png" alt="">
+        </div>
+        <p>Panasonic(松下)</p>
+      </li>
+      <li>
+        <div>
+          <img src="/images/pcb/test-logo.png" alt="">
+        </div>
+        <p>Panasonic(松下)</p>
+      </li>
+    </ul>
+  </div>
+</template>
+<style lang="scss" scoped>
+  .recommend-brand {
+    background: url('/images/pcb/recommend-brand.png') no-repeat;
+    width: 1190px;
+    height: 422px;
+    margin: 48px auto 0;
+    padding-top: 100px;
+    ul {
+      width: 1173px;
+      height: 289px;
+      margin: 0 auto;
+      padding: 40px 22px;
+      background: #fff;
+      li {
+        float: left;
+        margin-left: 7px;
+        width: 220px;
+        height: 208px;
+        -webkit-box-shadow: 0 0 5px 0 rgba(0, 0, 0, .1);
+        -moz-box-shadow: 0 0 5px 0 rgba(0, 0, 0, .1);
+        box-shadow: 0 0 5px 0 rgba(0, 0, 0, .1);
+        border-radius: 4px;
+        cursor: pointer;
+        border: 1px solid #fff;
+        &:hover {
+          border-color: #fa524b;
+          p {
+            font-weight: bold;
+          }
+        }
+        &:first-child {
+          margin-left: 0;
+        }
+        div {
+          width: 114px;
+          height: 108px;
+          line-height: 108px;
+          margin: 31px auto 26px;
+          img {
+            max-width: 114px;
+            max-height: 108px;
+          }
+        }
+        p {
+          text-align: center;
+        }
+      }
+    }
+  }
+</style>

+ 106 - 0
components/pcb/home/floors/Floor.vue

@@ -0,0 +1,106 @@
+<template>
+  <div class="floor">
+    <ul>
+      <li class="list-item">
+        <div class="img">
+          <img src="/images/pcb/test-logo.png" alt="">
+        </div>
+        <p class="text">HYCO组合式金属喷嘴</p>
+        <span class="text price">¥699</span>
+      </li>
+      <li class="list-item">
+        <div class="img">
+          <img src="/images/pcb/test-logo.png" alt="">
+        </div>
+        <p class="text">HYCO组合式金属喷嘴</p>
+        <span class="text price">¥699</span>
+      </li>
+      <li class="list-item">
+        <div class="img">
+          <img src="/images/pcb/test-logo.png" alt="">
+        </div>
+        <p class="text">HYCO组合式金属喷嘴</p>
+        <span class="text price">¥699</span>
+      </li>
+      <li class="list-item">
+        <div class="img">
+          <img src="/images/pcb/test-logo.png" alt="">
+        </div>
+        <p class="text">HYCO组合式金属喷嘴</p>
+        <span class="text price">¥699</span>
+      </li>
+      <li class="list-item">
+        <div class="img">
+          <img src="/images/pcb/test-logo.png" alt="">
+        </div>
+        <p class="text">HYCO组合式金属喷嘴</p>
+        <span class="text price">¥699</span>
+      </li>
+      <li class="list-item">
+        <div class="img">
+          <img src="/images/pcb/test-logo.png" alt="">
+        </div>
+        <p class="text">HYCO组合式金属喷嘴</p>
+        <span class="text price">¥699</span>
+      </li>
+      <li class="list-item">
+        <div class="img">
+          <img src="/images/pcb/test-logo.png" alt="">
+        </div>
+        <p class="text">HYCO组合式金属喷嘴</p>
+        <span class="text price">¥699</span>
+      </li>
+      <li class="list-item">
+        <div class="img">
+          <img src="/images/pcb/test-logo.png" alt="">
+        </div>
+        <p class="text">HYCO组合式金属喷嘴</p>
+        <span class="text price">¥699</span>
+      </li>
+    </ul>
+  </div>
+</template>
+<style lang="scss" scoped>
+  $img-size: 215px;
+  .floor {
+    .list-item {
+      display: inline-block;
+      margin-right: 10px;
+      width: 290px;
+      height: 350px;
+      border-radius: 2px;
+      -webkit-box-shadow: 2px 3px 9px 0 rgba( 0, 0, 0, .2 );
+      -moz-box-shadow: 2px 3px 9px 0 rgba( 0, 0, 0, .2 );
+      box-shadow: 2px 3px 9px 0 rgba( 0, 0, 0, .2 );
+      text-align: center;
+      border: 1px solid #fff;
+      cursor: pointer;
+      &:nth-child(4n) {
+        margin-right: 0;
+      }
+      &:nth-child(n + 5) {
+        margin-top: 10px;
+      }
+      &:hover {
+        border-color: #366cf3;
+      }
+      .img {
+        height: $img-size;
+        line-height: $img-size;
+        width: $img-size;
+        margin: 11px auto 30px;
+        img {
+          max-width: $img-size;
+          max-height: $img-size;
+        }
+      }
+      .text {
+        height: 20px;
+        font-weight: bold;
+      }
+      .price {
+        color: #f14f4f;
+      }
+    }
+  }
+</style>

+ 66 - 0
components/pcb/home/floors/Floors.vue

@@ -0,0 +1,66 @@
+<template>
+  <div class="floors">
+    <div class="floor-line line1">
+      <p>PCB物料<span>PCB material</span><a href="">查看更多</a></p>
+      <floor></floor>
+    </div>
+    <div class="floor-line line2">
+      <p>PCB常用耗材<span>PCB common consumables</span><a href="">查看更多</a></p>
+      <floor></floor>
+    </div>
+    <div class="floor-line line3">
+      <p>PCB设备<span>PCB equipment</span><a href="">查看更多</a></p>
+      <floor></floor>
+    </div>
+  </div>
+</template>
+<script>
+  import Floor from './Floor.vue'
+  export default {
+    components: {
+      Floor
+    }
+  }
+</script>
+<style lang="scss" scoped>
+  .floors {
+    width: 1190px;
+    margin: 0 auto 100px;
+    .floor-line {
+      margin-top: 60px;
+      p {
+        position: relative;
+        font-size: 30px;
+        font-weight: bold;
+        text-align: center;
+        line-height: 30px;
+        margin: 0 0 23px 0;
+        span {
+          font-size: 12px;
+          vertical-align: middle;
+          margin-left: 14px;
+        }
+        a {
+          font-size: 14px;
+         position: absolute;
+          right: 0;
+        }
+      }
+      &.line1 {
+        p, a {
+          color: #6fb61a;
+        }
+      }
+      &.line2 {
+        p, a {
+          color: #d83578;
+        }
+      }
+      &.line3 {
+        p, a {
+          color: #e25e44;
+        }
+      }
+    }
+  }
+</style>

+ 13 - 0
components/pcb/index.js

@@ -0,0 +1,13 @@
+import Kinds from './home/Kinds.vue'
+import Intro from './home/Intro.vue'
+import RecommendBrand from './home/RecommendBrand.vue'
+import Floors from './home/floors/Floors.vue'
+import Nav from './Nav.vue'
+import Detail from './product/Detail.vue'
+import BrandList from './brand/BrandList.vue'
+import PcbNavSearch from './PcbNavSearch.vue'
+import DetailBrand from './search/DetailBrand.vue'
+import GoodList from './search/GoodList.vue'
+import Kind from './search/Kind.vue'
+import ResultTitle from './search/ResultTitle.vue'
+export { Kinds, Intro, RecommendBrand, Floors, Nav, Detail, BrandList, PcbNavSearch, DetailBrand, GoodList, Kind, ResultTitle }

+ 542 - 0
components/pcb/product/Detail.vue

@@ -0,0 +1,542 @@
+<template>
+  <div class="detail">
+    <div class="item">
+      <div class="img inline-block">
+        <img :src="commodity.img || '/images/store/common/default.png'" alt=""/>
+      </div>
+      <div class="info inline-block">
+        <p class="name">{{commodity.code}}</p>
+        <p class="remind"><span>官方自营,品质保障</span>厂家直销,品质保证</p>
+        <!--<div class="price-area">-->
+          <!--<span class="left inline-block">价格<span><i>¥</i>1899.00</span></span>-->
+          <!--<span class="right inline-block"><span>6500</span><br/>浏览数</span>-->
+        <!--</div>-->
+        <div class="price-level">
+          <span class="left inline-block">
+              <div>单价&nbsp;¥&nbsp;(含税):</div>
+              起订量:
+          </span>
+          <ul class="inline-block">
+            <li :class="{active: getPriceLevel(fragment.num) == index}" v-for="(price, index) in commodity.prices">
+              <span class="price"><em>{{commodity.currencyName == 'RMB' ? '¥' : '$'}}</em>{{price.rMBPrice}}</span>
+              <div class="level" :title="price.start + '-' + price.end">{{price.start}}-{{price.end}}</div>
+              <i class="arrow"></i>
+            </li>
+          </ul>
+        </div>
+        <div class="input-area">
+          <!--<div class="operate-btn inline-block">-</div>
+          <input type="text" class="form-control">
+          <div class="operate-btn inline-block">+</div>-->
+          <div class="operate-btn inline-block" @click="fragment.canSub ?subNum():''" :style="!fragment.canSub ?'cursor: not-allowed;':''">-</div>
+          <input type="text" class="form-control" placeholder="数量" v-model="fragment.num" @change="inputNum()"style="padding: 0;min-width: 100px;text-align: center;"/>
+          <div class="operate-btn inline-block" @click="fragment.canAdd ?addNum():''" :style="!fragment.canAdd ?'cursor: not-allowed;':''">+</div>
+          <span class="reserve-info">
+            库存:{{commodity.reserve}}&nbsp;{{commodity.unit}}&nbsp;&nbsp;({{commodity.minBuyQty + commodity.unit}}&nbsp;起订)
+          </span>
+        </div>
+        <div class="operate-area">
+          <a class="inline-block operate-buy" @click="buy(true)">立即购买</a>
+          <a class="inline-block" @click="buy(false)">加入购物车</a>
+        </div>
+      </div>
+      <div class="shop inline-block fr">
+        <div class="search-area">
+          <input type="search" class="form-control" placeholder="产品名称/品牌/类目">
+          <span class="search-btn inline-block">搜索</span>
+        </div>
+        <p class="shop-info-title">
+          商家信息
+        </p>
+        <div class="shop-info">
+          <p class="shop-name">{{storeInfo.storeName}}</p>
+          <img class="identify" src="/images/pcb/identified.png">
+          <div class="info-line">
+            <span class="inline-block">电话:</span>
+            <span class="inline-block">{{storeInfo.enterprise.enTel}}</span>
+          </div>
+          <div class="info-line">
+            <span class="inline-block">传真:</span>
+            <span class="inline-block">{{storeInfo.enterprise.enFax}}</span>
+          </div>
+          <div class="info-line">
+            <span class="inline-block">地址:</span>
+            <span class="inline-block">{{storeInfo.enterprise.enAddress}}</span>
+          </div>
+          <div class="link">
+            <span class="link-btn"><img src="/images/pcb/link.png" alt="">联系卖家</span>
+          </div>
+        </div>
+      </div>
+    </div>
+    <ul class="kind">
+      <li class="inline-block" v-for="prop in properties">
+        {{prop[1].labelCn}}:{{prop[0].value || '-'}}
+      </li>
+    </ul>
+  </div>
+</template>
+<script>
+  function initFragment (commodity) {
+    if (!commodity) {
+      return {}
+    }
+    let fragment = {}
+    let prices = commodity.prices[0]
+    fragment.num = commodity.minBuyQty
+    fragment.prices = prices
+
+    if (commodity.currencyName !== 'USD') {
+      fragment.currency = 'RMB'
+    } else {
+      fragment.currency = 'USD'
+    }
+
+    if (fragment.currency !== 'USD') {
+      fragment.price = prices.rMBPrice
+    } else {
+      fragment.price = prices.uSDPrice
+    }
+    fragment.canAdd = true
+    fragment.canSub = false
+    return fragment
+  }
+  function getFragment (commodity, fragment) {
+    // 判断是否小于第一分段的起订量
+    if (commodity.prices[0].start > fragment.num) {
+      fragment.num = commodity.prices[0].start
+    }
+    // 获取分段的信息
+    let prices = commodity.prices
+    for (let i = 0; i < prices.length; i++) {
+      if (fragment.num <= prices[i].end) {
+        fragment.prices = prices[i]
+        break
+      }
+    }
+  }
+  import { buyOrCar } from '~utils/baseUtils'
+  export default {
+    data () {
+      return {
+        fragment: {
+          currency: 'RMB',
+          num: 0,
+          price: 0,
+          canAdd: true,
+          canSub: true}
+      }
+    },
+    computed: {
+      properties () {
+        return this.$store.state.pcb.product.detail.data
+      },
+      storeInfo () {
+        return this.$store.state.shop.storeInfo.store.data
+      },
+      commodity () {
+        let commodity = this.$store.state.shop.storeInfo.commodity.data
+        this.fragment = initFragment(commodity)
+        return commodity
+      }
+    },
+    methods: {
+      getPriceLevel: function (num) {
+        let prices = this.commodity.prices
+        if (this.commodity.prices) {
+          for (let i = 0; i < prices.length; i++) {
+            if (num >= prices[i].start && num <= prices[i].end) {
+              return i
+            }
+          }
+        }
+        return -1
+      },
+      changeNum: function (newNum) {
+        let pack = this.commodity.perQty || this.commodity.minPackQty
+        let buy = this.commodity.minBuyQty
+        let reserve = this.commodity.reserve
+        if (newNum < buy) {
+          this.$message.error('该商品最少购买' + buy + '件')
+          this.fragment.num = buy
+          this.fragment.canSub = false
+          if (this.fragment.num > reserve) {
+            this.$message.error('库存不足')
+            this.fragment.num = reserve - (reserve % pack)
+            this.fragment.canAdd = false
+          } else {
+            if (reserve - this.fragment.num - pack < 0) {
+              this.fragment.canAdd = false
+            } else {
+              this.fragment.canAdd = true
+            }
+          }
+        } else {
+          if (newNum - buy - pack < 0) {
+            this.fragment.canSub = false
+          } else {
+            this.fragment.canSub = true
+          }
+          //    console.log(newNum) 2222
+          if (newNum % pack === 0) {
+            this.fragment.num = newNum
+          } else {
+            this.fragment.num = (Math.floor(newNum / pack) + 1) * pack
+          }
+          if (this.fragment.num > reserve) {
+            this.$message.error('库存不足')
+            this.fragment.num = reserve - (reserve % pack)
+            this.fragment.canAdd = false
+          } else {
+            if (reserve - this.fragment.num - pack < 0) {
+              this.fragment.canAdd = false
+            } else {
+              this.fragment.canAdd = true
+            }
+          }
+        }
+      },
+      subNum () {
+        let pack = this.commodity.perQty || this.commodity.minPackQty
+        let newNum = this.fragment.num - pack
+        this.changeNum(newNum)
+        getFragment(this.commodity, this.fragment)
+      },
+      addNum () {
+        let pack = this.commodity.perQty || this.commodity.minPackQty
+        let newNum = this.fragment.num + pack
+        this.changeNum(newNum)
+        getFragment(this.commodity, this.fragment)
+      },
+      inputNum () {
+        if ((/^[\d]*$/).test(this.fragment.num)) {
+          this.changeNum(this.fragment.num)
+          getFragment(this.commodity, this.fragment)
+        } else {
+          this.$message.error('请输入数字')
+          this.fragment.num = this.commodity.minBuyQty
+        }
+      },
+      buy (flag) {
+        buyOrCar(flag, null, this, this.commodity)
+      }
+    }
+  }
+</script>
+<style lang="scss" scoped>
+  .detail {
+    .inline-block {
+      display: inline-block;
+      vertical-align: middle;
+    }
+    .item {
+      .img {
+        width: 300px;
+        height: 356px;
+        line-height: 356px;
+        text-align: center;
+        box-shadow: 0 0 7px 0 rgba(199, 200, 200, .35);
+        img {
+          max-width: 300px;
+          max-height: 356px;
+        }
+      }
+      .info {
+        margin-left: 17px;
+        height: 356px;
+        padding-top: 10px;
+        .name {
+          font-size: 24px;
+          font-weight: bold;
+          color: #666;
+          margin-bottom: 17px;
+        }
+        .remind {
+          margin: 17px 0;
+          span {
+            background: #e4393c;
+            color: #fff;
+            padding: 4px 8px;
+            border-radius: 3px;
+            margin-right: 10px;
+          }
+        }
+        /*.price-area {
+          width: 449px;
+          height: 75px;
+          background: url('/images/pcb/price-bg.png') no-repeat;
+          .left {
+            color: #666;
+            margin-left: 13px;
+            line-height: 40px;
+            height: 40px;
+            width: 339px;
+            border-right: 1px solid #c8e5ff;
+            margin-top: 18px;
+            span {
+              margin-left: 17px;
+              font-size: 32px;
+              color: #e4393c;
+              i {
+                font-size: 18px;
+                font-style: normal;
+              }
+            }
+          }
+          .right {
+            margin: 22px 0 0 30px;
+            font-size: 12px;
+            color: #666;
+            span {
+              font-size: 14px;
+              color: #ffa133;
+              margin-bottom: 8px;
+            }
+          }
+        }*/
+        .price-level {
+          width: 570px;
+          height: 87px;
+          padding: 17px 0 0 7px;
+          background: #fffaf1;
+          .left {
+            color: #999;
+            div {
+              margin-bottom: 19px;
+            }
+          }
+          ul {
+            margin-left: 15px;
+            li {
+              width: 83px;
+              margin-right: 4px;
+              float: left;
+              text-align: center;
+              .price {
+                color: #ffb385;
+                font-size: 22px;
+                margin-bottom: 19px;
+                em {
+                  font-style: normal;
+                  font-size: 13px;
+                  margin-right: 4px;
+                }
+              }
+              .level {
+                width: 82px;
+                height: 21px;
+                line-height: 21px;
+                font-size: 12px;
+                color: #999;
+                background: #e4e4e4;
+                margin-top: 9px;
+                overflow: hidden;
+                text-overflow: ellipsis;
+                white-space: nowrap;
+              }
+              &.active {
+                position: relative;
+                .price {
+                  color: #ff7800;
+                }
+                .level {
+                  background: #ccc;
+                  color: #333;
+                }
+                .arrow {
+                  content: '';
+                  position: absolute;
+                  top: 28px;
+                  left: 37px;
+                  border: {
+                    left: 4px solid transparent;
+                    right: 4px solid transparent;
+                    bottom: 8px solid #ccc;
+                  }
+                }
+              }
+            }
+          }
+        }
+        .input-area {
+          margin-top: 25px;
+          .operate-btn {
+            width: 33px;
+            height: 45px;
+            text-align: center;
+            line-height: 45px;
+            border: 1px solid #d9d9d9;
+            background: #f4f4f4;
+            cursor: pointer;
+            font-size: 20px;
+            user-select: none;
+          }
+          .form-control {
+            border: 1px solid #d9d9d9;
+            background: #fff;
+            width: 77px;
+            height: 45px;
+            border-radius: 0;
+            vertical-align: middle;
+            text-align: center;
+          }
+          .reserve-info {
+            color: #999;
+            margin-left: 10px;
+            vertical-align: bottom;
+          }
+        }
+        .operate-area {
+          margin-top: 12px;
+          .inline-block {
+            width: 126px;
+            height: 45px;
+            line-height: 45px;
+            text-align: center;
+            font-size: 18px;
+            color: #fff;
+            background: #418cf6;
+            border: 1px solid #418cf6;
+            &.operate-buy {
+              color: #418cf6;
+              background: #fff;
+              margin-right: 8px;
+            }
+          }
+        }
+      }
+      $base-color: #ffa133;
+      .shop {
+        height: 356px;
+        width: 259px;
+        text-align: center;
+        .search-area {
+          .form-control {
+            width: 198px;
+            height: 28px;
+            font-size: 12px;
+            padding: 0 14px;
+            border: 1px solid $base-color;
+            vertical-align: middle;
+            border: {
+              bottom-left-radius: 13px;
+              top-left-radius: 13px;
+              top-right-radius: 0;
+              bottom-right-radius: 0;
+            };
+          }
+          .search-btn {
+            width: 60px;
+            height: 28px;
+            line-height: 28px;
+            color: #fff;
+            background: $base-color;
+            border: 1px solid $base-color;
+            border: {
+              bottom-left-radius: 0;
+              top-left-radius: 0;
+              top-right-radius: 13px;
+              bottom-right-radius: 13px;
+            };
+            cursor: pointer;
+          }
+        }
+        .shop-info-title {
+          position: relative;
+          font-size: 16px;
+          color: #ffa133;
+          border: 1px solid #fee9d0;
+          line-height: 35px;
+          margin: 8px 0 0 0;
+          &::before {
+            content: '';
+            background: #fff;
+            width: 24px;
+            height: 24px;
+            position: absolute;
+            left: -12px;
+            top: -12px;
+            border-right: 1px solid #fee9d0;
+            -webkit-transform: rotate(45deg);
+            -moz-transform: rotate(45deg);
+            -ms-transform: rotate(45deg);
+            -o-transform: rotate(45deg);
+            transform: rotate(45deg);
+          }
+          &::after {
+            content: '';
+            position: absolute;
+            left: 1px;
+            top: 1px;
+            border: {
+              top: 15px solid $base-color;
+              right: 15px solid transparent;
+            }
+          }
+        }
+        .shop-info {
+          border: 1px solid #fee9d0;
+          .shop-name {
+            margin: 19px 0 9px;
+            color: #666;
+          }
+          .identify {
+            margin-bottom: 20px;
+          }
+          .info-line {
+            margin-bottom: 21px;
+            padding: 0 16px;
+            text-align: left;
+            .inline-block {
+              vertical-align: top;
+              &:first-child {
+                color: #666;
+              }
+              &:last-child {
+                max-width: 182px;
+              }
+            }
+          }
+          .link {
+            height: 70px;
+            width: 232px;
+            margin: 0 auto;
+            border-top: 1px dashed $base-color;
+            .link-btn {
+              display: block;
+              margin: 23px auto 0;
+              width: 124px;
+              height: 26px;
+              background: $base-color;
+              color: #fff;
+              line-height: 26px;
+              border-radius: 13px;
+              img {
+                margin-right: 7px;
+              }
+            }
+          }
+        }
+      }
+    }
+    .kind {
+      background: #f8fbfd;
+      margin: 38px 0 80px;
+      border: 1px solid #d6ebfd;
+      li {
+        width: 25%;
+        color: #666;
+        height: 40px;
+        line-height: 40px;
+        padding-left: 47px;
+        border-bottom: 1px solid #d6ebfd;
+        &:nth-last-child(-n + 4) {
+          border-bottom: none;
+        }
+        a {
+          color: #418cf6;
+        }
+      }
+    }
+  }
+</style>

+ 99 - 0
components/pcb/search/DetailBrand.vue

@@ -0,0 +1,99 @@
+<template>
+  <div class="brandDetail container" v-if="list_brands && list_brands.uuid">
+    <div id="brand">
+      <nuxt-link :to="`/product/brand/${list_brands.uuid}`" class="brand-logo">
+        <img :src="list.logoUrl || '/images/component/default.png'" :alt="list.nameEn" :title="list.nameEn"/>
+      </nuxt-link>
+      <div class="brand-message">
+        <div class="brand-main" v-show="list.series"><div>主营产品:</div><span>{{list.series}}</span></div>
+        <div class="brand-main" v-show="applications.length>0">
+          <div>应用领域:</div><span v-for="(item, index) in applications"><span>{{item}}</span><span v-show="index+1 < applications.length">|</span></span>
+        </div>
+        <div class="brand-main" v-show="list.brief"><div>品牌介绍:</div><span>{{list.brief}}</span></div>
+        <div class="brand-main" v-show="list.url"><div>官网地址:</div><a class="office-address" :href="list.url" target="_blank">{{list.url}}</a></div>
+      </div>
+    </div>
+    <nuxt-link :to="`/pcb/brand/${list_brands.uuid}`" class="brand-url">进入品牌中心</nuxt-link>
+  </div>
+</template>
+
+<script>
+  export default {
+    data () {
+      return {
+        applications: []
+      }
+    },
+    computed: {
+      list_brands () {
+        return this.$store.state.searchData.searchList.lists.data.brands
+      },
+      list () {
+        let list = this.$store.state.searchData.searchDetail.detail.data
+        if (list.application && list.application !== '') {
+          this.applications = list.application.split(',')
+        }
+        return list
+      }
+    }
+  }
+</script>
+
+<style scoped>
+  #brand{
+    min-height: 160px;
+  }
+  .brandDetail {
+    margin-top: 20px;
+    width: 1190px;
+    overflow: hidden;
+    border-bottom: 1px solid #e5e5e5;
+  }
+  .brand-main{
+    line-height: 20px;
+    margin-left: 223px;
+    margin-bottom: 10px;
+  }
+  .brand-main >span, .brand-main >a {
+    font-weight: 500;
+    font-size: 13px;
+    display: inline-block;
+    max-width: 92%;
+  }
+  .brand-main >div {
+    font-size: 14px;
+    font-weight: 700;
+    width: 8%;
+    display: inline-block;
+    float: left;
+  }
+  .office-address{
+    color: #666;
+  }
+  .office-address:hover{
+    color: #5078cb;
+    cursor: pointer;
+  }
+  .brandDetail .brand-logo{
+    float: left;
+    width: 213px;
+    height: 160px;
+    text-align: center;
+    line-height: 100px;
+  }
+  .brandDetail .brand-logo img {
+    width: 212px;
+    height: 159px;
+    border: 1px solid #ccc;
+    vertical-align: middle;
+  }
+  .brand-url{
+    color: white;
+    background: #2c87d7;
+    position: relative;
+    left: 1088px;
+    padding: 6px 8px;
+    border-radius: 5px;
+    bottom: 20px;
+  }
+</style>

+ 381 - 0
components/pcb/search/GoodList.vue

@@ -0,0 +1,381 @@
+<template>
+  <div>
+    <div class="tab-filter" >
+      <div class="inline-block item" @click="sortBy('normal1')" :class="{'active': activeTag === 'normal1'}">默认排序</div>
+      <div class="inline-block item" @click="sortBy('normal2')" :class="activeTag==='normal2'?'active':''">现货优选<i class="fa fa-long-arrow-down" v-show="reserve_asc"></i><i class="fa fa-long-arrow-up" v-show="!reserve_asc"></i></div>
+      <div class="inline-block item" @click="sortBy('price')" :class="activeTag==='price'?'active':''">价格<i class="fa fa-long-arrow-down" v-show="price_asc"></i><i class="fa fa-long-arrow-up" v-show="!price_asc"></i></div>
+      <div class="inline-block price-filter">
+        <input type="number" min="0" step="0.01" v-model="min_price" class="form-control" placeholder="¥" onfocus="this.placeholder=''" onblur="this.placeholder='¥'" />
+        <span>&nbsp;-&nbsp;</span>
+        <input type="number" :min="min_price === ''?0:min_price" step="0.01" v-model="max_price" class="form-control" placeholder="¥" onfocus="this.placeholder=''" onblur="this.placeholder='¥'" />
+        <a class="fp-btn inline-block" @click="filter_price">确定</a>
+      </div>
+      <div class="fr">
+        <span>共{{good_list.total}}条商品信息</span>
+        <span class="page-info"><span class="active">{{nowPage}}</span>/{{total_page}}</span>
+        <a href="javascript:void(0)" class="icon-xiangzuo iconfont" @click="changePage('pre')"></a>
+        <a href="javascript:void(0)" class="icon-xiangyou iconfont" @click="changePage('next')"></a>
+      </div>
+    </div>
+    <ul class="good-list" v-if="good_list.pcbgoods && good_list.pcbgoods.length">
+      <li v-for="item in good_list.pcbgoods" class="inline-block">
+        <nuxt-link :to="`/pcb/product/${item.productid}/${item.batchCode}`">
+          <div class="img">
+            <img :src="getLogo(item)">
+          </div>
+          <p class="price">{{item.prices ? item.currencyName === 'RMB' ? '¥' + '&nbsp;&nbsp;' + item.prices[0].rMBPrice : '$' +  '&nbsp;&nbsp;' + item.prices[0].uSDPrice : '-'}}</p>
+          <p>{{item.kindNameCn}}</p>
+          <p>销量<span class="sell-count">{{item.saleQty || 0}}</span>件</p>
+        </nuxt-link>
+      </li>
+    </ul>
+    <div class="com-empty" v-if="!good_list.pcbgoods || !good_list.pcbgoods.length">
+      <img class="com-empty-img" src="/images/brandList/empty-cart.png">
+      <span class="com-empty-text">暂无搜索结果</span>
+    </div>
+    <page :total="total_count" :page-size="pageSize"
+          :current="nowPage" @childEvent="listenPage"></page>
+  </div>
+</template>
+
+<script>
+  import Page from '~components/common/page/pageComponent.vue'
+  import Buy from '~components/common/buyOrCar/buyComponent.vue'
+  export default {
+    data () {
+      return {
+        nowPage: 1,
+        pageSize: 20,
+        sorting: {},
+        price_asc: true,
+        reserve_asc: true,
+        min_price: '',
+        max_price: '',
+        filter: {},
+        activeTag: 'normal1'
+      }
+    },
+    components: {
+      Page,
+      Buy
+    },
+    filters: {
+      currency: function (input) {
+        if (typeof input === 'number') {
+          if (input <= 0.000001) {
+            input = 0.000001
+          } else {
+            if (input.toString().indexOf('.') === -1) {
+              input = input + '.00'
+            } else {
+              let inputStr = input.toString()
+              let arr = inputStr.split('.')
+              let floatNum = arr[1]
+              if (floatNum.length > 6) {
+                input = inputStr.substring(0, arr[0].length + 7)
+                if (Number(floatNum.charAt(6)) > 4) {
+                  input = (Number(input) * 1000000 + 1) / 1000000
+                }
+              } else if (floatNum.length === 1) {
+                input = input + '0'
+              }
+            }
+          }
+        }
+        return input
+      }
+    },
+    watch: {
+      $route: function (val, oldVal) {
+        this.filter = {}
+        this.activeTag = 'normal1'
+      }
+    },
+    computed: {
+      good_lists () {
+        return this.$store.state.pcb.search.list
+      },
+      good_list () {
+        return this.good_lists.data
+      },
+      total_count () {
+        return Math.min(this.good_list.total, 100 * this.pageSize)
+      },
+      total_page () {
+        let currentCount = Math.floor(this.good_list.total / this.pageSize) + (this.good_list.total % this.pageSize > 0 ? 1 : 0)
+        return currentCount > 100 ? 100 : currentCount
+      },
+      buy_info () {
+        return this.$store.state.user.buy.buyInfo.data
+      },
+      car_info () {
+        return this.$store.state.user.car.addCarInfo.data
+      },
+      tab () {
+        return this.$store.state.chat.tab.tab.data
+      },
+      user () {
+        return this.$store.state.option.user
+      }
+    },
+    methods: {
+      goWebChat: function () {
+        if (!this.user.logged) {
+          this.$http.get('/login/page').then(response => {
+            if (response.data) {
+              this.$router.push('/auth/login')
+            }
+          })
+        } else {
+          // 获得窗口的垂直位置
+          let iTop = (window.screen.availHeight - 30 - 780) / 2
+          // 获得窗口的水平位置
+          let iLeft = (window.screen.availWidth - 10 - 1030) / 2
+          if (this.tab.close) {
+            this.tab.close()
+          }
+          let newTab = window.open('', '即时对话框', 'height=750, width=1000, top=' + iTop + ', left=' + iLeft + ', toolbar=no, menubar=no, scrollbars=no, resizable=no, location=no, status=no')
+          newTab.close()
+          newTab = window.open('', '即时对话框', 'height=750, width=1000, top=' + iTop + ', left=' + iLeft + ', toolbar=no, menubar=no, scrollbars=no, resizable=no, location=no, status=no')
+          this.$store.dispatch('chat/setChatTab', {tab: newTab})
+          this.$http.get('/basic/enterprise/' + this.storeInfo.enUU + '/info')
+            .then(response => {
+              let obj = {}
+              obj.userPhone = this.user.data.userTel
+              obj.userType = 'ENTERPRISE'
+              this.user.data.enterprises.forEach(function (item, index) {
+                if (item.current) {
+                  obj.enUU = item.uu
+                  obj.enterprise = {enUU: item.uu, name: item.enName}
+                }
+              })
+              obj.otherEnUU = response.data.uu
+              obj.otherUserType = 'STORE'
+              obj.otherEnterprise = {enUU: response.data.uu, name: response.data.enName}
+              obj.type = 'CHAT'
+              if (!(/^1\d{10}$/).test(response.data.enTel)) {
+                this.$http.get('/basic/enterprise/' + response.data.uu + '/admin').then(response => {
+                  obj.toPhone = response.data.userTel
+                  console.log(obj)
+                  this.openWebChat(newTab, obj)
+                }, err => {
+                  console.log(err)
+                  this.$message.error('暂无卖家管理员手机号!')
+                })
+              } else {
+                obj.toPhone = response.data.enTel
+                this.openWebChat(newTab, obj)
+              }
+            }, err => {
+              console.log(err)
+            })
+        }
+      },
+      openWebChat: function (newTab, obj) {
+        this.$http.post('https://im.ubtob.com/api/chat/infos?condition=chat_info', obj)
+          .then(response => {
+            if (response.data.success) {
+              newTab.location.href = 'https://im.ubtob.com/chat/visit?gid=' + response.data.content
+            }
+          })
+      },
+      listenPage: function (changedPage) {
+        this.nowPage = changedPage
+        this.$emit('pageEvent', this.nowPage)
+      },
+      changePage: function (type) {
+        if (type === 'next' && this.nowPage < this.total_page) {
+          this.listenPage(++this.nowPage)
+        } else if (type === 'pre' && this.nowPage > 1) {
+          this.listenPage(--this.nowPage)
+        }
+      },
+      sortBy: function (param) {
+        if (param === 'normal1') {
+          this.sorting = {}
+          this.activeTag = 'normal1'
+        } else if (param === 'normal2') {
+          if (this.reserve_asc) {
+            this.sorting = {'RESERVE': 'ASC'}
+          } else {
+            this.sorting = {'RESERVE': 'DESC'}
+          }
+          this.activeTag = 'normal2'
+          this.reserve_asc = !this.reserve_asc
+        } else if (param === 'type') {
+          this.sorting = {'RESERVE': 'DESC'}
+          this.activeTag = 'type'
+        } else if (param === 'price') {
+          if (this.price_asc) {
+            this.sorting = {'PRICE': 'ASC'}
+          } else {
+            this.sorting = {'PRICE': 'DESC'}
+          }
+          this.activeTag = 'price'
+          this.price_asc = !this.price_asc
+        }
+        this.$emit('sortEvent', this.sorting)
+        this.nowPage = 1
+      },
+      filter_price: function () {
+        if (this.min_price === '' && this.max_price !== '') {
+          this.filter.goods_maxpricermb = this.max_price
+        } else if (this.min_price !== '' && this.max_price === '') {
+          this.filter.goods_minpricermb = this.min_price
+        } else if (this.min_price !== '' && this.max_price !== '') {
+          if (this.min_price <= this.max_price) {
+            this.filter.goods_minpricermb = this.min_price
+            this.filter.goods_maxpricermb = this.max_price
+          }
+        } else {
+          delete this.filter.goods_minpricermb
+          delete this.filter.goods_maxpricermb
+        }
+        this.$emit('filterPriceEvent', this.filter)
+      },
+      clear_price: function () {
+        this.min_price = ''
+        this.max_price = ''
+        this.$emit('filterPriceEvent', this.filter)
+      },
+      goUnstandardDetail: function (comp) {
+        if (!comp.uuid) {
+          this.$router.push('/store/productDetail/' + comp.batchCode)
+        }
+      },
+      getLogo: function (item) {
+        if (item.batchCode) {
+          if (item.img) {
+            return item.img
+          } else {
+            return '/images/component/default.png'
+          }
+        } else {
+          if (item.brand && item.brand.logoUrl) {
+            return item.brand.logoUrl
+          } else {
+            return '/images/component/default.png'
+          }
+        }
+      }
+    }
+  }
+</script>
+
+<style scoped lang="scss">
+  .tab-filter {
+    height: 34px;
+    background: #f4f4f4;
+    padding: 5px 31px 0 14px;
+    margin-bottom: 20px;
+    .item {
+      width: 74px;
+      height: 24px;
+      text-align: center;
+      color: #999;
+      line-height: 22px;
+      background: #fff;
+      border: 1px solid #d9d9d9;
+      border-right: none;
+      cursor: pointer;
+      font-size: 12px;
+      &:last-child {
+        border-right: 1px solid #d9d9d9;
+      }
+      &.active {
+        border: 1px solid #5078cb;
+        background: #5078cb;
+        color: #fff;
+      }
+    }
+    .price-filter {
+      margin-left: 30px;
+      .form-control {
+        width: 74px;
+        height: 24px;
+        border: 1px solid #d9d9d9;
+        border-radius: 0;
+        padding: 0 6px;
+        font-size: 12px;
+      }
+      .fp-btn {
+        width: 43px;
+        height: 24px;
+        line-height: 24px;
+        background: #5078cb;
+        color: #fff;
+        text-align: center;
+        border-radius: 2px;
+        margin-left: 6px;
+      }
+    }
+    .fr {
+      height: 24px;
+      line-height: 24px;
+      color: #999;
+      .page-info {
+        margin-left: 20px;
+        margin-right: 4px;
+        .active {
+          color: #3f85f6;
+        }
+      }
+      .iconfont {
+        display: inline-block;
+        width: 38px;
+        height: 24px;
+        line-height: 24px;
+        text-align: center;
+        border: 1px solid #d9d9d9;
+        color: #666;
+        background: #fff;
+      }
+    }
+  }
+  .good-list {
+    .inline-block {
+      width: 220px;
+      height: 300px;
+      margin-right: 15px;
+      border: 1px solid #d9d9d9;
+      padding: 0 20px;
+      margin-bottom: 15px;
+      &:nth-child(5n) {
+        margin-right: 0;
+      }
+      p {
+        color: #666;
+      }
+      $img-size: 179px;
+      .img {
+        width: $img-size;
+        height: $img-size;
+        line-height: $img-size;
+        text-align: center;
+        margin: 0 auto;
+        img {
+          max-width: $img-size;
+          max-height: $img-size;
+        }
+      }
+      .price {
+        font-size: 18px;
+        color: #e4393c;
+      }
+      .sell-count {
+        color: #767cf9;
+      }
+    }
+  }
+  .com-empty{
+    text-align: center;
+    height:130px;
+    border: 1px solid #eee;
+    line-height: 130px;
+    margin-bottom: 20px;
+    .com-empty-text {
+      color: #aaa;
+      margin-left: 10px;
+    }
+  }
+</style>

+ 309 - 0
components/pcb/search/Kind.vue

@@ -0,0 +1,309 @@
+<template>
+  <div class="selector" >
+    <a class="show-filter" @click="show_filter = !show_filter">
+      <span v-text="show_filter?'收起筛选 ':'展开筛选 '"></span>
+      <i :class="show_filter?'fa fa-angle-up':'fa fa-angle-down'"></i>
+    </a>
+    <div v-show="show_filter">
+      <div class="sl-wrap" v-if="good_list.total > 0">
+        <div class="sl-key f14">类目:</div>
+        <div class="sl-value">
+          <span v-for="(kind_temp, index) in kind_exp_arr">
+            <div class="sl-filter" @click="click_kind_exp(kind_temp.ki_id, index)">
+              <a class="text-num" v-text="kind_temp.ki_name_cn"></a>
+              <span><i class="fa fa-close"></i></span>
+            </div>
+          </span>
+          <ul :class="show_kind">
+            <li @click="restore('kind')"><a>全部</a></li>
+            <li v-for="(item, index) in list_kind" v-if="item.ki_name_cn" @click="click_kind(item.ki_id, index)" :title="item.ki_name_cn">
+              <a v-text="item.ki_name_cn"></a>
+            </li>
+          </ul>
+        </div>
+        <div class="sl-clear"></div>
+        <div class="sl-ext">
+          <a @click="click_kind_more" v-if="list_kind.length>17">
+            <span v-text="kind_open?'更多':'收起'"></span>
+            <i class="fa fa-angle-down ng-scope" v-if="kind_open"></i>
+            <i class="fa fa-angle-up ng-scope" v-if="!kind_open"></i>
+          </a>
+        </div>
+      </div>
+      <div class="sl-wrap" v-if="good_list.total > 0">
+      <div class="sl-key f14">品牌:</div>
+      <div class="sl-value" >
+         <span v-for="(brand_temp, index) in brand_exp_arr" >
+          <div class="sl-filter" @click="click_brand_exp(brand_temp.br_id, index)">
+            <a class="text-num" v-text="brand_temp.br_name_cn"></a>
+            <span><i class="fa fa-close"></i></span>
+          </div>
+        </span>
+        <ul :class="show_brand">
+          <li @click="restore('brand')"><a>全部</a></li>
+          <li v-for="(item, index) in list_brand" v-if="item.br_name_cn" @click="click_brand(item.br_id, index)" :title="item.br_name_cn">
+            <a v-text="item.br_name_cn"></a>
+          </li>
+        </ul>
+      </div>
+      <div class="sl-clear"></div>
+      <div class="sl-ext" v-if="list_brand.length>17">
+        <a @click="click_brand_more">
+          <span v-text="brand_open?'更多':'收起'"></span>
+          <i class="fa fa-angle-down ng-scope" v-if="brand_open"></i>
+          <i class="fa fa-angle-up ng-scope" v-if="!brand_open"></i>
+        </a>
+      </div>
+    </div>
+    </div>
+  </div>
+</template>
+<script>
+  export default {
+    data () {
+      return {
+        show_filter: true,
+        kind_open: true,
+        brand_open: true,
+        show_kind: 'list-inline',
+        show_brand: 'list-inline',
+        filter: {},
+        kind_arr: [],
+        brand_arr: [],
+        kind_exp_arr: [],
+        brand_exp_arr: []
+      }
+    },
+    watch: {
+      $route: function (val, oldVal) {
+        this.filter = {}
+        this.kind_arr = []
+        this.brand_arr = []
+        this.kind_exp_arr = []
+        this.brand_exp_arr = []
+      }
+    },
+    computed: {
+      list_kinds () {
+        return this.$store.state.pcb.search.kinds
+      },
+      list_kind () {
+        return this.list_kinds.data
+      },
+      list_brands () {
+        return this.$store.state.pcb.search.brands
+      },
+      list_brand () {
+        return this.list_brands.data
+      },
+      good_lists () {
+        return this.$store.state.pcb.search.list
+      },
+      good_list () {
+        return this.good_lists.data
+      },
+      list_data_brands () {
+        return this.good_list.brands
+      }
+    },
+    methods: {
+      click_kind_more: function (event) {
+        if (this.kind_open) {
+          this.show_kind = 'list-inline2'
+        } else {
+          this.show_kind = 'list-inline'
+        }
+        this.kind_open = !this.kind_open
+      },
+      click_brand_more: function (event) {
+        if (this.brand_open) {
+          this.show_brand = 'list-inline2'
+        } else {
+          this.show_brand = 'list-inline'
+        }
+        this.brand_open = !this.brand_open
+      },
+      click_kind: function (id, index) {
+        this.kind_arr.push(id)
+        this.$emit('kindFilterEvent', this.kind_arr)
+        this.kind_exp_arr.push(this.list_kind[index])
+        this.kind_exp_arr[this.kind_exp_arr.length - 1].index = index
+        this.list_kind[index] = ''
+      },
+      click_brand: function (id, index) {
+        this.brand_arr.push(id)
+        this.$emit('brandFilterEvent', this.brand_arr)
+        this.brand_exp_arr.push(this.list_brand[index])
+        this.brand_exp_arr[this.brand_exp_arr.length - 1].index = index
+        this.list_brand[index] = ''
+      },
+      click_kind_exp: function (id, index) {
+        let idx = this.getIndex(this.kind_arr, id)
+        this.list_kind[this.kind_exp_arr[index].index] = this.kind_exp_arr[index]
+        this.kind_arr.splice(idx, 1)
+        this.$emit('kindFilterEvent', this.kind_arr)
+        this.kind_exp_arr.splice(index, 1)
+      },
+      click_brand_exp: function (id, index) {
+        let idx = this.getIndex(this.brand_arr, id)
+        this.list_brand[this.brand_exp_arr[index].index] = this.brand_exp_arr[index]
+        this.brand_arr.splice(idx, 1)
+        this.$emit('brandFilterEvent', this.brand_arr)
+        this.brand_exp_arr.splice(index, 1)
+      },
+      restore: function (name) {
+        if (name === 'kind') {
+          this.list_kind.concat(this.kind_exp_arr)
+          this.kind_exp_arr = []
+          this.kind_arr = []
+          this.$emit('kindFilterEvent', this.kind_arr)
+        } else if (name === 'brand') {
+          this.list_brand.concat(this.brand_exp_arr)
+          this.brand_exp_arr = []
+          this.brand_arr = []
+          this.$emit('brandFilterEvent', this.brand_arr)
+        }
+      },
+      getIndex: function (arr, obj) {
+        for (let i = 0; i < arr.length; i++) {
+          if (arr[i] === obj) {
+            return i
+          }
+        }
+        return -1
+      }
+    }
+  }
+</script>
+<style scoped>
+  .show-filter{
+    position: relative;
+    left: 1100px;
+    top: -10px;
+    color: #5078cb;
+    border: 1px solid #5078cb;
+    padding: 3px 8px;
+    background: #fff;
+  }
+  #searchResult .selector >div{
+    margin-bottom: 20px;
+    border-top: 2px solid #6493ff;
+  }
+  #searchResult .selector .sl-wrap {
+    position: relative;
+    padding: 10px 15px;
+    font-size: 12px;
+    line-height: 30px;
+    border: 1px solid #d4e1ff;
+    border-top: none;
+    border-bottom: 1px dashed #d4e1ff;
+  }
+  #searchResult .selector .sl-wrap:last-child {
+    border-bottom: 1px solid #d4e1ff;
+  }
+  #searchResult .selector .sl-wrap .sl-key {
+    float: left;
+  }
+  .f14 {
+    font-size: 14px;
+  }
+  #searchResult .selector .sl-wrap .sl-value {
+    margin-left: 78px;
+    margin-right: 50px;
+  }
+  #searchResult .selector .sl-wrap .sl-value span >.sl-filter {
+    display: inline-block;
+    position: relative;
+    line-height: 22px;
+    padding-left: 10px;
+    padding-right: 30px;
+    border: 1px solid #5078cb;
+    color: #5078cb;
+    cursor: pointer;
+    height: 22px;
+    margin-right: 10px;
+  }
+  #searchResult .selector .sl-wrap .sl-value span >.sl-filter a{
+    color: #666;
+    text-decoration: none;
+  }
+  #searchResult .selector .sl-wrap .sl-value span >.sl-filter span{
+    display: inline-block;
+    position: absolute;
+    right: 0;
+    top: -1px;
+    width: 20px;
+    text-align: center;
+    background: #5078cb;
+    color: #fff;
+  }
+  #searchResult .selector .sl-wrap .sl-value span >.sl-filter:hover {
+    border: 1px solid #ea1e23;
+  }
+  #searchResult .selector .sl-wrap .sl-value span >.sl-filter:hover a{
+    color: #ea1e23;
+  }
+  #searchResult .selector .sl-wrap .sl-value span >.sl-filter:hover span{
+    background: #ea1e23;
+  }
+  #searchResult .selector .sl-wrap .sl-clear {
+    clear: both;
+  }
+  #searchResult .selector .sl-wrap .sl-ext {
+    width: 40px;
+    top: 5px;
+    position: absolute;
+    right: 0;
+  }
+
+  .list-inline {
+    max-height: 60px;
+    overflow: hidden;
+    margin-bottom: 0;
+    padding-left: 0;
+    margin-left: -5px;
+    list-style: none;
+  }
+  .list-inline2 {
+    height: 100%;
+    overflow: hidden;
+    margin-bottom: 0;
+    padding-left: 0;
+    margin-left: -5px;
+    list-style: none;
+  }
+
+  #searchResult .selector .sl-wrap .sl-value li {
+    display: inline-block;
+    padding-right: 5px;
+    padding-left: 5px;
+    margin-right: 20px;
+    width: 10%;
+    height: 23px;
+    line-height: 23px;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+    cursor: pointer;
+    border: 1px solid #fff;
+  }
+  #searchResult .selector .sl-wrap .sl-value ul  a{
+    color: #666;
+  }
+  #searchResult .selector .sl-wrap .sl-value li:hover {
+    border: 1px solid #5078cb;
+    color: #5078cb;
+  }
+  #searchResult .selector .sl-wrap .sl-value li:hover a {
+    color: #5078cb;
+  }
+  .sl-ext a{
+    color: black;
+  }
+  .sl-ext a:hover{
+    color: #5078cb;
+    text-decoration: none;
+  }
+
+</style>
+

+ 52 - 0
components/pcb/search/ResultTitle.vue

@@ -0,0 +1,52 @@
+<template>
+  <div class="result-title text-muted">
+    搜索"<span class="text-inverse" >{{keyword}}</span>"<span v-if="status != 1">暂无此型号</span>
+    <span v-if="status != 3">,为您找到
+    <span class="text-num" v-text="good_list.total"></span> 个<span v-if="status == 2">相关</span>产品</span>:
+  </div>
+</template>
+<script>
+  export default{
+    props: ['keyword', 'page'],
+    data () {
+      return {
+        status: 1
+      }
+    },
+    computed: {
+      good_lists () {
+        return this.$store.state.pcb.search.list
+      },
+      good_list () {
+        if (this.page === 1) {
+          if (this.good_lists.data.components && this.good_lists.data.components.length > 0) {
+            if (this.keyword.toUpperCase() === this.good_lists.data.components[0].code.toUpperCase()) {
+              this.status = 1
+            } else {
+              this.status = 2
+            }
+          } else {
+            this.status = 3
+          }
+        }
+        return this.good_lists.data
+      }
+    }
+  }
+</script>
+<style scoped>
+  #searchResult .result-title {
+    margin-top: 5px;
+    padding: 10px 5px;
+    height: 30px;
+    line-height: 30px;
+    font-size: 14px;
+  }
+  .text-inverse {
+    color: #f40!important;
+  }
+  .text-num {
+    font-style: normal;
+    font-family: verdana;
+  }
+</style>

+ 1 - 1
nuxt.config.js

@@ -1,7 +1,7 @@
 const path = require('path')
 const isProdMode = Object.is(process.env.NODE_ENV, 'production')
 // b2c后台
-const baseUrl = process.env.BASE_URL || (isProdMode ? 'http://api.usoftmall.com/' : 'http://192.168.253.121:9090/platform-b2c')
+const baseUrl = process.env.BASE_URL || (isProdMode ? 'http://api.usoftmall.com/' : 'http://10.1.51.124:8080/platform-b2c')
 // 公共询价
 const commonUrl = process.env.COMMON_URL || (isProdMode ? 'https://api-inquiry.usoftmall.com/' : 'http://218.17.158.219:24000/')
 // 公共物料

+ 46 - 0
pages/pcb/brand/_id.vue

@@ -0,0 +1,46 @@
+<template>
+  <div class="details">
+    <div class="information">
+      <brand-detail :isPcb="true"/>
+      <div class="comm-list">
+        <categories-list :isPcb="true" @kindSelectAction="onKindSelect"/>
+        <brand-list :kindid="kindid"></brand-list>
+      </div>
+    </div>
+  </div>
+</template>
+<script>
+  import { BrandDetail, CategoriesList } from '~components/product'
+  import { BrandList } from '~components/pcb'
+  export default {
+    layout: 'pcb',
+    data () {
+      return {
+        code: '',
+        kindid: ''
+      }
+    },
+    components: {
+      BrandDetail,
+      CategoriesList,
+      BrandList
+    },
+    fetch ({ store, params }) {
+      return Promise.all([
+        store.dispatch('loadBrandDetail', { id: params.id, isPcb: true })
+      ])
+    },
+    methods: {
+      onKindSelect: function (kindid) {
+        this.kindid = kindid || null
+      }
+    }
+  }
+</script>
+<style scoped>
+  .comm-list{
+    width: 1190px;
+    margin: 0 auto;
+    overflow: hidden;
+  }
+</style>

+ 25 - 0
pages/pcb/index.vue

@@ -0,0 +1,25 @@
+<template>
+  <div>
+    <kinds></kinds>
+    <intro></intro>
+    <recommend-brand></recommend-brand>
+    <floors></floors>
+  </div>
+</template>
+<script>
+  import { Kinds, Intro, RecommendBrand, Floors } from '~components/pcb'
+  export default {
+    layout: 'pcb',
+    components: {
+      Kinds,
+      Intro,
+      RecommendBrand,
+      Floors
+    },
+    fetch ({ store }) {
+      return Promise.all([
+        store.dispatch('pcb/getPcbKinds', {parentId: 3825})
+      ])
+    }
+  }
+</script>

+ 26 - 0
pages/pcb/product/_productId/_batchCode.vue

@@ -0,0 +1,26 @@
+<template>
+  <div class="pcb-product-detail">
+    <detail></detail>
+  </div>
+</template>
+<script>
+  import { Detail } from '~components/pcb'
+  export default {
+    layout: 'pcb',
+    components: {
+      Detail
+    },
+    fetch ({store, params}) {
+      return Promise.all([
+        store.dispatch('pcb/getPcbProduct', {productId: params.productId}),
+        store.dispatch('shop/findCommodityOnBatchInfo', {batchCode: params.batchCode})
+      ])
+    }
+  }
+</script>
+<style scoped>
+    .pcb-product-detail {
+      width: 1190px;
+      margin: 0 auto;
+    }
+</style>

+ 112 - 0
pages/pcb/search/_keyword.vue

@@ -0,0 +1,112 @@
+<template>
+  <div class="container" id="searchResult">
+    <detail-brand></detail-brand>
+    <result-title :keyword="key" :page="nowPage"></result-title>
+    <kind @kindFilterEvent="listenKindFilter"
+          @brandFilterEvent="listenBrandFilter"
+    ></kind>
+    <good-list @pageEvent="listenPage"
+               @sortEvent="listenSort"
+               @filterPriceEvent="listenPriceFilter"
+    ></good-list>
+  </div>
+</template>
+<script>
+  import { GoodList, Kind, ResultTitle, DetailBrand } from '~components/pcb'
+  export default{
+    layout: 'pcb',
+    data () {
+      return {
+        key: this.$route.query.w,
+        pageSize: 15,
+        nowPage: 1,
+        sorting: {},
+        filter: {},
+        paramJSON: {}
+      }
+    },
+    fetch ({store, route}) {
+      return Promise.all([
+        store.dispatch('pcb/searchForKinds', {collectedField: 'goods_kind', keyword: route.query.w, filters: {}}),
+        store.dispatch('pcb/searchForBrands', {collectedField: 'goods_brand', keyword: route.query.w, filters: {}}),
+        store.dispatch('pcb/searchForList', {count: 15, filter: {}, keyword: route.query.w, page: 1, sorting: {}})
+      ])
+    },
+    components: {
+      ResultTitle,
+      Kind,
+      GoodList,
+      DetailBrand
+    },
+    methods: {
+      reloadList: function () {
+        if (this.sorting === {}) {
+          this.sorting = {}
+        }
+        this.$store.dispatch('pcb/searchForList', {count: this.pageSize, filter: this.filter, keyword: this.$route.query.w, page: this.nowPage, sorting: this.sorting})
+      },
+      reloadKind: function () {
+        if (!this.filter.goods_kindId) {
+          this.$store.dispatch('pcb/searchForKinds', {collectedField: 'goods_kind', keyword: this.$route.query.w, filters: this.paramJSON})
+        }
+      },
+      reloadBrand: function () {
+        if (!this.filter.goods_brandId) {
+          this.$store.dispatch('pcb/searchForBrands', {collectedField: 'goods_brand', keyword: this.$route.query.w, filters: this.paramJSON})
+        }
+      },
+      listenPage: function (nPage) {
+        this.nowPage = nPage
+        this.reloadList()
+      },
+      listenSort: function (sortType) {
+        this.sorting = sortType
+        this.reloadList()
+      },
+      listenPriceFilter: function (filterType) {
+        if (filterType.goods_minpricermb) {
+          this.filter.goods_minpricermb = filterType.goods_minpricermb
+        } else {
+          delete this.filter.goods_minpricermb
+        }
+        if (filterType.goods_maxpricermb) {
+          this.filter.goods_maxpricermb = filterType.goods_maxpricermb
+        } else {
+          delete this.filter.goods_maxpricermb
+        }
+        this.reloadList()
+      },
+      listenKindFilter: function (kindarr) {
+        this.nowPage = 1
+        if (kindarr.length === 0) {
+          delete this.filter.goods_kindId
+          delete this.paramJSON.goods_kindid
+          this.reloadKind()
+          this.reloadBrand()
+          this.reloadList()
+        } else {
+          this.filter.goods_kindId = kindarr
+          this.paramJSON.goods_kindid = kindarr
+          this.reloadBrand()
+          this.reloadList()
+        }
+      },
+      listenBrandFilter: function (brandarr) {
+        this.nowPage = 1
+        if (brandarr.length === 0) {
+          delete this.filter.goods_brandId
+          delete this.paramJSON.goods_brandid
+          this.reloadKind()
+          this.reloadBrand()
+          this.reloadList()
+        } else {
+          this.filter.goods_brandId = brandarr
+          this.paramJSON.goods_brandid = brandarr
+          this.reloadKind()
+          this.reloadList()
+        }
+      }
+    }
+  }
+</script>
+

+ 55 - 0
store/pcb.js

@@ -0,0 +1,55 @@
+import axios from '~plugins/axios'
+
+export const actions = {
+  // 获取pcb首页类目
+  getPcbKinds ({ commit }, params = {}) {
+    commit('kindsData/REQUEST_PCB_KINDS', params)
+    return axios.get(`/api/product/kind/${params.parentId}/pcbchildren_all`)
+      .then(response => {
+        commit('kindsData/GET_PCB_KINDS_SUCCESS', response.data)
+      }, err => {
+        commit('kindsData/GET_PCB_KINDS_FAILURE', err)
+      })
+  },
+  // 获取pcb产品详情
+  getPcbProduct ({ commit }, params = {}) {
+    commit('product/REQUEST_PCB_PRODUCT', params)
+    return axios.get(`/api/product/kind/pcbproperty/${params.productId}`)
+      .then(response => {
+        commit('product/GET_PCB_PRODUCT_SUCCESS', response.data)
+      }, err => {
+        commit('product/GET_PCB_PRODUCT_FAILURE', err)
+      })
+  },
+  // 获取pcb搜索kind
+  searchForKinds ({ commit }, params = {}) {
+    commit('search/REQUEST_KINDS', params)
+    return axios.get(`/search/PCBGoods/collect`, {params})
+      .then(response => {
+        commit('search/GET_KINDS_SUCCESS', response.data)
+      }, err => {
+        commit('search/GET_KINDS_FAILURE', err)
+      })
+  },
+  // 获取pcb搜索brand
+  searchForBrands ({ commit }, params = {}) {
+    commit('search/REQUEST_BRANDS', params)
+    return axios.get(`/search/PCBGoods/collect`, {params})
+      .then(response => {
+        commit('search/GET_BRANDS_SUCCESS', response.data)
+      }, err => {
+        commit('search/GET_BRANDS_FAILURE', err)
+      })
+  },
+  // 获取pcb搜索list
+  searchForList ({ commit }, params = {}) {
+    commit('search/REQUEST_LIST', params)
+    return axios.get(`/search/pcbgoods/page`, {params})
+      .then(response => {
+        commit('search/GET_LIST_SUCCESS', response.data)
+      }, err => {
+        commit('search/GET_LIST_FAILURE', err)
+      })
+  }
+}
+

+ 19 - 0
store/pcb/kindsData.js

@@ -0,0 +1,19 @@
+export const state = () => ({
+  kinds: {
+    fetching: false,
+    data: []
+  }
+})
+
+export const mutations = {
+  REQUEST_PCB_KINDS (state) {
+    state.kinds.fetching = true
+  },
+  GET_PCB_KINDS_SUCCESS (state, result) {
+    state.kinds.fetching = false
+    state.kinds.data = result
+  },
+  GET_PCB_KINDS_FAILURE (state) {
+    state.kinds.fetching = false
+  }
+}

+ 19 - 0
store/pcb/product.js

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

+ 47 - 0
store/pcb/search.js

@@ -0,0 +1,47 @@
+export const state = () => ({
+  kinds: {
+    fetching: false,
+    data: []
+  },
+  brands: {
+    fetching: false,
+    data: []
+  },
+  list: {
+    fetching: false,
+    data: []
+  }
+})
+
+export const mutations = {
+  REQUEST_KINDS (state) {
+    state.kinds.fetching = true
+  },
+  GET_KINDS_SUCCESS (state, result) {
+    state.kinds.fetching = false
+    state.kinds.data = result
+  },
+  GET_KINDS_FAILURE (state) {
+    state.kinds.fetching = false
+  },
+  REQUEST_BRANDS (state) {
+    state.brands.fetching = true
+  },
+  GET_BRANDS_SUCCESS (state, result) {
+    state.brands.fetching = false
+    state.brands.data = result
+  },
+  GET_BRANDS_FAILURE (state) {
+    state.brands.fetching = false
+  },
+  REQUEST_LIST (state) {
+    state.list.fetching = true
+  },
+  GET_LIST_SUCCESS (state, result) {
+    state.list.fetching = false
+    state.list.data = result
+  },
+  GET_LIST_FAILURE (state) {
+    state.list.fetching = false
+  }
+}