ソースを参照

提交订单操作

yangc 7 年 前
コミット
1e1a12e757

+ 46 - 0
assets/scss/mobileCommon.scss

@@ -548,3 +548,49 @@ table.com-price-list {
     }
   }
 }
+
+// 联系卖家
+.com-mobile-link {
+  float: right;
+  font-size: .26rem;
+  color: #3f84f6;
+  margin-right: .12rem;
+  i {
+    margin-right: .08rem;
+    position: relative;
+    top: .04rem;
+    font-size: .34rem;
+  }
+}
+
+.mobile-cart-check {
+  min-width: .36rem;
+  height: .36rem;
+  background: url('/images/mobile/center/user/car-noChecked.png') no-repeat;
+  background-size: contain;
+  &.active {
+    background-image: url('/images/mobile/center/user/car-checked.png');
+  }
+  vertical-align: middle;
+  margin-bottom: .02rem;
+  input {
+    display: none;
+  }
+  span {
+    font-size: .26rem;
+    position: static;
+    line-height: normal;
+    margin-left: .5rem;
+    vertical-align: top;
+    font-weight: normal;
+  }
+}
+
+.bottom-modal-check {
+  &.active {
+    background-image: url('/images/mobile/center/user/bottom-checked.png');
+  }
+  span {
+    font-size: .32rem;
+  }
+}

+ 81 - 0
components/mobile/base/BottomModalWrapper.vue

@@ -0,0 +1,81 @@
+<template>
+  <div class="mobile-modal" v-if="showModal" @click="$emit('closeAction', false)">
+    <div class="mobile-modal-box bottom-modal-wrapper" @click="stopPropagation($event)">
+      <div class="bottom-modal-header">{{title}}<i @click="$emit('closeAction', false)" class="icon-guanbi1 iconfont"></i></div>
+      <slot></slot>
+      <div class="bottom-modal-footer" @click="$emit('closeAction', true)">{{submitText}}</div>
+    </div>
+  </div>
+</template>
+<script>
+  export default {
+    props: {
+      showModal: {
+        type: Boolean,
+        default: false
+      },
+      title: {
+        type: String,
+        default: ''
+      },
+      submitText: {
+        type: String,
+        default: '确定'
+      }
+    }
+//    watch: {
+//      showModal: {
+//        handler: function (val) {
+//          if (val) {
+//            this.init()
+//          }
+//        }
+//      }
+//    },
+//    methods: {
+//      init () {
+//        this.$nextTick(() => {
+//          this._initscroll()
+//        })
+//      }
+//    },
+//    mounted() {
+//      this.init()
+//    }
+  }
+</script>
+<style lang="scss" scoped>
+  .mobile-modal {
+    .bottom-modal-wrapper {
+      bottom: 0;
+      top: initial;
+      left: 0;
+      right: 0;
+      text-align: center;
+      .bottom-modal-header {
+        height: 1rem;
+        line-height: 1rem;
+        font-weight: bold;
+        font-size: .42rem;
+        background: #fff;
+        position: relative;
+        border-top-left-radius: .2rem;
+        border-top-right-radius: .2rem;
+        i {
+          font-size: .32rem;
+          position: absolute;
+          right: .2rem;
+          top: 0;
+          color: #bfbfbf;
+        }
+      }
+      .bottom-modal-footer {
+        height: 1rem;
+        line-height: 1rem;
+        background: #3f84f6;
+        font-size: .36rem;
+        color: #fff;
+      }
+    }
+  }
+</style>

+ 54 - 0
components/mobile/base/ModalWrapper.vue

@@ -0,0 +1,54 @@
+<template>
+  <div class="mobile-modal" v-if="showModal" @click="$emit('closeAction')">
+    <div class="mobile-modal-box mobile-modal-wrapper" @click="stopPropagation($event)">
+      <div class="mobile-modal-header">{{title}}<i @click="$emit('closeAction')" class="icon-guanbi iconfont"></i></div>
+      <div ref="mobileModalBox" class="mobile-scroll-wrap"><div><slot></slot></div></div>
+    </div>
+  </div>
+</template>
+<script>
+  export default {
+    props: {
+      showModal: {
+        type: Boolean,
+        default: false
+      },
+      title: {
+        type: String,
+        default: ''
+      }
+    },
+    watch: {
+      showModal: {
+        handler: function (val) {
+          if (val) {
+            this.init()
+          }
+        }
+      }
+    },
+    methods: {
+      init () {
+        this.$nextTick(() => {
+          this._initscroll()
+        })
+      }
+    },
+    mounted() {
+      this.init()
+    }
+  }
+</script>
+<style lang="scss" scoped>
+  .mobile-modal .mobile-modal-wrapper {
+    top: 11%;
+    bottom: 11%;
+    left: 5%;
+    right: 5%;
+  }
+  .mobile-scroll-wrap {
+    overflow: hidden;
+    height: 100%;
+    background: #fff;
+  }
+</style>

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

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

+ 1 - 1
package.json

@@ -26,7 +26,7 @@
     "vue2-filters": "^0.1.9"
   },
   "scripts": {
-    "dev": "nodemon --exec node server.js",
+    "dev": "nodemon --exec node -max_old_space_size=4096 server.js",
     "analyze": "nuxt build --analyze",
     "dev-build": "nuxt build",
     "dev-start": "node server.js",

+ 1 - 35
pages/mobile/center/user/cart.vue

@@ -8,7 +8,7 @@
           </label>
           <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>
+          <a class="com-mobile-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">
@@ -399,18 +399,6 @@
             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 {
@@ -511,26 +499,4 @@
       }
     }
   }
-  .mobile-cart-check {
-    min-width: .36rem;
-    height: .36rem;
-    background: url('/images/mobile/center/user/car-noChecked.png') no-repeat;
-    background-size: contain;
-    &.active {
-      background-image: url('/images/mobile/center/user/car-checked.png');
-    }
-    vertical-align: middle;
-    margin-bottom: .02rem;
-    input {
-      display: none;
-    }
-    span {
-      font-size: .26rem;
-      margin-left: .15rem;
-      position: absolute;
-      left: .6rem;
-      top: .02rem;
-      font-weight: normal;
-    }
-  }
 </style>

+ 922 - 66
pages/mobile/center/user/pay/_orderId.vue

@@ -1,21 +1,23 @@
 <template>
   <div class="mobile-content mobile-content-long mobile-pay">
-    <div class="pay-head">
+    <div class="pay-head" @click="openAddrModal">
       <p class="info">
-        {{defaultAddress.name}}&nbsp;&nbsp;&nbsp;{{defaultAddress.tel | telHideFilter}}
+        {{selectedAddress.name}}&nbsp;&nbsp;&nbsp;{{selectedAddress.tel | telHideFilter}}
       </p>
       <div class="addr">
-        <i class="iconfont icon-tuxiang-"></i>
-        <span>{{defaultAddress.area + defaultAddress.detailAddress}}</span>
+        <img src="/images/mobile/center/user/addr-flag.png" alt="">
+        <span>{{selectedAddress.area + selectedAddress.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>
+        <p class="ps-store-name">{{item.storeName}}
+          <a class="com-mobile-link" @click="linkSaler(item)"><i class="iconfont icon-kefu1"></i>联系卖家</a>
+        </p>
         <div class="ps-goods-info clearfix">
           <div class="fl">
-            <span class="inline-block arrow">
+            <span class="inline-block arrow" @click="goodsScroll('left')">
             <i class="iconfont icon-xiangzuo"></i>
           </span>
             <ul class="ps-goods-list">
@@ -26,48 +28,271 @@
                 <div class="ps-goods-item text-ellipse"><span>规格:</span>{{goods.spec || '-'}}</div>
               </li>
             </ul>
-            <span class="inline-block arrow">
+            <span class="inline-block arrow" @click="goodsScroll('right')">
             <i class="iconfont icon-xiangyou"></i>
           </span>
           </div>
-          <div class="fr">
-            <p class="price text-ellipse"><span>{{payData.currency | currencyFilter}}</span>{{getTotalPrice(item)}}</p>
+          <div class="fr" @click="showDetailList(item.goods)">
+            <p class="price text-ellipse"><span>{{payData.currency | currencyFilter}}</span>{{item.goodsPrice}}</p>
             <p class="count text-ellipse">共{{item.goods.length || 0}}件产品</p>
           </div>
         </div>
-        <div class="ps-operate-line">
+        <div class="ps-operate-line" @click="showRuleSet(item.storeid)">
           <span class="title">配送方式</span>
           <div class="fr">
-            <p>第三方配送</p>
-            <span>全场满1000包邮</span>
-            <i class="iconfont icon-xiangyou"></i>
+            <div class="inline-block">
+              <span v-if="fareRule[item.storeid] && fareRule[item.storeid][0]">{{fareRule[item.storeid][0].method | deliveryRuleFilter}}</span>
+              <span v-if="fareRule[item.storeid] && fareRule[item.storeid][0]">{{fareRule[item.storeid][0].ruleName}}</span>
+              <span v-if="!(fareRule[item.storeid] && fareRule[item.storeid][0])" class="red">当前地址不支持配送,请与卖家协商处理</span>
+            </div>
+            <i class="iconfont icon-xiangyou" v-if="fareRule[item.storeid] && fareRule[item.storeid][0]"></i>
+          </div>
+        </div>
+        <div class="ps-operate-line ps-operate-takeself" v-if="checkShowTakeSelf(item)" @click="showTakeSelfSet(item.storeid)">
+          <span class="title">自提点</span>
+          <div class="fr">
+            <div class="inline-block">
+              <span>{{takeSelfData[item.storeid][0].takename}}</span>
+              <span>地址:{{takeSelfData[item.storeid][0].area + takeSelfData[item.storeid][0].detailAddress}}</span>
+              <span>营业时间:{{takeSelfData[item.storeid][0].businesstime}}</span>
+            </div>
           </div>
         </div>
+        <div class=""></div>
         <div class="ps-operate-line">
           <span class="title">订单备注</span>
-          <input type="text" placeholder="选填:填写内容需和卖家协商确认">
+          <input type="text" v-model="item.remark" placeholder="选填:填写内容需和卖家协商确认">
         </div>
         <div class="ps-operate-line ps-price">
-          <span class="inline-block">
-             运费:<span class="ol-price"><span>$</span>8.99</span>
+          <span class="inline-block text-ellipse">
+             运费:<span class="ol-price" v-if="item.fare"><span v-if="item.fare.fare > 0">{{item.fare.currencyName | currencyFilter}}</span>{{item.fare.fare || 0}}</span>
           </span>
-          <span class="inline-block">
-             店铺合计:<span class="ol-price"><span>$</span>9999.999999</span>
+          <span class="inline-block text-ellipse">
+             店铺合计:<span class="ol-price"><span>{{payData.currency | currencyFilter}}</span>{{item.goodsFarePrice || 0}}</span>
           </span>
         </div>
       </li>
     </ul>
+    <div class="ps-operate-line pay-operate">
+      <span class="title">支付方式</span>
+      <div class="fr">
+        <span>线下支付</span>
+        <!--<i class="iconfont icon-xiangyou"></i>-->
+      </div>
+    </div>
+    <div class="ps-operate-line pay-invoice" @click="openInvoiceModal">
+      <span class="title">开具发票</span>
+      <div class="fr">
+        <div class="inline-block" :style="!selectedInvoice ? 'line-height: unset;' : ''">
+          <template v-if="selectedInvoice">
+            <span>{{selectedInvoice.head}}</span>
+            <span>{{selectedInvoice.kind === 1205 ? '增值税专用发票' : '增值税普通发票'}}</span>
+          </template>
+          <template v-else>
+            <span>暂不开具发票</span>
+          </template>
+        </div>
+        <i class="iconfont icon-xiangyou"></i>
+      </div>
+    </div>
+    <div class="buy-wrap">
+      <div class="fr">
+        <span class="title">实付:</span><span class="ol-price price inline-block text-ellipse"><span>{{payData.currency | currencyFilter}}</span>{{allOrderPrice}}</span>
+        <button class="buy-btn" @click="confirmOrder">提交订单</button>
+      </div>
+    </div>
+
+    <!-- 联系卖家弹框start -->
+    <link-user :infoObj="currentStoreInfo"
+               :showLink="showLink"
+               @closeAction="showLink = false">
+
+    </link-user>
+    <!-- 联系卖家弹框end -->
+
+    <!-- 产品清单弹框start -->
+    <modal-wrapper :showModal="showModal"
+                   :title="'产品清单'"
+                   @closeAction="showModal = false">
+      <ul class="cGoods-list">
+        <li v-for="cGoods in currentGoods" class="clearfix">
+          <div class="fl">
+            <div class="cg-param-line text-ellipse">
+              <span>品牌:</span>{{cGoods.brName}}
+            </div>
+            <div class="cg-param-line text-ellipse">
+              <span>物料名称(类目):</span>{{cGoods.kiName}}
+            </div>
+            <div class="cg-param-line text-ellipse">
+              <span>型号:</span>{{cGoods.cmpCode}}
+            </div>
+            <div class="cg-param-line text-ellipse">
+              <span>规格:</span>{{cGoods.spec}}
+            </div>
+          </div>
+          <div class="fr">
+            <p class="ol-price text-ellipse"><span>{{cGoods.currencyName | currencyFilter}}</span>{{cGoods.price}}</p>
+            <p class="count text-ellipse">x&nbsp;{{cGoods.number}}</p>
+          </div>
+        </li>
+      </ul>
+    </modal-wrapper>
+    <!-- 产品清单弹框end -->
+
+    <!-- 选择配送方式弹框start -->
+    <bottom-modal-wrapper :showModal="showDeliveryModal"
+                          :title="'选择配送方式'"
+                          @closeAction="onDeliveryModalClose">
+      <ul class="delivery-rule-list">
+        <li v-for="cdr in fareRule[currentDeliveryStoreId]" @click="checkDelivery(cdr)">
+          <label class="bottom-modal-check mobile-cart-check" :class="{'active': cdr.$checked}">
+            <input type="checkbox">
+            <span>{{cdr.method | deliveryRuleFilter}}</span>
+          </label>
+          <div class="fr" v-if="cdr.fare && cdr.fare > 0">运费:<span class="ol-price"><span>{{cdr.currencyName | currencyFilter}}</span>{{cdr.fare}}</span></div>
+        </li>
+      </ul>
+    </bottom-modal-wrapper>
+    <!-- 选择配送方式弹框end -->
+
+    <!-- 选择发票弹框start -->
+    <modal-wrapper :showModal="showInvoiceModal"
+                   :title="'选择发票'"
+                   @closeAction="showInvoiceModal = false">
+      <ul class="invoice-list">
+        <li @click="setInvoiceCheck(-1)">
+          <label class="bottom-modal-check mobile-cart-check" :class="{active: selectedInvoiceIndex === -1}">
+            <input type="checkbox">
+          </label>
+          <span class="inv-head">暂不开票</span>
+        </li>
+        <li v-for="(inv, index) in invoiceData" @click="setInvoiceCheck(index)">
+          <label class="bottom-modal-check mobile-cart-check" :class="{'active': selectedInvoiceIndex === index}">
+            <input type="checkbox">
+          </label>
+          <span class="inv-head inline-block text-ellipse">{{inv.head}}</span>
+          <img class="inv-type" :src="`/images/mobile/center/user/${inv.kind === 1205 ? 'invoice-spec' : 'invoice-nor'}.png`" alt="">
+          <div class="content-line" v-if="inv.kind === 1205">
+            <div class="title inline-block">单位地址:</div>
+            <div class="content inline-block">{{inv.companyAddress || '-'}}</div>
+          </div>
+          <div class="content-line" v-if="inv.kind === 1205">
+            <div class="title inline-block">单位电话:</div>
+            <div class="content inline-block">{{inv.companyPhone || '-'}}</div>
+          </div>
+          <div class="content-line" v-if="inv.kind === 1205">
+            <div class="title inline-block">税务登记号:</div>
+            <div class="content inline-block">{{inv.companyTaxNumber || '-'}}</div>
+          </div>
+          <div class="content-line" v-if="inv.kind === 1205">
+            <div class="title inline-block">开户银行:</div>
+            <div class="content inline-block">{{inv.bankName || '-'}}</div>
+          </div>
+          <div class="content-line" v-if="inv.kind === 1205">
+            <div class="title inline-block">开户银行账户:</div>
+            <div class="content inline-block">{{inv.bankAccount || '-'}}</div>
+          </div>
+          <div class="content-line">
+            <div class="title inline-block">收票人:</div>
+            <div class="content inline-block">{{inv.name || '-'}}</div>
+          </div>
+          <div class="content-line">
+            <div class="title inline-block">联系电话:</div>
+            <div class="content inline-block">{{inv.telephone || '-'}}</div>
+          </div>
+          <div class="content-line">
+            <div class="title inline-block">详细地址:</div>
+            <div class="content inline-block">{{inv.area + inv.detailAddress}}</div>
+          </div>
+        </li>
+      </ul>
+    </modal-wrapper>
+    <!-- 选择发票弹框end -->
+
+    <!-- 选择地址弹框start -->
+    <modal-wrapper :showModal="showAddrModal"
+                   :title="'收货地址'"
+                   @closeAction="showAddrModal = false">
+      <ul class="addr-list">
+        <li v-for="(addr, index) in addressData" :class="{active: selectedAddressIndex === index}" @click="setAddressCheck(index)">
+          <div class="info-line">
+            <label class="mobile-cart-check" :class="{active: selectedAddressIndex === index}">
+              <input type="checkbox">
+            </label>
+            <span class="name inline-block text-ellipse">{{addr.name}}</span>
+            <span class="tel inline-block text-ellipse">{{addr.tel}}</span>
+            <i class="inline-block" v-if="addr.num === 1">默认地址</i>
+          </div>
+          <p>{{addr.area + addr.detailAddress}}</p>
+        </li>
+      </ul>
+    </modal-wrapper>
+    <!-- 选择地址弹框end -->
+
+    <!-- 选择自提点弹框start -->
+    <modal-wrapper :showModal="showTakeSelfModal"
+                   :title="'选择自提点'"
+                   @closeAction="showTakeSelfModal = false">
+      <ul class="addr-list takeself-list">
+        <li v-for="(takeself, index) in takeSelfData[currentTakeSelfStoreId]" @click="checkTakeSelf(index)" :class="{active: index === 0}">
+          <div class="info-line">
+            <label class="mobile-cart-check" :class="{active: index === 0}">
+              <input type="checkbox">
+            </label>
+            <span class="name inline-block text-ellipse">{{takeself.takename}}</span>
+          </div>
+          <p><span>地址:</span>{{takeself.area + takeself.detailAddress}}</p>
+          <p><span>营业时间:</span>{{takeself.businesstime}}</p>
+        </li>
+      </ul>
+    </modal-wrapper>
+    <!-- 选择自提点弹框end -->
+
+    <remind-box :title="remindText" :timeoutCount="timeoutCount"></remind-box>
   </div>
 </template>
 <script>
+  import { LinkUser, ModalWrapper, BottomModalWrapper } from '~components/mobile/base'
+  import { RemindBox } from '~components/mobile/common'
   export default {
     layout: 'mobile',
     middleware: 'authenticated',
     data () {
       return {
-        orderData: []
+        orderData: [],
+        // 联系卖家店铺信息
+        currentStoreInfo: {},
+        showLink: false,
+        showModal: false,
+        showDeliveryModal: false,
+        showInvoiceModal: false,
+        showAddrModal: false,
+        showTakeSelfModal: false,
+        currentGoods: [],
+        remindText: '',
+        timeoutCount: '',
+        // 配送规则
+        fareRule: {},
+        // 自提点
+        takeSelfData: {},
+        // 正在修改配送方式的店铺id
+        currentDeliveryStoreId: '',
+        // 订单总价
+        allOrderPrice: 0,
+        // 选中的发票
+        selectedInvoiceIndex: -1,
+        // 选中的地址
+        selectedAddressIndex: 0,
+        // 正在修改自提点的店铺id
+        currentTakeSelfStoreId: ''
       }
     },
+    components: {
+      LinkUser,
+      ModalWrapper,
+      RemindBox,
+      BottomModalWrapper
+    },
     fetch ({ store, params }) {
       return Promise.all([
         store.dispatch('userCenter/loadPayInfo', {enOrderid: params.orderId}),
@@ -75,8 +300,33 @@
         store.dispatch('userCenter/loadPayInvoice')
       ])
     },
+//    watch: {
+//      '$store.state.userCenter.list.invoice.data': {
+//        handler: function (val) {
+//          this.invoiceData = this.baseUtils.deepCopy(val)
+//          if (this.invoiceData && this.invoiceData.length) {
+//            this.invoiceData.forEach(item => {
+//              this.$set(item, '$checked', false)
+//            })
+//          }
+//        },
+//        immediate: true
+//      }
+//    },
     computed: {
       payData () {
+        //        // 人民币为专用增值税发票,美元不开发票    --1205专用增值税发票   --1206普通发票  --1207不开发票
+//        let invoices = this.baseUtils.deepCopy(this.$store.state.userCenter.list.pay.data)
+//        if (invoices.currency === 'USD') {
+//          invoices.invoicetype = 1207
+//          invoices.paytype = '1103'
+//        } else {
+//          invoices.invoicetype = 1205
+//          invoices.paytype = '1102'
+//        }
+//        // 默认选择第三方配送  --1301第三方配送 --卖家配送  --1303上门自提
+//        invoices.deliverytype = 1301
+//        return invoices
         return this.$store.state.userCenter.list.pay.data
       },
       addressData () {
@@ -85,11 +335,46 @@
       invoiceData () {
         return this.$store.state.userCenter.list.invoice.data
       },
-      defaultAddress () {
-        return this.addressData.find(item => {
-          return item.num === 1
+      // 已选择完的发票
+      selectedInvoice () {
+        return this.selectedInvoiceIndex > -1 ? this.invoiceData[this.selectedInvoiceIndex] : null
+      },
+//      // 选择中选中的发票
+//      checkedInvoiceObj () {
+//        return this.invoiceData.find(item => {
+//          return item.$checked
+//        })
+//      },
+      selectedAddress () {
+//        console.log(this.addressData[this.selectedAddressIndex])
+        return this.addressData[this.selectedAddressIndex]
+      },
+      ruleParamsArr () {
+        let arr = []
+        this.orderData.forEach(item => {
+          item.goodsPrice = this.getTotalPrice(item)
+          arr.push({
+            uuid: item.storeid,
+            fare: this.getTotalPrice(item)
+          })
         })
+        return arr
       }
+//      // 选择自提点的列表统计
+//      showTakeSelfList () {
+//        let arr = {}
+//        if (!this.showDeliveryModal || !this.showTakeSelfModal) { // 为了触发更新
+//          for (let attr in this.fareRule) {
+//            arr[attr] = this.fareRule[attr][0] && this.fareRule[attr][0].method === 1303
+//          }
+//        }
+//        return arr
+//      }
+//      defaultAddress () {
+//        return this.addressData.find(item => {
+//          return item.num === 1
+//        })
+//      }
     },
     created () {
       this.initOrderData()
@@ -104,13 +389,42 @@
             this.orderData.push({
               storeName: item.storeName,
               storeid: item.storeid,
-              supEnName: item.supEnName,
+              supEnUU: item.supEnUU,
               goods: [item]
             })
           } else {
             current.goods.push(item)
           }
         })
+        this.getDeliveryRule()
+        this.getTakeSelfInfo()
+      },
+      getDeliveryRule () {
+        return this.$http.post(`/trade/distributionRule/usable/rule?area=${this.selectedAddress.area}`, this.ruleParamsArr)
+          .then(res => {
+            this.fareRule = res.data || {}
+            this.initFare()
+          }, err => {
+            this.setRemindText(err.response.data || '系统错误')
+          })
+      },
+      getTakeSelfInfo () {
+        return this.$http.post(`/trade/takeSelf/store/takeSelf`, this.ruleParamsArr)
+            .then(res => {
+              this.takeSelfData = res.data || {}
+            }, err => {
+              this.setRemindText(err.response.data || '系统错误')
+            })
+      },
+      initFare () {
+        this.allOrderPrice = 0
+        this.orderData.forEach(item => {
+          item.fare = this.fareRule[item.storeid] && this.fareRule[item.storeid].length ? this.fareRule[item.storeid][0] : {}
+          item.goodsPrice = this.getTotalPrice(item) // 总价
+          // 包含运费的价格
+          item.goodsFarePrice = item.goodsPrice + (item.fare && item.fare.fare ? item.fare.fare : 0)
+          this.allOrderPrice += item.goodsFarePrice
+        })
       },
       getTotalPrice (storeItem) {
         let price = 0
@@ -118,12 +432,322 @@
           price += item.price * item.number
         })
         return Number(price.toFixed(6))
+      },
+      linkSaler (item) {
+        this.$http.get(`/basic/enterprise/${item.supEnUU}/info`).then(res => {
+          this.currentStoreInfo = res.data
+          this.showLink = true
+        }, err => {
+          this.setRemindText(err.response.data || '系统错误')
+          console.log(err)
+        })
+      },
+      showDetailList (goods) {
+        this.currentGoods = goods
+        this.showModal = true
+      },
+      goodsScroll (type) {
+        console.log(type)
+      },
+      setRemindText: function (str) {
+        this.remindText = str
+        this.timeoutCount++
+      },
+      checkShowTakeSelf (item) {
+        return item.fare && item.fare.method === 1303
+      },
+      // 显示配送规则弹框
+      showRuleSet: function (storeid) {
+        if (this.fareRule[storeid] && this.fareRule[storeid].length) {
+          this.currentDeliveryStoreId = storeid
+          this.clearCurrentDeliveryCheck()
+          this.fareRule[this.currentDeliveryStoreId][0].$checked = true
+          this.showDeliveryModal = true
+        }
+//        console.log(storeid)
+      },
+      clearCurrentDeliveryCheck () {
+        this.fareRule[this.currentDeliveryStoreId].forEach(item => {
+          if (!item.hasOwnProperty('$checked')) {
+            this.$set(item, '$checked', false)
+          } else {
+            item.$checked = false
+          }
+        })
+      },
+      checkDelivery (cdr) {
+        if (!cdr.$checked) {
+          this.clearCurrentDeliveryCheck()
+          cdr.$checked = true
+        }
+      },
+      onDeliveryModalClose (isSubmit) {
+        if (!isSubmit) {
+          this.showDeliveryModal = false
+//          this.currentDeliveryRule = {}
+        } else {
+          let currentDi = this.fareRule[this.currentDeliveryStoreId]
+          for (let i = 0; i < currentDi.length; i++) {
+            if (currentDi[i].$checked) {
+              this.baseUtils.exchangeArr(currentDi, i, 0)
+              break
+            }
+          }
+          this.initFare()
+          this.showDeliveryModal = false
+        }
+      },
+      // 显示自提点弹框
+      showTakeSelfSet (storeid) {
+        if (this.takeSelfData[storeid] && this.takeSelfData[storeid].length) {
+          this.currentTakeSelfStoreId = storeid
+          this.showTakeSelfModal = true
+        }
+      },
+      checkTakeSelf (index) {
+//        for (let i = 0; i < this.takeSelfData[this.currentTakeSelfStoreId].length; i++) {
+//          if (item.id === this.takeSelfData[this.currentTakeSelfStoreId][i].id) {
+//
+//            break
+//          }
+//        }
+        if (index > 0) {
+          this.baseUtils.exchangeArr(this.takeSelfData[this.currentTakeSelfStoreId], index, 0)
+        }
+        this.showTakeSelfModal = false
+      },
+      setInvoiceCheck (index) {
+        if (this.selectedInvoiceIndex === index) {
+          return
+        }
+        this.selectedInvoiceIndex = index
+        this.showInvoiceModal = false
+      },
+      openInvoiceModal () {
+        if (this.invoiceData && this.invoiceData.length) {
+          this.showInvoiceModal = true
+        } else {
+          this.setRemindText('暂无发票信息,请前往pc端维护')
+        }
+      },
+      setAddressCheck (index) {
+        if (this.selectedAddressIndex === index) {
+          return
+        }
+        this.selectedAddressIndex = index
+        this.showAddrModal = false
+        this.getDeliveryRule()
+      },
+      openAddrModal () {
+        if (this.addressData && this.addressData.length) {
+          this.showAddrModal = true
+        } else {
+          this.setRemindText('暂无收货地址,请前往pc端维护')
+        }
+      },
+      // 配送规则校验
+      checkRule () {
+        let flag = true
+        for (let attr in this.fareRule) {
+          if (!this.fareRule[attr].length) {
+            flag = false
+          }
+        }
+        return flag
+      },
+      // 收货地址校验
+      checkAddress () {
+        if (!this.selectedAddress) {
+          this.setRemindText('收货地址信息为空,请前往pc端添加收货地址')
+          return false
+        } else if (this.selectedAddress.area.indexOf('香港') > -1) {
+          if (this.payData.currency === 'RMB') {
+            this.setRemindText('当前选择的币别是RMB,地址却是香港')
+            return false
+          }
+        } else {
+          if (this.payData.currency === 'USD') {
+            this.setRemindText('当前选择的币别是USD,地址却是内陆')
+            return false
+          }
+        }
+        return true
+      },
+      // 提交订单流程
+      confirmOrder () {
+        if (this.accountInvalid) {
+          this.setRemindText('您的账户安全等级较低,请先在pc端进行信息完善')
+        } else {
+          if (this.payData.status === 502 || this.payData.status === 503) {
+            this.underLinePaySubmitted()
+          } else {
+            if (!this.checkRule()) {
+              this.setRemindText('当前地址部分卖家无法配送,请重新选择地址或与卖家协商处理')
+            } else {
+              let infos = []
+              let info = this.generateOrderInfo()
+              if (info) {
+                infos.push(info)
+                this.doSubmit(infos)
+              }
+            }
+          }
+        }
+      },
+      // 待付款订单-线下付款
+      underLinePaySubmitted () {
+        let arr = []
+        if (this.payData.orderids) {
+          arr = this.payData.orderids.split(',')
+        } else {
+          arr.push(this.payData.orderid)
+        }
+        let param = {
+          orderid: this.baseUtils.enidfilter(arr.join('-'))
+        }
+        console.log(param)
+        // 跳转至付款页面
+        return param
+      },
+      // 处理订单数据
+      generateOrderInfo () {
+        let orderInfo = {
+          id: this.payData.id,
+          orderid: this.payData.orderid
+        }
+        if (this.payData.currency === 'USD' && this.selectedInvoiceIndex !== -1) {
+          this.setRemindText('美元请选择暂不开票')
+          return false
+        }
+        if (this.checkAddress()) {
+          orderInfo.add_id = this.selectedAddress.id
+        } else {
+          return false
+        }
+        let submitParam = this.orderSubmitParams()
+        // 发票信息
+        if (this.selectedInvoice) {
+          if (this.selectedInvoice.kind === 1205) {
+            orderInfo.invoicetype = '1205'
+          } else if (this.selectedInvoice.kind === 1206) {
+            if (submitParam.includeConsignment) {
+              this.setRemindText('订单中包含寄售类型商品,请选择专票')
+              return false
+            }
+            orderInfo.invoicetype = '1206'
+          }
+          if (this.selectedInvoice.id) {
+            orderInfo.invoiceid = this.selectedInvoice.id
+          } else {
+            this.setRemindText('请添加发票信息')
+            return false
+          }
+        } else {
+          orderInfo.invoicetype = '1207'
+        }
+        orderInfo.totalprice = submitParam.goodsPrice
+        orderInfo.currency = this.payData.currency
+        orderInfo.orderRemark = JSON.stringify(submitParam.remarkObj)
+        // 1103线下 1102线上
+        orderInfo.payType = '1103'
+        orderInfo.splitInfo = {
+          ruleList: JSON.stringify(submitParam.ruleList),
+          takeList: JSON.stringify(submitParam.takeList)
+        }
+        orderInfo.orderDetails = this.convertOrderDetailParams()
+        console.log(orderInfo)
+        return orderInfo
+
+        // 人民币为专用增值税发票,美元不开发票    --1205专用增值税发票   --1206普通发票  --1207不开发票
+        // 默认选择第三方配送  --1301第三方配送 --卖家配送  --1303上门自提
+      },
+      // 订单提交的参数整合
+      orderSubmitParams () {
+        let params = {
+          // 不包含运费的价格
+          goodsPrice: 0,
+          // 备注
+          remarkObj: {},
+          // 配送方式
+          ruleList: {},
+          // 自提点
+          takeList: {},
+          // 是否包含寄售商品
+          includeConsignment: false
+        }
+        this.orderData.forEach(item => {
+          params.goodsPrice += item.goodsPrice
+          params.remarkObj[item.storeid] = item.remark
+          params.ruleList[item.storeid] = item.fare
+          params.takeList[item.storeid] = this.checkShowTakeSelf(item) ? this.takeSelfData[item.storeid][0] : null
+          if (item.storeid === '33069557578d44e69bd91ad12d28a8d4') {
+            params.includeConsignment = true
+          }
+        })
+        return params
+      },
+      // 提取要提交到服务器的订单明细goods数据
+      convertOrderDetailParams () {
+        let orderDetails = []
+        this.payData.orderDetails.forEach(item => {
+          orderDetails.push({
+            id: item.id,
+            number: item.number,
+            taxUnitprice: item.taxUnitprice,
+            remark: item.remark,
+            goodsnumber: item.goodsnumber,
+            storeid: item.storeid
+          })
+        })
+        return orderDetails
+      },
+      // 提交订单请求
+      doSubmit (orders) {
+        this.$http.put(`/trade/order/${this.baseUtils.enidfilter(this.payData.orderid)}/ensure`, orders)
+          .then(res => {
+            console.log(res)
+            if (res.data.code === 1) {
+              if (res.data.data && res.data.data[0]) {
+                let orderids = []
+                let batchCodes = []
+                for (let i = 0; i < res.data.data.length; i++) {
+                  orderids.push(res.data.data[i].orderid)
+                  for (let j = 0; j < res.data.data[i].orderDetails.length; j++) {
+                    batchCodes.push(res.data.data[i].orderDetails[j].batchCode)
+                  }
+                }
+                // 如果不是立即购买,删除购物车里的对应信息
+                if (!this.payData.buyNow) {
+                  this.$http.put('/trade/cart/delete', batchCodes)
+                }
+                // 跳转至订单提交完成页面
+                console.log('订单提交完成,跳转至结果页')
+                this.$router.push(`/mobile/center/user/pay/result/${this.baseUtils.enidfilter(orderids.join('-'))}`)
+              }
+            } else {
+              if (res.data.data.code === 6) {
+                this.setRemindText(res.data.message + ',请刷新界面之后重新操作')
+              } else if (res.data.data.code === 7) {
+                this.setRemindText(res.data.message + ',将为您跳转到购物车界面')
+                setTimeout(() => {
+                  this.$router.push('/mobile/center/user/cart')
+                }, 1500)
+              } else {
+                this.setRemindText(res.data.message)
+              }
+            }
+          }, err => {
+            console.log(err)
+            this.setRemindText(err.response.data || '提交订单失败')
+          })
       }
     }
   }
 </script>
 <style lang="scss" scoped>
+  $red-text: #f43938;
   .mobile-pay {
+    margin-bottom: 2.02rem;
     .pay-head {
       height: 1.31rem;
       padding: .25rem 0 0 .21rem;
@@ -142,9 +766,9 @@
         overflow: hidden;
         text-overflow: ellipsis;
         white-space: nowrap;
-        i {
-          font-size: .3rem;
-          margin-right: .1rem;
+        img {
+          height: .29rem;
+          margin-right: .16rem;
         }
         span {
           font-size: .26rem;
@@ -220,54 +844,286 @@
             }
           }
         }
-        .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;
+      }
+    }
+    .ps-operate-line {
+      height: .89rem;
+      line-height: .89rem;
+      padding: 0 .21rem 0 .25rem;
+      border-bottom: 1px solid #e4e4e4;
+      font-size: .28rem;
+      .fr {
+        height: 100%;
+        .inline-block {
+          line-height: normal;
+          text-align: right;
+          span {
+            font-size: .27rem;
+            color: #666;
+            &:first-child {
+              color: #333;
               font-weight: bold;
+              display: block;
+            }
+            &.red {
+              color: $red-text;
             }
+          }
+        }
+        i {
+          color: #bebebe;
+          margin-left: .14rem;
+        }
+      }
+      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;
+          max-width: 64%;
+          &:first-child {
+            max-width: 32%;
+            margin-right: .18rem;
+          }
+        }
+      }
+      &.pay-operate {
+        border-bottom: .11rem solid #f1f3f7;
+        padding-top: 0;
+        .fr {
+          line-height: .78rem;
+          i {
+            position: static;
+          }
+          span {
+            color: #333;
+            font-size: .28rem;
+          }
+        }
+      }
+      &.pay-invoice {
+        border-bottom: .11rem solid #f1f3f7;
+        .fr {
+          padding-top: 0;
+          .inline-block {
+            vertical-align: top;
+          }
+          i {
+            float: right;
+          }
+          span {
+            font-size: .28rem;
+            color: #333;
+            font-weight: normal !important;
+            max-width: 5rem;
+            overflow: hidden;
+            text-overflow: ellipsis;
+            white-space: nowrap;
+          }
+        }
+      }
+      &.ps-operate-takeself {
+        height: 1.35rem;
+        line-height: 1.35rem;
+        .fr {
+          span {
+            display: block;
+            max-width: 5.5rem;
+            overflow: hidden;
+            text-overflow: ellipsis;
+            white-space: nowrap;
+          }
+        }
+      }
+    }
+    .ol-price {
+      color: #f43938;
+      font-size: .32rem;
+      span {
+        font-size: .24rem;
+      }
+    }
+    .buy-wrap {
+      position: fixed;
+      bottom: .98rem;
+      height: 1.02rem;
+      line-height: 1.02rem;
+      padding-left: .27rem;
+      background: #fff;
+      width: 100%;
+      border-top: .02rem solid #ccc;
+      .fr {
+        .title {
+          font-size: .28rem;
+          margin-right: .13rem;
+        }
+        .price {
+          max-width: 3.6rem;
+          vertical-align: top;
+          span {
+            margin-right: .08rem;
+          }
+          margin-right: .13rem;
+        }
+        .buy-btn {
+          width: 2.08rem;
+          height: 1.02rem;
+          line-height: 1.02rem;
+          text-align: center;
+          font-size: .28rem;
+          color: #fff;
+          background: #fc2706;
+        }
+      }
+    }
+    .cGoods-list {
+      background: #fff;
+      li {
+        padding: .3rem .32rem;
+        border-bottom: 1px solid #e4e4e4;
+        .fl {
+          .cg-param-line {
+            width: 3.65rem;
+            margin-bottom: .23rem;
+            &:last-child {
+              margin-bottom: 0;
+            }
+            font-size: .28rem;
             span {
-              font-size: .27rem;
               color: #666;
             }
           }
-          input {
-            width: 4.78rem;
-            margin-left: .68rem;
-            padding: 0 .1rem;
-            height: .45rem;
+        }
+        .fr {
+          text-align: right;
+          p {
+            width: 2.3rem;
+          }
+          .ol-price {
+            margin-top: .59rem;
           }
-          &.ps-price {
+          .count {
+            color: #999;
+            font-size: .24rem;
+            margin-top: .32rem;
+          }
+        }
+      }
+    }
+    .delivery-rule-list {
+      li {
+        background: #fff;
+        text-align: left;
+        padding: 0 .31rem 0 .25rem;
+        height: .94rem;
+        line-height: .94rem;
+        .fr {
+          height: 100%;
+          .ol-price {
+            margin-left: .23rem;
+          }
+        }
+      }
+    }
+    .invoice-list {
+      background: #f1f3f7;
+      padding: .19rem 0;
+      li {
+        margin-bottom: .19rem;
+        position: relative;
+        &:last-child {
+          margin-bottom: 0;
+        }
+        background: #fff;
+        padding: .26rem .16rem .32rem .25rem;
+        .inv-head {
+          margin-left: .17rem;
+          max-width: 5.3rem;
+        }
+        .inv-type {
+          position: absolute;
+          right: 0;
+          top: 0;
+          height: .85rem;
+        }
+        .content-line {
+          margin-top: .23rem;
+          padding-left: .53rem;
+          .title {
+            width: 34%;
             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;
-              }
-            }
+            vertical-align: top;
+          }
+          .content {
+            width: 66%;
+            word-break: break-all;
+          }
+        }
+      }
+    }
+    .addr-list {
+      background: #f1f3f7;
+      padding: .19rem 0;
+      li {
+        margin-bottom: .19rem;
+        position: relative;
+        &:last-child {
+          margin-bottom: 0;
+        }
+        background: #fff;
+        padding: .35rem .25rem .28rem;
+        .info-line {
+          font-size: .3rem;
+          color: #666;
+
+          .name {
+            margin: 0 .27rem 0 .17rem;
+            max-width: 1.5rem;
+          }
+          .tel {
+            max-width: 2.3rem;
+          }
+          i {
+            width: 1.08rem;
+            height: .25rem;
+            line-height: .25rem;
+            font-size: .24rem;
+            text-align: center;
+            border: 1px solid #fc2706;
+            border-radius: .04rem;
+            color: #f43938;
+            font-style: normal;
+            margin-left: .48rem;
+          }
+        }
+        p {
+          margin-top: .19rem;
+          word-break: break-all;
+          padding-left: .54rem;
+          font-size: .28rem;
+          color: #999;
+        }
+        &.active {
+          .info-line {
+            color: #f43938;
+          }
+          p {
+            color: #666;
+          }
+        }
+      }
+    }
+    .takeself-list {
+      li {
+        .info-line {
+          .name {
+            max-width: 5.3rem;
           }
         }
       }

+ 30 - 0
pages/mobile/center/user/pay/result/_ids.vue

@@ -0,0 +1,30 @@
+<template>
+  <remind-box :title="remindText" :timeoutCount="timeoutCount"></remind-box>
+</template>
+<script>
+  import { RemindBox } from '~components/mobile/common'
+  export default {
+    layout: 'mobile',
+    middleware: 'authenticated',
+    data () {
+      return {
+        remindText: '',
+        timeoutCount: ''
+      }
+    },
+    components: {
+      RemindBox
+    },
+    fetch ({ store, params }) {
+      return Promise.all([])
+    },
+    methods: {
+      setRemindText: function (str) {
+        this.remindText = str
+        this.timeoutCount++
+      }
+    }
+  }
+</script>
+<style lang="scss" scoped>
+</style>

+ 42 - 9
plugins/mixin.js

@@ -64,6 +64,10 @@ Vue.mixin({
     },
     isMobile () {
       return this.$store.state.option.isMobile
+    },
+    // 账户安全状态
+    accountInvalid () {
+      return !this.user.data.pwdEnable || !this.user.data.haveUserQuestion || !this.user.data.emailValidCode || this.user.data.emailValidCode !== 2
     }
   },
   methods: {
@@ -79,15 +83,17 @@ Vue.mixin({
       }
     },
     _initscroll() {
-      if (!this.initScroll) {
-        this.initScroll = new BScroll(this.$refs.mobileModalBox, {
-          click: true
-        })
-      } else {
-        this.initScroll.destroy()
-        this.initScroll = new BScroll(this.$refs.mobileModalBox, {
-          click: true
-        })
+      if (this.$refs.mobileModalBox) {
+        if (!this.initScroll) {
+          this.initScroll = new BScroll(this.$refs.mobileModalBox, {
+            click: true
+          })
+        } else {
+          this.initScroll.destroy()
+          this.initScroll = new BScroll(this.$refs.mobileModalBox, {
+            click: true
+          })
+        }
       }
     },
     login: function (url) {
@@ -161,6 +167,33 @@ Vue.mixin({
           break
       }
       return tmp
+    },
+    deliveryRuleFilter: function (type) {
+      let tmp = ''
+      switch (type) {
+        case 1301:
+          tmp = '第三方配送'
+          break
+        case 1302:
+          tmp = '卖家配送'
+          break
+        case 1303:
+          tmp = '上门自提'
+          break
+      }
+      return tmp
+    },
+    invoiceTypeFilter: function (type) {
+      let tmp = ''
+      switch (type) {
+        case 1205:
+          tmp = '普票'
+          break
+        case 1206:
+          tmp = '专票'
+          break
+      }
+      return tmp
     }
   }
 })

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


BIN
static/images/mobile/center/user/bottom-checked.png


BIN
static/images/mobile/center/user/invoice-nor.png


BIN
static/images/mobile/center/user/invoice-spec.png


+ 10 - 0
store/userCenter.js

@@ -41,4 +41,14 @@ export const actions = {
         commit('list/GET_INVOICE_FAILURE', err)
       })
   }
+  // // app获取结算页配送规则
+  // loadPayFareRule ({ commit }, params = {}) {
+  //   commit('list/REQUEST_FARE_RULE')
+  //   return axios.post(`/trade/bill/list/personal?area=${params.area}`, params.storeArr)
+  //     .then(response => {
+  //       commit('list/GET_FARE_RULE_SUCCESS', response.data)
+  //     }, err => {
+  //       commit('list/GET_FARE_RULE_FAILURE', err)
+  //     })
+  // }
 }

+ 9 - 1
utils/baseUtils.js

@@ -408,6 +408,12 @@ const _getPriceByLevel = (prices, number, currency) => {
   }
 }
 
+const _exchangeArr = (arr, x, y) => {
+  let tmp = arr[x]
+  arr[x] = arr[y]
+  arr[y] = tmp
+}
+
 export default {
   // 获取字符串字符长度
   getRealLen: _getRealLen,
@@ -439,5 +445,7 @@ export default {
   // 获得店铺类型中文名
   storeTypeFilter: _storeTypeFilter,
   // 通过分段数量获取分段价格
-  getPriceByLevel: _getPriceByLevel
+  getPriceByLevel: _getPriceByLevel,
+  // 交换数组元素位置
+  exchangeArr: _exchangeArr
 }