Browse Source

订单确认页

yangc 7 years ago
parent
commit
12958c856b

+ 4 - 1
assets/scss/mobileCommon.scss

@@ -252,7 +252,7 @@ html {
     }
     &.mobile-link-en {
       top: 50%;
-      margin-top: -1.34rem;
+      margin-top: -2.14rem;
     }
   }
   .mobile-share-box {
@@ -320,6 +320,9 @@ html {
   padding-top: .88rem !important;
   margin-bottom: 1rem;
 }
+.mobile-content-long {
+  padding-top: 1.26rem !important;
+}
 
 /*求购title*/
 .seek-title {

+ 3 - 0
components/mobile/MobileHeader.vue

@@ -199,6 +199,9 @@
         } else if (val === '/mobile/center/user/cart') {
           this.showSearchIcon = false
           title = '购物车'
+        } else if (this.startWith(val, '/mobile/center/user/pay')) {
+          this.showSearchIcon = false
+          title = '填写订单'
         } else {
           this.showSearchIcon = true
           title = '优软商城'

+ 59 - 0
components/mobile/base/LinkUser.vue

@@ -0,0 +1,59 @@
+<template>
+  <div class="mobile-modal" v-if="showLink">
+    <div class="mobile-modal-box mobile-link-en">
+      <div class="mobile-modal-header">联系方式<i @click="$emit('closeAction')" class="icon-guanbi iconfont"></i></div>
+      <div class="mobile-modal-content">
+        <div v-if="checkTel" class="clearfix"><span class="pull-left">电话:</span><a :href="'tel:' + infoObj.enTel" target="_blank" class="content-line link-url pull-left">{{infoObj.enTel}}</a></div>
+        <div v-if="checkPhone" class="clearfix"><span class="pull-left">手机:</span><a :href="'tel:' + infoObj.enPhone" target="_blank" class="content-line link-url pull-left">{{infoObj.enPhone}}</a></div>
+        <div v-if="checkWeixin" class="clearfix"><span class="pull-left">微信:</span><span class="content-line pull-left">{{infoObj.enWeixin}}</span></div>
+        <div v-if="checkQQ" class="clearfix"><span class="pull-left">Q&nbsp;Q:</span><span class="content-line pull-left">{{infoObj.enQQ}}</span></div>
+        <div v-if="!empty">暂无联系方式</div>
+      </div>
+    </div>
+  </div>
+</template>
+<script>
+  export default {
+    props: {
+      showLink: {
+        type: Boolean,
+        default: false
+      },
+      infoObj: {
+        type: Object,
+        default: () => {
+          return {}
+        }
+      }
+    },
+    computed: {
+      checkTel () {
+        return this.checkInfo(this.infoObj.enTel)
+      },
+      checkPhone () {
+        return this.checkInfo(this.infoObj.enPhone)
+      },
+      checkWeixin () {
+        return this.checkInfo(this.infoObj.enWeixin)
+      },
+      checkQQ () {
+        return this.checkInfo(this.infoObj.enQQ)
+      },
+      empty () {
+        return this.checkTel || this.checkPhone || this.checkWeixin || this.checkQQ
+      }
+    },
+    methods: {
+      checkInfo: function (str) {
+        return str && str.trim() !== ''
+      }
+    }
+  }
+</script>
+<style lang="scss" scoped>
+  .mobile-modal .mobile-modal-box .mobile-modal-content {
+    .clearfix {
+      padding-left: 1rem;
+    }
+  }
+</style>

+ 2 - 1
components/mobile/base/index.js

@@ -1,4 +1,5 @@
 import SearchHeader from './SearchHeader.vue'
 import SearchHeader2 from './SearchHeader2.vue'
+import LinkUser from './LinkUser.vue'
 
-export { SearchHeader, SearchHeader2 }
+export { SearchHeader, SearchHeader2, LinkUser }

+ 103 - 19
pages/mobile/center/user/cart.vue

@@ -6,8 +6,9 @@
           <label class="mobile-cart-check" :class="{'active': item.$active}">
             <input type="checkbox" @change="setActive('store', storeIndex)">
           </label>
-          <span class="store-tag inline-block">{{baseUtils.storeTypeFilter(item.storeType)}}</span>
+          <span class="store-tag inline-block">{{item.storeType | storeTypeFilter}}</span>
           <p class="store-name inline-block text-ellipse">{{item.storeName}}</p>
+          <a class="link" @click="linkSaler(item)"><i class="iconfont icon-kefu1"></i>联系卖家</a>
         </div>
         <ul class="goods-list">
           <li class="goods-item" v-for="(goods, goodsIndex) in item.goods">
@@ -28,7 +29,7 @@
                 <span class="inline-block" @click="setGoods('add', goods)">+</span>
               </div>
               <div class="price-line">
-                <span>{{goods.currencyName === 'RMB' ? '¥' : '$'}}</span>{{goods.goods.currentPrice}}
+                <span>{{goods.currencyName | currencyFilter}}</span>{{goods.goods.currentPrice}}
               </div>
             </div>
           </li>
@@ -42,16 +43,20 @@
       </label>
       <div class="fr">
         <i class="fare">不含运费</i>
-        <span class="title">合计:</span><span class="price"><span</span>{{allPrice}}</span>
+        <span class="title">合计:</span><span class="price"><span v-show="allCount > 0">{{allCurrency | currencyFilter}}</span>{{allPrice}}</span>
         <button class="buy-btn" @click="submit">结算({{allCount}})</button>
       </div>
     </div>
     <remind-box :title="remindText" :timeoutCount="timeoutCount"></remind-box>
     <pull-up :fixId="'mobileFixContent'" :searchMore="fetching" :allPage="allPage" :page="page" @pullUpAction="onPullUpAction"></pull-up>
+    <link-user :infoObj="currentStoreInfo"
+               :showLink="showLink"
+               @closeAction="showLink = false"></link-user>
   </div>
 </template>
 <script>
   import {RemindBox, PullUp} from '~components/mobile/common'
+  import {LinkUser} from '~components/mobile/base'
   export default {
     layout: 'mobile',
     middleware: 'authenticated',
@@ -62,12 +67,16 @@
         timeoutCount: '',
         isAllChecked: false,
         page: 1,
-        count: 10
+        count: 10,
+        allCurrency: 'RMB', // 选定币别
+        currentStoreInfo: {},
+        showLink: false
       }
     },
     components: {
       RemindBox,
-      PullUp
+      PullUp,
+      LinkUser
     },
     fetch ({ store }) {
       return Promise.all([
@@ -78,6 +87,7 @@
       '$store.state.userCenter.list.cart.data': {
         handler: function (val) {
           let tmpVal = this.baseUtils.deepCopy(val)
+//          this.cartList = []
           tmpVal.content.forEach(item => {
             let current = this.cartList.find(objItem => {
               return objItem.storeUuid === item.storeUuid
@@ -106,6 +116,7 @@
                 storeName: item.storeName,
                 storeType: item.storeType,
                 storeUuid: item.storeUuid,
+                enterprise: item.storeEnterprise.enterpriseInfo,
                 goods: [item],
                 $active: false
               })
@@ -113,6 +124,7 @@
               current.goods.push(item)
             }
           })
+          this.checkAll()
         },
         immediate: true
       }
@@ -127,6 +139,7 @@
       allPage () {
         return this.cartData.totalPages
       },
+      // 已选goods
       allActiveObj () {
         let arr = []
         this.cartList.forEach(item => {
@@ -138,6 +151,7 @@
         })
         return arr
       },
+      // 统计价格
       allPrice () {
         let price = 0
         this.allActiveObj.forEach(item => {
@@ -145,6 +159,7 @@
         })
         return price
       },
+      // 统计数量
       allCount () {
         return this.allActiveObj.length
       }
@@ -154,19 +169,36 @@
         this.remindText = str
         this.timeoutCount++
       },
-      setActive: function (type, storeIndex, goodsIndex) {
+      checkCurrency: function (currency, callback) {
+        if (currency === this.allCurrency) {
+          callback.call()
+        } else {
+          this.setRemindText('所选产品币别与已选产品不是同一币别')
+        }
+      },
+      setActive (type, storeIndex, goodsIndex, goodsCheckFlag) {
         if (type === 'store') {
-          this.cartList[storeIndex].goods.forEach(item => {
-            item.$active = !this.cartList[storeIndex].$active
-          })
-          this.cartList[storeIndex].$active = !this.cartList[storeIndex].$active
+          let storeActive = this.cartList[storeIndex].$active
+          for (let i = 0; i < this.cartList[storeIndex].goods.length; i++) {
+            this.setActive('goods', storeIndex, i, !storeActive)
+          }
+//          this.cartList[storeIndex].goods.forEach(item => {
+//            this.checkCurrency(item.goods.currencyName, () => {
+//              item.$active = !this.cartList[storeIndex].$active
+//            })
+//          })
           this.checkAll()
         } else if (type === 'goods') {
-          this.cartList[storeIndex].goods[goodsIndex].$active = !this.cartList[storeIndex].goods[goodsIndex].$active
-          this.cartList[storeIndex].$active = !this.cartList[storeIndex].goods.find(item => {
-            return !item.$active
+          if (!this.allActiveObj[0]) {
+            this.allCurrency = this.cartList[storeIndex].goods[goodsIndex].currencyName
+          }
+          this.checkCurrency(this.cartList[storeIndex].goods[goodsIndex].currencyName, () => {
+            this.cartList[storeIndex].goods[goodsIndex].$active = typeof goodsCheckFlag === 'undefined' ? !this.cartList[storeIndex].goods[goodsIndex].$active : goodsCheckFlag
+//            this.cartList[storeIndex].$active = !this.cartList[storeIndex].goods.find(item => {
+//              return !item.$active
+//            })
+            this.checkAll()
           })
-          this.checkAll()
         } else if (type === 'all') {
           let activeFlag = true
           this.cartList.forEach(item => {
@@ -180,18 +212,21 @@
             this.cartList[i].$active = activeFlag
             this.setActive('store', i)
           }
-          this.isAllChecked = !activeFlag
+          this.checkAll()
         }
       },
       // 总勾选校验
       checkAll: function () {
         let activeFlag = true
         this.cartList.forEach(item => {
+          let itemActive = true
           item.goods.forEach(goodsItem => {
             if (!goodsItem.$active) {
               activeFlag = false
+              itemActive = false
             }
           })
+          item.$active = itemActive
         })
         this.isAllChecked = activeFlag
       },
@@ -285,8 +320,8 @@
         }
       },
       onPullUpAction: function () {
-//        this.page++
-//        this.reloadList()
+        this.page++
+        this.reloadList()
       },
       reloadList: function () {
         this.$store.dispatch('userCenter/loadCartList', {page: this.page, count: this.count})
@@ -296,6 +331,43 @@
           this.setRemindText('请勾选要生成订单的批次')
           return
         }
+        let arrOD = []
+        this.allActiveObj.forEach(item => {
+          arrOD.push({
+            batchCode: item.goods.batchCode,
+            minPackQty: item.goods.minPackQty,
+            number: item.goods.purchaseNumber,
+            storeid: item.storeUuid
+          })
+        })
+        console.log(arrOD)
+        this.$http.post('/trade/order/saveByGroup', {
+          arrOD: arrOD,
+          currency: this.allCurrency
+        }).then(res => {
+          console.log(res.data)
+          if (res.data.code === 1) {
+            if (res.data.message) {
+              this.setRemindText(res.data.message)
+            }
+            this.$router.push(`/mobile/center/user/pay/${this.baseUtils.enidfilter(res.data.data.orderid)}`)
+          } else if (res.data.code === 7) {
+            this.setRemindText('选中的购物车信息已经失效,将为您刷新界面之后重新操作')
+            setTimeout(() => {
+              this.page = 1
+              this.reloadList()
+            }, 1500)
+          } else {
+            this.setRemindText(res.data.message)
+          }
+        }, err => {
+          console.log(err.response.data.data || '系统错误')
+          this.setRemindText(err.response.data.data || '系统错误')
+        })
+      },
+      linkSaler (item) {
+        this.currentStoreInfo = item.enterprise
+        this.showLink = true
       }
     }
   }
@@ -304,10 +376,10 @@
   .mobile-cart {
     bottom: 2rem;
     .store-list {
-      margin: .19rem 0;
-      background: #fff;
       .store-item {
         padding: 0 .25rem;
+        background: #fff;
+        margin: .19rem 0;
         .store-info {
           height: .9rem;
           line-height: .9rem;
@@ -327,6 +399,18 @@
             margin-left: .08rem;
             max-width: 5.7rem;
           }
+          .link {
+            float: right;
+            font-size: .26rem;
+            color: #3f84f6;
+            margin-right: .12rem;
+            i {
+              margin-right: .08rem;
+              position: relative;
+              top: .04rem;
+              font-size: .34rem;
+            }
+          }
         }
         .goods-list {
           .goods-item {

+ 276 - 0
pages/mobile/center/user/pay/_orderId.vue

@@ -0,0 +1,276 @@
+<template>
+  <div class="mobile-content mobile-content-long mobile-pay">
+    <div class="pay-head">
+      <p class="info">
+        {{defaultAddress.name}}&nbsp;&nbsp;&nbsp;{{defaultAddress.tel | telHideFilter}}
+      </p>
+      <div class="addr">
+        <i class="iconfont icon-tuxiang-"></i>
+        <span>{{defaultAddress.area + defaultAddress.detailAddress}}</span>
+      </div>
+      <i class="iconfont icon-xiangyou fr"></i>
+    </div>
+    <ul class="pay-store-list">
+      <li class="ps-item" v-for="item in orderData">
+        <p class="ps-store-name">{{item.storeName}}</p>
+        <div class="ps-goods-info clearfix">
+          <div class="fl">
+            <span class="inline-block arrow">
+            <i class="iconfont icon-xiangzuo"></i>
+          </span>
+            <ul class="ps-goods-list">
+              <li class="inline-block" v-for="goods in item.goods">
+                <div class="ps-goods-item text-ellipse"><span>品牌:</span>{{goods.brName || '-'}}</div>
+                <div class="ps-goods-item text-ellipse"><span>类目:</span>{{goods.kiName || '-'}}</div>
+                <div class="ps-goods-item text-ellipse"><span>型号:</span>{{goods.cmpCode || '-'}}</div>
+                <div class="ps-goods-item text-ellipse"><span>规格:</span>{{goods.spec || '-'}}</div>
+              </li>
+            </ul>
+            <span class="inline-block arrow">
+            <i class="iconfont icon-xiangyou"></i>
+          </span>
+          </div>
+          <div class="fr">
+            <p class="price text-ellipse"><span>{{payData.currency | currencyFilter}}</span>{{getTotalPrice(item)}}</p>
+            <p class="count text-ellipse">共{{item.goods.length || 0}}件产品</p>
+          </div>
+        </div>
+        <div class="ps-operate-line">
+          <span class="title">配送方式</span>
+          <div class="fr">
+            <p>第三方配送</p>
+            <span>全场满1000包邮</span>
+            <i class="iconfont icon-xiangyou"></i>
+          </div>
+        </div>
+        <div class="ps-operate-line">
+          <span class="title">订单备注</span>
+          <input type="text" placeholder="选填:填写内容需和卖家协商确认">
+        </div>
+        <div class="ps-operate-line ps-price">
+          <span class="inline-block">
+             运费:<span class="ol-price"><span>$</span>8.99</span>
+          </span>
+          <span class="inline-block">
+             店铺合计:<span class="ol-price"><span>$</span>9999.999999</span>
+          </span>
+        </div>
+      </li>
+    </ul>
+  </div>
+</template>
+<script>
+  export default {
+    layout: 'mobile',
+    middleware: 'authenticated',
+    data () {
+      return {
+        orderData: []
+      }
+    },
+    fetch ({ store, params }) {
+      return Promise.all([
+        store.dispatch('userCenter/loadPayInfo', {enOrderid: params.orderId}),
+        store.dispatch('userCenter/loadAcceptAddress', {send: false}),
+        store.dispatch('userCenter/loadPayInvoice')
+      ])
+    },
+    computed: {
+      payData () {
+        return this.$store.state.userCenter.list.pay.data
+      },
+      addressData () {
+        return this.$store.state.userCenter.list.address.data
+      },
+      invoiceData () {
+        return this.$store.state.userCenter.list.invoice.data
+      },
+      defaultAddress () {
+        return this.addressData.find(item => {
+          return item.num === 1
+        })
+      }
+    },
+    created () {
+      this.initOrderData()
+    },
+    methods: {
+      initOrderData () {
+        this.payData.orderDetails.forEach(item => {
+          let current = this.orderData.find(objItem => {
+            return objItem.storeid === item.storeid
+          })
+          if (!current) {
+            this.orderData.push({
+              storeName: item.storeName,
+              storeid: item.storeid,
+              supEnName: item.supEnName,
+              goods: [item]
+            })
+          } else {
+            current.goods.push(item)
+          }
+        })
+      },
+      getTotalPrice (storeItem) {
+        let price = 0
+        storeItem.goods.forEach(item => {
+          price += item.price * item.number
+        })
+        return Number(price.toFixed(6))
+      }
+    }
+  }
+</script>
+<style lang="scss" scoped>
+  .mobile-pay {
+    .pay-head {
+      height: 1.31rem;
+      padding: .25rem 0 0 .21rem;
+      position: relative;
+      border-bottom: .18rem solid #f1f3f7;
+      background: url('/images/mobile/center/user/addr-border.png') no-repeat;
+      background-size: contain;
+      background-position: bottom;
+      .info {
+        padding-left: .43rem;
+        font-size: .3rem;
+        font-weight: bold;
+      }
+      .addr {
+        width: 6.5rem;
+        overflow: hidden;
+        text-overflow: ellipsis;
+        white-space: nowrap;
+        i {
+          font-size: .3rem;
+          margin-right: .1rem;
+        }
+        span {
+          font-size: .26rem;
+        }
+      }
+      .icon-xiangyou {
+        position: absolute;
+        right: .21rem;
+        top: .52rem;
+        color: #bebebe;
+      }
+    }
+    .pay-store-list {
+      .ps-item {
+        border-bottom: .18rem solid #f1f3f7;
+        .ps-store-name {
+          height: .89rem;
+          line-height: .89rem;
+          padding: 0 .25rem;
+          font-size: .28rem;
+          text-align: left;
+        }
+        .ps-goods-info {
+          background: #f0f0f0;
+          .fl {
+            padding: 0 .29rem;
+            position: relative;
+            .ps-goods-list {
+              width: 4.5rem;
+              height: 100%;
+              padding: .22rem 0;
+              overflow-x: auto;
+              white-space: nowrap;
+              li {
+                border-right: 1px solid #969696;
+                .ps-goods-item {
+                  width: 2.25rem;
+                  padding-left: .12rem;
+                }
+              }
+            }
+            .arrow {
+              position: absolute;
+              height: 100%;
+              color: #666;
+              background: #dfdfdf;
+              padding-top: .72rem;
+              top: 0;
+              &:first-child {
+                left: 0;
+              }
+              &:last-child {
+                right: 0;
+              }
+            }
+          }
+          .fr {
+            width: 2.3rem;
+            text-align: center;
+            .price {
+              color: #f43938;
+              font-size: .32rem;
+              margin-top: .44rem;
+              padding-right: .05rem;
+              span {
+                font-size: .24rem;
+              }
+            }
+            .count {
+              font-size: .28rem;
+              font-weight: bold;
+              margin-top: .2rem;
+            }
+          }
+        }
+        .ps-operate-line {
+          height: .89rem;
+          line-height: .89rem;
+          padding: 0 .21rem 0 .25rem;
+          border-bottom: 1px solid #e4e4e4;
+          font-size: .28rem;
+          .fr {
+            line-height: normal;
+            height: 100%;
+            padding-top: .05rem;
+            i {
+              color: #bebebe;
+              margin-left: .14rem;
+              position: relative;
+              bottom: .17rem;
+            }
+            p {
+              text-align: right;
+              padding-right: .46rem;
+              font-weight: bold;
+            }
+            span {
+              font-size: .27rem;
+              color: #666;
+            }
+          }
+          input {
+            width: 4.78rem;
+            margin-left: .68rem;
+            padding: 0 .1rem;
+            height: .45rem;
+          }
+          &.ps-price {
+            text-align: right;
+            padding-right: .31rem;
+            .inline-block {
+              font-size: .26rem;
+              .ol-price {
+                color: #f43938;
+                font-size: .32rem;
+                span {
+                  font-size: .24rem;
+                }
+              }
+              &:first-child {
+                margin-right: .18rem;
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+</style>

+ 24 - 0
plugins/mixin.js

@@ -137,6 +137,30 @@ Vue.mixin({
           return year + '-' + month + '-' + day + ' ' + hour + ':' + minutes + ':' + seconds
         }
       }
+    },
+    currencyFilter: function (val) {
+      return val === 'RMB' ? '¥' : '$'
+    },
+    telHideFilter: function (val) {
+      return val.slice(0, 3) + '****' + val.slice(7, 11)
+    },
+    storeTypeFilter: function (type) {
+      let tmp = ''
+      switch (type) {
+        case 'CONSIGNMENT':
+          tmp = '寄售'
+          break
+        case 'DISTRIBUTION':
+          tmp = '经销'
+          break
+        case 'AGENCY':
+          tmp = '代理'
+          break
+        case 'ORIGIN_FACTORY':
+          tmp = '原厂'
+          break
+      }
+      return tmp
     }
   }
 })

BIN
static/images/mobile/center/user/addr-border.png


+ 31 - 1
store/userCenter.js

@@ -2,7 +2,7 @@ import axios from '~plugins/axios'
 
 export const actions = {
   // app获取购物车列表
-  loadCartList({ commit }, params = {}) {
+  loadCartList ({ commit }, params = {}) {
     commit('list/REQUEST_CART')
     return axios.get('/trade/cart/pageInfo', {params: params})
       .then(response => {
@@ -10,5 +10,35 @@ export const actions = {
       }, err => {
         commit('list/GET_CART_FAILURE', err)
       })
+  },
+  // app获取结算页订单信息
+  loadPayInfo ({ commit }, params = {}) {
+    commit('list/REQUEST_PAY')
+    return axios.get('/trade/order/orderContainGoods', {params: params})
+      .then(response => {
+        commit('list/GET_PAY_SUCCESS', response.data)
+      }, err => {
+        commit('list/GET_PAY_FAILURE', err)
+      })
+  },
+  // app获取结算页收货地址
+  loadAcceptAddress ({ commit }, params = {}) {
+    commit('list/REQUEST_ADDRESS')
+    return axios.get('/trade/address/shipping', {params: params})
+      .then(response => {
+        commit('list/GET_ADDRESS_SUCCESS', response.data)
+      }, err => {
+        commit('list/GET_ADDRESS_FAILURE', err)
+      })
+  },
+  // app获取结算页发票信息
+  loadPayInvoice ({ commit }, params = {}) {
+    commit('list/REQUEST_INVOICE')
+    return axios.get('/trade/bill/list/personal', {params: params})
+      .then(response => {
+        commit('list/GET_INVOICE_SUCCESS', response.data)
+      }, err => {
+        commit('list/GET_INVOICE_FAILURE', err)
+      })
   }
 }

+ 42 - 0
store/userCenter/list.js

@@ -2,6 +2,18 @@ export const state = () => ({
   cart: {
     fetching: false,
     data: []
+  },
+  pay: {
+    fetching: false,
+    data: []
+  },
+  address: {
+    fetching: false,
+    data: []
+  },
+  invoice: {
+    fetching: false,
+    data: []
   }
 })
 
@@ -15,5 +27,35 @@ export const mutations = {
   GET_CART_SUCCESS (state, result) {
     state.cart.fetching = false
     state.cart.data = result
+  },
+  REQUEST_PAY (state) {
+    state.pay.fetching = true
+  },
+  GET_PAY_FAILURE (state) {
+    state.pay.fetching = false
+  },
+  GET_PAY_SUCCESS (state, result) {
+    state.pay.fetching = false
+    state.pay.data = result
+  },
+  REQUEST_ADDRESS (state) {
+    state.address.fetching = true
+  },
+  GET_ADDRESS_FAILURE (state) {
+    state.address.fetching = false
+  },
+  GET_ADDRESS_SUCCESS (state, result) {
+    state.address.fetching = false
+    state.address.data = result
+  },
+  REQUEST_INVOICE (state) {
+    state.invoice.fetching = true
+  },
+  GET_INVOICE_FAILURE (state) {
+    state.invoice.fetching = false
+  },
+  GET_INVOICE_SUCCESS (state, result) {
+    state.invoice.fetching = false
+    state.invoice.data = result
   }
 }