384 lines
18 KiB
Vue
384 lines
18 KiB
Vue
<template>
|
|
<view class="waper">
|
|
<u-navbar :autoBack="true" :placeholder="true" bgColor="#FBFBFB">
|
|
<view slot='center' class="navbar_title">订单详情</view>
|
|
</u-navbar>
|
|
<view class="waper_content" v-if="detail" :style="detail.status == 0 ? ('padding-bottom: ' + waperBottom + 'px;') : ''">
|
|
<view class="status">
|
|
<view>{{detail.statusText}}</view>
|
|
<view v-if="detail.status == 0">
|
|
<text>剩余支付时间</text>
|
|
<text>{{secondsToTime(timeNum)}}</text>
|
|
</view>
|
|
<view v-if="detail.status > 0">
|
|
<text>买家已付款,请等待商家发货</text>
|
|
</view>
|
|
</view>
|
|
<view class="address">
|
|
<view class="icon">
|
|
<image class="img" src="https://common/address.png" mode=""></image>
|
|
</view>
|
|
<view class="text">
|
|
<view>{{detail.provinceName + detail.cityName + detail.areaName + ' ' + detail.address}}</view>
|
|
<view>
|
|
<text>{{detail.consignee}}</text>
|
|
<text>{{detail.phone}}</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<view class="goods">
|
|
<view class="title">{{detail.orderItemList[0].storeName}}</view>
|
|
<view class="list_waper">
|
|
<view class="list" v-for="(i, index) in detail.orderItemList" :key="index">
|
|
<view class="img">
|
|
<image :src="$utils.setImgUrl(i.goodsImage)" mode=""></image>
|
|
</view>
|
|
<view class="text">
|
|
<view class="name">{{i.goodsTitle}}
|
|
<!-- <text v-if="detail.status > 0">{{i.refundStatus == 2 ? i.refundStatusText : i.dispatchStatusText}}</text> -->
|
|
</view>
|
|
<view class="tag">
|
|
<view>
|
|
<text v-if="i.goodsSkuText">{{i.goodsSkuName}}</text>
|
|
</view>
|
|
<view>X{{i.goodsNum}}</view>
|
|
</view>
|
|
<view class="money">
|
|
<text>总价:¥{{i.goodsPrice.toFixed(2)}}</text>
|
|
<view class="btns">
|
|
<text v-if="(detail.status == 1 || detail.status == 2) && i.refundStatus < 1" @click="showRefund(i)">退款</text>
|
|
<text v-if="detail.status == 1 && i.dispatchStatus == 1 && i.refundStatus == 0" @click="itemDispatch(i)">确认收货</text>
|
|
<text v-if="(detail.status == 1 || detail.status == 2) && i.refundStatus >= 1" @click="toRefundDetail(i.aftersale.id)">退款详情</text>
|
|
<text v-if="(detail.status == 1 || detail.status == 2) && i.refundStatus == -1" @click="toRefundDetail(i.aftersale.id)">拒绝退款</text>
|
|
</view>
|
|
</view>
|
|
<view class="money" v-if="i.expressName">
|
|
<text>快递公司:{{i.expressName}}</text>
|
|
</view>
|
|
<view class="money" v-if="i.expressNo">
|
|
<text>快递单号:{{i.expressNo}}</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<view class="order">
|
|
<view class="title">订单信息</view>
|
|
<view class="content">
|
|
<view class="list">
|
|
<view>商品总价</view>
|
|
<view>¥{{detail.goodsAmount.toFixed(2)}}</view>
|
|
</view>
|
|
<view class="list">
|
|
<view>运费</view>
|
|
<view>{{detail.dispatchAmount ? (detail.dispatchAmount).toFixed(2) : '包邮'}}</view>
|
|
</view>
|
|
<view class="list">
|
|
<view>配送方式</view>
|
|
<view>邮寄</view>
|
|
</view>
|
|
<view class="list">
|
|
<view>订单编号</view>
|
|
<view>
|
|
<text>{{detail.orderSn}}</text>
|
|
<text @click="copyCode(detail.orderSn)">复制</text>
|
|
</view>
|
|
</view>
|
|
<view class="list">
|
|
<view>创建时间</view>
|
|
<view>{{detail.createTime}}</view>
|
|
</view>
|
|
<view class="list" v-if="detail.paytime">
|
|
<view>付款时间</view>
|
|
<view>{{detail.paytime}}</view>
|
|
</view>
|
|
<view class="list">
|
|
<view>备注</view>
|
|
<view>{{detail.remark || '无'}}</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<view class="bottom" :style="'padding-bottom: ' + safeAreaBottom + 'px'" v-if="detail.status == 0">
|
|
<view class="bottom_waper">
|
|
<view @click="cancel">取消订单</view>
|
|
<view class="active" @click="payOrder">立即支付</view>
|
|
</view>
|
|
</view>
|
|
<u-popup :show="refund" mode="bottom" bgColor="transparent">
|
|
<view class="refund_waper">
|
|
<view class="title">请选择类型
|
|
<view class="icon" @click="closeRefund">
|
|
<u-icon name="close" size="32rpx" color="#333"></u-icon>
|
|
</view>
|
|
</view>
|
|
<view class="cont">
|
|
<view :class="{active: refundIndex === 0}" @click="refundIndex = 0;">仅退款</view>
|
|
<view :class="{active: refundIndex === 1}" @click="refundIndex = 1;">退货退款</view>
|
|
</view>
|
|
<view class="btn" @click="confirmRefund">下一步</view>
|
|
</view>
|
|
</u-popup>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
export default {
|
|
data () {
|
|
return {
|
|
safeAreaBottom: 0,
|
|
waperBottom: 0,
|
|
detail: null,
|
|
refund: false,
|
|
refundIndex: null,
|
|
refundData: null,
|
|
timeNum: 0,
|
|
timer: null
|
|
}
|
|
},
|
|
onLoad (options) {
|
|
this.safeAreaBottom = this.$safeAreaBottom;
|
|
this.waperBottom = this.safeAreaBottom + uni.upx2px(152);
|
|
this.orderdetail(options.id);
|
|
},
|
|
onShow () {
|
|
if (this.detail) this.orderdetail(this.detail.id)
|
|
},
|
|
onUnload () {
|
|
clearInterval(this.timer);
|
|
this.timer = null;
|
|
},
|
|
methods: {
|
|
async itemDispatch (item) {
|
|
let info = await this.$shop.confirmReceipt({ orderId: item.orderId, orderItemIds: [item.id] });
|
|
uni.showToast({ mask: true, title: '操作成功', icon: 'success' });
|
|
this.orderdetail(this.detail.id)
|
|
},
|
|
async orderdetail(id) {
|
|
let info = await this.$shop.orderdetail(id)
|
|
info.data.dispatchStatus = false;
|
|
info.data.orderItemList.forEach((item, index) => {
|
|
if (item.goodsSkuText) info.data.orderItemList[index].goodsSkuName = info.data.orderItemList[index].goodsSkuText.split(',').join('-');
|
|
if (item.dispatchStatus > 0) info.data.dispatchStatus = true;
|
|
})
|
|
if (info.data.status == 0) {
|
|
let configData = uni.getStorageSync('configData');
|
|
let creaetdTime = parseInt(new Date(info.data.createTime).getTime() / 1000);
|
|
let nowtime = parseInt(new Date().getTime() / 1000);
|
|
if ((creaetdTime + configData.expirationTime * 60) >= nowtime) {
|
|
this.timeNum = (creaetdTime + configData.expirationTime * 60) - nowtime;
|
|
this.setIntervalFn()
|
|
}
|
|
}
|
|
this.detail = info.data;
|
|
},
|
|
secondsToTime(seconds) {
|
|
const minutes = Math.floor((seconds % 3600) / 60);
|
|
const remainingSeconds = seconds % 60;
|
|
return (minutes >= 10 ? minutes : '0' + minutes) + ":" + (remainingSeconds >= 10 ? remainingSeconds : '0' + remainingSeconds);
|
|
},
|
|
setIntervalFn () {
|
|
clearInterval(this.timer);
|
|
this.timer = setInterval(() => {
|
|
if (this.timeNum <= 0) {
|
|
clearInterval(this.timer)
|
|
uni.navigateBack()
|
|
}
|
|
this.timeNum --;
|
|
}, 1000)
|
|
},
|
|
copyCode (str) {
|
|
uni.setClipboardData({
|
|
data: str,
|
|
success: () => {
|
|
uni.showToast({ mask: true, title: '内容已复制到剪切板', icon: 'none' })
|
|
}
|
|
})
|
|
},
|
|
async payOrder () {
|
|
uni.showLoading({ mask: true })
|
|
let info = await this.$shop.getWcscOrderSession({ orderId: this.detail.id });
|
|
if (info.code == 200) {
|
|
let patInfo = JSON.parse(info.msg);
|
|
uni.requestPayment({
|
|
provider: 'wxpay',
|
|
timeStamp: patInfo.timeStamp,
|
|
nonceStr: patInfo.nonceStr,
|
|
package: patInfo.packageValue,
|
|
signType: patInfo.signType,
|
|
paySign: patInfo.paySign,
|
|
success: (res) => {
|
|
uni.hideLoading();
|
|
this.showSuccess = true;
|
|
this.orderdetail(this.detail.id);
|
|
},
|
|
fail: function (err) {
|
|
uni.hideLoading();
|
|
uni.showToast({ mask: true, title: '支付取消', icon: 'none' })
|
|
}
|
|
});
|
|
} else {
|
|
uni.hideLoading();
|
|
uni.showToast({ mask: true, title: info.msg, icon: 'none' });
|
|
}
|
|
},
|
|
async cancel() {
|
|
let info = await this.$shop.cancleOrder({ orderId: this.detail.id, storeId: this.detail.orderItemList[0].storeId })
|
|
uni.showToast({ mask: true, title: '操作成功', icon: 'success' })
|
|
this.orderdetail(this.detail.id);
|
|
},
|
|
showRefund (info) {
|
|
this.refundData = info;
|
|
this.refundIndex = null;
|
|
this.refund = true;
|
|
},
|
|
closeRefund () {
|
|
this.refund = false;
|
|
this.refundIndex = null;
|
|
},
|
|
confirmRefund () {
|
|
if (this.refundIndex === null) {
|
|
uni.showToast({ mask: true, title: '请选择类型', icon: 'null' })
|
|
return false;
|
|
}
|
|
this.refundData.type = this.refundIndex;
|
|
uni.navigateTo({ url: '/pages/shop/refund?info=' + encodeURIComponent(JSON.stringify(this.refundData)) })
|
|
this.refundIndex = null;
|
|
this.refund = false;
|
|
},
|
|
toRefundDetail (id) {
|
|
uni.navigateTo({
|
|
url: '/pages/shop/refundReason?id=' + id
|
|
})
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
|
|
.waper_content{
|
|
width: 100%; box-sizing: border-box; padding: 24rpx;
|
|
.status{
|
|
width: 100%;
|
|
view{
|
|
&:nth-child(1){ font-weight: 500; font-size: 48rpx; color: rgba(0,0,0,0.85); line-height: 56rpx; }
|
|
&:nth-child(2){
|
|
margin-top: 5rpx; display: flex; align-items: center; height: 46rpx;
|
|
text{
|
|
&:nth-child(1){ color: rgba(0,0,0,0.45); font-size: 28rpx; }
|
|
&:nth-child(2){ margin-left: 16rpx; font-weight: bold; font-size: 28rpx; color: #FF5833; }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
.address{
|
|
width: 100%; margin-top: 32rpx; height: 140rpx; background: #fff; border-radius: 10rpx; box-sizing: border-box; padding: 0 24rpx 0 100rpx; position: relative;
|
|
.icon{ width: 36rpx; height: 50rpx; position: absolute; left: 34rpx; top: 50%; transform: translateY(-50%); }
|
|
.text{
|
|
width: 100%; display: flex; flex-direction: column; justify-content: center; height: 100%;
|
|
view{
|
|
&:nth-child(1){ height: 43rpx; width: 100%; font-size: 28rpx; color: rgba(0,0,0,0.85); font-weight: 500; line-height: 33rpx; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
&:nth-child(2){
|
|
margin-top: 14rpx; height: 36rpx; display: flex; align-items: center; font-size: 24rpx; color: rgba(0,0,0,0.65); line-height: 28rpx;
|
|
text{
|
|
margin-right: 36rpx;
|
|
&:last-child{ margin-right: 0; }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
.goods{
|
|
width: 100%; margin-top: 20rpx; background: #fff; border-radius: 10rpx; box-sizing: border-box; padding: 32rpx 24rpx 0;
|
|
.title{ line-height: 38rpx; color: #000; font-size: 32rpx; font-weight: 500; }
|
|
.list_waper{
|
|
width: 100%;
|
|
.list{
|
|
width: 100%; box-sizing: border-box; padding: 28rpx 0 28rpx 190rpx; position: relative; margin-top: 20rpx; min-height: 170rpx; border-bottom: 1rpx solid rgba(0,0,0,0.1);
|
|
&:last-child{ border-bottom: none; }
|
|
.img{
|
|
width: 170rpx; height: 170rpx; position: absolute; left: 0; top: 20rpx;
|
|
image{ border-radius: 10rpx; }
|
|
}
|
|
.text{
|
|
width: 100%;
|
|
.name{
|
|
color: rgba(0,0,0,0.85); line-height: 33rpx; font-size: 28rpx; font-weight: 500; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; position: relative; box-sizing: border-box;
|
|
// text{ position: absolute; right: 0; top: 0; line-height: 40rpx; color: #FF5833; }
|
|
}
|
|
.tag{
|
|
width: 100%; margin-top: 20rpx; display: flex; justify-content: space-between; align-items: center; height: 48rpx;
|
|
view{
|
|
&:nth-child(1){
|
|
display: flex; align-items: center;
|
|
text{ height: 48rpx; line-height: 48rpx; padding: 0 24rpx; box-sizing: border-box; background: #F4F4F4; border-radius: 2rpx; color: rgba(0,0,0,0.65); font-size: 24rpx; }
|
|
}
|
|
&:nth-child(2){ color: rgba(0,0,0,0.65); font-size: 24rpx; }
|
|
}
|
|
}
|
|
.money{
|
|
width: 100%; display: flex; align-items: center; justify-content: flex-end; margin-top: 30rpx;
|
|
text{ font-size: 28rpx; color: rgba(0,0,0,0.85); line-height: 33rpx; }
|
|
}
|
|
.btns{
|
|
display: flex; align-items: center; justify-content: flex-end; margin-left: 20rpx;
|
|
text{
|
|
width: 128rpx; height: 50rpx; border-radius: 50rpx; box-sizing: border-box; border: 2rpx solid #A2A2A4; text-align: center; line-height: 46rpx; color: #A2A2A4; font-size: 24rpx; font-weight: 500; margin-right: 20rpx;
|
|
&:last-child{ margin-right: 0; }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
.order{
|
|
width: 100%; margin-top: 20rpx; background: #fff; border-radius: 10rpx; box-sizing: border-box; padding: 32rpx 24rpx 24rpx;
|
|
.title{ line-height: 38rpx; color: rgba(0,0,0,0.85); font-size: 32rpx; font-weight: 500; }
|
|
.content{
|
|
width: 100%; margin-top: 24rpx;
|
|
.list{
|
|
width: 100%; box-sizing: border-box; padding-left: 130rpx; position: relative; min-height: 40rpx; margin-bottom: 18rpx;
|
|
&:last-child{ margin-bottom: 0; }
|
|
view{
|
|
&:nth-child(1){ color: rgba(0,0,0,0.65); font-size: 28rpx; position: absolute; left: 0; top: 0; line-height: 33rpx; }
|
|
&:nth-child(2){
|
|
color: rgba(0,0,0,0.85); font-size: 28rpx; line-height: 33rpx; display: flex; width: 100%; justify-content: flex-end; align-items: center;
|
|
text:last-child{
|
|
margin-left: 48rpx; color: #3F79FF; position: relative;
|
|
&::after{ content: ""; width: 2rpx; height: 24rpx; background: #A2A2A4; position: absolute; left: -23rpx; top: 50%; transform: translateY(-50%); }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
.bottom{
|
|
width: 100%; box-shadow: 0rpx -1rpx 6rpx 0rpx rgba(0,0,0,0.05); position: fixed; bottom: 0; left: 0; background: #fff;
|
|
.bottom_waper{
|
|
width: 100%; height: 120rpx; box-sizing: border-box; padding: 0 32rpx; display: flex; justify-content: flex-end; align-items: center;
|
|
view{
|
|
width: 228rpx; height: 80rpx; margin-right: 20rpx; box-sizing: border-box; border: 1rpx solid #999999; border-radius: 66rpx; text-align: center; line-height: 80rpx; font-size: 30rpx; color: rgba(0,0,0,0.45);
|
|
&:last-child{ margin-right: 0; }
|
|
&.active{ background: #03AE80; border-color: #03AE80; color: #fff; font-weight: 500; }
|
|
}
|
|
}
|
|
}
|
|
.refund_waper{
|
|
width: 100%; background: #fff; box-sizing: border-box; padding: 32rpx 32rpx 20rpx; border-radius: 30rpx 30rpx 0 0;
|
|
.title{
|
|
line-height: 42rpx; color: rgba(0,0,0,0.65); font-size: 36rpx; font-weight: 500; text-align: center; position: relative;
|
|
.icon{ position: absolute; right: 0; top: 0; }
|
|
}
|
|
.cont{
|
|
width: 100%; margin-top: 49rpx; display: flex; justify-content: center; align-items: center;
|
|
view{
|
|
width: 302rpx; height: 80rpx; box-sizing: border-box; border: 1rpx solid #999999; border-radius: 10rpx; text-align: center; line-height: 78rpx; color: rgba(0,0,0,0.45); font-size: 30rpx;
|
|
&.active{ background: #03AE80; border-color: #03AE80; color: #fff; }
|
|
&:first-child { margin-right: 20rpx; }
|
|
}
|
|
}
|
|
.btn{ width: 100%; height: 80rpx; background: #03AE80; border-radius: 66rpx; text-align: center; line-height: 80rpx; color: #fff; font-size: 32rpx; font-weight: 500; margin-top: 76rpx; }
|
|
}
|
|
</style> |