Browse Source

Merge branch 'master' into feature/yc-applyPurchase-1212

# Conflicts:
#	nuxt.config.js
yangc 8 years ago
parent
commit
58ac914fa5
100 changed files with 6472 additions and 407 deletions
  1. 32 2
      app.html
  2. 0 8
      assets/README.md
  3. 3 11
      assets/scss/activity.css
  4. 7 2
      assets/scss/common.scss
  5. 202 0
      assets/scss/mobileCommon.scss
  6. 0 6
      components/README.md
  7. 19 6
      components/common/buyOrCar/buyComponent.vue
  8. 36 0
      components/common/loading/Loading.vue
  9. 117 40
      components/default/Header.vue
  10. 12 12
      components/default/RightBar.vue
  11. 590 0
      components/default/Zhongqiu.vue
  12. 362 0
      components/default/christmas.vue
  13. 3 1
      components/default/index.js
  14. 13 3
      components/home/Carousel.vue
  15. 46 24
      components/main/Search.vue
  16. 289 0
      components/mobile/Home.vue
  17. 118 0
      components/mobile/MobileFooter.vue
  18. 319 0
      components/mobile/MobileHeader.vue
  19. 216 0
      components/mobile/brand/BrandCenter.vue
  20. 563 0
      components/mobile/brand/BrandDetail.vue
  21. 494 0
      components/mobile/brand/ComponentDetail.vue
  22. 16 0
      components/mobile/common/Loading.vue
  23. 42 0
      components/mobile/common/LoginBox.vue
  24. 51 0
      components/mobile/common/PullDown.vue
  25. 48 0
      components/mobile/common/RemindBox.vue
  26. 5 0
      components/mobile/common/index.js
  27. 27 0
      components/mobile/help/HelpFooter.vue
  28. 39 0
      components/mobile/help/HelpHeader.vue
  29. 4 0
      components/mobile/help/index.js
  30. 5 0
      components/mobile/index.js
  31. 297 0
      components/mobile/search/MainSearch.vue
  32. 386 0
      components/mobile/store/StoreDetail.vue
  33. 10 3
      components/product/ComponentGoods.vue
  34. 12 1
      components/product/brand/BrandComponent.vue
  35. 4 4
      components/product/component/ComponentDetail.vue
  36. 16 13
      components/product/component/StoreInfo.vue
  37. 11 3
      components/provider/Carousel.vue
  38. 15 7
      components/provider/NewStore.vue
  39. 23 1
      components/provider/Suppliers.vue
  40. 12 5
      components/register-saler/register/StepThird.vue
  41. 65 26
      components/search/GoodList.vue
  42. 23 0
      components/search/Kind.vue
  43. 1 1
      components/search/ResultTitle.vue
  44. 10 0
      components/searchStore/StoreContent.vue
  45. 111 70
      components/store/CommodityInfo.vue
  46. 74 32
      components/store/CommodityList.vue
  47. 20 4
      components/store/ComponentInfo.vue
  48. 11 1
      components/store/RecommendProduct.vue
  49. 88 1
      components/store/common/StoreHeader.vue
  50. 54 21
      layouts/error.vue
  51. 54 21
      layouts/errorPage.vue
  52. 34 0
      layouts/help.vue
  53. 16 13
      layouts/main.vue
  54. 33 0
      layouts/mobile.vue
  55. 3 3
      layouts/shop.vue
  56. 5 7
      nuxt.config.js
  57. 4 1
      package.json
  58. 0 7
      pages/README.md
  59. 11 5
      pages/activity/business.vue
  60. 6 2
      pages/auth/login.vue
  61. 80 16
      pages/index.vue
  62. 17 0
      pages/mobile/brand/_code.vue
  63. 20 0
      pages/mobile/brand/brandCenter/_initial.vue
  64. 30 0
      pages/mobile/brand/componentDetail/_uuid.vue
  65. 57 0
      pages/mobile/help/_id.vue
  66. 409 0
      pages/mobile/search/_keycode.vue
  67. 27 0
      pages/mobile/shop/_uuid.vue
  68. 317 0
      pages/mobile/shop/index.vue
  69. 418 0
      pages/mobile/user/index.vue
  70. 2 1
      pages/product/component/_uuid.vue
  71. 7 3
      pages/search/_keyword.vue
  72. 0 8
      plugins/README.md
  73. 1 1
      server.js
  74. 0 11
      static/README.md
  75. BIN
      static/images/404-mobile.png
  76. BIN
      static/images/christmas/btn.png
  77. BIN
      static/images/christmas/chirmas4.png
  78. BIN
      static/images/christmas/christmas1.png
  79. BIN
      static/images/christmas/christmas2.png
  80. BIN
      static/images/christmas/christmas3.png
  81. BIN
      static/images/christmas/christmas4.png
  82. BIN
      static/images/christmas/close.png
  83. BIN
      static/images/christmas/festival1.gif
  84. BIN
      static/images/christmas/festival_bg.png
  85. BIN
      static/images/christmas/festival_deng1.png
  86. BIN
      static/images/christmas/festival_deng2.png
  87. BIN
      static/images/christmas/festival_yanhualeft.gif
  88. BIN
      static/images/christmas/festival_yanhuaright.gif
  89. BIN
      static/images/mobile/@2x/brand-bg.png
  90. BIN
      static/images/mobile/@2x/brand/brandWall.png
  91. BIN
      static/images/mobile/@2x/car@2x.png
  92. BIN
      static/images/mobile/@2x/empty-collect.png
  93. BIN
      static/images/mobile/@2x/home/background@2x.png
  94. BIN
      static/images/mobile/@2x/home/background_search@2x.png
  95. BIN
      static/images/mobile/@2x/home/bookbrand@2x.png
  96. BIN
      static/images/mobile/@2x/home/brand@2x.png
  97. BIN
      static/images/mobile/@2x/home/hot-search.png
  98. BIN
      static/images/mobile/@2x/home/modelbrand@2x.png
  99. BIN
      static/images/mobile/@2x/home/phonebrand@2x.png
  100. BIN
      static/images/mobile/@2x/home/shopbrand@2x.png

+ 32 - 2
app.html

@@ -4,12 +4,16 @@
   <link rel="stylesheet" type="text/css" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css"/>
   <link rel="stylesheet" type="text/css" href="https://cdn.bootcss.com/font-awesome/4.7.0/css/font-awesome.min.css"/>
   <link rel="stylesheet" type="text/css" href="https://cdn.bootcss.com/element-ui/1.3.7/theme-default/index.css"/>
-  <link rel="stylesheet" type="text/css" href="https://at.alicdn.com/t/font_0d1jjt5tukcblnmi.css"/>
+  <!--<link rel="stylesheet" type="text/css" href="https://at.alicdn.com/t/font_0d1jjt5tukcblnmi.css"/>-->
+  <link rel="stylesheet" type="text/css" href="https://at.alicdn.com/t/font_452262_1eqwgrq76p2xzuxr.css">
   <link rel="stylesheet" type="text/css" href="https://cdn.bootcss.com/Swiper/3.4.2/css/swiper.css"/>
-  <!--<link rel="stylesheet" type="text/css" href="https://at.alicdn.com/t/font_452262_1qlk0md3oua6ecdi.css"/>-->
   {{ HEAD }}
   <script>
     var _hmt = _hmt || [];
+    var _paq = _paq || [];
+    /* tracker methods like "setCustomDimension" should be called before "trackPageView" */
+    _paq.push(['trackPageView']);
+    _paq.push(['enableLinkTracking']);
     (function (w, d) {
       if (/(MSIE)|(Trident)/.test(w.navigator.userAgent)) {
         var head = d.getElementsByTagName('head')[0]
@@ -41,6 +45,32 @@
       }
       var s = document.getElementsByTagName("script")[0];
       s.parentNode.insertBefore(bp, s);
+
+      // 用户浏览统计
+      <!-- Piwik -->
+        var u="//piwik.ubtob.com/";
+        _paq.push(['setTrackerUrl', u+'piwik.php']);
+        _paq.push(['setSiteId', '1']);
+        var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
+        g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'piwik.js'; s.parentNode.insertBefore(g,s);
+      <!-- End Piwik Code -->
+      if (/(iPhone|iPad|Opera Mini|Android.*Mobile|NetFront|PSP|BlackBerry|Windows Phone)/ig.test(w.navigator.userAgent)) {
+        var docEl = d.documentElement
+        var resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize'
+        var recalc = function () {
+          var clientWidth = docEl.clientWidth
+          if (!clientWidth) return
+          if (clientWidth >= 750) {
+            docEl.style.fontSize = '100px'
+          } else {
+            docEl.style.fontSize = 100 * (clientWidth / 750) + 'px'
+          }
+        }
+//        recalc()
+        if (!d.addEventListener) return
+        w.addEventListener(resizeEvt, recalc, false)
+        d.addEventListener('DOMContentLoaded', recalc, false)
+      }
     })(window, document)
   </script>
   <script type="text/javascript">

+ 0 - 8
assets/README.md

@@ -1,8 +0,0 @@
-# ASSETS
-
-This directory contains your un-compiled assets such as LESS, SASS, or JavaScript.
-
-More information about the usage of this directory in the documentation:
-https://nuxtjs.org/guide/assets#webpacked
-
-**This directory is not required, you can delete it if you don't want to use it.**

+ 3 - 11
assets/scss/activity.css

@@ -87,29 +87,21 @@ ul,li{
   display: inline-block;
   height: 235px;
 }
-.business .advantage .advantage-list ul  li{
+.business .advantage .advantage-list ul  li {
   float: left;
   width: 174px;
   height: 206px;
   border-radius: 10px;
   background: #fff;
-  margin: 0 6px;
+  margin: 0 10px;
   overflow: hidden;
   position: relative;
-  /*opacity:0;
-  transform:scale(0);
-  transition:.5s 0.1s;*/
 }
-/*.business .advantage.active .advantage-list ul  li{
-    opacity:1 !important; transform:none !important;
-}*/
 .business .advantage .advantage-list ul  li:hover{
   cursor: pointer;
-  width: 200px;
-  height: 233px;
-  margin: 0 10px;
   top: -16px;
   transition: top 1s ease-out;
+  transform:scale(1.2);
 }
 .business .advantage .advantage-list ul  li:hover p.title{
   background: #61d2f3;

+ 7 - 2
assets/scss/common.scss

@@ -19,6 +19,11 @@
   }
 }
 
+// ie等滚动条遮住元素
+html, body {
+  -ms-overflow-style: scrollbar;
+}
+
 #cnzz_stat_icon_1267002346 {
   display: none;
 }
@@ -332,9 +337,9 @@ div.el-tree-node__content{
   line-height: 36px;
   height: 36px;
 }
-.el-tree-node__children .el-tree-node__content{
+/*.el-tree-node__children .el-tree-node__content{
   padding-left: 8px !important;
-}
+}*/
 .el-tree-node__expand-icon.is-leaf{
   visibility: hidden;
 }

+ 202 - 0
assets/scss/mobileCommon.scss

@@ -0,0 +1,202 @@
+html {
+  overflow-y: scroll;
+  -webkit-text-size-adjust: 100%;
+  -ms-text-size-adjust: 100%;
+}
+
+html * {
+  outline:none;
+  -webkit-text-size-adjust: none;
+  -webkit-tap-highlight-color:rgba(0,0,0,0);
+  -webkit-overflow-scrolling: touch;
+}
+
+/* 内外边距通常让各个浏览器样式的表现位置不同 */
+body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, pre, code, form, fieldset, legend, input, textarea, p, blockquote, th, td, hr, button, article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section {
+  margin: 0;
+  padding: 0;
+}
+
+input, select, textarea {
+  font-size: 100%;
+}
+
+/* 去掉各 Table  cell 的边距并让其边重合 */
+table {
+  border-collapse: collapse;
+  border-spacing: 0;
+}
+
+/* 去除默认边框 */
+fieldset, img {
+  border: 0;
+}
+
+/* 去掉 firefox 下此元素的边框 */
+abbr, acronym {
+  border: 0;
+  font-variant: normal;
+}
+
+/* 一致的 del 样式 */
+del {
+  text-decoration: line-through;
+}
+
+address, caption, cite, code, dfn, em, th, var {
+  font-style: normal;
+  font-weight: 500;
+}
+
+/* 去掉列表前的标识, li 会继承 */
+ol, ul {
+  list-style: none;
+}
+
+/* 对齐是排版最重要的因素, 别让什么都居中 */
+caption, th {
+  text-align: left;
+}
+
+q:before, q:after {
+  content: '';
+}
+
+/* 统一上标和下标 */
+sub, sup {
+  font-size: 75%;
+  line-height: 0;
+  position: relative;
+  vertical-align: baseline;
+}
+
+sup {
+  top: -0.5em;
+}
+
+sub {
+  bottom: -0.25em;
+}
+
+/* 正常链接 未访问 */
+a:link {
+}
+
+/* 鼠标悬停 */
+a:hover {
+  text-decoration: underline;
+}
+
+/* 默认不显示下划线,保持页面简洁 */
+ins, a {
+  text-decoration: none;
+}
+.mobile-modal {
+  position: fixed;
+  top: 0;
+  width: 100%;
+  height: 100%;
+  z-index: 999;
+  background: rgba(0,0,0,.3);
+  .mobile-modal-box {
+    position: fixed;
+    width: 5.92rem;
+    font-size: .28rem;
+    top: 27%;
+    left: 11%;
+    z-index: 1000;
+    .mobile-modal-header {
+      line-height: .96rem;
+      background: rgb(65,141,246);
+      color: #fff;
+      text-align: center;
+      font-size: .32rem;
+      position: relative;
+      border-top-left-radius: .1rem;
+      border-top-right-radius: .1rem;
+      i {
+        position: absolute;
+        right: -.25rem;
+        font-size: .6rem;
+        bottom: .46rem;
+      }
+    }
+    .mobile-modal-content {
+      background: #fff;
+      color: #333;
+      padding: 0 .54rem;
+      border-bottom-left-radius: .1rem;
+      border-bottom-right-radius: .1rem;
+      div {
+        padding: .2rem 0;
+        line-height: .4rem;
+        border-bottom: .04rem solid rgb(183,213,254);
+        text-align: center;
+        &:last-child {
+          border-bottom: none;
+        }
+        &:first-child {
+          text-align: left;
+        }
+      }
+    }
+  }
+  .mobile-share-box {
+    position: fixed;
+    width: 100%;
+    font-size: .28rem;
+    bottom: 0;
+    left: 0;
+    z-index: 1000;
+    background: #fff;
+    color: #333;
+    .cancel-share {
+      height: .98rem;
+      line-height: .98rem;
+      font-size: .3rem;
+      text-align: center;
+      border-top: .04rem solid #cdcecf;
+    }
+    .share-area {
+      .share-item {
+        display: inline-block;
+        width: 1.5rem;
+        height: 1.52rem;
+        padding-top: .3rem;
+        i {
+          margin: 0 auto;
+          display: block;
+          font-size: .55rem;
+          width: .54rem;
+        }
+        span {
+          display: block;
+          text-align: center;
+          margin-top: .1rem;
+        }
+      }
+    }
+  }
+}
+.link-url {
+  color: #01a44e;
+}
+::-webkit-scrollbar {
+  opacity: 0;
+  display: none;
+}
+
+input {
+  -webkit-appearance: none;
+  -moz-appearance: none;
+  appearance: none;
+}
+
+/*loading优先级*/
+.loading {
+  z-index: 100000 !important;
+}
+
+.mobile-content {
+  padding-top: .88rem !important;
+}

+ 0 - 6
components/README.md

@@ -1,6 +0,0 @@
-# COMPONENTS
-
-The components directory contains your Vue.js Components.
-Nuxt.js doesn't supercharge these components.
-
-**This directory is not required, you can delete it if you don't want to use it.**

+ 19 - 6
components/common/buyOrCar/buyComponent.vue

@@ -1,15 +1,16 @@
 <template>
   <div>
-    <button class="btn btn-primary btn-buy-now"  @click="buyNow(true)"><span class="watch">立即购买</span></button>
-    <button class="btn btn-add-cart"  @click="buyNow(false)"><span class="watch">加入购物车</span></button>
+    <button style="z-index: 1000;" class="btn btn-primary btn-buy-now" :class="{'disabled': disabledFlag}"  @click="buyNow(true, $event)"><span class="watch">立即购买</span></button>
+    <button style="z-index: 1000;" class="btn btn-add-cart" :class="{'disabled': disabledFlag}"  @click="buyNow(false, $event)"><span class="watch">加入购物车</span></button>
   </div>
 </template>
 
 <script>
   export default {
-    props: ['item'],
+    props: ['item', 'disabledFlag'],
     methods: {
-      buyNow: function (isBuy) {
+      buyNow: function (isBuy, event) {
+        event.stopPropagation()
         if (!this.$store.state.option.user.logged) {
           this.$http.get('/login/page', {params: {returnUrl: window.location.href}}).then(response => {
             if (response.data) {
@@ -17,7 +18,7 @@
             }
           })
         } else {
-          if (this.item) {
+          if (this.item && !this.disabledFlag) {
             if (isBuy) {
               this.$http.post('trade/order/buyNow', [{
                 uuid: this.item.uuid,
@@ -45,7 +46,7 @@
                     }
                   } else {
                     if (response.data.data && response.data.data.unvailable === 1) {
-                      this.$message.error('产品信息已失效,请刷新面')
+                      this.$message.error('产品信息已失效,请刷新面')
                     } else {
                       this.$message.error(response.data.message)
                     }
@@ -82,6 +83,8 @@
                     }
                   } else {
                     if (response.data.code === 2) {
+                      this.$message.error('库存已不满足起订量')
+                    } else if (response.data.message === '该产品已失效') {
                       this.$message.error(response.data.message + ',请刷新页面')
                     } else {
                       this.$message.error(response.data.message)
@@ -191,4 +194,14 @@
     background-color: #5078CB;
     color: #fff;
   }
+  .btn-buy-now.disabled,
+  .btn-buy-now.disabled:focus,
+  .btn-add-cart.disabled,
+  .btn-add-cart.disabled:focus{
+    background-color: #d1d2d3!important;
+    border: none!important;
+    outline: none;
+    color: #fff!important;
+    cursor: not-allowed;
+  }
 </style>

+ 36 - 0
components/common/loading/Loading.vue

@@ -0,0 +1,36 @@
+<template lang="html">
+  <div class="loading" v-if="loading">
+    <img src="/images/all/loading.gif" alt="">
+  </div>
+</template>
+<script>
+  export default {
+    data: () => ({
+      loading: false
+    }),
+    methods: {
+      start () {
+        this.loading = true
+      },
+      finish () {
+        this.loading = false
+      }
+    }
+  }
+</script>
+<style scoped>
+  .loading {
+    position: fixed;
+    top: 0;
+    left: 0;
+    right: 0;
+    width:  100%;
+    height: 100%;
+    z-index: 1000;
+    text-align: center;
+  }
+  .loading img {
+    position: relative;
+    top: 40%;
+  }
+</style>

+ 117 - 40
components/default/Header.vue

@@ -10,28 +10,35 @@
         </div>
         <div class="navbar-right">
           <template v-if="user.logged">
-            <div class="item-wrap dropdown" @mouseleave="showEnterprises = false">
+            <div class="item-wrap dropdown">
               <div class="item dropdown-toggle">
                 欢迎您,{{ user.data.userName }}&nbsp;|&nbsp;
                 <a @click="logout()">[退出]</a>
                 <span>{{enterprise.enName}}</span>
               </div>
-              <ul class="dropdown-menu">
-                <li class="menu-item-first">
-                  <span class="member-text" :title="enterprise.enName"><i class="fa fa-map-marker"></i>&nbsp;{{ enterprise.uu?enterprise.enName: user.data.userName + '(个人账户)' }}</span>
-                  <a class="pull-right" @click="toggleEnterprises()" v-if="user.data.enterprises && user.data.enterprises.length > 0">
-                    {{ showEnterprises ? '取消' : '切换' }}
-                  </a>
-                </li>
-                <li class="menu-item"
-                    v-for="en in user.data.enterprises"
-                    v-if="showEnterprises && en.uu!=enterprise.uu">
-                  <a @click="switchEnterprise(en)" :title="en.enName">{{ en.enName }}</a>
-                </li>
-                <li class="menu-item"  v-if="showEnterprises && enterprise.uu">
-                  <a @click="switchEnterprise({uu: 0})"><span v-text="user.data.userName"></span>(个人账户)</a>
-                </li>
-              </ul>
+              <div class="dropdown-menu">
+                <div class="menu-item-first">
+                  <span>您可切换至以下账户:</span>
+                </div>
+                <ul>
+                  <!-- <li class="menu-item-first">
+                     <span class="member-text" :title="enterprise.enName"><i class="fa fa-map-marker"></i>&nbsp;{{ enterprise.uu?enterprise.enName: user.data.userName + '(个人账户)' }}</span>
+                     <a class="pull-right" @click="toggleEnterprises()" v-if="user.data.enterprises && user.data.enterprises.length > 0">
+                     {{ showEnterprises ? '取消' : '切换' }}
+                     </a>
+                     <span>您可切换至以下账户:</span>
+                     <input type="text" placeholder="请输入公司名称" v-model="keyword"><span class="search-enterprise" @click="searchEnterprise()">搜索</span>
+                   </li>-->
+                  <li class="menu-item"
+                      v-for="en in sortEnterprises"
+                      v-if="en.uu!=enterprise.uu">
+                    <a @click="switchEnterprise(en)" :title="en.enName">{{ en.enName }}</a>
+                  </li>
+                  <li class="menu-item"  v-if="enterprise.uu">
+                    <a @click="switchEnterprise({uu: 0})"><span v-text="user.data.userName"></span>(个人账户)</a>
+                  </li>
+                </ul>
+              </div>
             </div>
             <nuxt-link class="item" :to="'/'">商城首页</nuxt-link>
             <!--<nuxt-link class="item" to="/user">买家中心</nuxt-link>
@@ -58,7 +65,11 @@
     name: 'header',
     data () {
       return {
-        showEnterprises: false
+//        showEnterprises: false
+//        searchEnterpriseArr: [],
+//        keyword: '',
+//        isSearching: false
+        showEnterpriseToggle: false
       }
     },
     computed: {
@@ -73,6 +84,15 @@
           return {enName: '个人账户'}
         }
       },
+      sortEnterprises () {
+        let ens = this.user.data.enterprises
+        if (ens && ens.length) {
+          ens.sort(function (a, b) {
+            return b.lastLoginTime - a.lastLoginTime
+          })
+        }
+        return ens
+      },
       url () {
         return this.$store.state.option.url
       }
@@ -100,17 +120,13 @@
           }
         })
       },
-      toggleEnterprises () {
-        this.showEnterprises = !this.showEnterprises
-      },
       // 切换当前企业
       switchEnterprise (en) {
-        this.toggleEnterprises()
+        this.showEnterpriseToggle = false
         this.$http.get(`/user/authentication/${en.uu}`).then(() => {
           this.$store.dispatch('loadUserInfo')
-//          let href = window.location.href
-//          let hrefPath = href.slice(href.length - 14, href.length)
-//          if (hrefPath === 'register-saler' && en.uu !== 0 && en.isVendor === 313) {
+//          let path = this.$route.path
+//          if (path === '/register-saler' && en.uu !== 0 && en.isVendor === 313) {
 //            window.location.href = '/vendor#/index'
 //          } else {
 //            window.location.reload()
@@ -142,9 +158,21 @@
           }
         }
       }
-    },
-    beforeMount () {
-      // this.$store.dispatch('loadUserInfo')
+//      searchEnterprise () {
+//        let key = this.keyword
+//        let enterprise = this.user.data.enterprises
+//        this.isSearching = true
+//        this.searchEnterpriseArr = []
+//        if (this.keyword === '') {
+//          this.isSearching = false
+//        } else {
+//          for (let i = 0; i < enterprise.length; i++) {
+//            if (enterprise[i].enName.indexOf(key) !== -1) {
+//              this.searchEnterpriseArr.push(enterprise[i])
+//            }
+//          }
+//        }
+//      }
     }
   }
 </script>
@@ -162,7 +190,7 @@
     overflow: hidden;
     text-overflow: ellipsis;
     white-space: nowrap;
-    height: 30px;
+    height: 25px;
   }
   .header .navbar .navbar-container .navbar-right .dropdown .dropdown-menu .menu-item{
     height: 30px;
@@ -239,9 +267,11 @@
           }
 
           .dropdown {
-
             .dropdown-toggle {
               line-height: $nav-height;
+              border-left: 1px solid $black-light;
+              border-right: 1px solid $black-light;
+              height: 35px;
               a {
                 margin-left: 15px;
                 float: right;
@@ -249,6 +279,10 @@
                   color: $red !important;
                 }
               }
+              &:hover {
+                border-left: 1px solid #999;
+                border-right: 1px solid #999;
+              }
               span {
                 display: inline-block;
                 max-width: 190px;
@@ -258,25 +292,68 @@
                 float: right;
               }
             }
+            .menu-item-first {
+              background: #eee;
+              padding: 0 12px;
+              line-height: 30px;
+              font-size: 12px;
+              >span:nth-child(1) {
+                cursor: default;
+                font-weight: bold;
+              }
+              input {
+                width: 174px;
+                height: 24px;
+                margin-left: 35px;
+                background: #fff;
+                border: 1px solid #5078cb;
+                padding-left: 4px;
+              }
+              .search-enterprise {
+                display: inline-block;
+                width: 36px;
+                height: 24px;
+                color: #fff;
+                background: #5078cb;
+                text-align: center;
+                line-height: 24px;
+                cursor: pointer;
+              }
+            }
 
             .dropdown-menu {
-              min-width: 220px;
-              margin-left: -1px;
-              border: $border;
-              border-top: none;
-              padding: 1em;
+              padding: 0 6px 13px;
               margin:0;
-              border: none;
               border-radius: 0;
+              right: unset;
+              background: #fff;
+              border: 1px solid #999999;
+              border-top: none;
+              -webkit-box-shadow: none;
+              -moz-box-shadow: none;
+              box-shadow: none;
+
+              ::-webkit-scrollbar {
+                background: #f6f6f6;
+              }
 
-              .menu-item-first {
-                margin-bottom: 10px;
+              ul {
+                max-height: 300px;
+                overflow-y: auto;
+                background: #f6f6f6;
               }
 
               .menu-item {
-                line-height: 30px;
+                padding: 0 12px;
                 a {
-                  color: $accent;
+                  color: #333;
+                  max-width: 300px;
+                  line-height: 30px;
+                  width: auto;
+                  &:hover {
+                    color: #5078cb;
+                    text-decoration: none!important;
+                  }
                 }
               }
             }

+ 12 - 12
components/default/RightBar.vue

@@ -3,7 +3,7 @@
     <div class="right-bar">
       <ul class="right-bar-center">
         <li class="right-bar-item" @mouseenter="loadCarCount()">
-          <a @click="goCart" class="title">
+          <a @click="goCart" class="title" target="_blank">
             <i class="iconfont icon-shopping-cart icon-xlg"></i>
           </a>
           <div class="sidebar-menu"><a @click="goCart" title="我的购物车" target="_blank">我的购物车<em><span>(<span v-text="cartCount.count || 0"></span>)</span></em></a></div>
@@ -26,14 +26,14 @@
             <p>周一至周五 9:00-18:00</p>
           </div>
         </li>
-        <!--<li class="right-bar-item contact-menu">-->
-          <!--<a href="javascript:void(0)" class="title" @click="goWebChat">-->
-            <!--<i class="fa fa-comments-o" aria-hidden="true" style="color: #FFFFFF;">-->
-            <!--</i>-->
-            <!--<i class="remind-point" v-if="user.logged && chatCount>0"></i>-->
-          <!--</a>-->
-          <!--<div class="sidebar-menu" title="优软互联"><a @click="goWebChat">优软互联<span v-if="user.logged">({{chatCount}})</span></a></div>-->
-        <!--</li>-->
+        <li class="right-bar-item contact-menu">
+          <a href="javascript:void(0)" class="title" @click="goWebChat">
+            <i class="fa fa-comments-o" aria-hidden="true" style="color: #FFFFFF;">
+            </i>
+            <i class="remind-point" v-if="user.logged && chatCount>0"></i>
+          </a>
+          <div class="sidebar-menu" title="优软互联"><a @click="goWebChat">优软互联<span v-if="user.logged">({{chatCount}})</span></a></div>
+        </li>
       </ul>
       <ul class="right-bar-bottom">
         <li class="right-bar-item" @mouseenter="loadHistorys()">
@@ -233,16 +233,16 @@
         }
       },
       openWebChat: function (newTab, obj) {
-        this.$http.post('http://im.ubtob.com/api/chat/infos?condition=chat_info', obj)
+        this.$http.post('https://im.ubtob.com/api/chat/infos?condition=chat_info', obj)
           .then(response => {
             if (response.data.success) {
-              newTab.location.href = 'http://192.168.253.121:20220/chat/visit?gid=' + response.data.content
+              newTab.location.href = 'https://im.ubtob.com/chat/visit?gid=' + response.data.content
             }
           })
       },
       getChatCount: function () {
         if (this.user.logged) {
-          this.$http.get('http://im.ubtob.com/api/chat/message', {params: {enUU: this.enterprise.uu, operate: 'count_unread', phone: this.user.data.userTel}})
+          this.$http.get('https://im.ubtob.com/api/chat/message', {params: {enUU: this.enterprise.uu, operate: 'count_unread', phone: this.user.data.userTel}})
             .then(response => {
               this.chatCount = response.data.count
             })

+ 590 - 0
components/default/Zhongqiu.vue

@@ -0,0 +1,590 @@
+<template>
+  <div class="banner" v-if="isClose">
+    <div class="banner-modal">
+      <div class="banner-img">
+        <img src="/images/zhongqiu/zq1.png" />
+        <img src="/images/zhongqiu/zq2.png" />
+        <img src="/images/zhongqiu/zq3.png" />
+        <img src="/images/zhongqiu/zq4.png" />
+        <img src="/images/zhongqiu/zq5.png" />
+        <img src="/images/zhongqiu/zq6.png" />
+        <img src="/images/zhongqiu/zq7.png" />
+        <img src="/images/zhongqiu/zq8.png" />
+        <img src="/images/zhongqiu/zq9.png" />
+        <img src="/images/zhongqiu/zq10.png" />
+        <img src="/images/zhongqiu/zq11.png" />
+        <img src="/images/zhongqiu/zq12.png" />
+        <img src="/images/zhongqiu/zq13.png" />
+        <a @click="isOpendZq" href="javascript:void(0)">×</a>
+      </div>
+    </div>
+  </div>
+</template>
+<script>
+  export default {
+    name: 'zhongqiu',
+    data () {
+      return {
+        isClose: false
+      }
+    },
+    beforeMount () {
+      var self = this
+      setTimeout(getTotelNumber, 10000)
+      function getTotelNumber () {
+        self.isOpendZq()
+      }
+      getTotelNumber()
+    },
+    mounted () {
+      const endTime = window.localStorage.getItem('endTime')
+      const overTime = new Date('2017/10/9 00:00:00').getTime()
+      if (overTime - (new Date().getTime()) > 0) {
+        if (endTime) {
+          if (new Date().getTime() - endTime >= 4 * 3600000) {
+            this.isClose = true
+            window.localStorage.setItem('endTime', new Date().getTime())
+          } else {
+            this.isClose = false
+          }
+        } else {
+          this.isClose = true
+          window.localStorage.setItem('endTime', new Date().getTime())
+        }
+      }
+    },
+    methods: {
+      isOpendZq () {
+        this.isClose = false
+      }
+    }
+  }
+</script>
+<style scoped>
+  .banner{
+    width:100%;
+    height:100%;
+    top: 0;
+    left: 0;
+    position:fixed;
+    z-index:3000;
+  }
+  .banner-modal{
+    background: rgba(0,0,0,.6);
+    width:2000px;
+    height:1100px;
+  }
+  .banner-img{
+    position:absolute;
+    top:10%;
+    left:50%;
+    width:900px;
+    margin-left:-450px;
+  }
+  .banner-img img{
+    display:block;
+    width:900px;
+    position:absolute;
+    top:0;
+    left:0;
+  }
+  .banner-img a{
+    display:block;
+    width:30px;
+    height:30px;
+    line-height:30px;
+    font-size:20px;
+    background: #ffffff;
+    border-radius:50%;
+    text-align: center;
+    color:#d8d4d4;
+    position:absolute;
+    top:0;
+    right:0;
+    z-index:5000;
+  }
+  .banner-img a:hover{
+    cursor:pointer;
+  }
+  img:nth-child(1){
+    z-index:120;
+    -webkit-transform-origin: 200px 100px;
+    -moz--transform-origin: 200px 100px;
+    -ms--transform-origin: 200px 100px;
+    -o--transform-origin: 200px 100px;
+    transform-origin:130px 150px;
+    -webkit-animation: animation1 8s linear;
+    -moz-animation: animation1 8s linear;
+    -ms-animation: animation1 8s linear;
+    -o-animation: animation1 8s linear;
+    animation: animation1 8s linear;
+  }
+  img:nth-child(2){
+    z-index:110;
+    -webkit-animation: animation2 8s linear;
+    -moz-animation: animation2 8s linear;
+    -ms-animation: animation2 8s linear;
+    -o-animation: animation2 8s linear;
+    animation: animation2 8s linear;
+  }
+  img:nth-child(3){z-index:20;
+    -webkit-animation: animation3 8s linear;
+    -moz-animation: animation3 8s linear;
+    -ms-animation: animation3 8s linear;
+    -o-animation: animation3 8s linear;
+    animation: animation3 8s linear;
+  }
+  img:nth-child(4){z-index:30;
+    -webkit-animation: animation4 8s linear;
+    -moz-animation: animation4 8s linear;
+    -ms-animation: animation4 8s linear;
+    -o-animation: animation4 8s linear;
+    animation: animation4 8s linear;
+  }
+  img:nth-child(5){
+    z-index:100;
+    -webkit-animation: animation5 8s linear;
+    -moz-animation: animation5 8s linear;
+    -ms-animation: animation5 8s linear;
+    -o-animation: animation5 8s linear;
+    animation: animation5 8s linear;
+  }
+  img:nth-child(6){z-index:90;
+    -webkit-animation: animation6 8s linear;
+    -moz-animation: animation6 8s linear;
+    -ms-animation: animation6 8s linear;
+    -o-animation: animation6 8s linear;
+    animation: animation6 8s linear;
+  }
+  img:nth-child(7){z-index:10;
+    -webkit-transform-origin: 270px 450px;
+    -moz--transform-origin: 270px 450px;
+    -ms--transform-origin: 270px 450px;
+    -o--transform-origin: 270px 450px;
+    transform-origin:270px 500px;
+    -webkit-animation: animation7 8s linear;
+    -moz-animation: animation7 8s linear;
+    -ms-animation: animation7 8s linear;
+    -o-animation: animation7 8s linear;
+    animation: animation7 8s linear;
+  }
+  img:nth-child(8){z-index:130;
+    -webkit-animation: animation8 8s linear;
+    -moz-animation: animation8 8s linear;
+    -ms-animation: animation8 8s linear;
+    -o-animation: animation8 8s linear;
+    animation: animation8 8s linear;
+  }
+  img:nth-child(9){z-index:40;
+    -webkit-transform-origin: 200px 500px;
+    -moz--transform-origin: 200px 500px;
+    -ms--transform-origin: 200px 500px;
+    -o--transform-origin: 200px 500px;
+    transform-origin:200px 500px;
+    -webkit-animation: animation9 8s linear;
+    -moz-animation: animation9 8s linear;''
+  -ms-animation: animation9 8s linear;
+    -o-animation: animation9 8s linear;
+    animation: animation9 8s linear;
+  }
+  img:nth-child(10){z-index:50;
+    -webkit-transform-origin: 240px 500px;
+    -moz--transform-origin: 240px 500px;
+    -ms--transform-origin: 240px 500px;
+    -o--transform-origin: 240px 500px;
+    transform-origin:240px 500px;
+    -webkit-animation: animation10 8s linear;
+    -moz-animation: animation10 8s linear;
+    -ms-animation: animation10 8s linear;
+    -o-animation: animation10 8s linear;
+    animation: animation10 8s linear;
+  }
+  img:nth-child(11){z-index:60;
+    -webkit-transform-origin: 300px 500px;
+    -moz--transform-origin: 300px 500px;
+    -ms--transform-origin: 300px 500px;
+    -o--transform-origin: 300px 500px;
+    transform-origin:300px 500px;
+    -webkit-animation: animation11 8s linear;
+    -moz-animation: animation11 8s linear;
+    -ms-animation: animation11 8s linear;
+    -o-animation: animation11 8s linear;
+    animation: animation11 8s linear;
+  }
+  img:nth-child(12){z-index:70;
+    -webkit-transform-origin: 650px 500px;
+    -moz--transform-origin: 650px 500px;
+    -ms--transform-origin: 650px 500px;
+    -o--transform-origin: 650px 500px;
+    transform-origin:650px 500px;
+    -webkit-animation: animation12 8s linear;
+    -moz-animation: animation12 8s linear;
+    -ms-animation: animation12 8s linear;
+    -o-animation: animation12 8s linear;
+    animation: animation12 8s linear;
+  }
+  img:nth-child(13){z-index:80;
+    -webkit-transform-origin: 700px 500px;
+    -moz--transform-origin: 700px 500px;
+    -ms--transform-origin: 700px 500px;
+    -o--transform-origin: 700px 500px;
+    transform-origin:700px 500px;
+    -webkit-animation: animation13 8s linear;
+    -moz-animation: animation13 8s linear;
+    -ms-animation: animation13 8s linear;
+    -o-animation: animation13 8s linear;
+    animation: animation13 8s linear;
+  }
+  @keyframes animation1{
+    0%{ opacity:0 ;
+      -webkit-transform: rotate(60deg);
+      -moz-transform: rotate(60deg);
+      -ms-transform: rotate(60deg);
+      -o-transform: rotate(60deg);
+      transform: rotate(60deg)
+    }
+    5%{ opacity:1;
+      -webkit-transform: rotate(0deg);
+      -moz-transform: rotate(0deg);
+      -ms-transform: rotate(0deg);
+      -o-transform: rotate(0deg);
+      transform: rotate(0deg)
+    }
+    100%{ opacity:1;  }
+  }
+  @keyframes animation2{
+    0%{ opacity:0 ;
+    }
+    5%{ opacity:0 ;
+    }
+    10%{ opacity:1 ;
+    }
+    100%{ opacity:1;
+    }
+  }
+  @keyframes animation3{
+    0%{ opacity:0 ;
+    }
+    5%{ opacity:0 ;
+      -webkit-transform: scale(.5);
+      -moz-transform: scale(.5);
+      -ms-transform: scale(.5);
+      -o-transform: scale(.5);
+      transform: scale(.5)
+    }
+    50%{ opacity:1 ;
+      -webkit-transform: scale(1);
+      -moz-transform: scale(1);
+      -ms-transform: scale(1);
+      -o-transform: scale(1);
+      transform: scale(1);
+      -webkit-transform: rotate(45deg);
+      -moz-transform: rotate(45deg);
+      -ms-transform: rotate(45deg);
+      -o-transform: rotate(45deg);
+      transform: rotate(45deg)
+    }
+    100%{ opacity:1;
+      -webkit-transform: rotate(0deg);
+      -moz-transform: rotate(0deg);
+      -ms-transform: rotate(0deg);
+      -o-transform: rotate(0deg);
+      transform: rotate(0deg)
+    }
+  }
+  @keyframes animation4{
+    0%{ opacity:0 ;
+    }
+    5%{ opacity:0 ;
+      -webkit-transform: scale(.5);
+      -moz-transform: scale(.5);
+      -ms-transform: scale(.5);
+      -o-transform: scale(.5);
+      transform: scale(.5)
+    }
+    50%{ opacity:1 ;
+      -webkit-transform: scale(1);
+      -moz-transform: scale(1);
+      -ms-transform: scale(1);
+      -o-transform: scale(1);
+      transform: scale(1);
+      -webkit-transform: rotate(-60deg);
+      -moz-transform: rotate(-60deg);
+      -ms-transform: rotate(-60deg);
+      -o-transform: rotate(-60deg);
+      transform: rotate(-60deg)
+    }
+    100%{ opacity:1;
+      -webkit-transform: rotate(0deg);
+      -moz-transform: rotate(0deg);
+      -ms-transform: rotate(0deg);
+      -o-transform: rotate(0deg);
+      transform: rotate(0deg)
+    }
+  }
+  @keyframes animation5{
+    0%{ opacity:0 ;
+    }
+    7%{ opacity:0 ;
+    }
+    13%{ opacity:1 ;
+    }
+    100%{ opacity:1;
+    }
+  }
+  @keyframes animation6{
+    0%{ opacity:0 ;
+    }
+    10%{ opacity:0 ;
+      -webkit-transform: scale(.5);
+      -moz-transform: scale(.5);
+      -ms-transform: scale(.5);
+      -o-transform: scale(.5);
+      transform: scale(.5)
+    }
+    40%{ opacity:1 ;
+      -webkit-transform: scale(1);
+      -moz-transform: scale(1);
+      -ms-transform: scale(1);
+      -o-transform: scale(1);
+      transform: scale(1);
+      -webkit-transform: rotate(60deg);
+      -moz-transform: rotate(60deg);
+      -ms-transform: rotate(60deg);
+      -o-transform: rotate(60deg);
+      transform: rotate(60deg)
+    }
+    100%{ opacity:1;
+      -webkit-transform: rotate(0deg);
+      -moz-transform: rotate(0deg);
+      -ms-transform: rotate(0deg);
+      -o-transform: rotate(0deg);
+      transform: rotate(0deg)
+    }
+  }
+  @keyframes animation7{
+    0%{ opacity:0 ;
+    }
+    30%{ opacity:0 ;
+    }
+    45%{ opacity:1 ;
+      -webkit-transform: rotate(-20deg);
+      -moz-transform: rotate(-20deg);
+      -ms-transform: rotate(-20deg);
+      -o-transform: rotate(-20deg);
+      transform: rotate(-20deg)
+    }
+    60%{ opacity:1 ;
+      -webkit-transform: rotate(20deg);
+      -moz-transform: rotate(20deg);
+      -ms-transform: rotate(20deg);
+      -o-transform: rotate(20deg);
+      transform: rotate(20deg)
+    }
+    70%{ opacity:1 ;
+      -webkit-transform: rotate(0deg);
+      -moz-transform: rotate(0deg);
+      -ms-transform: rotate(0deg);
+      -o-transform: rotate(0deg);
+      transform: rotate(0deg)
+    }
+    100%{ opacity:1;
+    }
+  }
+  @keyframes animation8{
+    0%{
+      opacity:0;
+    }
+    13%{ opacity:0 ;
+      -webkit-transform:translateY(300px);
+      -moz-transform:translateY(300px);
+      -ms-transform:translateY(300px);
+      -o-transform:translateY(300px);
+      transform:translateY(300px);
+    }
+    35%{ opacity:1 ;
+      -webkit-transform:translateY(0px);
+      -moz-transform:translateY(0px);
+      -ms-transform:translateY(0px);
+      -o-transform:translateY(0px);
+      transform:translateY(0px);
+    }
+    100%{ opacity:1;
+    }
+  }
+  @keyframes animation9{
+    0%{ opacity:0 ;
+
+    }
+    30%{ opacity:0 ;
+      -webkit-transform: scale(0);
+      -moz-transform: scale(0);
+      -ms-transform: scale(0);
+      -o-transform: scale(0);
+      transform: scale(0);
+    }
+    55%{ opacity:1 ;
+      -webkit-transform: scale(.9);
+      -moz-transform: scale(.9);
+      -ms-transform: scale(.9);
+      -o-transform: scale(.9);
+      transform: scale(.9);
+    }
+    60%{ opacity:1 ;
+      -webkit-transform: scale(.7);
+      -moz-transform: scale(.7);
+      -ms-transform: scale(.7);
+      -o-transform: scale(.7);
+      transform: scale(.7);
+    }
+    80%{ opacity:1 ;
+      -webkit-transform: scale(1);
+      -moz-transform: scale(1);
+      -ms-transform: scale(1);
+      -o-transform: scale(1);
+      transform: scale(1);
+    }
+    100%{ opacity:1;
+    }
+  }
+  @keyframes animation10{
+    0%{ opacity:0 ;
+
+    }
+    30%{ opacity:0 ;
+      -webkit-transform: scale(0);
+      -moz-transform: scale(0);
+      -ms-transform: scale(0);
+      -o-transform: scale(0);
+      transform: scale(0);
+    }
+    55%{ opacity:1 ;
+      -webkit-transform: scale(.9);
+      -moz-transform: scale(.9);
+      -ms-transform: scale(.9);
+      -o-transform: scale(.9);
+      transform: scale(.9);
+    }
+    60%{ opacity:1 ;
+      -webkit-transform: scale(.7);
+      -moz-transform: scale(.7);
+      -ms-transform: scale(.7);
+      -o-transform: scale(.7);
+      transform: scale(.7);
+    }
+    80%{ opacity:1 ;
+      -webkit-transform: scale(1);
+      -moz-transform: scale(1);
+      -ms-transform: scale(1);
+      -o-transform: scale(1);
+      transform: scale(1);
+    }
+    100%{ opacity:1;
+    }
+  }
+  @keyframes animation11{
+    0%{ opacity:0 ;
+
+    }
+    30%{ opacity:0 ;
+      -webkit-transform: scale(0);
+      -moz-transform: scale(0);
+      -ms-transform: scale(0);
+      -o-transform: scale(0);
+      transform: scale(0);
+    }
+    55%{ opacity:1 ;
+      -webkit-transform: scale(.9);
+      -moz-transform: scale(.9);
+      -ms-transform: scale(.9);
+      -o-transform: scale(.9);
+      transform: scale(.9);
+    }
+    60%{ opacity:1 ;
+      -webkit-transform: scale(.7);
+      -moz-transform: scale(.7);
+      -ms-transform: scale(.7);
+      -o-transform: scale(.7);
+      transform: scale(.7);
+    }
+    80%{ opacity:1 ;
+      -webkit-transform: scale(1);
+      -moz-transform: scale(1);
+      -ms-transform: scale(1);
+      -o-transform: scale(1);
+      transform: scale(1);
+    }
+    100%{ opacity:1;
+    }
+  }
+  @keyframes animation12{
+    0%{ opacity:0 ;
+
+    }
+    30%{ opacity:0 ;
+      -webkit-transform: scale(0);
+      -moz-transform: scale(0);
+      -ms-transform: scale(0);
+      -o-transform: scale(0);
+      transform: scale(0);
+    }
+    55%{ opacity:1 ;
+      -webkit-transform: scale(.9);
+      -moz-transform: scale(.9);
+      -ms-transform: scale(.9);
+      -o-transform: scale(.9);
+      transform: scale(.9);
+    }
+    60%{ opacity:1 ;
+      -webkit-transform: scale(.7);
+      -moz-transform: scale(.7);
+      -ms-transform: scale(.7);
+      -o-transform: scale(.7);
+      transform: scale(.7);
+    }
+    80%{ opacity:1 ;
+      -webkit-transform: scale(1);
+      -moz-transform: scale(1);
+      -ms-transform: scale(1);
+      -o-transform: scale(1);
+      transform: scale(1);
+    }
+    100%{ opacity:1;
+    }
+  }
+  @keyframes animation13{
+    0%{ opacity:0 ;
+
+    }
+    30%{ opacity:0 ;
+      -webkit-transform: scale(0);
+      -moz-transform: scale(0);
+      -ms-transform: scale(0);
+      -o-transform: scale(0);
+      transform: scale(0);
+    }
+    55%{ opacity:1 ;
+      -webkit-transform: scale(.9);
+      -moz-transform: scale(.9);
+      -ms-transform: scale(.9);
+      -o-transform: scale(.9);
+      transform: scale(.9);
+    }
+    60%{ opacity:1 ;
+      -webkit-transform: scale(.7);
+      -moz-transform: scale(.7);
+      -ms-transform: scale(.7);
+      -o-transform: scale(.7);
+      transform: scale(.7);
+    }
+    80%{ opacity:1 ;
+      -webkit-transform: scale(1);
+      -moz-transform: scale(1);
+      -ms-transform: scale(1);
+      -o-transform: scale(1);
+      transform: scale(1);
+    }
+    100%{ opacity:1;
+    }
+  }
+</style>

+ 362 - 0
components/default/christmas.vue

@@ -0,0 +1,362 @@
+<template>
+  <div class="christmas" v-if="hasOpen">
+    <div class="christmas-modal">
+      <div class="christmas-info" v-if="!hasNewYear">
+        <a href="/activity/business" target="_blank"></a>
+        <a href="javascript:void(0)" @click="close"></a>
+        <div class="christmas-img">
+          <img src="/images/christmas/christmas1.png">
+          <img src="/images/christmas/christmas2.png">
+          <img src="/images/christmas/christmas4.png">
+        </div>
+      </div>
+      <div class="festival-info" v-if="hasNewYear">
+        <div class="festival-img">
+          <img src="/images/christmas/festival_bg.png">
+          <img src="/images/christmas/festival_deng1.png">
+          <img src="/images/christmas/festival_deng2.png">
+          <img src="/images/christmas/festival_deng1.png">
+          <img src="/images/christmas/festival_deng2.png">
+          <img src="/images/christmas/festival_yanhuaright.gif">
+          <img src="/images/christmas/festival_yanhualeft.gif">
+        </div>
+        <a href="/activity/business" target="_blank">马上开店</a>
+        <a href="https://account.ubtob.com/sso/login?returnURL=https%253A%252F%252Fwww.usoftmall.com%252F&appId=mall&baseUrl=https%3A%2F%2Fwww.usoftmall.com%2Flogin%2Fother" target="_blank">立刻购买</a>
+        <a href="javascript:void(0)" @click="close"></a>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+    export default {
+      name: 'christmas',
+      props: ['hasNewYear'],
+      data () {
+        return {
+          hasOpen: true
+        }
+      },
+      methods: {
+        close () {
+          this.hasOpen = false
+          this.$emit('listenopen')
+        }
+      }
+    }
+</script>
+
+<style scoped>
+  .christmas{
+    position:fixed;
+    top:0;
+    left:0;
+    z-index:10000;
+    width:100%;
+    height:100%;
+  }
+  .christmas-modal{
+    background:rgba(0,0,0,.6);
+    width:100%;
+    height:100%;
+  }
+  .christmas-info{
+    position:absolute;
+    top:50%;
+    left:50%;
+    transform: translate(-50%, -50%);
+    width:985px;
+    height:740px;
+  }
+  .festival-info{
+    position:absolute;
+    top:50%;
+    left:50%;
+    transform: translate(-50%, -50%);
+    width:683px;
+    height:613px;
+  }
+  .christmas-info a, .festival-info a{
+    position:relative;
+    z-index:100000;
+    display:block;
+    width:190px;
+    height:52px;
+    line-height: 52px;
+    text-align: center;
+  }
+  .festival-info a:nth-child(2){
+    top:566px;
+    left:123px;
+    font-size: 28px;
+    font-weight: bold;
+    animation: newYearBtn .2s infinite;
+    -moz-animation: newYearBtn .2s infinite;
+    -o-animation: newYearBtn .2s infinite;
+    -webkit-animation: newYearBtn .2s infinite;
+  }
+  .festival-info a:nth-child(3){
+    top:514px;
+    left:369px;
+    font-size: 28px;
+    font-weight: bold;
+    animation: newYearBtn .2s .1s infinite;
+    -moz-animation: newYearBtn .2s .1s infinite;
+    -o-animation: newYearBtn .2s .1s infinite;
+    -webkit-animation: newYearBtn .2s .1s infinite;
+  }
+  .festival-info a:nth-child(4){
+    top:447px;
+    left:630px;
+    width: 45px;
+    height: 45px;
+    background: url('/images/christmas/close.png')no-repeat center center;
+  }
+  .christmas-info a:first-child{
+    top:72%;
+    left:39%;
+    width:200px;
+    height:50px;
+    background: url('/images/christmas/btn.png')no-repeat center center;
+    animation: christmas1 1s linear infinite;
+    -o-animation: christmas1 1s linear infinite;
+    -webkit-animation: christmas1 1s linear infinite;
+    -moz-animation: christmas1 1s linear infinite;
+  }
+  .christmas-info a:first-child:hover{
+    animation: none;
+    cursor:pointer;
+   }
+  .christmas-info a:nth-child(2){
+    top:8%;
+    left:85%;
+    width: 45px;
+    height: 45px;
+    background: url('/images/christmas/close.png')no-repeat center center;
+  }
+  .christmas-info .christmas-img img{
+    position:absolute;
+    top:50%;
+    left:50%;
+    transform: translate(-50%, -50%);
+  }
+  .festival-info .festival-img{
+    position:relative;
+  }
+  .festival-info .festival-img img{
+    position:absolute;
+  }
+  .festival-info .festival-img img:nth-child(2){
+    top:219px;
+    left:-35px;
+    -webkit-transform-origin: top center;
+    -moz-transform-origin: top center;
+    -ms-transform-origin: top center;
+    -o-transform-origin: top center;
+    transform-origin: top center;
+    animation:newYearImg 7s linear 3.5s infinite;
+    -o-animation:newYearImg 7s linear 3.5s infinite;
+    -webkit-animation:newYearImg 7s linear 3.5s infinite;
+    -moz-animation:newYearImg 7s linear 3.5s infinite;
+  }
+  .festival-info .festival-img img:nth-child(3){
+    top:80px;
+    left:17px;
+    -webkit-transform-origin: top center;
+    -moz-transform-origin: top center;
+    -ms-transform-origin: top center;
+    -o-transform-origin: top center;
+    transform-origin: top center;
+    animation:newYearImg 5s linear 2.5s infinite;
+    -o-animation:newYearImg 5s linear 2.5s infinite;
+    -webkit-animation:newYearImg 5s linear 2.5s infinite;
+    -moz-animation:newYearImg 5s linear 2.5s infinite;
+  }
+  .festival-info .festival-img img:nth-child(4){
+    top:219px;
+    left:641px;
+    -webkit-transform-origin: top center;
+    -moz-transform-origin: top center;
+    -ms-transform-origin: top center;
+    -o-transform-origin: top center;
+    transform-origin: top center;
+    animation:newYearImg 7s linear infinite;
+    -o-animation:newYearImg 7s linear infinite;
+    -moz-animation:newYearImg 7s linear infinite;
+    -webkit-animation:newYearImg 7s linear infinite;
+  }
+  .festival-info .festival-img img:nth-child(5){
+    top:80px;
+    left:613px;
+    -webkit-transform-origin: top center;
+    -moz-transform-origin: top center;
+    -ms-transform-origin: top center;
+    -o-transform-origin: top center;
+    transform-origin: top center;
+    animation:newYearImg 5s linear infinite;
+    -o-animation:newYearImg 5s linear infinite;
+    -moz-animation:newYearImg 5s linear infinite;
+    -webkit-animation:newYearImg 5s linear infinite;
+  }
+  .festival-info .festival-img img:nth-child(6){
+    top:-165px;
+    left:615px;
+    opacity:.75;
+    /*animation: newYearYanHua 5s infinite;*/
+  }
+  .festival-info .festival-img img:nth-child(7){
+    top:420px;
+    left:-105px;
+    opacity:.75;
+    /*animation: newYearYanHua 5s 1s infinite;*/
+  }
+  .christmas-info .christmas-img img:nth-child(2){
+    animation: christmas2 25s infinite;
+    -moz-animation: christmas2 25s infinite;
+    -o-animation: christmas2 25s infinite;
+    -webkit-animation: christmas2 25s infinite;
+  }
+  .christmas-info .christmas-img img:nth-child(3){
+    animation: christmas3 30s infinite;
+    -o-animation: christmas3 30s infinite;
+    -webkit-animation: christmas3 30s infinite;
+    -moz-animation: christmas3 30s infinite;
+  }
+  @keyframes christmas1 {
+    0%{top:72%}
+    25%{top:71.9%}
+    50%{top:72.9%}
+    75%{top:71.9%}
+    100%{top:72%}
+  }
+  @keyframes christmas2 {
+    0%{top:40%;left:50%;opacity: 0}
+    25%{left:48%;opacity: 1}
+    50%{left:53%}
+    75%{left:48%; opacity: 1}
+    100%{top:45%;left:50%;opacity: 0}
+  }
+  @keyframes christmas3 {
+    0%{top:20%;left:50%;opacity: 0}
+    25%{left:48%;opacity: 1}
+    50%{left:53%}
+    75%{left:48%; opacity: 1}
+    100%{top:30%;left:50%;opacity: 0}
+  }
+  @-moz-keyframes christmas1 {
+    0%{top:72%}
+    25%{top:71.9%}
+    50%{top:72.9%}
+    75%{top:71.9%}
+    100%{top:72%}
+  }
+  @-moz-keyframes christmas2 {
+    0%{top:40%;left:50%;opacity: 0}
+    25%{left:48%;opacity: 1}
+    50%{left:53%}
+    75%{left:48%; opacity: 1}
+    100%{top:45%;left:50%;opacity: 0}
+  }
+  @-moz-keyframes christmas3 {
+    0%{top:20%;left:50%;opacity: 0}
+    25%{left:48%;opacity: 1}
+    50%{left:53%}
+    75%{left:48%; opacity: 1}
+    100%{top:30%;left:50%;opacity: 0}
+  }
+  @-webkit-keyframes christmas1 {
+    0%{top:72%}
+    25%{top:71.9%}
+    50%{top:72.9%}
+    75%{top:71.9%}
+    100%{top:72%}
+  }
+  @-webkit-keyframes christmas2 {
+    0%{top:40%;left:50%;opacity: 0}
+    25%{left:48%;opacity: 1}
+    50%{left:53%}
+    75%{left:48%; opacity: 1}
+    100%{top:45%;left:50%;opacity: 0}
+  }
+  @-webkit-keyframes christmas3 {
+    0%{top:20%;left:50%;opacity: 0}
+    25%{left:48%;opacity: 1}
+    50%{left:53%}
+    75%{left:48%; opacity: 1}
+    100%{top:30%;left:50%;opacity: 0}
+  }
+  @-o-keyframes christmas1 {
+    0%{top:72%}
+    25%{top:71.9%}
+    50%{top:72.9%}
+    75%{top:71.9%}
+    100%{top:72%}
+  }
+  @-o-keyframes christmas2 {
+    0%{top:40%;left:50%;opacity: 0}
+    25%{left:48%;opacity: 1}
+    50%{left:53%}
+    75%{left:48%; opacity: 1}
+    100%{top:45%;left:50%;opacity: 0}
+  }
+  @-o-keyframes christmas3 {
+    0%{top:20%;left:50%;opacity: 0}
+    25%{left:48%;opacity: 1}
+    50%{left:53%}
+    75%{left:48%; opacity: 1}
+    100%{top:30%;left:50%;opacity: 0}
+  }
+  @keyframes newYearBtn {
+    0%{color:#000}
+    50%{color:#fe0000;}
+    100%{color:#000}
+  }
+  @-o-keyframes newYearBtn {
+    0%{color:#000}
+    50%{color:#fe0000;}
+    100%{color:#000}
+  }
+  @-moz-keyframes newYearBtn {
+    0%{color:#000}
+    50%{color:#fe0000;}
+    100%{color:#000}
+  }
+  @-webkit-keyframes newYearBtn {
+    0%{color:#000;}
+    50%{color:#fe0000;}
+    100%{color:#000;}
+  }
+  @keyframes newYearImg {
+    0%{transform: rotate(0deg);}
+    25%{transform: rotate(-15deg);}
+    50%{transform: rotate(0deg);}
+    75%{transform: rotate(15deg);}
+    100%{transform: rotate(0deg);}
+  }
+  @-o-keyframes newYearImg {
+    0%{transform: rotate(0deg);}
+    25%{transform: rotate(-15deg);}
+    50%{transform: rotate(0deg);}
+    75%{transform: rotate(15deg);}
+    100%{transform: rotate(0deg);}
+  }
+  @-webkit-keyframes newYearImg {
+    0%{transform: rotate(0deg);}
+    25%{transform: rotate(-15deg);}
+    50%{transform: rotate(0deg);}
+    75%{transform: rotate(15deg);}
+    100%{transform: rotate(0deg);}
+  }
+  @-moz-keyframes newYearImg {
+    0%{transform: rotate(0deg);}
+    25%{transform: rotate(-15deg);}
+    50%{transform: rotate(0deg);}
+    75%{transform: rotate(15deg);}
+    100%{transform: rotate(0deg);}
+  }
+  @keyframes newYearYanHua {
+    0%{opacity:1;transform:scale(0);}
+    26%{opacity:1;transform:scale(.7);}
+    100%{transform:scale(1);opacity:0;}
+  }
+</style>

+ 3 - 1
components/default/index.js

@@ -1,5 +1,7 @@
 import Header from './Header.vue'
 import Footer from './Footer.vue'
 import RightBar from './RightBar.vue'
+import Christmas from './christmas.vue'
+import ZhongQiu from './Zhongqiu.vue'
 
-export { Header, Footer, RightBar }
+export { Header, Footer, RightBar, Christmas, ZhongQiu }

+ 13 - 3
components/home/Carousel.vue

@@ -30,7 +30,10 @@
         activeSlide: 0,
         swiperOption: {
           autoplay: 6000,
+          initialSlide: 0,
           pagination: '.swiper-pagination',
+          // 解决点击分页器后图片就不能轮播的问题
+          autoplayDisableOnInteraction: false,
           paginationClickable: true,
           mousewheelControl: false,
           effect: 'fade',
@@ -47,15 +50,22 @@
             if (this.banners.data.length && swiper.activeIndex <= 0) {
               swiper.activeIndex = this.banners.data.length
             }
-            document.querySelector('.carousel').style.backgroundColor =
-              this.banners.data[swiper.activeIndex - 1].metadata['background-color']
+            let carousel = document.querySelector('.carousel')
+            if (carousel && carousel !== null) {
+              carousel.style.backgroundColor =
+                this.banners.data[swiper.activeIndex - 1].metadata['background-color']
+            }
           }
         }
       }
     },
     computed: {
       banners () {
-        return this.$store.state.carousel.banners
+        let banner = this.$store.state.carousel.banners
+        banner.data.sort(function (a, b) {
+          return a.orderNumber - b.orderNumber
+        })
+        return banner
       },
       activeColor () {
         return this.banners.data.length ? this.banners.data[this.activeSlide].metadata['background-color'] : null

+ 46 - 24
components/main/Search.vue

@@ -37,8 +37,14 @@
     <div class="search-hot">
       <ul class="list-untyled">
         <li class="item item-first">热门搜索</li>
-        <li class="item" v-for="w in hotwords">
-          <nuxt-link :to="w.url" target="_blank">{{ w.name }}</nuxt-link>
+        <li class="item" v-for="w in hotBrand" v-if="ifFloorsHotSearchInValid">
+          <nuxt-link :to="'/product/brand/' + w.uuid" target="_blank">{{ w.nameEn }}</nuxt-link>
+        </li>
+        <li class="item" v-for="w in hotDevice" v-if="ifFloorsHotSearchInValid">
+          <nuxt-link :to="'/product/component/' + w.uuid" target="_blank">{{ w.code }}</nuxt-link>
+        </li>
+        <li class="item" v-if="!ifFloorsHotSearchInValid && index > 0" v-for="(w, index) in hotSearchData.items">
+          <a :href="w.hrefUrl" target="_blank">{{w.body}}</a>
         </li>
       </ul>
     </div>
@@ -60,6 +66,12 @@
       }
     },
     computed: {
+      hotDevice () {
+        return this.$store.state.hotSearchDevice.hot.data
+      },
+      hotBrand () {
+        return this.$store.state.hotSearchBrand.hot.data
+      },
       similarKeywords () {
         return this.$store.state.search.keywords
       },
@@ -68,26 +80,22 @@
           this.associate.show &&
           this.similarKeywords.data &&
           (this.similarKeywords.data.brand || this.similarKeywords.data.component || this.similarKeywords.data.kind)
-      }
-    },
-    props: {
-      hotwords: {
-        type: Array,
-        default () {
-          return [{
-            name: 'SCT2080KEC',
-            url: '/product/component/1100400300009990'
-          }, {
-            name: '电池组',
-            url: '/product/kind/346'
-          }, {
-            name: 'Vishay',
-            url: '/product/brand/30327265e42a871be050007f01003d96'
-          }, {
-            name: 'Panasonic',
-            url: '/product/brand/30327265e47d871be050007f01003d96'
-          }]
+      },
+      hotSearchData () {
+        let list = this.$store.state.floor.list_v3.data
+        let obj = {}
+        if (list && list.length > 0) {
+          obj = list.find(item => item.floorNumber === 2) || {}
+        }
+        return obj
+      },
+      ifFloorsHotSearchInValid () {
+        let obj = this.hotSearchData
+        if (obj.items && obj.items.length) {
+          let result = obj.items.find(item => !item.body || item.body === '') || true
+          return result !== true
         }
+        return true
       }
     },
     watch: {
@@ -150,6 +158,7 @@
         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')
@@ -176,7 +185,7 @@
     }
   }
 </script>
-<style lang="scss" scoped>
+<style lang="scss" scoped type="text/scss">
   @import '~assets/scss/variables';
   .form-control{
     border-radius: 0;
@@ -206,16 +215,29 @@
       width: 79px;
       border-radius: 0;
     }
+    .search-hot ul{
+      line-height: 12px;
+    }
     .search-hot ul li a{
       color: #838383;
     }
     .search-hot {
+      margin-top:5px;
       .item {
         display: inline-block;
+        max-width:22%;
+        text-align: center;
+        vertical-align: middle;
         font-size: $font-size-small;
-        margin-right: $pad;
-
+        padding-right: $pad;
+        a{
+          display:block;
+          overflow: hidden;
+          text-overflow: ellipsis;
+          white-space: nowrap;
+        }
         &.item-first {
+          width:12%;
           color: $red;
         }
       }

+ 289 - 0
components/mobile/Home.vue

@@ -0,0 +1,289 @@
+<template>
+  <div class="home">
+    <div class="mobile-modal" v-if="showStoreInfo">
+      <div class="mobile-modal-box">
+        <div class="mobile-modal-header">联系方式<i @click="showStoreInfo = false" class="icon-guanbi iconfont"></i></div>
+        <div class="mobile-modal-content">
+          <div>商家地址:深圳市南山区英唐大厦6楼</div>
+         <!-- <div class="content-line link-url">在线咨询</div>-->
+          <div>致电:<a href="tel:4008301818" target="_blank" class="content-line link-url">4008301818</a></div>
+          <div>邮件:<a href="mailto:yrsc@usoftchina.com" target="_blank" class="content-line link-url">yrsc@usoftchina.com</a></div>
+        </div>
+      </div>
+    </div>
+    <div v-if="!showMainSearch">
+      <div class="home-header" :style="'background:url(' + bgUrl + ')no-repeat center center/100% 6.14rem'">
+        <!--<a @click="goLastPage"><i class="iconfont icon-fanhui"></i></a>-->
+        <div class="home-search">
+          <!--<ul>-->
+          <!--<li :class="activeType=='model'?'active':''" @click="activeType='model'"><span>型号</span></li>-->
+          <!--<li :class="activeType=='brand'?'active':''" @click="activeType='brand'"><span>品牌</span></li>-->
+          <!--<li :class="activeType=='shops'?'active':''" @click="activeType='shops'"><span>商家</span></li>-->
+          <!--</ul>-->
+          <div class="home-input">
+            <input type="text" placeholder="请输入您要查找的型号或品牌"
+                   @click="onHomeSearchClick()"/>
+            <i class="iconfont icon-sousuo"></i>
+          </div>
+          <!--<p style="color:#e45803;line-height:.4rem;margin-top:.1rem;width:4.2rem;margin-left:1rem;">搜品牌、搜现货 、搜好店 、搜规格书 就上优软商城</p>-->
+        </div>
+      </div>
+      <div class="home-main">
+        <nuxt-link to="/mobile/shop" class="home-main-content">
+          <div>
+            <img src="/images/mobile/@2x/home/shopbrand@2x.png">
+          </div>
+          <p>店铺列表</p>
+        </nuxt-link>
+        <nuxt-link to="/mobile/brand/brandCenter/ABCD" class="home-main-content">
+          <div>
+            <!--<i class="icon-pinpai iconfont"></i>-->
+            <img src="/images/mobile/@2x/home/brand@2x.png" alt="">
+          </div>
+          <!--<h2>
+            {{numbrand[0]}}
+          </h2>-->
+          <p>品牌列表</p>
+        </nuxt-link>
+        <a @click="goCollect" class="home-main-content">
+          <div>
+            <img src="/images/mobile/@2x/home/storebrand@2x.png">
+          </div>
+          <p>我的收藏</p>
+        </a>
+        <a @click="showStoreInfo = true" class="home-main-content">
+          <div>
+            <img src="/images/mobile/@2x/home/phonebrand@2x.png">
+          </div>
+          <p>联系我们</p>
+        </a>
+        <!--<a class="home-main-content">
+          <div>
+            <i class="icon-xinghao iconfont"></i>
+          </div>
+          <h2>
+            {{numbrand[1]}}
+          </h2>
+          <p>型号</p>
+        </a>
+        <a class="home-main-content">
+          <div>
+            <i class="icon-biaoguigeshuomingshu iconfont"></i>
+          </div>
+          <h2>
+            {{numbrand[2]}}
+          </h2>
+          <p>规格书</p>
+        </a>-->
+      </div>
+    </div>
+    <main-search v-else @cancelSearchAction="onCancelSearch"></main-search>
+    <login-box @onLoginBoxClose="showLoginBox = false" v-if="showLoginBox"></login-box>
+  </div>
+</template>
+
+<script>
+  import MainSearch from '~/components/mobile/search/MainSearch.vue'
+  import {LoginBox} from '~components/mobile/common'
+  export default {
+    name: 'home',
+    data () {
+      return {
+        activeType: 'model',
+        showMainSearch: false,
+        showStoreInfo: false,
+        isMore: false,
+        isShow: false,
+        len: 0,
+        bgUrl: '/images/mobile/@2x/home/background@2x.png',
+        showLoginBox: false
+      }
+    },
+    components: {
+      MainSearch,
+      LoginBox
+    },
+    methods: {
+      onHomeSearchClick () {
+        this.showMainSearch = true
+        this.$store.dispatch('searchData/getSearchHistory')
+      },
+      matNumber (num) {
+        if (num > 99999999) {
+          this.isShow = true
+          let str2 = num.toString()
+          num = Math.floor(num / 100000000)
+          if (parseInt(str2.charAt(str2.length - 8)) > 8) {
+            num = num + 1
+          }
+          num += '亿'
+        }
+        if (num > 9999) {
+          this.isMore = true
+          let str = num.toString()
+          num = Math.floor(num / 10000)
+          if (parseInt(str.charAt(str.length - 4)) > 4) {
+            num = num + 1
+          }
+          num += '万'
+        } else {
+          num += '个'
+        }
+        return num
+      },
+      forNum (numbers) {
+        let num = []
+        for (let i = 0; i < numbers.length; i++) {
+          num.push(this.matNumber(numbers[i].count))
+        }
+        return num
+      },
+      onCancelSearch: function () {
+        this.showMainSearch = false
+      },
+      goCollect: function () {
+        if (this.user.logged) {
+          this.$router.push('/mobile/user')
+        } else {
+          this.showLoginBox = true
+        }
+      },
+      goLastPage: function () {
+        window.history.back(-1)
+      }
+    },
+    computed: {
+      numbrand () {
+        return this.forNum(this.counts)
+      },
+      counts () {
+        return this.$store.state.product.common.counts.data
+      },
+      user () {
+        return this.$store.state.option.user
+      }
+    }
+  }
+</script>
+
+<style lang="scss" scoped>
+  .home{
+    font-size: .28rem;
+    background: #f7fbff;
+    position: fixed;
+    top: 0;
+    bottom: .98rem;
+    width: 100%;
+    overflow-y: auto;
+    .home-header{
+      width:100%;
+      height:6.12rem;
+      >a{
+        font-size:.28rem;
+        color:#fff;
+        position: absolute;
+        left: .1rem;
+        top: .2rem;
+        i{
+          font-size: .48rem;
+          margin-right: -.1rem;
+          color: #666;
+        }
+      }
+      .home-search{
+        width:6rem;
+        line-height: .3rem;
+        margin:0 auto;
+        text-align: center;
+        padding-top: 1.74rem;
+        ul{
+          display:inline-flex;
+        li{
+          flex:1;
+          text-align:center;
+          >span{
+             display:inline-block;
+             width:.72rem;
+             line-height:.33rem;
+             height:.33rem;
+             background: #fff;
+             color:#000;
+             border-radius: .05rem .05rem 0 0 ;
+           }
+          }
+          li.active span{
+              background: #3c7cf5;
+              color:#fff;
+              cursor:pointer;
+          }
+        }
+        .home-input{
+          width: 6rem;
+          height: .61rem;
+          line-height: .61rem;
+          input{
+            width:5.17rem;
+            display: inline-block;
+            padding: 0 1rem 0 .16rem;
+            margin-right:-.83rem;
+            font-size:.24rem;
+            border:.04rem solid #3c7cf5;
+            border-radius:.05rem;
+          }
+          i{
+             display:inline-block;
+             text-align: center;
+             width:.83rem;
+             font-size:.33rem;
+             border-left:none;
+             color: #999;
+            vertical-align: middle;
+          }
+        }
+      }
+    }
+    }
+    .home-main{
+      text-align: center;
+      padding-top: .46rem;
+    }
+    .home-main a.home-main-content {
+      width:50%;
+      margin-bottom:.52rem;
+      display: inline-block;
+    }
+    .home-main .home-main-content div{
+      border-radius: .2rem;
+      width:1.14rem;
+      height:1.14rem;
+      margin:0 auto;
+    }
+    .home-main .home-main-content div>img{
+      width: 100%;
+      height:100%;
+    }
+  .home-main .home-main-content div>i {
+    font-size: .8rem;
+  }
+  .home-main .home-main-content:nth-child(3) div>i {
+    color: #ff3064;
+  }
+  /*.home-main .home-main-content:nth-child(5) div>i {
+    color: #fa6743;
+  }
+  .home-main .home-main-content:nth-child(6) div>i {
+    color: #fcb836;
+  }*/
+    .home-main .home-main-content p{
+      font-size:.28rem;
+      color:rgb(51,51,51);
+      line-height: .52rem;
+    }
+    .home-main .home-main-content h2{
+      font-size:.3rem;
+      color:#ff7800;
+      line-height: .32rem;
+      margin:0;
+      margin-top:.1rem;
+    }
+</style>

+ 118 - 0
components/mobile/MobileFooter.vue

@@ -0,0 +1,118 @@
+<template>
+  <div class="mobile-footer">
+    <span :class="activeType=='home'?'active':''">
+      <nuxt-link to="/">
+        <i :class="activeType=='home'?'iconfont icon-shouye':'iconfont icon-shouye1'"></i><p>首页</p>
+      </nuxt-link>
+    </span>
+    <span :class="activeType=='shops'?'active':''">
+      <nuxt-link to="/mobile/shop">
+        <i :class="activeType=='shops'?'iconfont icon-dianpu':'iconfont icon-dianpu1'"></i><p>店铺</p>
+      </nuxt-link>
+    </span>
+    <span :class="activeType=='user'?'active':''">
+      <a @click="goCollect">
+        <i :class="activeType=='user'?'iconfont icon-icon':'iconfont icon-wo'"></i><p>我</p>
+      </a>
+    </span>
+    <a @click="toTop" v-show="!hideToTop"><i class="iconfont icon-arrow-up icon-xlg"></i></a>
+    <login-box @onLoginBoxClose="showLoginBox = false" v-if="showLoginBox"></login-box>
+  </div>
+</template>
+<script>
+  import { scrollTo } from '~utils/scroll'
+  import {LoginBox} from '~components/mobile/common'
+  export default{
+    name: 'MobileFooter',
+    data () {
+      return {
+        hideToTop: true,
+        showLoginBox: false
+      }
+    },
+    components: {
+      LoginBox
+    },
+    computed: {
+      activeType () {
+        return this.$route.path === '/' ? 'home' : this.$route.path === '/mobile/shop' ? 'shops' : this.$route.path === '/mobile/user' ? 'user' : ''
+      },
+      user () {
+        return this.$store.state.option.user
+      }
+    },
+    mounted: function () {
+      this.$nextTick(function () {
+        window.addEventListener('scroll', this.onScroll)
+      })
+    },
+    methods: {
+      onScroll () {
+        let scrolled = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop
+        if (scrolled > window.screen.availHeight) {
+          this.hideToTop = false
+        } else {
+          this.hideToTop = true
+        }
+      },
+      toTop () {
+        scrollTo('body', 300)
+      },
+      goCollect: function () {
+        if (this.user.logged) {
+          this.$router.push('/mobile/user')
+        } else {
+          this.showLoginBox = true
+        }
+      }
+    }
+  }
+</script>
+<style scoped>
+  .mobile-footer{
+    position:fixed;
+    bottom:0;
+    width:100%;
+    height:.98rem;
+    text-align: center;
+    border-top:.04rem solid #ccc;
+    background: #ffffff;
+    z-index: 10;
+  }
+  .mobile-footer span{
+    display: inline-block;
+    width: 2.5rem;
+    font-size:.32rem;
+    color:#b0b0b0;
+    padding-top:.1rem;
+  }
+
+  .mobile-footer span a{
+    color:#b0b0b0;
+  }
+
+  .mobile-footer span a i{
+    font-size:.45rem;
+  }
+  .mobile-footer span a p{
+    font-size:.22rem;
+  }
+
+  .mobile-footer span.active a{
+    color:#3976f4;
+  }
+  .mobile-footer >a {
+    position: absolute;
+    right: .1rem;
+    top: -1rem;
+    background: rgba(0,0,0,.4);
+    color: #fff;
+    width: .88rem;
+    height: .88rem;
+    line-height: .88rem;
+    border-radius: 100%;
+  }
+  .mobile-footer >a i{
+    font-size: .46rem;
+  }
+</style>

+ 319 - 0
components/mobile/MobileHeader.vue

@@ -0,0 +1,319 @@
+<template>
+  <div class="mobile-nav">
+   <!-- <div class="mobile-modal" v-if="showStoreInfo || showShare" @click="cancelModal">
+      <div class="mobile-modal-box" v-if="showStoreInfo" @click="stopPropagation($event)">
+        <div class="mobile-modal-header">联系方式<i @click="showStoreInfo = false" class="icon-guanbi iconfont"></i></div>
+        <div class="mobile-modal-content" v-if="showDefaultAddr">
+          <div>商家地址:深圳市南山区英唐大厦6楼</div>
+          <div class="content-line link-url">在线咨询</div>
+          <div>致电:<a href="tel:0755-96586323" class="content-line link-url">0755-96586323</a></div>
+          <div>邮件:<a href="mailto:yrsc@usoftchina.com" class="content-line link-url">yrsc@usoftchina.com</a></div>
+        </div>
+        <div class="mobile-modal-content" v-if="!showDefaultAddr">
+        <div>商家地址:{{store.enterprise.enAddress || store.enterprise.address}}</div>
+        <div class="content-line link-url">在线咨询</div>
+        <div>致电:<a :href="'tel:'+store.enterprise.enTel" class="content-line link-url">{{store.enterprise.enTel}}</a></div>
+          <div>邮件:<a :href="'mailto:'+store.enterprise.enEmail" class="content-line link-url">{{store.enterprise.enEmail}}</a></div>
+        </div>
+      </div>
+      <div class="mobile-share-box" v-if="showShare" @click="stopPropagation($event)">
+        <div class="share-area">
+          <ul>
+            <li class="share-item" @click="shareWeChat">
+             <i class="icon-weixin iconfont" style="color: #07af12;"></i>
+              <span>微信</span>
+            </li>
+            <li class="share-item" @click="shareQQ">
+              <i class="icon-qq1 iconfont" style="color: #5872f4;"></i>
+              <span>QQ</span>
+            </li>
+            <li class="share-item" @click="shareWeibo">
+              <i class="icon-ff0000 iconfont" style="color: #ff0000;"></i>
+              <span>微博</span>
+            </li>
+            <li class="share-item" @click="shareMessage">
+              <i class="icon-msnui-msg-invert iconfont" style="color: #25cdb7"></i>
+              <span>短信</span>
+              <a href="sms:" class="hide" id="share-sms"></a>
+            </li>
+            <li class="share-item" @click="shareEmail">
+              <i class="icon-youjian iconfont" style="height: .57rem;font-size: .41rem;color:#f18215;"></i>
+              <span>邮件</span>
+              <a href="mailto:" class="hide" id="share-mail"></a>
+            </li>
+            <li class="share-item" @click="flash">
+              <i class="icon-shuaxin iconfont" style="color: #2584cd;"></i>
+              <span>刷新</span>
+            </li>
+            <li class="share-item" @click="copyLink" id="copyLink"  :data-clipboard-text="url">
+              <i class="icon-lianjie iconfont" style="color: #73b0df;"></i>
+              <span>复制链接</span>
+            </li>
+          </ul>
+        </div>
+        <div class="cancel-share" @click="showShare=false">取消</div>
+      </div>
+    </div>-->
+    <div class="mobile-header" v-if="showHeader && !showMainSearch">
+      <a @click="goLastPage"><i class="iconfont icon-fanhui"></i></a>
+      <p>{{title}}
+        <span @click="goMainSearch"><i class="icon-sousuo iconfont"></i>搜索</span>
+      </p>
+    </div>
+    <main-search v-if="showMainSearch" @cancelSearchAction="onCancelSearch"></main-search>
+<!--    <i v-show="rightIcon=='share'" class="iconfont icon-fenxiang" @click="showShare = true" @touchmove="onTouchMove($event)"></i>
+    <i v-show="rightIcon=='phone'" class="iconfont icon-dianhua" @click="showLink" @touchmove="onTouchMove($event)"></i>-->
+  </div>
+</template>
+<script>
+//  import Clipboard from 'clipboard'
+  import MainSearch from '~/components/mobile/search/MainSearch.vue'
+  export default {
+    data () {
+      return {
+//        showStoreInfo: false,
+//        showShare: false,
+//        rightIcon: 'phone',
+//        showDefaultAddr: true,
+//        url: '',
+//        clipboard: {},
+        showMainSearch: false,
+        title: '优软商城',
+        showHeader: false
+//        showSearch: false
+      }
+    },
+    components: {
+      MainSearch
+    },
+    watch: {
+      $route: function (val, oldVal) {
+        this.showMainSearch = false
+        this.title = this.initHeader(val.path)
+      }
+    },
+    created () {
+      this.title = this.initHeader(this.$route.path)
+    },
+    computed: {
+      brandDetail () {
+        return this.$store.state.brandDetail.detail.data
+      },
+      store () {
+        return this.$store.state.shop.storeInfo.store.data
+      },
+      component () {
+        return this.$store.state.componentDetail.detail.data
+      }
+//      showHeader () {
+//        return this.$route.path !== '/' || !this.$route.path || this.$route.path === ''
+//      },
+//      showSearch () {
+//        return this.$route.path !== '/' && !this.$route.path.startsWith('/mobile/search')
+//      }
+    },
+//    mounted () {
+//      let _this = this
+//      _this.url = window.location.href
+//      _this.clipboard = new Clipboard('#copyLink')
+//      _this.clipboard.on('success', e => {
+//        _this.clipboard.destroy()
+//        _this.showShare = false
+//      })
+//      _this.clipboard.on('error', e => {
+//        alert('浏览器不支持自动复制,请手动复制')
+//        _this.clipboard.destroy()
+//      })
+//    },
+    methods: {
+      goLastPage: function () {
+        window.history.back(-1)
+      },
+      initHeader: function (val) {
+//        if (val !== '/' || !val || val === '') {
+//          this.showHeader = true
+//          this.showSearch = !val.startsWith('/mobile/search')
+//        } else {
+//          this.showHeader = false
+//          this.showSearch = false
+//        }
+        this.showHeader = val !== '/' || !val || val === ''
+//        this.showSearch = val !== '/' && !this.startWith(val, '/mobile/search')
+        let title = '优软商城'
+        if (this.startWith(val, '/mobile/brand/componentDetail/')) {
+          title = this.component.code
+//          this.rightIcon = 'share'
+        } else if (this.startWith(val, '/mobile/brand/brandCenter')) {
+          title = '品牌墙'
+//          this.rightIcon = 'share'
+        } else if (this.startWith(val, '/mobile/brand/')) {
+          if (this.brandDetail.nameCn) {
+            if (this.brandDetail.nameCn !== this.brandDetail.nameEn) {
+              title = this.brandDetail.nameEn + '(' + this.brandDetail.nameCn + ')'
+            } else {
+              title = this.brandDetail.nameCn
+            }
+          } else {
+            if (this.component.brand.nameCn !== this.component.brand.nameEn) {
+              title = this.component.brand.nameEn + '(' + this.component.brand.nameCn + ')'
+            } else {
+              title = this.component.brand.nameCn
+            }
+          }
+//          this.rightIcon = 'share'
+        } else if (this.startWith(val, '/mobile/shop/')) {
+          title = this.store.storeName
+//          this.rightIcon = 'phone'
+        } else if (this.startWith(val, '/mobile/shop')) {
+          title = '店铺列表'
+//          this.rightIcon = 'phone'
+        } else if (this.startWith(val, '/mobile/user')) {
+          title = '我的收藏'
+//          this.rightIcon = 'phone'
+        } else if (this.startWith(val, '/mobile/search')) {
+          title = '搜索结果'
+//          this.rightIcon = 'share'
+        } else if (val === '' || val === '/' || !val) {
+          title = '优软商城'
+//          this.rightIcon = 'phone'
+        } else {
+          title = '优软商城'
+//          this.rightIcon = 'phone'
+        }
+        return title
+      },
+//      showLink: function () {
+//        this.showStoreInfo = true
+//        if (this.$route.path.startsWith('/mobile/shop/')) {
+//          this.showDefaultAddr = false
+//        } else {
+//          this.showDefaultAddr = true
+//        }
+//      },
+//      shareWeibo: function () {
+//        let _shareUrl = 'http://v.t.sina.com.cn/share/share.php?&appkey=895033136'     // 真实的appkey,必选参数
+//        _shareUrl += '&url=' + encodeURIComponent(document.location)     // 参数url设置分享的内容链接|默认当前页location,可选参数
+//        _shareUrl += '&title=' + encodeURIComponent(document.title)    // 参数title设置分享的标题|默认当前页标题,可选参数
+//        _shareUrl += '&source=' + encodeURIComponent('')
+//        _shareUrl += '&sourceUrl=' + encodeURIComponent('')
+//        _shareUrl += '&content=' + 'utf-8'   // 参数content设置页面编码gb2312|utf-8,可选参数
+//        _shareUrl += '&pic=' + encodeURIComponent('')  // 参数pic设置图片链接|默认为空,可选参数
+//        window.open(_shareUrl)
+//        this.showShare = false
+//      },
+//      shareWeChat: function () {
+//      },
+//      shareQQ: function () {
+//        let url = encodeURIComponent(document.location)
+//        let title = encodeURIComponent(document.title)
+//        let source = encodeURIComponent('')
+//        let desc = '优软商城'
+//        let pics = 'http://dfs.ubtob.com/group1/M00/4F/C3/CgpkyFnxWjOAMy5DAAlh1PrLlc8684.png'
+//        window.open('http://connect.qq.com/widget/shareqq/index.html?url=' +
+//          url + '&title=' + title + '&source=' + source + '&desc=' + desc + '&pics=' + pics)
+//        this.showShare = false
+//      },
+//      shareMessage: function () {
+//        document.getElementById('share-sms').click()
+//      },
+//      shareEmail: function () {
+//        document.getElementById('share-mail').click()
+//      },
+//      flash: function () {
+//        window.location.reload()
+//      },
+//      copyLink: function () {
+//        let _this = this
+//        _this.url = window.location.href
+//        _this.clipboard = new Clipboard('#copyLink')
+//      },
+//      onTouchMove: function (e) {
+//        let width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth
+//        let height = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight
+//        let x = Math.min(width - 40, e.touches[0].clientX)
+//        let y = Math.min(height - 40, e.touches[0].clientY)
+//        x = Math.max(0, x)
+//        y = Math.max(0, y)
+//        e.preventDefault()
+//        e.target.style.left = x * 2 / 100.0 + 'rem'
+//        e.target.style.top = y * 2 / 100.0 + 'rem'
+//      },
+      onCancelSearch: function () {
+        this.showMainSearch = false
+      },
+//      cancelModal: function () {
+//        this.showStoreInfo = false
+//        this.showShare = false
+//      },
+      stopPropagation: function (event) {
+        event.stopPropagation()
+      },
+      goMainSearch: function () {
+        this.showMainSearch = true
+        this.$store.dispatch('searchData/getSearchHistory')
+      },
+      startWith: function (str, s) {
+        let reg = new RegExp('^' + s)
+        return reg.test(str)
+      }
+    }
+  }
+</script>
+<style lang="scss" scoped>
+  .mobile-header{
+    position: fixed;
+    top: 0;
+    z-index: 10;
+    width:100%;
+    height:.88rem;
+    line-height: .88rem;
+    border-bottom:.04rem solid #ccc;
+    background: #3e82f5;
+    padding:0 .2rem 0 .1rem;
+    color:#fff;
+  }
+  .mobile-header p{
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+    font-size:.36rem;
+    text-align: center;
+    margin: 0;
+    width: 6rem;
+    padding-left: 1rem;
+  }
+  .mobile-header a{
+    font-size:.28rem;
+    color:#fff;
+    position: absolute;
+  }
+  .mobile-header a i{
+    font-size: .48rem;
+    margin-right: -.1rem;
+  }
+  .mobile-header p span {
+    position: absolute;
+    right: .4rem;
+    font-size: .28rem;
+  }
+  .mobile-header p span i {
+    font-size: .28rem;
+  }
+  .mobile-nav >i{
+    font-size: .4rem;
+    position: fixed;
+    right: .25rem;
+    top: .25rem;
+    z-index: 1000;
+    color: #fff;
+    background: rgba( 0, 0, 0, .251 );
+    width: .8rem;
+    height: .8rem;
+    line-height: .8rem;
+    border-radius: 100%;
+    padding-left: .2rem;
+  }
+  .hide {
+    display: none;
+  }
+</style>

+ 216 - 0
components/mobile/brand/BrandCenter.vue

@@ -0,0 +1,216 @@
+<template>
+  <div class="mobile-brand-center mobile-content">
+    <div class="mobile-brand-wrap">
+      <div class="mobile-brand-header">
+        <img src="/images/mobile/@2x/brand/brandWall.png" alt="">
+        <div class="mobile-brand-index" :class="{'scrolled': isScrolled}">
+          <p>索引:</p>
+          <nuxt-link :to="'/mobile/brand/brandCenter/' + item"
+                     :class="{'active': item == activeIndex}"
+                     :key="key" v-for="(item, key) in initArr">{{item}}</nuxt-link>
+        </div>
+      </div>
+      <div class="mobile-brand-list">
+        <div v-for="(brands, initial) in brandList">
+          <div class="brand-initial">
+            <p v-text="initial" :style="initial === '0~9' ? 'font-size: .28rem': 'font-size: .32rem'"></p>
+            <span>
+              {{initial}}开头共<span>{{brands.length || 0}}</span>个品牌
+            </span>
+          </div>
+          <div class="brand-items">
+            <nuxt-link :to="`/mobile/brand/${brand.uuid}/`" :key="key" v-for="(brand, key) in brands">
+              <div>{{brand.nameEn}}</div>
+              <div v-if="brand.nameCn != brand.nameEn">{{brand.nameCn}}</div>
+            </nuxt-link>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+<script>
+  function sortList (letter) {
+    return function (a, b) {
+      var value1 = a[letter]
+      var value2 = b[letter]
+      if (value1 > value2) {
+        return 1
+      } else if (value1 < value2) {
+        return -1
+      } else {
+        return 0
+      }
+    }
+  }
+  export default {
+    name: 'brandList',
+    data () {
+      return {
+        initArr: [
+          'ABCD', 'EFGH', 'IJKL', 'MNOP', 'QRST', 'UVWX', 'YZ', '0~9'
+        ],
+        activeIndex: this.$route.params.initial,
+        isScrolled: false
+      }
+    },
+    mounted: function () {
+      let _this = this
+      _this.$nextTick(function () {
+        window.addEventListener('scroll', function () {
+          _this.onScroll()
+        }, false)
+      })
+    },
+    watch: {
+      $route: function (val, oldVal) {
+        this.activeIndex = val.params.initial
+      }
+    },
+    computed: {
+      brandList () {
+        let brandsList = this.$store.state.product.brand.brandList.data
+        if (brandsList) {
+          for (let i in brandsList) {
+            brandsList[i] = brandsList[i].sort(sortList('nameEn'))
+          }
+        }
+        let temp = {}
+        let keys = []
+        for (let key in brandsList) {
+          keys.push(key)
+        }
+        keys = keys.sort()
+        for (let i = 0; i < keys.length; i++) {
+          temp[keys[i]] = brandsList[keys[i]]
+        }
+        return temp
+      }
+    },
+    methods: {
+      onScroll () {
+        if (this.startWith(this.$route.path, '/mobile/brand/brandCenter')) {
+          let scrolled = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop
+          this.isScrolled = scrolled > 0
+        }
+      },
+      startWith: function (str, s) {
+        let reg = new RegExp('^' + s)
+        return reg.test(str)
+      }
+    }
+  }
+</script>
+<style lang="scss" scoped>
+  .mobile-brand-center {
+    margin-bottom: .98rem;
+    width: 100%;
+    background: #f7f7f7;
+    padding-top: .24rem;
+    .mobile-brand-wrap {
+      width: 6.96rem;
+      background: #fff;
+      margin: 0 auto;
+      padding: 0 .21rem;
+      border-radius: .1rem;
+      .mobile-brand-header {
+        text-align: center;
+        >img {
+          margin: .24rem auto .19rem;
+          width: 6.09rem;
+          height: .66rem;
+        }
+        .mobile-brand-index {
+          font-size: .3rem;
+          line-height: .62rem;
+          background: #f4fafd;
+          margin: .19rem 0 .25rem 0;
+          padding: 0 .07rem;
+          text-align: left;
+          p {
+            float: left;
+          }
+          a {
+            color: #666;
+            width: 1.1rem;
+            display: inline-block;
+            text-align: center;
+            &.active, &.hover, &.focus {
+              color: #418bf6;
+            }
+          }
+          &.scrolled {
+            position: fixed;
+            top: .88rem;
+            width: 100%;
+            background: #fff;
+            border-bottom: .04rem solid #ccc;
+            left: 0;
+            padding-left: .58rem;
+            margin-top: 0;
+          }
+        }
+      }
+      .mobile-brand-list {
+        font-size: .3rem;
+        .brand-initial {
+          border-bottom: .04rem solid #418bf6;
+          p {
+            width: .64rem;
+            height: .43rem;
+            line-height: .43rem;
+            margin: 0;
+            background: #418bf6;
+            color: #fff;
+            font-size: .32rem;
+            text-align: center;
+            display: inline-block;
+            border-top-left-radius: .05rem;
+            border-top-right-radius: .05rem;
+          }
+          >span {
+            font-size: .22rem;
+            color: #999;
+            >span {
+              color: #418bf6;
+            }
+          }
+        }
+        .brand-items {
+          overflow: hidden;
+          margin-bottom: .2rem;
+          a {
+            overflow: hidden;
+            display: inline-block;
+            color: #333;
+            border-radius: .05rem;
+            background: #fff;
+            margin: .18rem .42rem .12rem 0;
+            height: .78rem;
+            float: left;
+            &:nth-child(3n) {
+              margin-right: 0;
+            }
+            &:active {
+              color: #418bf6;
+            }
+            div {
+              width: 1.9rem;
+              height: .39rem;
+              line-height: .39rem;
+              text-align: left;
+              text-overflow: ellipsis;
+              white-space: nowrap;
+              overflow: hidden;
+              &:nth-child(2) {
+                font-size: .26rem;
+                color: #666;
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+
+</style>

+ 563 - 0
components/mobile/brand/BrandDetail.vue

@@ -0,0 +1,563 @@
+<template>
+  <div class="brand-detail mobile-content" @click="checkShowFilter()">
+    <div class="brand-logo">
+      <div class="brand-logo-box">
+        <img :src="brandDetail.logoUrl || '/images/component/default.png'" :alt="brandDetail.nameEn"/>
+      </div>
+    </div>
+    <div class="brand-switch-item">
+      <span :class="activeType=='detail'?'mobile-switch-btn active':'mobile-switch-btn'" @click="setActiveType('detail')">品牌</span>
+      <span :class="activeType=='product'?'mobile-switch-btn active':'mobile-switch-btn'" @click="setActiveType('product')">产品</span>
+    </div>
+    <div class="brand-param-list" v-if="activeType=='detail'">
+      <div class="brand-param-item" v-if="brandDetail.series">
+        <p class="remind-title">主营产品</p>
+        <img class="remind-tag" src="/images/mobile/@2x/title-line.png" alt="">
+        <div class="main-sell">{{brandDetail.series}}</div>
+      </div>
+      <div class="brand-param-item" v-if="applications.length>0">
+        <p class="remind-title">应用领域</p>
+        <img class="remind-tag" src="/images/mobile/@2x/title-line.png" alt="">
+        <div class="main-sell">
+          <span v-for="(item, index) in applications"><span>{{item}}</span><span v-show="index+1 < applications.length">|</span></span>
+        </div>
+      </div>
+      <div class="brand-param-item" v-if="brandDetail.brief">
+        <p class="remind-title">品牌介绍</p>
+        <img class="remind-tag" src="/images/mobile/@2x/title-line.png" alt="">
+        <div class="main-sell">{{brandDetail.brief | wordFilter}}</div>
+      </div>
+      <div class="brand-param-item" v-if="brandDetail.url">
+        <p class="remind-title">官网地址</p>
+        <img class="remind-tag" src="/images/mobile/@2x/title-line.png" alt="">
+        <a class="brand-url" :href="brandDetail.url" v-text="brandDetail.url"></a>
+      </div>
+    </div>
+    <div class="brand-product-list" v-if="activeType=='product'">
+      <!--{{showKindList}}-->
+      <div class="search-box" v-if="searchLists && searchLists.length > 0 || isSearch">
+        <div class="kind-selecter" @click="onListClick($event)">
+          <div @mouseenter="isInList = true" @mouseleave="isInList = false">
+            <span v-text="selectedKind.substring(0, 4)"></span>
+            <ul v-if="showKindList">
+              <li @click="selectKind({nameCn: '全部分类', id: ''}, $event)" v-show="selectedKind !== '全部分类'">全部分类</li>
+              <li v-for="kind in kindList" v-text="kind.nameCn" @click="selectKind(kind, $event)" v-show="selectedKind !== kind.nameCn"></li>
+            </ul>
+          </div>
+        </div>
+        <div class="kind-search">
+          <input type="text" v-model="keyword" placeholder="请输入型号">
+          <i @click="goodsSearch()" class="icon-sousuo iconfont"></i>
+        </div>
+      </div>
+      <ul class="product-list" v-if="productList.totalElements > 0">
+        <li v-for="product in searchLists">
+          <nuxt-link class="text-left" :to="'/mobile/brand/componentDetail/' + product.uuid">{{product.code}}</nuxt-link>
+          <a class="text-right" @click="toShowPdf(product.attach)" v-if="product.attach">规格书 <i class="icon-chakan iconfont"></i></a>
+          <a class="text-right grey" v-if="!product.attach">规格书 <i>-</i></a>
+        </li>
+      </ul>
+      <div class="no-product" v-if="!productList.totalElements || productList.totalElements == 0">
+        <img :src="!isSearch?'/images/mobile/@2x/car@2x.png':'/images/mobile/@2x/search-empty.png'" alt="">
+        <div>抱歉,暂无产品信息</div>
+      </div>
+    </div>
+    <loading v-show="isSearchingMore"></loading>
+    <login-box @onLoginBoxClose="showLoginBox = false" v-if="showLoginBox"></login-box>
+  </div>
+</template>
+<script>
+  import { Loading, LoginBox } from '~components/mobile/common'
+  export default {
+    name: 'MobileBrandsDetail',
+    data () {
+      return {
+        applications: [],
+        activeType: 'detail',
+        keyword: '',
+        showKindList: false,
+        parentid: 0,
+        ids: null,
+        pageParams: {
+          page: 1,
+          count: 10,
+          filter: {}
+        },
+        selectedKind: '全部分类',
+        isInList: false,
+        isSearch: false,
+        isSearchingMore: false,
+        searchLists: [],
+        isChange: false,
+        isFilter: false,
+        showLoginBox: false
+      }
+    },
+    components: {
+      Loading,
+      LoginBox
+    },
+    filters: {
+      wordFilter: function (str) {
+        return str.length > 65 ? str.substring(0, 65) + '...' : str
+      }
+    },
+    mounted: function () {
+      let _this = this
+      _this.$nextTick(function () {
+        window.addEventListener('scroll', function () {
+          _this.scroll()
+        }, false)
+        document.addEventListener('click', _this.checkShowFilter)
+      })
+    },
+    watch: {
+      keyword: function (val, oldVal) {
+        this.isSearch = true
+      }
+    },
+    computed: {
+      brandDetail () {
+        let list = this.$store.state.brandDetail.detail.data
+        if (list.application && list.application !== '') {
+          this.applications = list.application.split(',')
+        }
+        this.pageParams.filter.brandid = list.id
+        return list
+      },
+      productList () {
+        let list = this.$store.state.brandComponent.component.data
+        if (this.isChange || this.isFilter) {
+          this.searchLists = []
+          this.pageParams.page = 1
+          this.isChange = false
+          this.isFilter = false
+        } else {
+          this.searchLists = this.searchLists.concat(list.content)
+          this.isSearchingMore = false
+        }
+        return list
+      },
+      allPage () {
+        return this.productList.totalPages || 0
+      },
+      kindList () {
+        let brands = this.$store.state.brandCategories.categories.data
+        if (!brands || brands.length === 0) {
+          return []
+        }
+        // 初始化去除重复数据
+        for (let i = 0; i < brands.length; i++) {
+          for (let j = 0; j < brands[i].length; j++) {
+            brands[i][j].children = []
+          }
+        }
+
+        // 处理第1层
+        if ((brands[0] && brands[0].length > 0) && (brands[1] && brands[1].length > 0)) {
+          for (let i = 0; i < brands[1].length; i++) {
+            for (let j = 0; j < brands[0].length; j++) {
+              if (brands[0][j].id === brands[1][i].parentid) {
+                if (!brands[0][j].children) {
+                  brands[0][j].children = []
+                }
+                brands[0][j].children.push(brands[1][i])
+                break
+              }
+            }
+          }
+        }
+
+        // 处理第2层
+        if ((brands[1] && brands[1].length > 0) && (brands[2] && brands[2].length > 0)) {
+          for (let i = 0; i < brands[2].length; i++) {
+            for (let j = 0; j < brands[1].length; j++) {
+              if (brands[1][j].id === brands[2][i].parentid) {
+                if (!brands[1][j].children) {
+                  brands[1][j].children = []
+                }
+                brands[1][j].children.push(brands[2][i])
+                break
+              }
+            }
+          }
+        }
+
+        // 处理第3层
+        if ((brands[2] && brands[2].length > 0) && (brands[3] && brands[3].length > 0)) {
+          for (let i = 0; i < brands[3].length; i++) {
+            for (let j = 0; j < brands[2].length; j++) {
+              if (brands[2][j].id === brands[3][i].parentid) {
+                if (!brands[2][j].children) {
+                  brands[2][j].children = []
+                }
+                brands[2][j].children.push(brands[3][i])
+                break
+              }
+            }
+          }
+        }
+        let kindList = []
+        if (brands[0]) {
+          for (let i = 0; i < brands[0].length; i++) {
+            this.getKinds(brands[0][i], kindList)
+          }
+        }
+        return kindList
+      },
+      user () {
+        return this.$store.state.option.user
+      }
+    },
+    methods: {
+      onListClick: function ($event) {
+        $event.stopPropagation()
+        this.showKindList = !this.showKindList
+//        alert(this.showKindList)
+      },
+      scroll: function () {
+        let scrolled = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop
+        if (Math.ceil(scrolled + window.screen.availHeight) >= document.body.scrollHeight && !this.isSearchingMore && this.pageParams.page < this.allPage && this.activeType === 'product') {
+          this.getMoreProduct()
+        }
+      },
+      getMoreProduct: function () {
+        if (!this.isSearchingMore) {
+          this.pageParams.page++
+          this.isSearchingMore = true
+          this.pageCommodity(this.pageParams, this.ids)
+        }
+      },
+      getKinds: function (list, kindList) {
+        if (list.children && list.children.length > 0) {
+          for (let i = 0; i < list.children.length; i++) {
+            this.getKinds(list.children[i], kindList)
+          }
+        } else {
+          kindList.push(list)
+        }
+      },
+      selectKind: function (data, $event) {
+        $event.stopPropagation()
+        this.showKindList = false
+        this.selectedKind = data.nameCn
+        this.isFilter = true
+        if (this.parentid === data.id) {
+          this.parentid = 0
+          this.ids = null
+        } else {
+          if (data.level === 1) {
+            this.parentid = data.id
+          }
+        }
+        this.pageParams.page = 1
+        this.pageParams.filter.brandid = this.brandDetail.id
+        if (data.id !== '') {
+          this.pageParams.filter.kindid = data.id
+        } else {
+          delete this.pageParams.filter.kindid
+        }
+        this.pageCommodity(this.pageParams, this.ids)
+      },
+      goodsSearch () {
+        this.pageParams.page = 1
+        this.pageParams.filter.code = this.keyword
+        this.isFilter = true
+        this.pageCommodity(this.pageParams)
+      },
+      async pageCommodity (params) {
+        try {
+          let { data } = await this.$http.get('/api/product/component/list', { params })
+          this.$store.commit('brandComponent/GET_COMPONENT_SUCCESS', data)
+        } catch (err) {
+          this.$store.commit('brandComponent/GET_COMPONENT_FAILURE', err)
+        }
+      },
+      checkShowFilter: function () {
+        if (!this.isInList) {
+          this.showKindList = false
+        }
+      },
+      toShowPdf: function (url) {
+        if (this.user.logged) {
+          if (url && url !== '1') {
+            window.location.href = url
+          }
+        } else {
+          this.showLoginBox = true
+        }
+      },
+      setActiveType: function (type) {
+//        if (type === 'product' && (this.pageParams.page !== 1 || this.isFilter)) {
+//          this.pageParams = {
+//            page: 1,
+//            count: 10,
+//            filter: {brandid: this.brandDetail.id}
+//          }
+//          this.selectedKind = '全部分类'
+//          this.keyword = ''
+//          this.isChange = true
+//          this.$store.dispatch('loadBrandComponent', this.pageParams)
+//          this.pageCommodity(this.pageParams)
+//        }
+        this.activeType = type
+      }
+    }
+  }
+</script>
+<style lang="scss" scoped>
+  .brand-detail {
+    margin: 0 auto;
+    margin-bottom: 1.2rem;
+    text-align: center;
+    background: #f7f7f7;
+    .brand-logo {
+      height: 3.17rem;
+      width: 6.96rem;
+      display: inline-block;
+      margin: .28rem auto;
+      line-height: 2.13rem;
+      background: #fff;
+      text-align: center;
+      border-radius: .1rem;
+      background: url('/images/mobile/@2x/brand-bg.png')no-repeat;
+      background-size: 7.16rem 3.17rem;
+      background-position: -.1rem 0;
+      box-shadow: 0 0 .01rem .03rem #eee;
+      .brand-logo-box {
+        border: .04rem solid #c7e5fd;
+        border-radius: .1rem;
+        height: 2.21rem;
+        width: 3.73rem;
+        margin: .5rem auto 0;
+        background: #fff;
+        position: relative;
+        img {
+          max-height: 2.13rem;
+          max-width: 3.63rem;
+        }
+      }
+    }
+    .brand-switch-item {
+      text-align: center;
+      background: #fff;
+      margin-bottom: .28rem;
+      .mobile-switch-btn {
+        background: #fff;
+        color: #666;
+        display: inline-block;
+        height: .64rem;
+        font-size: .34rem;
+        line-height: .64rem;
+        width: 1.4rem;
+        &:first-child {
+          margin-right: 1.78rem;
+        }
+        &.active {
+          color: #fc5708;
+          border-bottom: .04rem solid #fc5708;
+        }
+      }
+    }
+    .brand-param-list {
+      text-align: left;
+      padding: .3rem .44rem .11rem;
+      margin-top: .28rem;
+      background: #fff;
+      .brand-param-item {
+        font-size: .3rem;
+        margin-bottom: .48rem;
+        .remind-tag {
+          width: 1.18rem;
+          float: left;
+          margin-top: .05rem;
+        }
+        .remind-title {
+          font-size: .3rem;
+          color: #418bf6;
+          margin: 0;
+        }
+        .main-sell {
+          color: #666;
+          line-height: .4rem;
+          max-height: 1.2rem;
+          overflow: hidden;
+          text-overflow: ellipsis;
+          display: -webkit-box;
+          -webkit-box-orient: vertical;
+          -webkit-line-clamp: 3;
+          margin-top: .15rem;
+        }
+        .brand-url {
+          overflow: hidden;
+          text-overflow: ellipsis;
+          white-space: nowrap;
+          color: #01a44e;
+          margin-left: .28rem;
+          position: relative;
+          bottom: .32rem;
+          max-width: 5rem;
+          display: inline-block;
+          &:hover, &:active, &:focus, &:visited {
+            text-decoration: underline!important;
+          }
+        }
+      }
+    }
+    .brand-product-list {
+      font-size: .28rem;
+      background: #fff;
+      ul.product-list {
+        text-align: center;
+        li {
+          margin-left: .42rem;
+          width: 6.66rem;
+          height: .66rem;
+          line-height: .66rem;
+          border: {
+            bottom: .04rem solid rgb(230,228,228);
+          }
+          &:nth-child(even) {
+            background: #f9f9f9;
+          }
+          &:nth-child(1) {
+            border-top: .04rem solid rgb(230,228,228);
+          }
+          &:active, &:hover {
+            background: #eee;
+          }
+          .text-left {
+            float: left;
+            color: #333;
+            width: 4.45rem;
+            overflow: hidden;
+            text-overflow: ellipsis;
+            white-space: nowrap;
+          }
+          .text-right {
+            float: right;
+            color: #333;
+            i {
+              font-size: .55rem;
+              float: right;
+              margin-right: .27rem;
+              margin-left: .54rem;
+              color: #6fcafe;
+              width: .55rem;
+              height: .65rem;
+              display: inline-block;
+              text-align: center;
+              font-style: normal;
+            }
+            &.grey{
+              i {
+                color: #999;
+              }
+            }
+          }
+        }
+      }
+      .search-box {
+        margin-bottom: .28rem;
+        padding-top: .28rem;
+        .kind-selecter {
+          display: inline-block;
+          position: relative;
+          float: left;
+          margin-left: .72rem;
+          div {
+            display: inline-block;
+            span {
+              width: 1.64rem;
+              height: .6rem;
+              line-height: .52rem;
+              border: .04rem solid rgb(195,195,195);
+              border-radius: .05rem;
+              font-size: .28rem;
+              display: inline-block;
+              background: url('/images/mobile/@2x/productDetail/kind-narrow-down@2x.png')no-repeat;
+              padding-right: .15rem;
+              background-position: 1.35rem .25rem;
+              background-size: .14rem .1rem;
+              overflow: hidden;
+            }
+          }
+        }
+        .kind-search {
+          display: inline-block;
+          margin-right: .19rem;
+          width: 4.36rem;
+          height: .6rem;
+          line-height: .6rem;
+          vertical-align: middle;
+          input[type = "text"] {
+            display: inline-block;
+            width: 3.61rem;
+            height: .6rem;
+            border: .04rem solid rgb(195,195,195);
+            padding-left: .21rem;
+            font-size: .24rem;
+            float: left;
+            border-radius: .05rem;
+          }
+          i {
+            background: rgb(65,142,247);
+            width: .73rem;
+            height: .6rem;
+            line-height: .6rem;
+            font-size: .32rem;
+            color: #fff;
+            display: inline-block;
+            margin-left: -.04rem;
+          }
+        }
+        ul {
+          position: absolute;
+          top: 0.65rem;
+          max-height: 3.15rem;
+          overflow-y: auto;
+          z-index: 1;
+          &::-webkit-scrollbar {
+            display: block;
+            background: rgba(0,0,0,.6);
+            width: 0.05rem;
+          }
+          &::-webkit-scrollbar-thumb {
+            background-color: #999;
+          }
+          li {
+            width: 1.64rem;
+            height: .83rem;
+            line-height: .83rem;
+            padding: 0 .08rem;
+            overflow: hidden;
+            text-overflow: ellipsis;
+            white-space: nowrap;
+            background: rgba(0, 0, 0, 0.6);
+            color: #fff;
+          }
+        }
+      }
+      .no-product {
+        background: #fff;
+        padding-top: 1rem;
+        img {
+          display: block;
+          text-align: center;
+          margin: 0 auto;
+          margin-bottom: .45rem;
+          width: 4.11rem;
+          height: 2.5rem;
+        }
+        div {
+          width: 5.27rem;
+          margin: 0 auto;
+          text-align: center;
+          line-height: .4rem;
+          font-size: .32rem;
+          color: #999;
+        }
+      }
+    }
+  }
+</style>

+ 494 - 0
components/mobile/brand/ComponentDetail.vue

@@ -0,0 +1,494 @@
+<template>
+  <div class="component-detail mobile-content">
+    <div class="base-detail">
+      <div class="base-detail-item" v-if="component.kind.nameCn">
+        <span>类&nbsp;&nbsp;&nbsp;&nbsp;目:</span>
+        <span>{{component.kind.nameCn}}</span>
+      </div>
+      <div class="base-detail-item" v-if="component.brand.nameCn">
+        <span>品&nbsp;&nbsp;&nbsp;&nbsp;牌:</span>
+        <span>{{component.brand.nameCn}}</span>
+      </div>
+      <div class="base-detail-item attach" @click="goAttach(component.attach)">
+        <span v-if="component.attach">规格书:<img src="/images/mobile/@2x/productDetail/pdf.png" alt=""><span>查看</span></span>
+        <span v-else>规格书:-</span>
+      </div>
+      <div class="base-detail-item product-description" v-if="component.description">
+        <span class="description">产品描述:{{component.description}}</span>
+      </div>
+      <i class="iconfont icon-shoucang" :style="isCollect?'color:#ff7800':'color: #ddd'" @click="collectComponent"></i>
+    </div>
+    <div class="product-switch-item">
+      <span :class="activeType=='param'?'mobile-switch-btn active':'mobile-switch-btn'" @click="activeType='param'">参数</span>
+      <span :class="activeType=='store'?'mobile-switch-btn active':'mobile-switch-btn'" @click="activeType='store'">商家</span>
+    </div>
+    <div class="product-params" v-if="activeType == 'param'">
+      <div class="param-item" v-if="prop.value && prop.value!=''" v-for="prop in component.properties">
+        <span class="prop-name">{{prop.property.labelCn}}</span>
+        <span class="prop-value">{{prop.value}}</span>
+      </div>
+    </div>
+    <div class="product-store" v-if="activeType == 'store'">
+      <table v-if="searchLists&&searchLists.length > 0">
+        <thead>
+          <tr>
+            <th>商家</th>
+            <th>生产日期</th>
+            <th>数量<span>(PCS)</span></th>
+            <th>单价</th>
+            <th>交期(天)</th>
+          </tr>
+        </thead>
+        <tbody>
+          <tr v-for="store in searchLists">
+            <td class="store-name">
+              <div>
+                <nuxt-link :to="'/mobile/shop/' + store.storeid">
+                  {{store.storeName || '-' | storeNameFilter}}
+                </nuxt-link>
+              </div>
+            </td>
+            <td>
+              <div v-if="!store.packaging && !store.breakUp && !store.produceDate">-</div>
+              <div>{{store.produceDate}}</div>
+              <div>{{store.packaging}}</div>
+              <div>{{store.breakUp?'可拆卖':'不可拆卖'}}</div>
+            </td>
+            <td>
+              <div v-if="!store.prices || store.prices.length == 0">-</div>
+              <div v-for="price in store.prices">{{price.start}}+</div>
+            </td>
+            <td>
+              <div v-if="!store.prices || store.prices.length == 0">
+                <span>—</span>
+              </div>
+              <div v-for="price in store.prices" class="price-level">
+                <span v-if="store.currencyName.indexOf('RMB')!==-1">¥{{price.rMBPrice | currency}}</span>
+                <span v-if="store.currencyName.indexOf('USD')!==-1">${{price.uSDPrice | currency}}</span>
+              </div>
+            </td>
+            <td class="push-date">
+              <div v-if="store.b2cMinDelivery">
+                <span>{{store.b2cMinDelivery}}</span>
+                <span v-if="store.b2cMaxDelivery && store.b2cMaxDelivery !== store.b2cMinDelivery">-</span>
+                <span v-if="store.b2cMaxDelivery && store.b2cMaxDelivery !== store.b2cMinDelivery">{{store.b2cMaxDelivery}}</span>
+              </div>
+              <div v-if="store.minBuyQty"><span class="order-tag">订</span>{{store.minBuyQty}}起订</div>
+              <div v-if="!store.b2cMinDelivery">
+                <span>—</span>
+              </div>
+            </td>
+          </tr>
+        </tbody>
+      </table>
+    </div>
+    <div v-if="(storeList.totalElements == 0 && activeType == 'store') || (component.properties && component.properties.length == 0 && activeType == 'param')" class="no-store">
+      <img src="/images/mobile/@2x/car@2x.png" alt="">
+      <div v-if="activeType == 'store'">抱歉,暂无商家出售此型号!</div>
+      <div v-if="activeType == 'store'">您可前往<strong>www.usoftmall.com</strong>网页版进行<strong>“发布求购”</strong>或<strong>“产品上架”</strong>操作!</div>
+      <div v-if="activeType == 'param'">抱歉,暂无参数信息!</div>
+    </div>
+    <remind-box :title="collectResult" :timeoutCount="timeoutCount"></remind-box>
+    <loading v-show="isSearchingMore"></loading>
+    <login-box @onLoginBoxClose="showLoginBox = false" v-if="showLoginBox"></login-box>
+  </div>
+</template>
+<script>
+  import {RemindBox, Loading, LoginBox} from '~components/mobile/common'
+  export default {
+    data () {
+      return {
+        activeType: 'param',
+        collectResult: '收藏成功',
+        timeoutCount: 0,
+        storeIds: [],
+        UmallExist: false,
+        storeExist: false,
+        params: {
+          count: 10,
+          page: 1,
+          sorting: {'minPriceRMB': 'ASC'},
+          filter: {
+            uuid: this.$route.params.uuid,
+            ignoreUMall: false,
+            ignoreStore: false,
+            storeIds: ''
+          }
+        },
+        isSearchingMore: false,
+        searchLists: [],
+        showLoginBox: false
+      }
+    },
+    components: {
+      RemindBox,
+      Loading,
+      LoginBox
+    },
+    mounted: function () {
+      let _this = this
+      _this.$nextTick(function () {
+        window.addEventListener('scroll', function () {
+          _this.scroll()
+        }, false)
+      })
+    },
+    computed: {
+      component () {
+        return this.$store.state.componentDetail.detail.data
+      },
+      storeList () {
+        let storeList = this.$store.state.componentInformation.information.data
+        let _self = this
+        if (storeList.content) {
+          storeList.content.forEach(function (item) {
+            _self.storeIds.push(item.storeid)
+          })
+        }
+        if (this.storeIds.length > 0) {
+          if (this.storeIds.indexOf(this.storeId) === -1) {
+            this.storeExist = true
+          } else {
+            this.storeIds.splice(this.storeIds.indexOf(this.storeId), 1)
+            if (this.storeIds.length > 0) {
+              this.storeExist = true
+            }
+            this.UmallExist = true
+          }
+        }
+        this.searchLists = this.searchLists.concat(storeList.content)
+        this.isSearchingMore = false
+        return storeList
+      },
+      allPage () {
+        return this.storeList.totalPages
+      },
+      colList () {
+        return this.$store.state.product.common.collectList.data
+      },
+      isCollect () {
+        let id = this.component.id
+        let store = this.colList
+        if (store) {
+          for (let i = 0; i < store.length; i++) {
+            if (store[i].componentid === id) {
+              return true
+            }
+          }
+        } else {
+          return false
+        }
+      },
+      user () {
+        return this.$store.state.option.user
+      }
+    },
+    filters: {
+      currency: function (num) {
+        if (typeof num === 'number') {
+          if (num <= 0.000001) {
+            num = 0.000001
+          } else {
+            if (num.toString().indexOf('.') === -1) {
+              num += '.00'
+            } else {
+              let inputStr = num.toString()
+              let arr = inputStr.split('.')
+              let floatNum = arr[1]
+              if (floatNum.length > 6) {
+                num = inputStr.substring(0, arr[0].length + 7)
+                if (Number(floatNum.charAt(6)) > 4) {
+                  num = (Number(num) * 1000000 + 1) / 1000000
+                }
+              } else if (floatNum.length === 1) {
+                num = num + '0'
+              }
+            }
+          }
+        }
+        return num
+      },
+      storeNameFilter: function (str) {
+        if (str === '') {
+          return str
+        }
+        let len = 0
+        let index = 0
+        for (let i = 0; i < str.length; i++) {
+          if (index === 0 && str.charAt(i).charCodeAt(0) > 255) {
+            len = len + 2
+          } else {
+            len++
+          }
+          if (len > 22) {
+            index = i
+            break
+          }
+        }
+        if (index > 0) {
+          return str.substring(0, index) + '...'
+        } else {
+          return str
+        }
+      }
+    },
+    methods: {
+      scroll: function () {
+        let scrolled = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop
+        if (Math.ceil(scrolled + window.screen.availHeight) >= document.body.scrollHeight && !this.isSearchingMore && this.params.page < this.allPage) {
+          this.getMoreStore()
+        }
+      },
+      getMoreStore: function () {
+        if (!this.isSearchingMore) {
+          this.params.page++
+          this.isSearchingMore = true
+          this.$store.dispatch('loadComponentInformation', this.params)
+        }
+      },
+      goAttach: function (url) {
+        if (this.user.logged) {
+          if (url && url !== '1') {
+            window.location.href = url
+          }
+        } else {
+          this.showLoginBox = true
+        }
+      },
+      collectComponent: function () {
+        if (this.user.logged) {
+          if (!this.isCollect) {
+            this.$store.dispatch('product/saveEntity', {componentid: this.component.id, kind: 2})
+            this.collectResult = '收藏成功'
+            this.timeoutCount++
+          } else {
+            this.$http.post('/trade/collection/delete/cmpId', [this.component.id]).then(response => {
+              this.collectResult = '取消成功'
+              this.timeoutCount++
+              this.$store.dispatch('product/saveStores')
+            })
+          }
+        } else {
+          this.showLoginBox = true
+        }
+      }
+    }
+  }
+</script>
+<style lang="scss" scoped>
+  .component-detail {
+    font-size: .28rem;
+    margin-bottom: 1.2rem;
+    background: #f7f7f7;
+    padding-top: .2rem;
+    .base-detail {
+      margin: 0 .27rem .2rem .27rem;
+      padding: .18rem .36rem 0 .36rem;
+      border-radius: .1rem;
+      background: url('/images/mobile/@2x/productDetail/component-desc-bg.png')no-repeat;
+      background-size: cover;
+      max-height: 3.17rem;
+      position: relative;
+      .base-detail-item {
+        margin-top: .2rem;
+        position: relative;
+        color: #fff;
+        &:nth-child(1) {
+          margin-top: 0;
+        }
+        &:nth-last-child(1) {
+          color: #999;
+        }
+        &.attach {
+          display: inline-block;
+          img {
+            background-color: #fff;
+            width: .36rem;
+            height: .4rem;
+            position: relative;
+            bottom: .05rem;
+          }
+          >span >span {
+            margin-left: .1rem;
+            color: #418bf6;
+          }
+        }
+        &:last-child {
+          margin-bottom: 0;
+        }
+        &.product-description {
+          height: 1.58rem;
+        }
+        .description {
+          line-height: .4rem;
+          max-height: 1.2rem;
+          word-break: break-all;
+          overflow : hidden;
+          text-overflow: ellipsis;
+          display: -webkit-box;
+          -webkit-line-clamp: 3;
+          -webkit-box-orient: vertical;
+          color: #999;
+        }
+      }
+      >i {
+        position: absolute;
+        font-size: .4rem;
+        background: #fff;
+        width: .6rem;
+        height: .6rem;
+        line-height: .6rem;
+        border-radius: 100%;
+        box-shadow: 0 0 .05rem #aaa;
+        right: .28rem;
+        top: .55rem;
+        text-align: center;
+      }
+    }
+    .product-switch-item {
+      text-align: center;
+      background: #fff;
+      .mobile-switch-btn {
+        background: #fff;
+        color: #666;
+        display: inline-block;
+        height: .64rem;
+        line-height: .64rem;
+        font-size: .34rem;
+        width: 1.4rem;
+        &:first-child {
+          margin-right: 1.78rem;
+        }
+        &.active {
+          color: #fc5708;
+          border-bottom: .04rem solid #fc5708;
+        }
+      }
+    }
+    .product-params {
+      line-height: .28rem;
+      margin-top: .2rem;
+      .param-item {
+        padding: .19rem .4rem;
+        border-bottom: 0.04rem solid #eee;
+        &:nth-child(1) {
+          border-top: 0.04rem solid #eee;
+        }
+        &:nth-child(even) {
+          background: #f9f9f9;
+        }
+        &:nth-child(odd) {
+          background: #fff;
+        }
+        .prop-name {
+          width: 3.72rem;
+          display: inline-block;
+          text-overflow: ellipsis;
+          overflow: hidden;
+          white-space: nowrap;
+        }
+        .prop-value {
+          text-overflow: ellipsis;
+          overflow: hidden;
+          white-space: nowrap;
+          display: inline-block;
+          width: 2.69rem;
+          float: right;
+          text-align: right;
+        }
+      }
+    }
+    .product-store {
+      margin: .2rem 0;
+      table {
+        width: 100%;
+        font-size: .28rem;
+        thead {
+          background: #d5e5fb;
+          tr {
+            th {
+              font-weight: bold;
+              text-align: center;
+              height: .78rem;
+              line-height: .78rem;
+              >span {
+               font-size: .22rem;
+              }
+            }
+          }
+        }
+        tbody {
+          background: #fff;
+          tr {
+            border-bottom: 0.2rem solid #f7f7f7;
+            td {
+              padding: .2rem .1rem;
+              &.store-name {
+                color: #418bf6;
+                div {
+                  padding: 0;
+                  width: 1.2rem;
+                  overflow: hidden;
+                  margin-left: .16rem;
+                }
+              }
+              div {
+                margin-bottom: .2rem;
+                text-align: left;
+                &:last-child {
+                  margin-bottom: 0;
+                }
+              }
+              &.push-date {
+              text-align: center;
+                div {
+                  text-align: center;
+                }
+            }
+              .price-level:last-child {
+                color: #fc5708;
+              }
+              .order-tag {
+                display: inline-block;
+                font-size: .18rem;
+                color: #fff;
+                font-weight: bold;
+                background: #ee1717;
+                height: .27rem;
+                width: .27rem;
+                line-height: .27rem;
+                text-align: center;
+                border-radius: .05rem;
+                position: relative;
+                top: -.03rem;
+              }
+            }
+          }
+        }
+      }
+    }
+    .no-store {
+      background: #fff;
+      padding-top: 1rem;
+      img {
+        display: block;
+        text-align: center;
+        margin: 0 auto;
+        margin-bottom: .45rem;
+        width: 3.31rem;
+        height: 2.13rem;
+      }
+      div {
+        width: 5.27rem;
+        margin: 0 auto;
+        text-align: center;
+        line-height: .4rem;
+        color: #999;
+        .link-url {
+          color: #01a44e;
+        }
+      }
+    }
+  }
+
+</style>

+ 16 - 0
components/mobile/common/Loading.vue

@@ -0,0 +1,16 @@
+<template>
+  <div class="loading">
+    <img src="/images/all/loading.gif" alt="">
+  </div>
+</template>
+<style lang="scss" scoped>
+  .loading {
+    text-align: center;
+    background: #fff;
+    >img {
+      width: .64rem;
+      height: .64rem;
+      margin: .2rem 0;
+    }
+  }
+</style>

+ 42 - 0
components/mobile/common/LoginBox.vue

@@ -0,0 +1,42 @@
+<template>
+  <div class="mobile-modal">
+    <div class="mobile-modal-box">
+      <div class="mobile-modal-header">请登录后再操作<i @click="close" class="icon-guanbi iconfont"></i></div>
+      <div class="mobile-modal-content">
+        <span @click="close">暂不登录</span><span @click="goLogin">马上登录</span>
+      </div>
+    </div>
+  </div>
+</template>
+<script>
+  export default {
+    name: 'loginBox',
+    methods: {
+      close: function () {
+        this.$emit('onLoginBoxClose')
+      },
+      goLogin: function () {
+        this.$router.push('/auth/login?returnUrl=' + window.location.href)
+      }
+    }
+  }
+</script>
+<style lang="scss" scoped>
+  .mobile-modal-content {
+    padding: .54rem !important;
+    text-align: center;
+    span {
+      display: inline-block;
+      width: 1.5rem;
+      height: .6rem;
+      line-height: .6rem;
+      text-align: center;
+      background: #418df6;
+      color: #fff;
+      border-radius: .1rem;
+      &:first-child {
+        margin-right: .5rem;
+      }
+    }
+  }
+</style>

+ 51 - 0
components/mobile/common/PullDown.vue

@@ -0,0 +1,51 @@
+<template>
+  <div class="loading" v-show="isSearchingMore">
+    <img src="/images/all/loading.gif" alt="">
+  </div>
+</template>
+<script>
+  export default {
+    data () {
+      return {
+        isSearchingMore: false,
+        searchLists: [],
+        page: 1
+      }
+    },
+    props: ['searchMore', 'allPage', 'count'],
+    mounted: function () {
+      let _this = this
+      _this.$nextTick(function () {
+        window.addEventListener('scroll', function () {
+          _this.scroll()
+        }, false)
+      })
+    },
+    methods: {
+      scroll: function () {
+        let scrolled = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop
+        if (Math.ceil(scrolled + window.screen.availHeight) >= document.body.scrollHeight && !this.isSearchingMore && this.page < this.allPage) {
+          this.getMore()
+        }
+      },
+      getMore: function () {
+        if (!this.isSearchingMore) {
+          this.page++
+          this.isSearchingMore = true
+          this.searchMore(this.page, this.count)
+        }
+      }
+    }
+  }
+</script>
+<style lang="scss" scoped>
+  .loading {
+    text-align: center;
+    background: #fff;
+    >img {
+      width: .64rem;
+      height: .64rem;
+      margin: .2rem 0;
+    }
+  }
+</style>

+ 48 - 0
components/mobile/common/RemindBox.vue

@@ -0,0 +1,48 @@
+<template>
+  <div class="com-remind-box" v-show="showBox">{{title}}</div>
+</template>
+<script>
+  export default {
+    props: ['title', 'timeoutCount'],
+    data () {
+      return {
+        showBox: false,
+        timer: ''
+      }
+    },
+    watch: {
+      timeoutCount: function (val, oldVal) {
+        if (val > 0) {
+          clearTimeout(this.timer)
+          this.setTimer()
+        } else {
+          this.showBox = false
+        }
+      }
+    },
+    methods: {
+      setTimer: function () {
+        let _this = this
+        _this.showBox = true
+        _this.timer = setTimeout(function () {
+          _this.showBox = false
+        }, 1000)
+      }
+    }
+  }
+</script>
+<style>
+  .com-remind-box{
+    position: fixed;
+    top: 50%;
+    left: 50%;
+    margin-left: -1.07rem;
+    margin-top: -.6rem;
+    z-index: 100;
+    background: rgba(0,0,0,.6);
+    color: #fff;
+    font-size: .28rem;
+    padding: .44rem .51rem;
+    border-radius: .1rem;
+  }
+</style>

+ 5 - 0
components/mobile/common/index.js

@@ -0,0 +1,5 @@
+import Loading from './Loading.vue'
+import RemindBox from './RemindBox.vue'
+import LoginBox from './LoginBox.vue'
+
+export { Loading, RemindBox, LoginBox }

+ 27 - 0
components/mobile/help/HelpFooter.vue

@@ -0,0 +1,27 @@
+<template>
+  <footer>
+      <div class=" text-center">
+        <p>
+          &copy; 2016 深圳市优软科技有限公司
+        </p>
+      </div>
+  </footer>
+</template>
+<script>
+  export default{
+    name: 'HelpFooter'
+  }
+</script>
+<style scoped>
+footer{
+  position: fixed;
+  bottom: 0;
+  background: #fff;
+  height: 40px;
+  line-height: 40px;
+}
+footer p{
+  font-size: 14px;
+  color: #000;
+}
+</style>

+ 39 - 0
components/mobile/help/HelpHeader.vue

@@ -0,0 +1,39 @@
+<template>
+  <nav id="nav" class="navbar navbar-default">
+    <div class="container-fluid">
+      <div class="navbar-header">
+        <a class="navbar-brand pull-left" href="/" style="color: #fff; font-size: 16px;">返回首页</a>
+      </div>
+    </div>
+  </nav>
+</template>
+<script>
+  export default {
+  }
+</script>
+<style lang="scss" scoped>
+  @import '~assets/scss/mobileCommon';
+  /* nav */
+  #nav {
+    background-color: #474443;
+    border-color: #474443;
+  }
+  .navbar {
+    margin-bottom: 0;
+    min-height: 40px;
+  }
+  .navbar-toggle {
+    padding: 4px 5px;
+  }
+  .navbar-default .navbar-collapse, .navbar-default .navbar-form {
+    border-color: #666666;
+  }
+  .navbar-default .navbar-nav>li>a {
+    color: #dddddd;
+  }
+  .navbar-brand {
+    padding: 10px 15px;
+    height: 40px;
+  }
+
+</style>

+ 4 - 0
components/mobile/help/index.js

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

+ 5 - 0
components/mobile/index.js

@@ -0,0 +1,5 @@
+import MobileHeader from './MobileHeader.vue'
+import MobileFooter from './MobileFooter.vue'
+import Home from './Home.vue'
+
+export { MobileFooter, MobileHeader, Home }

+ 297 - 0
components/mobile/search/MainSearch.vue

@@ -0,0 +1,297 @@
+<template>
+  <div class="main-search" @touchstart="cancelFocus" id="main-search">
+    <div class="main-search-header">
+      <input type="text" id="search-box" v-model="keyword" placeholder="请输入您要查找的型号或品牌" @keyup.13="onSearch()">
+      <span @click="onSearch()">搜索</span>
+      <a @click="cancelSearch">取消</a>
+    </div>
+    <ul class="associate-list" v-show="associate.show">
+      <li @click="onAssociateClick(similar)" v-for="similar in similarKeywords.all">
+        <i class="icon-sousuo iconfont"></i>
+        <span>{{similar}}</span>
+      </li>
+      <li @click="onAssociateClick(keyword)">查找“{{keyword}}”</li>
+    </ul>
+    <div class="hot-history" v-show="!associate.show">
+      <div class="search-history" v-if="searchHistory && searchHistory.length > 0">
+        <p>历史搜索<i class="iconfont icon-lajitong" @click="deleteHistory"></i></p>
+        <ul>
+          <li v-for="item in searchHistory" @click="onSearch(item.keyword)">
+            <a>{{item.keyword}}</a>
+          </li>
+        </ul>
+      </div>
+      <div class="search-hot">
+        <img src="/images/mobile/@2x/home/hot-search.png" alt="">
+        <ul>
+          <li v-for="hotword in hotwords">
+            <nuxt-link :to="hotword.url" v-text="hotword.name"></nuxt-link>
+          </li>
+        </ul>
+      </div>
+    </div>
+  </div>
+</template>
+<script>
+  export default {
+    name: 'home',
+    data () {
+      return {
+        keyword: '',
+        associate: {
+          show: false
+        }
+      }
+    },
+    props: {
+      hotwords: {
+        type: Array,
+        default () {
+          return [
+            {name: 'DSP1-DC5V-F', url: '/mobile/brand/componentDetail/0900300200000669'},
+            {name: 'Vishay', url: '/mobile/brand/30327265e42a871be050007f01003d96'},
+            {name: 'Panasonic', url: '/mobile/brand/30327265e47d871be050007f01003d96'},
+            {name: 'Taiyo Yuden', url: '/mobile/brand/30327265e4be871be050007f01003d96'},
+            {name: 'AE324FB5PN', url: '/mobile/brand/componentDetail/0900502200684613'}
+          ]
+        }
+      }
+    },
+//    filters: {
+//      similarFilter: function ([key, keyword]) {
+//        console.log(keyword)
+//        let index = key.indexOf(keyword)
+//        if (index !== -1) {
+//          key = key.substring(0, index) + '<strong>' + key.substr(index, keyword.length) + '</strong>' + key.substring(index + keyword.length, key.length)
+//        }
+//        return key
+//      }
+//    },
+    methods: {
+      onSearch (key) {
+        if (key && key !== '') {
+          this.keyword = key
+        }
+        if (this.keyword) {
+          this.$router.push({path: '/mobile/search?w=' + encodeURIComponent(this.keyword)})
+        }
+      },
+      onChange () {
+        if (!this.keyword) {
+          this.associate.show = false
+          this.$store.dispatch('resetSearchKeywords')
+        } else {
+          this.searchKeywords()
+        }
+        if (this.click_flag) {
+          this.associate.show = false
+        }
+      },
+      searchKeywords () {
+        this.$store.dispatch('searchKeywords', { keyword: this.keyword })
+        this.associate.show = true
+      },
+      onAssociateClick (word) {
+        this.keyword = word
+        this.onSearch()
+      },
+      cancelSearch: function () {
+        this.$emit('cancelSearchAction')
+      },
+      cancelFocus: function () {
+        document.getElementById('search-box').blur()
+      },
+      deleteHistory () {
+        this.$http.delete('/search/searchHistory').then(response => {
+          this.$store.dispatch('searchData/getSearchHistory')
+        })
+      }
+    },
+    created () {
+      this.$store.dispatch('resetSearchKeywords')
+    },
+    mounted () {
+      document.getElementById('search-box').focus()
+      let height = window.innerHeight
+      window.onresize = function () {
+        if (window.innerHeight < height) {
+          document.getElementById('main-search').style.bottom = (window.innerHeight - height) / (document.documentElement.clientWidth / 750) + 'rem'
+        } else {
+          document.getElementById('main-search').style.bottom = 0
+        }
+      }
+    },
+    watch: {
+      'keyword': function (val, oldVal) {
+        let keywords = this.similarKeywords.data
+        if (!keywords || !keywords.length) {
+          this.onChange()
+        }
+      }
+    },
+    computed: {
+      similarKeywords () {
+        return this.$store.state.search.keywords.data
+      },
+      searchHistory () {
+        return this.$store.state.searchData.searchHistory.searchHistory.data
+      }
+    }
+  }
+</script>
+<style lang="scss" scoped>
+  .main-search {
+    background: #fff;
+    width: 100%;
+    position: fixed;
+    z-index: 1000;
+    top: -2rem;
+    bottom: 0;
+    .main-search-header {
+      height: .88rem;
+      background: #3e82f5;
+      padding-left: .5rem;
+      line-height: .88rem;
+      margin-top: 2rem;
+      input {
+        width: 4.78rem;
+        height: .62rem;
+        line-height: .62rem;
+        font-size: .28rem;
+        color: #999;
+        padding-left: .2rem;
+        border: .04rem solid #fff;
+        background: #fff;
+        outline: none;
+        border-radius: 0;
+        float: left;
+        margin-top: .12rem;
+        -webkit-appearance: none;
+        border-top-left-radius: .05rem;
+        border-bottom-left-radius: .05rem;
+      }
+      span {
+        display: inline-block;
+        width: 1.02rem;
+        text-align: center;
+        height: .62rem;
+        line-height: .62rem;
+        color: #366df3;
+        font-size: .28rem;
+        margin-left: .02rem;
+        border-top-right-radius: .05rem;
+        border-bottom-right-radius: .05rem;
+        background: #fff;
+        float: left;
+        margin-top: .12rem;
+      }
+      a {
+        font-size: .28rem;
+        color: #fff;
+        margin-left: .2rem;
+      }
+    }
+    .associate-list {
+      background: #fff;
+      li {
+        height: 0.7rem;
+        line-height: .9rem;
+        margin: 0 .45rem;
+        border-bottom: .04rem solid #f1f0f0;
+        i {
+          font-size: .36rem;
+          margin-right: .24rem;
+          color: #ddd;
+        }
+        span {
+          color: #999;
+          font-size: .28rem;
+          line-height: .58rem;
+          height: .58rem;
+          display: inline-block;
+        }
+        &:active, &:hover {
+          background: #eee;
+        }
+        &:last-child {
+          text-align: center;
+          font-size: .3rem;
+          color: #3976f4;
+          border-bottom: none;
+          &:active, &:hover {
+            background: #fff;
+          }
+        }
+      }
+    }
+    .hot-history {
+      .search-history {
+        padding-left: .51rem;
+        padding-top: .38rem;
+        >p {
+          font-size: .3rem;
+          color: #333;
+          i {
+            font-size: .3rem;
+            float: right;
+            margin-right: 0.4rem;
+          }
+        }
+        ul {
+          text-align: left;
+          margin-top: .26rem;
+          li {
+            display: inline-block;
+            max-width: 2.83rem;
+            overflow: hidden;
+            text-overflow: ellipsis;
+            white-space: nowrap;
+            margin: 0 .1rem .1rem 0;
+            background: #f2f6ff;
+            height: .56rem;
+            line-height: .56rem;
+            padding: 0 .12rem;
+            a {
+              font-size: .3rem;
+              color: #666;
+            }
+          }
+        }
+      }
+      .search-hot {
+        text-align: center;
+        margin-top: .3rem;
+        >img {
+          width: 2.56rem;
+          height: .67rem;
+        }
+        ul {
+          text-align: left;
+          padding-left: .51rem;
+          margin-top: .31rem;
+          li {
+            display: inline-block;
+            max-width: 2.83rem;
+            overflow: hidden;
+            text-overflow: ellipsis;
+            white-space: nowrap;
+            margin: 0 .1rem .1rem 0;
+            background: #fef1eb;
+            height: .56rem;
+            line-height: .56rem;
+            padding: 0 .12rem;
+            a {
+              font-size: .3rem;
+              color: #666;
+            }
+            &:nth-child(1) {
+              a {
+                color: #fc5708;
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+</style>

+ 386 - 0
components/mobile/store/StoreDetail.vue

@@ -0,0 +1,386 @@
+<template>
+  <div class="store-detail mobile-content">
+    <div class="store-logo">
+      <div class="store-logo-box">
+        <img :src="store.logoUrl || '/images/component/default.png'"/>
+        <i class="iconfont icon-shoucang" :style="isFocus === 'true'?'color:#ff7800':'color: #ddd'" @click="collectStore"></i>
+      </div>
+    </div>
+    <div class="store-switch-item">
+      <span :class="activeType=='product'?'mobile-switch-btn active':'mobile-switch-btn'" @click="activeType='product'">产品</span>
+      <span :class="activeType=='detail'?'mobile-switch-btn active':'mobile-switch-btn'" @click="activeType='detail'">介绍</span>
+    </div>
+    <div class="store-description" v-if="activeType=='detail'">
+      <p>
+        {{store.description}}
+      </p>
+    </div>
+    <div class="product-store" v-if="activeType == 'product'">
+      <table v-if="commodities.content&&commodities.content.length > 0">
+        <thead>
+        <tr>
+          <th>型号/品牌</th>
+          <th>包装</th>
+          <th>数量</th>
+          <th>单价</th>
+          <th>交期(天)</th>
+        </tr>
+        </thead>
+        <tbody>
+        <tr v-for="commodity in searchLists" @click="goProductDetail(commodity.uuid)">
+          <td class="store-name">
+            <div>{{commodity.code}}</div>
+            <div>{{commodity.brandNameCn}}</div>
+          </td>
+          <td>
+            <div v-if="!commodity.packaging && !commodity.breakUp && !commodity.produceDate">-</div>
+            <div>{{commodity.packaging}}</div>
+            <div>{{commodity.breakUp?'可拆卖':'不可拆卖'}}</div>
+            <div>{{commodity.produceDate}}</div>
+          </td>
+          <td>
+            <div v-if="!commodity.prices || commodity.prices.length == 0">-</div>
+            <div v-for="price in commodity.prices">{{price.start}}+</div>
+          </td>
+          <td>
+            <div v-if="!commodity.prices || commodity.prices.length == 0">
+              <span>—</span>
+            </div>
+            <div v-for="price in commodity.prices" class="price-level">
+              <span v-if="commodity.currencyName.indexOf('RMB')!==-1">¥{{price.rMBPrice | currency}}</span>
+              <span v-if="commodity.currencyName.indexOf('USD')!==-1">${{price.uSDPrice | currency}}</span>
+            </div>
+          </td>
+          <td>
+            <div v-if="commodity.b2cMinDelivery">
+              <span>{{commodity.b2cMinDelivery}}</span>
+              <span v-if="commodity.b2cMaxDelivery && commodity.b2cMaxDelivery !== commodity.b2cMinDelivery">-</span>
+              <span v-if="commodity.b2cMaxDelivery && commodity.b2cMaxDelivery !== commodity.b2cMinDelivery">{{commodity.b2cMaxDelivery}}</span>
+            </div>
+            <div v-if="commodity.minBuyQty"><span class="order-tag">订</span>{{commodity.minBuyQty}}起订</div>
+            <div v-if="!commodity.b2cMinDelivery">
+              <span>—</span>
+            </div>
+          </td>
+        </tr>
+        </tbody>
+      </table>
+      <div v-if="!commodities.content || commodities.content.length == 0" class="no-product">
+        <img src="/images/mobile/@2x/car@2x.png" alt="">
+        <div>抱歉,暂无产品信息</div>
+      </div>
+    </div>
+    <remind-box :title="collectResult" :timeoutCount="timeoutCount"></remind-box>
+    <loading v-show="isSearchingMore"></loading>
+    <login-box @onLoginBoxClose="showLoginBox = false" v-if="showLoginBox"></login-box>
+  </div>
+</template>
+<script>
+  import {RemindBox, Loading, LoginBox} from '~components/mobile/common'
+  export default {
+    data () {
+      return {
+        activeType: 'product',
+        collectResult: '收藏成功',
+        timeoutCount: 0,
+        isSearchingMore: false,
+        searchLists: [],
+        page: 1,
+        showLoginBox: false
+      }
+    },
+    components: {
+      RemindBox,
+      Loading,
+      LoginBox
+    },
+    mounted: function () {
+      let _this = this
+      _this.$nextTick(function () {
+        window.addEventListener('scroll', function () {
+          _this.scroll()
+        }, false)
+      })
+    },
+    filters: {
+      currency: function (num) {
+        if (typeof num === 'number') {
+          if (num <= 0.000001) {
+            num = 0.000001
+          } else {
+            if (num.toString().indexOf('.') === -1) {
+              num += '.00'
+            } else {
+              let inputStr = num.toString()
+              let arr = inputStr.split('.')
+              let floatNum = arr[1]
+              if (floatNum.length > 6) {
+                num = inputStr.substring(0, arr[0].length + 7)
+                if (Number(floatNum.charAt(6)) > 4) {
+                  num = (Number(num) * 1000000 + 1) / 1000000
+                }
+              } else if (floatNum.length === 1) {
+                num = num + '0'
+              }
+            }
+          }
+        }
+        return num
+      }
+    },
+    computed: {
+      store () {
+        return this.$store.state.shop.storeInfo.store.data
+      },
+      commodities () {
+        let list = this.$store.state.shop.storeInfo.storeCommodity.data
+        this.searchLists = this.searchLists.concat(list.content)
+        this.isSearchingMore = false
+        return list
+      },
+      allPage () {
+        return this.commodities.totalPages
+      },
+      isFocus () {
+        return this.$store.state.shop.storeInfo.focusList.data
+      },
+      user () {
+        return this.$store.state.option.user
+      }
+    },
+    methods: {
+      scroll: function () {
+        let scrolled = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop
+        if (Math.ceil(scrolled + window.screen.availHeight) >= document.body.scrollHeight && !this.isSearchingMore && this.page < this.allPage && this.activeType === 'product') {
+          this.getMoreCom()
+        }
+      },
+      getMoreCom: function () {
+        if (!this.isSearchingMore) {
+          this.page++
+          this.isSearchingMore = true
+          console.log(this.page)
+          this.pageCommodity({ page: this.page, count: 6 })
+        }
+      },
+      async pageCommodity (pageParams, kindId, keyword) {
+        let params = { storeid: this.$route.params.uuid, origin: 'store', kindUuid: kindId, code: keyword }
+        params.page = pageParams.page
+        params.count = pageParams.count
+        try {
+          let { data } = await this.$http.get('/api/commodity/commodities', { params })
+          this.$store.commit('shop/storeInfo/GET_STORE_COMMODITY_SUCCESS', data)
+        } catch (err) {
+          this.$store.commit('shop/storeInfo/GET_STORE_COMMODITY_FAILURE', err)
+        }
+      },
+      goProductDetail: function (uuid) {
+        this.$router.push('/mobile/brand/componentDetail/' + uuid)
+      },
+      collectStore: function () {
+        if (this.user.logged) {
+          if (this.isFocus === 'false') {
+            this.$store.dispatch('shop/StoreFocus', {storeName: this.store.storeName, storeid: this.store.id})
+              .then(response => {
+                this.$store.dispatch('shop/StoreFocusList', {id: this.store.id})
+                this.collectResult = '收藏成功'
+                this.timeoutCount++
+              })
+          } else if (this.isFocus === 'true') {
+            this.$http.post('/trade/storeFocus/delete/storeId', [this.store.id])
+              .then(response => {
+                this.$store.dispatch('shop/StoreFocusList', {id: this.store.id})
+                this.collectResult = '取消成功'
+                this.timeoutCount++
+              })
+          }
+        } else {
+          this.showLoginBox = true
+        }
+      }
+    }
+  }
+</script>
+<style lang="scss" scoped>
+  .store-detail {
+    margin: 0 auto;
+    margin-bottom: 1.2rem;
+    text-align: center;
+    background: #f7f7f7;
+    height: 100%;
+    .store-logo {
+      height: 3.17rem;
+      width: 6.96rem;
+      display: inline-block;
+      margin: .2rem auto;
+      line-height: 2.13rem;
+      background: #fff;
+      text-align: center;
+      border-radius: .1rem;
+      background: url('/images/mobile/@2x/brand-bg.png') no-repeat;
+      background-size: cover;
+      .store-logo-box {
+        border: .04rem solid #c7e5fd;
+        border-radius: .1rem;
+        height: 2.21rem;
+        width: 3.73rem;
+        margin: .5rem auto 0;
+        background: #fff;
+        position: relative;
+        img {
+          max-height: 2.1rem;
+          max-width: 3.6rem;
+        }
+        >i {
+          position: absolute;
+          font-size: .4rem;
+          background: #fff;
+          width: .6rem;
+          height: .6rem;
+          line-height: .6rem;
+          border-radius: 100%;
+          box-shadow: 0 0 .05rem #aaa;
+          right: -1.44rem;
+          top: .75rem;
+          text-align: center;
+        }
+      }
+    }
+    .store-switch-item {
+      text-align: center;
+      background: #fff;
+      .mobile-switch-btn {
+        background: #fff;
+        color: #666;
+        display: inline-block;
+        height: .64rem;
+        font-size: .34rem;
+        line-height: .64rem;
+        width: 1.4rem;
+        &:first-child {
+          margin-right: 1.78rem;
+        }
+        &.active {
+          color: #fc5708;
+          border-bottom: .04rem solid #fc5708;
+        }
+      }
+    }
+    .store-description {
+      background: #f7f7f7;
+      width: 100%;
+      p {
+        background: #fff;
+        margin: .2rem auto 0;
+        padding: .4rem .34rem;
+        width: 100%;
+        font-size: .3rem;
+        color: #666;
+        text-align: left;
+        height: 95%;
+        box-shadow: 0 .03rem .01rem 0 #cdcbcb96;
+        line-height: .5rem;
+      }
+    }
+    .product-store {
+      margin: .2rem 0 0 0;
+      table {
+        width: 100%;
+        font-size: .28rem;
+        thead {
+          background: #d5e5fb;
+          tr {
+            th {
+              font-weight: bold;
+              text-align: center;
+              height: .78rem;
+              line-height: .78rem;
+            }
+          }
+        }
+        tbody {
+          tr {
+            background: #fff;
+            border-bottom: 0.2rem solid #f7f7f7;
+            td {
+              padding: .2rem .1rem;
+              text-align: left;
+              div {
+                overflow: hidden;
+                text-overflow: ellipsis;
+                white-space: nowrap;
+                margin-bottom: .2rem;
+                max-width: 1.58rem;
+                &:last-child {
+                  margin-bottom: 0;
+                }
+              }
+              .price-level:last-child {
+                color: #fc5708;
+              }
+              .order-tag {
+                display: inline-block;
+                font-size: .18rem;
+                color: #fff;
+                font-weight: bold;
+                background: #ee1717;
+                height: .27rem;
+                width: .27rem;
+                line-height: .27rem;
+                text-align: center;
+                border-radius: .05rem;
+                position: relative;
+                top: -.03rem;
+              }
+            }
+            &:active {
+              background: #e1e1e1;
+            }
+          }
+        }
+      }
+      .no-store {
+        background: #fff;
+        padding-top: 1rem;
+        img {
+          display: block;
+          text-align: center;
+          margin: 0 auto;
+          margin-bottom: .45rem;
+          width: 3.31rem;
+          height: 2.13rem;
+        }
+        div {
+          width: 5.27rem;
+          margin: 0 auto;
+          text-align: center;
+          line-height: .4rem;
+          color: #999;
+          .link-url {
+            color: #01a44e;
+          }
+        }
+      }
+    }
+    .no-product {
+      background: #fff;
+      padding-top: 1rem;
+      img {
+        display: block;
+        text-align: center;
+        margin: 0 auto;
+        margin-bottom: .45rem;
+        width: 3.31rem;
+        height: 2.13rem;
+      }
+      div {
+        width: 5.27rem;
+        margin: 0 auto;
+        text-align: center;
+        line-height: .4rem;
+        font-size: .32rem;
+        color: #999;
+      }
+    }
+  }
+</style>

+ 10 - 3
components/product/ComponentGoods.vue

@@ -12,7 +12,7 @@
         <th width="160">品牌/型号</th>
         <th width="100">包装/生产日期</th>
         <th width="110">库存</th>
-        <th width="90">数量</th>
+        <th width="90">梯度/pcs</th>
         <th width="90">香港交货<span style="font-size: 12px;">($)</span></th>
         <th width="100">大陆交货<span style="font-size: 12px;">(¥)</span></th>
         <th width="100">交期(天)</th>
@@ -22,7 +22,8 @@
       <tbody id="productList-content">
       <!--| orderBy : dir + orderType  ng-class="{'tr-even' : !compGoods.isOdd}"-->
       <tr v-for="compGoods in componentGoods.content">
-        <td>
+        <td style="position: relative">
+          <img class="sellout-flag" v-if="compGoods.status === 602" src="/images/search/sellout-search.png" alt="">
           <!--store/{{compGoods.storeId}}#/batchInfo/{{compGoods.batchCode}}-->
           <nuxt-link v-if="compGoods.batchCode" :to="`/store/${compGoods.storeId}/${compGoods.batchCode}`" target="_blank">
             <img :src="compGoods.img?compGoods.img:compGoods.brand&&compGoods.brand.logoUrl?compGoods.brand.logoUrl:'/images/all/default.png'"/>
@@ -95,7 +96,7 @@
             <span>—</span>
           </div>
           <div v-if="compGoods.reserve > 0">
-            <buy :item="compGoods"></buy>
+            <buy :item="compGoods" :disabledFlag="compGoods.status === 602"></buy>
           </div>
         </td>
       </tr>
@@ -349,6 +350,12 @@
   .product-list tbody tr td .can-div-sell {
     color: #333;
   }
+  .product-list tbody tr td .sellout-flag {
+    position: absolute;
+    right: 0;
+    bottom: 0;
+    border: none;
+  }
   .search-record{
     width: 100%;
     margin: 0 auto;

+ 12 - 1
components/product/brand/BrandComponent.vue

@@ -19,7 +19,7 @@
       <tbody>
         <tr class="text-center" v-for="item in list.content">
           <td><a :href="'/product/component/' + item.uuid"><span>{{item.code}}</span></a></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><a @click="toAttach(item.attach)"><button class="btn btn-default"  :disabled="!item.attach" :class="{'disabledbtn':!item.attach}">Datasheet手册</button></a></td>
           <td>
             <button class="btn btn-default disabledbtn" :disabled="true">申请样片</button>
           </td>
@@ -97,6 +97,17 @@
         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)
+        }
       }
     }
   }

+ 4 - 4
components/product/component/ComponentDetail.vue

@@ -55,10 +55,10 @@
               </div>
             </div>
             <div class="message-detail"></div>
-            <div class="form-group">
-               <button type="text" v-if="!collectList" @click="collect(list.id)" class="btn btn-default btn-store">加入收藏</button>
-               <button class="btn btn-default btn-store" v-if="collectList" disabled="disabled">已收藏</button>
-            </div>
+            <!--<div class="form-group">-->
+               <!--<button type="text" v-if="!collectList" @click="collect(list.id)" class="btn btn-default btn-store">加入收藏</button>-->
+               <!--<button class="btn btn-default btn-store" v-if="collectList" disabled="disabled">已收藏</button>-->
+            <!--</div>-->
           </div>
         </div>
       </div>

+ 16 - 13
components/product/component/StoreInfo.vue

@@ -34,11 +34,11 @@
       <table class="table">
         <thead>
           <tr class="height54">
-            <th class="text-center" width="100">制造商型号</th>
-            <th class="text-center" width="120">生产日期</th>
+            <th class="text-center" width="100">型号</th>
             <th class="text-center" width="80">包装方式</th>
+            <th class="text-center" width="120">生产日期</th>
             <th class="text-center" width="150">库存</th>
-            <th class="text-center" width="80">数量</th>
+            <th class="text-center" width="80">梯度/pcs</th>
             <th class="text-center" width="100">香港交货<span style="font-size: 12px;">($)</span></th>
             <th class="text-center" width="130">大陆交货<span style="font-size: 12px;">(¥)</span></th>
             <th class="text-center" width="120">交期<span style="font-size: 12px;">(天)</span></th>
@@ -47,18 +47,19 @@
         </thead>
         <tbody class="text-center">
           <tr style="cursor: pointer;" v-for="list in storeList.content" @click="goProductDetail(list.storeid, list.batchCode)">
-            <td>
+            <td style="position: relative">
+              <img class="sellout-flag" v-if="list.status === 602" src="/images/search/sellout-search.png" alt="">
               <a v-if="list.code">{{list.code}}</a>
               <a v-if="!list.code">—</a>
             </td>
-            <td>
-              <a v-if="list.produceDate">{{list.produceDate}}</a>
-              <a v-if="!list.produceDate">—</a>
-            </td>
             <td>
               <a v-if="list.packaging">{{list.packaging}}</a>
               <a v-if="!list.packaging">—</a>
             </td>
+            <td>
+              <a v-if="list.produceDate">{{list.produceDate}}</a>
+              <a v-if="!list.produceDate">—</a>
+            </td>
             <td style="text-align: left;padding-left: 25px;">
               <a>
                 <div v-if="list.reserve">
@@ -120,7 +121,7 @@
               </a>
             </td>
             <td>
-              <buy :item="list"></buy>
+              <buy :item="list" :disabledFlag="list.status === 602"></buy>
             </td>
           </tr>
           <tr v-if="!storeList.content || storeList.content.length == 0">
@@ -342,6 +343,11 @@
     vertical-align: middle;
     text-align: center;
   }
+  .storeInfo .goodsList tbody tr td .sellout-flag {
+    position: absolute;
+    right: 0;
+    bottom: 0;
+  }
   .storeInfo .goodsList tbody tr td a {
     color: #474443;
   }
@@ -396,10 +402,7 @@
     margin-left: 10%;
   }
   .storeInfo .table tbody tr:hover{
-    background: #f5f5f5;
-  }
-  .storeInfo .table tbody tr:hover{
-    background: #f5f5f5;
+    background: #ecf2fd;
   }
   .storeInfo .goodsList .can-div-sell {
     text-align: left;

+ 11 - 3
components/provider/Carousel.vue

@@ -3,7 +3,9 @@
     <div v-swiper:mySwiper="swiperOption">
       <div class="swiper-wrapper">
         <div class="swiper-slide" v-for="banner in banners">
-          <img :src="banner.pictureUrl">
+          <a :href="banner.hrefUrl" target="_blank">
+            <img :src="banner.pictureUrl">
+          </a>
         </div>
       </div>
       <div class="swiper-pagination swiper-pagination-bullets"></div>
@@ -20,10 +22,12 @@
         activeSlide: 0,
         swiperOption: {
           autoplay: 5000,
-          initialSlide: 1,
+          initialSlide: 0,
           loop: true,
           effect: 'fade',
           lazyLoading: true,
+          // 解决点击分页器后图片就不能轮播的问题
+          autoplayDisableOnInteraction: false,
           pagination: '.swiper-pagination',
           paginationClickable: true,
           paginationElement: 'li',
@@ -42,7 +46,11 @@
 //    }
     computed: {
       banners () {
-        return this.$store.state.carousel.banners.data
+        let banner = this.$store.state.carousel.banners
+        banner.data.sort(function (a, b) {
+          return a.orderNumber - b.orderNumber
+        })
+        return banner.data
       }
     }
   }

+ 15 - 7
components/provider/NewStore.vue

@@ -50,18 +50,26 @@ export default {
     },
     storeCount () {
       return this.$store.state.provider.storeCms.storeCount.data
+    },
+    enterprise () {
+      let ens = this.user.data.enterprises
+      if (ens && ens.length) {
+        return ens.find(item => item.current) || {enName: '个人账户'}
+      } else {
+        return {enName: '个人账户'}
+      }
     }
   },
   methods: {
     goStoreApply: function () {
-      if (!this.user.logged) {
-        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)
-          }
-        })
+      if (this.user.logged) {
+        if (this.enterprise && this.enterprise.isVendor === 313) {
+          window.location.href = '/vendor#/store-apply'
+        } else {
+          this.$router.push('/register-saler')
+        }
       } else {
-        window.location.href = '/vendor#/store-apply'
+        this.$router.push('/auth/login')
       }
     }
   }

+ 23 - 1
components/provider/Suppliers.vue

@@ -15,7 +15,7 @@
         </td>
         <td width="150" style="vertical-align: middle"><span>入驻商家:</span><span class="text-message">{{stores ? stores.totalElements : 0}}</span><span>家</span></td>
         <td width="150" style="vertical-align: middle;">
-          <a href="/vendor#/store-apply" style="width: 100px; height: 30px; display: inline-block;"><button class="btn btn-primary" style="margin-left: 6px;">立即入驻</button></a>
+          <a @click="goStoreApply" style="width: 100px; height: 30px; display: inline-block;"><button class="btn btn-primary" style="margin-left: 6px;">立即入驻</button></a>
         </td>
       </tr>
       </thead>
@@ -73,6 +73,17 @@ export default {
   computed: {
     stores () {
       return this.$store.state.provider.stores.storeList.data
+    },
+    user () {
+      return this.$store.state.option.user
+    },
+    enterprise () {
+      let ens = this.user.data.enterprises
+      if (ens && ens.length) {
+        return ens.find(item => item.current) || {enName: '个人账户'}
+      } else {
+        return {enName: '个人账户'}
+      }
     }
   },
   methods: {
@@ -108,6 +119,17 @@ export default {
       this.pageParams.keyword = this.keyword === '' ? null : this.keyword
 
       this.pageCommodity(this.pageParams)
+    },
+    goStoreApply: function () {
+      if (this.user.logged) {
+        if (this.enterprise && this.enterprise.isVendor === 313) {
+          window.location.href = '/vendor#/store-apply'
+        } else {
+          this.$router.push('/register-saler')
+        }
+      } else {
+        this.$router.push('/auth/login')
+      }
     }
   }
 }

+ 12 - 5
components/register-saler/register/StepThird.vue

@@ -265,7 +265,7 @@
       <span @click="sectionChange(2)">上一步</span>
       <span @click="btnDisabled?'':selectFlag == 'open'?submitApply():goProduct()" :class="btnDisabled?'btn-disabled':''">提交申请</span>
     </div>
-    <div class="loading" v-if="showLoading">
+    <div class="loading" v-show="showLoading">
       <img src="/images/all/loading.gif" alt="">
     </div>
   </div>
@@ -413,6 +413,7 @@
         }
       },
       registerSelf: function () {
+        this.showLoading = true
         this.$http.post('/basic/enterprise/register?filePath=' + this.registerData.url, this.registerData.enterprise)
           .then(response => {
             if (response.data.success) {
@@ -426,17 +427,20 @@
                     this.loginData.enterprise.uu = response.data.data.enuu
                     this.storeApply(response.data.data.enuu)
 //                    window.location.reload()
+                    this.showLoading = false
                   })
                 }
               )
             } else {
               this.isSelfRegisterSuccess = false
-              this.$message.error('个人注册失败,请重新填写信息')
+              this.showLoading = false
+              this.$message.error('企业注册失败,请重新填写信息')
             }
           }, err => {
             console.log(err)
             this.isSelfRegisterSuccess = false
-            this.$message.error('个人注册失败,请重新填写信息')
+            this.showLoading = false
+            this.$message.error('企业注册失败,请重新填写信息')
           })
       },
       storeApply: function (enuu) {
@@ -558,6 +562,7 @@
           } else if (!this.checkData.checked) {
             this.$message.error('您还没有勾选相关条款')
           } else {
+            this.showLoading = true
             this.$http.post('/basic/enterprise/register?filePath=' + this.registerData.url, this.registerData.enterprise)
               .then(response => {
                 if (response.data.success) {
@@ -566,12 +571,14 @@
                   this.reflashEnterprise(response.data.data.enuu, baseUrl || '/vendor#/vendor_upload')
                 } else {
                   this.isSelfRegisterSuccess = false
-                  this.$message.error('个人注册失败,请重新填写信息')
+                  this.$message.error('企业注册失败,请重新填写信息')
                 }
+                this.showLoading = false
               }, err => {
                 console.log(err)
                 this.isSelfRegisterSuccess = false
-                this.$message.error('个人注册失败,请重新填写信息')
+                this.showLoading = false
+                this.$message.error('企业注册失败,请重新填写信息')
               })
           }
         } else {

+ 65 - 26
components/search/GoodList.vue

@@ -5,8 +5,8 @@
         <div class="fl">&nbsp;&nbsp;| 产品信息(<span class="text-num"></span><span class="text-num" v-text="good_list.total"></span>)</div>
         <div class="fr">
           <div @click="sortBy('normal1')" :class="activeTag==='normal1'?'active':''"><a >综合排序</a></div>
-          <div @click="sortBy('normal2')" :class="activeTag==='normal2'?'active':''"><a >现货优选</a></div>
-          <div @click="sortBy('type')" :class="activeTag==='type'?'active':''"><a >型号精确</a></div>
+          <div @click="sortBy('normal2')" :class="activeTag==='normal2'?'active':''"><a >现货优选<i class="fa fa-long-arrow-down" v-show="reserve_asc"></i><i class="fa fa-long-arrow-up" v-show="!reserve_asc"></i></a></div>
+          <!--<div @click="sortBy('type')" :class="activeTag==='type'?'active':''"><a >型号精确</a></div>-->
           <div style="display:none"><a href="">销量</a></div>
           <div style="display:none"><a href="">人气</a></div>
           <div style="display:none"><a href="">信用</a></div>
@@ -40,33 +40,39 @@
         <table class="product-list" >
           <thead>
           <tr style="height: 40px;">
-            <th width="80"></th>
+            <!--<th width="80"></th>-->
             <th width="160">品牌/型号/类目</th>
-            <th width="100">装/生产日期</th>
-            <th width="110">店铺名称</th>
+            <th width="100">装/生产日期</th>
+            <th width="110">商家名称</th>
             <th width="110">库存</th>
-            <th width="90">梯</th>
+            <th width="90">梯度/pcs</th>
             <th width="90" v-if="!crname_click_flag.rmb_click_flag">香港交货</th>
             <th width="110" v-if="!crname_click_flag.usd_click_flag">大陆交货<span style="font-size: 12px;">(含税)</span></th>
             <th width="110">交期<span style="font-size: 12px;">(天)</span></th>
+            <th width="100">规格书</th>
             <th width="100">操作</th>
           </tr>
           </thead>
           <tbody id="productList-content">
-          <tr v-for="item in good_list.components">
-            <td>
-              <nuxt-link class="component-img-box" :to="item.batchCode?`/store/${item.storeId}/${item.batchCode}`:`/product/component/${item.uuid}`">
-      <!--          <img :src="item.img?item.img:item.brand&&item.brand.logoUrl?item.brand.logoUrl:'/images/component/default.png'">-->
-                <img :src="item.batchCode?item.img?item.img:'/images/component/default.png':item.brand&&item.brand.logoUrl?item.brand.logoUrl:'/images/component/default.png'">
-              </nuxt-link>
-            </td>
+          <tr v-for="item in good_list.components" @click="goUnstandardDetail(item)">
+            <!--<td>-->
+            <!--<nuxt-link class="component-img-box" :to="item.batchCode?`/store/${item.storeId}/${item.batchCode}`:`/product/component/${item.uuid}`">-->
+              <!--&lt;!&ndash;          <img :src="item.img?item.img:item.brand&&item.brand.logoUrl?item.brand.logoUrl:'/images/component/default.png'">&ndash;&gt;-->
+              <!--<img class="component-img" :src="item.batchCode?item.img?item.img:'/images/component/default.png':item.brand&&item.brand.logoUrl?item.brand.logoUrl:'/images/component/default.png'">-->
+              <!--<img v-if="item.status === 602" class="sellout-flag" src="/images/search/sellout-search.png" alt="">-->
+            <!--</nuxt-link>-->
+          <!--</td>-->
             <td class="brand-code">
-              <div class="brand" v-if="item.brand.nameEn"><nuxt-link :to="`/product/brand/${item.brand.uuid}`" class="text-num" v-text="item.brand.nameEn"></nuxt-link></div>
-              <div class="brand" v-if="!item.brand.nameEn">—</div>
-              <div class="code"  v-if="item.code"><nuxt-link :to="`/product/component/${item.uuid}`" class="f16 text-bold text-num" v-text="item.code"></nuxt-link></div>
+              <img v-if="item.status === 602" class="sellout-flag" src="/images/search/sellout-search.png" alt="">
+              <div class="brand" v-if="item.brand&&item.brand.nameEn"><nuxt-link :to="`/product/brand/${item.brand.uuid}`" class="text-num" v-text="item.brand.nameEn"></nuxt-link></div>
+              <div class="brand" v-if="!item.brand||!item.brand.nameEn">{{item.brandEn||'—'}}</div>
+              <div class="code"  v-if="item.code">
+                <nuxt-link v-if="item.uuid" :to="`/product/component/${item.uuid}`" class="f16 text-bold text-num" v-text="item.code"></nuxt-link>
+                <span v-if="!item.uuid">{{item.code}}</span>
+              </div>
               <div class="brand" v-if="!item.code">—</div>
-              <div class="brand"  v-if="item.kind.nameCn"><nuxt-link :to="`/product/kind/${item.kindid}`" v-text="item.kind.nameCn"></nuxt-link></div>
-              <div class="brand" v-if="!item.kind.nameCn">—</div>
+              <div class="brand"  v-if="item.kind&&item.kind.nameCn"><nuxt-link :to="`/product/kind/${item.kindid}`" v-text="item.kind.nameCn"></nuxt-link></div>
+              <div class="brand" v-if="!item.kind||!item.kind.nameCn">{{item.kindName || ''}}</div>
             </td>
             <td>
               <div class="package" v-text="item.packaging"></div>
@@ -127,12 +133,16 @@
                 <span v-if="item.b2cMinDelivery == item.b2cMaxDelivery" v-text="item.b2cMinDelivery"></span>
               </div>
             </td>
+            <td>
+              <span v-if="item.attach && item.attach !=='1'"><a :href="item.attach" target="_blank"><img src="/images/store/common/pdf.png" alt=""/></a></span>
+              <span v-show="!item.attach || item.attach =='1'">—</span>
+            </td>
             <td>
               <div v-show="!item.reserve">
                 <span>—</span>
               </div>
               <div v-if="item.reserve > 0">
-              <buy :item="item" :isStoreStyle="false"></buy>
+              <buy :item="item" :isStoreStyle="false" :disabledFlag="item.status === 602"></buy>
               </div>
             </td>
           </tr>
@@ -169,6 +179,7 @@
         pageSize: 15,
         sorting: {},
         price_asc: true,
+        reserve_asc: true,
         min_price: '',
         max_price: '',
         filter: {},
@@ -206,6 +217,12 @@
         return input
       }
     },
+    watch: {
+      $route: function (val, oldVal) {
+        this.filter = {}
+        this.activeTag = 'normal1'
+      }
+    },
     computed: {
       good_lists () {
         return this.$store.state.searchData.searchList.lists
@@ -230,24 +247,30 @@
       },
       sortBy: function (param) {
         if (param === 'normal1') {
-          this.sorting = {'GO_SEARCH': 'DESC', 'GO_RESERVE': 'DESC'}
+          this.sorting = {}
           this.activeTag = 'normal1'
         } else if (param === 'normal2') {
-          this.sorting = {'GO_RESERVE': 'DESC', 'GO_SEARCH': 'DESC'}
+          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 = {'GO_SEARCH': 'DESC', 'GO_RESERVE': 'DESC'}
+          this.sorting = {'RESERVE': 'DESC'}
           this.activeTag = 'type'
         } else if (param === 'price') {
           if (this.price_asc) {
-            this.sorting = {'GO_MINPRICERMB': 'ASC', 'GO_RESERVE': 'DESC', 'GO_SEARCH': 'DESC'}
+            this.sorting = {'PRICE': 'ASC'}
           } else {
-            this.sorting = {'GO_MINPRICERMB': 'DESC', 'GO_RESERVE': 'DESC', 'GO_SEARCH': 'DESC'}
+            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 !== '') {
@@ -269,6 +292,11 @@
         this.min_price = ''
         this.max_price = ''
         this.$emit('filterPriceEvent', this.filter)
+      },
+      goUnstandardDetail: function (comp) {
+        if (!comp.brand && comp.brandEn) {
+          this.$router.push('/store/' + comp.storeId + '/' + comp.batchCode)
+        }
       }
     }
   }
@@ -409,6 +437,7 @@
   .product-list .brand-code {
     font-size: 14px;
     text-align: center;
+    position: relative;
   }
   .product-list .brand-code .brand{
   font-size: 12px;
@@ -427,13 +456,23 @@
 
   .product-list tbody>tr {
     border: 1px solid #e8e8e8;
+    cursor: pointer ;
+    position: relative;
   }
-
+  .product-list tbody>tr:hover{
+   background: #ecf2fd;
+ }
   .product-list tbody>tr .component-img-box {
     width: 80px;
     height: 80px;
+    position: relative;
+  }
+  .product-list tbody>tr .brand-code .sellout-flag {
+    position: absolute;
+    right: 0;
+    bottom: 0;
   }
-  .product-list tbody>tr img {
+  .product-list tbody>tr .component-img-box .component-img {
     border: 1px solid #e8e8e8;
     margin: 10px 0 5px 0;
     max-width: 80px;

+ 23 - 0
components/search/Kind.vue

@@ -265,6 +265,29 @@
         }
       }
     },
+    watch: {
+      $route: function (val, oldVal) {
+        this.store_type_co = {store_type: 'CONSIGNMENT'}
+        this.store_type_ag = {store_type: 'AGENCY'}
+        this.store_type_di = {store_type: 'DISTRIBUTION'}
+        this.store_type_or = {store_type: 'ORIGINAL_FACTORY'}
+        this.filter = {}
+        this.kind_arr = []
+        this.brand_arr = []
+        this.type_arr = []
+        this.crname_arr = []
+        this.kind_exp_arr = []
+        this.brand_exp_arr = []
+        this.co_click_flag = false
+        this.ag_click_flag = false
+        this.di_click_flag = false
+        this.or_click_flag = false
+        this.crname_click_flag = {
+          rmb_click_flag: false,
+          usd_click_flag: false
+        }
+      }
+    },
     computed: {
       list_kinds () {
         return this.$store.state.searchData.searchKinds.kinds

+ 1 - 1
components/search/ResultTitle.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="result-title text-muted">
-    搜索"<span class="text-inverse" >{{keyword}}</span>"<span v-if="status != 1">暂无结果</span>
+    搜索"<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>

+ 10 - 0
components/searchStore/StoreContent.vue

@@ -33,6 +33,7 @@
             <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>-->
+          <img v-if="item.status == 602" class="sellout-store-commodity" src="/images/search/sellout-search.png" alt="">
           <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>
@@ -260,12 +261,14 @@
     float: right;
   }
   .store-component-list >li {
+    position: relative;
     display: inline-block;
     text-align: center;
     border: 1px solid rgb( 231, 231, 231 );
     margin-right: 14px;
     width: 152px;
     height: 178px;
+    vertical-align: middle;
   }
   .store-component-list >li:hover {
     cursor: pointer;
@@ -282,6 +285,13 @@
     width: 149px;
     height:114px;
   }
+  .store-component-list >li >img {
+    position: absolute;
+    width: 62px;
+    height: 50px;
+    right: 0;
+    top: 63px;
+  }
   .store-component-list >li .describe-list {
     padding: 2px 10px;
     background: #dee0e5;

+ 111 - 70
components/store/CommodityInfo.vue

@@ -15,7 +15,9 @@
       <div class="commodity-detail">
         <div class="img">
           <img :src="commodity.img || '/images/store/common/default.png'" style="width: 256px;height: 256px;"/>
-          <div class="box"></div>
+          <div class="box">
+            <img v-if="commodity.status === 602" src="/images/store/isSellOut.png" alt="">
+          </div>
         </div>
         <div class="content">
           <div class="code">
@@ -46,7 +48,7 @@
               <span class="name">封&nbsp;装</span>:<span v-text="commodity.encapsulation || '无封装信息'"></span>
             </div>
             <div class="com-info">
-              <span class="name">库&nbsp;存</span>:<span v-text="commodity.reserve || 0"></span>
+              <span class="name">库&nbsp;存</span>:<span v-text="commodity.reserve || 0"></span><em style="margin-left: 3px;">PCS</em>
               (<span v-text="commodity.minBuyQty || 1"></span>个起订)
               <span :class="commodity.breakUp?'div-sell can-div-sell':'div-sell not-div-sell'" v-text="commodity.breakUp?'可拆卖':'不可拆卖'" ></span>
             </div>
@@ -59,11 +61,11 @@
                 <span>(天)</span>
               </div>
             </div>
-            <div class="com-info form-inline">
+            <div class="com-info form-inline" v-if="commodity.status !== 602 && commodity.status !== 612">
               <span class="name">数&nbsp;量</span>:
               <div class="input-group" style="width: 120px">
                 <div :class="fragment.canSub ? ' input-group-addon operate':'input-group-addon'" @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;"/>
+                <input type="text" class="form-control" placeholder="数量" v-model="fragment.num" @change="inputNum()" @input="onInput()" style="padding: 0;min-width: 100px;text-align: center;"/>
                 <div :class="fragment.canAdd ?'input-group-addon operate':'input-group-addon'" @click="fragment.canAdd ?addNum():''" :style="!fragment.canAdd ?'cursor: not-allowed;':''">+</div>
                 <!--   <div class="input-group-addon operate" @click="subNum()">-</div>
                    <input type="text" class="form-control" placeholder="数量" v-model="fragment.num" @change="inputNum()"style="padding: 0;min-width: 100px;text-align: center;"/>
@@ -89,17 +91,18 @@
                  <span>{{(calculate || 0) | currency}}</span>
               </span>
             </div>
-            <div class="button">
+            <div class="button" v-if="commodity.status !== 602 && commodity.status !== 612">
               <button class="btn btn-default btn-primary" @click="buyNow(false, commodity)">加入购物车</button>
               <button class="btn btn-default btn-now" @click="buyNow(true, commodity)">立即购买</button>
             </div>
+            <div class="warn-area" v-if="commodity.status === 602 || commodity.status === 612" v-text="commodity.status === 602 ? '此产品已售罄':'此产品已下架'"></div>
           </div>
           <div class="price-block">
             <div class="commodity-price">
               <div class="title">价格梯度</div>
               <div class="table">
                 <div class="head">
-                  <div class="fragment">数量</div>
+                  <div class="fragment">梯度/pcs</div>
                   <div class="price">单价¥(含税)</div>
                   <div class="price">单价$</div>
                 </div>
@@ -176,6 +179,10 @@
           canSub: true}
       }
     },
+    watch: {
+      fragment: function (val, oldVal) {
+      }
+    },
     filters: {
       currency: function (num) {
         if (typeof num === 'number' && num > 0) {
@@ -215,8 +222,8 @@
         return this.$store.state.shop.storeInfo.component.data
       },
       calculate () {
-        this.fragment.total = this.fragment.price * this.fragment.num
-        return Math.ceil(this.fragment.total * Math.pow(10, 6)) / Math.pow(10, 6)
+        this.fragment.total = this.fragment.price * Math.pow(10, 6) * this.fragment.num
+        return Math.ceil(this.fragment.total) / Math.pow(10, 6)
       },
       user () {
         return this.$store.state.option.user
@@ -228,6 +235,18 @@
       })
     },
     methods: {
+      onInput () {
+        let prices = this.commodity.prices
+        if (prices && prices.length) {
+          let _this = this
+          for (let i = 0; i < prices.length; i++) {
+            if (_this.fragment.num >= prices[i].start && _this.fragment.num <= prices[i].end) {
+              _this.fragment.price = _this.fragment.currency === 'RMB' ? prices[i].rMBPrice : prices[i].uSDPrice
+              break
+            }
+          }
+        }
+      },
       loadSaveHistory () {
         if (this.user.logged) {
           this.$store.dispatch('shop/saveHistory', {id: this.commodity.batchCode})
@@ -245,55 +264,59 @@
         let buy = this.commodity.minBuyQty
         let reserve = this.commodity.reserve
         let breakUp = this.commodity.breakUp
-        newNum = parseInt(newNum)
-        if (breakUp) {
-          if (newNum < buy) {
-            this.$message.error('最小起订量为' + buy)
-            this.fragment.num = buy
-            this.fragment.canSub = false
-            this.fragment.canAdd = true
-          } else if (newNum > reserve) {
-            this.$message.error('库存不足')
-            this.fragment.num = reserve
-            this.fragment.canAdd = false
-            this.fragment.canSub = true
-          } else {
-            this.fragment.canSub = true
-            this.fragment.canAdd = true
-            this.fragment.num = newNum
-            newNum === buy && (this.fragment.canSub = false)
-            newNum === reserve && (this.fragment.canAdd = false)
-          }
+        if (!newNum) {
+          this.fragment.num = buy
         } else {
-          if (newNum < buy) {
-            this.$message.error('最小起订量为' + buy)
-            this.fragment.num = buy
-            this.fragment.canSub = false
-            if (newNum > reserve) {
+          newNum = parseInt(newNum)
+          if (breakUp) {
+            if (newNum < buy) {
+              this.$message.error('最小起订量为' + buy)
+              this.fragment.num = buy
+              this.fragment.canSub = false
+              this.fragment.canAdd = true
+            } else if (newNum > reserve) {
               this.$message.error('库存不足')
-              this.fragment.num = reserve - (reserve % pack)
+              this.fragment.num = reserve
               this.fragment.canAdd = false
+              this.fragment.canSub = true
+            } else {
+              this.fragment.canSub = true
+              this.fragment.canAdd = true
+              this.fragment.num = newNum
+              newNum === buy && (this.fragment.canSub = false)
+              newNum === reserve && (this.fragment.canAdd = false)
             }
-          } else if (newNum > reserve) {
-            this.fragment.canSub = true
-            this.fragment.canAdd = false
-            this.$message.error('库存不足')
-            this.fragment.num = reserve - (reserve % pack)
           } else {
-            this.fragment.canSub = true
-            this.fragment.canAdd = true
-            let remainder = newNum % pack
-            if (remainder !== 0) {
-              console.log(this.fragment.num)
-              this.$message.error('不支持拆包且包装量为' + pack)
-              // 这个直接赋值的,应该给这个值进行判断(Math.floor(newNum / pack) + 1) * pack
-              let res = (Math.floor(newNum / pack) + 1) * pack
-              this.fragment.num = res > reserve ? Math.floor(newNum / pack) * pack : res
+            if (newNum < buy) {
+              this.$message.error('最小起订量为' + buy)
+              this.fragment.num = buy
+              this.fragment.canSub = false
+              if (newNum > reserve) {
+                this.$message.error('库存不足')
+                this.fragment.num = reserve - (reserve % pack)
+                this.fragment.canAdd = false
+              }
+            } else if (newNum > reserve) {
+              this.fragment.canSub = true
+              this.fragment.canAdd = false
+              this.$message.error('库存不足')
+              this.fragment.num = reserve - (reserve % pack)
             } else {
-              this.fragment.num = newNum
+              this.fragment.canSub = true
+              this.fragment.canAdd = true
+              let remainder = newNum % pack
+              if (remainder !== 0) {
+//                console.log(this.fragment.num)
+                this.$message.error('不支持拆包且包装量为' + pack)
+                // 这个直接赋值的,应该给这个值进行判断(Math.floor(newNum / pack) + 1) * pack
+                let res = (Math.floor(newNum / pack) + 1) * pack
+                this.fragment.num = res > reserve ? Math.floor(newNum / pack) * pack : res
+              } else {
+                this.fragment.num = newNum
+              }
+              newNum === buy && (this.fragment.canSub = false)
+              newNum === reserve && (this.fragment.canAdd = false)
             }
-            newNum === buy && (this.fragment.canSub = false)
-            newNum === reserve && (this.fragment.canAdd = false)
           }
         }
       },
@@ -307,6 +330,7 @@
         }
         this.changeNum(newNum)
         getFragment(this.commodity, this.fragment)
+        this.onInput()
       },
       addNum () {
         let pack = this.commodity.perQty || this.commodity.minPackQty
@@ -318,6 +342,7 @@
         }
         this.changeNum(newNum)
         getFragment(this.commodity, this.fragment)
+        this.onInput()
       },
       inputNum () {
         if ((/^[\d]*$/).test(this.fragment.num)) {
@@ -511,12 +536,18 @@
     height: 320px;
   }
 
-  .commodity-detail .img img {
-    border: 1px solid #D6D3CE;
+  .commodity-detail .img >img {
+      border: 1px solid #D6D3CE;
   }
 
   .commodity-detail .img  .box {
     height: 62px;
+    position: relative;
+  }
+  .commodity-detail .img  .box img {
+    position: absolute;
+    right: 3px;
+    bottom: 64px;
   }
 
   .commodity-detail .content {
@@ -537,22 +568,26 @@
     line-height: 40px;
   }
 
-  .commodity-detail .content .com-info {
+	.commodity-detail .content .com-info {
+		font-size: 14px;
+		line-height: 26px;
+	}
+  .commodity-detail .content .com-info em {
     font-size: 14px;
     line-height: 26px;
-  }
-
-  .input-group .input-group-operate {
-    padding: 6px 12px;
-    font-size: 14px;
-    font-weight: 400;
-    line-height: 1;
-    color: #555;
-    text-align: center;
-    background-color: #eee;
-    border: 1px solid #ccc;
-    border-radius: 4px;
-  }
+    font-style: normal;
+  }
+	.input-group .input-group-operate {
+		padding: 6px 12px;
+		font-size: 14px;
+		font-weight: 400;
+		line-height: 1;
+		color: #555;
+		text-align: center;
+		background-color: #eee;
+		border: 1px solid #ccc;
+		border-radius: 4px;
+	}
 
   .input-group .input-group-operate:last-child {
     border-bottom-left-radius: 0;
@@ -573,6 +608,12 @@
   .content .com-info:hover a{
     color: #23527c;
   }
+  .content .warn-area {
+    font-size: 16px;
+    font-weight: bold;
+    color: #333;
+    margin-top: 15px;
+  }
   .commodity-info-detail {
     float: left;
     padding-top: 10px;
@@ -643,17 +684,17 @@
   }
 
   ul.list-inline {
-    margin: 0px;
+    margin: 0;
   }
 
   .commodity-price ul.list-inline li {
-    padding-left: 0px;
-    padding-right: 0px;
+    padding-left: 0;
+    padding-right: 0;
     border-bottom: 1px dashed #D6D3CE;
   }
 
   .commodity-price .table {
-    margin-bottom: 0px;
+    margin-bottom: 0;
   }
 
   .commodity-price ul>li:last-child {

+ 74 - 32
components/store/CommodityList.vue

@@ -6,7 +6,7 @@
           <span style="line-height: 34px;">产品分类</span>
         </div>
         <div class="category-content">
-          <el-tree :data="kinds" :props="defaultProps" accordion :highlight-current="true" @current-change="handlerCurrentNode"></el-tree>
+          <el-tree :data="kinds" :props="defaultProps" :default-expanded-keys="[0]" node-key="level" accordion :highlight-current="true" @current-change="handlerCurrentNode"></el-tree>
         </div>
       </div>
       <!-- 产品列表 -->
@@ -30,27 +30,29 @@
         <table class="goodslist" style="width: 970px">
           <thead>
           <tr style="height: 40px;">
-            <th width="90"></th>
+            <!--<th width="90"></th>-->
             <th width="150">品牌/型号</th>
             <th width="100">包装/生产日期</th>
             <th width="90">库存</th>
-            <th width="90">数量</th>
-            <th width="90">香港交货<span style="font-size: 12px;">($)</span></th>
-            <th width="100">大陆交货<span style="font-size: 12px;">(¥)</span></th>
+            <th width="90">梯度/pcs</th>
+            <!--<th width="90">香港交货<span style="font-size: 12px;">($)</span></th>-->
+            <!--<th width="100">大陆交货<span style="font-size: 12px;">(¥)</span></th>-->
+            <th width="100">单价</th>
             <th width="100">交期(天)</th>
+            <th width="100">规格书</th>
             <th width="100">操作</th>
           </tr>
           </thead>
           <tbody id="goodslist-content">
-          <tr v-for="commodity in commodities.content">
-            <td class="commodity-icon">
-              <a :href="'/store/' + commodity.storeid + '/' + commodity.batchCode" target="_blank">
-                <div class="img"><img :src="commodity.img || '/images/store/common/default.png'"/></div>
-              </a>
-            </td>
+          <tr v-for="commodity in commodities.content" @click="goBatchDetail(storeInfo.uuid, commodity.batchCode)">
             <td class="brand-code">
-              <div class="brand" v-if="commodity.brandNameEn" v-text="commodity.brandNameEn"></div>
-              <div class="brand" v-if="!commodity.brandNameEn">—</div>
+              <img class="sellout-store-commodity" v-if="commodity.status === 602" src="/images/search/sellout-search.png" alt="">
+              <div class="brand" v-if="commodity.brandNameEn || commodity.brandEn">
+                <a v-if="commodity.brandNameEn && commodity.branduuid" @click="goBrandDetail('/product/brand/' + commodity.branduuid, $event)" v-text="commodity.brandNameEn"></a>
+                <span v-if="commodity.brandNameEn && !commodity.branduuid" v-text="commodity.brandNameEn"></span>
+                <span v-if="commodity.brandEn">{{commodity.brandEn}}</span>
+              </div>
+              <div class="brand" v-if="!commodity.brandNameEn && !commodity.brandEn">—</div>
               <div class="code" v-if="commodity.code" v-text="commodity.code"></div>
               <div class="code" v-if="!commodity.code">—</div>
             </td>
@@ -60,35 +62,39 @@
               <div class="date" v-if='commodity.produceDate' v-text="commodity.produceDate">2016-12-01</div>
             </td>
             <td style="text-align: left;vertical-align: middle;">
-              <div class="goods" v-if="commodity.reserve">
-                库存:<span v-text="commodity.reserve">31500</span>
+              <div class="goods" v-if="commodity.reserve || commodity.status === 602">
+                库存:<span v-text="commodity.reserve"></span>
               </div>
-              <div v-if="!commodity.reserve" style="text-align: center;margin-left: 0;"><span>—</span></div>
-              <div class="from" v-if="commodity.reserve && commodity.reserve>0">
-                起:<span v-if="commodity.minBuyQty" v-text="commodity.minBuyQty">300</span>
+              <div v-if="!commodity.reserve && commodity.status !== 602" style="text-align: center;margin-left: 0;"><span>—</span></div>
+              <div class="from" v-if="commodity.reserve && commodity.reserve>0 || commodity.status === 602">
+                起:<span v-if="commodity.minBuyQty" v-text="commodity.minBuyQty">300</span>
               </div>
               <!--<div class="multiple">
                 倍数:<span>1</span>
               </div>-->
-              <div class="can-div-sell" v-if="commodity.reserve" v-text="commodity.breakUp?'可拆卖':'不可拆卖'"></div>
+              <div class="can-div-sell" v-if="commodity.reserve || commodity.status === 602" v-text="commodity.breakUp?'可拆卖':'不可拆卖'"></div>
             </td>
             <td>
               <div v-for="price in commodity.prices" v-text="price.start + '+'"></div>
             </td>
+            <!--<td>-->
+              <!--<div v-show="commodity.currencyName.indexOf('USD')==-1 || !commodity.prices">-->
+                <!--<span>—</span>-->
+              <!--</div>-->
+              <!--<div v-for="price in commodity.prices">{{price.uSDPrice | currency}}</div>-->
+            <!--</td>-->
+            <!--<td>-->
+              <!--<div v-show="commodity.currencyName.indexOf('RMB')==-1 || !commodity.prices">-->
+                <!--<span>—</span>-->
+              <!--</div>-->
+              <!--<div v-for="price in commodity.prices" >{{price.rMBPrice | currency}}</div>-->
+            <!--</td>-->
             <td>
-              <div v-show="commodity.currencyName.indexOf('USD')==-1 || !commodity.prices">
-                <span>—</span>
-              </div>
-              <div v-for="price in commodity.prices">{{price.uSDPrice | currency}}</div>
+              <div v-for="price in commodity.prices">{{commodity.currencyName.indexOf('USD')!=-1?'$':'¥'}}{{commodity.currencyName.indexOf('USD')!=-1?price.uSDPrice:price.rMBPrice | currency}}</div>
+              <div v-if="commodity.currencyName.indexOf('RMB')==-1 || !commodity.prices && commodity.currencyName.indexOf('USD')==-1 || !commodity.prices"></div>
             </td>
             <td>
-              <div v-show="commodity.currencyName.indexOf('RMB')==-1 || !commodity.prices">
-                <span>—</span>
-              </div>
-              <div v-for="price in commodity.prices" >{{price.rMBPrice | currency}}</div>
-            </td>
-            <td>
-              <div v-if="commodity.b2cMinDelivery">交期:
+              <div v-if="commodity.b2cMinDelivery">
                 <!--{{commodity.b2cMinDelivery || 0}}-{{commodity.b2cMaxDelivery || 0}}天-->
                 <span v-if="commodity.b2cMinDelivery != commodity.b2cMaxDelivery" v-text="commodity.b2cMinDelivery + '-' + commodity.b2cMaxDelivery"></span>
                 <span v-if="commodity.b2cMinDelivery == commodity.b2cMaxDelivery" v-text="commodity.b2cMinDelivery"></span>
@@ -96,7 +102,13 @@
               <div v-if="!commodity.b2cMinDelivery"><span>—</span></div>
             </td>
             <td>
-              <buy :item="commodity"></buy>
+              <div v-if="commodity.attach">
+                <a :href="commodity.attach && commodity.attach !== '1'" target="_blank"><img src="/images/store/common/pdf.png" alt=""/></a>
+              </div>
+              <div v-show="!commodity.attach || commodity.attach == '1'">—</div>
+            </td>
+            <td>
+              <buy :item="commodity" :disabledFlag="commodity.status === 602"></buy>
             </td>
           </tr>
           <tr v-if="!commodities.content || commodities.content.length == 0">
@@ -128,6 +140,9 @@ function getAllLeafIds (kind) {
     return null
   }
   if (kind.isLeaf === 1) {
+    if (kind.nameCn === '其他') {
+      return '其他'
+    }
     return kind.id
   } else {
     if (!kind.children || kind.children.length === 0) {
@@ -193,6 +208,9 @@ export default {
   computed: {
     commodities () {
       return this.$store.state.shop.storeInfo.storeCommodity.data
+    },
+    storeInfo () {
+      return this.$store.state.shop.storeInfo.store.data
     }
   },
   methods: {
@@ -236,6 +254,13 @@ export default {
     handleCurrentChange (page) {
       this.pageParams.page = page
       this.pageCommodity(this.pageParams, this.ids, this.searchCode)
+    },
+    goBatchDetail (storeId, batchCode) {
+      window.open('/store/' + storeId + '/' + batchCode)
+    },
+    goBrandDetail (url, event) {
+      event.stopPropagation()
+      window.open(url)
     }
 //    goBack () {
 //      this.$router.back(-1)
@@ -393,6 +418,7 @@ export default {
 	#goods-list-fragment .goodslist .brand-code {
 		font-size: 14px;
 		text-align: center;
+    position: relative;
 	}
 
 	#goods-list-fragment #search_btn {
@@ -407,6 +433,9 @@ export default {
 	#goods-list-fragment .brand-code .code {
 		font-weight: 600;
 	}
+#goods-list-fragment .brand-code .brand a:hover {
+  color: #f39801;
+}
 
 	#goods-list-fragment .goodslist th {
 		color: rgb(50,50,50);
@@ -428,7 +457,14 @@ export default {
 
 	#goods-list-fragment .goodslist tbody>tr {
 		border: 1px solid #e8e8e8;
+    cursor: pointer;
 	}
+#goods-list-fragment .goodslist tbody>tr:hover{
+  background: #ecf2fd;
+}
+  #goods-list-fragment .goodslist tbody>tr td.commodity-icon {
+    position: relative;
+  }
 	#goods-list-fragment .goodslist tbody>tr td.commodity-icon .img{
 		border: 1px solid #e8e8e8;
 		margin: 10px;
@@ -441,6 +477,11 @@ export default {
 		width: 80px;
 		height: 80px;
 	}
+  #goods-list-fragment .goodslist tbody>tr td.brand-code .sellout-store-commodity {
+    position: absolute;
+    right: 0;
+    bottom: 0;
+  }
 	#goods-list-fragment .goodslist td {
 		font-size: 12px;
 		color: #333;
@@ -453,6 +494,7 @@ export default {
 
 	/* 物品列表按钮 */
 	#goods-list-fragment .btn-buy-now {
+    margin: 5px 0;
 		background-color: #5078CB;
 		color: #fff;
 		width: 80px;
@@ -462,7 +504,7 @@ export default {
 	}
 
 	#goods-list-fragment .btn-add-cart {
-		margin-top: 10px;
+    margin: 10px 0 5px 0;
 		color: #214797;
 		width: 80px;
 		height: 30px;

+ 20 - 4
components/store/ComponentInfo.vue

@@ -4,15 +4,16 @@
       <div class="head">
         <span class="tab">产品参数<b class="tip">(仅供参考,以实际产品为准)</b></span>
       </div>
-      <ul class="list-unstyled list-inline" style="margin-left: 0px;" v-if="component.properties">
-        <li v-for="property in component.properties">
+      <ul class="list-unstyled list-inline" style="margin-left: 0px;">
+        <li v-for="property in component.properties" v-if="property.value">
           <div class="property-name">
             <span v-text="property.property.labelCn"></span>:
           </div>
           <div class="property-value">{{property.value ? property.value : '-'}}</div>
         </li>
-        <li v-if="!component.properties || component.properties.length === 0" class="text-center" style="display:block;margin-top:0;">
-          暂无参数信息
+        <li v-if="!commodity.uuid || !component.properties || component.properties.length === 0" class="text-info">
+          <!--<i class="fa fa-smile-o fa-lg"></i> 暂无参数信息-->
+          <span class="info">卖家上传的产品暂无参数,请 <a href="">联系卖家</a> 了解具体详情</span>
         </li>
       </ul>
     </div>
@@ -25,6 +26,9 @@ export default {
   computed: {
     component () {
       return this.$store.state.shop.storeInfo.component.data
+    },
+    commodity () {
+      return this.$store.state.shop.storeInfo.commodity.data
     }
   }
 }
@@ -52,6 +56,18 @@ export default {
 		line-height: 30px;
 	}
 
+  .component-info ul li.text-info span.info{
+    padding-left: 270px;
+    font-size: 14px;
+    color: #333;
+  }
+  .component-info ul li.text-info span.info a{
+    font-size: 14px;
+    color: #5078cb;
+  }
+  .component-info ul li.text-info span.info a:hover{
+    text-decoration: underline!important ;
+  }
 	.component-info .head {
 		font-size: 14px;
 		font-weight: 600;

+ 11 - 1
components/store/RecommendProduct.vue

@@ -3,7 +3,11 @@
     <div class="recommend-list">
       <ul>
         <li v-for="commodity in commodities">
-          <div class="img"><a href="javascript:void(0);"><img :src="commodity.comImg.startsWith('static')?'/'+commodity.comImg:commodity.comImg"/></a></div>
+          <div class="img">
+            <a href="javascript:void(0);">
+              <img :src="commodity.comImg.startsWith('static')?'/'+commodity.comImg:commodity.comImg"/>
+            </a>
+          </div>
           <div class="content">
             <p v-text="commodity.comCode">MRFE6S9045NF001</p>
             <p class="color666" v-text="commodity.brandNameCn">PANFAEFQ</p>
@@ -21,6 +25,7 @@
             <div class="by-cart"><button title="加入购物车" @click="buyNow(false, commodity)"><img src="/images/store/icon/cart-blue.png"/></button></div>
             <div class="buy-now"><button title="立即购买" @click="buyNow(true, commodity)">立即购买</button></div>
           </div>
+          <img class="recommend-sellout" v-if="commodity.status == 602" src="/images/store/isSellOut.png" alt="">
         </li>
       </ul>
     </div>
@@ -395,4 +400,9 @@
     text-align: center;
     height: 260px;
   }
+  #recommend-fragment ul li .recommend-sellout {
+    position: absolute;
+    right: 0;
+    bottom: 0;
+  }
 </style>

+ 88 - 1
components/store/common/StoreHeader.vue

@@ -14,13 +14,17 @@
                   </a>
                 </div>
                 <div class="icon-style">
-                  <!--<button class="btn btn-xs btn-danger btn-nav" v-if="!isFocus"><span class="watch">关注</span></button>-->
+                  <button class="btn btn-xs btn-danger btn-nav" v-if="!isFocus"><span class="watch">关注</span></button>
                   <span v-if="isFocus == 'false' || typeof isFocus == 'object'"><button type="text" @click="focus(storeInfo.id, storeInfo.storeName)" class="btn btn-xs btn-danger btn-nav"><span class="watch">关注</span></button></span>
                   <span v-if="isFocus == 'true'" ><button class="btn btn-xs btn-default btn-nav" style="width:50px"><span>已关注</span></button></span>
                   <span v-if="storeInfo.type == 'ORIGINAL_FACTORY'">&nbsp;<img src="/images/store/icon/icon-factory.png"/></span>
                   <span v-else-if="storeInfo.type == 'AGENCY'">&nbsp;<img src="/images/store/icon/icon-agent.png"/></span>
                   <span v-else-if="storeInfo.type == 'DISTRIBUTION'">&nbsp;<img src="/images/store/icon/icon-distribution.png"/></span>
                   <span v-else-if="storeInfo.type == 'CONSIGNMENT'">&nbsp;<img src="/images/store/icon/consignment.png"/></span>
+                  <span class="link-seller">
+                    <img src="/images/all/songguo.png">
+							      <a @click="goWebChat()" class="contact_btn">联系卖家</a>
+                  </span>
                 </div>
               </div>
               <div class="clearfix"></div>
@@ -87,6 +91,9 @@ export default {
     },
     isFocus () {
       return this.$store.state.shop.storeInfo.focusList.data
+    },
+    tab () {
+      return this.$store.state.chat.tab.tab.data
     }
   },
   methods: {
@@ -108,6 +115,68 @@ export default {
         this.$store.dispatch('shop/StoreFocus', {storeName: name, storeid: id})
         this.isFocus = true
       }
+    },
+    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 => {
+                console.log(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
+              console.log(obj)
+              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
+          }
+        })
     }
   }
 }
@@ -388,4 +457,22 @@ export default {
 		position: relative;
 		top: -9px;
 	}
+  .icon-style >span {
+    margin-right: 5px;
+  }
+  .icon-style .link-seller {
+    cursor: pointer;
+  }
+  .icon-style .link-seller img {
+    top: -2px;
+  }
+  .icon-style .link-seller a {
+    font-size: 12px;
+    color: #fff;
+    line-height: 20px;
+    height: 20px;
+    padding: 0 7px;
+    background: #ef7f03;
+    border-radius: 2px;
+  }
 </style>

+ 54 - 21
layouts/error.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="error">
-    <div class="section">
+    <div class="section" :class="{'mobile-page': isMobile}">
       <div class="container">
         <div class="btn-click">
           <a href="/"><i class="fa fa-home" style="margin-right:5px;"></i>返回首页</a>
@@ -13,7 +13,18 @@
 
 <script>
   export default {
-    props: ['error']
+    props: ['error'],
+    layout (context) {
+      return context.store.state.option.isMobile ? 'login' : 'default'
+    },
+    computed: {
+      isMobile () {
+        return this.$store.state.option.isMobile
+      }
+//      background () {
+//        return this.isMobile ? '#ebfdff url("/images/404-mobile.png")no-repeat center center' : '#ebfdff url("/images/404.png")no-repeat center center'
+//      }
+    }
   }
 </script>
 
@@ -22,24 +33,46 @@
     background: #ebfdff url('/images/404.png')no-repeat center center;
     height:900px;
     position:relative;
-  }
-  .section .btn-click{
-    position:absolute;
-    top:54%;
-    left:50%;
-    margin-left:-150px;
-  }
-  .section .btn-click a{
-    display:inline-block;
-    width:130px;
-    height:33px;
-    font-size: 16px;
-    line-height: 33px;
-    color:#fff;
-    background: #f87c29;
-    text-align: center;
-    margin:0 10px;
-    border-radius: 2px;
-    text-decoration: none;
+    .btn-click{
+      position:absolute;
+      top:54%;
+      left:50%;
+      margin-left:-150px;
+      a{
+        display:inline-block;
+        width:130px;
+        height:33px;
+        font-size: 16px;
+        line-height: 33px;
+        color:#fff;
+        background: #f87c29;
+        text-align: center;
+        margin:0 10px;
+        border-radius: 2px;
+        text-decoration: none;
+      }
+    }
+    &.mobile-page {
+      background: #ebfdff url("/images/404-mobile.png")no-repeat center center;
+      position: fixed;
+      top: 0;
+      bottom: 0;
+      left: 0;
+      right: 0;
+      height: auto;
+      .btn-click{
+        top: 66%;
+        left: 1.2rem;
+        margin-left: 0;
+        a{
+          width: 2.3rem;
+          height: .63rem;
+          font-size: .32rem;
+          line-height: .63rem;
+          margin: 0 .1rem;
+          border-radius: .04rem;
+        }
+      }
+    }
   }
 </style>

+ 54 - 21
layouts/errorPage.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="error">
-    <div class="section">
+    <div class="section" :class="{'mobile-page': isMobile}">
       <div class="container">
         <div class="btn-click">
           <a href="/"><i class="fa fa-home" style="margin-right:5px;"></i>返回首页</a>
@@ -13,7 +13,18 @@
 
 <script>
   export default {
-    props: ['error']
+    props: ['error'],
+    layout (context) {
+      return context.store.state.option.isMobile ? 'login' : 'default'
+    },
+    computed: {
+      isMobile () {
+        return this.$store.state.option.isMobile
+      }
+//      background () {
+//        return this.isMobile ? '#ebfdff url("/images/404-mobile.png")no-repeat center center' : '#ebfdff url("/images/404.png")no-repeat center center'
+//      }
+    }
   }
 </script>
 
@@ -22,24 +33,46 @@
     background: #ebfdff url('/images/404.png')no-repeat center center;
     height:900px;
     position:relative;
-  }
-  .section .btn-click{
-    position:absolute;
-    top:54%;
-    left:50%;
-    margin-left:-150px;
-  }
-  .section .btn-click a{
-    display:inline-block;
-    width:130px;
-    height:33px;
-    font-size: 16px;
-    line-height: 33px;
-    color:#fff;
-    background: #f87c29;
-    text-align: center;
-    margin:0 10px;
-    border-radius: 2px;
-    text-decoration: none;
+    .btn-click{
+      position:absolute;
+      top:54%;
+      left:50%;
+      margin-left:-150px;
+      a{
+        display:inline-block;
+        width:130px;
+        height:33px;
+        font-size: 16px;
+        line-height: 33px;
+        color:#fff;
+        background: #f87c29;
+        text-align: center;
+        margin:0 10px;
+        border-radius: 2px;
+        text-decoration: none;
+      }
+    }
+    &.mobile-page {
+      background: #ebfdff url("/images/404-mobile.png")no-repeat center center;
+      position: fixed;
+      top: 0;
+      bottom: 0;
+      left: 0;
+      right: 0;
+      height: auto;
+      .btn-click{
+        top: 66%;
+        left: 1.2rem;
+        margin-left: 0;
+        a{
+          width: 2.3rem;
+          height: .63rem;
+          font-size: .32rem;
+          line-height: .63rem;
+          margin: 0 .1rem;
+          border-radius: .04rem;
+        }
+      }
+    }
   }
 </style>

+ 34 - 0
layouts/help.vue

@@ -0,0 +1,34 @@
+<template>
+  <div id="main">
+    <header-view v-if="!isMobile"></header-view>
+    <main-header v-if="!isMobile"></main-header>
+    <main-nav v-if="!isMobile"></main-nav>
+    <help-header v-if="isMobile"></help-header>
+    <nuxt/>
+    <footer-view v-if="!isMobile"></footer-view>
+    <right-bar v-if="!isMobile"></right-bar>
+    <help-footer v-else></help-footer>
+  </div>
+</template>
+<script>
+  import { Header, Footer, RightBar } from '~components/default'
+  import { MainHeader, MainNav } from '~components/main'
+  import { HelpHeader, HelpFooter } from '~components/mobile/help'
+  export default {
+    name: 'help',
+    components: {
+      HeaderView: Header,
+      FooterView: Footer,
+      RightBar,
+      MainHeader,
+      MainNav,
+      HelpHeader,
+      HelpFooter
+    },
+    computed: {
+      isMobile: function () {
+        return this.$store.state.option.isMobile
+      }
+    }
+  }
+</script>

+ 16 - 13
layouts/main.vue

@@ -20,11 +20,6 @@
       MainHeader,
       MainNav
     },
-//    data () {
-//      return {
-//        isInFrame: false
-//      }
-//    },
     head () {
       return {
         title: this.title,
@@ -35,17 +30,25 @@
       }
     },
     computed: {
+      isMobile: function () {
+        return this.$store.state.option.isMobile
+      },
       isInFrame () {
-        let cookies = this.$store.state.option.cookies
-        let cookieArr = cookies.split(';')
-        let cookieObj = {}
-        for (let i = 0; i < cookieArr.length; i++) {
-          let tmpArr = cookieArr[i].split('=') || []
-          if (tmpArr.length === 2) {
-            cookieObj[tmpArr[0].trim()] = tmpArr[1].trim()
+        if (this.$route.query.type === 'erp') {
+          this.$store.commit('option/ADD_COOKIES', 'type=erp;')
+          return true
+        } else {
+          let cookies = this.$store.state.option.cookies
+          let cookieArr = cookies.split(';')
+          let cookieObj = {}
+          for (let i = 0; i < cookieArr.length; i++) {
+            let tmpArr = cookieArr[i].split('=') || []
+            if (tmpArr.length === 2) {
+              cookieObj[tmpArr[0].trim()] = tmpArr[1].trim()
+            }
           }
+          return cookieObj.type === 'erp'
         }
-        return cookieObj.type === 'erp' || this.$route.query.type === 'erp'
       },
       title () {
         let path = this.$route.path

+ 33 - 0
layouts/mobile.vue

@@ -0,0 +1,33 @@
+<template>
+  <div id="mobile">
+    <mobile-header></mobile-header>
+    <nuxt/>
+    <mobile-footer></mobile-footer>
+  </div>
+</template>
+<script>
+  import { MobileHeader, MobileFooter } from '~components/mobile'
+  export default {
+    name: 'mobile',
+    components: {
+      MobileHeader,
+      MobileFooter
+    },
+//    middleware: 'authenticated',
+    head () {
+      return {
+        meta: [
+          { name: 'apple-mobile-web-app-capable', content: 'yes' },
+          { name: 'MobileOptimized', content: '320' },
+          { name: 'HandheldFriendly', content: 'true' },
+          { name: 'viewport', content: 'width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no' },
+          { 'http-equiv': 'Cache-Control', content: 'no-siteapp' },
+          { name: 'format-detection', content: 'telephone=no, email=no' }
+        ]
+      }
+    }
+  }
+</script>
+<style lang="scss">
+  @import '~assets/scss/mobileCommon';
+</style>

+ 3 - 3
layouts/shop.vue

@@ -46,7 +46,7 @@
       },
       title () {
         let path = this.$route.path
-        if (path.startsWith('/store/') && getCount(path, '/') === 2) {
+        if ((path.startsWith('/store/') && getCount(path, '/') === 2) || path.endsWith('/description')) {
           if (path.indexOf('33069557578d44e69bd91ad12d28a8d4') === -1) {
             return this.storeInfo.storeName + this.getStoreType(this.storeInfo.type) + '专卖店-优软商城'
           } else {
@@ -60,7 +60,7 @@
       },
       description () {
         let path = this.$route.path
-        if (path.startsWith('/store/') && getCount(path, '/') === 2) {
+        if ((path.startsWith('/store/') && getCount(path, '/') === 2) || path.endsWith('/description')) {
           if (path.indexOf('33069557578d44e69bd91ad12d28a8d4') === -1) {
             return this.storeInfo.storeName + '官方' + this.getStoreType(this.storeInfo.type) + '专卖店,提供最新IC电子元器件现货在线销售。'
           } else {
@@ -74,7 +74,7 @@
       },
       keywords () {
         let path = this.$route.path
-        if (path.startsWith('/store/') && getCount(path, '/') === 2) {
+        if ((path.startsWith('/store/') && getCount(path, '/') === 2) || path.endsWith('/description')) {
           if (path.indexOf('33069557578d44e69bd91ad12d28a8d4') === -1) {
             return '电子元器件' + this.getStoreType(this.storeInfo.type) + '专卖店'
           } else {

+ 5 - 7
nuxt.config.js

@@ -23,9 +23,9 @@ module.exports = {
     ]
   },
   /*
-  ** Customize the progress-bar color
+  ** loading Style
   */
-  loading: { color: '#3B8070' },
+  loading: '~components/common/loading/Loading.vue',
   /*
   ** Build configuration
   */
@@ -36,7 +36,7 @@ module.exports = {
     extend (config, { dev, isClient, isServer }) {
       config.resolve.alias['~utils'] = path.join(__dirname, 'utils')
       config.module.rules.push({
-        test: /\.scss$/,
+        test: /\.(scss|css)$/,
         loader: 'vue-style-loader!css-loader!sass-loader'
       })
       config.module.rules.push({
@@ -72,9 +72,7 @@ module.exports = {
     ]
   },
   css: [
-    /* {
-    src: 'font-awesome/css/font-awesome.css'
-  }, */{src: '~assets/scss/app.scss', lang: 'scss'}
+     { src: '~assets/scss/app.scss', lang: 'scss' }
     /* {
       src: 'swiper/dist/css/swiper.css'
     } */ /* , {
@@ -107,5 +105,5 @@ module.exports = {
     ssr: false
   }],
   /* TODO 暂时代理到商城测试版,之后再做出调整 */
-  proxyTable: ['/api/**', '/search/**', '/user/**', '/login/**', '/register/**', '/logout/**', '/static/**', '/vendor**', '/user**', '/trade/**', '/recommendation/**', '/store-service/**', '/basic/**', '/logout**', '/operation/**', '/help**', '/product**', '/store**', '/order/proxy**', '/report/**', '/store/**#/**', '/kdn/**', '/product/**Submit', '/admin**', '/product/**Submit/**', '/release/**', '/auth/store/**', '/produce/**', '/file**', '/rate/**', '/log/**', '/help-service/**', '/seek/**']
+  proxyTable: ['/api/**', '/search/**', '/user/**', '/login/**', '/register/**', '/logout/**', '/static/**', '/vendor**', '/user**', '/trade/**', '/recommendation/**', '/store-service/**', '/basic/**', '/logout**', '/operation/**', '/help**', '/product**', '/store**', '/order/proxy**', '/report/**', '/store/**#/**', '/kdn/**', '/product/**Submit', '/admin**', '/product/**Submit/**', '/release/**', '/auth/store/**', '/produce/**', '/file**', '/rate/**', '/log/**', '/help-service/**', '/keyword/**', '/tip/**', '/seek/**']
 }

+ 4 - 1
package.json

@@ -8,6 +8,7 @@
     "axios": "^0.15.3",
     "bezier-easing": "^2.0.3",
     "bootstrap": "^3.3.7",
+    "clipboard": "^1.7.1",
     "cookiejar": "^2.1.1",
     "cross-env": "^3.1.4",
     "element-ui": "^1.3.7",
@@ -39,6 +40,7 @@
     "babel-plugin-transform-runtime": "^6.23.0",
     "babel-preset-es2015": "^6.24.1",
     "babel-preset-stage-2": "^6.24.1",
+    "css-loader": "^0.28.7",
     "eslint": "^3.15.0",
     "eslint-config-standard": "^6.2.1",
     "eslint-loader": "^1.6.1",
@@ -46,6 +48,7 @@
     "eslint-plugin-promise": "^3.4.1",
     "eslint-plugin-standard": "^2.0.1",
     "node-sass": "^4.5.3",
-    "sass-loader": "^6.0.6"
+    "sass-loader": "^6.0.6",
+    "vue-loader": "^13.3.0"
   }
 }

+ 0 - 7
pages/README.md

@@ -1,7 +0,0 @@
-# PAGES
-
-This directory contains your Application Views and Routes.
-The framework reads all the .vue files inside this directory and create the router of your application.
-
-More information about the usage of this directory in the documentation:
-https://nuxtjs.org/guide/routing

+ 11 - 5
pages/activity/business.vue

@@ -1,7 +1,9 @@
 <template>
   <div class="business">
     <!--banner-->
-    <div class="banner"></div>
+    <a href="https://account.ubtob.com/sso/register_mall?appId=mall&returnURL=https%3A%2F%2Fwww.usoftmall.com%2F%3FreturnURL%3Dhttps%253A%252F%252Fwww.usoftmall.com%252F" target="_blank">
+      <div class="banner"></div>
+    </a>
     <!--介绍-->
     <div class="session introduction">
       <div class="content">
@@ -13,7 +15,8 @@
           我们严格把关供应商资质,从源头上杜绝虚假信息,做到付款交期如实,借助物流仓储的一站式服务帮您实现交易高效、库存无忧。<br/>
         </div>
         <div class="join">
-          <a href="http://account.ubtob.com/sso/register?returnURL=http%253A%252F%252Fwww.usoftmall.com%252Flogin%252Fproxy&appId=mall" target="_blank">立即入驻</a>
+          <a href="https://account.ubtob.com/sso/register_mall?appId=mall&returnURL=https%3A%2F%2Fwww.usoftmall.com%2F%3FreturnURL%3Dhttps%253A%252F%252Fwww.usoftmall.com%252F
+" target="_blank">立即入驻</a>
         </div>
       </div>
     </div>
@@ -49,7 +52,8 @@
           </ul>
         </div>
         <div class="join">
-          <a href="http://account.ubtob.com/sso/register?returnURL=http%253A%252F%252Fwww.usoftmall.com%252Flogin%252Fproxy&appId=mall" target="_blank">立即入驻</a>
+          <a href="https://account.ubtob.com/sso/register_mall?appId=mall&returnURL=https%3A%2F%2Fwww.usoftmall.com%2F%3FreturnURL%3Dhttps%253A%252F%252Fwww.usoftmall.com%252F
+" target="_blank">立即入驻</a>
         </div>
       </div>
     </div>
@@ -93,7 +97,8 @@
           </ul>
         </div>
         <div class="join">
-          <a href="http://account.ubtob.com/sso/register?returnURL=http%253A%252F%252Fwww.usoftmall.com%252Flogin%252Fproxy&appId=mall" target="_blank">立即入驻</a>
+          <a href="https://account.ubtob.com/sso/register_mall?appId=mall&returnURL=https%3A%2F%2Fwww.usoftmall.com%2F%3FreturnURL%3Dhttps%253A%252F%252Fwww.usoftmall.com%252F
+" target="_blank">立即入驻</a>
         </div>
       </div>
     </div>
@@ -115,7 +120,8 @@
           </div>
         </div>
         <div class="join">
-          <a href="http://account.ubtob.com/sso/register?returnURL=http%253A%252F%252Fwww.usoftmall.com%252Flogin%252Fproxy&appId=mall" target="_blank">立即入驻</a>
+          <a href="https://account.ubtob.com/sso/register_mall?appId=mall&returnURL=https%3A%2F%2Fwww.usoftmall.com%2F%3FreturnURL%3Dhttps%253A%252F%252Fwww.usoftmall.com%252F
+" target="_blank">立即入驻</a>
         </div>
       </div>
     </div>

+ 6 - 2
pages/auth/login.vue

@@ -1,11 +1,15 @@
 <template>
-
+  <div>
+    <!--登录代理页面-->
+  </div>
 </template>
 <script>
   export default {
+    name: 'login',
     layout: 'login',
     mounted () {
-      this.$http.get('/login/page', {params: {returnUrl: window.location.protocol + '//' + window.location.host}}).then(response => {
+      let uri = this.$route.query.returnUrl ? this.$route.query.returnUrl : window.location.protocol + '//' + window.location.host + '/'
+      this.$http.get('/login/page', {params: {returnUrl: uri}}).then(response => {
         if (response.data) {
           window.location.href = response.data.content + '&baseUrl=' + encodeURIComponent(window.location.protocol + '//' + window.location.host + response.data.baseUrl)
         }

+ 80 - 16
pages/index.vue

@@ -1,27 +1,35 @@
 <template>
   <div class="index">
-    <carousel>
-      <kind-category @loadchild="loadProductKinds"></kind-category>
-    </carousel>
-    <advert></advert>
-    <floor-list></floor-list>
-    <news></news>
-    <partner></partner>
+    <div v-if="isMobile">
+      <Home></Home>
+    </div>
+    <div v-if="!isMobile">
+      <christmas v-if="isOpen" @listenopen="listenOpen" :hasNewYear="hasNewYear"></christmas>
+      <carousel>
+        <kind-category @loadchild="loadProductKinds"></kind-category>
+      </carousel>
+      <advert></advert>
+      <floor-list></floor-list>
+      <news></news>
+      <partner></partner>
+    </div>
   </div>
 </template>
 <script>
   import { KindCategory, Carousel, Advert, FloorList, Partner, News } from '~components/home'
+  import { Christmas } from '~components/default'
+  import { Home } from '~components/mobile'
 
   export default {
     name: 'index',
-    layout: 'main',
-    fetch ({ store }) {
-      return Promise.all([
-        store.dispatch('loadFloors'),
-        store.dispatch('loadBanners', {type: 'home'}),
-        store.dispatch('loadProductKinds', { id: 0 }),
-        store.dispatch('loadNewsSnapshot', { page: 1, pageSize: 10 })
-      ])
+    layout (context) {
+      return context.store.state.option.isMobile ? 'mobile' : 'main'
+    },
+    data () {
+      return {
+        isOpen: false,
+        hasNewYear: false
+      }
     },
     components: {
       KindCategory,
@@ -29,9 +37,65 @@
       Advert,
       FloorList,
       Partner,
-      News
+      News,
+      Christmas,
+      Home
+    },
+    fetch ({store}) {
+      return !store.state.option.isMobile ? Promise.all([
+        store.dispatch('loadFloors'),
+        store.dispatch('loadBanners', {type: 'home'}),
+        store.dispatch('loadProductKinds', { id: 0 }),
+        store.dispatch('loadNewsSnapshot', { page: 1, pageSize: 10 })
+      ]) : []
+    },
+    mounted () {
+      let user = this.user.logged
+      let count = 1
+      let self = this
+      const nowDate = new Date()
+      const activeStartDate = new Date('2017/12/20 00:00:00')
+      const activeEndDate = new Date('2018/1/2 00:00:00')
+      const EndDate = new Date('2017/12/26 00:00:00')
+      this.hasNewYear = nowDate > EndDate
+      if (nowDate > activeStartDate && nowDate < activeEndDate) {
+        const endTime = window.localStorage.getItem('endTime')
+        if (!user) {
+          setInterval(function () {
+            count++
+            if (count >= 60 * 60 * 2) {
+              count = 1
+              self.isOpen = true
+            }
+          }, 1000)
+        }
+        if (endTime) {
+          if (nowDate.getTime() - endTime >= 1000 * 60 * 60 * 2) {
+            user ? this.isOpen = false : this.isOpen = true
+            window.localStorage.setItem('endTime', nowDate.getTime())
+          } else {
+            this.isOpen = false
+          }
+        } else {
+          user ? this.isOpen = false : this.isOpen = true
+          window.localStorage.setItem('endTime', nowDate.getTime())
+        }
+      } else {
+        this.isOpen = false
+      }
+    },
+    computed: {
+      user () {
+        return this.$store.state.option.user
+      },
+      isMobile: function () {
+        return this.$store.state.option.isMobile
+      }
     },
     methods: {
+      listenOpen () {
+        this.isOpen = false
+      },
       loadProductKinds (id) {
         this.$store.dispatch('loadAllProductKinds', {id})
       }

+ 17 - 0
pages/mobile/brand/_code.vue

@@ -0,0 +1,17 @@
+<template>
+  <brand-detail></brand-detail>
+</template>
+<script>
+  import BrandDetail from '~components/mobile/brand/BrandDetail.vue'
+  export default {
+    layout: 'mobile',
+    components: {
+      BrandDetail
+    },
+    fetch ({ store, params }) {
+      return Promise.all([
+        store.dispatch('loadBrandDetail', { id: params.code })
+      ])
+    }
+  }
+</script>

+ 20 - 0
pages/mobile/brand/brandCenter/_initial.vue

@@ -0,0 +1,20 @@
+<template>
+  <brand-center></brand-center>
+</template>
+<script>
+  import BrandCenter from '~components/mobile/brand/BrandCenter.vue'
+  export default {
+    layout: 'mobile',
+    components: {
+      BrandCenter
+    },
+    fetch ({store, route}) {
+      return Promise.all([
+        store.dispatch('product/loadBrands', {'keyword': route.params.initial})
+      ])
+    }
+  }
+</script>
+<style>
+
+</style>

+ 30 - 0
pages/mobile/brand/componentDetail/_uuid.vue

@@ -0,0 +1,30 @@
+<template>
+  <component-detail></component-detail>
+</template>
+<script>
+  import ComponentDetail from '~components/mobile/brand/ComponentDetail.vue'
+  export default {
+    layout: 'mobile',
+    components: {
+      ComponentDetail
+    },
+    fetch ({ store, params }) {
+      return Promise.all([
+        store.dispatch('loadComponentDetail', {id: params.uuid}),
+//        store.dispatch('loadComponentStore', {uuid: params.uuid}),
+        store.dispatch('loadComponentInformation',
+          {
+            count: 10,
+            page: 1,
+            sorting: {'minPriceRMB': 'ASC'},
+            filter: {
+              uuid: params.uuid,
+              ignoreUMall: false,
+              ignoreStore: false,
+              storeIds: ''
+            }}),
+        store.dispatch('product/saveStores')
+      ])
+    }
+  }
+</script>

+ 57 - 0
pages/mobile/help/_id.vue

@@ -0,0 +1,57 @@
+<template>
+  <!--文章详情-->
+  <div class="helper-center-details" style="color: #000">
+    <div class="ql-container ql-snow" v-html="helpDetail.article"></div>
+    <div v-if="helpDetail.length == 0" style="color: #999;">暂无数据!</div>
+  </div>
+</template>
+<script>
+  export default {
+    layout: 'help',
+    fetch ({ store, route }) {
+      return Promise.all([
+        store.dispatch('loadHelpDetail', route.params)
+      ])
+    },
+    computed: {
+      helpDetail () {
+        return this.$store.state.help.detail.data
+      }
+    }
+  }
+</script>
+<style>
+ .helper-center-details{
+   width: 100%;
+   margin-bottom: 50px;
+}
+ .helper-center-details .ql-container{
+   margin: 0 auto;
+   width: 95%;
+ }
+ .helper-center-details .ql-container .ql-size-20{
+   display: block;
+   margin-top: 15px;
+   font-weight: bold;
+ }
+ .helper-center-details .ql-container strong{
+   display: block;
+   margin-top: 15px;
+   font-size: 16px;
+ }
+ .helper-center-details p, .helper-center-details h3{
+   margin: 0 auto;
+   width: 100%;
+ }
+ .helper-center-details span{
+   font-size: 16px;
+ }
+ .helper-center-details span.ql-size-16 img{
+   width: 5%;
+ }
+ .helper-center-details img{
+   margin: 0 auto;
+   width: 100%;
+   text-align: center;
+ }
+</style>

+ 409 - 0
pages/mobile/search/_keycode.vue

@@ -0,0 +1,409 @@
+<template>
+  <div class="search-list mobile-content">
+  <div class="search-item">
+      <span :class="activeType=='store'?'active':''" @click="clickType('store')">所有器件</span>
+      <span :class="activeType=='support'?'active':''" @click="clickType('support')">仅看有货</span>
+    </div>
+
+    <div class="brand-list-content" v-if="(!productList.brands && brandList && brandList.length > 0) && productList.expose > 0">
+      <div class="brand-list-top">
+        <span>品牌墙</span>
+        <span class="row-switch" @click="onclick()" v-if="brandList.length > 8">{{!isShow?'收起':'展开'}}<i :class="{'iconfont icon-arrow-down':isShow,'icon-icon-shang iconfont':!isShow}"></i></span>
+      </div>
+      <div class="brand-list-item" >
+        <div v-for="item in isShow?brandList.slice(0, 8):brandList">
+          <nuxt-link :to="'/mobile/brand/'+item.br_uuid">
+            <img :src="item.logoUrl ||'/images/component/default.png'"/>
+          </nuxt-link>
+        </div>
+      </div>
+    </div>
+
+    <div class="detail-brand-content" v-if="productList.brands" @click="goBrand(list.uuid)">
+      <h4>主营产品 <img src="/images/mobile/@2x/search/search-brand.png" alt=""></h4>
+      <div class="brand-list">
+        <div class="list-left">
+          <img :src="list.logoUrl || '/images/component/default.png'" :alt="list.nameEn"/>
+          <span>{{list.nameCn}}</span>
+        </div>
+        <p>{{list.series | productDescFilter}}</p>
+      </div>
+    </div>
+
+    <div class="detail-brand" v-for="(item, index) in searchLists" :style="index == 0 ? 'padding-top: .2rem;' : ''" v-if="searchLists.length > 0">
+      <div class="brand-item" @click="goComponent(item.uuid)">
+        <p>型号:<span>{{item.code}}</span></p>
+        <p>品牌:<span>{{item.brandEn || item.brand.nameCn}}</span></p>
+        <p>产品描述:<span>{{item.description || '-'}}</span></p>
+        <i class="iconfont icon-shoucang" :style="(item.isFocus)?'color:#ff7800':'color:#bbb'" @click="collect(item, $event)"></i>
+      </div>
+    </div>
+
+    <div class="none-state" v-if="!productList.components || productList.components.length === 0">
+      <img :src="brandList && brandList.length > 0 ? '/images/mobile/@2x/car@2x.png':'/images/mobile/@2x/search-empty.png'">
+      <p v-text="brandList && brandList.length > 0 ? '抱歉,暂无器件信息' : '抱歉,暂无搜索结果'"></p>
+      <a @click="goLastPage">返回上一页</a>
+    </div>
+    <remind-box :title="collectResult" :timeoutCount="timeoutCount"></remind-box>
+    <loading v-show="isSearchSearchingMore"></loading>
+    <login-box @onLoginBoxClose="showLoginBox = false" v-if="showLoginBox"></login-box>
+  </div>
+</template>
+
+<script>
+  import {RemindBox, Loading, LoginBox} from '~components/mobile/common'
+  export default {
+    layout: 'mobile',
+    data () {
+      return {
+        activeType: 'store',
+        count: '',
+        filter: {},
+        page: 1,
+        sorting: {'RESERVE': 'DESC'},
+        paramJSON: {},
+        isShow: true,
+        isMove: '',
+        isFocus: false,
+        isClickCollect: false,
+        collectResult: '收藏成功',
+        timeoutCount: 0,
+        searchLists: [],
+        isSearchSearchingMore: false,
+        showLoginBox: false,
+        isChange: false
+      }
+    },
+    components: {
+      RemindBox,
+      Loading,
+      LoginBox
+    },
+    mounted: function () {
+      let _this = this
+      _this.$nextTick(function () {
+        window.addEventListener('scroll', function () {
+          _this.scroll()
+        }, false)
+      })
+    },
+    fetch ({store, route}) {
+      return Promise.all([
+        store.dispatch('searchData/searchForListInMobile', {count: 15, filter: {}, keyword: route.query.w, page: 1, sorting: {'RESERVE': 'DESC'}}),
+        store.dispatch('searchData/searchForBrands', {collectList: 'goods_brand', keyword: route.query.w, paramJSON: {}})
+      ])
+    },
+    filters: {
+      productDescFilter: function (str) {
+        return str.length > 50 ? str.substring(0, 50) + '...' : str
+      }
+    },
+    computed: {
+      productList () {
+        let list = this.$store.state.searchData.searchList.lists.data
+        if (this.isChange) {
+          this.searchLists = []
+          this.page = 1
+          this.isChange = false
+        } else {
+          this.searchLists = this.searchLists.concat(list.components)
+          this.isSearchSearchingMore = false
+        }
+        return list
+      },
+      allPage () {
+        return Math.floor(this.productList.total / this.productList.size) + Math.floor(this.productList.total % this.productList.size > 0 ? 1 : 0)
+      },
+      brandList () {
+        return this.$store.state.searchData.searchBrands.brands.data
+      },
+      brandDetail () {
+        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
+      },
+      user () {
+        return this.$store.state.option.user
+      }
+    },
+    methods: {
+      onclick () {
+        this.isShow = !this.isShow
+      },
+      clickType (type) {
+//        this.searchLists = []
+        this.isChange = true
+        if (type === 'store') {
+          this.activeType = 'store'
+          delete this.filter.goods_status
+          delete this.paramJSON.goods_status
+          this.reloadData()
+        } else if (type === 'support') {
+          this.activeType = 'support'
+          this.filter.goods_status = 601
+          this.paramJSON.goods_status = 601
+          this.reloadData()
+        }
+      },
+      goBrand: function (uuid) {
+        this.$router.push('/mobile/brand/' + uuid)
+      },
+      collect: function (item, $event) {
+        this.isClickCollect = true
+        if (this.user.logged) {
+          if (!item.isFocus) {
+            this.$http.post('/trade/collection/save', {componentid: item.cmpId, kind: 2})
+              .then(response => {
+                item.isFocus = true
+                this.collectResult = '收藏成功'
+                this.timeoutCount++
+              })
+          } else {
+            this.$http.post('/trade/collection/delete/cmpId', [item.cmpId]).then(response => {
+              item.isFocus = false
+              this.collectResult = '取消成功'
+              this.timeoutCount++
+            })
+          }
+        } else {
+          this.showLoginBox = true
+        }
+      },
+      goComponent: function (uuid) {
+        if (!this.isClickCollect) {
+          this.$router.push('/mobile/brand/componentDetail/' + uuid)
+        } else {
+          this.isClickCollect = false
+        }
+      },
+      goLastPage: function () {
+        window.history.back(-1)
+      },
+      getMoreSearch: function () {
+        this.page++
+        this.isSearchSearchingMore = true
+        this.$store.dispatch('searchData/searchForListInMobile', {count: 15, filter: this.filter, keyword: this.$route.query.w, page: this.page, sorting: this.sorting})
+      },
+      reloadData: function () {
+        this.$store.dispatch('searchData/searchForListInMobile', {count: 15, filter: this.filter, keyword: this.$route.query.w, page: 1, sorting: this.sorting})
+        this.$store.dispatch('searchData/searchForBrands', {collectList: 'goods_brand', keyword: this.$route.query.w, paramJSON: this.paramJSON})
+      },
+      scroll: function () {
+        let scrolled = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop
+        if (Math.ceil(scrolled + window.screen.availHeight) >= document.body.scrollHeight && !this.isSearchSearchingMore && this.page < this.allPage) {
+          this.getMoreSearch()
+        }
+      }
+    }
+  }
+</script>
+
+<style scoped lang="scss">
+  .search-list{
+    width:100%;
+    padding-bottom: 1rem;
+    .none-state{
+      text-align: center;
+      margin-top:2rem;
+      width:100%;
+      img{
+        margin:0 auto;
+        width: 3.31rem;
+        height: 2.13rem;
+      }
+      p {
+        font-size: .32rem;
+        color: #999;
+        margin: 1.19rem 0 0 0;
+      }
+      a {
+        display: block;
+        font-size: .28rem;
+        color: #fff;
+        width: 1.88rem;
+        height: .54rem;
+        line-height: .54rem;
+        background: #418bf6;
+        margin: .7rem auto 0;
+        border-radius: .05rem;
+      }
+    }
+    .search-item{
+      text-align: center;
+      span{
+        display:inline-block;
+        width:1.41rem;
+        line-height: .76rem;
+        font-size:.32rem;
+        color:#666;
+        &:first-child {
+          margin-right: 2rem;
+        }
+      }
+      span.active{
+        color:#3976f4;
+        border-bottom:.04rem solid #3976f4;
+      }
+    }
+
+    .brand-list-content{
+      margin:0 auto;
+      border-top:.04rem solid #dedfdf;
+      border-bottom:.04rem solid #dedfdf;
+      width:7.1rem;
+      min-height:1.51rem;
+      overflow: hidden;
+      text-align: left;
+      padding-top:.33rem;
+      padding-bottom:.33rem;
+      .brand-list-top{
+        span:first-child{
+          font-size:.32rem;
+          float: left;
+          margin: 0 0 .1rem .2rem;
+        }
+        span.row-switch{
+          font-size:.28rem;
+          color:#53a0f7;
+          float: right;
+          margin: 0 .2rem 0 0;
+          i {
+            font-size: .16rem;
+          }
+        }
+      }
+      .brand-list-item{
+        overflow: hidden;
+        margin: .1rem .2rem 0;
+        text-align: center;
+        clear: both;
+        >div {
+          display: inline-block;
+          margin-right: .14rem;
+          float: left;
+          &:nth-child(4n) {
+            margin-right: 0;
+          }
+          a {
+            width: 1.57rem;
+            height: .77rem;
+            display: inline-block;
+            margin: .1rem 0;
+            border: .04rem solid #53a0f7;
+            border-radius: .1rem;
+            line-height: .77rem;
+            img{
+              max-width:1.07rem;
+              max-height:.57rem;
+            }
+          }
+        }
+      }
+    }
+
+    .detail-brand-content{
+      margin:0 auto;
+      border-top:.04rem solid #dedfdf;
+      border-bottom:.04rem solid #dedfdf;
+      width:7.1rem;
+      height:3.02rem;
+      padding-top:.18rem;
+      h4{
+        font-size:.32rem;
+        line-height: .6rem;
+        margin:0 0 0 3.97rem;
+        position: relative;
+        img {
+          position: absolute;
+          left: -1.28rem;
+          top: .24rem;
+          width: 3.8rem;
+          height: .11rem;
+        }
+      }
+      .brand-list{
+        margin:0 .15rem;
+        .list-left{
+          border:.02rem solid #418ef7;
+          border-radius: .05rem;
+          width:2.03rem;
+          height:1.73rem;
+          display: inline-block;
+          img{
+            display:block;
+            width:100%;
+            height:1.25rem;
+          }
+          span{
+            display: block;
+            font-size: .24rem;
+            color:#fff;
+            text-align: center;
+            width:100%;
+            background: #418ef7;
+            line-height: .45rem;
+            overflow: hidden;
+            text-overflow: ellipsis;
+            white-space: nowrap;
+          }
+        }
+        p{
+          width:4.3rem;
+          font-size:.28rem;
+          line-height: .4rem;
+          padding:.12rem .46rem 0 .05rem;
+          float: right;
+        }
+      }
+    }
+
+    .detail-brand{
+      background: #f8fcff;
+      width:100%;
+      min-height:1.5rem;
+      padding-bottom: .2rem;
+      .brand-item{
+        width:7rem;
+        margin:0 auto;
+        border-radius:.1rem;
+        background: #fff;
+        padding:.2rem;
+        position:relative;
+        -webkit-box-shadow: 0 .03rem .01rem 0 #cdcbcb96;
+        -moz-box-shadow: 0 .03rem .01rem 0 #cdcbcb96;
+        box-shadow: 0 .03rem .01rem 0 #cdcbcb96;
+        &:active{
+          background: #e1e1e1;
+        }
+        p{
+          font-size:.28rem;
+          line-height:.4rem;
+          color:#333;
+          margin:0;
+          span{}
+        }
+        i{
+          display:block;
+          position:absolute;
+          top:.1rem;
+          right:.22rem;
+          font-size:.5rem;
+          color:#ff7800;
+          width: .6rem;
+          height: .6rem;
+          line-height: .6rem;
+          text-align: center;
+        }
+      }
+      div.active{
+        background: #d4d;
+      }
+    }
+  }
+
+</style>

+ 27 - 0
pages/mobile/shop/_uuid.vue

@@ -0,0 +1,27 @@
+<template>
+  <div>
+    <store-detail></store-detail>
+  </div>
+</template>
+<script>
+  import StoreDetail from '~components/mobile/store/StoreDetail.vue'
+  export default {
+    layout: 'mobile',
+    fetch ({ store, params }) {
+      return Promise.all([
+        store.dispatch('shop/findStoreInfoFromUuid', params),
+        store.dispatch('shop/pageCommoditiesOfStore', params.uuid, { page: 1, count: 10 })
+      ])
+    },
+    computed: {
+      description () {
+        return this.$store.state.shop.storeInfo.store.data
+      }
+    },
+    components: {
+      StoreDetail
+    }
+  }
+</script>
+<style scoped>
+</style>

+ 317 - 0
pages/mobile/shop/index.vue

@@ -0,0 +1,317 @@
+<template>
+  <div class="shop mobile-content">
+    <div class="shop-top">
+      <p><i class="iconfont icon-dianpu1"></i><span>{{list.totalElements || 0}}</span>家店铺</p>
+      <span @click="onClick()">{{downName}} <i class="iconfont icon-arrow-down"></i></span>
+      <ul class="supdown" v-if="down">
+        <li @click="onDown('ORIGINAL_FACTORY-DISTRIBUTION-AGENCY-CONSIGNMENT')" v-show="downName !== '全部'">全部</li>
+        <li @click="onDown('ORIGINAL_FACTORY')" v-show="downName !== '原厂'">原厂</li>
+        <li @click="onDown('AGENCY')" v-show="downName !== '代理'">代理</li>
+        <li @click="onDown('DISTRIBUTION')" v-show="downName !== '经销'">经销</li>
+        <li @click="onDown('CONSIGNMENT')" v-show="downName !== '寄售'">寄售</li>
+      </ul>
+    </div>
+    <div class="shop-list" v-for="item in searchLists" @click="goStoreDetail(item.uuid)" v-if="item">
+      <h3>{{item.storeName}}</h3>
+      <div class="list-item">
+        <div class="item-img">
+          <i :style="'background:url(' + isType(item.type) + ')no-repeat 0 0/.65rem .33rem;'"></i>
+          <img :src="item.logoUrl || '/images/component/default.png'">
+        </div>
+        <div class="list-item-phone">
+          <p>电话:<span>{{item.enterprise.enTel}}</span></p>
+          <p>传真:<span>{{item.enterprise.enFax}}</span></p>
+          <!--<p>商家介绍: <nuxt-link :to="'/mobile/merchantDescription/'+item.uuid">点击查看</nuxt-link></p>-->
+          <p>联系商家:<a @click="selectStoreInfo(item, $event)">点击查看</a></p>
+          <i class="iconfont icon-shoucang" :style="item.isFocus=='true'?'color:#ff7800':'color:#bbb'" @click="focusStore(item, $event)"></i>
+        </div>
+      </div>
+    </div>
+    <remind-box :title="collectResult" :timeoutCount="timeoutCount"></remind-box>
+    <loading v-show="isSearchingMore"></loading>
+    <div class="mobile-modal" v-if="showStoreInfo">
+      <div class="mobile-modal-box">
+        <div class="mobile-modal-header">联系方式<i @click="showStoreInfo = false" class="icon-guanbi iconfont"></i></div>
+        <div class="mobile-modal-content">
+          <div v-if="checkInfo(enterpriseInfo.enAddress || enterpriseInfo.address)">商家地址:{{enterpriseInfo.enAddress || enterpriseInfo.address}}</div>
+          <!--<div class="content-line link-url">在线咨询</div>-->
+          <div v-if="checkInfo(enterpriseInfo.enTel)">致电:<a :href="'tel:' + enterpriseInfo.enTel" target="_blank" class="content-line link-url">{{enterpriseInfo.enTel}}</a></div>
+          <div v-if="checkInfo(enterpriseInfo.enEmail)">邮件:<a :href="'mailto:' + enterpriseInfo.enEmail" target="_blank" class="content-line link-url">{{enterpriseInfo.enEmail}}</a></div>
+        </div>
+      </div>
+    </div>
+    <login-box @onLoginBoxClose="showLoginBox = false" v-if="showLoginBox"></login-box>
+  </div>
+</template>
+
+<script>
+  import {RemindBox, Loading, LoginBox} from '~components/mobile/common'
+  export default {
+    layout: 'mobile',
+    data () {
+      return {
+        page: 1,
+        count: 10,
+        types: 'ORIGINAL_FACTORY-DISTRIBUTION-AGENCY-CONSIGNMENT',
+        down: false,
+        downName: '全部',
+        isFocus: true,
+        collectResult: '收藏成功',
+        timeoutCount: 0,
+        isSearchingMore: false,
+        searchLists: [],
+        isChange: false,
+        showStoreInfo: false,
+        enterpriseInfo: {},
+        showLoginBox: false
+      }
+    },
+    components: {
+      RemindBox,
+      Loading,
+      LoginBox
+    },
+    fetch ({ store }) {
+      return Promise.all([
+        store.dispatch('provider/findStoreListInMobil', { page: 1, count: 10, types: 'ORIGINAL_FACTORY-DISTRIBUTION-AGENCY-CONSIGNMENT' })
+      ])
+    },
+    computed: {
+      list () {
+        let list = this.$store.state.provider.stores.storeList.data
+        if (this.isChange) {
+          this.searchLists = []
+          this.page = 1
+          this.isChange = false
+        } else {
+          this.searchLists = this.searchLists.concat(list.content)
+          this.isSearchingMore = false
+        }
+        return list
+      },
+      allPage () {
+        return this.list.totalPages
+      },
+      user () {
+        return this.$store.state.option.user
+      }
+    },
+    mounted: function () {
+      let _this = this
+      _this.$nextTick(function () {
+        window.addEventListener('scroll', function () {
+          _this.scroll()
+        }, false)
+      })
+    },
+    methods: {
+      scroll: function () {
+        let scrolled = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop
+        if (Math.ceil(scrolled + window.screen.availHeight) >= document.body.scrollHeight && !this.isSearchingMore && this.page < this.allPage) {
+          this.getMoreStore()
+        }
+      },
+      getMoreStore: function () {
+        if (!this.isSearchingMore) {
+          this.page++
+          this.isSearchingMore = true
+          this.$store.dispatch('provider/findStoreListInMobil', { page: this.page, count: this.count, types: this.types })
+        }
+      },
+      isType (type) {
+        let bgurl = ''
+        if (type === 'ORIGINAL_FACTORY') {
+          bgurl = '/images/mobile/@2x/shop/original_factory.png'
+        } else if (type === 'DISTRIBUTION') {
+          bgurl = '/images/mobile/@2x/shop/distribution.png'
+        } else if (type === 'AGENCY') {
+          bgurl = '/images/mobile/@2x/shop/agency.png'
+        } else if (type === 'CONSIGNMENT') {
+          bgurl = '/images/mobile/@2x/shop/consignment.png'
+        }
+        return bgurl
+      },
+      onClick () {
+        this.down = !this.down
+      },
+      onDown (type) {
+        this.isChange = true
+        this.down = !this.down
+        this.types = type
+        if (type === 'ORIGINAL_FACTORY') {
+          this.downName = '原厂'
+        } else if (type === 'DISTRIBUTION') {
+          this.downName = '经销'
+        } else if (type === 'AGENCY') {
+          this.downName = '代理'
+        } else if (type === 'CONSIGNMENT') {
+          this.downName = '寄售'
+        } else if (type === 'ORIGINAL_FACTORY-DISTRIBUTION-AGENCY-CONSIGNMENT') {
+          this.downName = '全部'
+        }
+        this.$store.dispatch('provider/findStoreListInMobil', { page: 1, count: 10, types: type })
+      },
+      focusStore: function (item, $event) {
+//        item.isFocus = item.isFocus === 'false' ? 'true' : 'false'
+        $event.stopPropagation()
+        if (this.user.logged) {
+          if (item.isFocus === 'false') {
+            this.$http.post('/trade/storeFocus/save', {storeName: item.storeName, storeid: item.id})
+              .then(response => {
+                item.isFocus = 'true'
+                this.collectResult = '收藏成功'
+                this.timeoutCount++
+              })
+          } else {
+            this.$http.post('/trade/storeFocus/delete/storeId', [item.id])
+              .then(response => {
+                item.isFocus = 'false'
+                this.collectResult = '取消成功'
+                this.timeoutCount++
+              })
+          }
+        } else {
+          this.showLoginBox = true
+        }
+      },
+      goStoreDetail: function (uuid) {
+        this.$router.push('/mobile/shop/' + uuid)
+      },
+      selectStoreInfo: function (store, $event) {
+        $event.stopPropagation()
+        this.enterpriseInfo = store.enterprise || {}
+        this.showStoreInfo = true
+      },
+      checkInfo: function (str) {
+        return str && str.trim() !== ''
+      }
+    }
+  }
+</script>
+
+<style scoped lang="scss">
+  .shop{
+    margin-bottom: .98rem;
+    background: #e2e4e6;
+    .shop-top{
+      width:100%;
+      height:1.14rem;
+      line-height: 1.14rem;
+      padding:0 .3rem;
+      position:relative;
+      background:#fff;
+      .supdown{
+        position: absolute;
+        top: .8rem;
+        right: .1rem;
+        z-index: 1;
+        background: #616264;
+        border-radius: .1rem;
+        li{
+          font-size: .28rem;
+          color: #ffffff;
+          line-height: .8rem;
+          padding: 0 .4rem;
+          height: .8rem;
+        }
+      }
+      p{
+        font-size:.24rem;
+        color:#000;
+        display: inline-block;
+        i{
+          font-size: .53rem;
+          color:#418ef7;
+        }
+        span{
+          font-size:.3rem;
+          color:#f94f28;
+          margin:0 .1rem;
+        }
+      }
+      >span{
+        font-size:.28rem;
+        color:#53a0f7;
+        float: right;
+      }
+    }
+    .shop-list {
+      background:#fff;
+      margin-top:.1rem;
+      border-bottom: .1rem solid #e2e4e6;
+     /* padding-bottom:.1rem;*/
+      box-shadow: 0 .03rem .01rem 0 #cdcbcb96;
+      h3{
+        font-size: .32rem;
+        line-height: .4rem;
+        margin: 0 0 0 .27rem;
+        overflow: hidden;
+        text-overflow: ellipsis;
+        white-space: nowrap;
+        padding-top: .1rem;
+        position: relative;
+        top: .1rem;
+      }
+      .list-item{
+        width:6.77rem;
+        margin-left:.39rem;
+        .item-img{
+          position:relative;
+          width:2.42rem;
+          height:1.69rem;
+          display: inline-block;
+          vertical-align: middle;
+          i{
+            display:block;
+            position:absolute;
+            width:.65rem;
+            height:.33rem;
+          }
+          img{
+            display:inline-block;
+            width:100%;
+            height:100%;
+            border:.04rem solid #eee;
+            background-color: #fff;
+          }
+        }
+        .list-item-phone{
+          width:3.95rem;
+          padding:.18rem 0;
+          position:relative;
+          display: inline-block;
+          vertical-align: middle;
+          margin-left: .2rem;
+          p{
+            font-size:.28rem;
+            line-height: .67rem;
+            margin:0;
+            overflow: hidden;
+            text-overflow: ellipsis;
+            white-space: nowrap;
+            width: 3.2rem;
+          }
+          i{
+            display:block;
+            position:absolute;
+            top: -.06rem;
+            right: -.06rem;
+            font-size:.5rem;
+            color:#ff7800;
+            width: .6rem;
+            height: .6rem;
+            text-align: center;
+            line-height: .6rem;
+          }
+          i.active{
+            color:#333;
+          }
+        }
+      }
+      &:active {
+        background: #e1e1e1;
+      }
+    }
+  }
+
+</style>

+ 418 - 0
pages/mobile/user/index.vue

@@ -0,0 +1,418 @@
+<template>
+  <div class="user-content mobile-content">
+    <div class="user-name">
+      <img src="/images/component/default.png"/>
+      <div class="user-info">
+        <p v-text="userInfo.data.userName"></p>
+        <p v-text="enterpriseInfo.enName"></p>
+      </div>
+      <span @click="onclick()">{{listName}}<i class="iconfont icon-arrow-down"></i></span>
+      <ul class="supdown" v-if="down">
+        <li @click="onDown('1')" v-show="!isDevice || !isShop">全部收藏</li>
+        <li @click="onDown('-1')" v-show="isDevice || !isShop">店铺关注</li>
+        <li @click="onDown('0')" v-show="!isDevice || isShop">器件收藏</li>
+      </ul>
+    </div>
+    <div class="collect-list-type" v-if="focusPage.totalElements > 0 && isShop">
+      <p>店铺</p>
+    </div>
+    <div class="shop-list" v-if="isShop" v-for="item in focusPage.content" @click="goStoreDetail(item.storeInfo.uuid)">
+      <h3>{{item.storeName}}</h3>
+      <div class="list-item">
+        <div class="item-img">
+          <img :src="getBackground(item.storeInfo.type)" />
+          <img :src="item.storeInfo.logoUrl || '/images/component/default.png'">
+        </div>
+        <div class="list-item-phone">
+          <p>电话:<span>{{item.storeInfo.enterprise.enTel}}</span></p>
+          <p>传真:<span>{{item.storeInfo.enterprise.enFax}}</span></p>
+          <p>联系商家:<a @click="selectStoreInfo(item, $event)">点击查看</a></p>
+          <i class="iconfont icon-shoucang" @click="cancelFocus('store', item, $event)"></i>
+        </div>
+      </div>
+    </div>
+    <div class="collect-list-type" v-if="collectSave.totalElements > 0 && isDevice">
+      <p>器件</p>
+    </div>
+    <div class="detail-brand" v-for="(item, index) in collectSave.content" v-if="isDevice" @click="goComponentDetail(item.componentinfo.uuid)">
+      <a>
+        <div class="brand-item">
+          <p>型号:<span>{{item.componentinfo.code}}</span></p>
+          <p>品牌:<span>{{item.componentinfo.brand.nameCn}}</span></p>
+          <p>产品描述:<span>{{item.componentinfo.kind.nameCn}}</span></p>
+          <i class="iconfont icon-shoucang" @click="cancelFocus('product', item, $event)"></i>
+        </div>
+      </a>
+    </div>
+    <div class="none-state" v-if="(collectSave.totalElements == 0 && !isShop) || (focusPage.totalElements == 0 && !isDevice) || (collectSave.totalElements == 0 && focusPage.totalElements == 0)">
+      <img src="/images/mobile/@2x/empty-collect.png">
+      <p v-text="getRemindText()"></p>
+      <nuxt-link to="/">返回首页</nuxt-link>
+    </div>
+    <remind-box :title="collectResult" :timeoutCount="timeoutCount"></remind-box>
+    <div class="mobile-modal" v-if="showStoreInfo">
+      <div class="mobile-modal-box">
+        <div class="mobile-modal-header">联系方式<i @click="showStoreInfo = false" class="icon-guanbi iconfont"></i></div>
+        <div class="mobile-modal-content">
+          <div v-if="checkInfo(storeInfo.enAddress || storeInfo.address)">商家地址:{{storeInfo.enAddress || storeInfo.address}}</div>
+          <!--<div class="content-line link-url">在线咨询</div>-->
+          <div v-if="checkInfo(storeInfo.enTel)">致电:<a :href="'tel:' + storeInfo.enTel" target="_blank" class="content-line link-url">{{storeInfo.enTel}}</a></div>
+          <div v-if="checkInfo(storeInfo.enEmail)">邮件:<a :href="'mailto:' + storeInfo.enEmail" target="_blank" class="content-line link-url">{{storeInfo.enEmail}}</a></div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+  import RemindBox from '~components/mobile/common/RemindBox.vue'
+  export default {
+    layout: 'mobile',
+    data () {
+      return {
+        userName: '',
+        down: false,
+        count: '',
+        page: '',
+        type: '',
+        listName: '全部收藏',
+        isShop: true,
+        isDevice: true,
+        collectResult: '取消成功',
+        timeoutCount: 0,
+        showStoreInfo: false,
+        storeInfo: {}
+      }
+    },
+    components: {
+      RemindBox
+    },
+    fetch ({ store }) {
+      return Promise.all([
+        store.dispatch('product/saveStores', { count: 100, page: 1, type: 'component' }),
+        store.dispatch('shop/StoreFocusPage', { count: 100, page: 1 })
+      ])
+    },
+    methods: {
+      onclick () {
+        this.down = !this.down
+      },
+      onDown (type) {
+        if (type === '-1') {
+          this.listName = '店铺关注'
+          this.isShop = true
+          this.isDevice = false
+          this.down = false
+        }
+        if (type === '0') {
+          this.listName = '器件收藏'
+          this.isDevice = true
+          this.isShop = false
+          this.down = false
+        }
+        if (type === '1') {
+          this.listName = '全部收藏'
+          this.isDevice = true
+          this.isShop = true
+          this.down = false
+        }
+      },
+      cancelFocus: function (type, item, event) {
+        event.stopPropagation()
+        if (type === 'store') {
+          this.$http.post('/trade/storeFocus/delete/storeId', [item.storeid])
+            .then(response => {
+              this.$store.dispatch('shop/StoreFocusPage', { count: 100, page: 1 })
+              this.timeoutCount++
+            })
+        } else {
+          // /trade/collection/
+          this.$http.delete('/trade/collection/' + item.id)
+            .then(response => {
+              this.$store.dispatch('product/saveStores', { count: 100, page: 1, type: 'component' })
+              this.timeoutCount++
+            })
+        }
+      },
+      getBackground: function (type) {
+        let url = ''
+        if (type === 'AGENCY') {
+          url += '/images/mobile/@2x/shop/agency.png'
+        } else if (type === 'DISTRIBUTION') {
+          url += '/images/mobile/@2x/shop/distribution.png'
+        } else if (type === 'ORIGINAL_FACTORY') {
+          url += '/images/mobile/@2x/shop/original_factory.png'
+        } else if (type === 'CONSIGNMENT') {
+          url = '/images/mobile/@2x/shop/consignment.png'
+        }
+        return url
+      },
+      goStoreDetail: function (uuid) {
+        this.$router.push('/mobile/shop/' + uuid)
+      },
+      goComponentDetail: function (uuid) {
+        this.$router.push('/mobile/brand/componentDetail/' + uuid)
+      },
+      getRemindText: function () {
+        if (this.isDevice && !this.isShop) {
+          return '抱歉,暂无器件收藏'
+        } else if (!this.isDevice && this.isShop) {
+          return '抱歉,暂无店铺关注'
+        } else {
+          return '抱歉,暂无收藏记录'
+        }
+      },
+      selectStoreInfo: function (store, event) {
+        event.stopPropagation()
+        this.storeInfo = store.storeInfo.enterprise || {}
+        this.showStoreInfo = true
+      },
+      checkInfo: function (str) {
+        return str && str.trim() !== ''
+      }
+    },
+    computed: {
+      collectSave () {
+        return this.$store.state.product.common.collectList.data
+      },
+      userInfo () {
+        return this.$store.state.option.user
+      },
+      enterpriseInfo () {
+        let ens = this.userInfo.data.enterprises
+//        if (ens && ens.length) {
+//          return ens.find(item => item.current) || {enName: this.userInfo.data.userName + '(个人账户)'}
+//        } else {
+//          return {enName: this.userInfo.data.userName + '(个人账户)'}
+//        }
+        if (ens && ens.length) {
+          for (let i = 0; i < ens.length; i++) {
+            if (ens[i].current) {
+              return ens[i]
+            }
+          }
+        }
+        return {enName: this.userInfo.data.userName + '(个人账户)'}
+      },
+      focusPage () {
+        return this.$store.state.shop.storeInfo.focusPage.data
+      }
+    }
+  }
+</script>
+
+<style scoped lang="scss">
+  .user-content{
+    margin-bottom: .98rem;
+    background: #dfe2e4;
+
+    .none-state{
+      text-align: center;
+      padding:1.5rem 0;
+      background: #fff;
+      margin-top:.1rem;
+      width:100%;
+      img{
+        margin:0 auto;
+        width: 4.08rem;
+        height: 2.62rem;
+      }
+      p {
+        font-size: .32rem;
+        color: #999;
+        margin: 1.19rem 0 0 0;
+      }
+      a {
+        display: block;
+        font-size: .28rem;
+        color: #fff;
+        width: 1.88rem;
+        height: .54rem;
+        line-height: .54rem;
+        background: #418bf6;
+        margin: .7rem auto 0;
+        border-radius: .05rem;
+      }
+    }
+    .user-name{
+      padding:.14rem 0 .2rem .34rem;
+      background:#fff;
+      width:100%;
+      position:relative;
+      border-bottom: .1rem solid #dfe2e4;
+      .supdown{
+        position:absolute;
+        top:.8rem;
+        right:.3rem;
+        z-index:10;
+        width:1.7rem;
+        background:#616264;
+        border-radius:.1rem;
+        li{
+          font-size: .28rem;
+          color:#ffffff;
+          height: .32rem;
+          line-height: .32rem;
+          margin: .4rem 0;
+          text-align: center;
+        }
+      }
+      img{
+        display: inline-block;
+        width:1.25rem;
+        height:1.25rem;
+        border:.04rem solid #c5dbfc;
+        border-radius: .05rem;
+        vertical-align: middle;
+      }
+      .user-info {
+        margin-left:.25rem;
+        display: inline-block;
+        vertical-align: middle;
+        p{
+          font-size:.3rem;
+          margin:0;
+          font-weight: bold;
+          display: block;
+          overflow: hidden;
+          text-overflow: ellipsis;
+          white-space: nowrap;
+          width: 3.92rem;
+          &:nth-child(2) {
+            font-weight: normal;
+            margin-top: .3rem;
+          }
+        }
+      }
+      span{
+        font-size:.28rem;
+        color:#53a0f7;
+        position: relative;
+        bottom: .3rem;
+      }
+    }
+    .shop-list {
+      background:#fff;
+      border-bottom: .1rem solid #dfe2e4;
+      padding: .14rem 0 .14rem 0;
+      h3{
+        font-size: .32rem;
+        line-height: .4rem;
+        margin: 0 0 0 .27rem;
+        overflow: hidden;
+        text-overflow: ellipsis;
+        white-space: nowrap;
+        padding-top: .1rem;
+        position: relative;
+        top: .1rem;
+      }
+      .list-item{
+        width:6.77rem;
+        margin-left:.39rem;
+        .item-img{
+          width:2.4rem;
+          vertical-align: middle;
+          display: inline-block;
+          img{
+            &:nth-child(2) {
+              width:2.4rem;
+              height:1.69rem;
+              border: .04rem solid #eee;
+            }
+            &:nth-child(1) {
+              position:absolute;
+              width:.65rem;
+              height:.33rem;
+            }
+          }
+        }
+        .list-item-phone{
+          width:3.95rem;
+          padding:.18rem 0;
+          position:relative;
+          display: inline-block;
+          vertical-align: middle;
+          margin-left: .26rem;
+          p{
+            font-size:.28rem;
+            line-height: .67rem;
+            margin:0;
+            overflow: hidden;
+            text-overflow: ellipsis;
+            white-space: nowrap;
+            width: 3.2rem;
+          }
+          i{
+            display:block;
+            position:absolute;
+            top: -.06rem;
+            right: -.18rem;
+            font-size:.5rem;
+            color:#ff7800;
+            width: .6rem;
+            height: .6rem;
+            text-align: center;
+            line-height: .6rem;
+          }
+        }
+      }
+      &:active {
+        background: #e1e1e1;
+      }
+    }
+    .detail-brand{
+      background: #fff;
+      width:100%;
+      min-height:1.5rem;
+      padding:.2rem 0;
+      border-bottom: .1rem solid #dfe2e4;
+      &:nth-child(1) {
+        margin-top:.1rem;
+      }
+      .brand-item{
+        width:7rem;
+        margin:0 auto;
+        border-radius:.1rem;
+        background: #fff;
+        padding:.2rem;
+        position:relative;
+        &:active{
+          background: #e1e1e1;
+        }
+        p{
+          font-size:.28rem;
+          line-height:.4rem;
+          color:#333;
+          margin:0;
+        }
+        i{
+          display:block;
+          position:absolute;
+          top:.2rem;
+          right:.1rem;
+          font-size:.5rem;
+          color:#ff7800;
+          width: .6rem;
+          height: .6rem;
+          line-height: .6rem;
+          text-align: center;
+        }
+      }
+      div.active{
+        background: #d4d;
+      }
+    }
+    .collect-list-type {
+      background: #fff;
+      border-bottom: .04rem solid #acacac;
+      p {
+        font-size: .32rem;
+        margin: 0 0 0 .13rem;
+        width: .92rem;
+        text-align: center;
+        line-height: .5rem;
+        border-bottom: .06rem solid #418bf6;
+      }
+    }
+  }
+</style>

+ 2 - 1
pages/product/component/_uuid.vue

@@ -27,7 +27,8 @@
               uuid: route.params.uuid,
               ignoreUMall: false,
               ignoreStore: false,
-              storeIds: ''
+              storeIds: '',
+              status: 601
             }}),
         store.dispatch('getUmallStoreId'),
         store.dispatch('product/saveStores')

+ 7 - 3
pages/search/_keyword.vue

@@ -25,7 +25,7 @@
         key: this.$route.query.w,
         pageSize: 15,
         nowPage: 1,
-        sorting: {'GO_RESERVE': 'DESC', 'GO_SEARCH': 'DESC'},
+        sorting: {},
         filter: {},
         paramJSON: {},
         crname_click_flag: {
@@ -38,7 +38,7 @@
       return Promise.all([
         store.dispatch('searchData/searchForKinds', {collectList: 'goods_kind', keyword: route.query.w, paramJSON: {}}),
         store.dispatch('searchData/searchForBrands', {collectList: 'goods_brand', keyword: route.query.w, paramJSON: {}}),
-        store.dispatch('searchData/searchForList', {count: 15, filter: {}, keyword: route.query.w, page: 1, sorting: {'GO_RESERVE': 'DESC', 'GO_SEARCH': 'DESC'}}),
+        store.dispatch('searchData/searchForList', {count: 15, filter: {}, keyword: route.query.w, page: 1, sorting: {}}),
         store.dispatch('searchData/searchForStoreType', {collectList: 'goods_store_type', keyword: route.query.w, paramJSON: {}}),
         store.dispatch('searchData/searchForCrname', {collectList: 'goods_crname', keyword: route.query.w, paramJSON: {}})
       ])
@@ -52,7 +52,7 @@
     methods: {
       reloadList: function () {
         if (this.sorting === {}) {
-          this.sorting = {'GO_RESERVE': 'DESC', 'GO_SEARCH': 'DESC'}
+          this.sorting = {}
         }
         this.$store.dispatch('searchData/searchForList', {count: this.pageSize, filter: this.filter, keyword: this.$route.query.w, page: this.nowPage, sorting: this.sorting})
       },
@@ -98,6 +98,7 @@
         this.reloadList()
       },
       listenKindFilter: function (kindarr) {
+        this.nowPage = 1
         if (kindarr.length === 0) {
           delete this.filter.goods_kindId
           delete this.paramJSON.goods_kindid
@@ -116,6 +117,7 @@
         }
       },
       listenBrandFilter: function (brandarr) {
+        this.nowPage = 1
         if (brandarr.length === 0) {
           delete this.filter.goods_brandId
           delete this.paramJSON.goods_brandid
@@ -134,6 +136,7 @@
         }
       },
       listenTypeFilter: function (typearr) {
+        this.nowPage = 1
         if (typearr.length === 0) {
           delete this.filter.goods_store_type
           delete this.paramJSON.goods_store_type
@@ -151,6 +154,7 @@
         }
       },
       listenCrnameFilter: function (crnamearr) {
+        this.nowPage = 1
         if (crnamearr.length === 0) {
           delete this.filter.goods_crname
           delete this.paramJSON.goods_crname

+ 0 - 8
plugins/README.md

@@ -1,8 +0,0 @@
-# PLUGINS
-
-This directory contains your Javascript plugins that you want to run before instantiating the root vue.js application.
-
-More information about the usage of this directory in the documentation:
-https://nuxtjs.org/guide/plugins
-
-**This directory is not required, you can delete it if you don't want to use it.**

+ 1 - 1
server.js

@@ -16,7 +16,7 @@ config.dev = !(process.env.NODE_ENV === 'production')
 const proxyTable = config.proxyTable
 if (proxyTable) {
   // 本地代理支持localhost、127.0.0.1等不同地址跨域
-  app.use((req, res, next) => {
+  app.use((req, res, next, store) => {
     res.header('Access-Control-Allow-Origin', '*')
     res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE')
     res.header('Access-Control-Allow-Headers', 'Content-Type')

+ 0 - 11
static/README.md

@@ -1,11 +0,0 @@
-# STATIC
-
-This directory contains your static files.
-Each file inside this directory is mapped to /.
-
-Example: /static/robots.txt is mapped as /robots.txt.
-
-More information about the usage of this directory in the documentation:
-https://nuxtjs.org/guide/assets#static
-
-**This directory is not required, you can delete it if you don't want to use it.**

BIN
static/images/404-mobile.png


BIN
static/images/christmas/btn.png


BIN
static/images/christmas/chirmas4.png


BIN
static/images/christmas/christmas1.png


BIN
static/images/christmas/christmas2.png


BIN
static/images/christmas/christmas3.png


BIN
static/images/christmas/christmas4.png


BIN
static/images/christmas/close.png


BIN
static/images/christmas/festival1.gif


BIN
static/images/christmas/festival_bg.png


BIN
static/images/christmas/festival_deng1.png


BIN
static/images/christmas/festival_deng2.png


BIN
static/images/christmas/festival_yanhualeft.gif


BIN
static/images/christmas/festival_yanhuaright.gif


BIN
static/images/mobile/@2x/brand-bg.png


BIN
static/images/mobile/@2x/brand/brandWall.png


BIN
static/images/mobile/@2x/car@2x.png


BIN
static/images/mobile/@2x/empty-collect.png


BIN
static/images/mobile/@2x/home/background@2x.png


BIN
static/images/mobile/@2x/home/background_search@2x.png


BIN
static/images/mobile/@2x/home/bookbrand@2x.png


BIN
static/images/mobile/@2x/home/brand@2x.png


BIN
static/images/mobile/@2x/home/hot-search.png


BIN
static/images/mobile/@2x/home/modelbrand@2x.png


BIN
static/images/mobile/@2x/home/phonebrand@2x.png


BIN
static/images/mobile/@2x/home/shopbrand@2x.png


Some files were not shown because too many files changed in this diff