<template>
|
|
<view class="hand-firm">
|
|
<navbar
|
|
title="确定下单"
|
|
leftClick
|
|
@leftClick="$utils.navigateBack"
|
|
/>
|
|
|
|
<!-- 商品信息 -->
|
|
<view class="content-wrapper">
|
|
|
|
<uv-checkbox-group
|
|
shape="circle"
|
|
v-model="checkboxValue">
|
|
|
|
<view class="section-wrapper">
|
|
<view class="section-title">
|
|
<view class="title-bar"></view>
|
|
<text>商品信息</text>
|
|
</view>
|
|
|
|
<view class="product-card" v-for="(info, index) in productInfo.commonShop">
|
|
|
|
<view class="checkbox">
|
|
<uv-checkbox
|
|
:name="info.id"
|
|
activeColor="#eb3300"
|
|
size="40rpx"
|
|
icon-size="35rpx"
|
|
></uv-checkbox>
|
|
</view>
|
|
|
|
<image class="product-image" :src="info.image &&
|
|
info.image.split(',')[0]" mode="aspectFill"></image>
|
|
<view class="product-details">
|
|
<view class="product-name">{{info.name || ''}}</view>
|
|
<view class="product-tags">
|
|
<text class="tag">快速下单</text>
|
|
</view>
|
|
<view class="product-price">
|
|
<text class="price-value">¥{{info.price || ''}}</text>
|
|
<text class="price-unit">元/{{info.unit || ''}}</text>
|
|
</view>
|
|
<view class="selectNum">
|
|
<uv-number-box v-model="info.selectNum"></uv-number-box>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
</uv-checkbox-group>
|
|
|
|
<!-- 个人信息 -->
|
|
<view class="section-wrapper">
|
|
<view class="section-title">
|
|
<view class="title-bar"></view>
|
|
<text>填写个人信息</text>
|
|
</view>
|
|
|
|
<view class="address-section">
|
|
<view v-if="addressTotal > 0" class="has-address">
|
|
<view class="address-info" @click="openAddress">
|
|
<view class="address-user">
|
|
<text class="name">{{address.name}}</text>
|
|
<text class="phone">{{address.phone}}</text>
|
|
</view>
|
|
<view class="address-detail">
|
|
{{address.address}} {{address.addressDetails}}
|
|
</view>
|
|
<view class="address-action">
|
|
<text class="address-tip">选择其他已添加过的地址</text>
|
|
<view class="arrow-right"></view>
|
|
</view>
|
|
</view>
|
|
<view class="address-tag">
|
|
<text>已添加过的地址</text>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 地址表单 -->
|
|
<view v-else class="no-address">
|
|
<redact-address-form
|
|
ref="addressForm"
|
|
@saveOrUpdate="handleAddressSave"
|
|
></redact-address-form>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 底部按钮 -->
|
|
<view class="order-submit">
|
|
<button class="submit-btn-close" @click="cancelOrderFast">取消</button>
|
|
<button class="submit-btn" @click="submitOrder">快捷下单(¥{{ totalPrice }})</button>
|
|
</view>
|
|
|
|
<!-- 地址选择弹窗 -->
|
|
<uv-popup ref="addressPopup" :round="30" style="padding-bottom: 90rpx;">
|
|
<addressList ref="addressList" height="60vh" @select="selectAddress" />
|
|
<view class="add-btn">
|
|
<view @click="$utils.navigateTo('/pages_order/mine/address?type=back')" class="button-submit">新增地址</view>
|
|
</view>
|
|
</uv-popup>
|
|
|
|
<kefu/>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
import redactAddressForm from '../components/address/redactAddressForm.vue';
|
|
import addressList from '../components/address/addressList.vue';
|
|
export default {
|
|
components: {
|
|
redactAddressForm,
|
|
addressList
|
|
},
|
|
data() {
|
|
return {
|
|
checkboxValue : [],
|
|
productInfo: {
|
|
commonShop : [],
|
|
}, // 信息
|
|
orderId: '', // 订单ID
|
|
address: {
|
|
name: '请选择地址',
|
|
address: '',
|
|
phone: ''
|
|
},
|
|
addressTotal: 0,
|
|
orderInfo: [],
|
|
isLoading: false, // 加载状态
|
|
shouldSubmitOrder: false // 标记是否应该在获取地址后自动提交订单
|
|
};
|
|
},
|
|
computed: {
|
|
totalPrice(){
|
|
if (!this.checkboxValue.length || !this.productInfo.commonShop) {
|
|
return 0
|
|
}
|
|
let price = 0
|
|
this.productInfo.commonShop.forEach(n => {
|
|
if(this.checkboxValue.includes(n.id)){
|
|
price += n.price * (n.selectNum || 1)
|
|
}
|
|
})
|
|
return Number(price).toFixed(2)
|
|
},
|
|
},
|
|
onLoad(options) {
|
|
// 获取订单ID
|
|
if (options.orderId) {
|
|
this.orderId = options.orderId;
|
|
this.getOrderInfo();
|
|
}
|
|
},
|
|
onShow() {
|
|
// 获取地址列表
|
|
this.getAddressList();
|
|
},
|
|
methods: {
|
|
// 获取订单信息
|
|
getOrderInfo() {
|
|
this.$api('getOrderInfo', res => {
|
|
if (res.code === 200 && res.result[0]) {
|
|
// 如果返回商品信息,则设置商品信息 commonShop
|
|
this.productInfo = res.result[0];
|
|
|
|
this.productInfo.commonShop.forEach(n => {
|
|
this.checkboxValue.push(n.id)
|
|
})
|
|
}
|
|
});
|
|
},
|
|
|
|
// 获取地址列表
|
|
getAddressList() {
|
|
// 调用地址列表组件获取地址
|
|
this.$refs.addressList.getAddressList().then(res => {
|
|
if (res && res.total) {
|
|
this.addressTotal = res.total;
|
|
|
|
// 查找默认地址
|
|
if (res.records && res.records.length > 0) {
|
|
const defaultAddress = res.records.find(addr => addr.defaultFlag === '1');
|
|
if (defaultAddress) {
|
|
this.address = defaultAddress;
|
|
} else {
|
|
// 如果没有默认地址,使用第一个地址
|
|
this.address = res.records[0];
|
|
}
|
|
|
|
// 如果标记为需要自动提交订单
|
|
if (this.shouldSubmitOrder) {
|
|
this.shouldSubmitOrder = false; // 重置标记
|
|
this.submitOrder(true); // 执行提交订单,传入true表示不再验证地址
|
|
}
|
|
}
|
|
} else {
|
|
this.addressTotal = 0;
|
|
}
|
|
|
|
// 完成加载
|
|
this.isLoading = false;
|
|
}).catch(err => {
|
|
console.error('获取地址列表失败', err);
|
|
this.addressTotal = 0;
|
|
this.isLoading = false;
|
|
});
|
|
},
|
|
|
|
// 打开地址选择弹窗
|
|
openAddress() {
|
|
this.$refs.addressPopup.open('bottom');
|
|
},
|
|
|
|
// 选择地址
|
|
selectAddress(address) {
|
|
this.address = address;
|
|
this.$refs.addressPopup.close();
|
|
},
|
|
|
|
// 处理地址保存
|
|
handleAddressSave(address) {
|
|
// 显示加载状态
|
|
this.isLoading = true;
|
|
|
|
// 保存地址
|
|
this.$api('saveOrUpdateAddress', address, res => {
|
|
if (res.code === 200) {
|
|
uni.showToast({
|
|
title: '地址保存成功',
|
|
icon: 'success'
|
|
});
|
|
|
|
// 标记需要在获取地址后自动提交订单
|
|
this.shouldSubmitOrder = true;
|
|
|
|
// 重新获取地址列表
|
|
this.getAddressList();
|
|
} else {
|
|
uni.showToast({
|
|
title: res.message || '保存失败',
|
|
icon: 'none'
|
|
});
|
|
this.isLoading = false;
|
|
}
|
|
});
|
|
},
|
|
|
|
// 提交订单
|
|
submitOrder(skipAddressCheck = false) {
|
|
if (!skipAddressCheck && this.addressTotal === 0) {
|
|
const addressForm = this.$refs.addressForm;
|
|
// 验证地址表单
|
|
const isValid = addressForm.parameterVerification(addressForm.addressDetail);
|
|
if (!isValid.auth) {
|
|
uni.showToast({
|
|
title: isValid.title,
|
|
icon: 'none'
|
|
});
|
|
return;
|
|
}
|
|
|
|
// 显示加载状态
|
|
this.isLoading = true;
|
|
|
|
// 保存地址并继续
|
|
addressForm.onSubmit();
|
|
return;
|
|
}
|
|
|
|
// 显示加载中
|
|
uni.showLoading({
|
|
title: '提交订单中...'
|
|
});
|
|
|
|
let list = []
|
|
|
|
this.productInfo.commonShop.forEach(n => {
|
|
if(this.checkboxValue.includes(n.id)){
|
|
list.push({
|
|
num: n.selectNum || 1,
|
|
shopId: n.id,
|
|
})
|
|
}
|
|
})
|
|
|
|
let data = {
|
|
addressId: this.address.id,
|
|
payType: 1, // 默认微信支付
|
|
orderId: this.orderId,
|
|
list: JSON.stringify(list),
|
|
}
|
|
|
|
/*
|
|
{
|
|
addressId: this.address.id,
|
|
productId: this.productInfo.id,
|
|
num : 1,
|
|
payType: 1, // 默认微信支付
|
|
orderId: this.orderId
|
|
}
|
|
*/
|
|
|
|
// 创建订单
|
|
this.$api('createSumOrder', data, res => {
|
|
uni.hideLoading();
|
|
if (res.code === 200) {
|
|
uni.requestPaymentWxPay(res)
|
|
.then(e => {
|
|
uni.showToast({
|
|
title: '下单成功',
|
|
icon: 'none'
|
|
})
|
|
|
|
this.paySuccess(res)
|
|
}).catch(n => {
|
|
setTimeout(uni.redirectTo, 700, {
|
|
url: '/pages/index/order'
|
|
})
|
|
})
|
|
} else {
|
|
uni.showToast({
|
|
title: res.message || '下单失败',
|
|
icon: 'none'
|
|
});
|
|
}
|
|
});
|
|
},
|
|
paySuccess(res){
|
|
setTimeout(uni.redirectTo, 700, {
|
|
url: '/pages/index/order'
|
|
})
|
|
},
|
|
cancelOrderFast(){
|
|
uni.showModal({
|
|
title: '确认取消吗?',
|
|
success : res => {
|
|
if(res.confirm){
|
|
this.$api('cancelOrderFast', {
|
|
orderId : this.orderId
|
|
}).then(res => {
|
|
uni.showToast({
|
|
title: '取消成功',
|
|
icon: 'none',
|
|
success() {
|
|
uni.navigateBack(-1)
|
|
}
|
|
})
|
|
})
|
|
}
|
|
}
|
|
})
|
|
},
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped lang="scss">
|
|
.hand-firm {
|
|
min-height: 100vh;
|
|
background-color: #f6f6f6;
|
|
padding-bottom: 120rpx;
|
|
|
|
.content-wrapper {
|
|
padding: 20rpx;
|
|
}
|
|
|
|
.section-wrapper {
|
|
margin-bottom: 20rpx;
|
|
border-radius: 12rpx;
|
|
overflow: hidden;
|
|
width: 100%;
|
|
background-color: #fff;
|
|
}
|
|
|
|
.section-title {
|
|
display: flex;
|
|
align-items: center;
|
|
padding: 30rpx;
|
|
border-bottom: 1rpx solid #f0f0f0;
|
|
|
|
.title-bar {
|
|
width: 6rpx;
|
|
height: 30rpx;
|
|
background-color: #D03F25;
|
|
margin-right: 15rpx;
|
|
border-radius: 3rpx;
|
|
}
|
|
|
|
text {
|
|
font-size: 32rpx;
|
|
font-weight: 500;
|
|
color: #333;
|
|
}
|
|
}
|
|
|
|
.product-card {
|
|
display: flex;
|
|
padding: 30rpx;
|
|
|
|
.checkbox{
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
}
|
|
|
|
.product-image {
|
|
width: 200rpx;
|
|
height: 200rpx;
|
|
margin-right: 30rpx;
|
|
background-color: #f9f9f9;
|
|
border-radius: 8rpx;
|
|
}
|
|
|
|
.product-details {
|
|
flex: 1;
|
|
display: flex;
|
|
flex-direction: column;
|
|
justify-content: space-between;
|
|
gap: 6rpx;
|
|
|
|
.product-name {
|
|
font-size: 28rpx;
|
|
font-weight: 500;
|
|
color: #333;
|
|
}
|
|
|
|
.product-tags {
|
|
display: flex;
|
|
|
|
.tag {
|
|
font-size: 24rpx;
|
|
color: #D03F25;
|
|
padding: 4rpx 12rpx;
|
|
background-color: rgba(208, 63, 37, 0.1);
|
|
border-radius: 14rpx;
|
|
margin-right: 15rpx;
|
|
}
|
|
}
|
|
|
|
.product-price {
|
|
font-size: 26rpx;
|
|
color: #666;
|
|
|
|
.price-value {
|
|
font-size: 30rpx;
|
|
font-weight: 600;
|
|
color: #D03F25;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.address-section {
|
|
.has-address {
|
|
position: relative;
|
|
|
|
.address-info {
|
|
padding: 30rpx;
|
|
|
|
.address-user {
|
|
margin-bottom: 15rpx;
|
|
|
|
.name {
|
|
font-size: 32rpx;
|
|
font-weight: 500;
|
|
color: #333;
|
|
margin-right: 30rpx;
|
|
}
|
|
|
|
.phone {
|
|
font-size: 28rpx;
|
|
color: #666;
|
|
}
|
|
}
|
|
|
|
.address-detail {
|
|
font-size: 28rpx;
|
|
color: #666;
|
|
line-height: 1.5;
|
|
margin-bottom: 20rpx;
|
|
}
|
|
|
|
.address-action {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
padding-top: 20rpx;
|
|
border-top: 1px solid #eee;
|
|
|
|
.address-tip {
|
|
font-size: 28rpx;
|
|
color: #D03F25;
|
|
}
|
|
|
|
.arrow-right {
|
|
width: 16rpx;
|
|
height: 16rpx;
|
|
border-top: 2rpx solid #D03F25;
|
|
border-right: 2rpx solid #D03F25;
|
|
transform: rotate(45deg);
|
|
}
|
|
}
|
|
}
|
|
|
|
.address-tag {
|
|
position: absolute;
|
|
top: 20rpx;
|
|
right: 0;
|
|
background-color: #D03F25;
|
|
color: #fff;
|
|
font-size: 24rpx;
|
|
padding: 8rpx 20rpx;
|
|
border-radius: 30rpx 0 0 30rpx;
|
|
}
|
|
}
|
|
|
|
.no-address {
|
|
padding: 20rpx;
|
|
}
|
|
}
|
|
|
|
.order-submit {
|
|
display: flex;
|
|
padding: 20rpx 30rpx;
|
|
background-color: #fff;
|
|
box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.05);
|
|
gap: 20rpx;
|
|
.submit-btn-close{
|
|
height: 90rpx;
|
|
line-height: 90rpx;
|
|
text-align: center;
|
|
background-color: rgba($uni-color, 0.2);
|
|
border: 1rpx solid $uni-color;
|
|
color: $uni-color;
|
|
font-size: 32rpx;
|
|
border-radius: 45rpx;
|
|
border: none;
|
|
flex: 1;
|
|
}
|
|
.submit-btn {
|
|
height: 90rpx;
|
|
line-height: 90rpx;
|
|
text-align: center;
|
|
background-color: $uni-color;
|
|
color: #fff;
|
|
font-size: 32rpx;
|
|
border-radius: 45rpx;
|
|
border: none;
|
|
flex: 4;
|
|
}
|
|
}
|
|
|
|
.add-btn {
|
|
padding: 30rpx;
|
|
|
|
.button-submit {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 100%;
|
|
height: 90rpx;
|
|
background-color: #D03F25;
|
|
color: #fff;
|
|
font-size: 32rpx;
|
|
border-radius: 45rpx;
|
|
}
|
|
}
|
|
}
|
|
</style>
|