366 lines
11 KiB
Vue
366 lines
11 KiB
Vue
<template>
|
||
<BasePage :back="back">
|
||
<div class="tradelist b_l_w">
|
||
<div class="tabs">
|
||
<van-tabs class="area" v-model:active="TradeArea" color="#f00" title-active-color="#222"
|
||
title-inactive-color="#999" line-width="0" line-height=".667vw" @change="changeMall">
|
||
<van-tab v-for="i in mallList" :title="i.label" :name="i.value"></van-tab>
|
||
</van-tabs>
|
||
|
||
<van-tabs class="states" v-model:active="activeTab" color="#ca2904" title-active-color="#ca2904"
|
||
title-inactive-color="#000" line-width="4vw" line-height=".667vw" @change="onTabChange">
|
||
<van-tab title="全部" name=""></van-tab>
|
||
<van-tab v-for="i in tradeStates" :title="i.label" :name="String(i.value)"></van-tab>
|
||
</van-tabs>
|
||
</div>
|
||
<van-search v-model="_searchParams.ordernum" left-icon=" " shape="round" placeholder="输入订单号搜索" @search="onSearch"
|
||
@clear="onClear">
|
||
<template #right-icon>
|
||
<van-icon name="/img/sort-search.png" @click="onSearch"></van-icon>
|
||
</template>
|
||
</van-search>
|
||
|
||
<BaseList ref="baseList" url="/v1/client/FOrdersClient" :params="searchParams" :parseData="parseData"
|
||
style="padding: 3.33vw;" @refresh="onRefresh" @load="onLoad">
|
||
<template #default="{ item }">
|
||
<div class="list">
|
||
<div class="order_box">
|
||
<span :class="'state' + item.mallstate" class="state">{{ item.mallstatename.slice(0, 2) }}</span>
|
||
<span>订单编号:{{ item.ordernum }}</span>
|
||
<img src="/img/copy_b.png" @click="$copyText(item.ordernum); $showSuccessToast('复制成功')" alt="">
|
||
</div>
|
||
<div class="goods_box">
|
||
<img :src="$file(item.shopimg || item.proimg)" alt="">
|
||
<div class="goods_info">
|
||
<div class="tit">{{ item.shopname || item.proname }}</div>
|
||
<div class="spec" v-if="!item.shopname">
|
||
<span>{{ item.proskuname }}</span>
|
||
<p>x{{ item.buynums }}</p>
|
||
</div>
|
||
<div class="concession">
|
||
<span v-if="item.mallstate !== 5">¥{{ item.proskusaleprice?.toFixed(2) }}</span>
|
||
<span v-else>{{ item.proskusaleprice?.toFixed(2) }}积分</span>
|
||
<p v-if="item.discountratio && item.mallstate !== 5">惠利{{ item.discountratio }}%</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="price" v-if="item.mallstate !== 5">
|
||
实付:<span>¥<b>{{ item.realmoney?.toFixed(2) }}</b></span>
|
||
</div>
|
||
<div class="price" v-else>
|
||
实付:<span><b>{{ item.ordermoney?.toFixed(2) }}</b></span>
|
||
</div>
|
||
<div class="state_box">
|
||
<b :class="'b' + item.state">{{ item.statename }}</b>
|
||
<div class="btn_box">
|
||
<button v-if="item.state === 0" @click="cancelTrade(item)">取消订单</button>
|
||
<button v-if="!item.shopname" @click="$navigate(`TradeDetail?ordernum=${item.ordernum}`)">查看详情</button>
|
||
<button v-else @click="$navigate(`MerchantTradeDetail?id=${item.ordernum}`)">查看详情</button>
|
||
<button v-if="item.state === 3 || item.state === 4" @click="showLogistics(item)">物流信息</button>
|
||
|
||
<button v-if="item.state === 3" @click="confirmReceipt(item)">确认收货</button>
|
||
<!-- <button v-if="item.state === 3" @click="refundTrade(item)">退款</button> -->
|
||
<button v-if="item.state === 0" @click="$navigate(`Pay?ordernum=${item.ordernum}`)">立即支付</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
</BaseList>
|
||
|
||
|
||
<van-popup v-model:show="logisticsVisible" round position="bottom" teleport="body">
|
||
<div class="logistics-popup">
|
||
<div class="logistics-tit">物流信息</div>
|
||
<div class="logistics-content">
|
||
<div class="logistics-item">
|
||
<span class="label">物流公司</span>
|
||
<span class="value">{{ currentLogistics?.exportname }}</span>
|
||
</div>
|
||
<div class="logistics-item">
|
||
<span class="label">物流单号</span>
|
||
<span class="value">{{ currentLogistics?.exportnum }}</span>
|
||
<img src="/img/copy_b.png" @click="$copyText(currentLogistics?.exportnum); $showSuccessToast('复制成功')"
|
||
alt="">
|
||
</div>
|
||
</div>
|
||
<div class="logistics-close">
|
||
<van-button type="primary" block round color="#ca2904" @click="logisticsVisible = false">关闭</van-button>
|
||
</div>
|
||
</div>
|
||
</van-popup>
|
||
</div>
|
||
</BasePage>
|
||
</template>
|
||
|
||
<script>
|
||
export default {
|
||
name: 'TradeList',
|
||
|
||
data() {
|
||
return {
|
||
TradeArea: this.$route.query.TradeArea || 0,
|
||
activeTab: this.$route.query.state || '',
|
||
_searchParams: {
|
||
ordernum: '',
|
||
state: '',
|
||
},
|
||
tradeStates: [
|
||
{
|
||
"value": 0,
|
||
"label": "待付款"
|
||
},
|
||
{
|
||
"value": 1,
|
||
"label": "待发货"
|
||
},
|
||
{
|
||
"value": 3,
|
||
"label": "待收货"
|
||
},
|
||
{
|
||
"value": 4,
|
||
"label": "已完成"
|
||
},
|
||
{
|
||
"value": 6,
|
||
"label": "已退款"
|
||
}
|
||
],
|
||
mallList: [
|
||
{ value: 0, label: '全部订单' },
|
||
{
|
||
"value": 1,
|
||
"label": "礼包订单"
|
||
},
|
||
{
|
||
"value": 3,
|
||
"label": "商城订单"
|
||
},
|
||
{
|
||
"value": 4,
|
||
"label": "买单订单"
|
||
},
|
||
{
|
||
"value": 5,
|
||
"label": "积分订单"
|
||
},
|
||
],
|
||
_initializing: true,
|
||
logisticsVisible: false,
|
||
currentLogistics: null,
|
||
}
|
||
},
|
||
|
||
computed: {
|
||
parseData() {
|
||
return res => res.data.items
|
||
},
|
||
searchParams() {
|
||
const params = {
|
||
ordernum: this._searchParams.ordernum,
|
||
state: this._searchParams.state === '' ? '' : Number(this._searchParams.state),
|
||
}
|
||
if (this.TradeArea !== 0) {
|
||
params.mallstate = this.TradeArea
|
||
}
|
||
return params
|
||
},
|
||
},
|
||
|
||
|
||
watch: {
|
||
'$route.query.TradeArea': {
|
||
handler(val) {
|
||
this.TradeArea = val !== undefined ? Number(val) : 0
|
||
},
|
||
immediate: true
|
||
},
|
||
'$route.query.state': {
|
||
handler(val) {
|
||
this.activeTab = val || ''
|
||
this._searchParams.state = val || ''
|
||
},
|
||
immediate: true
|
||
}
|
||
},
|
||
|
||
beforeRouteLeave(to, from) {
|
||
if (to.name === 'TradeDetail' || to.name === 'MerchantTradeDetail') {
|
||
sessionStorage.setItem('TradeList_scroll', window.scrollY || 0)
|
||
sessionStorage.setItem('TradeList_fromDetail', '1')
|
||
}
|
||
this._pauseScroll = true
|
||
},
|
||
|
||
mounted() {
|
||
const isReturningFromDetail = sessionStorage.getItem('TradeList_fromDetail') === '1'
|
||
sessionStorage.removeItem('TradeList_fromDetail')
|
||
this.loadFilterOptions()
|
||
if (!isReturningFromDetail) {
|
||
sessionStorage.setItem('TradeList_scroll', '0')
|
||
}
|
||
|
||
this._pauseScroll = false
|
||
window.addEventListener('scroll', this.saveScroll)
|
||
this.$refs.baseList?.refresh()
|
||
},
|
||
|
||
onUnmounted() {
|
||
window.removeEventListener('scroll', this.saveScroll)
|
||
},
|
||
|
||
methods: {
|
||
saveScroll() {
|
||
if (this._pauseScroll) return
|
||
const scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0
|
||
sessionStorage.setItem('TradeList_scroll', scrollTop)
|
||
},
|
||
onLoad() {
|
||
const scrollTop = sessionStorage.getItem('TradeList_scroll')
|
||
if (scrollTop && scrollTop !== '0' && !this._scrollRestored) {
|
||
this._scrollRestored = true
|
||
window.removeEventListener('scroll', this.saveScroll)
|
||
this.$nextTick(() => {
|
||
window.scrollTo(0, Number(scrollTop))
|
||
})
|
||
setTimeout(() => {
|
||
window.addEventListener('scroll', this.saveScroll)
|
||
}, 100)
|
||
}
|
||
},
|
||
// 加载订单状态和类型列表
|
||
async loadFilterOptions() {
|
||
try {
|
||
const [stateRes, areaRes] = await Promise.all([
|
||
this.$get('/v1/client/FOrdersClient/orderstate'),
|
||
this.$get('/v1/client/EProsClient/mallstate'),
|
||
])
|
||
this.tradeStates = stateRes.data || []
|
||
this.mallList = [{ value: 0, label: '全部订单' }, ...(areaRes.data || [])]
|
||
this._initializing = false
|
||
} catch (err) {
|
||
this.$showFailToast(err.message || '加载失败')
|
||
}
|
||
},
|
||
|
||
// Tab 切换 - 订单状态
|
||
onTabChange(name) {
|
||
this._searchParams.state = name
|
||
// this.$refs.baseList?.refresh()
|
||
},
|
||
|
||
// Tab 切换 - 订单类型
|
||
changeMall(val) {
|
||
this.TradeArea = val
|
||
this._searchParams.state = ''
|
||
this.activeTab = ''
|
||
// 不需要手动 refresh,BaseList 的 watch params 会自动触发
|
||
},
|
||
|
||
// 搜索 & 清除
|
||
onSearch() {
|
||
this.$refs.baseList?.refresh()
|
||
},
|
||
onClear() {
|
||
this._searchParams.ordernum = ''
|
||
this.$refs.baseList?.refresh()
|
||
},
|
||
|
||
// 确认收货
|
||
confirmReceipt(item) {
|
||
this.$showConfirmDialog({ title: '是否确认收货' })
|
||
.then(() => this.$put(`/v1/client/FOrdersClient/${item.ordernum}/receipt`))
|
||
.then(() => {
|
||
this.$showSuccessToast('确认收货成功')
|
||
this.$refs.baseList?.refresh()
|
||
})
|
||
.catch()
|
||
},
|
||
|
||
// 取消订单
|
||
cancelTrade(item) {
|
||
this.$showConfirmDialog({ title: '是否确认取消订单' })
|
||
.then(() => this.$put(`/v1/client/FOrdersClient/${item.ordernum}/cancel`))
|
||
.then(() => {
|
||
this.$showSuccessToast('取消订单成功')
|
||
this.$refs.baseList?.refresh()
|
||
})
|
||
.catch()
|
||
},
|
||
|
||
// 退款
|
||
// refundTrade(item) {
|
||
// this.$showConfirmDialog({ title: '是否申请退款' })
|
||
// .then(() => this.$get(`/v1/client/FOrdersClient/${item.ordernum}/refund`))
|
||
// .then(() => {
|
||
// this.$showSuccessToast('退款申请成功')
|
||
// this.$refs.baseList?.refresh()
|
||
// })
|
||
// .catch()
|
||
// },
|
||
|
||
// 显示物流信息
|
||
showLogistics(item) {
|
||
this.currentLogistics = item
|
||
this.logisticsVisible = true
|
||
},
|
||
|
||
back() {
|
||
this.$navigate('/My');
|
||
},
|
||
|
||
onRefresh() { },
|
||
},
|
||
}
|
||
</script>
|
||
|
||
<style lang="less" scoped>
|
||
.logistics-popup {
|
||
padding: 20px;
|
||
|
||
.logistics-tit {
|
||
font-size: 16px;
|
||
font-weight: bold;
|
||
text-align: center;
|
||
margin-bottom: 20px;
|
||
}
|
||
|
||
.logistics-content {
|
||
background: #f5f5f5;
|
||
border-radius: 8px;
|
||
padding: 15px;
|
||
margin-bottom: 20px;
|
||
}
|
||
|
||
.logistics-item {
|
||
display: flex;
|
||
align-items: center;
|
||
margin-bottom: 12px;
|
||
|
||
&:last-child {
|
||
margin-bottom: 0;
|
||
}
|
||
|
||
.label {
|
||
width: 70px;
|
||
color: #999;
|
||
}
|
||
|
||
.value {
|
||
flex: 1;
|
||
color: #333;
|
||
}
|
||
|
||
img {
|
||
width: 16px;
|
||
height: 16px;
|
||
margin-left: 8px;
|
||
}
|
||
}
|
||
|
||
.logistics-close {
|
||
margin-top: 10px;
|
||
}
|
||
}
|
||
</style>
|