Files
orico-association/pagesMall/order/details.vue
2026-03-25 15:53:37 +08:00

565 lines
15 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.

<!-- +----------------------------------------------------------------------
| 麦沃德科技赋能开发者助力商协会发展
+----------------------------------------------------------------------
| Copyright (c) 20172024 www.wdsxh.cn All rights reserved.
+----------------------------------------------------------------------
| 沃德商协会系统并不是自由软件不加密并不代表开源未经许可不可自由转售和商用
+----------------------------------------------------------------------
| Author: MY WORLD Team <bd@maiwd.cn> www.maiwd.cn
+----------------------------------------------------------------------
| 订单详情 开发者: 麦沃德科技-半夏
+---------------------------------------------------------------------- -->
<template>
<view class="container" :style="{ '--theme-color': themeColor }">
<!-- 标题栏 -->
<title-bar :showBack="true" title="订单详情"></title-bar>
<!-- 内容区 -->
<view class="container-main" :style="{paddingBottom: (orderInfo.state == 1 || orderInfo.state == 2 || orderInfo.state == 3) ? '144rpx' : '32rpx'}" v-if="loadEnd">
<!-- 订单状态 -->
<view class="main-status">
<block v-if="orderInfo.state == 1">
<view class="status-text">待付款</view>
<view class="status-tips flex align-items-center">
<view class="icon" :style="{'background-image': 'url('+ iconClock +')'}" v-if="iconClock"></view>
<view class="text">商品未付款,请及时付款</view>
</view>
</block>
<block v-else-if="orderInfo.state == 2">
<view class="status-text">
<text v-if="orderInfo.delivery_method == 2">待自提</text>
<text v-else>待发货</text>
</view>
<view class="status-tips flex align-items-center">
<view class="icon" :style="{'background-image': 'url('+ iconClock +')'}" v-if="iconClock"></view>
<view class="text">
<text v-if="orderInfo.delivery_method == 2">商品待自提</text>
<text v-else>商品待发货</text>
</view>
</view>
</block>
<block v-else-if="orderInfo.state == 3">
<view class="status-text">待收货</view>
<view class="status-tips flex align-items-center">
<view class="icon" :style="{'background-image': 'url('+ iconClock +')'}" v-if="iconClock"></view>
<view class="text">商品已发货,请及时收货</view>
</view>
</block>
<block v-else-if="orderInfo.state == 4">
<view class="status-text">已完成</view>
<view class="status-tips flex align-items-center">
<view class="icon" :style="{'background-image': 'url('+ iconClock +')'}" v-if="iconClock"></view>
<view class="text">商品已完成收货</view>
</view>
</block>
</view>
<!-- 到店自提 -->
<view class="main-address" v-if="orderInfo.delivery_method == 2">
<view class="address-title">自提地址</view>
<view class="address-box flex align-items-center" @click="toNavigation()">
<view class="box-text flex-item">{{mallConfig.address}}</view>
<view class="box-icon" :style="{'background-image': 'url('+ iconMore +')'}" v-if="iconMore"></view>
</view>
<view class="address-info flex flex-wrap" v-if="mallConfig.mobile" @click="onContact()">{{mallConfig.mobile}}</view>
</view>
<!-- 地址选择 -->
<view class="main-address" v-else>
<view class="address-name">{{orderInfo.user_address || ""}}</view>
<view class="address-info flex flex-wrap" v-if="orderInfo.real_name || orderInfo.user_phone">
<text v-if="orderInfo.real_name">{{orderInfo.real_name}}</text>
<text v-if="orderInfo.user_phone">{{orderInfo.user_phone}}</text>
</view>
</view>
<!-- 自提提货码 -->
<view class="main-code" v-if="orderInfo.delivery_method == 2 && orderInfo.pick_up_code">
<view class="code">{{orderInfo.pick_up_code}}</view>
<view class="label">提货码</view>
</view>
<!-- 商品信息 -->
<view class="main-goods">
<block v-for="(item, index) in orderInfo.goods" :key="index">
<mall-store :show-data="item"></mall-store>
</block>
</view>
<!-- 订单信息 -->
<view class="main-order">
<view class="order-info">
<view class="title">商品总额</view>
<view class="value">{{orderInfo.goods_price || ''}}</view>
</view>
<view class="order-info" v-if="orderInfo.delivery_method == 1">
<view class="title">运费总额</view>
<view class="value">{{orderInfo.pay_postage || '0.00'}}</view>
</view>
<view class="order-info">
<view class="title">总计金额</view>
<view class="value">{{orderInfo.total_price || '0.00'}}</view>
</view>
<view class="order-info" v-if="orderInfo.delivery_method == 2">
<view class="title">发货方式</view>
<view class="value" style="color: #5A5B6E;">到店自提</view>
</view>
</view>
<!-- 底部按钮 -->
<view class="main-footer" v-if="orderInfo.state == 1 || orderInfo.state == 2 || orderInfo.state == 3">
<view class="flex align-items-center" v-if="orderInfo.state == 1">
<view class="footer-money"><text></text>{{orderInfo.total_price}}</view>
<view class="footer-btn flex-item" :style="{background: themeColor}" @click="handlePayment()">立即支付</view>
<view class="footer-btn flex-item" style="background: #FF626E;" @click="handleCancel()">取消订单</view>
</view>
<view class="flex align-items-center" v-if="orderInfo.state == 2">
<view class="footer-btn flex-item" style="background: #FF626E;" @click="handleRefund()">申请退款</view>
</view>
<view class="flex align-items-center" v-if="orderInfo.state == 3">
<view class="footer-btn flex-item" style="background: #FF626E;" @click="handleRefund()">申请退款</view>
<view class="footer-btn flex-item" :style="{background: themeColor}" @click="handleDelivery()">确认收货</view>
</view>
<view class="safe-padding"></view>
</view>
</view>
</view>
</template>
<script>
import { mapState } from "vuex"
import mallStore from "@/pagesMall/component/mall/store.vue"
import svgData from "@/common/svg.js"
export default {
components: {
mallStore
},
data() {
return {
// 是否加载完成
loadEnd: false,
// 订单id
orderId: null,
// 订单号
orderNo: null,
// 订单详情
orderInfo: {},
// 商城配置
mallConfig: {},
// 延时器
delayer: null,
};
},
computed: {
...mapState({
themeColor: state => state.app.themeColor,
iconClock: state => {
return svgData.svgToUrl("clock", state.app.themeColor)
},
iconMore: state => {
return svgData.svgToUrl("more", state.app.themeColor)
},
deliveryManagement: state => state.app.deliveryManagement,
})
},
onLoad(option) {
if (uni.getStorageSync("token")) {
uni.showLoading({
title: "加载中"
})
if (option.order_id) this.orderId = option.order_id;
else if (option.id) this.orderNo = option.id;
this.getMallConfig()
this.getOrderDetails(() => {
uni.hideLoading()
this.loadEnd = true
})
} else {
this.$util.verifyLogin(2)
}
},
onShow() {
if (this.loadEnd) this.getOrderDetails()
},
onUnload() {
if (this.delayer) clearTimeout(this.delayer)
},
methods: {
// 获取订单详情
getOrderDetails(fn) {
var data = {}
if (this.orderId) data.id = this.orderId
else if (this.orderNo) data.order_no = this.orderNo
this.$util.request("mall.orderDetails", data).then(res => {
if (fn) fn()
if (res.code == 1) {
this.orderInfo = res.data
this.orderInfo.goods_price = parseFloat(parseFloat(this.orderInfo.total_price) - parseFloat(this.orderInfo.pay_postage || 0)).toFixed(2)
} else {
uni.showToast({
title: res.msg,
icon: 'none'
})
}
}).catch(error => {
if (fn) fn()
console.error('获取订单详情', error)
})
},
// 获取商城配置
getMallConfig() {
this.$util.request("mall.config").then(res => {
if (res.code == 1) {
this.mallConfig = res.data
} else {
uni.showToast({
title: res.msg,
icon: 'none'
})
}
}).catch(error => {
console.error('获取商城配置', error)
})
},
// 取消订单
handleCancel() {
uni.showModal({
title: '提示',
content: '确认取消该订单吗?',
confirmText: '确认取消',
confirmColor: this.themeColor,
cancelText: '我再想想',
cancelColor: '#999999',
success: (res) => {
if (res.confirm) {
uni.showLoading({
title: "加载中",
mask: true
})
this.$util.request("mall.delOrder", {
order_id: this.orderInfo.id,
}).then(res => {
uni.hideLoading()
if (res.code == 1) {
uni.showToast({
title: "取消成功",
icon: "success",
mask: true,
duration: 1500
})
this.delayer = setTimeout(() => {
uni.navigateBack()
}, 1500)
} else {
uni.showToast({
title: res.msg,
icon: 'none'
})
}
}).catch(error => {
uni.hideLoading()
console.error('取消订单', error)
})
}
}
})
},
// 立即支付
handlePayment() {
this.$util.toPage({
mode: 1,
path: `/pagesMall/order/payment?money=${this.orderInfo.total_price}&id=${this.orderInfo.id}`
})
},
// 申请退款
handleRefund() {
this.$util.toPage({
mode: 1,
path: "/pagesMall/refund/apply?id=" + this.orderInfo.id
})
},
// 确认收货
handleDelivery() {
if (this.deliveryManagement == 1) {
if (wx.openBusinessView) {
wx.openBusinessView({
businessType: 'weappOrderConfirm',
extraData: { transaction_id: this.orderInfo.trade_no },
success: e => {
if (e.extraData.status === 'success') {
uni.showLoading({
title: "加载中",
mask: true
})
this.$util.request("mall.orderCollect", {
id: this.orderInfo.id,
}).then(res => {
uni.hideLoading()
if (res.code == 1) {
uni.showToast({
title: "签收成功",
icon: "success",
mask: true,
duration: 1500
})
this.delayer = setTimeout(() => {
uni.navigateBack()
}, 1500)
} else {
uni.showToast({
title: res.msg,
icon: 'none'
})
}
}).catch(error => {
uni.hideLoading()
console.error('确认收货', error)
})
} else {
console.error("调用微信收货", e)
}
},
fail: (err) => {
console.error("调用微信收货", err)
},
});
} else {
uni.showToast({
title: "您的微信版本过低,请升级微信版本后重试",
duration: 2000,
icon: "none",
});
}
} else {
uni.showModal({
title: '提示',
content: '确认此商品已收货,\n点击确认收货后订单完成?',
confirmText: '确认收货',
confirmColor: this.themeColor,
cancelText: '我再想想',
cancelColor: '#999999',
success: (res) => {
if (res.confirm) {
uni.showLoading({
title: "加载中",
mask: true
})
this.$util.request("mall.orderCollect", {
id: this.orderInfo.id,
}).then(res => {
uni.hideLoading()
if (res.code == 1) {
uni.showToast({
title: "签收成功",
icon: "success",
mask: true,
duration: 1500
})
this.delayer = setTimeout(() => {
uni.navigateBack()
}, 1500)
} else {
uni.showToast({
title: res.msg,
icon: 'none'
})
}
}).catch(error => {
uni.hideLoading()
console.error('确认收货', error)
})
}
}
})
}
},
// 跳转地图导航
toNavigation() {
this.$util.toPage({
mode: 7,
address: {
latitude: this.mallConfig.latitude,
longitude: this.mallConfig.longitude,
address: this.mallConfig.address,
},
})
},
// 联系
onContact() {
this.$util.toPage({
mode: 6,
phone: this.mallConfig.mobile,
})
},
}
}
</script>
<style lang="scss">
.container {
.container-main {
padding: 32rpx 32rpx 144rpx;
.main-status {
padding: 16rpx 16rpx 48rpx;
.status-text {
color: #5A5B6E;
font-size: 48rpx;
line-height: 68rpx;
}
.status-tips {
margin-top: 16rpx;
.icon {
width: 32rpx;
height: 32rpx;
background-size: 32rpx;
}
.text {
margin-left: 16rpx;
color: var(--theme-color);
font-size: 28rpx;
line-height: 40rpx;
}
}
}
.main-address {
border-radius: 20rpx;
padding: 32rpx;
background: #FFF;
.address-title {
color: #5A5B6E;
font-size: 28rpx;
font-weight: 600;
line-height: 40rpx;
margin-bottom: 24rpx;
}
.address-name {
color: #5A5B6E;
font-size: 32rpx;
line-height: 44rpx;
}
.address-box {
.box-text {
color: #5A5B6E;
font-size: 32rpx;
line-height: 44rpx;
margin-right: 64rpx;
}
.box-icon {
width: 32rpx;
height: 32rpx;
background-size: 32rpx;
}
}
.address-info {
margin-top: 24rpx;
color: #979797;
font-size: 28rpx;
line-height: 40rpx;
gap: 16rpx;
}
}
.main-code {
margin-top: 32rpx;
padding: 40rpx 32rpx;
border-radius: 16rpx;
background: #FFFFFF;
.code {
text-align: center;
color: #5A5B6E;
font-size: 40rpx;
font-weight: 600;
line-height: 56rpx;
}
.label {
margin-top: 12rpx;
color: #979797;
font-size: 24rpx;
line-height: 34rpx;
text-align: center;
}
}
.main-goods {
margin-top: 32rpx;
display: flex;
flex-direction: column;
row-gap: 32rpx;
}
.main-order {
margin-top: 32rpx;
padding: 32rpx;
border-radius: 16rpx;
background: #FFFFFF;
.order-info {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 32rpx;
&:first-child {
margin-top: 0;
}
.title {
color: #979797;
font-size: 28rpx;
line-height: 40rpx;
}
.value {
color: var(--theme-color);
font-size: 28rpx;
line-height: 40rpx;
margin-left: 24rpx;
}
}
}
.main-footer {
position: fixed;
left: 0;
right: 0;
bottom: 0;
z-index: 96;
background: #FFF;
border-top: 1rpx solid #F6F7FB;
padding: 16rpx 24rpx;
.footer-money {
color: var(--theme-color);
font-size: 40rpx;
line-height: 56rpx;
text {
font-size: 28rpx;
}
}
.footer-btn {
margin-left: 24rpx;
padding: 20rpx 44rpx;
background: var(--theme-color);
border-radius: 16rpx;
color: #FFF;
text-align: center;
font-size: 28rpx;
line-height: 40rpx;
&:first-child {
margin-left: 0;
}
}
}
}
}
</style>