Initial commit
This commit is contained in:
328
miniprogram/pages/refund/refund-list/index.js
Normal file
328
miniprogram/pages/refund/refund-list/index.js
Normal file
@@ -0,0 +1,328 @@
|
||||
// pages/refund/refund-list/index.js
|
||||
import Toast from 'tdesign-miniprogram/toast/index';
|
||||
import { config } from '../../../config/index';
|
||||
|
||||
Page({
|
||||
data: {
|
||||
refundList: [],
|
||||
currentStatus: '', // 当前筛选状态
|
||||
loading: false,
|
||||
page: 1,
|
||||
pageSize: 10,
|
||||
hasMore: true
|
||||
},
|
||||
|
||||
onLoad(options) {
|
||||
console.log('[退款记录] 页面加载', options);
|
||||
this.loadRefundList();
|
||||
},
|
||||
|
||||
onShow() {
|
||||
// 页面显示时刷新数据
|
||||
this.refreshData();
|
||||
},
|
||||
|
||||
onPullDownRefresh() {
|
||||
this.refreshData();
|
||||
},
|
||||
|
||||
onReachBottom() {
|
||||
if (this.data.hasMore && !this.data.loading) {
|
||||
this.loadMoreData();
|
||||
}
|
||||
},
|
||||
|
||||
// 刷新数据
|
||||
refreshData() {
|
||||
this.setData({
|
||||
page: 1,
|
||||
hasMore: true,
|
||||
refundList: []
|
||||
});
|
||||
this.loadRefundList();
|
||||
},
|
||||
|
||||
// 加载更多数据
|
||||
loadMoreData() {
|
||||
this.setData({
|
||||
page: this.data.page + 1
|
||||
});
|
||||
this.loadRefundList(false);
|
||||
},
|
||||
|
||||
// 加载退款记录列表
|
||||
loadRefundList(showLoading = true) {
|
||||
if (showLoading) {
|
||||
this.setData({ loading: true });
|
||||
}
|
||||
|
||||
let token = wx.getStorageSync('token');
|
||||
if (!token) {
|
||||
// 自动设置测试token
|
||||
const testToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjozNywiZXhwIjoxNzYxNjE5NjAyLCJpYXQiOjE3NjE1MzMyMDJ9.xyZLQbwhYyUDiF9_UOCX39nVwYOHvvd6d4TqwFnT_yg';
|
||||
wx.setStorageSync('token', testToken);
|
||||
token = testToken;
|
||||
console.log('[退款记录] 自动设置测试token');
|
||||
}
|
||||
|
||||
const params = {
|
||||
page: this.data.page,
|
||||
page_size: this.data.pageSize
|
||||
};
|
||||
|
||||
if (this.data.currentStatus) {
|
||||
params.status = this.data.currentStatus;
|
||||
}
|
||||
|
||||
const queryString = Object.keys(params)
|
||||
.map(key => `${key}=${encodeURIComponent(params[key])}`)
|
||||
.join('&');
|
||||
|
||||
console.log('[退款记录] 请求参数', params);
|
||||
|
||||
wx.request({
|
||||
url: `${config.apiBase}/refunds/user?${queryString}`,
|
||||
method: 'GET',
|
||||
header: {
|
||||
'Authorization': `Bearer ${token}`,
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
success: (res) => {
|
||||
console.log('[退款记录] API响应', res);
|
||||
|
||||
if (res.statusCode === 200 && res.data.code === 200) {
|
||||
const newRefunds = res.data.data.list || [];
|
||||
console.log('API返回的原始数据:', newRefunds);
|
||||
const processedRefunds = newRefunds.map(item => this.processRefundItem(item));
|
||||
console.log('处理后的数据:', processedRefunds);
|
||||
|
||||
this.setData({
|
||||
refundList: this.data.page === 1 ? processedRefunds : [...this.data.refundList, ...processedRefunds],
|
||||
hasMore: newRefunds.length === this.data.pageSize,
|
||||
loading: false
|
||||
});
|
||||
|
||||
if (showLoading) {
|
||||
wx.stopPullDownRefresh();
|
||||
}
|
||||
} else {
|
||||
console.error('[退款记录] API错误', res.data);
|
||||
Toast({
|
||||
context: this,
|
||||
selector: '#t-toast',
|
||||
message: res.data.message || '获取退款记录失败',
|
||||
theme: 'error',
|
||||
});
|
||||
this.setData({ loading: false });
|
||||
}
|
||||
},
|
||||
fail: (error) => {
|
||||
console.error('[退款记录] 网络错误', error);
|
||||
Toast({
|
||||
context: this,
|
||||
selector: '#t-toast',
|
||||
message: '网络错误',
|
||||
theme: 'error',
|
||||
});
|
||||
this.setData({ loading: false });
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// 处理退款记录数据
|
||||
processRefundItem(item) {
|
||||
// 状态文本映射 - 后端返回的是数字状态
|
||||
const statusMap = {
|
||||
1: '待审核',
|
||||
2: '审核通过',
|
||||
3: '审核拒绝',
|
||||
4: '退款中',
|
||||
5: '退款成功',
|
||||
6: '退款失败'
|
||||
};
|
||||
|
||||
// 状态字符串映射(用于CSS类名)
|
||||
const statusClassMap = {
|
||||
1: 'pending',
|
||||
2: 'approved',
|
||||
3: 'rejected',
|
||||
4: 'processing',
|
||||
5: 'completed',
|
||||
6: 'failed'
|
||||
};
|
||||
|
||||
// 格式化金额 - 添加安全检查,将分转换为元
|
||||
const refundAmount = ((item.refund_amount || 0) / 100).toFixed(2);
|
||||
|
||||
// 格式化时间
|
||||
const createdAt = this.formatTime(item.created_at);
|
||||
|
||||
// 生成操作按钮
|
||||
const actions = this.generateActions(statusClassMap[item.status]);
|
||||
|
||||
return {
|
||||
id: item.id,
|
||||
orderNo: item.order ? item.order.order_no : '',
|
||||
refundAmount: refundAmount,
|
||||
reason: item.refund_reason,
|
||||
status: statusClassMap[item.status] || 'pending',
|
||||
statusText: statusMap[item.status] || '未知状态',
|
||||
createdAt: createdAt,
|
||||
actions: actions
|
||||
};
|
||||
},
|
||||
|
||||
// 生成操作按钮
|
||||
generateActions(status) {
|
||||
const actions = [];
|
||||
|
||||
switch (status) {
|
||||
case 'pending':
|
||||
actions.push({ type: 'cancel', text: '取消申请' });
|
||||
break;
|
||||
case 'approved':
|
||||
actions.push({ type: 'view', text: '查看详情' });
|
||||
break;
|
||||
case 'rejected':
|
||||
actions.push({ type: 'view', text: '查看详情' });
|
||||
actions.push({ type: 'reapply', text: '重新申请' });
|
||||
break;
|
||||
case 'completed':
|
||||
actions.push({ type: 'view', text: '查看详情' });
|
||||
break;
|
||||
}
|
||||
|
||||
return actions;
|
||||
},
|
||||
|
||||
// 格式化时间
|
||||
formatTime(timeStr) {
|
||||
if (!timeStr) return '';
|
||||
|
||||
const date = new Date(timeStr);
|
||||
const year = date.getFullYear();
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(date.getDate()).padStart(2, '0');
|
||||
const hour = String(date.getHours()).padStart(2, '0');
|
||||
const minute = String(date.getMinutes()).padStart(2, '0');
|
||||
|
||||
return `${year}-${month}-${day} ${hour}:${minute}`;
|
||||
},
|
||||
|
||||
// 状态筛选
|
||||
onStatusFilter(e) {
|
||||
const status = e.currentTarget.dataset.status;
|
||||
console.log('[退款记录] 状态筛选', status);
|
||||
|
||||
this.setData({
|
||||
currentStatus: status,
|
||||
page: 1,
|
||||
hasMore: true,
|
||||
refundList: []
|
||||
});
|
||||
|
||||
this.loadRefundList();
|
||||
},
|
||||
|
||||
// 退款记录项点击
|
||||
onRefundItemTap(e) {
|
||||
const refund = e.currentTarget.dataset.refund;
|
||||
console.log('[退款记录] 点击退款记录', refund);
|
||||
|
||||
// 跳转到退款详情页面
|
||||
wx.navigateTo({
|
||||
url: `/pages/refund/refund-detail/index?id=${refund.id}`
|
||||
});
|
||||
},
|
||||
|
||||
// 操作按钮点击
|
||||
onActionTap(e) {
|
||||
e.stopPropagation(); // 阻止事件冒泡
|
||||
|
||||
const { refundId, action } = e.currentTarget.dataset;
|
||||
console.log('[退款记录] 操作按钮点击', { refundId, action });
|
||||
|
||||
switch (action) {
|
||||
case 'cancel':
|
||||
this.cancelRefund(refundId);
|
||||
break;
|
||||
case 'view':
|
||||
wx.navigateTo({
|
||||
url: `/pages/refund/refund-detail/index?id=${refundId}`
|
||||
});
|
||||
break;
|
||||
case 'reapply':
|
||||
this.reapplyRefund(refundId);
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
// 取消退款申请
|
||||
cancelRefund(refundId) {
|
||||
wx.showModal({
|
||||
title: '取消申请',
|
||||
content: '确定要取消这个退款申请吗?',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
this.performCancelRefund(refundId);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// 执行取消退款
|
||||
performCancelRefund(refundId) {
|
||||
const token = wx.getStorageSync('token');
|
||||
|
||||
wx.showLoading({ title: '处理中...' });
|
||||
|
||||
wx.request({
|
||||
url: `${config.apiBase}/refunds/${refundId}/cancel`,
|
||||
method: 'PUT',
|
||||
header: {
|
||||
'Authorization': `Bearer ${token}`,
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
success: (res) => {
|
||||
wx.hideLoading();
|
||||
|
||||
if (res.statusCode === 200 && res.data.code === 200) {
|
||||
Toast({
|
||||
context: this,
|
||||
selector: '#t-toast',
|
||||
message: '取消成功',
|
||||
theme: 'success',
|
||||
});
|
||||
|
||||
// 刷新列表
|
||||
this.refreshData();
|
||||
} else {
|
||||
Toast({
|
||||
context: this,
|
||||
selector: '#t-toast',
|
||||
message: res.data.message || '取消失败',
|
||||
theme: 'error',
|
||||
});
|
||||
}
|
||||
},
|
||||
fail: (error) => {
|
||||
wx.hideLoading();
|
||||
console.error('[退款记录] 取消退款失败', error);
|
||||
Toast({
|
||||
context: this,
|
||||
selector: '#t-toast',
|
||||
message: '网络错误',
|
||||
theme: 'error',
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// 重新申请退款
|
||||
reapplyRefund(refundId) {
|
||||
// 获取原退款记录信息,跳转到退款申请页面
|
||||
wx.navigateTo({
|
||||
url: `/pages/refund/refund-apply/index?reapply=1&refundId=${refundId}`
|
||||
});
|
||||
}
|
||||
});
|
||||
8
miniprogram/pages/refund/refund-list/index.json
Normal file
8
miniprogram/pages/refund/refund-list/index.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"navigationBarTitleText": "退款记录",
|
||||
"enablePullDownRefresh": true,
|
||||
"onReachBottomDistance": 50,
|
||||
"usingComponents": {
|
||||
"t-toast": "tdesign-miniprogram/toast/toast"
|
||||
}
|
||||
}
|
||||
124
miniprogram/pages/refund/refund-list/index.wxml
Normal file
124
miniprogram/pages/refund/refund-list/index.wxml
Normal file
@@ -0,0 +1,124 @@
|
||||
<!--pages/refund/refund-list/index.wxml-->
|
||||
<view class="refund-list">
|
||||
<!-- 页面标题 -->
|
||||
<view class="page-header">
|
||||
<text class="page-title">退款记录</text>
|
||||
</view>
|
||||
|
||||
<!-- 状态筛选 -->
|
||||
<view class="status-filter">
|
||||
<view
|
||||
class="filter-item {{currentStatus === '' ? 'active' : ''}}"
|
||||
data-status=""
|
||||
bindtap="onStatusFilter"
|
||||
>
|
||||
全部
|
||||
</view>
|
||||
<view
|
||||
class="filter-item {{currentStatus === 'pending' ? 'active' : ''}}"
|
||||
data-status="pending"
|
||||
bindtap="onStatusFilter"
|
||||
>
|
||||
待审核
|
||||
</view>
|
||||
<view
|
||||
class="filter-item {{currentStatus === 'approved' ? 'active' : ''}}"
|
||||
data-status="approved"
|
||||
bindtap="onStatusFilter"
|
||||
>
|
||||
审核通过
|
||||
</view>
|
||||
<view
|
||||
class="filter-item {{currentStatus === 'rejected' ? 'active' : ''}}"
|
||||
data-status="rejected"
|
||||
bindtap="onStatusFilter"
|
||||
>
|
||||
审核拒绝
|
||||
</view>
|
||||
<view
|
||||
class="filter-item {{currentStatus === 'processing' ? 'active' : ''}}"
|
||||
data-status="processing"
|
||||
bindtap="onStatusFilter"
|
||||
>
|
||||
退款中
|
||||
</view>
|
||||
<view
|
||||
class="filter-item {{currentStatus === 'completed' ? 'active' : ''}}"
|
||||
data-status="completed"
|
||||
bindtap="onStatusFilter"
|
||||
>
|
||||
退款成功
|
||||
</view>
|
||||
<view
|
||||
class="filter-item {{currentStatus === 'failed' ? 'active' : ''}}"
|
||||
data-status="failed"
|
||||
bindtap="onStatusFilter"
|
||||
>
|
||||
退款失败
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 退款记录列表 -->
|
||||
<view class="refund-items" wx:if="{{refundList.length > 0}}">
|
||||
<view
|
||||
class="refund-item"
|
||||
wx:for="{{refundList}}"
|
||||
wx:key="id"
|
||||
bindtap="onRefundItemTap"
|
||||
data-refund="{{item}}"
|
||||
>
|
||||
<!-- 退款状态和时间 -->
|
||||
<view class="refund-header">
|
||||
<view class="refund-status {{item.status}}">{{item.statusText}}</view>
|
||||
<view class="refund-time">{{item.createdAt}}</view>
|
||||
</view>
|
||||
|
||||
<!-- 订单信息 -->
|
||||
<view class="order-info">
|
||||
<text class="order-label">订单号:</text>
|
||||
<text class="order-no">{{item.orderNo}}</text>
|
||||
</view>
|
||||
|
||||
<!-- 退款金额 -->
|
||||
<view class="refund-amount">
|
||||
<text class="amount-label">退款金额:</text>
|
||||
<text class="amount-value">¥{{item.refundAmount}}</text>
|
||||
</view>
|
||||
|
||||
<!-- 退款原因 -->
|
||||
<view class="refund-reason" wx:if="{{item.reason}}">
|
||||
<text class="reason-label">退款原因:</text>
|
||||
<text class="reason-text">{{item.reason}}</text>
|
||||
</view>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<view class="refund-actions" wx:if="{{item.actions && item.actions.length > 0}}">
|
||||
<view
|
||||
class="action-btn {{action.type}}"
|
||||
wx:for="{{item.actions}}"
|
||||
wx:for-item="action"
|
||||
wx:key="type"
|
||||
data-refund-id="{{item.id}}"
|
||||
data-action="{{action.type}}"
|
||||
bindtap="onActionTap"
|
||||
>
|
||||
{{action.text}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 空状态 -->
|
||||
<view class="empty-state" wx:if="{{refundList.length === 0 && !loading}}">
|
||||
<image class="empty-icon" src="/assets/images/empty-refund.png" mode="aspectFit"></image>
|
||||
<text class="empty-text">暂无退款记录</text>
|
||||
</view>
|
||||
|
||||
<!-- 加载状态 -->
|
||||
<view class="loading-state" wx:if="{{loading}}">
|
||||
<text>加载中...</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- Toast 组件 -->
|
||||
<t-toast id="t-toast" />
|
||||
208
miniprogram/pages/refund/refund-list/index.wxss
Normal file
208
miniprogram/pages/refund/refund-list/index.wxss
Normal file
@@ -0,0 +1,208 @@
|
||||
/* pages/refund/refund-list/index.wxss */
|
||||
.refund-list {
|
||||
background-color: #f5f5f5;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
/* 页面标题 */
|
||||
.page-header {
|
||||
background-color: #fff;
|
||||
padding: 32rpx;
|
||||
border-bottom: 1rpx solid #eee;
|
||||
}
|
||||
|
||||
.page-title {
|
||||
font-size: 36rpx;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
/* 状态筛选 */
|
||||
.status-filter {
|
||||
display: flex;
|
||||
background-color: #fff;
|
||||
padding: 24rpx 32rpx;
|
||||
border-bottom: 1rpx solid #eee;
|
||||
}
|
||||
|
||||
.filter-item {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
padding: 16rpx 0;
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
border-radius: 8rpx;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.filter-item.active {
|
||||
background-color: #ff6b35;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* 退款记录列表 */
|
||||
.refund-items {
|
||||
padding: 24rpx 32rpx;
|
||||
}
|
||||
|
||||
.refund-item {
|
||||
background-color: #fff;
|
||||
border-radius: 16rpx;
|
||||
padding: 32rpx;
|
||||
margin-bottom: 24rpx;
|
||||
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
/* 退款头部 */
|
||||
.refund-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.refund-status {
|
||||
padding: 8rpx 16rpx;
|
||||
border-radius: 8rpx;
|
||||
font-size: 24rpx;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.refund-status.pending {
|
||||
background-color: #fff3cd;
|
||||
color: #856404;
|
||||
}
|
||||
|
||||
.refund-status.approved {
|
||||
background-color: #d1ecf1;
|
||||
color: #0c5460;
|
||||
}
|
||||
|
||||
.refund-status.rejected {
|
||||
background-color: #f8d7da;
|
||||
color: #721c24;
|
||||
}
|
||||
|
||||
.refund-status.completed {
|
||||
background-color: #d4edda;
|
||||
color: #155724;
|
||||
}
|
||||
|
||||
.refund-time {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
/* 订单信息 */
|
||||
.order-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.order-label {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
margin-right: 16rpx;
|
||||
}
|
||||
|
||||
.order-no {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* 退款金额 */
|
||||
.refund-amount {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.amount-label {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
margin-right: 16rpx;
|
||||
}
|
||||
|
||||
.amount-value {
|
||||
font-size: 32rpx;
|
||||
color: #ff6b35;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* 退款原因 */
|
||||
.refund-reason {
|
||||
display: flex;
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.reason-label {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
margin-right: 16rpx;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.reason-text {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
/* 操作按钮 */
|
||||
.refund-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 16rpx;
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
padding: 12rpx 24rpx;
|
||||
border-radius: 8rpx;
|
||||
font-size: 26rpx;
|
||||
text-align: center;
|
||||
min-width: 120rpx;
|
||||
}
|
||||
|
||||
.action-btn.primary {
|
||||
background-color: #ff6b35;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.action-btn.secondary {
|
||||
background-color: #f8f9fa;
|
||||
color: #666;
|
||||
border: 1rpx solid #dee2e6;
|
||||
}
|
||||
|
||||
/* 空状态 */
|
||||
.empty-state {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 120rpx 32rpx;
|
||||
}
|
||||
|
||||
.empty-icon {
|
||||
width: 200rpx;
|
||||
height: 200rpx;
|
||||
margin-bottom: 32rpx;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.empty-text {
|
||||
font-size: 28rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
/* 加载状态 */
|
||||
.loading-state {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 80rpx 32rpx;
|
||||
font-size: 28rpx;
|
||||
color: #999;
|
||||
}
|
||||
Reference in New Issue
Block a user