建材商城系统20241014
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

465 lines
15 KiB

<template>
<view class="hand-firm">
<navbar
title="确定下单"
leftClick
@leftClick="$utils.navigateBack"
/>
<!-- 商品信息 -->
<view class="content-wrapper">
<view class="section-wrapper">
<view class="section-title">
<view class="title-bar"></view>
<text>商品信息</text>
</view>
<view class="product-card">
<image class="product-image" :src="productInfo.image" mode="aspectFit"></image>
<view class="product-details">
<view class="product-name">{{productInfo.name || '泰山工装石膏板'}}</view>
<view class="product-tags">
<text class="tag">{{productInfo.categoryName || '建材材料'}}</text>
<text class="tag">快速下单</text>
</view>
<view class="product-price">
<text class="price-value">¥{{productInfo.price || '38.00'}}</text>
<text class="price-unit">/{{productInfo.unit || '米'}}</text>
</view>
</view>
</view>
</view>
<!-- 个人信息 -->
<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" @click="submitOrder">快捷下单</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>
</view>
</template>
<script>
import redactAddressForm from '../components/address/redactAddressForm.vue';
import addressList from '../components/address/addressList.vue';
export default {
components: {
redactAddressForm,
addressList
},
data() {
return {
productInfo: {}, // 商品信息
orderId: '', // 订单ID
address: {
name: '请选择地址',
address: '',
phone: ''
},
addressTotal: 0,
orderInfo: [],
isLoading: false, // 加载状态
shouldSubmitOrder: false // 标记是否应该在获取地址后自动提交订单
};
},
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]) {
// 如果返回商品信息,则设置商品信息
if (res.result[0].commonShop) {
this.productInfo = res.result[0].commonShop;
}
}
});
},
// 获取地址列表
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: '提交订单中...'
});
// 创建订单
this.$api('createOrder', {
addressId: this.address.id,
productId: this.productInfo.id,
num : 1,
payType: 1, // 默认微信支付
orderId: this.orderId
}, res => {
uni.hideLoading();
if (res.code === 200) {
uni.showToast({
title: '下单成功',
icon: 'success',
duration: 1500,
success: () => {
setTimeout(() => {
// 跳转到订单列表页
this.$utils.redirectTo('/pages_order/order/orderList');
}, 1500);
}
});
} else {
uni.showToast({
title: res.message || '下单失败',
icon: 'none'
});
}
});
}
}
}
</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;
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;
.product-image {
width: 180rpx;
height: 180rpx;
margin-right: 30rpx;
background-color: #f9f9f9;
border-radius: 8rpx;
}
.product-details {
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
.product-name {
font-size: 32rpx;
font-weight: 500;
color: #333;
margin-bottom: 15rpx;
}
.product-tags {
display: flex;
margin-bottom: 20rpx;
.tag {
font-size: 24rpx;
color: #D03F25;
padding: 4rpx 12rpx;
background-color: rgba(208, 63, 37, 0.1);
border-radius: 4rpx;
margin-right: 15rpx;
}
}
.product-price {
font-size: 28rpx;
color: #666;
.price-value {
font-size: 40rpx;
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 {
position: fixed;
bottom: 0;
left: 0;
right: 0;
padding: 20rpx 30rpx;
background-color: #fff;
box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.05);
.submit-btn {
width: 100%;
height: 90rpx;
line-height: 90rpx;
text-align: center;
background-color: #D03F25;
color: #fff;
font-size: 32rpx;
border-radius: 45rpx;
border: none;
}
}
.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>