3
0
Fork 0
web-store-retail-h5/pages/refund/detail.vue

487 lines
11 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.

<template>
<view class="refund-container">
<!-- 导航栏 -->
<u-navbar
title="退款列表"
:border-bottom="false"
:background="{ backgroundColor: '#005bac' }"
title-color="#fff"
/>
<view class="tips">
<u-icon name="info-circle" color="#005bac" size="20"></u-icon>
<text class="tips-text">如有疑问请联系客服</text>
</view>
<!-- <view class="date-filter">
<view class="date-picker-container">
<view class="date-input-wrapper" @click="showStartDatePicker = true">
<text>{{ startDate || '开始时间' }}</text>
</view>
<text class="separator"></text>
<view class="date-input-wrapper" @click="showEndDatePicker = true">
<text>{{ endDate || '结束时间' }}</text>
</view>
</view>
<button class="search-button" @click="handleSearch">
<u-icon name="search" color="#ffffff" size="20" />
</button>
</view> -->
<!-- 空状态 -->
<u-empty
mode="data"
v-if="refundList.length === 0 && !loading"
text="暂无退款记录"
></u-empty>
<!-- 退款列表 -->
<view class="refund-list">
<u-list @scrolltolower="loadMore" :show-scrollbar="false">
<u-list-item v-for="(item, index) in refundList" :key="index">
<view class="refund-item">
<view class="refund-header">
<view class="order-info">
<text class="order-number"
>订单编号{{ item.businessCode }}</text
>
<text class="member-code">会员编号{{ item.memberCode }}</text>
</view>
<view
class="refund-status"
:class="getStatusClass(item.refundStatus)"
>
{{ getStatusText(item.refundStatus) }}
</view>
</view>
<view class="refund-content">
<view class="refund-amount">
<text class="amount-label">退款金额</text>
<text class="amount-value"
>¥{{ stateFormat(item.refundMoney) }}</text
>
</view>
<view class="refund-time">
<text class="time-label">退款时间</text>
<text class="time-value">{{
formatDate(item.finishTime)
}}</text>
</view>
</view>
</view>
</u-list-item>
</u-list>
<!-- 加载更多 -->
<u-loadmore :status="loadStatus" />
</view>
<u-datetime-picker
:show="showStartDatePicker"
v-model="startDate"
mode="date"
@confirm="onStartDateConfirm"
@cancel="showStartDatePicker = false"
style="flex: 0"
></u-datetime-picker>
<u-datetime-picker
:show="showEndDatePicker"
v-model="endDate"
mode="date"
@confirm="onEndDateConfirm"
@cancel="showEndDatePicker = false"
style="flex: 0"
></u-datetime-picker>
</view>
</template>
<script>
import { getRefundList } from '@/config/mine'
import dayjs from '../../uni_modules/uview-ui/libs/util/dayjs.js'
export default {
name: 'RefundDetail',
data() {
return {
// 筛选条件
startDate: '',
endDate: '',
showStartDatePicker: false,
showEndDatePicker: false,
maxDate: new Date().getTime(),
// 列表数据
refundList: [],
loading: false,
loadStatus: 'loadmore',
// 分页参数
currentPage: 1,
pageSize: 10,
hasMore: true,
// 状态映射
statusMap: {
0: '退款申请中',
1: '退款中',
2: '已退款',
3: '退款失败',
},
}
},
onLoad() {
this.loadRefundList()
},
onPullDownRefresh() {
this.refreshList()
},
methods: {
// 加载退款列表
async loadRefundList(isLoadMore = false) {
if (this.loading) return
this.loading = true
this.loadStatus = 'loading'
try {
const params = {
pageNum: this.currentPage,
pageSize: this.pageSize,
startDate: this.startDate,
endDate: this.endDate,
}
const res = await getRefundList(params)
if (res.code === 200) {
const newList = res.rows || []
if (isLoadMore) {
this.refundList = [...this.refundList, ...newList]
} else {
this.refundList = newList
}
// 判断是否还有更多数据
this.hasMore = newList.length === this.pageSize
this.loadStatus = this.hasMore ? 'loadmore' : 'nomore'
if (this.hasMore) {
this.currentPage++
}
} else {
this.$u.toast(res.message || '加载失败')
this.loadStatus = 'loadmore'
}
} catch (error) {
console.error('加载退款列表失败:', error)
this.$u.toast('加载失败,请重试')
this.loadStatus = 'loadmore'
} finally {
this.loading = false
uni.stopPullDownRefresh()
}
},
stateFormat(val) {
if (val) {
return Number(val)
.toFixed(2)
.replace(/(\d)(?=(\d{3})+\.)/g, ($0, $1) => {
return $1 + ','
})
.replace(/\.$/, '')
}
},
// 加载更多
loadMore() {
if (this.hasMore && !this.loading) {
this.loadRefundList(true)
}
},
// 刷新列表
refreshList() {
this.currentPage = 1
this.hasMore = true
this.loadRefundList()
},
// 搜索
handleSearch() {
if (this.startDate && this.endDate && this.startDate > this.endDate) {
this.$u.toast('开始日期不能大于结束日期')
return
}
this.refreshList()
},
// 重置
handleReset() {
this.startDate = ''
this.endDate = ''
this.refreshList()
},
onStartDateConfirm(e) {
this.startDate = this.formatDate(new Date(e.value))
this.startDateValue = e.value
this.showStartDatePicker = false
},
onEndDateConfirm(e) {
this.endDate = this.formatDate(new Date(e.value))
this.endDateValue = e.value
this.showEndDatePicker = false
},
// 格式化显示日期
formatDate(dateString) {
if (!dateString) return ''
return dayjs(dateString).format('YYYY-MM-DD HH:mm:ss')
},
// 获取状态文本
getStatusText(status) {
console.log(status)
return this.statusMap[status] || '未知状态'
},
// 获取状态样式类
getStatusClass(status) {
const classMap = {
0: 'status-pending',
1: 'status-failed',
2: 'status-success',
3: 'status-cancelled',
}
return classMap[status] || 'status-default'
},
},
}
</script>
<style lang="scss" scoped>
.refund-container {
min-height: 100vh;
background-color: #f5f5f5;
}
.tips {
display: flex;
align-items: center;
justify-content: center;
background-color: #f8f9fa;
margin: 16rpx 30rpx;
padding: 12rpx 20rpx;
border-radius: 4rpx;
border-left: 3rpx solid #005bac;
.tips-text {
font-size: 22rpx;
color: #005bac;
font-weight: 400;
margin-left: 8rpx;
line-height: 1.5;
}
}
.filter-section {
background-color: #fff;
padding: 20rpx 30rpx;
margin-bottom: 20rpx;
.date-filter {
display: flex;
align-items: center;
margin-bottom: 20rpx;
.date-item {
flex: 1;
display: flex;
align-items: center;
justify-content: space-between;
padding: 20rpx;
border: 1px solid #e4e4e4;
border-radius: 8rpx;
background-color: #fafafa;
.date-label {
font-size: 28rpx;
color: #666;
}
.date-value {
font-size: 28rpx;
color: #333;
margin-left: 10rpx;
}
}
.date-separator {
padding: 0 20rpx;
font-size: 28rpx;
color: #666;
}
}
.filter-actions {
display: flex;
justify-content: center;
gap: 20rpx;
}
}
.refund-list {
padding: 10rpx 30rpx 0;
}
.refund-item {
background-color: #fff;
border-radius: 12rpx;
padding: 30rpx;
margin-bottom: 20rpx;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
.refund-header {
display: flex;
justify-content: space-between;
align-items: flex-start;
margin-bottom: 20rpx;
.order-info {
flex: 1;
.order-number {
display: block;
font-size: 28rpx;
color: #333;
font-weight: 500;
margin-bottom: 8rpx;
}
.member-code {
font-size: 24rpx;
color: #666;
}
}
.refund-status {
padding: 8rpx 16rpx;
border-radius: 20rpx;
font-size: 24rpx;
font-weight: 500;
&.status-pending {
background-color: #fff7e6;
color: #fa8c16;
}
&.status-success {
background-color: #f6ffed;
color: #52c41a;
}
&.status-failed {
background-color: #fff2f0;
color: #ff4d4f;
}
&.status-cancelled {
background-color: #f5f5f5;
color: #8c8c8c;
}
&.status-default {
background-color: #f5f5f5;
color: #666;
}
}
}
.refund-content {
display: flex;
justify-content: space-between;
align-items: center;
.refund-amount,
.refund-time {
display: flex;
flex-direction: column;
align-items: flex-start;
.amount-label,
.time-label {
font-size: 24rpx;
color: #666;
margin-bottom: 8rpx;
}
.amount-value {
font-size: 32rpx;
color: #005bac;
font-weight: 600;
}
.time-value {
font-size: 28rpx;
color: #333;
}
}
.refund-time {
align-items: flex-end;
}
}
}
// 响应式适配
@media (max-width: 750rpx) {
.filter-section {
.date-filter {
flex-direction: column;
gap: 20rpx;
.date-separator {
display: none;
}
}
}
}
.date-filter {
display: flex;
align-items: center;
padding: 15px 10px;
background-color: #ffffff;
.date-picker-container {
flex: 1;
display: flex;
align-items: center;
background-color: #f2f2f2;
border-radius: 8px;
padding: 4px;
.date-input-wrapper {
flex: 1;
text-align: center;
padding: 6px 0;
font-size: 14px;
color: #333;
}
.separator {
color: #999;
margin: 0 5px;
}
}
.search-button {
width: 44px;
height: 36px;
margin-left: 10px;
background-color: #007aff;
color: white;
display: flex;
align-items: center;
justify-content: center;
border-radius: 4px;
padding: 0;
line-height: 1;
border: none;
&:after {
border: none;
}
}
}
</style>