forked from angelo/web-retail-h5
736 lines
15 KiB
Vue
736 lines
15 KiB
Vue
<!--
|
|
* @Descripttion: 订单撤销页面
|
|
* @version: 1.0.0
|
|
* @Author: kBank
|
|
* @Date: 2022-11-21 15:11:22
|
|
-->
|
|
<template>
|
|
<view class="content">
|
|
<view
|
|
v-for="(item, index) in orderLists"
|
|
:key="`order-${item.orderCode || index}`"
|
|
class="orderList_i"
|
|
>
|
|
<view @click.stop="getDetails(item)">
|
|
<view class="disFlex atm just mbt10">
|
|
<view class="disFlex atm">
|
|
<view class="quan">{{ item.orderTypeVal }}</view>
|
|
<view class="tit1">订单编号{{ item.orderCode }}</view>
|
|
</view>
|
|
<view class="tit2">
|
|
{{ item.orderStatusVal }}
|
|
</view>
|
|
</view>
|
|
|
|
<view
|
|
v-for="(ctem, cndex) in item.itemList"
|
|
:key="`item-${ctem.productName || cndex}`"
|
|
class="disFlex atm just mbt10"
|
|
>
|
|
<view class="disFlex atm">
|
|
<img :src="ctem.cover" alt="商品图片" />
|
|
<view class="tit3">
|
|
{{ ctem.productName }}
|
|
</view>
|
|
</view>
|
|
<view style="text-align: right">
|
|
<view class="tit4">
|
|
{{ formatPrice(ctem.price) }}
|
|
</view>
|
|
<view class="tit5">x{{ ctem.quantity }}</view>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="tit1">创建时间:{{ item.creationTime }}</view>
|
|
</view>
|
|
|
|
<view class="xian"></view>
|
|
|
|
<view class="disFlex">
|
|
<view style="flex: 1"></view>
|
|
<view class="disFlex">
|
|
<u-button
|
|
type="primary"
|
|
class="lBtn"
|
|
:plain="true"
|
|
shape="circle"
|
|
text="撤销订单"
|
|
color="#999"
|
|
@click="cancleOrder(item)"
|
|
></u-button>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 订单详情弹窗 -->
|
|
<u-popup
|
|
v-model="detailsShow"
|
|
class="pop"
|
|
closeable
|
|
:round="10"
|
|
mode="center"
|
|
@close="detailsShow = false"
|
|
>
|
|
<view class="pop_a">
|
|
<view class="t_tit">订单详情</view>
|
|
<view class="pop_t">商品信息</view>
|
|
<view class="xian"></view>
|
|
|
|
<view class="orderList_a">
|
|
<view
|
|
v-for="(ctem, cndex) in details.itemList"
|
|
:key="`detail-item-${ctem.productName || cndex}`"
|
|
class="disFlex atm just mbt10"
|
|
>
|
|
<view class="disFlex just" style="flex: 1">
|
|
<img :src="ctem.cover" alt="商品图片" />
|
|
<view style="flex: 1">
|
|
<view class="disFlex atm just">
|
|
<view class="tit3">
|
|
{{ ctem.productName }}
|
|
</view>
|
|
<view class="tit5">x{{ ctem.quantity }}</view>
|
|
</view>
|
|
<view
|
|
class="tit3"
|
|
style="color: #999; font-size: 24rpx; margin-top: 6rpx"
|
|
>
|
|
{{ ctem.specsName }}
|
|
</view>
|
|
<view class="tit4">
|
|
{{ formatPrice(ctem.price) }}
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="disFlex atm just mbt10">
|
|
<view class="tit1">订单金额</view>
|
|
<view class="tit6">
|
|
{{ formatCurrency(details.orderAmount) }}
|
|
</view>
|
|
</view>
|
|
|
|
<view class="disFlex atm just mbt10">
|
|
<view class="tit1">订单业绩(PV)</view>
|
|
<view class="tit6">
|
|
{{ formatCurrency(details.orderAchieve) }}
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 暂时注释的订单业绩(BV)
|
|
<view class="disFlex atm just mbt10">
|
|
<view class="tit1">订单业绩(BV)</view>
|
|
<view class="tit6">
|
|
{{ formatCurrency(details.orderAssAchieve) }}
|
|
</view>
|
|
</view>
|
|
-->
|
|
|
|
<view class="xian"></view>
|
|
|
|
<view class="pop_t mbt10">收货人信息</view>
|
|
<view class="disFlex atm mbt10 tit6">
|
|
<view>{{ details.recName }}</view>
|
|
<view>{{ details.recPhone }}</view>
|
|
</view>
|
|
<view class="mbt10 tit1">
|
|
{{ details.recProvince }} {{ details.recCity }}
|
|
{{ details.recCounty }} {{ details.address }}
|
|
</view>
|
|
</view>
|
|
</u-popup>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
import * as api from '@/config/order.js'
|
|
|
|
export default {
|
|
name: 'CancelOrder',
|
|
data() {
|
|
return {
|
|
orderTypes: [],
|
|
rightShow: false,
|
|
remarkEd: '',
|
|
content: '确认取消订单?',
|
|
isRemark: false,
|
|
cancelCode: '',
|
|
details: {},
|
|
orderStatusList: [],
|
|
detailsShow: false,
|
|
isTab: -1,
|
|
// 查询参数
|
|
queryParams: {
|
|
pageNum: 1,
|
|
pageSize: 50,
|
|
},
|
|
select: {
|
|
orderType: '',
|
|
},
|
|
orderLists: [],
|
|
}
|
|
},
|
|
|
|
onLoad() {
|
|
this.getDataList()
|
|
},
|
|
|
|
onShow() {},
|
|
|
|
onReachBottom() {
|
|
this.queryParams.pageNum++
|
|
this.getDataList()
|
|
},
|
|
|
|
methods: {
|
|
/**
|
|
* 格式化价格显示
|
|
*/
|
|
formatPrice(price) {
|
|
if (!price && price !== 0) return ''
|
|
// 这里可以根据需要调用相应的格式化方法
|
|
return this.numberToCurrency(this.isLocal(price))
|
|
},
|
|
|
|
/**
|
|
* 格式化货币显示
|
|
*/
|
|
formatCurrency(amount) {
|
|
if (!amount && amount !== 0) return ''
|
|
return this.toThousandthAndKeepDecimal(amount)
|
|
},
|
|
|
|
/**
|
|
* 数字转货币格式 - 替代原来的filter
|
|
*/
|
|
numberToCurrency(num) {
|
|
// 这里实现原来filter的逻辑
|
|
if (!num && num !== 0) return ''
|
|
return parseFloat(num).toFixed(2)
|
|
},
|
|
|
|
/**
|
|
* 本地化处理 - 替代原来的filter
|
|
*/
|
|
isLocal(value) {
|
|
// 这里实现原来filter的逻辑
|
|
return value
|
|
},
|
|
|
|
/**
|
|
* 千分位格式化 - 替代原来的filter
|
|
*/
|
|
toThousandthAndKeepDecimal(num) {
|
|
if (!num && num !== 0) return '0.00'
|
|
return parseFloat(num)
|
|
.toFixed(2)
|
|
.replace(/\d{1,3}(?=(\d{3})+(\.\d*)?$)/g, '$&,')
|
|
},
|
|
|
|
/**
|
|
* 撤销订单
|
|
*/
|
|
cancleOrder(item) {
|
|
const that = this
|
|
uni.showModal({
|
|
title: '确定撤销订单?',
|
|
success: function (response) {
|
|
if (response.confirm) {
|
|
api
|
|
.selfRevokeListCheck(item)
|
|
.then(res => {
|
|
if (res.code === 200) {
|
|
api
|
|
.selfRevokeOrder(item)
|
|
.then(res => {
|
|
if (res.code === 200) {
|
|
uni.showToast({
|
|
title: res.msg,
|
|
icon: 'none',
|
|
duration: 1500,
|
|
})
|
|
that.orderLists = []
|
|
that.getDataList()
|
|
} else {
|
|
uni.showToast({
|
|
title: res.msg,
|
|
icon: 'none',
|
|
duration: 1500,
|
|
})
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('撤销订单失败:', error)
|
|
uni.showToast({
|
|
title: '撤销订单失败',
|
|
icon: 'none',
|
|
duration: 1500,
|
|
})
|
|
})
|
|
} else {
|
|
uni.showToast({
|
|
title: res.msg,
|
|
icon: 'none',
|
|
duration: 1500,
|
|
})
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('检查撤销条件失败:', error)
|
|
uni.showToast({
|
|
title: '操作失败,请重试',
|
|
icon: 'none',
|
|
duration: 1500,
|
|
})
|
|
})
|
|
}
|
|
},
|
|
})
|
|
},
|
|
|
|
/**
|
|
* 获取订单详情
|
|
*/
|
|
getDetails(item) {
|
|
api
|
|
.orderDetails(item.orderCode)
|
|
.then(res => {
|
|
this.details = res.data || {}
|
|
this.detailsShow = true
|
|
})
|
|
.catch(error => {
|
|
console.error('获取订单详情失败:', error)
|
|
uni.showToast({
|
|
title: '获取订单详情失败',
|
|
icon: 'none',
|
|
duration: 1500,
|
|
})
|
|
})
|
|
},
|
|
|
|
/**
|
|
* 获取订单状态列表
|
|
*/
|
|
getOrderStatus() {
|
|
api
|
|
.orderStatus()
|
|
.then(res => {
|
|
res.data.unshift({
|
|
label: '全部',
|
|
value: '',
|
|
})
|
|
this.orderStatusList = res.data
|
|
})
|
|
.catch(error => {
|
|
console.error('获取订单状态失败:', error)
|
|
})
|
|
},
|
|
|
|
/**
|
|
* 获取数据列表
|
|
*/
|
|
getDataList() {
|
|
api
|
|
.selfRevokeList(Object.assign({}, this.queryParams))
|
|
.then(res => {
|
|
this.orderLists = this.orderLists.concat(res.rows || [])
|
|
this.total = res.total
|
|
})
|
|
.catch(error => {
|
|
console.error('获取订单列表失败:', error)
|
|
uni.showToast({
|
|
title: '获取订单列表失败',
|
|
icon: 'none',
|
|
duration: 1500,
|
|
})
|
|
})
|
|
},
|
|
},
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.index_header {
|
|
background: #fff;
|
|
font-size: 18px;
|
|
font-family:
|
|
PingFang SC-Semibold,
|
|
PingFang SC;
|
|
font-weight: 600;
|
|
color: #333333;
|
|
text-align: center;
|
|
padding: 10px 0;
|
|
position: fixed;
|
|
width: 100%;
|
|
z-index: 100000000;
|
|
}
|
|
|
|
.shareImg {
|
|
position: fixed;
|
|
margin: 14rpx 24rpx;
|
|
z-index: 1000000000;
|
|
right: 10rpx;
|
|
top: 10rpx;
|
|
|
|
img {
|
|
width: 40rpx;
|
|
height: 40rpx;
|
|
}
|
|
}
|
|
|
|
.zhan1 {
|
|
height: 50px;
|
|
}
|
|
|
|
.seach {
|
|
background: #fff;
|
|
overflow: hidden;
|
|
padding: 20rpx;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
position: relative;
|
|
border-bottom: 2rpx solid #eee;
|
|
|
|
.seach_i {
|
|
padding: 0 20rpx;
|
|
border-radius: 34rpx;
|
|
background: #f5f6f8;
|
|
flex: 1;
|
|
}
|
|
|
|
.seatch_r {
|
|
background: #005bac;
|
|
border-radius: 50%;
|
|
padding: 8rpx;
|
|
margin-left: 24rpx;
|
|
}
|
|
}
|
|
|
|
.timeSlide {
|
|
display: flex;
|
|
align-items: center;
|
|
padding: 38rpx 26rpx;
|
|
|
|
.timeA {
|
|
font-size: 26rpx;
|
|
font-family: Source Han Sans CN;
|
|
font-weight: 400;
|
|
color: #333;
|
|
margin-right: 46rpx;
|
|
border-bottom: 2rpx solid #fff;
|
|
}
|
|
|
|
.timeB {
|
|
width: 158rpx;
|
|
font-size: 24rpx;
|
|
font-family: Arial;
|
|
font-weight: 400;
|
|
color: #999999;
|
|
margin-right: 46rpx;
|
|
border-bottom: 2rpx solid #eee;
|
|
text-align: center;
|
|
}
|
|
}
|
|
|
|
.tab {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
padding: 0 24rpx;
|
|
margin-top: 20rpx;
|
|
margin-bottom: 6rpx;
|
|
}
|
|
|
|
.tab_i {
|
|
text-align: center;
|
|
font-size: 28rpx;
|
|
font-family: PingFang SC;
|
|
font-weight: 400;
|
|
color: #333333;
|
|
white-space: nowrap;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
}
|
|
|
|
.heng {
|
|
width: 24px;
|
|
height: 2px;
|
|
background: #ed1d25;
|
|
border-radius: 1px 1px 1px 1px;
|
|
margin-top: 4rpx;
|
|
}
|
|
|
|
.heng1 {
|
|
width: 24px;
|
|
height: 2px;
|
|
background: #fff;
|
|
border-radius: 1px 1px 1px 1px;
|
|
margin-top: 4rpx;
|
|
}
|
|
|
|
.hui {
|
|
height: 10rpx;
|
|
background: #eee;
|
|
}
|
|
|
|
.zhan {
|
|
height: 80rpx;
|
|
}
|
|
|
|
.con_top {
|
|
position: fixed;
|
|
background: #fff;
|
|
width: 100%;
|
|
z-index: 10;
|
|
}
|
|
|
|
.disFlex {
|
|
display: flex;
|
|
}
|
|
|
|
.atm {
|
|
align-items: center;
|
|
}
|
|
|
|
.just {
|
|
justify-content: space-between;
|
|
}
|
|
|
|
.mbt10 {
|
|
margin-bottom: 14rpx;
|
|
}
|
|
|
|
.orderList_i {
|
|
padding: 25rpx;
|
|
border-bottom: 22rpx solid #eee;
|
|
background: #fff;
|
|
|
|
img {
|
|
width: 124rpx;
|
|
height: 124rpx;
|
|
border-radius: 20rpx;
|
|
margin-right: 20rpx;
|
|
}
|
|
}
|
|
|
|
.orderList_a {
|
|
img {
|
|
width: 124rpx;
|
|
height: 124rpx;
|
|
border-radius: 20rpx;
|
|
margin-right: 20rpx;
|
|
}
|
|
}
|
|
|
|
.quan {
|
|
background: #3d3d3d;
|
|
border-radius: 15px;
|
|
font-size: 20rpx;
|
|
font-family: Source Han Sans CN;
|
|
font-weight: 400;
|
|
color: #ffffff;
|
|
padding: 5rpx 20rpx;
|
|
margin-right: 10rpx;
|
|
}
|
|
|
|
.tit1 {
|
|
font-size: 24rpx;
|
|
font-family: Source Han Sans CN;
|
|
font-weight: 400;
|
|
color: #999999;
|
|
}
|
|
|
|
.tit2 {
|
|
font-size: 24rpx;
|
|
font-family: Source Han Sans CN;
|
|
font-weight: 400;
|
|
color: #69a35b;
|
|
}
|
|
|
|
.tit3 {
|
|
font-size: 28rpx;
|
|
font-family: Source Han Sans CN;
|
|
font-weight: 400;
|
|
color: #333333;
|
|
}
|
|
|
|
.tit4 {
|
|
font-size: 24rpx;
|
|
font-family: Source Han Sans CN;
|
|
font-weight: 400;
|
|
color: #005bac;
|
|
}
|
|
|
|
.tit5 {
|
|
font-size: 22rpx;
|
|
font-family: Source Han Sans CN;
|
|
font-weight: 400;
|
|
color: #666666;
|
|
}
|
|
|
|
.tit6 {
|
|
font-size: 26rpx;
|
|
font-family: Source Han Sans CN;
|
|
font-weight: 400;
|
|
color: #333333;
|
|
}
|
|
|
|
.xian {
|
|
background: #eee;
|
|
height: 2rpx;
|
|
margin: 20rpx 0;
|
|
}
|
|
|
|
.lBtn {
|
|
margin-right: 20rpx;
|
|
}
|
|
|
|
.pop_a {
|
|
padding: 20rpx;
|
|
}
|
|
|
|
.t_tit {
|
|
text-align: center;
|
|
margin-top: 20px;
|
|
}
|
|
|
|
.pop_t {
|
|
font-size: 28rpx;
|
|
font-family: Source Han Sans CN;
|
|
font-weight: bold;
|
|
color: #333333;
|
|
}
|
|
|
|
:deep(.u-popup__content) {
|
|
// width: 90%;
|
|
}
|
|
|
|
.pop :deep(.u-popup__content) {
|
|
width: 90%;
|
|
}
|
|
|
|
.rightPopup {
|
|
width: 645rpx;
|
|
|
|
.popup_top {
|
|
padding: 25rpx;
|
|
background-color: rgba(176, 196, 222, 0.45);
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
font-size: 28rpx;
|
|
font-family: Source Han Sans CN;
|
|
font-weight: 400;
|
|
color: #333333;
|
|
border-bottom: 2rpx solid #eeeeee;
|
|
|
|
.top_red {
|
|
color: #005bac;
|
|
}
|
|
}
|
|
|
|
.typesBox {
|
|
margin-top: 40rpx;
|
|
|
|
.typeTitle {
|
|
padding: 0 24rpx;
|
|
font-size: 30rpx;
|
|
font-family: Source Han Sans CN;
|
|
font-weight: bold;
|
|
color: #333333;
|
|
}
|
|
|
|
.choiceBox {
|
|
padding: 0 12rpx;
|
|
display: flex;
|
|
margin-top: 17rpx;
|
|
align-items: center;
|
|
|
|
.flex_btn {
|
|
background-color: #f4f4f4;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: 14rpx 20rpx;
|
|
border-radius: 30rpx;
|
|
font-size: 24rpx;
|
|
font-family: Source Han Sans CN;
|
|
font-weight: 400;
|
|
color: #333333;
|
|
margin: 17rpx 5rpx;
|
|
width: 100%;
|
|
}
|
|
|
|
.selectbtn {
|
|
background-color: #005bac;
|
|
color: #ffffff;
|
|
}
|
|
}
|
|
|
|
.choiceBox1 {
|
|
padding: 0 12rpx;
|
|
display: flex;
|
|
margin-top: 17rpx;
|
|
align-items: center;
|
|
flex-wrap: wrap;
|
|
|
|
.flex_btn {
|
|
background-color: rgba(176, 196, 222, 0.45);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: 14rpx 20rpx;
|
|
border-radius: 30rpx;
|
|
font-size: 24rpx;
|
|
font-family: Source Han Sans CN;
|
|
font-weight: 400;
|
|
color: #333333;
|
|
margin: 17rpx 5rpx;
|
|
}
|
|
|
|
.selectbtn {
|
|
background-color: #005bac;
|
|
color: #ffffff;
|
|
}
|
|
}
|
|
}
|
|
|
|
.footer {
|
|
position: fixed;
|
|
bottom: 0;
|
|
display: flex;
|
|
align-items: center;
|
|
width: 100%;
|
|
|
|
.footer_l {
|
|
width: 327rpx;
|
|
text-align: center;
|
|
background: #f3f3f3;
|
|
height: 100rpx;
|
|
line-height: 100rpx;
|
|
}
|
|
|
|
.footer_r {
|
|
width: 327rpx;
|
|
text-align: center;
|
|
background: #005bac;
|
|
height: 100rpx;
|
|
line-height: 100rpx;
|
|
color: #fff;
|
|
}
|
|
}
|
|
}
|
|
|
|
.contain :deep(.u-transition) {
|
|
top: 45px !important;
|
|
}
|
|
|
|
.timePicker :deep(.u-transition) {
|
|
z-index: 10076 !important;
|
|
}
|
|
</style>
|