continuePay.vue
<template> <div id="detailOrder"> <flexbox orient="vertical" :gutter="0"> <flexbox-item> <div class="flex-demo"> <div class="detailHeader"> <span class="goOrder" @click="goOrderDetail('/detail')"> <icon name="detailback" :scale="3"></icon> </span> <span>选择支付方式</span> </div> </div> </flexbox-item> <flexbox-item> <div class="choose_box"> <div class="my_card" @click="selectWechat"> <flexbox :gutter="0"> <flexbox-item :span="2" class="card_icon"> <p class="middle_icon"><icon name="wechatPay" scale="3"></icon></p> </flexbox-item> <flexbox-item :span="8"> <p>微信支付</p> </flexbox-item> <flexbox-item :span="2"> <p class="middle_icon" v-if="wechatCircle"><x-icon type="ios-circle-outline" size="26"></x-icon></p> <p class="middle_icon" v-if="wechatCheck"><x-icon type="ios-checkmark-outline" size="26"></x-icon></p> </flexbox-item> </flexbox> </div> <div class="my_card" @click="selectMyCard" > <flexbox :gutter="0"> <flexbox-item :span="2" class="card_icon"> <p class="middle_icon"><icon name="cardPay" scale="3"></icon></p> </flexbox-item> <flexbox-item :span="8"> <p :class="{disableCard:cardInfo.length=='0'}">消费卡</p> </flexbox-item> <flexbox-item :span="2"> <p class="middle_icon" v-if="cardCircle"><x-icon type="ios-circle-outline" size="26"></x-icon></p> <p class="middle_icon" v-if="cardCheck"><x-icon type="ios-checkmark-outline" size="26"></x-icon></p> </flexbox-item> </flexbox> </div> <div class="blank_box"></div> </div> <popup v-model="chooseThisCard" position="bottom" max-height="50%"> <h4 class="card_title">请选择卡片</h4> <div v-for="(item,index) in cardInfo" class="card_item" @click="cardSelected(index,item)"> <flexbox :gutter="0"> <flexbox-item :span="2"> <div class="card_one_item"> <icon name="cardPay" scale="3"></icon> </div> </flexbox-item> <flexbox-item :span="8"> <p>{{item.name}} <span>({{item.card_code}})</span></p> </flexbox-item> <flexbox-item :span="2"> <p class="selected" v-if="showIcon(index)"><x-icon type="ios-checkmark-outline" size="30"></x-icon></p> <p v-if="otherCard(index)"><x-icon type="ios-circle-outline" size="30"></x-icon></p> </flexbox-item> </flexbox> </div> </popup> </flexbox-item> <flexbox-item> <div class="flex-demo menu-bottom" > <flexbox :gutter="0" class="bottom_order"> <flexbox-item :span="9"> <div class="money_box"> 合计:<span class="order_money">¥</span> </div> </flexbox-item> <flexbox-item :span="3"> <div class="payOrder" @click="payOrder">去支付</div> </flexbox-item> </flexbox> </div> </flexbox-item> </flexbox> </div> </template> <script> import { mapGetters } from 'vuex' import {Flexbox, FlexboxItem,Popup } from 'vux' export default { data() { return { wechatCheck:true, wechatCircle:false, cardCheck:false, cardCircle:true, chooseThisCard:false, currentItem:'', } }, computed: { ...mapGetters([ 'orderNo', "cardInfo", ]), }, created(){ console.log(this.orderNo) console.log(this.cardInfo) if(!this.cardInfo){ this.$store.dispatch('getCardInfo') } }, methods:{ payOrder(){ }, getCardInfo(){ this.$http.get('/shop/api/get-wx-user-customer',{ params:{ customerId:_global.customerId } }).then((response) => { if(response.data.status){ this.cardInfo=response.data.data; this.$store.commit('saveMyCard',this.cardInfo); }else{ this.$store.commit('saveMyCard',{}); } }).catch((error)=>{ this.$vux.toast.show({ text: "网络异常", type: 'cancel' }) }) }, goOrderDetail(path){ this.$router.push({path:path}) }, /**选择微信&&消费卡的function */ selectMyCard(){ if(this.cardInfo.length=='0'){ this.$vux.toast.show({ text: "没有消费卡", type: 'cancel' }) return } this.chooseThisCard=true; }, selectWechat(){ this.wechatCheck=true; this.wechatCircle=false; this.cardCheck=false; this.cardCircle=true; this.cardIndex=''; this.payType=1; }, /** 选择消费卡的function */ cardSelected(index,item){ this.wechatCheck=false; this.wechatCircle=true; this.cardIndex=index; this.chooseThisCard=false; this.cardCheck=true; this.cardCircle=false; this.currentItem=item; this.payType=2; }, showIcon(index){ if(index === this.cardIndex){ return true }else { return false; } }, otherCard(index){ if(index === this.cardIndex){ return false }else { return true; } }, }, components: { Flexbox, FlexboxItem,Popup }, } </script> <style lang="less"> #detailOrder{ .detailHeader{ height: 45px; text-align: center; position: relative; font-size: 18px; line-height: 45px; border-bottom: 3px solid #ccc; .goOrder{ position: absolute; left: 20px; top: 6px; } } .choose_box{ height: 105px; .disableCard{ color: #c0c1c2; } .middle_icon{ margin:12px 0 6px 0; } .card_icon{ text-align: center; } .my_card{ background: #fff; border-top: 1px solid #F2F2F2; } } .menu-bottom{ position: fixed; width: 100%; bottom: 0; .bottom_order{ line-height: 60px; height: 60px; box-sizing: border-box; font-size:18px; background: #fff; .money_box{ margin-left: 10px; height:60px; } .order_money{ color:#EB3D3D; font-size: 22px; } .payOrder{ text-align: center; background:#0c6; color:#fff; } } } } </style>
account.vue
<template> <div> <flexbox orient="vertical" :gutter="0"> <flexbox-item> <div class="flex-demo"> <div> <div class="meal_box"> <flexbox :gutter="0" class="select_title" v-if="self_mention==1&&delivery==1"> <flexbox-item :span="6"> <button @click="selfMeal" class="selfMeal" :class="{selectSelf:addressType==1}" :disabled="self_mention==0">自助取餐</button> </flexbox-item> <flexbox-item :span="6"> <button @click="deliveryMeal" class="deliveryMeal" :class="{selectDelivery:addressType==2}" :disabled="delivery==0">送货上门</button> </flexbox-item> </flexbox> <flexbox :gutter="0" class="selfDetail" v-if="addressType==1"> <flexbox-item :span="1"> <icon name="address" scale="2"></icon> </flexbox-item> <flexbox-item :span="10"> <div> <p>{{storeName.name}}</p> <div class="detailAddress">地址:{{storeName.address}}<span class="my_remark">{{storeName.address_detail}}</span></div> </div> </flexbox-item> </flexbox> <flexbox :gutter="0" class="deliveryDetail" v-if="addressType==2" @click.native="selectAddress"> <flexbox-item :span="1"> <icon name="address" scale="2"></icon> </flexbox-item> <flexbox-item :span="10"> <div v-if="addressItem"> <p><span class="my_remark">收货人:{{addressItem.name}}</span></p> <p><span class="my_remark">手机号:{{addressItem.phone}}</span></p> <div class="detailAddress"> <span class="my_remark"> 收货地址:{{addressItem.address}}{{addressItem.address_detail}} </span> </div> </div> <div v-else="!addressItem"> 请选择地址 </div> </flexbox-item> <flexbox-item :span="1"> <icon name="rightIcon" scale="3"></icon> </flexbox-item> </flexbox> </div> </div> </div> </flexbox-item> <flexbox-item> <scroller lock-x height="-295px"> <div class=""> <div v-for="list of shopCart.items"> <shopcart-item :good=item v-for="item of list"></shopcart-item> </div> </div> </scroller> </flexbox-item> <flexbox-item> <div class="choose_box"> <div class="my_card" @click="selectWechat"> <flexbox :gutter="0"> <flexbox-item :span="2" class="card_icon"> <p class="middle_icon"><icon name="wechatPay" scale="3"></icon></p> </flexbox-item> <flexbox-item :span="8"> <p>微信支付</p> </flexbox-item> <flexbox-item :span="2"> <p class="middle_icon" v-if="wechatCircle"><x-icon type="ios-circle-outline" size="26"></x-icon></p> <p class="middle_icon" v-if="wechatCheck"><x-icon type="ios-checkmark-outline" size="26"></x-icon></p> </flexbox-item> </flexbox> </div> <div class="my_card" @click="selectMyCard"> <flexbox :gutter="0"> <flexbox-item :span="2" class="card_icon"> <p class="middle_icon"><icon name="cardPay" scale="3"></icon></p> </flexbox-item> <flexbox-item :span="8"> <p>消费卡</p> </flexbox-item> <flexbox-item :span="2"> <p class="middle_icon" v-if="cardCircle"><x-icon type="ios-circle-outline" size="26"></x-icon></p> <p class="middle_icon" v-if="cardCheck"><x-icon type="ios-checkmark-outline" size="26"></x-icon></p> </flexbox-item> </flexbox> </div> <div class="blank_box"></div> </div> <popup v-model="chooseThisCard" position="bottom" max-height="50%"> <h4 class="card_title">请选择卡片</h4> <div v-for="(item,index) in cardInfo" class="card_item" @click="cardSelected(index,item)"> <flexbox :gutter="0"> <flexbox-item :span="2"> <div class="card_one_item"> <icon name="cardPay" scale="3"></icon> </div> </flexbox-item> <flexbox-item :span="8"> <p>{{item.name}} <span>({{item.card_code}})</span></p> </flexbox-item> <flexbox-item :span="2"> <p class="selected" v-if="showIcon(index)"><x-icon type="ios-checkmark-outline" size="30"></x-icon></p> <p v-if="otherCard(index)"><x-icon type="ios-circle-outline" size="30"></x-icon></p> </flexbox-item> </flexbox> </div> </popup> </flexbox-item> <flexbox-item> <div class="flex-demo menu-bottom" > <flexbox :gutter="0" class="bottom_order"> <flexbox-item :span="9"> <div class="money_box"> 合计:<span class="order_money">¥{{shopCart.totalMoney}}</span> </div> </flexbox-item> <flexbox-item :span="3"> <div class="payOrder" @click="payOrder">去支付</div> </flexbox-item> </flexbox> </div> </flexbox-item> </flexbox> </div> </template> <script> import { mapGetters } from 'vuex' import {Shopcart,ShopcartItem} from "../shopcart" import { Cell, Group,Popup,Flexbox, FlexboxItem, Scroller,XButton,XHeader,Selector} from 'vux' export default { data() { return { wechatCheck:true, wechatCircle:false, cardCheck:false, cardCircle:true, chooseThisCard:false, orderNo:'', addressItem:'', payType:1, } }, computed: { ...mapGetters([ 'shopCart', "cardInfo", "storeName", "addressType", "delivery", "self_mention", ]), }, created(){ this.getStorage() this.wechatConfig() this.getDefaultAddress() if(!this.cardInfo){ this.$store.dispatch('getCardInfo') } if(!_global.customerId){ let $this=this setTimeout(()=>{ this.$vux.toast.show({ text: "新用户请绑定手机号", type:'cancel', onHide(){ $this.$router.push({path:"/binding"}) } },1000) }) } }, methods: { getStorage(){ let cartStorage = JSON.parse(window.sessionStorage.getItem('shopCart')) let storeStorage = JSON.parse(window.sessionStorage.getItem('storeName')) let deliveryStorage = JSON.parse(window.sessionStorage.getItem('delivery')) let selfStorage = JSON.parse(window.sessionStorage.getItem('self_mention')) let addressTypeStorage = JSON.parse(window.sessionStorage.getItem('addressType')) if(cartStorage){ this.$store.commit("saveShopCart",cartStorage) } if(storeStorage){ this.$store.commit("storageStore",storeStorage) } if(deliveryStorage){ this.$store.commit("delivery",deliveryStorage) } if(selfStorage){ this.$store.commit("selfMention",selfStorage) } if(addressTypeStorage){ this.$store.commit("saveAddressType",addressTypeStorage) } }, getDefaultAddress(){ this.$http.get('/shop/api/get-default-address',{ params:{ customerId:_global.customerId } }).then((response) => { if(response.data.status){ this.addressItem=response.data.data this.$store.commit("saveAddressItem",this.addressItem) } }).catch((error)=>{ this.$vux.toast.show({ text: "网络异常", type: 'cancel' }) }) }, // getCardInfo(){ // this.$http.get('/shop/api/get-wx-user-customer',{ // params:{ // customerId:_global.customerId // } // }).then((response) => { // if(response.data.status){ // this.cardInfo=response.data.data; // this.$store.commit('saveMyCard',this.cardInfo); // }else{ // this.$store.commit('saveMyCard',{}); // } // }).catch((error)=>{ // this.$vux.toast.show({ // text: "网络异常", // type: 'cancel' // }) // }) // }, selfMeal(){ this.$store.commit('saveAddressType',1); }, deliveryMeal(){ this.$store.commit('saveAddressType',2); }, selectAddress(){ this.$router.push({ name: 'addressList', params: {clickStatus: 1}}) }, /**选择微信&&消费卡的function */ selectMyCard(){ this.chooseThisCard=true; }, selectWechat(){ this.wechatCheck=true; this.wechatCircle=false; this.cardCheck=false; this.cardCircle=true; this.cardIndex=''; this.payType=1; }, /** 选择消费卡的function */ cardSelected(index,item){ this.wechatCheck=false; this.wechatCircle=true; this.cardIndex=index; this.chooseThisCard=false; this.cardCheck=true; this.cardCircle=false; this.currentItem=item; this.payType=2; }, showIcon(index){ if(index === this.cardIndex){ return true }else { return false; } }, otherCard(index){ if(index === this.cardIndex){ return false }else { return true; } }, /** 下面是跟支付有关的function*/ wechatConfig() { let urls = location.href.split('#')[0] let postData={ url:urls, mallId:_global.mallId } this.$http.post('/shop/api/js-sdk-config', postData).then((response) => { if (response.status === 200 && response.data.status === 1) { this.$wechat.config(JSON.parse(response.data.data)) } else { this.$vux.toast.show({ text: '微信参数错误', type: 'cancel' }) } }).catch(() => { this.$vux.toast.show({ text: "网络异常", type: 'cancel' }) }) }, validate(){ if(!this.addressItem&&this.addressType=='2'){ return { code : 'error', msg: '请选择收货地址'} } if(!this.storeName&&this.addressType=='1'){ return { code : 'error', msg: '请选择收货地址'} } return {code :'success'} }, payOrder(){ let validResult=this.validate() if(validResult.code ==='error'){ this.$vux.toast.show({ text: validResult.msg, type: 'cancel' }) return false } if(this.shopCart.num ==0 ){ let self=this this.$vux.toast.show({ text: "你还没有购买商品", type: 'cancel', time:"1000", onHide(){ self.$router.push({path:'/'}) } }) return } var postAddress if(this.addressType==1){ postAddress=this.storeName }else{ postAddress=this.addressItem } let orderInfo={ shopCart:this.shopCart, address:postAddress.id, mallId:_global.mallId, customerId:_global.customerId, type:this.addressType, } this.$http.post('/shop/api/create-order',orderInfo).then((response) => { if(response.data.status){ this.orderNo=response.data.data if(this.payType==2){ this.cardPay() }else{ this.getWxApi() } }else{ this.$vux.toast.show({ text: response.data.message, type:'cancel' }) } }).catch((error)=>{ this.$vux.toast.show({ text: "网络异常", type: 'cancel' }) }) }, cardPay(){ let postCard={ type:1, orderNo:this.orderNo, cardCode:this.currentItem.card_code, customerId:_global.customerId, totalAmount:this.shopCart.totalMoney, } this.$http.post('/shop/api/pay-order',postCard).then((response) => { if(response.data.status){ this.$store.dispatch("emptyCart") this.$store.commit("saveItemIndex",'2') // this.$store.commit("savePayType",'2') let $this=this this.$vux.toast.show({ text: '支付成功', type: 'success', onHide(){ $this.$router.push({path:'/orderList'}) } }) }else{ this.$vux.toast.show({ text: response.data.message, }) } }).catch((error)=>{ this.$vux.toast.show({ text: "网络异常", type:'cancel' }) }) }, wechatPay(config) { let $this= this this.$wechat.chooseWXPay({ timestamp: config.timestamp, // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符 nonceStr: config.nonceStr, // 支付签名随机串,不长于 32 位 package: config.package, // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=***) signType: config.signType, // 签名方式,默认为'SHA1',使用新版支付需传入'MD5' paySign: config.paySign, // 支付签名 appId:config.appId, success: function (response) { // 支付成功后的回调函数 $this.$store.dispatch("emptyCart") $this.$store.commit("saveItemIndex",'2') // $this.$store.commit("savePayType",'1') $this.$vux.toast.show({ text: '支付成功', type: 'success', onHide(){ $this.$router.push({path:'/orderList'}) } }) }, cancel: function (re) { $this.$vux.toast.show({ text: '支付已取消', type: 'cancel' }) } }); }, getWxApi(){ this.$http.post('/shop/api/wx-pay',{orderNo:this.orderNo}).then((response) => { if(response.data.status){ this.wechatPay(response.data.data) }else{ this.$vux.toast.show({ text: response.data.message, type:'cancel' }) } }).catch((error)=>{ this.$vux.toast.show({ text: "网络异常", type:'cancel' }) }) }, }, components: { Group, Cell, Flexbox, FlexboxItem, Scroller, XHeader, Popup, XButton, Selector, Shopcart,ShopcartItem }, } </script> <style lang="less"> body,html{ background: #F2F2F2; font-size: 14px; } .bottom_order{ line-height: 60px; height: 60px; box-sizing: border-box; font-size:18px; background: #fff; .money_box{ margin-left: 10px; height:60px; } .order_money{ color:#EB3D3D; font-size: 22px; } .payOrder{ text-align: center; background:#0c6; color:#fff; } } .my_remark{ display: inline-block; padding-left:10px; } .meal_box{ padding: 5px 10px; height:120px; background: #fff; } .selfDetail{ margin-top: 15px; .detailAddress{ color: #999; } } .deliveryDetail{ margin-top: 15px; .detailAddress{ color: #999; } } .select_title{ text-align: center; button{ padding: 2px 10px; min-width: 120px; text-align: center; line-height: 30px; display: inline-block; border: 1px solid #E4E4E4; color: #A1A1A1; background: #fff; } .selectSelf{ background: #EB3D3D; color: #fff; border:none; } .selectDelivery{ background: #EB3D3D; color: #fff; border:none; } .selfMeal{ float: right; } .deliveryMeal{ float: left; } } .vux-x-icon { fill: #09BB07; } .choose_box{ height: 105px; .middle_icon{ margin:12px 0 6px 0; } .card_icon{ text-align: center; } .my_card{ background: #fff; border-top: 1px solid #F2F2F2; } } .card_title{ line-height: 40px; text-align: center; background:#fff; font-weight:300; } .card_item{ background: #fff; border:1px solid #f2f2f2; padding:5px 10px; .card_one_item{ margin-top: 8px; } } </style>
store/index.js
import Vue from 'vue' import Vuex from 'vuex' import Axios from '../service/axios' Vue.use(Vuex) export default new Vuex.Store({ state: { shopCart:{ items:{}, totalMoney:0, num:0, }, detailProList:{}, showShopcart:false, showDetailFood:false, storeName:{}, delivery:'', self_mention:'', order_no:'', userInfo:'', cardInfo:'', addressList:'', ifAddNewAddress:false, getCurrentMoney (money){ let money1 = money * 100; let intMoney1 = parseInt(money1); let diff = money1 - intMoney1; let exit=String(diff).indexOf('e') let decDiff = parseInt(diff * 10); console.log(decDiff) if (decDiff > 5&&exit=='-1') { intMoney1 += 1; } return intMoney1/100; }, addressType:'1', itemIndex:'', // payType:'', cartStyle:'1', }, getters: { shopCart:state=>{ return state.shopCart }, cartStyle:state=>{ return state.cartStyle }, // payType:state=>{ // return state.payType // }, addressType:state=>{ return state.addressType }, allAddressList:state=>{ return state.addressList }, ifAddNewAddress:state=>{ return state.ifAddNewAddress }, cardInfo:state=>{ return state.cardInfo }, userInfo:state=>{ return state.userInfo }, detailProList:state=>{ return state.detailProList }, showShopcart:state=>{ return state.showShopcart }, showDetailFood:state=>{ return state.showDetailFood }, storeName:state=>{ return state.storeName }, orderNo:state=>{ return state.order_no }, delivery:state=>{ return state.delivery }, self_mention:state=>{ return state.self_mention }, }, mutations: { saveItemIndex(state,itemIndex){ state.itemIndex=itemIndex }, controlCartStyle(state,cartStyle){ state.cartStyle=cartStyle }, saveShopCart(state,shopCart){ state.shopCart=shopCart }, // savePayType(state,payType){ // state.payType=payType // }, saveAddressType(state,type){ state.addressType=type window.sessionStorage.setItem('addressType',JSON.stringify(state.addressType)); }, saveUserInfo(state,userInfo){ state.userInfo=userInfo; }, selfMention(state,item){ state.self_mention=item window.sessionStorage.setItem('self_mention',JSON.stringify(state.self_mention)); }, delivery(state,item){ state.delivery=item window.sessionStorage.setItem('delivery',JSON.stringify(state.delivery)); }, saveMyCard(state,cardInfo){ state.cardInfo=cardInfo }, saveOrderNo(state,order_no){ state.order_no=order_no }, addShopCart(state,item){ let cart =state.shopCart if(cart.items[item.date] === undefined){ cart.items[item.date]=[] } let isExist=false for(let i in cart.items[item.date]){ if(cart.items[item.date][i].id==item.id){ cart.items[item.date][i].num +=1; isExist=true; break; } } if(!isExist){ item.num=1 cart.items[item.date].push(item) } cart.num +=1; cart.totalMoney +=Number(item.price); cart.totalMoney=state.getCurrentMoney(cart.totalMoney); window.sessionStorage.setItem('shopCart',JSON.stringify(cart)); }, saveAddressList(state,addressList){ state.addressList=addressList state.ifAddNewAddress=false }, ifAddNewAddress(state,ifAddNewAddress){ state.ifAddNewAddress=ifAddNewAddress }, minusShopCart(state,item){ if(item.num==0){ return } item.num -=1; let cart=state.shopCart cart.num -=1; cart.totalMoney -=Number(item.price); cart.totalMoney=state.getCurrentMoney(cart.totalMoney); if(item.num==0){ var deleteShopCart=cart.items[item.date]; for(var j=0;j<deleteShopCart.length;j++){ if(item.id==deleteShopCart[j].id){ deleteShopCart.splice(j,1); } } } if(cart.num==0){ state.showShopcart=false } window.sessionStorage.setItem('shopCart',JSON.stringify(cart)); }, deleteShopCart(state,item){ let cart=state.shopCart cart.num -=item.num cart.totalMoney -=(item.num*item.price) cart.totalMoney=state.getCurrentMoney(cart.totalMoney); /** item.number = 0 是为了清空商品详情里面number */ item.num=0 var deleteShopCart=cart.items[item.date]; for(var j=0;j<deleteShopCart.length;j++){ if(item.id==deleteShopCart[j].id){ deleteShopCart.splice(j,1); } } if(cart.num==0){ state.showShopcart=false } window.sessionStorage.setItem('shopCart',JSON.stringify(cart)); }, emptyShopCart(state){ state.shopCart={ items:{}, totalMoney:0, num:0, } state.detailProList.num=0 state.showShopcart=false window.sessionStorage.setItem('shopCart',JSON.stringify(state.shopCart)); }, detailProList(state,item){ state.detailProList=item }, showShopcart(state){ state.showShopcart=!state.showShopcart }, showDetail(state){ state.showDetailFood=!state.showDetailFood }, storageStore(state,item){ state.storeName=item window.sessionStorage.setItem('storeName',JSON.stringify(state.storeName)); }, }, actions: { addCart({commit},item){ commit("addShopCart",item) }, minusCart({commit},item){ commit("minusShopCart",item) }, deleteCart({commit},item){ commit("deleteShopCart",item) }, emptyCart({commit}){ commit("emptyShopCart") }, watchDetail({commit},item){ commit("detailProList",item) }, storageStore({commit},item){ commit("storageStore",item) }, showCart({commit}){ commit("showShopcart") }, showDetailFood({commit}){ commit("showDetail") }, getCardInfo({commit}){ Axios.get('/shop/api/get-wx-user-customer',{ params:{ customerId:_global.customerId } }).then((response) => { if(response.data.status){ console.log(11111) commit('saveMyCard',response.data.data); } }) } } })