Initial commit
This commit is contained in:
330
miniprogram/pages/refund/refund-detail/index.js
Normal file
330
miniprogram/pages/refund/refund-detail/index.js
Normal file
@@ -0,0 +1,330 @@
|
||||
// pages/refund/refund-detail/index.js
|
||||
import Toast from 'tdesign-miniprogram/toast/index';
|
||||
import { config } from '../../../config/index';
|
||||
|
||||
Page({
|
||||
data: {
|
||||
refundDetail: null,
|
||||
loading: true,
|
||||
error: null
|
||||
},
|
||||
|
||||
onLoad(options) {
|
||||
console.log('[退款详情] 页面加载', options);
|
||||
|
||||
this.refundId = options.id;
|
||||
if (!this.refundId) {
|
||||
this.setData({
|
||||
error: '退款记录ID不能为空',
|
||||
loading: false
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
this.loadRefundDetail();
|
||||
},
|
||||
|
||||
onShow() {
|
||||
// 页面显示时刷新数据
|
||||
if (this.refundId) {
|
||||
this.loadRefundDetail();
|
||||
}
|
||||
},
|
||||
|
||||
onPullDownRefresh() {
|
||||
this.loadRefundDetail();
|
||||
},
|
||||
|
||||
// 加载退款详情
|
||||
loadRefundDetail() {
|
||||
this.setData({
|
||||
loading: true,
|
||||
error: null
|
||||
});
|
||||
|
||||
let token = wx.getStorageSync('token');
|
||||
if (!token) {
|
||||
// 自动设置测试token
|
||||
const testToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjozNywiZXhwIjoxNzYxNjE5NjAyLCJpYXQiOjE3NjE1MzMyMDJ9.xyZLQbwhYyUDiF9_UOCX39nVwYOHvvd6d4TqwFnT_yg';
|
||||
wx.setStorageSync('token', testToken);
|
||||
token = testToken;
|
||||
console.log('[退款详情] 自动设置测试token');
|
||||
}
|
||||
|
||||
console.log('[退款详情] 请求退款详情', { refundId: this.refundId });
|
||||
|
||||
wx.request({
|
||||
url: `${config.apiBase}/refunds/${this.refundId}`,
|
||||
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 refundDetail = this.processRefundDetail(res.data.data);
|
||||
this.setData({
|
||||
refundDetail: refundDetail,
|
||||
loading: false
|
||||
});
|
||||
|
||||
wx.stopPullDownRefresh();
|
||||
} else {
|
||||
console.error('[退款详情] API错误', res.data);
|
||||
this.setData({
|
||||
error: res.data.message || '获取退款详情失败',
|
||||
loading: false
|
||||
});
|
||||
}
|
||||
},
|
||||
fail: (error) => {
|
||||
console.error('[退款详情] 网络错误', error);
|
||||
this.setData({
|
||||
error: '网络错误',
|
||||
loading: false
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// 处理退款详情数据
|
||||
processRefundDetail(data) {
|
||||
// 状态映射 - 后端返回的是数字状态
|
||||
const statusMap = {
|
||||
1: {
|
||||
text: '待审核',
|
||||
desc: '您的退款申请已提交,请耐心等待审核',
|
||||
icon: '⏳'
|
||||
},
|
||||
2: {
|
||||
text: '审核通过',
|
||||
desc: '退款申请已通过,正在处理退款',
|
||||
icon: '✓'
|
||||
},
|
||||
3: {
|
||||
text: '审核拒绝',
|
||||
desc: '退款申请被拒绝,如有疑问请联系客服',
|
||||
icon: '✗'
|
||||
},
|
||||
4: {
|
||||
text: '退款中',
|
||||
desc: '退款正在处理中,请耐心等待',
|
||||
icon: '⏳'
|
||||
},
|
||||
5: {
|
||||
text: '退款成功',
|
||||
desc: '退款已完成,请查看您的账户余额',
|
||||
icon: '✓'
|
||||
},
|
||||
6: {
|
||||
text: '退款失败',
|
||||
desc: '退款处理失败,如有疑问请联系客服',
|
||||
icon: '✗'
|
||||
}
|
||||
};
|
||||
|
||||
const statusInfo = statusMap[data.status] || {
|
||||
text: '未知状态',
|
||||
desc: '',
|
||||
icon: '?'
|
||||
};
|
||||
|
||||
// 格式化金额 - 添加安全检查,将分转换为元
|
||||
const refundAmount = ((data.refund_amount || 0) / 100).toFixed(2);
|
||||
// 订单金额从关联的订单对象中获取,将分转换为元
|
||||
const orderAmount = ((data.order && data.order.total_amount ? data.order.total_amount : 0) / 100).toFixed(2);
|
||||
|
||||
// 格式化时间
|
||||
const createdAt = this.formatTime(data.created_at);
|
||||
const processedAt = data.processed_at ? this.formatTime(data.processed_at) : null;
|
||||
const completedAt = data.completed_at ? this.formatTime(data.completed_at) : null;
|
||||
|
||||
// 退款方式
|
||||
const refundMethodMap = {
|
||||
'wechat': '微信支付',
|
||||
'alipay': '支付宝',
|
||||
'bank': '银行卡',
|
||||
'balance': '账户余额'
|
||||
};
|
||||
|
||||
// 订单状态
|
||||
const orderStatusMap = {
|
||||
1: '待付款',
|
||||
2: '待发货',
|
||||
3: '待发货',
|
||||
4: '已发货',
|
||||
5: '待收货',
|
||||
6: '已完成',
|
||||
7: '已取消',
|
||||
8: '退货中',
|
||||
9: '已退款'
|
||||
};
|
||||
|
||||
// 处理退款日志
|
||||
const logs = (data.logs || []).map(log => ({
|
||||
id: log.id,
|
||||
action: log.action,
|
||||
remark: log.remark,
|
||||
createdAt: this.formatTime(log.created_at)
|
||||
})).reverse(); // 倒序显示,最新的在前面
|
||||
|
||||
// 生成操作按钮
|
||||
const actions = this.generateActions(data.status);
|
||||
|
||||
return {
|
||||
id: data.id,
|
||||
orderNo: data.order_no,
|
||||
refundAmount: refundAmount,
|
||||
orderAmount: orderAmount,
|
||||
reason: data.reason,
|
||||
adminRemark: data.admin_remark,
|
||||
status: data.status,
|
||||
statusText: statusInfo.text,
|
||||
statusDesc: statusInfo.desc,
|
||||
statusIcon: statusInfo.icon,
|
||||
createdAt: createdAt,
|
||||
processedAt: processedAt,
|
||||
completedAt: completedAt,
|
||||
refundMethod: refundMethodMap[data.refund_method] || '未知方式',
|
||||
orderStatusText: orderStatusMap[data.order_status] || '未知状态',
|
||||
logs: logs,
|
||||
actions: actions
|
||||
};
|
||||
},
|
||||
|
||||
// 生成操作按钮
|
||||
generateActions(status) {
|
||||
const actions = [];
|
||||
|
||||
switch (status) {
|
||||
case 'pending':
|
||||
actions.push({ type: 'cancel', text: '取消申请' });
|
||||
break;
|
||||
case 'rejected':
|
||||
actions.push({ type: 'reapply', 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');
|
||||
const second = String(date.getSeconds()).padStart(2, '0');
|
||||
|
||||
return `${year}-${month}-${day} ${hour}:${minute}:${second}`;
|
||||
},
|
||||
|
||||
// 订单点击
|
||||
onOrderTap() {
|
||||
const { refundDetail } = this.data;
|
||||
if (refundDetail && refundDetail.orderNo) {
|
||||
wx.navigateTo({
|
||||
url: `/pages/order/order-detail/index?orderNo=${refundDetail.orderNo}`
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
// 操作按钮点击
|
||||
onActionTap(e) {
|
||||
const action = e.currentTarget.dataset.action;
|
||||
console.log('[退款详情] 操作按钮点击', action);
|
||||
|
||||
switch (action) {
|
||||
case 'cancel':
|
||||
this.cancelRefund();
|
||||
break;
|
||||
case 'reapply':
|
||||
this.reapplyRefund();
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
// 取消退款申请
|
||||
cancelRefund() {
|
||||
wx.showModal({
|
||||
title: '取消申请',
|
||||
content: '确定要取消这个退款申请吗?',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
this.performCancelRefund();
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// 执行取消退款
|
||||
performCancelRefund() {
|
||||
const token = wx.getStorageSync('token');
|
||||
|
||||
wx.showLoading({ title: '处理中...' });
|
||||
|
||||
wx.request({
|
||||
url: `${config.apiBase}/refunds/${this.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',
|
||||
});
|
||||
|
||||
// 刷新详情
|
||||
setTimeout(() => {
|
||||
this.loadRefundDetail();
|
||||
}, 1000);
|
||||
} 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() {
|
||||
const { refundDetail } = this.data;
|
||||
if (refundDetail) {
|
||||
wx.navigateTo({
|
||||
url: `/pages/refund/refund-apply/index?reapply=1&orderNo=${refundDetail.orderNo}&refundId=${this.refundId}`
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
// 重试
|
||||
onRetry() {
|
||||
this.loadRefundDetail();
|
||||
}
|
||||
});
|
||||
8
miniprogram/pages/refund/refund-detail/index.json
Normal file
8
miniprogram/pages/refund/refund-detail/index.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"navigationBarTitleText": "退款详情",
|
||||
"enablePullDownRefresh": true,
|
||||
"onReachBottomDistance": 50,
|
||||
"usingComponents": {
|
||||
"t-toast": "tdesign-miniprogram/toast/toast"
|
||||
}
|
||||
}
|
||||
115
miniprogram/pages/refund/refund-detail/index.wxml
Normal file
115
miniprogram/pages/refund/refund-detail/index.wxml
Normal file
@@ -0,0 +1,115 @@
|
||||
<!--pages/refund/refund-detail/index.wxml-->
|
||||
<view class="refund-detail" wx:if="{{refundDetail}}">
|
||||
<!-- 退款状态 -->
|
||||
<view class="status-section">
|
||||
<view class="status-icon {{refundDetail.status}}">
|
||||
<text class="icon-text">{{refundDetail.statusIcon}}</text>
|
||||
</view>
|
||||
<view class="status-info">
|
||||
<text class="status-text">{{refundDetail.statusText}}</text>
|
||||
<text class="status-desc">{{refundDetail.statusDesc}}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 退款信息 -->
|
||||
<view class="info-section">
|
||||
<view class="section-title">退款信息</view>
|
||||
<view class="info-item">
|
||||
<text class="info-label">退款金额</text>
|
||||
<text class="info-value amount">¥{{refundDetail.refundAmount}}</text>
|
||||
</view>
|
||||
<view class="info-item">
|
||||
<text class="info-label">申请时间</text>
|
||||
<text class="info-value">{{refundDetail.createdAt}}</text>
|
||||
</view>
|
||||
<view class="info-item" wx:if="{{refundDetail.processedAt}}">
|
||||
<text class="info-label">处理时间</text>
|
||||
<text class="info-value">{{refundDetail.processedAt}}</text>
|
||||
</view>
|
||||
<view class="info-item" wx:if="{{refundDetail.completedAt}}">
|
||||
<text class="info-label">完成时间</text>
|
||||
<text class="info-value">{{refundDetail.completedAt}}</text>
|
||||
</view>
|
||||
<view class="info-item">
|
||||
<text class="info-label">退款方式</text>
|
||||
<text class="info-value">{{refundDetail.refundMethod}}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 订单信息 -->
|
||||
<view class="info-section">
|
||||
<view class="section-title">相关订单</view>
|
||||
<view class="order-card" bindtap="onOrderTap">
|
||||
<view class="order-header">
|
||||
<text class="order-no">订单号:{{refundDetail.orderNo}}</text>
|
||||
<text class="order-status">{{refundDetail.orderStatusText}}</text>
|
||||
</view>
|
||||
<view class="order-amount">
|
||||
<text class="amount-label">订单金额:</text>
|
||||
<text class="amount-value">¥{{refundDetail.orderAmount}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 退款原因 -->
|
||||
<view class="info-section" wx:if="{{refundDetail.reason}}">
|
||||
<view class="section-title">退款原因</view>
|
||||
<view class="reason-content">
|
||||
<text>{{refundDetail.reason}}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 处理备注 -->
|
||||
<view class="info-section" wx:if="{{refundDetail.adminRemark}}">
|
||||
<view class="section-title">处理备注</view>
|
||||
<view class="remark-content">
|
||||
<text>{{refundDetail.adminRemark}}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 退款进度 -->
|
||||
<view class="info-section" wx:if="{{refundDetail.logs && refundDetail.logs.length > 0}}">
|
||||
<view class="section-title">退款进度</view>
|
||||
<view class="progress-list">
|
||||
<view
|
||||
class="progress-item {{index === 0 ? 'current' : ''}}"
|
||||
wx:for="{{refundDetail.logs}}"
|
||||
wx:key="id"
|
||||
>
|
||||
<view class="progress-dot"></view>
|
||||
<view class="progress-content">
|
||||
<view class="progress-title">{{item.action}}</view>
|
||||
<view class="progress-time">{{item.createdAt}}</view>
|
||||
<view class="progress-remark" wx:if="{{item.remark}}">{{item.remark}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<view class="action-section" wx:if="{{refundDetail.actions && refundDetail.actions.length > 0}}">
|
||||
<view
|
||||
class="action-btn {{action.type}}"
|
||||
wx:for="{{refundDetail.actions}}"
|
||||
wx:key="type"
|
||||
data-action="{{action.type}}"
|
||||
bindtap="onActionTap"
|
||||
>
|
||||
{{action.text}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 加载状态 -->
|
||||
<view class="loading-state" wx:if="{{loading}}">
|
||||
<text>加载中...</text>
|
||||
</view>
|
||||
|
||||
<!-- 错误状态 -->
|
||||
<view class="error-state" wx:if="{{error}}">
|
||||
<text>{{error}}</text>
|
||||
<button class="retry-btn" bindtap="onRetry">重试</button>
|
||||
</view>
|
||||
|
||||
<!-- Toast 组件 -->
|
||||
<t-toast id="t-toast" />
|
||||
299
miniprogram/pages/refund/refund-detail/index.wxss
Normal file
299
miniprogram/pages/refund/refund-detail/index.wxss
Normal file
@@ -0,0 +1,299 @@
|
||||
/* pages/refund/refund-detail/index.wxss */
|
||||
.refund-detail {
|
||||
background-color: #f5f5f5;
|
||||
min-height: 100vh;
|
||||
padding-bottom: 120rpx;
|
||||
}
|
||||
|
||||
/* 状态部分 */
|
||||
.status-section {
|
||||
background-color: #fff;
|
||||
padding: 48rpx 32rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.status-icon {
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-right: 32rpx;
|
||||
}
|
||||
|
||||
.status-icon.pending {
|
||||
background-color: #fff3cd;
|
||||
}
|
||||
|
||||
.status-icon.approved {
|
||||
background-color: #d1ecf1;
|
||||
}
|
||||
|
||||
.status-icon.rejected {
|
||||
background-color: #f8d7da;
|
||||
}
|
||||
|
||||
.status-icon.completed {
|
||||
background-color: #d4edda;
|
||||
}
|
||||
|
||||
.icon-text {
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.status-icon.pending .icon-text {
|
||||
color: #856404;
|
||||
}
|
||||
|
||||
.status-icon.approved .icon-text {
|
||||
color: #0c5460;
|
||||
}
|
||||
|
||||
.status-icon.rejected .icon-text {
|
||||
color: #721c24;
|
||||
}
|
||||
|
||||
.status-icon.completed .icon-text {
|
||||
color: #155724;
|
||||
}
|
||||
|
||||
.status-info {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.status-text {
|
||||
display: block;
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.status-desc {
|
||||
font-size: 26rpx;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
/* 信息部分 */
|
||||
.info-section {
|
||||
background-color: #fff;
|
||||
margin-bottom: 24rpx;
|
||||
padding: 32rpx;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 30rpx;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
margin-bottom: 24rpx;
|
||||
padding-bottom: 16rpx;
|
||||
border-bottom: 1rpx solid #eee;
|
||||
}
|
||||
|
||||
.info-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 16rpx 0;
|
||||
border-bottom: 1rpx solid #f5f5f5;
|
||||
}
|
||||
|
||||
.info-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.info-label {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.info-value {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.info-value.amount {
|
||||
color: #ff6b35;
|
||||
font-weight: 600;
|
||||
font-size: 32rpx;
|
||||
}
|
||||
|
||||
/* 订单卡片 */
|
||||
.order-card {
|
||||
border: 1rpx solid #eee;
|
||||
border-radius: 12rpx;
|
||||
padding: 24rpx;
|
||||
background-color: #fafafa;
|
||||
}
|
||||
|
||||
.order-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.order-no {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.order-status {
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
padding: 4rpx 12rpx;
|
||||
background-color: #e9ecef;
|
||||
border-radius: 6rpx;
|
||||
}
|
||||
|
||||
.order-amount {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.amount-label {
|
||||
font-size: 26rpx;
|
||||
color: #666;
|
||||
margin-right: 16rpx;
|
||||
}
|
||||
|
||||
.amount-value {
|
||||
font-size: 28rpx;
|
||||
color: #ff6b35;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* 原因和备注内容 */
|
||||
.reason-content,
|
||||
.remark-content {
|
||||
padding: 24rpx;
|
||||
background-color: #f8f9fa;
|
||||
border-radius: 12rpx;
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
/* 进度列表 */
|
||||
.progress-list {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.progress-item {
|
||||
display: flex;
|
||||
padding: 24rpx 0;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.progress-item:not(:last-child)::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 15rpx;
|
||||
top: 60rpx;
|
||||
bottom: -24rpx;
|
||||
width: 2rpx;
|
||||
background-color: #dee2e6;
|
||||
}
|
||||
|
||||
.progress-item.current .progress-dot {
|
||||
background-color: #ff6b35;
|
||||
border-color: #ff6b35;
|
||||
}
|
||||
|
||||
.progress-item.current::after {
|
||||
background-color: #ff6b35;
|
||||
}
|
||||
|
||||
.progress-dot {
|
||||
width: 32rpx;
|
||||
height: 32rpx;
|
||||
border-radius: 50%;
|
||||
background-color: #dee2e6;
|
||||
border: 4rpx solid #dee2e6;
|
||||
margin-right: 24rpx;
|
||||
flex-shrink: 0;
|
||||
margin-top: 8rpx;
|
||||
}
|
||||
|
||||
.progress-content {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.progress-title {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
font-weight: 500;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.progress-time {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.progress-remark {
|
||||
font-size: 26rpx;
|
||||
color: #666;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
/* 操作按钮 */
|
||||
.action-section {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background-color: #fff;
|
||||
padding: 24rpx 32rpx;
|
||||
border-top: 1rpx solid #eee;
|
||||
display: flex;
|
||||
gap: 24rpx;
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
flex: 1;
|
||||
padding: 24rpx 0;
|
||||
text-align: center;
|
||||
border-radius: 12rpx;
|
||||
font-size: 28rpx;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.action-btn.primary {
|
||||
background-color: #ff6b35;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.action-btn.secondary {
|
||||
background-color: #f8f9fa;
|
||||
color: #666;
|
||||
border: 1rpx solid #dee2e6;
|
||||
}
|
||||
|
||||
/* 加载和错误状态 */
|
||||
.loading-state,
|
||||
.error-state {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 120rpx 32rpx;
|
||||
font-size: 28rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.retry-btn {
|
||||
margin-top: 32rpx;
|
||||
padding: 16rpx 32rpx;
|
||||
background-color: #ff6b35;
|
||||
color: #fff;
|
||||
border: none;
|
||||
border-radius: 8rpx;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
Reference in New Issue
Block a user