Browse Source

Merge branch 'feature-wcz-supplier20180425' into release-20170915

# Conflicts:
#	nuxt.config.js
Administrator 7 years ago
parent
commit
b72a1001fc

+ 3 - 0
components/main/Nav.vue

@@ -22,6 +22,9 @@
       <nuxt-link target="_blank" :to="{ name: 'store-uuid', params: { uuid: '33069557578d44e69bd91ad12d28a8d4' } }" class="item">
         <span>库存寄售</span>
       </nuxt-link>
+      <nuxt-link to="/supplier" class="item">
+        <span>供应商</span>
+      </nuxt-link>
       <nuxt-link to="/applyPurchase" class="item">
         <span>求购询价</span>
         <img class="new-animate" src="/images/all/banner-cuxiao03.png" alt="">

+ 16 - 0
components/supplier/banner.vue

@@ -0,0 +1,16 @@
+<template>
+  <div class="banner"></div>
+</template>
+
+<script>
+  export default {
+    name: 'BannerView'
+  }
+</script>
+
+<style type="text/scss" lang="scss">
+.banner{
+  height:470px;
+  background: url(/images/supplier/bgImg.jpg)no-repeat center center
+}
+</style>

+ 547 - 0
components/supplier/details.vue

@@ -0,0 +1,547 @@
+<template>
+  <div class="details_info">
+    <div class="container">
+      <div class="crumbs">
+        <div class="container">
+          <div class="menu-com row">
+            <div class="menu-title col-md-12">
+              <a href="/">首页 ></a>
+              <a href="/supplier">供应商资源 ></a>
+              <span>供应商物料</span>
+            </div>
+          </div>
+        </div>
+      </div>
+      <div class="top">
+        <div class="img">
+          <img :src="detail.cmpImg || '/images/store/common/default.png'">
+        </div>
+        <div class="right">
+          <h4 v-text="detail.cmpCode">3</h4>
+          <ul class="list-unstyled">
+            <li class="item">
+              <span>类目(名称)</span>
+              <p v-if="detail.standard === 1" v-text="detail.kind ? spliceString(detail.kind, 135) : '暂无信息'">1</p>
+              <p v-if="detail.standard !== 1" v-text="detail.prodName ? spliceString(detail.prodName, 135) : '暂无信息'">1</p>
+            </li>
+            <li class="item">
+              <span>品牌</span>
+              <p v-text="detail.standard !== 1 ? detail.brand : detail.pbranden">2</p>
+            </li>
+            <li class="item">
+              <span>单位</span>
+              <p v-text="detail.unit ? detail.unit : 'PCS'">32</p>
+            </li>
+            <li class="item">
+              <span>规格</span>
+              <p v-text="detail.spec ? detail.spec : '暂无信息'">32</p>
+            </li>
+          </ul>
+          <a @click="hasDialog = true">立即询价</a>
+        </div>
+      </div>
+      <div class="detail">
+        <div class="info_title">
+          <p>产品参数<span>(仅供参考,以实际产品为准)</span></p> <a v-if="!(!detail.cmpUuId || cmpInfo.properties.length === 0)" @click="hasDown = !hasDown">更多 <i class="el-icon-arrow-down" v-if="hasDown"></i> <i v-if="!hasDown" class="el-icon-arrow-up"></i></a>
+        </div>
+        <div class="empty" v-if="!detail.cmpUuId || cmpInfo.properties.length === 0">
+          <img src="/images/supplier/icon/empty.png">
+          <div class="info">
+            <p>产品暂无参数</p>
+            <a href="javascript:history.go(-1)"><i class="fa fa-reply" style="margin-right:5px;"></i>返回上一页</a>
+          </div>
+        </div>
+        <ul class="list-unstyled" :style="hasDown ? height300 : heightAuto">
+          <li v-if="detail.cmpUuId" v-for="item in cmpInfo.properties"><span v-text="item.property.labelCn"></span><span v-text="item.value ? item.value : '-'"></span></li>
+        </ul>
+      </div>
+    </div>
+    <el-dialog
+      title="我要询价"
+      :visible.sync="hasDialog ">
+      <div class="form_dialog">
+        <ul class="list-inline">
+          <li class="form-item">
+            <span>型号:</span>
+            <p v-text="detail.cmpCode ? spliceString(detail.cmpCode, 90) : '-'">3</p>
+          </li>
+          <li class="form-item">
+            <span>类目:</span>
+            <p v-if="detail.standard === 1" v-text="detail.kind ? spliceString(detail.kind, 90) : '-'">1</p>
+            <p v-if="detail.standard !== 1" v-text="detail.prodName ? spliceString(detail.prodName, 90) : '-'">1</p>
+          </li>
+          <li class="form-item">
+            <span>品牌:</span>
+            <p v-text="detail.standard !== 1 ? spliceString(detail.brand, 90) : spliceString(detail.pbranden, 90)">2</p>
+          </li>
+          <li class="form-item">
+            <span>规格:</span>
+            <p v-text="detail.spec ? spliceString(detail.spec, 90) : '-'">3</p>
+          </li>
+          <li class="form-item">
+            <span><i>*</i>截止日期:</span>
+            <el-date-picker
+              :class="{'error': !validObj.deadline}"
+              v-model="applyObj.deadline"
+              type="date"
+              :picker-options="pickerOptions"
+              @change="setDeadLineValid"
+              :editable="false"
+              :clearable="true"
+              size="mini">
+            </el-date-picker>
+          </li>
+          <li class="form-item">
+            <span>封装:</span>
+            <input type="text" class="form-control" v-model="applyObj.encapsulation"/>
+          </li>
+          <li class="form-item">
+            <span>单价预算:</span>
+            <select v-model="applyObj.currency" class="form-control" style="width:40px;">
+              <option value="RMB">¥</option>
+              <option value="USD">$</option>
+            </select>
+            <input type="number" v-model="applyObj.unitPrice" class="form-control" :class="{'error': !validObj.unitPrice}"/>
+          </li>
+          <li class="form-item">
+            <span>生产日期:</span>
+            <input type="text" class="form-control" v-model="applyObj.produceDate"/>
+          </li>
+          <li class="form-item">
+            <span>采购数量:</span>
+            <input type="number" class="form-control" v-model="applyObj.amount" :class="{'error': !validObj.amount}"/>
+          </li>
+        </ul>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <button @click="goPublish" :disabled="isClick">询价提交</button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+  import {spliceStr, formatDate} from '~utils/baseUtils.js'
+  export default {
+    name: 'DetailsView',
+    data () {
+      return {
+        isClick: false,
+        hasDown: false,
+        height300: {
+          maxHeight: '306px'
+        },
+        heightAuto: {
+          height: 'auto'
+        },
+        applyObj: {
+          unitPrice: '',
+          currency: 'RMB',
+          encapsulation: '',
+          produceDate: '',
+          amount: '',
+          deadline: ''
+        },
+        validObj: {
+          unitPrice: true,
+          amount: true,
+          deadline: true
+        },
+        pickerOptions: {
+          disabledDate (time) {
+            // 大于等于今天 小于三个月后
+            return time.getTime() < Date.now() - 1000 * 60 * 60 * 24 || time.getTime() > Date.now() + 1000 * 60 * 60 * 24 * 30 * 3
+          }
+        },
+        hasDialog: false,
+        searchCode: ''
+      }
+    },
+    computed: {
+      detail () {
+        return this.$store.state.supplier.detail.detail.data
+      },
+      cmpInfo () {
+        return this.$store.state.supplier.detail.cmpInfo.data
+      },
+      user () {
+        return this.$store.state.option.user
+      }
+    },
+    methods: {
+      spliceString (str, length) {
+        return spliceStr(str, length)
+      },
+      // 时间格式化
+      setDeadLineValid: function () {
+        this.applyObj.deadline = formatDate(this.applyObj.deadline, 'yyyy-MM-dd hh:mm:ss')
+        this.validObj.deadline = true
+      },
+      // 检查单价预算
+      checkUnitPrice () {
+        this.validObj.unitPrice = this.applyObj.unitPrice === '' ? true : this.applyObj.unitPrice > 0 && this.applyObj.unitPrice < 100000000
+        if (!this.validObj.unitPrice && this.applyObj.unitPrice <= 0) {
+          this.$message.error('单价必须是大于0的数字')
+        }
+        return this.validObj.unitPrice
+      },
+      // 检查采购数量
+      checkAmount () {
+        this.validObj.amount = this.applyObj.amount === '' ? true : this.applyObj.amount > 0 && this.applyObj.amount < 1000000000
+        return this.validObj.amount
+      },
+      // 检查时间是否有输入
+      checkDeadline () {
+        this.validObj.deadline = Boolean(this.applyObj.deadline)
+        return this.validObj.deadline
+      },
+      // 检查各个字段输入正常数据
+      checkAll () {
+        return this.checkDeadline() && this.checkUnitPrice() && this.checkAmount()
+      },
+      emptyForm () {
+        for (let attr in this.applyObj) {
+          this.applyObj[attr] = attr === 'currency' ? 'RMB' : ''
+        }
+      },
+      // 请求询价信息
+      goPublish () {
+        let _this = this
+        this.isClick = true
+        setTimeout(function () {
+          _this.isClick = false
+        }, 1000)
+        if (this.checkAll()) {
+          let inquiry = {}
+          let inquiryItem = {}
+          if (this.user.data.enterprise) {
+            inquiry.enUU = this.user.data.enterprise.uu
+          }
+          let date = new Date()
+          let currency = this.applyObj.unitPrice ? this.applyObj.currency : null
+          inquiry.recorderUU = this.user.data.userUU
+          inquiry.code = 'MALL' + date.getTime()
+          inquiry.date = date
+          inquiry.recorder = this.user.data.userName
+          inquiry.endDate = this.applyObj.deadline
+          inquiry.sourceapp = 'MALL'
+          inquiry.amount = 1
+          inquiryItem.userUU = this.user.data.userUU
+          inquiryItem.source = 'MALL'
+          inquiryItem.userName = this.user.data.userName
+          inquiryItem.userTel = this.user.data.userTel
+          inquiryItem.needquantity = this.applyObj.amount
+          inquiryItem.inbrand = this.detail.brand
+          inquiryItem.currency = currency
+          inquiryItem.cmpCode = this.detail.cmpCode.toUpperCase()
+          inquiryItem.unitPrice = this.applyObj.unitPrice
+          inquiryItem.produceDate = this.applyObj.produceDate
+          inquiryItem.date = date
+          inquiryItem.endDate = this.applyObj.deadline
+          inquiryItem.encapsulation = this.applyObj.encapsulation
+          inquiryItem.spec = this.detail.spec
+          inquiryItem.prodTitle = this.detail.prodName
+          let inquiryItems = []
+          inquiryItems.push(inquiryItem)
+          inquiry.inquiryItems = inquiryItems
+          inquiry.currency = this.applyObj.unitPrice ? this.applyObj.currency : null
+          this.$http.post('/inquiry/buyer/save', inquiry)
+            .then(res => {
+              this.$message.success('发布成功')
+              this.hasDialog = false
+              this.emptyForm()
+            }, error => {
+              console.log(error)
+              this.$message.error('发布失败')
+            })
+        } else {
+          if (!this.validObj.deadline) {
+            this.$message.error('截止日期不能为空')
+          } else if (!this.validObj.amount) {
+            this.$message.error('请输入正确的数值')
+          }
+        }
+      }
+    }
+  }
+</script>
+
+<style type="text/scss" lang="scss">
+.details_info{
+  background: #fff;
+  .el-dialog{
+    width: 680px!important;
+    .el-dialog__header{
+      background: #4290f7;
+      line-height: 40px;
+      padding: 0 20px 0;
+      .el-dialog__title{
+        color:#fff;
+      }
+      .el-dialog__headerbtn:hover .el-dialog__close, .el-dialog__headerbtn:focus .el-dialog__close{
+        color:#fff;
+      }
+    }
+    .el-dialog__body{
+      padding: 10px 20px;
+    }
+    .el-dialog__footer{
+      text-align: center;
+      button{
+        display:inline-block;
+        border:0;
+        box-shadow: none;
+        background: #3c7cf5;
+        color:#fff;
+        font-size: 14px;
+        line-height: 30px;
+        height:30px;
+        padding:0 10px;
+        border-radius:5px;
+      }
+    }
+  }
+  .form_dialog{
+    .el-date-editor--date {
+      width: 230px;
+      &.error {
+        input {
+          border: 1px solid #f4645f !important;
+        }
+      }
+    }
+    ul{
+      li{
+        width:50%;
+        font-size: 14px;
+        color:#666;
+        vertical-align: top;
+        margin-bottom:15px;
+        &.form-item {
+          position: relative;
+          p{
+            margin:0;
+            margin-left:80px;
+            word-break: break-all;
+            word-wrap: break-word;
+          }
+          span {
+            float:left;
+            width: 80px;
+            text-align: right;
+            display: inline-block;
+            color:#3c7cf5;
+            i {
+              position: relative;
+              top: 2px;
+              right: 5px;
+              color: #e41515;
+            }
+          }
+          ul {
+            line-height: normal;
+            position: absolute;
+            top: 19px;
+            left: 79px;
+            background: #fff;
+            border: 1px solid #b5b5b5;
+            z-index: 1;
+            max-height: 120px;
+            overflow-y: auto;
+            overflow-x: hidden;
+            border-radius: 3px;
+            width: 114px;
+            font-size: 12px;
+            li {
+              height: 24px;
+              line-height: 24px;
+              cursor: pointer;
+              overflow: hidden;
+              text-overflow: ellipsis;
+              white-space: nowrap;
+              padding: 0 5px;
+              &:hover {
+                background: #ddd;
+              }
+            }
+          }
+          select {
+            width: 40px;
+            position: absolute;
+            height: 20px;
+            background: url('/images/applyPurchase/select.png')no-repeat right;
+            background-position-x: 23px;
+            padding: 0 0 0 7px;
+            border-radius: 0;
+            & + input {
+              padding-left: 45px;
+            }
+          }
+          .el-input {
+            width: 230px;
+          }
+          input {
+            font-size: 14px;
+            width: 230px;
+            height: 20px;
+            line-height: 20px;
+            border-radius: 2px;
+            padding: 0 3px;
+            box-shadow: none;
+            -webkit-box-shadow: none;
+            -moz-box-shadow: none;
+            &.error {
+              border-color: #f4645f!important;
+            }
+          }
+        }
+      }
+    }
+  }
+  .crumbs{
+    background: #fff;
+    .menu-com{
+      margin: 0;
+      .menu-title{
+        line-height: 40px;
+        font-size: 14px;
+        padding-left: 0;
+        margin:0;
+        a{
+          color: #5078cb;
+          font-size: 14px;
+        }
+      }
+    }
+  }
+  .top{
+    margin-bottom:20px;
+    .img{
+      float:left;
+      width:350px;
+      height:350px;
+      vertical-align: top;
+      padding:36px;
+      border:1px solid #bababa;
+      img{
+        width:100%;
+        height:100%;
+      }
+    }
+    .right{
+      position:relative;
+      height:350px;
+      margin-left:370px;
+      h4{
+        width:800px;
+        font-size: 25px;
+        line-height: 25px;
+        font-weight: bold;
+        overflow: hidden;
+        text-overflow: ellipsis;
+        white-space:nowrap;
+        border-bottom:1px solid #3c7cf5;
+        margin:0;
+        padding-bottom:20px;
+      }
+      a{
+        display:inline-block;
+        position:absolute;
+        bottom:0;
+        left: 0;
+        background: #3c7cf5;
+        color:#fff;
+        font-size: 14px;
+        line-height: 30px;
+        height:30px;
+        padding:0 10px;
+        border-radius:5px;
+      }
+      ul{
+        padding-top:35px;
+        li{
+          margin-bottom:25px;
+          span{
+            display:inline-block;
+            width:70px;
+            float:left;
+            color:#3c7cf5;
+            vertical-align: top;
+            text-align: right;
+          }
+          p{
+            width:365px;
+            font-size: 14px;
+            color:#333;
+            margin:0;
+            margin-left:90px;
+            word-wrap: break-word;
+            word-break: normal;
+          }
+        }
+      }
+    }
+  }
+  .detail{
+    margin-bottom:90px;
+    border:1px solid #e5e5e5;
+    .empty {
+      padding:75px 0;
+      text-align: center;
+      img {
+        vertical-align: top;
+        margin-right: 15px;
+      }
+      .info {
+        display: inline-block;
+        padding-top: 10px;
+      }
+    }
+    .info_title{
+      position:relative;
+      line-height: 34px;
+      font-weight: bold;
+      color:#fff;
+      background: #3c7cf5;
+      padding-left:15px;
+      text-align: left;
+      p{
+        font-size: 16px;
+        margin:0;
+        span{
+          font-size: 12px;
+        }
+      }
+      a{
+        position:absolute;
+        top:0;
+        right:20px;
+        color:#fff;
+      }
+    }
+    ul{
+      margin-left:0;
+      overflow: hidden;
+      li{
+        line-height: 34px;
+        text-align: center;
+        overflow: hidden;
+        > span{
+          display:inline-block;
+          width:50%;
+        }
+        &:nth-child(odd){
+          background: #fff;
+        }
+        &:nth-child(even){
+          background: #f5f6f8;
+        }
+        &.empty{
+          padding: 100px 0;
+          font-size: 24px;
+        }
+      }
+    }
+  }
+}
+</style>

+ 6 - 0
components/supplier/index.js

@@ -0,0 +1,6 @@
+import MerchantView from './merchant'
+import Resource from './resource'
+import DetailsView from './details'
+import Banner from './banner'
+
+export { MerchantView, Resource, DetailsView, Banner }

+ 371 - 0
components/supplier/merchant.vue

@@ -0,0 +1,371 @@
+<template>
+<div class="merchant">
+  <div class="container">
+    <div class="top clearfix">
+      <div class="title">
+        <p>High quality dealer</p>
+        <h2>供应商列表</h2>
+      </div>
+      <div class="search">
+        <div class="input-group">
+          <input type="search" class="form-control" title="code" placeholder="名称/地址/行业/型号/品牌"
+                 v-model="searchCode" @keyup.13="goodsSearch(searchCode)" @search="goodsSearch(searchCode)"/>
+          <span class="input-group-btn">
+            <button type="button" class="btn" @click="goodsSearch(searchCode)">&nbsp;查 询</button>
+          </span>
+        </div>
+      </div>
+    </div>
+
+    <div class="list_info">
+      <div class="empty" v-if="!list.content || list.content.length === 0">
+        <img src="/images/supplier/icon/empty.png">
+        <div class="info">
+          <p>暂无供应商信息</p>
+          <a href="javascript:history.go(-1)"><i class="fa fa-reply" style="margin-right:5px;"></i>返回上一页</a>
+        </div>
+      </div>
+      <ul class="list-inline">
+        <li v-for="item in list.content" @click="jumpResource(item.enUU, item.hasProduct)">
+          <div class="has_shop" v-if="item.isStore === 1">已开店</div>
+          <div class="enterprise_name" v-text="item.enName">深圳英优软科技有限公司</div>
+          <div class="select_btn" v-html="isInFrame ? '添加为<br/>供应商' : '查看<br/>更多'" @mouseleave="hasJump = false" @mouseenter="hasJump = true" @click="addResource(item.enUU, item.hasProduct)"></div>
+          <div class="popups">
+            <p>企业执照号:</p><p v-text="item.enBusinesscode ? item.enBusinesscode : '暂无信息'">1</p>
+            <p>地址:</p><p v-text="item.enAddress ? item.enAddress : '暂无信息'">1</p>
+            <p>邮箱:</p><p v-text="item.enEmail ? item.enEmail : '暂无信息'">h</p>
+            <p>电话:</p><p v-text="item.enTel ? item.enTel : '暂无信息'">1</p>
+            <p>行业:</p><p v-text="item.enIndustry ? item.enIndustry : '暂无信息'">1</p>
+          </div>
+        </li>
+      </ul>
+      <div style="float: right;">
+        <page :total="list.totalElements" :page-size="pageParams.count"
+              :current="pageParams.page" v-on:childEvent="handleCurrentChange">
+        </page>
+      </div>
+    </div>
+    <el-dialog
+      title="提示"
+      :visible.sync="hasDialog ">
+      <div class="form_dialog">
+        <p><span>供应商正在完善产品信息,</span>暂时不能查看更多。 </p>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <a type="button" @click="hasDialog=false">我知道了</a>
+      </span>
+    </el-dialog>
+  </div>
+</div>
+</template>
+
+<script>
+  import Page from '~components/common/page/pageComponent.vue'
+  export default {
+    name: 'MerchantView',
+    data () {
+      return {
+        hasDialog: false,
+        hasJump: false,
+        searchCode: '',
+        pageParams: {
+          count: 20,
+          page: 1
+        }
+      }
+    },
+    components: {
+      Page
+    },
+    computed: {
+      isInFrame () {
+        if (this.$route.query.type === 'erp') {
+          return true
+        }
+      },
+      list () {
+        return this.$store.state.supplier.merchant.merchant.data
+      }
+    },
+    methods: {
+      addResource (id, type) {
+        if (this.isInFrame) {
+          this.$http.get(`/basic/enterprise /${id}/info`)
+            .then(res => {
+              if (res.data) {
+                window.open(this.$route.query.localPath + this.$route.query.erpPath + '?b2bdata=' + encodeURIComponent(JSON.stringify(res.data)))
+              }
+            })
+            .catch(err => {
+              console.log(err)
+            })
+        } else {
+          if (type === 1) {
+            this.$router.push('supplier/' + id)
+          } else {
+            this.hasDialog = true
+          }
+        }
+      },
+      jumpResource (id, type) {
+        if (!this.hasJump) {
+          if (type === 1) {
+            this.$router.push('supplier/' + id)
+          } else {
+            this.hasDialog = true
+          }
+        }
+      },
+      goodsSearch (type) {
+        this.pageParams.page = 1
+        this.$store.dispatch('supplier/loadVendorList', {page: this.pageParams.page, size: this.pageParams.count, keyword: type})
+      },
+      handleCurrentChange (type) {
+        this.pageParams.page = type
+        this.$store.dispatch('supplier/loadVendorList', {page: type, size: this.pageParams.count, keyword: this.searchCode})
+      }
+    }
+  }
+</script>
+
+<style type="text/scss" lang="scss">
+.merchant{
+  background: #ecf1f1 url(/images/supplier/banner.jpg)no-repeat;
+  border-top:3px solid #000;
+  padding-bottom:25px;
+  margin-top:-1.5em;
+  .el-dialog{
+    width: 290px!important;
+    .el-dialog__header{
+      background: #4290f7;
+      line-height: 40px;
+      padding: 0 20px 0;
+      .el-dialog__title{
+        color:#fff;
+      }
+      .el-dialog__headerbtn:hover .el-dialog__close, .el-dialog__headerbtn:focus .el-dialog__close{
+        color:#fff;
+      }
+    }
+    .el-dialog__body{
+      padding: 10px 20px;
+    }
+    .el-dialog__footer{
+      text-align: center;
+      a{
+        display:inline-block;
+        background: #3c7cf5;
+        color:#fff;
+        font-size: 14px;
+        line-height: 30px;
+        height:30px;
+        padding:0 10px;
+        border-radius:5px;
+      }
+    }
+  }
+  .form_dialog{
+    p{
+      width:200px;
+      font-size: 14px;
+      color:#666666;
+      margin:0 auto;
+      padding-top:5px;
+      line-height: 20px;
+      span{
+        color:#eb6054;
+      }
+    }
+  }
+  .top{
+    padding-top:30px;
+    margin-bottom:40px;
+    .title{
+      margin:0 auto;
+      text-align: center;
+      width:215px;
+      border-bottom:1px solid #ff5151;
+      color:#fff;
+      p{
+        margin:0;
+      }
+      h2{
+        font-size: 32px;
+        margin:0;
+        line-height: 46px;
+      }
+      &:before{
+        content: '';
+        display:block;
+        position:relative;
+        left:55px;
+        top:61px;
+        width:105px;
+        height:1px;
+        background: #ff8a00;
+      }
+      &:after{
+        content: '';
+        display:block;
+        position:relative;
+        left:55px;
+        top:4px;
+        width:105px;
+        height:1px;
+        background: #fff600;
+      }
+    }
+    .search{
+      float:right;
+      width:310px;
+      text-align: right;
+      margin-right:10px;
+      .btn{
+        width:68px;
+        background: #ffa200;
+        color:#fff;
+      }
+    }
+  }
+  .list_info{
+    padding: 0 10px;
+    .empty{
+      height:418px;
+      border:15px solid #c4e9f9;
+      background: #eef9fd;
+      padding-top:165px;
+      text-align: center;
+      img{
+        vertical-align: top;
+        margin-right:15px;
+      }
+      .info{
+        display: inline-block;
+        padding-top:10px;
+      }
+    }
+    > ul{
+      margin-left:5px;
+      li{
+        position:relative;
+        vertical-align: top;
+        width:267px;
+        height:115px;
+        border-radius:5px;
+        margin-right:32px;
+        margin-bottom:60px;
+        background: #ffffff;
+        box-shadow: 0 3px 10px rgba(0,0,0,.8);
+        &:nth-child(4n) {
+          margin-right:0;
+        }
+        &:after{
+          content: '';
+          display:block;
+          position:absolute;
+          top:99%;
+          left:50%;
+          z-index:200;
+          width:88px;
+          height:22px;
+          margin-left:-44px;
+          background: url(/images/supplier/icon/bottom_center_img.png)no-repeat;
+        }
+        .has_shop {
+          position:absolute;
+          right:0;
+          top:0;
+          width:68px;
+          height:22px;
+          background: url(/images/supplier/icon/top_right_img.png)no-repeat;
+          color:#fff;
+          font-weight: bold;
+          text-align: center;
+          line-height: 22px;
+        }
+        .enterprise_name{
+          padding-top:15px;
+          width:98%;
+          overflow: hidden;
+          text-overflow: ellipsis;
+          white-space:nowrap;
+          border-bottom:1px solid #b9def7;
+          font-weight: bold;
+          color:#1891e4;
+          font-size: 18px;
+          line-height: 48px;
+          text-align: center;
+        }
+        .select_btn{
+          position:absolute;
+          bottom:-10px;
+          left:50%;
+          z-index:250;
+          width:56px;
+          height:56px;
+          padding:10px 0;
+          margin-left:-28px;
+          text-align: center;
+          line-height: 18px;
+          background: #1891e4;
+          border-radius:50%;
+          color:#fff;
+        }
+        &:hover{
+          cursor:pointer;
+          .popups{
+            top:99%;
+            opacity:1;
+            z-index:100;
+          }
+        }
+        .popups{
+          position:absolute;
+          top:50px;
+          left:0;
+          background: #6c6c6c;
+          width:267px;
+          min-height:20px;
+          padding:20px 15px 5px 10px;
+          transition: all .5s ease;
+          opacity: 0;
+          color:#fff;
+          overflow: hidden;
+          p{
+            float:left;
+            margin: 0 !important;
+            line-height: 18px;
+            max-height:18px;
+            overflow: hidden;
+            text-overflow: ellipsis;
+            white-space: nowrap;
+            &:nth-child(2n-1){
+              width:42px;
+            }
+            &:first-child{
+              width:85px;
+            }
+            &:nth-child(2n){
+              width:200px;
+            }
+            &:nth-child(2){
+              width:155px;
+            }
+            &:nth-child(4){
+              max-height:38px;
+              overflow: hidden;
+              white-space:pre-wrap;
+              word-wrap:break-word;
+            }
+            &:last-child{
+              overflow: hidden;
+              text-overflow: ellipsis;
+              white-space: nowrap;
+            }
+          }
+        }
+      }
+    }
+  }
+}
+</style>

+ 712 - 0
components/supplier/resource.vue

@@ -0,0 +1,712 @@
+<template>
+<div class="resource_info">
+  <div class="container">
+    <div class="crumbs">
+      <div class="container">
+        <div class="menu-com row">
+          <div class="menu-title col-md-12">
+            <a href="/">首页 ></a>
+            <a href="/supplier">供应商资源 ></a>
+            <span>供应商物料</span>
+          </div>
+        </div>
+      </div>
+    </div>
+    <div class="user_info">
+      <div class="user_title">
+        <div class="user_name">
+          <span>{{enUser.enName}}&nbsp;&nbsp;<i class="fa fa-angle-down"></i></span>
+          <a :href="/store/+ storeInfo.uuid" target="_blank" v-if="storeInfo.uuid">进入店铺</a>
+        </div>
+        <div class="user_mes">
+          <div class="mes-list">
+            <p>
+              <span><i class="supplier_icon1"></i>企业执照号:{{enUser.enBussinessCode ? enUser.enBussinessCode : '暂无信息'}}</span>
+              <span><i class="supplier_icon2"></i> 地址:{{enUser.enAddress ? enUser.enAddress : '暂无信息'}}</span>
+            </p>
+            <p>
+              <span><i class="supplier_icon3"></i> 邮箱:{{enUser.enEmail ? enUser.enEmail : '暂无信息'}}</span>
+              <span><i class="supplier_icon4"></i> 电话:{{enUser.enTel ? enUser.enTel : '暂无信息'}}</span>
+              <span><i class="supplier_icon5"></i> 行业:{{enUser.enIndustry ? enUser.enIndustry : '暂无信息'}}</span>
+            </p>
+          </div>
+        </div>
+      </div>
+      <div class="search">
+        <div class="input-group">
+          <input type="search" class="form-control" placeholder="请输入要查找的内容"
+                 v-model="searchCode" @keyup.13="goodsSearch(searchCode)" @search="goodsSearch(searchCode)"/>
+          <span class="input-group-btn">
+            <button type="button" class="btn" id="search_btn" @click="goodsSearch(searchCode)">
+              搜索 <i class="fa fa-search"></i>
+            </button>
+        </span>
+        </div>
+      </div>
+    </div>
+    <div class="info_list">
+      <table>
+        <thead>
+        <tr>
+          <th width="66">序号</th>
+          <th width="1008">
+            <span>原厂型号 / 品牌</span>
+            <span>类目(名称) / 单位</span>
+            <span>规格</span>
+          </th>
+          <th width="116">操作</th>
+        </tr>
+        </thead>
+        <tbody>
+          <tr v-for="(item, index) in list.content" @click="jumpDetail(item.id)">
+            <td v-text="index + 1">12</td>
+            <td>
+              <ul class="list-inline">
+                <li class="item">
+                  <span class="fl">原厂型号</span>
+                  <p v-text="item.cmpCode ? spliceString(item.cmpCode, 95) : '暂无信息'">2</p>
+                </li>
+                <li class="item">
+                  <span class="fl">类目(名称)</span>
+                  <p v-if="item.standard === 1" v-text="item.kind ? spliceString(item.kind, 95) : '暂无信息'">1</p>
+                  <p v-if="item.standard !== 1" v-text="item.prodName ? spliceString(item.prodName, 95) : '暂无信息'">1</p>
+                </li>
+                <li class="item">
+                  <span class="fl">规格</span>
+                  <p v-text="item.spec ? spliceString(item.spec, 95) : '暂无信息'">1</p>
+                </li>
+                <li class="item">
+                  <span class="fl">品牌</span>
+                  <p v-text="item.standard !== 1 ? spliceString(item.brand, 95) : spliceString(item.pbranden, 95)">2</p>
+                </li>
+                <li class="item">
+                  <span class="fl">单位</span>
+                  <p v-text="item.unit ? item.unit : 'PCS'">1</p>
+                </li>
+              </ul>
+            </td>
+            <td>
+              <a @click="immediatelyClick(item)" @mouseleave="hasClick = false" @mouseenter="hasClick = true">立即询价</a>
+            </td>
+          </tr>
+        </tbody>
+      </table>
+      <div style="float: right;background: #ecf1f1;">
+        <page :total="list.totalElements" :page-size="pageParams.count"
+              :current="pageParams.page" v-on:childEvent="handleCurrentChange">
+        </page>
+      </div>
+    </div>
+    <el-dialog
+      title="我要询价"
+      :visible.sync="hasDialog">
+      <div class="form_dialog">
+        <ul class="list-inline">
+          <li class="form-item">
+            <span>型号:</span>
+            <p v-text="applyObj.cmpCode ? spliceString(applyObj.cmpCode, 90) : '-'">32432</p>
+          </li>
+          <li class="form-item">
+            <span>类目:</span>
+            <p v-text="applyObj.prodName ? spliceString(applyObj.prodName, 90) : '-'">32</p>
+          </li>
+          <li class="form-item">
+            <span>品牌:</span>
+            <p v-text="applyObj.brand ? spliceString(applyObj.brand, 90) : '-'">32432</p>
+          </li>
+          <li class="form-item">
+            <span>规格:</span>
+            <p v-text="applyObj.spec ? spliceString(applyObj.spec, 90) : '-'">32432</p>
+          </li>
+          <li class="form-item">
+            <span><i>*</i>截止日期:</span>
+            <el-date-picker
+              :class="{'error': !validObj.deadline}"
+              v-model="applyObj.deadline"
+              type="date"
+              :picker-options="pickerOptions"
+              @change="setDeadLineValid"
+              :editable="false"
+              :clearable="true"
+              size="mini">
+            </el-date-picker>
+          </li>
+          <li class="form-item">
+            <span>封装:</span>
+            <input type="text" class="form-control" v-model="applyObj.encapsulation"/>
+          </li>
+          <li class="form-item">
+            <span>单价预算:</span>
+            <select v-model="applyObj.currency" class="form-control" style="width:40px;">
+              <option value="RMB">¥</option>
+              <option value="USD">$</option>
+            </select>
+            <input type="number" v-model="applyObj.unitPrice" class="form-control" :class="{'error': !validObj.unitPrice}"/>
+          </li>
+          <li class="form-item">
+            <span>生产日期:</span>
+            <input type="text" class="form-control" v-model="applyObj.produceDate"/>
+          </li>
+          <li class="form-item">
+            <span>采购数量:</span>
+            <input type="number" class="form-control" v-model="applyObj.amount" :class="{'error': !validObj.amount}"/>
+          </li>
+        </ul>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <button @click="goPublish" :disabled="isClick">询价提交</button>
+      </span>
+    </el-dialog>
+  </div>
+</div>
+</template>
+
+<script>
+  import {spliceStr, formatDate} from '~utils/baseUtils.js'
+  import Page from '~/components/common/page/pageComponent.vue'
+  export default {
+    name: 'ResourceView',
+    data () {
+      return {
+        isClick: false,
+        applyObj: {
+          cmpCode: '',
+          brand: '',
+          unitPrice: '',
+          currency: 'RMB',
+          prodName: '',
+          spec: '',
+          encapsulation: '',
+          produceDate: '',
+          amount: '',
+          deadline: ''
+        },
+        validObj: {
+          unitPrice: true,
+          amount: true,
+          deadline: true
+        },
+        pickerOptions: {
+          disabledDate (time) {
+            // 大于等于今天 小于三个月后
+            return time.getTime() < Date.now() - 1000 * 60 * 60 * 24 || time.getTime() > Date.now() + 1000 * 60 * 60 * 24 * 30 * 3
+          }
+        },
+        hasDialog: false,
+        hasClick: false,
+        searchCode: '',
+        pageParams: {
+          count: 20,
+          page: 1
+        }
+      }
+    },
+    components: {
+      Page
+    },
+    computed: {
+      list () {
+        return this.$store.state.supplier.material.material.data
+      },
+      enUser () {
+        return this.$store.state.supplier.material.enUser.data
+      },
+      storeInfo () {
+        return this.$store.state.shop.storeInfo.store.data
+      },
+      user () {
+        return this.$store.state.option.user
+      }
+    },
+    methods: {
+      // 格式化字符串长度
+      spliceString (str, length) {
+        return spliceStr(str, length)
+      },
+      // 跳转到器件详情页面
+      jumpDetail (id) {
+        if (!this.hasClick) {
+          this.$router.push(this.$route.path + '/' + id)
+        }
+      },
+      // 获取分页数据
+      handleCurrentChange (type) {
+        this.pageParams.page = type
+        this.$store.dispatch('supplier/loadMaterialList', {page: type, size: this.pageParams.count, vendUU: this.$route.params.uuid, keyword: this.searchCode})
+      },
+      // 根据搜索信息获取数据
+      goodsSearch (type) {
+        this.pageParams.page = 1
+        this.$store.dispatch('supplier/loadMaterialList', {
+          page: this.pageParams.page,
+          size: this.pageParams.count,
+          vendUU: this.$route.params.uuid,
+          keyword: type
+        })
+      },
+      // 弹出询价界面
+      immediatelyClick (type) {
+        this.hasDialog = true
+        this.applyObj.cmpCode = type.cmpCode
+        this.applyObj.brand = (type.standard === 1 ? type.pbranden : type.brand)
+        this.applyObj.spec = type.spec
+        this.applyObj.prodName = (type.standard === 1 ? type.kind : type.prodName)
+      },
+      // 时间格式化
+      setDeadLineValid: function () {
+        this.applyObj.deadline = formatDate(this.applyObj.deadline, 'yyyy-MM-dd hh:mm:ss')
+        this.validObj.deadline = true
+      },
+      // 检查单价预算
+      checkUnitPrice () {
+        this.validObj.unitPrice = this.applyObj.unitPrice === '' ? true : this.applyObj.unitPrice > 0 && this.applyObj.unitPrice < 100000000
+        if (!this.validObj.unitPrice && this.applyObj.unitPrice <= 0) {
+          this.$message.error('单价必须是大于0的数字')
+        }
+        return this.validObj.unitPrice
+      },
+      // 检查采购数量
+      checkAmount () {
+        this.validObj.amount = this.applyObj.amount === '' ? true : this.applyObj.amount > 0 && this.applyObj.amount < 1000000000
+        return this.validObj.amount
+      },
+      // 检查时间是否有输入
+      checkDeadline () {
+        this.validObj.deadline = Boolean(this.applyObj.deadline)
+        return this.validObj.deadline
+      },
+      // 检查各个字段输入正常数据
+      checkAll () {
+        return this.checkDeadline() && this.checkUnitPrice() && this.checkAmount()
+      },
+      emptyForm () {
+        for (let attr in this.applyObj) {
+          this.applyObj[attr] = attr === 'currency' ? 'RMB' : ''
+        }
+      },
+      // 请求询价信息
+      goPublish () {
+        let _this = this
+        this.isClick = true
+        setTimeout(function () {
+          _this.isClick = false
+        }, 1000)
+        if (this.checkAll()) {
+          let inquiry = {}
+          let inquiryItem = {}
+          if (this.user.data.enterprise) {
+            inquiry.enUU = this.user.data.enterprise.uu
+          }
+          let date = new Date()
+          let currency = this.applyObj.unitPrice ? this.applyObj.currency : null
+          inquiry.recorderUU = this.user.data.userUU
+          inquiry.code = 'MALL' + date.getTime()
+          inquiry.date = date
+          inquiry.recorder = this.user.data.userName
+          inquiry.endDate = this.applyObj.deadline
+          inquiry.sourceapp = 'MALL'
+          inquiry.amount = 1
+          inquiryItem.userUU = this.user.data.userUU
+          inquiryItem.source = 'MALL'
+          inquiryItem.userName = this.user.data.userName
+          inquiryItem.userTel = this.user.data.userTel
+          inquiryItem.needquantity = this.applyObj.amount
+          inquiryItem.inbrand = this.applyObj.brand
+          inquiryItem.currency = currency
+          inquiryItem.cmpCode = this.applyObj.cmpCode.toUpperCase()
+          inquiryItem.unitPrice = this.applyObj.unitPrice
+          inquiryItem.produceDate = this.applyObj.produceDate
+          inquiryItem.date = date
+          inquiryItem.endDate = this.applyObj.deadline
+          inquiryItem.encapsulation = this.applyObj.encapsulation
+          inquiryItem.spec = this.applyObj.spec
+          inquiryItem.prodTitle = this.applyObj.prodName
+          let inquiryItems = []
+          inquiryItems.push(inquiryItem)
+          inquiry.inquiryItems = inquiryItems
+          inquiry.currency = this.applyObj.unitPrice ? this.applyObj.currency : null
+          this.$http.post('/inquiry/buyer/save', inquiry)
+            .then(res => {
+              this.$message.success('发布成功')
+              this.hasDialog = false
+              this.emptyForm()
+            }, error => {
+              console.log(error)
+              this.$message.error('发布失败')
+            })
+        } else {
+          if (!this.validObj.deadline) {
+            this.$message.error('截止日期不能为空')
+          } else if (!this.validObj.amount) {
+            this.$message.error('请输入正确的数值')
+          }
+        }
+      }
+    }
+  }
+</script>
+
+<style type="text/scss" lang="scss">
+.resource_info{
+  background: #ecf1f1;
+  .el-dialog{
+    width: 680px!important;
+    .el-dialog__header{
+      background: #4290f7;
+      line-height: 40px;
+      padding: 0 20px 0;
+      .el-dialog__title{
+        color:#fff;
+      }
+      .el-dialog__headerbtn:hover .el-dialog__close, .el-dialog__headerbtn:focus .el-dialog__close{
+        color:#fff;
+      }
+    }
+    .el-dialog__body{
+      padding: 10px 20px;
+    }
+    .el-dialog__footer{
+      text-align: center;
+      button{
+        display:inline-block;
+        background: #3c7cf5;
+        color:#fff;
+        font-size: 14px;
+        line-height: 30px;
+        height:30px;
+        padding:0 10px;
+        box-shadow: none;
+        border: 0;
+        border-radius:5px;
+      }
+    }
+  }
+  .form_dialog{
+    .el-date-editor--date{
+      width: 230px;
+      &.error {
+        input {
+          border: 1px solid #f4645f !important;
+        }
+      }
+    }
+    ul{
+      li{
+        width:50%;
+        font-size: 14px;
+        color:#666;
+        vertical-align: top;
+        margin-bottom:15px;
+        &.form-item {
+          position: relative;
+          p{
+            margin:0;
+            margin-left:80px;
+            word-break: break-all;
+            word-wrap: break-word;
+          }
+          span {
+            float:left;
+            width: 80px;
+            text-align: right;
+            display: inline-block;
+            color:#3c7cf5;
+            i {
+              position: relative;
+              top: 2px;
+              right: 5px;
+              color: #e41515;
+            }
+          }
+          ul {
+            line-height: normal;
+            position: absolute;
+            top: 19px;
+            left: 79px;
+            background: #fff;
+            border: 1px solid #b5b5b5;
+            z-index: 1;
+            max-height: 120px;
+            overflow-y: auto;
+            overflow-x: hidden;
+            border-radius: 3px;
+            width: 114px;
+            font-size: 12px;
+            li {
+              height: 24px;
+              line-height: 24px;
+              cursor: pointer;
+              overflow: hidden;
+              text-overflow: ellipsis;
+              white-space: nowrap;
+              padding: 0 5px;
+              &:hover {
+                background: #ddd;
+              }
+            }
+          }
+          select {
+            width: 40px;
+            position: absolute;
+            height: 20px;
+            background: url('/images/applyPurchase/select.png')no-repeat right;
+            background-position-x: 23px;
+            padding: 0 0 0 7px;
+            border-radius: 0;
+            & + input {
+              padding-left: 45px;
+            }
+          }
+          .el-input {
+            width: 230px;
+          }
+          input {
+            font-size: 14px;
+            width: 230px;
+            height: 20px;
+            line-height: 20px;
+            border-radius: 2px;
+            padding: 0 3px;
+            box-shadow: none;
+            -webkit-box-shadow: none;
+            -moz-box-shadow: none;
+            &.error {
+              border-color: #f4645f!important;
+            }
+          }
+        }
+      }
+    }
+  }
+  .crumbs{
+    background: #ecf1f1;
+    .menu-com{
+      margin: 0;
+      .menu-title{
+        line-height: 40px;
+        font-size: 14px;
+        padding-left: 0;
+        margin:0;
+        a{
+          color: #5078cb;
+          font-size: 14px;
+        }
+      }
+    }
+  }
+  .user_info{
+    margin-bottom:5px;
+    .user_title{
+      display:inline-block;
+      position:relative;
+      padding-bottom:13px;
+      margin-right:330px;
+      &:hover{
+        .user_mes{
+          display:block;
+        }
+      }
+      .user_name{
+        span{
+          font-size: 20px;
+          color:#666;
+          font-weight: bold;
+          margin-right:10px;
+        }
+        a{
+          display:inline-block;
+          padding:0 10px;
+          border-radius:3px;
+          font-size: 12px;
+          height:24px;
+          line-height: 24px;
+          color:#fff;
+          background: #ffa200;
+        }
+      }
+      .user_mes{
+        display:none;
+        position:absolute;
+        top:100%;
+        left:0;
+        z-index: 200;
+        height:10px;
+        &:before{
+          content: '';
+          display:block;
+          position:absolute;
+          bottom:5px;
+          left:20px;
+          z-index: 100;
+          border: 5px solid rgba(0,0,0,.7);
+          -webkit-transform: rotate(45deg);
+          -moz-transform: rotate(45deg);
+          -o-transform:rotate(45deg);
+          -ms-transform: rotate(45deg);
+          transform:rotate(45deg);
+        }
+        .mes-list{
+          padding:10px 10px;
+          background: rgba(0,0,0,.7);
+          color:#fff;
+          p{
+            max-width:1183px;
+            min-width:118px;
+            margin:0;
+            line-height: 20px;
+            font-size: 12px;
+            color:#fff;
+            overflow: hidden;
+            white-space: nowrap;
+            span{
+              margin: 0 5px;
+              .supplier_icon1{
+                display:inline-block;
+                position: relative;
+                top: 5px;
+                width:20px;
+                height:18px;
+                background: url(/images/supplier/icon/supplier_icon.png)no-repeat 0 0;
+              }
+              .supplier_icon2{
+                display:inline-block;
+                position: relative;
+                top: 5px;
+                width:20px;
+                height:18px;
+                background: url(/images/supplier/icon/supplier_icon.png)no-repeat -20px 0;
+              }
+              .supplier_icon3{
+                display:inline-block;
+                position: relative;
+                top: 5px;
+                width:20px;
+                height:18px;
+                background: url(/images/supplier/icon/supplier_icon.png)no-repeat -40px 0;
+              }
+              .supplier_icon4{
+                display:inline-block;
+                position: relative;
+                top: 5px;
+                height:18px;
+                width:22px;
+                background: url(/images/supplier/icon/supplier_icon.png)no-repeat -60px 0;
+              }
+              .supplier_icon5{
+                display:inline-block;
+                position: relative;
+                top: 5px;
+                width:20px;
+                height:18px;
+                background: url(/images/supplier/icon/supplier_icon.png)no-repeat -85px 0;
+              }
+            }
+          }
+        }
+      }
+    }
+    .search{
+      width:310px;
+      margin:0;
+      float:right;
+      .btn{
+        background: #3c7cf5;
+        color:#fff;
+      }
+    }
+  }
+  .info_list{
+    padding-bottom:200px;
+    table {
+      table-layout: fixed;
+      thead{
+        tr{
+          line-height: 32px;
+          vertical-align: middle;
+          th{
+            font-size: 14px;
+            color:#fff;
+            text-align: center;
+            background: #3975f4;
+            span{
+              display:inline-block;
+              width:33%;
+            }
+          }
+        }
+      }
+      tbody{
+        tr{
+          border:1px solid #dadada;
+          &:nth-child(odd){
+            background: #fff;
+          }
+          &:nth-child(even){
+            background: #f8f8f8;
+          }
+          &:hover{
+            cursor:pointer;
+            background: #f8fafe;
+            td{
+              &:first-child{
+                border-left:1px solid #3975f4;
+              }
+              &:last-child{
+                border-right:1px solid #3975f4;
+              }
+              border-top:1px solid #3975f4;
+              border-bottom:1px solid #3975f4;
+            }
+          }
+          td{
+            vertical-align: middle;
+            margin:0 auto;
+            padding:10px 0;
+            &:first-child, &:last-child{
+              color:#ed791c;
+              text-align: center;
+            }
+            a{
+              display:inline-block;
+              padding:0 10px;
+              margin:0 auto;
+              line-height: 24px;
+              border-radius:3px;
+              height:24px;
+              font-size: 12px;
+              color:#fff;
+              background: #3c7cf5;
+              text-align: center;
+            }
+            ul{
+              margin-left:5px;
+            }
+            .item{
+              font-size: 12px;
+              line-height: 18px;
+              padding: 10px 0;
+              vertical-align: top;
+              width:33%;
+              span{
+                display:inline-block;
+                width:85px;
+                text-align: right;
+                color:#3c7cf5;
+              }
+              p{
+                display:block;
+                width:210px;
+                margin-left:100px;
+                margin-bottom:0;
+                color:#333;
+                word-break: break-all;
+                word-wrap:break-word;
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+}
+</style>

+ 22 - 0
pages/supplier/_uuid/_id.vue

@@ -0,0 +1,22 @@
+<template>
+  <div class="supplier">
+    <details-view/>
+  </div>
+</template>
+
+<script>
+  import { DetailsView } from '~components/supplier'
+  export default {
+    name: 'SupplierDetails',
+    layout: 'main',
+    middleware: 'authenticated',
+    fetch ({store, route}) {
+      return Promise.all([
+        store.dispatch('supplier/loadMaterialDetail', {id: route.params.id})
+      ])
+    },
+    components: {
+      DetailsView
+    }
+  }
+</script>

+ 24 - 0
pages/supplier/_uuid/index.vue

@@ -0,0 +1,24 @@
+<template>
+  <div class="supplier">
+    <resource/>
+  </div>
+</template>
+
+<script>
+  import { Resource } from '~components/supplier'
+  export default {
+    name: 'SupplierResource',
+    layout: 'main',
+    middleware: 'authenticated',
+    fetch ({store, route}) {
+      return Promise.all([
+        store.dispatch('supplier/loadMaterialList', {page: 1, size: 20, vendUU: route.params.uuid}),
+        store.dispatch('supplier/loadEnUser', {enUU: route.params.uuid, filter: 'enUU'}),
+        store.dispatch('shop/findStoreInfoFromUuid', {enUU: route.params.uuid, filter: 'enUU'})
+      ])
+    },
+    components: {
+      Resource
+    }
+  }
+</script>

+ 36 - 0
pages/supplier/index.vue

@@ -0,0 +1,36 @@
+<template>
+  <div class="supplier">
+    <!--<carousel>-->
+      <!--<kind-category @loadchild="loadProductKinds"></kind-category>-->
+    <!--</carousel>-->
+    <banner/>
+    <merchant-view/>
+  </div>
+</template>
+
+<script>
+  import { KindCategory, Carousel } from '~components/home'
+  import { MerchantView, Banner } from '~components/supplier'
+  export default {
+    name: 'SupplierView',
+    layout: 'main',
+    fetch ({store}) {
+      return Promise.all([
+        store.dispatch('supplier/loadVendorList', {page: 1, size: 20}),
+        store.dispatch('loadBanners', {type: 'home'}),
+        store.dispatch('loadProductKinds', { id: 0 })
+      ])
+    },
+    components: {
+      KindCategory,
+      Carousel,
+      MerchantView,
+      Banner
+    },
+    methods: {
+      loadProductKinds (id) {
+        this.$store.dispatch('loadAllProductKinds', {id})
+      }
+    }
+  }
+</script>

BIN
static/images/supplier/banner.jpg


BIN
static/images/supplier/bgImg.jpg


BIN
static/images/supplier/icon/bottom_center_img.png


BIN
static/images/supplier/icon/empty.png


BIN
static/images/supplier/icon/supplier_icon.png


BIN
static/images/supplier/icon/top_right_img.png


+ 53 - 0
store/supplier.js

@@ -0,0 +1,53 @@
+import axios from '~/plugins/axios'
+
+export const actions = {
+  // 获取供应商展示列表
+  loadVendorList ({commit}, params) {
+    commit('merchant/REQUEST_MERCHANT')
+    return axios.get('/vendor/introduction/vendor/list', {params})
+      .then(res => {
+        commit('merchant/GET_MERCHANT_SUCCESS', res.data)
+      }, (err) => {
+        commit('merchant/GET_MERCHANT_FAILURE', err)
+      })
+  },
+  // 获取供应商物料列表
+  loadMaterialList ({commit}, params = {}) {
+    commit('material/REQUEST_MATERIAL')
+    return axios.get('/vendor/introduction/product/list', {params})
+      .then(res => {
+        commit('material/GET_MATERIAL_SUCCESS', res.data)
+      }, (err) => {
+        commit('material/GET_MATERIAL_FAILURE', err)
+      })
+  },
+  // 获取获取物料详细信息
+  loadMaterialDetail ({commit}, params = {}) {
+    commit('detail/REQUEST_DETAIL')
+    return axios.get('/vendor/introduction/product/detail', {params})
+      .then(res => {
+        commit('detail/GET_DETAIL_SUCCESS', res.data)
+        if (res.data.cmpUuId) {
+          commit('detail/REQUEST_CMPINFO')
+          return axios.get(`/api/commodity/component/${res.data.cmpUuId}`)
+            .then(res => {
+              commit('detail/GET_CMPINFO_SUCCESS', res.data)
+            }, (err) => {
+              commit('detail/GET_CMPINFO_FAILURE', err)
+            })
+        }
+      }, (err) => {
+        commit('detail/GET_DETAIL_FAILURE', err)
+      })
+  },
+  // 获取企业信息
+  loadEnUser ({commit}, params = {}) {
+    commit('material/REQUEST_ENUSER')
+    return axios.get(`/basic/enterprise/${params.enUU}/info`)
+      .then(res => {
+        commit('material/GET_ENUSER_SUCCESS', res.data)
+      }, (err) => {
+        commit('material/GET_ENUSER_FAILURE', err)
+      })
+  }
+}

+ 33 - 0
store/supplier/detail.js

@@ -0,0 +1,33 @@
+export const state = () => ({
+  detail: {
+    fetching: false,
+    data: []
+  },
+  cmpInfo: {
+    fetching: false,
+    data: []
+  }
+})
+
+export const mutations = {
+  REQUEST_DETAIL (state) {
+    state.detail.detching = true
+  },
+  GET_DETAIL_SUCCESS (state, result) {
+    state.detail.fetching = false
+    state.detail.data = result
+  },
+  GET_DETAIL_FAILURE (state) {
+    state.detail.fetching = false
+  },
+  REQUEST_CMPINFO (state) {
+    state.cmpInfo.detching = true
+  },
+  GET_CMPINFO_SUCCESS (state, result) {
+    state.cmpInfo.fetching = false
+    state.cmpInfo.data = result
+  },
+  GET_CMPINFO_FAILURE (state) {
+    state.cmpInfo.fetching = false
+  }
+}

+ 33 - 0
store/supplier/material.js

@@ -0,0 +1,33 @@
+export const state = () => ({
+  material: {
+    fetching: false,
+    data: []
+  },
+  enUser: {
+    fetching: false,
+    data: []
+  }
+})
+
+export const mutations = {
+  REQUEST_MATERIAL (state) {
+    state.material.fetching = true
+  },
+  GET_MATERIAL_SUCCESS (state, result) {
+    state.material.fetching = false
+    state.material.data = result
+  },
+  GET_MATERIAL_FAILURE (state) {
+    state.material.fetching = false
+  },
+  REQUEST_ENUSER (state) {
+    state.enUser.fetching = true
+  },
+  GET_ENUSER_SUCCESS (state, result) {
+    state.enUser.fetching = false
+    state.enUser.data = result
+  },
+  GET_ENUSER_FAILURE (state) {
+    state.enUser.fetching = false
+  }
+}

+ 19 - 0
store/supplier/merchant.js

@@ -0,0 +1,19 @@
+export const state = () => ({
+  merchant: {
+    fetching: false,
+    data: []
+  }
+})
+
+export const mutations = {
+  REQUEST_MERCHANT (state) {
+    state.merchant.detching = true
+  },
+  GET_MERCHANT_SUCCESS (state, result) {
+    state.merchant.fetching = false
+    state.merchant.data = result
+  },
+  GET_MERCHANT_FAILURE (state) {
+    state.merchant.fetching = false
+  }
+}

+ 11 - 0
utils/baseUtils.js

@@ -96,6 +96,17 @@ export const cutOutString = (str, length) => {
   return str
 }
 
+// 根据字符长度剪切字符
+export const spliceStr = (str, length) => {
+  for (let i = 1; i <= str.length; i++) {
+    if (getRealLength(str.substr(0, i)) > length) {
+      str = str.substr(0, i - 1) + '...'
+      break
+    }
+  }
+  return str
+}
+
 // 格式化日期,返回字符串
 export const formatDate = (date, fmt) => {
   if (!date) {

+ 304 - 9
yarn.lock

@@ -90,6 +90,12 @@ ansi-styles@^3.1.0:
   dependencies:
     color-convert "^1.0.0"
 
+ansi-styles@^3.2.1:
+  version "3.2.1"
+  resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
+  dependencies:
+    color-convert "^1.9.0"
+
 anymatch@^1.3.0:
   version "1.3.0"
   resolved "http://registry.npm.taobao.org/anymatch/download/anymatch-1.3.0.tgz#a3e52fa39168c825ff57b0248126ce5a8ff95507"
@@ -252,6 +258,14 @@ babel-code-frame@^6.11.0, babel-code-frame@^6.16.0, babel-code-frame@^6.22.0:
     esutils "^2.0.2"
     js-tokens "^3.0.0"
 
+babel-code-frame@^6.26.0:
+  version "6.26.0"
+  resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b"
+  dependencies:
+    chalk "^1.1.3"
+    esutils "^2.0.2"
+    js-tokens "^3.0.2"
+
 babel-core@^6.24.0, babel-core@^6.24.1, babel-core@^6.25.0:
   version "6.25.0"
   resolved "http://registry.npm.taobao.org/babel-core/download/babel-core-6.25.0.tgz#7dd42b0463c742e9d5296deb3ec67a9322dad729"
@@ -1096,6 +1110,16 @@ camelcase@^3.0.0:
   version "3.0.0"
   resolved "http://registry.npm.taobao.org/camelcase/download/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a"
 
+camelcase@^4.1.0:
+  version "4.1.0"
+  resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd"
+
+can-promise@^0.0.1:
+  version "0.0.1"
+  resolved "https://registry.yarnpkg.com/can-promise/-/can-promise-0.0.1.tgz#7a7597ad801fb14c8b22341dfec314b6bd6ad8d3"
+  dependencies:
+    window-or-global "^1.0.1"
+
 caniuse-api@^1.5.2:
   version "1.6.1"
   resolved "http://registry.npm.taobao.org/caniuse-api/download/caniuse-api-1.6.1.tgz#b534e7c734c4f81ec5fbe8aca2ad24354b962c6c"
@@ -1142,6 +1166,14 @@ chalk@^2.0.1:
     escape-string-regexp "^1.0.5"
     supports-color "^4.0.0"
 
+chalk@^2.3.2:
+  version "2.4.0"
+  resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.0.tgz#a060a297a6b57e15b61ca63ce84995daa0fe6e52"
+  dependencies:
+    ansi-styles "^3.2.1"
+    escape-string-regexp "^1.0.5"
+    supports-color "^5.3.0"
+
 chokidar@^1.4.3, chokidar@^1.6.1:
   version "1.7.0"
   resolved "http://registry.npm.taobao.org/chokidar/download/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468"
@@ -1190,6 +1222,14 @@ cli-width@^2.0.0:
   version "2.1.0"
   resolved "http://registry.npm.taobao.org/cli-width/download/cli-width-2.1.0.tgz#b234ca209b29ef66fc518d9b98d5847b00edf00a"
 
+clipboard@^1.7.1:
+  version "1.7.1"
+  resolved "https://registry.yarnpkg.com/clipboard/-/clipboard-1.7.1.tgz#360d6d6946e99a7a1fef395e42ba92b5e9b5a16b"
+  dependencies:
+    good-listener "^1.2.2"
+    select "^1.1.2"
+    tiny-emitter "^2.0.0"
+
 cliui@^2.1.0:
   version "2.1.0"
   resolved "http://registry.npm.taobao.org/cliui/download/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1"
@@ -1239,6 +1279,12 @@ color-convert@^1.0.0, color-convert@^1.3.0:
   dependencies:
     color-name "^1.1.1"
 
+color-convert@^1.9.0:
+  version "1.9.1"
+  resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.1.tgz#c1261107aeb2f294ebffec9ed9ecad529a6097ed"
+  dependencies:
+    color-name "^1.1.1"
+
 color-name@^1.0.0, color-name@^1.1.1:
   version "1.1.2"
   resolved "http://registry.npm.taobao.org/color-name/download/color-name-1.1.2.tgz#5c8ab72b64bd2215d617ae9559ebb148475cf98d"
@@ -1431,7 +1477,7 @@ cross-spawn@^3.0.0:
     lru-cache "^4.0.1"
     which "^1.2.9"
 
-cross-spawn@^5.1.0:
+cross-spawn@^5.0.1, cross-spawn@^5.1.0:
   version "5.1.0"
   resolved "http://registry.npm.taobao.org/cross-spawn/download/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449"
   dependencies:
@@ -1483,6 +1529,25 @@ css-loader@^0.28.0:
     postcss-value-parser "^3.3.0"
     source-list-map "^0.1.7"
 
+css-loader@^0.28.7:
+  version "0.28.11"
+  resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-0.28.11.tgz#c3f9864a700be2711bb5a2462b2389b1a392dab7"
+  dependencies:
+    babel-code-frame "^6.26.0"
+    css-selector-tokenizer "^0.7.0"
+    cssnano "^3.10.0"
+    icss-utils "^2.1.0"
+    loader-utils "^1.0.2"
+    lodash.camelcase "^4.3.0"
+    object-assign "^4.1.1"
+    postcss "^5.0.6"
+    postcss-modules-extract-imports "^1.2.0"
+    postcss-modules-local-by-default "^1.2.0"
+    postcss-modules-scope "^1.1.0"
+    postcss-modules-values "^1.3.0"
+    postcss-value-parser "^3.3.0"
+    source-list-map "^2.0.0"
+
 css-select@^1.1.0:
   version "1.2.0"
   resolved "http://registry.npm.taobao.org/css-select/download/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858"
@@ -1508,7 +1573,7 @@ cssesc@^0.1.0:
   version "0.1.0"
   resolved "http://registry.npm.taobao.org/cssesc/download/cssesc-0.1.0.tgz#c814903e45623371a0477b40109aaafbeeaddbb4"
 
-"cssnano@>=2.6.1 <4":
+"cssnano@>=2.6.1 <4", cssnano@^3.10.0:
   version "3.10.0"
   resolved "http://registry.npm.taobao.org/cssnano/download/cssnano-3.10.0.tgz#4f38f6cea2b9b17fa01490f23f1dc68ea65c1c38"
   dependencies:
@@ -1633,6 +1698,10 @@ delayed-stream@~1.0.0:
   version "1.0.0"
   resolved "http://registry.npm.taobao.org/delayed-stream/download/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
 
+delegate@^3.1.2:
+  version "3.2.0"
+  resolved "https://registry.yarnpkg.com/delegate/-/delegate-3.2.0.tgz#b66b71c3158522e8ab5744f720d8ca0c2af59166"
+
 delegates@^1.0.0:
   version "1.0.0"
   resolved "http://registry.npm.taobao.org/delegates/download/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a"
@@ -1666,6 +1735,10 @@ diffie-hellman@^5.0.0:
     miller-rabin "^4.0.0"
     randombytes "^2.0.0"
 
+dijkstrajs@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/dijkstrajs/-/dijkstrajs-1.0.1.tgz#d3cd81221e3ea40742cfcde556d4e99e98ddc71b"
+
 doctrine@^2.0.0:
   version "2.0.0"
   resolved "http://registry.npm.taobao.org/doctrine/download/doctrine-2.0.0.tgz#c73d8d2909d22291e1a007a395804da8b665fe63"
@@ -2019,6 +2092,18 @@ evp_bytestokey@^1.0.0:
   dependencies:
     create-hash "^1.1.1"
 
+execa@^0.7.0:
+  version "0.7.0"
+  resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777"
+  dependencies:
+    cross-spawn "^5.0.1"
+    get-stream "^3.0.0"
+    is-stream "^1.1.0"
+    npm-run-path "^2.0.0"
+    p-finally "^1.0.0"
+    signal-exit "^3.0.0"
+    strip-eof "^1.0.0"
+
 exit-hook@^1.0.0:
   version "1.1.1"
   resolved "http://registry.npm.taobao.org/exit-hook/download/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8"
@@ -2163,9 +2248,9 @@ find-up@^1.0.0:
     path-exists "^2.0.0"
     pinkie-promise "^2.0.0"
 
-find-up@^2.1.0:
+find-up@^2.0.0, find-up@^2.1.0:
   version "2.1.0"
-  resolved "http://registry.npm.taobao.org/find-up/download/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7"
+  resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7"
   dependencies:
     locate-path "^2.0.0"
 
@@ -2324,6 +2409,10 @@ get-stdin@^4.0.1:
   version "4.0.1"
   resolved "http://registry.npm.taobao.org/get-stdin/download/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe"
 
+get-stream@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14"
+
 getpass@^0.1.1:
   version "0.1.7"
   resolved "http://registry.npm.taobao.org/getpass/download/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa"
@@ -2377,6 +2466,12 @@ globule@^1.0.0:
     lodash "~4.17.4"
     minimatch "~3.0.2"
 
+good-listener@^1.2.2:
+  version "1.2.2"
+  resolved "https://registry.yarnpkg.com/good-listener/-/good-listener-1.2.2.tgz#d53b30cdf9313dffb7dc9a0d477096aa6d145c50"
+  dependencies:
+    delegate "^3.1.2"
+
 graceful-fs@^4.1.2, graceful-fs@^4.1.4, graceful-fs@^4.1.6:
   version "4.1.11"
   resolved "http://registry.npm.taobao.org/graceful-fs/download/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658"
@@ -2416,6 +2511,10 @@ has-flag@^2.0.0:
   version "2.0.0"
   resolved "http://registry.npm.taobao.org/has-flag/download/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51"
 
+has-flag@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
+
 has-unicode@^2.0.0:
   version "2.0.1"
   resolved "http://registry.npm.taobao.org/has-unicode/download/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9"
@@ -2806,6 +2905,10 @@ is-resolvable@^1.0.0:
   dependencies:
     tryit "^1.0.1"
 
+is-stream@^1.1.0:
+  version "1.1.0"
+  resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
+
 is-svg@^2.0.0:
   version "2.1.0"
   resolved "http://registry.npm.taobao.org/is-svg/download/is-svg-2.1.0.tgz#cf61090da0d9efbcab8722deba6f032208dbb0e9"
@@ -2832,6 +2935,10 @@ isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0:
   version "1.0.0"
   resolved "http://registry.npm.taobao.org/isarray/download/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
 
+isarray@^2.0.1:
+  version "2.0.4"
+  resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.4.tgz#38e7bcbb0f3ba1b7933c86ba1894ddfc3781bbb7"
+
 isexe@^2.0.0:
   version "2.0.0"
   resolved "http://registry.npm.taobao.org/isexe/download/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
@@ -2863,7 +2970,7 @@ js-beautify@^1.6.3:
     mkdirp "~0.5.0"
     nopt "~3.0.1"
 
-js-tokens@^3.0.0:
+js-tokens@^3.0.0, js-tokens@^3.0.2:
   version "3.0.2"
   resolved "http://registry.npm.taobao.org/js-tokens/download/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b"
 
@@ -2993,6 +3100,15 @@ load-json-file@^1.0.0:
     pinkie-promise "^2.0.0"
     strip-bom "^2.0.0"
 
+load-json-file@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8"
+  dependencies:
+    graceful-fs "^4.1.2"
+    parse-json "^2.2.0"
+    pify "^2.0.0"
+    strip-bom "^3.0.0"
+
 loader-fs-cache@^1.0.0:
   version "1.0.1"
   resolved "http://registry.npm.taobao.org/loader-fs-cache/download/loader-fs-cache-1.0.1.tgz#56e0bf08bd9708b26a765b68509840c8dec9fdbc"
@@ -3115,6 +3231,13 @@ lru-cache@^4.0.1, lru-cache@^4.0.2:
     pseudomap "^1.0.2"
     yallist "^2.1.2"
 
+lru-cache@^4.1.1:
+  version "4.1.2"
+  resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.2.tgz#45234b2e6e2f2b33da125624c4664929a0224c3f"
+  dependencies:
+    pseudomap "^1.0.2"
+    yallist "^2.1.2"
+
 macaddress@^0.2.8:
   version "0.2.8"
   resolved "http://registry.npm.taobao.org/macaddress/download/macaddress-0.2.8.tgz#5904dc537c39ec6dbefeae902327135fa8511f12"
@@ -3137,6 +3260,12 @@ media-typer@0.3.0:
   version "0.3.0"
   resolved "http://registry.npm.taobao.org/media-typer/download/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
 
+mem@^1.1.0:
+  version "1.1.0"
+  resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76"
+  dependencies:
+    mimic-fn "^1.0.0"
+
 memory-fs@^0.4.0, memory-fs@^0.4.1, memory-fs@~0.4.1:
   version "0.4.1"
   resolved "http://registry.npm.taobao.org/memory-fs/download/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552"
@@ -3214,6 +3343,10 @@ mime@1.3.x, mime@^1.3.4:
   version "1.3.6"
   resolved "http://registry.npm.taobao.org/mime/download/mime-1.3.6.tgz#591d84d3653a6b0b4a3b9df8de5aa8108e72e5e0"
 
+mimic-fn@^1.0.0:
+  version "1.2.0"
+  resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022"
+
 minimalistic-assert@^1.0.0:
   version "1.0.0"
   resolved "http://registry.npm.taobao.org/minimalistic-assert/download/minimalistic-assert-1.0.0.tgz#702be2dda6b37f4836bcb3f5db56641b64a1d3d3"
@@ -3405,6 +3538,12 @@ normalize-url@^1.4.0:
     query-string "^4.1.0"
     sort-keys "^1.0.0"
 
+npm-run-path@^2.0.0:
+  version "2.0.2"
+  resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f"
+  dependencies:
+    path-key "^2.0.0"
+
 "npmlog@0 || 1 || 2 || 3 || 4", npmlog@^4.0.0, npmlog@^4.0.2:
   version "4.1.2"
   resolved "http://registry.npm.taobao.org/npmlog/download/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b"
@@ -3566,6 +3705,14 @@ os-locale@^1.4.0:
   dependencies:
     lcid "^1.0.0"
 
+os-locale@^2.0.0:
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.1.0.tgz#42bc2900a6b5b8bd17376c8e882b65afccf24bf2"
+  dependencies:
+    execa "^0.7.0"
+    lcid "^1.0.0"
+    mem "^1.1.0"
+
 os-tmpdir@^1.0.0, os-tmpdir@^1.0.1:
   version "1.0.2"
   resolved "http://registry.npm.taobao.org/os-tmpdir/download/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
@@ -3585,6 +3732,10 @@ output-file-sync@^1.1.0:
     mkdirp "^0.5.1"
     object-assign "^4.1.0"
 
+p-finally@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae"
+
 p-limit@^1.1.0:
   version "1.1.0"
   resolved "http://registry.npm.taobao.org/p-limit/download/p-limit-1.1.0.tgz#b07ff2d9a5d88bec806035895a2bab66a27988bc"
@@ -3656,6 +3807,10 @@ path-is-inside@^1.0.1:
   version "1.0.2"
   resolved "http://registry.npm.taobao.org/path-is-inside/download/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53"
 
+path-key@^2.0.0:
+  version "2.0.1"
+  resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40"
+
 path-parse@^1.0.5:
   version "1.0.5"
   resolved "http://registry.npm.taobao.org/path-parse/download/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1"
@@ -3672,6 +3827,12 @@ path-type@^1.0.0:
     pify "^2.0.0"
     pinkie-promise "^2.0.0"
 
+path-type@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73"
+  dependencies:
+    pify "^2.0.0"
+
 pbkdf2@^3.0.3:
   version "3.0.12"
   resolved "http://registry.npm.taobao.org/pbkdf2/download/pbkdf2-3.0.12.tgz#be36785c5067ea48d806ff923288c5f750b6b8a2"
@@ -3720,6 +3881,10 @@ pluralize@^1.2.1:
   version "1.2.1"
   resolved "http://registry.npm.taobao.org/pluralize/download/pluralize-1.2.1.tgz#d1a21483fd22bb41e58a12fa3421823140897c45"
 
+pngjs@^3.3.0:
+  version "3.3.3"
+  resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-3.3.3.tgz#85173703bde3edac8998757b96e5821d0966a21b"
+
 post-compile-webpack-plugin@^0.1.1:
   version "0.1.1"
   resolved "http://registry.npm.taobao.org/post-compile-webpack-plugin/download/post-compile-webpack-plugin-0.1.1.tgz#1b1a0eea890ce748556ca49e066a48c900e0b370"
@@ -3869,27 +4034,27 @@ postcss-minify-selectors@^2.0.4:
     postcss "^5.0.14"
     postcss-selector-parser "^2.0.0"
 
-postcss-modules-extract-imports@^1.0.0:
+postcss-modules-extract-imports@^1.0.0, postcss-modules-extract-imports@^1.2.0:
   version "1.2.0"
   resolved "http://registry.npm.taobao.org/postcss-modules-extract-imports/download/postcss-modules-extract-imports-1.2.0.tgz#66140ecece38ef06bf0d3e355d69bf59d141ea85"
   dependencies:
     postcss "^6.0.1"
 
-postcss-modules-local-by-default@^1.0.1:
+postcss-modules-local-by-default@^1.0.1, postcss-modules-local-by-default@^1.2.0:
   version "1.2.0"
   resolved "http://registry.npm.taobao.org/postcss-modules-local-by-default/download/postcss-modules-local-by-default-1.2.0.tgz#f7d80c398c5a393fa7964466bd19500a7d61c069"
   dependencies:
     css-selector-tokenizer "^0.7.0"
     postcss "^6.0.1"
 
-postcss-modules-scope@^1.0.0:
+postcss-modules-scope@^1.0.0, postcss-modules-scope@^1.1.0:
   version "1.1.0"
   resolved "http://registry.npm.taobao.org/postcss-modules-scope/download/postcss-modules-scope-1.1.0.tgz#d6ea64994c79f97b62a72b426fbe6056a194bb90"
   dependencies:
     css-selector-tokenizer "^0.7.0"
     postcss "^6.0.1"
 
-postcss-modules-values@^1.1.0:
+postcss-modules-values@^1.1.0, postcss-modules-values@^1.3.0:
   version "1.3.0"
   resolved "http://registry.npm.taobao.org/postcss-modules-values/download/postcss-modules-values-1.3.0.tgz#ecffa9d7e192518389f42ad0e83f72aec456ea20"
   dependencies:
@@ -3993,6 +4158,14 @@ postcss@^6.0.1:
     source-map "^0.5.6"
     supports-color "^4.1.0"
 
+postcss@^6.0.8:
+  version "6.0.21"
+  resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.21.tgz#8265662694eddf9e9a5960db6da33c39e4cd069d"
+  dependencies:
+    chalk "^2.3.2"
+    source-map "^0.6.1"
+    supports-color "^5.3.0"
+
 preload-webpack-plugin@^1.2.2:
   version "1.2.2"
   resolved "http://registry.npm.taobao.org/preload-webpack-plugin/download/preload-webpack-plugin-1.2.2.tgz#d1b6f0eab3c2d0bb4c249d409cf6b7a8b0a415dd"
@@ -4011,6 +4184,10 @@ preserve@^0.2.0:
   version "0.2.0"
   resolved "http://registry.npm.taobao.org/preserve/download/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b"
 
+prettier@^1.7.0:
+  version "1.12.1"
+  resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.12.1.tgz#c1ad20e803e7749faf905a409d2367e06bbe7325"
+
 pretty-error@^2.0.2:
   version "2.1.1"
   resolved "http://registry.npm.taobao.org/pretty-error/download/pretty-error-2.1.1.tgz#5f4f87c8f91e5ae3f3ba87ab4cf5e03b1a17f1a3"
@@ -4083,6 +4260,16 @@ q@^1.1.2:
   version "1.5.0"
   resolved "http://registry.npm.taobao.org/q/download/q-1.5.0.tgz#dd01bac9d06d30e6f219aecb8253ee9ebdc308f1"
 
+qrcode@^1.2.0:
+  version "1.2.0"
+  resolved "https://registry.yarnpkg.com/qrcode/-/qrcode-1.2.0.tgz#330d24313fbf8d429a806091af9525250239e44a"
+  dependencies:
+    can-promise "^0.0.1"
+    dijkstrajs "^1.0.1"
+    isarray "^2.0.1"
+    pngjs "^3.3.0"
+    yargs "^8.0.2"
+
 qs@6.4.0, qs@~6.4.0:
   version "6.4.0"
   resolved "http://registry.npm.taobao.org/qs/download/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233"
@@ -4135,6 +4322,13 @@ read-pkg-up@^1.0.1:
     find-up "^1.0.0"
     read-pkg "^1.0.0"
 
+read-pkg-up@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be"
+  dependencies:
+    find-up "^2.0.0"
+    read-pkg "^2.0.0"
+
 read-pkg@^1.0.0:
   version "1.1.0"
   resolved "http://registry.npm.taobao.org/read-pkg/download/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28"
@@ -4143,6 +4337,14 @@ read-pkg@^1.0.0:
     normalize-package-data "^2.3.2"
     path-type "^1.0.0"
 
+read-pkg@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8"
+  dependencies:
+    load-json-file "^2.0.0"
+    normalize-package-data "^2.3.2"
+    path-type "^2.0.0"
+
 readable-stream@1.0:
   version "1.0.34"
   resolved "http://registry.npm.taobao.org/readable-stream/download/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c"
@@ -4349,6 +4551,12 @@ resolve@^1.1.6, resolve@^1.2.0:
   dependencies:
     path-parse "^1.0.5"
 
+resolve@^1.4.0:
+  version "1.7.1"
+  resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.7.1.tgz#aadd656374fd298aee895bc026b8297418677fd3"
+  dependencies:
+    path-parse "^1.0.5"
+
 restore-cursor@^1.0.1:
   version "1.0.1"
   resolved "http://registry.npm.taobao.org/restore-cursor/download/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541"
@@ -4429,6 +4637,10 @@ scss-tokenizer@^0.2.3:
     js-base64 "^2.1.8"
     source-map "^0.4.2"
 
+select@^1.1.2:
+  version "1.1.2"
+  resolved "https://registry.yarnpkg.com/select/-/select-1.1.2.tgz#0e7350acdec80b1108528786ec1d4418d11b396d"
+
 "semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@~5.3.0:
   version "5.3.0"
   resolved "http://registry.npm.taobao.org/semver/download/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f"
@@ -4565,6 +4777,10 @@ source-map@^0.4.2:
   dependencies:
     amdefine ">=0.0.4"
 
+source-map@^0.6.1:
+  version "0.6.1"
+  resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
+
 spdx-correct@~1.0.0:
   version "1.0.2"
   resolved "http://registry.npm.taobao.org/spdx-correct/download/spdx-correct-1.0.2.tgz#4b3073d933ff51f3912f03ac5519498a4150db40"
@@ -4689,6 +4905,10 @@ strip-bom@^3.0.0:
   version "3.0.0"
   resolved "http://registry.npm.taobao.org/strip-bom/download/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3"
 
+strip-eof@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf"
+
 strip-indent@^1.0.1:
   version "1.0.1"
   resolved "http://registry.npm.taobao.org/strip-indent/download/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2"
@@ -4715,6 +4935,12 @@ supports-color@^4.0.0, supports-color@^4.1.0:
   dependencies:
     has-flag "^2.0.0"
 
+supports-color@^5.3.0:
+  version "5.4.0"
+  resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.4.0.tgz#1c6b337402c2137605efe19f10fec390f6faab54"
+  dependencies:
+    has-flag "^3.0.0"
+
 svgo@^0.7.0:
   version "0.7.2"
   resolved "http://registry.npm.taobao.org/svgo/download/svgo-0.7.2.tgz#9f5772413952135c6fefbf40afe6a4faa88b4bb5"
@@ -4785,6 +5011,10 @@ timers-browserify@^2.0.2:
   dependencies:
     setimmediate "^1.0.4"
 
+tiny-emitter@^2.0.0:
+  version "2.0.2"
+  resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.0.2.tgz#82d27468aca5ade8e5fd1e6d22b57dd43ebdfb7c"
+
 to-arraybuffer@^1.0.0:
   version "1.0.1"
   resolved "http://registry.npm.taobao.org/to-arraybuffer/download/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43"
@@ -4989,6 +5219,10 @@ vue-hot-reload-api@^2.0.11:
   version "2.1.0"
   resolved "http://registry.npm.taobao.org/vue-hot-reload-api/download/vue-hot-reload-api-2.1.0.tgz#9ca58a6e0df9078554ce1708688b6578754d86de"
 
+vue-hot-reload-api@^2.2.0:
+  version "2.3.0"
+  resolved "https://registry.yarnpkg.com/vue-hot-reload-api/-/vue-hot-reload-api-2.3.0.tgz#97976142405d13d8efae154749e88c4e358cf926"
+
 vue-loader@^11.3.4:
   version "11.3.4"
   resolved "http://registry.npm.taobao.org/vue-loader/download/vue-loader-11.3.4.tgz#65e10a44ce092d906e14bbc72981dec99eb090d2"
@@ -5006,6 +5240,24 @@ vue-loader@^11.3.4:
     vue-style-loader "^2.0.0"
     vue-template-es2015-compiler "^1.2.2"
 
+vue-loader@^13.3.0:
+  version "13.7.1"
+  resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-13.7.1.tgz#d9009d0abd392b4efe8b8fb1f542f6723b02dd3a"
+  dependencies:
+    consolidate "^0.14.0"
+    hash-sum "^1.0.2"
+    loader-utils "^1.1.0"
+    lru-cache "^4.1.1"
+    postcss "^6.0.8"
+    postcss-load-config "^1.1.0"
+    postcss-selector-parser "^2.0.0"
+    prettier "^1.7.0"
+    resolve "^1.4.0"
+    source-map "^0.6.1"
+    vue-hot-reload-api "^2.2.0"
+    vue-style-loader "^3.0.0"
+    vue-template-es2015-compiler "^1.6.0"
+
 vue-meta@^0.5.6:
   version "0.5.6"
   resolved "http://registry.npm.taobao.org/vue-meta/download/vue-meta-0.5.6.tgz#e4b56838167f0aa40a202f45e1eec6fb91861689"
@@ -5051,6 +5303,13 @@ vue-style-loader@^2.0.0:
     hash-sum "^1.0.2"
     loader-utils "^1.0.2"
 
+vue-style-loader@^3.0.0:
+  version "3.1.2"
+  resolved "https://registry.yarnpkg.com/vue-style-loader/-/vue-style-loader-3.1.2.tgz#6b66ad34998fc9520c2f1e4d5fa4091641c1597a"
+  dependencies:
+    hash-sum "^1.0.2"
+    loader-utils "^1.0.2"
+
 vue-template-compiler@^2.2.6:
   version "2.4.1"
   resolved "http://registry.npm.taobao.org/vue-template-compiler/download/vue-template-compiler-2.4.1.tgz#20115cf8714f222f9be4111ec75b079a1c9b8197"
@@ -5062,6 +5321,10 @@ vue-template-es2015-compiler@^1.2.2:
   version "1.5.3"
   resolved "http://registry.npm.taobao.org/vue-template-es2015-compiler/download/vue-template-es2015-compiler-1.5.3.tgz#22787de4e37ebd9339b74223bc467d1adee30545"
 
+vue-template-es2015-compiler@^1.6.0:
+  version "1.6.0"
+  resolved "https://registry.yarnpkg.com/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.6.0.tgz#dc42697133302ce3017524356a6c61b7b69b4a18"
+
 vue2-filters@^0.1.9:
   version "0.1.9"
   resolved "http://registry.npm.taobao.org/vue2-filters/download/vue2-filters-0.1.9.tgz#3fc9e78e5744efff03223cff0e395907bb6b41ed"
@@ -5157,6 +5420,10 @@ which-module@^1.0.0:
   version "1.0.0"
   resolved "http://registry.npm.taobao.org/which-module/download/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f"
 
+which-module@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a"
+
 which@1, which@^1.2.9:
   version "1.2.14"
   resolved "http://registry.npm.taobao.org/which/download/which-1.2.14.tgz#9a87c4378f03e827cecaf1acdf56c736c01c14e5"
@@ -5169,6 +5436,10 @@ wide-align@^1.1.0:
   dependencies:
     string-width "^1.0.2"
 
+window-or-global@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/window-or-global/-/window-or-global-1.0.1.tgz#dbe45ba2a291aabc56d62cf66c45b7fa322946de"
+
 window-size@0.1.0:
   version "0.1.0"
   resolved "http://registry.npm.taobao.org/window-size/download/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d"
@@ -5233,6 +5504,12 @@ yargs-parser@^5.0.0:
   dependencies:
     camelcase "^3.0.0"
 
+yargs-parser@^7.0.0:
+  version "7.0.0"
+  resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-7.0.0.tgz#8d0ac42f16ea55debd332caf4c4038b3e3f5dfd9"
+  dependencies:
+    camelcase "^4.1.0"
+
 yargs@^6.0.0:
   version "6.6.0"
   resolved "http://registry.npm.taobao.org/yargs/download/yargs-6.6.0.tgz#782ec21ef403345f830a808ca3d513af56065208"
@@ -5269,6 +5546,24 @@ yargs@^7.0.0:
     y18n "^3.2.1"
     yargs-parser "^5.0.0"
 
+yargs@^8.0.2:
+  version "8.0.2"
+  resolved "https://registry.yarnpkg.com/yargs/-/yargs-8.0.2.tgz#6299a9055b1cefc969ff7e79c1d918dceb22c360"
+  dependencies:
+    camelcase "^4.1.0"
+    cliui "^3.2.0"
+    decamelize "^1.1.1"
+    get-caller-file "^1.0.1"
+    os-locale "^2.0.0"
+    read-pkg-up "^2.0.0"
+    require-directory "^2.1.1"
+    require-main-filename "^1.0.1"
+    set-blocking "^2.0.0"
+    string-width "^2.0.0"
+    which-module "^2.0.0"
+    y18n "^3.2.1"
+    yargs-parser "^7.0.0"
+
 yargs@~3.10.0:
   version "3.10.0"
   resolved "http://registry.npm.taobao.org/yargs/download/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1"