Files
yycea/uniapp/小程序代码/pagesPoints/order/details.vue
2026-03-17 09:56:06 +08:00

389 lines
10 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 == 2">
<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 == 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">
<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-goods flex align-items-center">
<image class="goods-image" :src="orderInfo.goods_info.image" mode="aspectFill"></image>
<view class="goods-info flex-item">
<view class="info-top text-ellipsis-more">{{orderInfo.goods_info.name}}</view>
<view class="info-bottom">
<view class="bottom-points">{{orderInfo.goods_info.points || orderInfo.goods_info.points}}积分</view>
<view class="bottom-number text-ellipsis">×{{orderInfo.number || 1}}</view>
</view>
</view>
</view>
<!-- 订单信息 -->
<view class="main-order">
<view class="order-info">
<view class="info-title">订单编号</view>
<view class="info-value">{{orderInfo.order_no || ''}}</view>
<view class="info-btn" @click="handleCopy(orderInfo.order_no)">复制</view>
</view>
<view class="order-info">
<view class="info-title">积分消耗</view>
<view class="info-value" :style="{color: themeColor}">-{{orderInfo.total_points || 0}}积分</view>
</view>
<view class="order-info">
<view class="info-title">兑换时间</view>
<view class="info-value">{{orderInfo.redemption_time || ''}}</view>
</view>
<block v-if="orderInfo.logistics">
<view class="order-info" v-if="orderInfo.state == 3 || orderInfo.state == 4">
<view class="info-title">发货时间</view>
<view class="info-value">{{orderInfo.logistics.send_time || ''}}</view>
</view>
<view class="order-info" v-if="orderInfo.state == 3 || orderInfo.state == 4">
<view class="info-title">快递公司</view>
<view class="info-value">{{orderInfo.logistics.delivery_name || ''}}</view>
</view>
<view class="order-info" v-if="orderInfo.state == 3 || orderInfo.state == 4">
<view class="info-title">快递单号</view>
<view class="info-value">{{orderInfo.logistics.delivery_no || ''}}</view>
<view class="info-btn" @click="handleCopy(orderInfo.logistics.delivery_no)">复制</view>
</view>
</block>
</view>
<!-- 底部按钮 -->
<view class="main-footer" v-if="orderInfo.state == 3">
<view class="footer-btn" :style="{background: themeColor}" @click="handleDelivery()">确认收货</view>
<view class="safe-padding"></view>
</view>
</view>
</view>
</template>
<script>
import { mapState } from "vuex"
import svgData from "@/common/svg.js"
export default {
data() {
return {
// 是否加载完成
loadEnd: false,
// 订单id
orderId: null,
// 订单详情
orderInfo: {},
// 延时器
delayer: null,
};
},
computed: {
...mapState({
themeColor: state => state.app.themeColor,
iconClock: state => {
return svgData.svgToUrl("clock", state.app.themeColor)
},
})
},
onLoad(option) {
this.orderId = option.id;
if (uni.getStorageSync("token")) {
uni.showLoading({
title: "加载中"
})
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) {
this.$util.request("points.orderDetails", {
id: this.orderId
}).then(res => {
if (fn) fn()
if (res.code == 1) {
this.orderInfo = res.data
} else {
uni.showToast({
title: res.msg,
icon: 'none'
})
}
}).catch(error => {
if (fn) fn()
console.error('获取订单详情', error)
})
},
// 确认收货
handleDelivery() {
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("points.orderConfirm", {
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)
})
}
}
})
},
// 复制
handleCopy(value) {
this.$util.toPage({
mode: 8,
content: value
})
},
}
}
</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-name {
color: #5A5B6E;
font-size: 32rpx;
line-height: 44rpx;
}
.address-info {
margin-top: 24rpx;
color: #979797;
font-size: 28rpx;
line-height: 40rpx;
gap: 16rpx;
}
}
.main-goods {
margin-top: 32rpx;
border-radius: 20rpx;
background: #FFF;
padding: 32rpx;
.goods-image {
width: 160rpx;
min-width: 160rpx;
height: 160rpx;
border-radius: 20rpx;
}
.goods-info {
flex: 1;
height: 160rpx;
margin-left: 32rpx;
display: flex;
flex-direction: column;
justify-content: space-between;
overflow: hidden;
.info-top {
color: #5A5B6E;
font-size: 28rpx;
line-height: 40rpx;
}
.info-bottom {
display: flex;
align-items: center;
.bottom-points {
color: var(--theme-color);
font-size: 28rpx;
font-weight: 600;
line-height: 44rpx;
}
.bottom-number {
flex: 1;
margin-left: 16rpx;
text-align: right;
color: #5A5B6E;
font-size: 28rpx;
line-height: 32rpx;
}
}
}
}
.main-order {
margin-top: 32rpx;
padding: 32rpx;
border-radius: 16rpx;
background: #FFFFFF;
.order-info {
display: flex;
align-items: center;
margin-top: 32rpx;
&:first-child {
margin-top: 0;
}
.info-title {
color: #979797;
font-size: 28rpx;
line-height: 40rpx;
}
.info-value {
margin-left: 24rpx;
flex: 1;
color: #5A5B6E;
font-size: 28rpx;
line-height: 40rpx;
text-align: right;
}
.info-btn {
margin-left: 16rpx;
color: var(--theme-color);
font-size: 28rpx;
line-height: 40rpx;
}
}
}
.main-footer {
position: fixed;
left: 0;
right: 0;
bottom: 0;
z-index: 96;
background: #FFF;
border-top: 1rpx solid #F6F7FB;
padding: 16rpx 24rpx;
.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>