purchase-let/pagesOrder/settle/settle.vue

747 lines
19 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="">
<view class="m-card m-address" style="margin-top: 20rpx;">
<view class="address-info"
style='display: flex;justify-content: space-between;width: 690rpx;align-items: center;'>
<view class="top" style="align-items: flex-start;">
<!-- <view style="color: #333;width: 200rpx;">
<view style="margin: 0 10rpx;color:#20B128;width: 150rpx;">配送点</view>
<view class="isreser"> {{reservation?"次日可提":"当日可提" }}
</view>
</view> -->
<view>
<view style="color: #333;">
{{shop_Info.name}}
</view>
<view style="font-size: 24rpx;color: #333;margin: 10rpx 0;">
{{shop_Info.detailed_address}}
</view>
<view>
<view>
<text>{{shop_Info.phone}}</text>
</view>
</view>
</view>
</view>
<view style="padding: 20rpx;background-color:#20B128;color: white;border-radius: 40rpx;flex-shrink: 0;"
@click="navgo(`/multipleShop/index/index?event=settle&cart_id=${cartStore.cartList.join(',')}`)">
切换配送点
</view>
</view>
</view>
<view class="m-card good-info">
<view class="head-title">商品明细</view>
<view class="m-good" v-for="(item, index) in cartList" :key="index">
<view class="image">
<up-image width="160rpx" height="160rpx" :src="item.imgs"></up-image>
</view>
<view class="body-content">
<view>
<view class="title">
<view>{{ item.name }}</view>
<view>¥{{ item.price }}</view>
</view>
<view class="tips">
<view>{{ item.sku_name }}</view>
<view>x{{ item.cart_num }}/{{ item.unit_name }}</view>
</view>
</view>
<view class="time">
{{ orderInfo.delivery_msg }}
</view>
</view>
</view>
</view>
<view class="m-card good-info">
<view class="head-title">价格明细</view>
<view class="row">
<view>商品总价 <text>共计{{ cartList.length }}款商品</text></view>
<view v-if="orderInfo.pay_price">
<text>¥</text>{{ c_price(orderInfo.pay_price, 0) }}<text>.{{ c_price(orderInfo.pay_price, 1) }}</text>
</view>
<view v-else>
<up-skeleton :loading="true" :animate="true"></up-skeleton>
</view>
</view>
<view class="row">
<view>运费</view>
<view><text>¥</text>0<text>.00</text></view>
</view>
<view class="row" v-if="[4,5,6].includes(userInfo.user_ship)" style="color: red;">
<view>优惠减免</view>
<view v-if="orderInfo.frozen_money">
<text>¥</text>{{ c_price(orderInfo.frozen_money, 0) }}<text>.{{ c_price(orderInfo.frozen_money, 1) }}</text>
</view>
<view v-else>
<up-skeleton :loading="true" :animate="true"></up-skeleton>
</view>
</view>
<view class="row" v-if="userInfo.user_ship==1 ">
<view>优惠返还</view>
<view v-if="orderInfo.activity_price">
<text>¥</text>{{ c_price(orderInfo.activity_price, 0) }}<text>.{{ c_price(orderInfo.activity_price, 1) }}</text>
</view>
<view v-else>
<up-skeleton :loading="true" :animate="true"></up-skeleton>
</view>
</view>
<up-alert v-if="timeContent!=''" type="error" :description="timeContent"></up-alert>
<!-- <up-notice-bar text="门店切换已移动到首页,若切换店铺,购物车商品将跟随门店一起切换"></up-notice-bar> -->
</view>
<view class="m-card order-remark">
<!-- <view style="display: flex;align-items: center;">
<text style="margin-right: 20rpx;">是否存货</text>
<up-radio-group v-model="is_storage" placement="row">
<up-radio activeColor="#20b128" label="立即提货" :name="0" style="margin-right: 10rpx;"></up-radio>
<up-radio activeColor="#20b128" label="全部存货" :name="1"></up-radio>
</up-radio-group>
</view> -->
<view class="head-title" style="margin-top: 20rpx;">
<text>订单备注</text>
<text>{{formData.remark.length}}/140</text>
</view>
<up-textarea style="background-color: #F6F6F6;" v-model="formData.remark" placeholder="暂无备注内容"
:height="40"></up-textarea>
</view>
<view style="width: 100%;height: 500rpx;"></view>
<view class="fiexd-bottom" style="z-index: 999;">
<view class="pay-type-bottom">
<view class=" good-info">
<view class="head-title">支付方式</view>
<view class="row">
<view class="icon-text">
<up-icon name="weixin-circle-fill" color="#20b128" size="22"></up-icon>
<text style="margin-left: 20rpx;font-size: 26rpx;">微信支付</text>
</view>
<view class="icon" @click="onChoosePaytype(7)">
<image v-if="pay_type == 7" src="@/static/icon/check.png" />
<image v-if="pay_type != 7 || pay_type == 3 || pay_type == 18 || !pay_type"
src="@/static/icon/n-check.png" />
</view>
</view>
<!-- <view class="row"
v-if="userInfo.user_ship == 4 || userInfo.user_ship == 5 || userInfo.user_ship == 6 || userInfo.user_ship == 1"> -->
<view class="row">
<!-- <view class="row"> -->
<view class="icon-text">
<image src="@/static/icon/YEZF.png" style="width:40rpx;height: 40rpx;" />
<text style="margin-left: 20rpx;font-size: 26rpx;">余额支付</text>
<text style="margin-left: 20rpx;font-size: 22rpx;color: #FFB76D;">(
可用¥{{userInfo.now_money}}
)</text>
</view>
<view class="icon" @click="onChoosePaytype(3)">
<image v-if="pay_type == 3" src="@/static/icon/check.png" />
<image v-if="pay_type != 3 || pay_type == 7 || pay_type == 18 || !pay_type"
src="@/static/icon/n-check.png" />
</view>
</view>
<!-- <view class="row" v-if="userInfo.user_ship == 1"> -->
<view class="row">
<view class="icon-text">
<image src="@/static/icon/cgkzf.png" style="width:40rpx;height: 40rpx;" />
<text style="margin-left: 20rpx;font-size: 26rpx;">采购款支付</text>
<text style="margin-left: 20rpx;font-size: 22rpx;color: #1296DB;">(
可用¥{{userInfo.purchase_funds}}
)</text>
</view>
<view class="icon" @click="onChoosePaytype(18)">
<image v-if="pay_type == 18" src="@/static/icon/check.png" />
<image v-if="pay_type != 18 || pay_type == 3 || pay_type == 7 || !pay_type"
src="@/static/icon/n-check.png" />
</view>
</view>
</view>
</view>
<view class="submit-row">
<view class="tips">
<view style="margin-right: 20rpx;transform: translateY(5rpx);">共 {{ cartList.length }} 款</view>
<view class="all">
<text style="color: #000;">合计: </text>
<text>¥</text>
<block v-if="orderInfo.total_price">
<text
style="font-size: 32rpx;font-weight: bold;">{{ c_price(orderInfo.pay_price, 0) }}</text>
<text>.{{ c_price(orderInfo.pay_price, 1) }}</text>
</block>
</view>
</view>
<view style="width: 200rpx;">
<up-button color="#20B128" shape="circle" @click="submitOrder" :throttleTime="1000">支付</up-button>
</view>
</view>
</view>
<up-modal :show="timeShow" :content='timeContent' @confirm="timeShow=false"></up-modal>
<addressPopup ref="addressRef" :show="showAddress" :list="addressList" @close="showAddress = false"
@change="changeAddress" />
<shopListPopupVue ref="shopRef" :show="shopListShow" :list="merchantList" @close="shopListShow = false"
@change="changeShop" @search="searchShop" />
<modal title="尚未设置收货地址" content="您还没有添加收货地址,请点击添加" cancleText="取消" confirmText="添加地址" :show="toastAddressShow"
@close="toastAddressoff" @change="addAddress" />
<ZyPasswordboard v-if='passwordBoardVisible' v-model:visible="passwordBoardVisible" v-bind="passwordBoardProps"
@close='closeKeyBord' />
<up-modal :show="showModal" title="您还没设置密码" :closeOnClickOverlay="true" zoom confirmText='去设置' showCancelButton
@close='showModal=false' @cancel='showModal=false' @confirm="navgo('/pagesOrder/setPayPassword/index')"
confirmColor='#27B52F' cancelText='取消'></up-modal>
</view>
</template>
<script setup>
import {
onLoad,
onShow
} from "@dcloudio/uni-app"
import {
nextTick,
ref
} from "vue"
import useUserStore from "@/store/user";
import addressPopup from "@/components/addressPopup.vue";
import shopListPopupVue from "@/components/shopListPopup.vue";
import useCartStore from "@/store/cart.js";
import modal from "@/components/modal.vue";
import {
checkOrderApi
} from "@/api/cart.js";
import {
userInfoApi,
addressListsApi,
merchantListApi,
checkInventoryApi
} from "@/api/user.js";
import {
createOrderApi
} from "@/api/order.js";
import ZyPasswordboard from '@/uni_modules/zy-passwordboard/components/zy-passwordboard/zy-passwordboard.vue';
const userInfo = useUserStore().userInfo;
const shop_Info = ref({})
// 用户选择的门店信息
let STORE_INFO = uni.getStorageSync('STORE_INFO');
console.log(STORE_INFO)
if (STORE_INFO) {
shop_Info.value = JSON.parse(STORE_INFO)
} else {
uni.$u.toast('获取门店信息失败,请在首页选择门店')
}
const cartStore = useCartStore();
const reservation_time = ref('')
const is_storage = ref(0)
const LocationShow = ref(false)
const timeShow = ref(false)
const timeContent = ref('')
const formData = ref({
remark: ""
})
const isAddress = ref(false);
const toastAddressShow = ref(false);
const onChoosePaytype = (e) => {
pay_type.value = e;
}
// 选择地址
const addressRef = ref(null);
const showAddress = ref(false);
const addressInfo = ref({});
const changeAddress = (e) => {
addressInfo.value = e;
showAddress.value = false;
isAddress.value = true;
}
const openAddress = () => {
if (addressList.length > 0) showAddress.value = true;
else uni.navigateTo({
url: '/pagesOrder/addressEdit/addressEdit?type=settle'
})
}
// 地址相关
const addressList = ref([]);
const getAddressList = () => {
addressListsApi().then(res => {
addressList.value = res.data.lists;
addressList.value.forEach(item => {
if (item.is_default) {
addressInfo.value = item;
isAddress.value = true;
}
})
if (!isAddress.value && addressList.value.length > 0) {
addressInfo.value = addressList.value[0];
isAddress.value = true;
}
if (addressInfo.value.address_id) {
nextTick(() => {
addressRef.value.setCheck(addressInfo.value.address_id);
})
}
})
}
// 提货点相关
const shopRef = ref(null);
const shopListShow = ref(false);
const merchantList = ref([]);
const myAddressInfo = ref({
long: "",
lat: ""
})
const shopInfo = ref({
mer_id: ''
});
const getMerchantList = (mer_name = null) => {
merchantListApi({
// ...myAddressInfo.value,
// mer_name: mer_name ? mer_name : ''
}).then(res => {
merchantList.value = res.data.lists;
if (mer_name === null && myAddressInfo.value.long && merchantList.value.length > 0 && !shopInfo
.value.mer_id) {
shopInfo.value = merchantList.value[0];
shopInfo.value.recommend = 1;
nextTick(() => {
shopRef.value.setCheck(shopInfo.value.mer_id);
})
}
})
}
const changeShop = (e) => {
shopInfo.value = e;
shopListShow.value = false;
}
const searchShop = (e) => {
getMerchantList(e)
}
const onCall = (e) => {
uni.makePhoneCall({
phoneNumber: e,
success() {
callShow.value = false
}
})
}
// 选择地址
const addAddress = () => {
// toastAddressShow.value = false;
// nextTick(() => {
// showAddress.value = true;
// })
uni.navigateTo({
url: '/pagesOrder/addressEdit/addressEdit?type=settle'
})
}
// 继续支付
const goPay = () => {
toastAddressShow.value = false;
isAddress.value = true;
submitOrder();
}
// 提交订单
const submitOrder = () => {
if (orderInfo.value.pay_price == 0) {
pay_type.value = 3;
return uni.$u.toast('当前支付金额为0暂不能使用微信支付')
}
// if (!isAddress.value && orderInfo.value.shipping_type == 1) return toastAddressShow.value = true;
if (orderInfo.value.address_id == 0) return toastAddressShow.value = true;
createOrder();
}
// 订单相关
let location = {
lat: '',
long: "",
};
let reservation = ref(0);
const cartList = ref([]);
const orderInfo = ref({});
const checkOrder = (store_id) => {
checkOrderApi({
cart_id: cartStore.cartList,
store_id: shop_Info.value.id || 0,
...location
}).then(res => {
cartList.value = res.data.cart_list;
orderInfo.value = res.data.order;
shop_Info.value = res.data.shopInfo || {}
if (res.data.alert != '') {
timeShow.value = true
timeContent.value = res.data.alert
}
checkInventoryApi({
cart_id: cartStore.cartList,
store_id: store_id || res.data.shopInfo.id
}).then(res => {
reservation.value = res.data.reservation
})
// if (orderInfo.value.default_delivery == 0) {
// orderInfo.value.shipping_type = 2
// }
})
}
// const checkOrderA
const pay_type = ref('7');
// 支付密码
const passwordBoardVisible = ref(false);
const passwordBoardProps = {
title: '输入支付密码',
onComplete(value) {
password.value = value
passwordBoardVisible.value = false
payFn()
}
};
const closeKeyBord = () => {
password.value = ''
}
const password = ref('')
const payFn = () => {
let shareInfo = uni.getStorageSync('SHARE_INFO');
createOrderApi({
reservation: reservation.value,
password: password.value,
spread_uid: (shareInfo && shareInfo.uid) ? shareInfo.uid : '',
cart_id: cartStore.cartList,
address_id: addressInfo.value.address_id,
pay_type: pay_type.value,
store_id: shop_Info.value.id,
shipping_type: orderInfo.value.shipping_type,
mark: formData.value.remark,
is_storage: is_storage.value
}).then(res => {
if (pay_type.value == 3 || pay_type.value == 18) {
if (res.code == 1) {
uni.showToast({
title: res.msg,
icon: "none",
success() {
setTimeout(() => {
uni.redirectTo({
url: '/pagesOrder/order/order?back=-1&type=2'
})
}, 1500)
}
})
} else {
uni.$u.toast(res.msg);
}
} else {
if (!res.data?.nonceStr) return uni.$u.toast('支付失败!');
uni.requestPayment({
provider: 'wxpay',
timeStamp: res.data.timeStamp,
nonceStr: res.data.nonceStr,
package: res.data.package,
signType: res.data.signType,
paySign: res.data.paySign,
success: (e) => {
if (e.errMsg == 'requestPayment:ok') {
uni.showModal({
title: '订单支付成功',
confirmText: '查看订单',
cancelText: '继续购买',
success: (e) => {
if (e.confirm) uni.redirectTo({
url: '/pagesOrder/order/order?back=-1&type=2'
})
else uni.navigateBack();
}
})
} else uni.$u.toast('支付失败')
},
fail: (e) => {
uni.$u.toast('用户取消支付');
uni.redirectTo({
url: '/pagesOrder/order/order?back=-1&type=1'
})
}
})
}
}).catch(err => {
uni.$u.toast(err.msg || '网络错误')
})
}
const showModal = ref(false)
const navgo = (url) => {
showModal.value &&= false
uni.navigateTo({
url
})
}
const createOrder = async () => {
if (!pay_type.value) return uni.$u.toast('请选择支付方式');
if (pay_type.value == 3 || pay_type.value == 18) {
let res = await userInfoApi()
return res.data.pay_password ? passwordBoardVisible.value = true : showModal.value = true
}
payFn()
}
const c_price = (price, index = 0) => {
price = price + '';
return price.split('.')[index] || (index ? '00' : '0');
}
const toastAddressoff = () => {
toastAddressShow.value = false;
uni.redirectTo({
url: '/pagesOrder/settle/settle'
});
}
onLoad(options => {
checkOrder(shop_Info.value.id);
})
onShow(() => {
getAddressList();
})
uni.$on('settle', function(data) {
let datas = JSON.parse(data)
shop_Info.value = datas
})
</script>
<style lang="scss">
.isreser {
// margin: 0 10rpx;
// margin-top: 5rpx;
color: black;
background-color: #F6EECD;
// padding: 5rpx 4rpx;
border-radius: 10rpx;
text-align: center;
width: 95%;
}
.m-card {
margin: 20rpx;
border-radius: 14rpx;
background-color: #fff;
padding: 20rpx;
}
.row {
padding: 0;
overflow: hidden;
}
.m-address {
margin-bottom: 20rpx;
display: flex;
justify-content: space-between;
color: #999999;
.address-info {
width: 450rpx;
.top {
display: flex;
font-size: 28rpx;
.t-name {
color: #444;
margin: 0 10rpx;
}
}
.bottom {
font-size: 24rpx;
}
}
}
.m-good {
display: flex;
justify-content: space-between;
margin-bottom: 20rpx;
.image {
width: 160rpx;
height: 160rpx;
margin-right: 20rpx;
border-radius: 14rpx;
overflow: hidden;
}
.body-content {
width: 490rpx;
display: flex;
flex-direction: column;
justify-content: space-between;
color: #989898;
.title {
display: flex;
justify-content: space-between;
font-size: 28rpx;
color: #444;
}
.tips {
display: flex;
justify-content: space-between;
font-size: 24rpx;
margin-top: 10rpx;
align-items: center;
}
.time {
background-color: #F6F6F6;
padding: 5rpx 10rpx;
font-size: 26rpx;
color: #444;
border-radius: 10rpx;
}
}
}
.good-info {
margin-bottom: 20rpx;
.head-title {
margin-bottom: 18rpx;
color: #000;
font-weight: bold;
}
.row {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 18rpx;
.red {
color: #F55726;
}
.icon-text {
display: flex;
align-items: center;
}
.icon {
image {
width: 40rpx;
height: 40rpx;
}
}
}
.row-need {
display: flex;
justify-content: flex-end;
color: #F55726;
}
text {
font-size: 22rpx;
}
}
.order-remark {
.head-title {
margin-bottom: 18rpx;
display: flex;
justify-content: space-between;
}
}
.tips {
font-size: 28rpx;
color: #999;
display: flex;
justify-content: flex-end;
align-items: center;
flex: 1;
margin-right: 20rpx;
.all {
color: #F55726;
}
}
.item-center {
display: flex;
align-items: center;
position: relative;
}
.ship-type {
display: flex;
z-index: 9;
background-color: #F6F6F6;
border-radius: 30rpx;
.ship-type-item {
width: 82rpx;
height: 54rpx;
line-height: 54rpx;
text-align: center;
transition: background-color 0.3s ease;
border-radius: 30rpx;
}
.actShipItem {
background-color: #27B52F;
color: white;
}
}
.fiexd-bottom {
position: fixed;
bottom: 0;
left: 0;
// height: calc(constant(safe-area-inset-bottom) + 120rpx);
/* 适用于iOS设备 */
// height: calc(env(safe-area-inset-bottom) + 120rpx);
/* 适用于Android设备 */
width: 100%;
box-sizing: border-box;
background-color: #fff;
padding: 20rpx;
padding-bottom: calc(constant(safe-area-inset-bottom) + 20rpx);
/* 适用于iOS设备 */
padding-bottom: calc(env(safe-area-inset-bottom) + 20rpx);
/* 适用于Android设备 */
.submit-row {
display: flex;
justify-content: space-between;
align-items: center;
}
.pay-type-bottom {
margin-bottom: 50rpx;
}
}
</style>