8 changed files with 2150 additions and 67 deletions
@ -0,0 +1,612 @@ |
|||
<template> |
|||
<view class="after-sale-add"> |
|||
<!-- 商品信息卡片 --> |
|||
<view class="card-section"> |
|||
<view class="card-header"> |
|||
<text class="card-title">商品信息</text> |
|||
</view> |
|||
<view class="product-section"> |
|||
<image |
|||
class="product-image" |
|||
:src="productInfo.image || '/static/image/default-product.png'" |
|||
mode="aspectFill" |
|||
/> |
|||
<view class="product-info"> |
|||
<text class="product-title">{{ |
|||
productInfo.title || "IP文创公仔" |
|||
}}</text> |
|||
<text class="product-subtitle">{{ |
|||
productInfo.subtitle || "这里是文创公仔的副标题" |
|||
}}</text> |
|||
<text class="product-desc">{{ |
|||
productInfo.description || "介绍" |
|||
}}</text> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 售后表单卡片 --> |
|||
<view class="card-section"> |
|||
<view class="card-header"> |
|||
<text class="card-title">售后信息</text> |
|||
</view> |
|||
<view class="form-section"> |
|||
<!-- 售后类型 --> |
|||
<view class="form-item" @click="showTypePopup"> |
|||
<text class="form-label">售后类型</text> |
|||
<view class="form-value-with-icon"> |
|||
<text class="form-value">{{ afterSaleForm.type }}</text> |
|||
<uni-icons type="right" size="16" color="#999" /> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 售后原因 --> |
|||
<view class="form-item" @click="showReasonPopup"> |
|||
<text class="form-label">售后原因</text> |
|||
<view class="form-value-with-icon"> |
|||
<text class="form-value">{{ afterSaleForm.reason }}</text> |
|||
<uni-icons type="right" size="16" color="#999" /> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 理由说明 --> |
|||
<view class="form-item"> |
|||
<text class="form-label">理由说明</text> |
|||
<textarea |
|||
class="reason-textarea" |
|||
v-model="afterSaleForm.description" |
|||
placeholder="请详细描述问题..." |
|||
maxlength="500" |
|||
/> |
|||
<text class="char-count" |
|||
>{{ afterSaleForm.description.length }}/500</text |
|||
> |
|||
</view> |
|||
|
|||
<!-- 图片上传 --> |
|||
<view class="form-item"> |
|||
<text class="form-label" |
|||
>问题图片 <text class="required">*</text></text |
|||
> |
|||
<text class="form-sub-label">最多可上传9张图片</text> |
|||
<view class="image-upload-section"> |
|||
<uni-file-picker |
|||
v-model="afterSaleForm.images" |
|||
fileMediatype="image" |
|||
mode="grid" |
|||
:limit="9" |
|||
@select="onImageSelect" |
|||
@delete="onImageDelete" |
|||
/> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 提交按钮 --> |
|||
<view class="submit-section"> |
|||
<button |
|||
class="submit-btn" |
|||
@click="submitAfterSale" |
|||
:disabled="!canSubmit" |
|||
> |
|||
提交售后申请 |
|||
</button> |
|||
</view> |
|||
|
|||
<!-- 售后类型选择弹窗 --> |
|||
<uni-popup ref="typePopup" type="bottom"> |
|||
<view class="type-popup"> |
|||
<view class="popup-header"> |
|||
<text class="popup-title">选择售后类型</text> |
|||
<text class="popup-close" @click="closeTypePopup">×</text> |
|||
</view> |
|||
<view class="popup-content"> |
|||
<view |
|||
class="type-option" |
|||
v-for="(type, index) in typeOptions" |
|||
:key="index" |
|||
@click="selectType(type)" |
|||
> |
|||
<view class="type-content"> |
|||
<text class="type-text">{{ type.text }}</text> |
|||
<uni-icons |
|||
v-if="afterSaleForm.type === type.text" |
|||
type="checkmarkempty" |
|||
size="16" |
|||
color="#ff4757" |
|||
/> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<view class="popup-actions"> |
|||
<button class="confirm-btn" @click="confirmType">确认</button> |
|||
</view> |
|||
</view> |
|||
</uni-popup> |
|||
|
|||
<!-- 售后原因选择弹窗 --> |
|||
<uni-popup ref="reasonPopup" type="bottom"> |
|||
<view class="reason-popup"> |
|||
<view class="popup-header"> |
|||
<text class="popup-title">选择售后原因</text> |
|||
<text class="popup-close" @click="closeReasonPopup">×</text> |
|||
</view> |
|||
<view class="popup-content"> |
|||
<view |
|||
class="reason-option" |
|||
v-for="(reason, index) in reasonOptions" |
|||
:key="index" |
|||
@click="selectReason(reason)" |
|||
> |
|||
<view class="reason-content"> |
|||
<text class="reason-text">{{ reason.text }}</text> |
|||
<uni-icons |
|||
v-if="afterSaleForm.reason === reason.text" |
|||
type="checkmarkempty" |
|||
size="16" |
|||
color="#ff4757" |
|||
/> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<view class="popup-actions"> |
|||
<button class="confirm-btn" @click="confirmReason">确认</button> |
|||
</view> |
|||
</view> |
|||
</uni-popup> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
data() { |
|||
return { |
|||
productInfo: { |
|||
image: "", |
|||
title: "IP文创公仔", |
|||
subtitle: "这里是文创公仔的副标题", |
|||
description: "介绍", |
|||
}, |
|||
afterSaleForm: { |
|||
type: "换货", |
|||
reason: "商品质量问题", |
|||
description: "", |
|||
images: [], |
|||
}, |
|||
typeOptions: [ |
|||
{ text: "换货", value: "exchange" }, |
|||
{ text: "仅退款", value: "refund" }, |
|||
{ text: "退货", value: "return" }, |
|||
], |
|||
reasonOptions: [ |
|||
{ text: "商品质量问题", value: "quality" }, |
|||
{ text: "物流包装破损", value: "damage" }, |
|||
{ text: "未收到货", value: "not_received" }, |
|||
{ text: "商品与描述不符", value: "mismatch" }, |
|||
{ text: "其他原因", value: "other" }, |
|||
], |
|||
selectedType: null, |
|||
selectedReason: null, |
|||
}; |
|||
}, |
|||
computed: { |
|||
canSubmit() { |
|||
return ( |
|||
this.afterSaleForm.description.trim().length > 0 && |
|||
this.afterSaleForm.images.length > 0 |
|||
); |
|||
}, |
|||
}, |
|||
onLoad(options) { |
|||
// 接收商品信息参数 |
|||
if (options.productInfo) { |
|||
this.productInfo = JSON.parse(decodeURIComponent(options.productInfo)); |
|||
} |
|||
}, |
|||
methods: { |
|||
// 显示售后类型选择弹窗 |
|||
showTypePopup() { |
|||
this.$refs.typePopup.open(); |
|||
}, |
|||
|
|||
// 关闭售后类型选择弹窗 |
|||
closeTypePopup() { |
|||
this.$refs.typePopup.close(); |
|||
}, |
|||
|
|||
// 选择售后类型 |
|||
selectType(type) { |
|||
this.selectedType = type; |
|||
}, |
|||
|
|||
// 确认售后类型 |
|||
confirmType() { |
|||
if (this.selectedType) { |
|||
this.afterSaleForm.type = this.selectedType.text; |
|||
} |
|||
this.closeTypePopup(); |
|||
}, |
|||
|
|||
// 显示售后原因选择弹窗 |
|||
showReasonPopup() { |
|||
this.$refs.reasonPopup.open(); |
|||
}, |
|||
|
|||
// 关闭售后原因选择弹窗 |
|||
closeReasonPopup() { |
|||
this.$refs.reasonPopup.close(); |
|||
}, |
|||
|
|||
// 选择售后原因 |
|||
selectReason(reason) { |
|||
this.selectedReason = reason; |
|||
}, |
|||
|
|||
// 确认售后原因 |
|||
confirmReason() { |
|||
if (this.selectedReason) { |
|||
this.afterSaleForm.reason = this.selectedReason.text; |
|||
} |
|||
this.closeReasonPopup(); |
|||
}, |
|||
|
|||
// 图片选择回调 |
|||
onImageSelect(e) { |
|||
console.log("选择图片:", e); |
|||
uni.uploadFile({ |
|||
url: this.NEWAPIURL_DES + "/system/oss/upload", //仅为示例,非真实的接口地址 |
|||
filePath: e.tempFilePaths[0], |
|||
name: "file", |
|||
|
|||
success: (uploadFileRes) => { |
|||
console.log(uploadFileRes); |
|||
let data = JSON.parse(uploadFileRes.data); |
|||
if (data.code == 200) { |
|||
this.afterSaleForm.images.push(data.url); |
|||
} |
|||
}, |
|||
}); |
|||
}, |
|||
|
|||
// 图片删除回调 |
|||
onImageDelete(e) { |
|||
console.log("删除图片:", e); |
|||
}, |
|||
|
|||
// 提交售后申请 |
|||
async submitAfterSale() { |
|||
if (!this.canSubmit) { |
|||
uni.showToast({ |
|||
title: "请填写理由说明并上传图片", |
|||
icon: "none", |
|||
}); |
|||
return; |
|||
} |
|||
|
|||
try { |
|||
uni.showLoading({ |
|||
title: "提交中...", |
|||
}); |
|||
|
|||
// 构建提交数据 |
|||
const submitData = { |
|||
productId: this.productInfo.id, |
|||
type: this.afterSaleForm.type, |
|||
reason: this.afterSaleForm.reason, |
|||
description: this.afterSaleForm.description, |
|||
images: this.afterSaleForm.images.map( |
|||
(item) => item.url || item.path |
|||
), |
|||
}; |
|||
|
|||
// 调用售后申请API |
|||
this.Post(submitData, "/framework/afterSale/create", "DES") |
|||
.then((res) => { |
|||
uni.hideLoading(); |
|||
if (res.code === 200) { |
|||
uni.showToast({ |
|||
title: "售后申请提交成功", |
|||
icon: "success", |
|||
}); |
|||
|
|||
// 延迟跳转到售后列表 |
|||
setTimeout(() => { |
|||
uni.redirectTo({ |
|||
url: "/subPackages/afterSale/list", |
|||
}); |
|||
}, 1500); |
|||
} else { |
|||
uni.showToast({ |
|||
title: res.msg || "提交失败", |
|||
icon: "none", |
|||
}); |
|||
} |
|||
}) |
|||
.catch((error) => { |
|||
uni.hideLoading(); |
|||
console.error("提交售后申请失败:", error); |
|||
uni.showToast({ |
|||
title: "提交失败", |
|||
icon: "none", |
|||
}); |
|||
}); |
|||
} catch (error) { |
|||
uni.hideLoading(); |
|||
console.error("提交售后申请失败:", error); |
|||
uni.showToast({ |
|||
title: "提交失败", |
|||
icon: "none", |
|||
}); |
|||
} |
|||
}, |
|||
}, |
|||
}; |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.after-sale-add { |
|||
min-height: 100vh; |
|||
background-color: #f8f9fa; |
|||
padding: 16rpx; |
|||
padding-bottom: calc(120rpx + env(safe-area-inset-bottom)); |
|||
padding-bottom: calc(120rpx + constant(safe-area-inset-bottom)); |
|||
} |
|||
|
|||
// 卡片样式 |
|||
.card-section { |
|||
background-color: #fff; |
|||
border-radius: 16rpx; |
|||
margin-bottom: 16rpx; |
|||
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.08); |
|||
overflow: hidden; |
|||
} |
|||
|
|||
.card-header { |
|||
padding: 20rpx 24rpx; |
|||
border-bottom: 1rpx solid #f0f0f0; |
|||
background-color: #fafafa; |
|||
} |
|||
|
|||
.card-title { |
|||
font-size: 30rpx; |
|||
font-weight: 600; |
|||
color: #333; |
|||
} |
|||
|
|||
// 商品信息区域 |
|||
.product-section { |
|||
padding: 24rpx; |
|||
display: flex; |
|||
align-items: flex-start; |
|||
} |
|||
|
|||
.product-image { |
|||
width: 120rpx; |
|||
height: 120rpx; |
|||
border-radius: 12rpx; |
|||
background-color: #f0f0f0; |
|||
margin-right: 20rpx; |
|||
flex-shrink: 0; |
|||
} |
|||
|
|||
.product-info { |
|||
flex: 1; |
|||
display: flex; |
|||
flex-direction: column; |
|||
} |
|||
|
|||
.product-title { |
|||
font-size: 32rpx; |
|||
font-weight: 600; |
|||
color: #333; |
|||
margin-bottom: 6rpx; |
|||
} |
|||
|
|||
.product-subtitle { |
|||
font-size: 26rpx; |
|||
color: #666; |
|||
margin-bottom: 4rpx; |
|||
} |
|||
|
|||
.product-desc { |
|||
font-size: 24rpx; |
|||
color: #999; |
|||
} |
|||
|
|||
// 表单区域 |
|||
.form-section { |
|||
padding: 0; |
|||
} |
|||
|
|||
.form-item { |
|||
padding: 20rpx 24rpx; |
|||
border-bottom: 1rpx solid #f0f0f0; |
|||
|
|||
&:last-child { |
|||
border-bottom: none; |
|||
} |
|||
} |
|||
|
|||
.form-label { |
|||
font-size: 28rpx; |
|||
color: #333; |
|||
font-weight: 500; |
|||
margin-bottom: 12rpx; |
|||
display: block; |
|||
} |
|||
|
|||
.required { |
|||
color: #ff4757; |
|||
font-weight: bold; |
|||
} |
|||
|
|||
.form-sub-label { |
|||
font-size: 24rpx; |
|||
color: #999; |
|||
margin-bottom: 12rpx; |
|||
display: block; |
|||
} |
|||
|
|||
.form-value { |
|||
font-size: 28rpx; |
|||
color: #333; |
|||
} |
|||
|
|||
.form-value-with-icon { |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: space-between; |
|||
padding: 12rpx 0; |
|||
} |
|||
|
|||
// 理由说明文本框 |
|||
.reason-textarea { |
|||
width: 100%; |
|||
min-height: 120rpx; |
|||
max-height: 200rpx; |
|||
padding: 16rpx; |
|||
border: 1rpx solid #e0e0e0; |
|||
border-radius: 12rpx; |
|||
font-size: 28rpx; |
|||
color: #333; |
|||
background-color: #fafafa; |
|||
box-sizing: border-box; |
|||
resize: none; |
|||
} |
|||
|
|||
.char-count { |
|||
font-size: 24rpx; |
|||
color: #999; |
|||
text-align: right; |
|||
margin-top: 8rpx; |
|||
display: block; |
|||
} |
|||
|
|||
// 图片上传区域 |
|||
.image-upload-section { |
|||
margin-top: 12rpx; |
|||
} |
|||
|
|||
// 提交按钮区域 |
|||
.submit-section { |
|||
position: fixed; |
|||
bottom: 0; |
|||
left: 0; |
|||
right: 0; |
|||
background-color: #fff; |
|||
padding: 20rpx 30rpx; |
|||
padding-bottom: calc(20rpx + env(safe-area-inset-bottom)); |
|||
border-top: 1rpx solid #eee; |
|||
box-shadow: 0 -2rpx 12rpx rgba(0, 0, 0, 0.08); |
|||
} |
|||
|
|||
.submit-btn { |
|||
width: 100%; |
|||
height: 80rpx; |
|||
background-color: #ff4757; |
|||
color: #fff; |
|||
border: none; |
|||
border-radius: 12rpx; |
|||
font-size: 32rpx; |
|||
font-weight: 600; |
|||
|
|||
&:disabled { |
|||
background-color: #ccc; |
|||
} |
|||
} |
|||
|
|||
// 售后类型选择弹窗 |
|||
.type-popup { |
|||
background-color: #fff; |
|||
border-radius: 20rpx 20rpx 0 0; |
|||
overflow: hidden; |
|||
} |
|||
|
|||
.popup-header { |
|||
display: flex; |
|||
justify-content: space-between; |
|||
align-items: center; |
|||
padding: 30rpx; |
|||
border-bottom: 1rpx solid #f0f0f0; |
|||
} |
|||
|
|||
.popup-title { |
|||
font-size: 32rpx; |
|||
font-weight: 600; |
|||
color: #333; |
|||
} |
|||
|
|||
.popup-close { |
|||
font-size: 40rpx; |
|||
color: #999; |
|||
} |
|||
|
|||
.popup-content { |
|||
max-height: 600rpx; |
|||
overflow-y: auto; |
|||
} |
|||
|
|||
.type-option { |
|||
padding: 30rpx; |
|||
border-bottom: 1rpx solid #f0f0f0; |
|||
|
|||
&:last-child { |
|||
border-bottom: none; |
|||
} |
|||
} |
|||
|
|||
.type-content { |
|||
display: flex; |
|||
justify-content: space-between; |
|||
align-items: center; |
|||
} |
|||
|
|||
.type-text { |
|||
font-size: 28rpx; |
|||
color: #333; |
|||
} |
|||
|
|||
.popup-actions { |
|||
padding: 30rpx; |
|||
border-top: 1rpx solid #f0f0f0; |
|||
} |
|||
|
|||
.confirm-btn { |
|||
width: 100%; |
|||
height: 80rpx; |
|||
background-color: #ff4757; |
|||
color: #fff; |
|||
border: none; |
|||
border-radius: 12rpx; |
|||
font-size: 32rpx; |
|||
font-weight: 600; |
|||
} |
|||
|
|||
// 售后原因选择弹窗 |
|||
.reason-popup { |
|||
background-color: #fff; |
|||
border-radius: 20rpx 20rpx 0 0; |
|||
overflow: hidden; |
|||
} |
|||
|
|||
.reason-option { |
|||
padding: 30rpx; |
|||
border-bottom: 1rpx solid #f0f0f0; |
|||
|
|||
&:last-child { |
|||
border-bottom: none; |
|||
} |
|||
} |
|||
|
|||
.reason-content { |
|||
display: flex; |
|||
justify-content: space-between; |
|||
align-items: center; |
|||
} |
|||
|
|||
.reason-text { |
|||
font-size: 28rpx; |
|||
color: #333; |
|||
} |
|||
</style> |
@ -0,0 +1,632 @@ |
|||
<template> |
|||
<view class="after-sale-detail"> |
|||
<!-- 状态头部 --> |
|||
<view class="status-header"> |
|||
<view |
|||
class="status-badge" |
|||
:class="[getStatusClass(afterSaleDetail.status)]" |
|||
> |
|||
{{ getStatusText(afterSaleDetail.status) }} |
|||
</view> |
|||
<view class="status-desc">{{ |
|||
getStatusDesc(afterSaleDetail.status) |
|||
}}</view> |
|||
</view> |
|||
|
|||
<!-- 商品信息 --> |
|||
<view class="product-section"> |
|||
<view class="section-title">商品信息</view> |
|||
<view class="product-info"> |
|||
<image |
|||
class="product-image" |
|||
:src="afterSaleDetail.productImage" |
|||
mode="aspectFill" |
|||
/> |
|||
<view class="product-details"> |
|||
<text class="product-title">{{ afterSaleDetail.productTitle }}</text> |
|||
<text class="product-spec">{{ afterSaleDetail.productSpec }}</text> |
|||
<text class="order-number" |
|||
>订单号:{{ afterSaleDetail.orderNumber }}</text |
|||
> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 售后信息 --> |
|||
<view class="after-sale-section"> |
|||
<view class="section-title">售后信息</view> |
|||
<view class="info-list"> |
|||
<view class="info-item"> |
|||
<text class="info-label">售后类型</text> |
|||
<text class="info-value">{{ afterSaleDetail.type }}</text> |
|||
</view> |
|||
<view class="info-item"> |
|||
<text class="info-label">售后原因</text> |
|||
<text class="info-value">{{ afterSaleDetail.reason }}</text> |
|||
</view> |
|||
<view class="info-item"> |
|||
<text class="info-label">申请时间</text> |
|||
<text class="info-value">{{ |
|||
formatTime(afterSaleDetail.createTime) |
|||
}}</text> |
|||
</view> |
|||
<view class="info-item"> |
|||
<text class="info-label">售后单号</text> |
|||
<text class="info-value">{{ afterSaleDetail.afterSaleNumber }}</text> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 问题描述 --> |
|||
<view class="description-section"> |
|||
<view class="section-title">问题描述</view> |
|||
<view class="description-content"> |
|||
<text class="description-text">{{ afterSaleDetail.description }}</text> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 问题图片 --> |
|||
<view |
|||
class="images-section" |
|||
v-if="afterSaleDetail.images && afterSaleDetail.images.length > 0" |
|||
> |
|||
<view class="section-title">问题图片</view> |
|||
<view class="images-grid"> |
|||
<image |
|||
class="problem-image" |
|||
v-for="(image, index) in afterSaleDetail.images" |
|||
:key="index" |
|||
:src="image" |
|||
mode="aspectFill" |
|||
@click="previewImage(index)" |
|||
/> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 处理进度 --> |
|||
<view class="progress-section"> |
|||
<view class="section-title">处理进度</view> |
|||
<view class="progress-list"> |
|||
<view |
|||
class="progress-item" |
|||
v-for="(progress, index) in afterSaleDetail.progressList" |
|||
:key="index" |
|||
:class="{ |
|||
active: progress.isActive, |
|||
completed: progress.isCompleted, |
|||
}" |
|||
> |
|||
<view class="progress-icon"> |
|||
<uni-icons |
|||
:type="progress.isCompleted ? 'checkmarkempty' : 'circle'" |
|||
size="20" |
|||
:color="progress.isCompleted ? '#34c759' : '#ddd'" |
|||
/> |
|||
</view> |
|||
<view class="progress-content"> |
|||
<text class="progress-title">{{ progress.title }}</text> |
|||
<text class="progress-time">{{ formatTime(progress.time) }}</text> |
|||
<text class="progress-desc" v-if="progress.description">{{ |
|||
progress.description |
|||
}}</text> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 客服回复 --> |
|||
<view class="reply-section" v-if="afterSaleDetail.reply"> |
|||
<view class="section-title">客服回复</view> |
|||
<view class="reply-content"> |
|||
<text class="reply-text">{{ afterSaleDetail.reply.content }}</text> |
|||
<text class="reply-time">{{ |
|||
formatTime(afterSaleDetail.reply.time) |
|||
}}</text> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 底部操作 --> |
|||
<view class="bottom-actions" v-if="showBottomActions"> |
|||
<button |
|||
class="action-btn secondary" |
|||
@click="cancelAfterSale" |
|||
v-if="afterSaleDetail.status === 'pending'" |
|||
> |
|||
取消申请 |
|||
</button> |
|||
<button class="action-btn primary" @click="contactService"> |
|||
联系客服 |
|||
</button> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
data() { |
|||
return { |
|||
afterSaleId: "", |
|||
afterSaleDetail: { |
|||
id: "", |
|||
status: "pending", |
|||
productImage: "", |
|||
productTitle: "", |
|||
productSpec: "", |
|||
orderNumber: "", |
|||
type: "", |
|||
reason: "", |
|||
description: "", |
|||
images: [], |
|||
createTime: "", |
|||
afterSaleNumber: "", |
|||
progressList: [], |
|||
reply: null, |
|||
}, |
|||
}; |
|||
}, |
|||
computed: { |
|||
showBottomActions() { |
|||
return ["pending", "processing"].includes(this.afterSaleDetail.status); |
|||
}, |
|||
}, |
|||
onLoad(options) { |
|||
if (options.id) { |
|||
this.afterSaleId = options.id; |
|||
this.loadAfterSaleDetail(); |
|||
} |
|||
}, |
|||
methods: { |
|||
// 加载售后详情 |
|||
async loadAfterSaleDetail() { |
|||
try { |
|||
uni.showLoading({ |
|||
title: "加载中...", |
|||
}); |
|||
|
|||
this.Post( |
|||
{ id: this.afterSaleId }, |
|||
"/framework/afterSale/detail", |
|||
"DES" |
|||
) |
|||
.then((res) => { |
|||
uni.hideLoading(); |
|||
if (res.code === 200) { |
|||
this.afterSaleDetail = res.data; |
|||
} else { |
|||
uni.showToast({ |
|||
title: res.msg || "加载失败", |
|||
icon: "none", |
|||
}); |
|||
} |
|||
}) |
|||
.catch((error) => { |
|||
uni.hideLoading(); |
|||
console.error("加载售后详情失败:", error); |
|||
uni.showToast({ |
|||
title: "加载失败", |
|||
icon: "none", |
|||
}); |
|||
}); |
|||
} catch (error) { |
|||
uni.hideLoading(); |
|||
console.error("加载售后详情失败:", error); |
|||
uni.showToast({ |
|||
title: "加载失败", |
|||
icon: "none", |
|||
}); |
|||
} |
|||
}, |
|||
|
|||
// 预览图片 |
|||
previewImage(index) { |
|||
uni.previewImage({ |
|||
current: index, |
|||
urls: this.afterSaleDetail.images, |
|||
}); |
|||
}, |
|||
|
|||
// 取消售后申请 |
|||
cancelAfterSale() { |
|||
uni.showModal({ |
|||
title: "确认取消", |
|||
content: "确定要取消这个售后申请吗?", |
|||
success: (res) => { |
|||
if (res.confirm) { |
|||
this.Post( |
|||
{ id: this.afterSaleId }, |
|||
"/framework/afterSale/cancel", |
|||
"DES" |
|||
) |
|||
.then((res) => { |
|||
if (res.code === 200) { |
|||
uni.showToast({ |
|||
title: "取消成功", |
|||
icon: "success", |
|||
}); |
|||
// 重新加载详情 |
|||
this.loadAfterSaleDetail(); |
|||
} else { |
|||
uni.showToast({ |
|||
title: res.msg || "取消失败", |
|||
icon: "none", |
|||
}); |
|||
} |
|||
}) |
|||
.catch((error) => { |
|||
console.error("取消售后申请失败:", error); |
|||
uni.showToast({ |
|||
title: "取消失败", |
|||
icon: "none", |
|||
}); |
|||
}); |
|||
} |
|||
}, |
|||
}); |
|||
}, |
|||
|
|||
// 联系客服 |
|||
contactService() { |
|||
// 这里可以跳转到客服页面或拨打电话 |
|||
uni.showModal({ |
|||
title: "联系客服", |
|||
content: "请拨打客服电话:400-123-4567", |
|||
confirmText: "拨打", |
|||
success: (res) => { |
|||
if (res.confirm) { |
|||
// 拨打电话 |
|||
uni.makePhoneCall({ |
|||
phoneNumber: "400-123-4567", |
|||
}); |
|||
} |
|||
}, |
|||
}); |
|||
}, |
|||
|
|||
// 获取状态文本 |
|||
getStatusText(status) { |
|||
const statusMap = { |
|||
pending: "待处理", |
|||
processing: "处理中", |
|||
completed: "已完成", |
|||
cancelled: "已取消", |
|||
}; |
|||
return statusMap[status] || "未知状态"; |
|||
}, |
|||
|
|||
// 获取状态描述 |
|||
getStatusDesc(status) { |
|||
const descMap = { |
|||
pending: "您的售后申请已提交,请耐心等待处理", |
|||
processing: "客服正在处理您的售后申请", |
|||
completed: "您的售后申请已处理完成", |
|||
cancelled: "您的售后申请已取消", |
|||
}; |
|||
return descMap[status] || ""; |
|||
}, |
|||
|
|||
// 获取状态样式类 |
|||
getStatusClass(status) { |
|||
const classMap = { |
|||
pending: "status-pending", |
|||
processing: "status-processing", |
|||
completed: "status-completed", |
|||
cancelled: "status-cancelled", |
|||
}; |
|||
return classMap[status] || "status-default"; |
|||
}, |
|||
|
|||
// 格式化时间 |
|||
formatTime(time) { |
|||
if (!time) return ""; |
|||
const date = new Date(time); |
|||
return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart( |
|||
2, |
|||
"0" |
|||
)}-${String(date.getDate()).padStart(2, "0")} ${String( |
|||
date.getHours() |
|||
).padStart(2, "0")}:${String(date.getMinutes()).padStart(2, "0")}`; |
|||
}, |
|||
}, |
|||
}; |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.after-sale-detail { |
|||
min-height: 100vh; |
|||
background-color: #f5f5f5; |
|||
padding-bottom: calc(120rpx + env(safe-area-inset-bottom)); |
|||
padding-bottom: calc(120rpx + constant(safe-area-inset-bottom)); |
|||
} |
|||
|
|||
// 状态头部 |
|||
.status-header { |
|||
background-color: #fff; |
|||
padding: 40rpx 30rpx; |
|||
text-align: center; |
|||
margin-bottom: 20rpx; |
|||
} |
|||
|
|||
.status-badge { |
|||
display: inline-block; |
|||
padding: 12rpx 24rpx; |
|||
border-radius: 20rpx; |
|||
font-size: 28rpx; |
|||
color: #fff; |
|||
font-weight: 600; |
|||
margin-bottom: 16rpx; |
|||
|
|||
&.status-pending { |
|||
background-color: #ff9500; |
|||
} |
|||
|
|||
&.status-processing { |
|||
background-color: #007aff; |
|||
} |
|||
|
|||
&.status-completed { |
|||
background-color: #34c759; |
|||
} |
|||
|
|||
&.status-cancelled { |
|||
background-color: #999; |
|||
} |
|||
|
|||
&.status-default { |
|||
background-color: #999; |
|||
} |
|||
} |
|||
|
|||
.status-desc { |
|||
font-size: 26rpx; |
|||
color: #666; |
|||
line-height: 1.4; |
|||
} |
|||
|
|||
// 通用区域样式 |
|||
.section-title { |
|||
font-size: 30rpx; |
|||
font-weight: 600; |
|||
color: #333; |
|||
margin-bottom: 24rpx; |
|||
} |
|||
|
|||
// 商品信息 |
|||
.product-section { |
|||
background-color: #fff; |
|||
padding: 30rpx; |
|||
margin-bottom: 20rpx; |
|||
} |
|||
|
|||
.product-info { |
|||
display: flex; |
|||
align-items: flex-start; |
|||
} |
|||
|
|||
.product-image { |
|||
width: 120rpx; |
|||
height: 120rpx; |
|||
border-radius: 8rpx; |
|||
margin-right: 20rpx; |
|||
flex-shrink: 0; |
|||
} |
|||
|
|||
.product-details { |
|||
flex: 1; |
|||
display: flex; |
|||
flex-direction: column; |
|||
} |
|||
|
|||
.product-title { |
|||
font-size: 30rpx; |
|||
font-weight: 600; |
|||
color: #333; |
|||
margin-bottom: 8rpx; |
|||
line-height: 1.4; |
|||
} |
|||
|
|||
.product-spec { |
|||
font-size: 26rpx; |
|||
color: #666; |
|||
margin-bottom: 12rpx; |
|||
} |
|||
|
|||
.order-number { |
|||
font-size: 24rpx; |
|||
color: #999; |
|||
} |
|||
|
|||
// 售后信息 |
|||
.after-sale-section { |
|||
background-color: #fff; |
|||
padding: 30rpx; |
|||
margin-bottom: 20rpx; |
|||
} |
|||
|
|||
.info-list { |
|||
display: flex; |
|||
flex-direction: column; |
|||
gap: 20rpx; |
|||
} |
|||
|
|||
.info-item { |
|||
display: flex; |
|||
justify-content: space-between; |
|||
align-items: center; |
|||
} |
|||
|
|||
.info-label { |
|||
font-size: 28rpx; |
|||
color: #666; |
|||
min-width: 140rpx; |
|||
flex-shrink: 0; |
|||
} |
|||
|
|||
.info-value { |
|||
font-size: 28rpx; |
|||
color: #333; |
|||
flex: 1; |
|||
text-align: right; |
|||
} |
|||
|
|||
// 问题描述 |
|||
.description-section { |
|||
background-color: #fff; |
|||
padding: 30rpx; |
|||
margin-bottom: 20rpx; |
|||
} |
|||
|
|||
.description-content { |
|||
background-color: #f8f9fa; |
|||
border-radius: 8rpx; |
|||
padding: 20rpx; |
|||
} |
|||
|
|||
.description-text { |
|||
font-size: 28rpx; |
|||
color: #333; |
|||
line-height: 1.6; |
|||
} |
|||
|
|||
// 问题图片 |
|||
.images-section { |
|||
background-color: #fff; |
|||
padding: 30rpx; |
|||
margin-bottom: 20rpx; |
|||
} |
|||
|
|||
.images-grid { |
|||
display: grid; |
|||
grid-template-columns: repeat(3, 1fr); |
|||
gap: 16rpx; |
|||
} |
|||
|
|||
.problem-image { |
|||
width: 100%; |
|||
aspect-ratio: 1; |
|||
border-radius: 8rpx; |
|||
} |
|||
|
|||
// 处理进度 |
|||
.progress-section { |
|||
background-color: #fff; |
|||
padding: 30rpx; |
|||
margin-bottom: 20rpx; |
|||
} |
|||
|
|||
.progress-list { |
|||
display: flex; |
|||
flex-direction: column; |
|||
gap: 30rpx; |
|||
} |
|||
|
|||
.progress-item { |
|||
display: flex; |
|||
align-items: flex-start; |
|||
position: relative; |
|||
|
|||
&:not(:last-child)::after { |
|||
content: ""; |
|||
position: absolute; |
|||
left: 10rpx; |
|||
top: 40rpx; |
|||
width: 2rpx; |
|||
height: 30rpx; |
|||
background-color: #eee; |
|||
} |
|||
|
|||
&.completed:not(:last-child)::after { |
|||
background-color: #34c759; |
|||
} |
|||
} |
|||
|
|||
.progress-icon { |
|||
margin-right: 20rpx; |
|||
flex-shrink: 0; |
|||
margin-top: 4rpx; |
|||
} |
|||
|
|||
.progress-content { |
|||
flex: 1; |
|||
display: flex; |
|||
flex-direction: column; |
|||
} |
|||
|
|||
.progress-title { |
|||
font-size: 28rpx; |
|||
color: #333; |
|||
font-weight: 500; |
|||
margin-bottom: 8rpx; |
|||
} |
|||
|
|||
.progress-time { |
|||
font-size: 24rpx; |
|||
color: #999; |
|||
margin-bottom: 8rpx; |
|||
} |
|||
|
|||
.progress-desc { |
|||
font-size: 26rpx; |
|||
color: #666; |
|||
line-height: 1.4; |
|||
} |
|||
|
|||
// 客服回复 |
|||
.reply-section { |
|||
background-color: #fff; |
|||
padding: 30rpx; |
|||
margin-bottom: 20rpx; |
|||
} |
|||
|
|||
.reply-content { |
|||
background-color: #f0f8ff; |
|||
border-radius: 8rpx; |
|||
padding: 20rpx; |
|||
} |
|||
|
|||
.reply-text { |
|||
font-size: 28rpx; |
|||
color: #333; |
|||
line-height: 1.6; |
|||
margin-bottom: 12rpx; |
|||
display: block; |
|||
} |
|||
|
|||
.reply-time { |
|||
font-size: 24rpx; |
|||
color: #999; |
|||
} |
|||
|
|||
// 底部操作 |
|||
.bottom-actions { |
|||
position: fixed; |
|||
bottom: 0; |
|||
left: 0; |
|||
right: 0; |
|||
background-color: #fff; |
|||
padding: 20rpx 30rpx; |
|||
padding-bottom: calc(20rpx + env(safe-area-inset-bottom)); |
|||
border-top: 1rpx solid #eee; |
|||
display: flex; |
|||
gap: 20rpx; |
|||
} |
|||
|
|||
.action-btn { |
|||
flex: 1; |
|||
height: 80rpx; |
|||
border-radius: 12rpx; |
|||
font-size: 32rpx; |
|||
font-weight: 600; |
|||
border: none; |
|||
|
|||
&.secondary { |
|||
background-color: #fff; |
|||
color: #666; |
|||
border: 1rpx solid #ddd; |
|||
} |
|||
|
|||
&.primary { |
|||
background-color: #007aff; |
|||
color: #fff; |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,530 @@ |
|||
<template> |
|||
<view class="after-sale-list"> |
|||
<!-- 状态筛选 --> |
|||
<view class="filter-section"> |
|||
<view class="filter-tabs"> |
|||
<view |
|||
class="filter-tab" |
|||
:class="{ active: currentStatus === item.value }" |
|||
v-for="item in statusOptions" |
|||
:key="item.value" |
|||
@click="changeStatus(item.value)" |
|||
> |
|||
<text class="tab-text">{{ item.text }}</text> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 售后列表 --> |
|||
<scroll-view |
|||
class="list-scroll" |
|||
scroll-y |
|||
@scrolltolower="loadMore" |
|||
@refresherrefresh="onRefresh" |
|||
:refresher-enabled="true" |
|||
:refresher-triggered="refresherTriggered" |
|||
> |
|||
<view class="list-content"> |
|||
<view |
|||
class="after-sale-item" |
|||
v-for="item in afterSaleList" |
|||
:key="item.id" |
|||
@click="goToDetail(item)" |
|||
> |
|||
<!-- 商品信息 --> |
|||
<view class="product-info"> |
|||
<image |
|||
class="product-image" |
|||
:src="item.productImage" |
|||
mode="aspectFill" |
|||
/> |
|||
<view class="product-details"> |
|||
<text class="product-title">{{ item.productTitle }}</text> |
|||
<text class="product-spec">{{ item.productSpec }}</text> |
|||
<view class="product-meta"> |
|||
<text class="order-number">订单号:{{ item.orderNumber }}</text> |
|||
<text class="create-time">{{ |
|||
formatTime(item.createTime) |
|||
}}</text> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 售后信息 --> |
|||
<view class="after-sale-info"> |
|||
<view class="info-row"> |
|||
<text class="info-label">售后类型:</text> |
|||
<text class="info-value">{{ item.type }}</text> |
|||
</view> |
|||
<view class="info-row"> |
|||
<text class="info-label">售后原因:</text> |
|||
<text class="info-value">{{ item.reason }}</text> |
|||
</view> |
|||
<view class="info-row"> |
|||
<text class="info-label">申请时间:</text> |
|||
<text class="info-value">{{ formatTime(item.createTime) }}</text> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 状态和操作 --> |
|||
<view class="status-section"> |
|||
<view class="status-badge" :class="[getStatusClass(item.status)]"> |
|||
{{ getStatusText(item.status) }} |
|||
</view> |
|||
<view class="action-buttons"> |
|||
<button |
|||
class="action-btn" |
|||
@click.stop="cancelAfterSale(item)" |
|||
v-if="item.status === 'pending'" |
|||
> |
|||
取消申请 |
|||
</button> |
|||
<button class="action-btn primary" @click.stop="goToDetail(item)"> |
|||
查看详情 |
|||
</button> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 加载更多 --> |
|||
<view class="load-more" v-if="hasMore"> |
|||
<text class="load-text">加载中...</text> |
|||
</view> |
|||
<view class="no-more" v-else> |
|||
<text class="no-more-text">没有更多数据了</text> |
|||
</view> |
|||
|
|||
<!-- 空状态 --> |
|||
<view class="empty-state" v-if="afterSaleList.length === 0 && !loading"> |
|||
<image |
|||
class="empty-image" |
|||
:src="showImg('/uploads/20250808/c16267f9cc2b7a68bf23713b5847987e.png')" |
|||
mode="aspectFit" |
|||
/> |
|||
<text class="empty-text">暂无售后记录</text> |
|||
</view> |
|||
</view> |
|||
</scroll-view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
data() { |
|||
return { |
|||
currentStatus: "all", |
|||
statusOptions: [ |
|||
{ text: "全部", value: "all" }, |
|||
{ text: "待处理", value: "pending" }, |
|||
{ text: "处理中", value: "processing" }, |
|||
{ text: "已完成", value: "completed" }, |
|||
{ text: "已取消", value: "cancelled" }, |
|||
], |
|||
afterSaleList: [], |
|||
page: 1, |
|||
pageSize: 10, |
|||
hasMore: true, |
|||
loading: false, |
|||
refresherTriggered: false, |
|||
}; |
|||
}, |
|||
onLoad() { |
|||
this.loadAfterSaleList(); |
|||
}, |
|||
onShow() { |
|||
// 页面显示时刷新数据 |
|||
this.refreshList(); |
|||
}, |
|||
methods: { |
|||
// 切换状态筛选 |
|||
changeStatus(status) { |
|||
if (this.currentStatus === status) return; |
|||
this.currentStatus = status; |
|||
this.resetList(); |
|||
this.loadAfterSaleList(); |
|||
}, |
|||
|
|||
// 重置列表 |
|||
resetList() { |
|||
this.afterSaleList = []; |
|||
this.page = 1; |
|||
this.hasMore = true; |
|||
}, |
|||
|
|||
// 加载售后列表 |
|||
async loadAfterSaleList() { |
|||
if (this.loading || !this.hasMore) return; |
|||
|
|||
try { |
|||
this.loading = true; |
|||
|
|||
const params = { |
|||
page: this.page, |
|||
pageSize: this.pageSize, |
|||
status: this.currentStatus === "all" ? "" : this.currentStatus, |
|||
}; |
|||
|
|||
this.Post(params, "/framework/afterSale/list", "DES") |
|||
.then((res) => { |
|||
this.loading = false; |
|||
if (res.code === 200) { |
|||
const newList = res.data.list || []; |
|||
|
|||
if (this.page === 1) { |
|||
this.afterSaleList = newList; |
|||
} else { |
|||
this.afterSaleList.push(...newList); |
|||
} |
|||
|
|||
this.hasMore = newList.length === this.pageSize; |
|||
this.page++; |
|||
} else { |
|||
uni.showToast({ |
|||
title: res.msg || "加载失败", |
|||
icon: "none", |
|||
}); |
|||
} |
|||
}) |
|||
.catch((error) => { |
|||
this.loading = false; |
|||
console.error("加载售后列表失败:", error); |
|||
uni.showToast({ |
|||
title: "加载失败", |
|||
icon: "none", |
|||
}); |
|||
}); |
|||
} catch (error) { |
|||
this.loading = false; |
|||
console.error("加载售后列表失败:", error); |
|||
uni.showToast({ |
|||
title: "加载失败", |
|||
icon: "none", |
|||
}); |
|||
} |
|||
}, |
|||
|
|||
// 上拉加载更多 |
|||
loadMore() { |
|||
this.loadAfterSaleList(); |
|||
}, |
|||
|
|||
// 下拉刷新 |
|||
onRefresh() { |
|||
this.refresherTriggered = true; |
|||
this.resetList(); |
|||
this.loadAfterSaleList().finally(() => { |
|||
this.refresherTriggered = false; |
|||
}); |
|||
}, |
|||
|
|||
// 刷新列表 |
|||
refreshList() { |
|||
this.resetList(); |
|||
this.loadAfterSaleList(); |
|||
}, |
|||
|
|||
// 跳转到详情页 |
|||
goToDetail(item) { |
|||
uni.navigateTo({ |
|||
url: `/subPackages/afterSale/detail?id=${item.id}`, |
|||
}); |
|||
}, |
|||
|
|||
// 取消售后申请 |
|||
cancelAfterSale(item) { |
|||
uni.showModal({ |
|||
title: "确认取消", |
|||
content: "确定要取消这个售后申请吗?", |
|||
success: (res) => { |
|||
if (res.confirm) { |
|||
this.Post({ id: item.id }, "/framework/afterSale/cancel", "DES") |
|||
.then((res) => { |
|||
if (res.code === 200) { |
|||
uni.showToast({ |
|||
title: "取消成功", |
|||
icon: "success", |
|||
}); |
|||
this.refreshList(); |
|||
} else { |
|||
uni.showToast({ |
|||
title: res.msg || "取消失败", |
|||
icon: "none", |
|||
}); |
|||
} |
|||
}) |
|||
.catch((error) => { |
|||
console.error("取消售后申请失败:", error); |
|||
uni.showToast({ |
|||
title: "取消失败", |
|||
icon: "none", |
|||
}); |
|||
}); |
|||
} |
|||
}, |
|||
}); |
|||
}, |
|||
|
|||
// 获取状态文本 |
|||
getStatusText(status) { |
|||
const statusMap = { |
|||
pending: "待处理", |
|||
processing: "处理中", |
|||
completed: "已完成", |
|||
cancelled: "已取消", |
|||
}; |
|||
return statusMap[status] || "未知状态"; |
|||
}, |
|||
|
|||
// 获取状态样式类 |
|||
getStatusClass(status) { |
|||
const classMap = { |
|||
pending: "status-pending", |
|||
processing: "status-processing", |
|||
completed: "status-completed", |
|||
cancelled: "status-cancelled", |
|||
}; |
|||
return classMap[status] || "status-default"; |
|||
}, |
|||
|
|||
// 格式化时间 |
|||
formatTime(time) { |
|||
if (!time) return ""; |
|||
const date = new Date(time); |
|||
return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart( |
|||
2, |
|||
"0" |
|||
)}-${String(date.getDate()).padStart(2, "0")} ${String( |
|||
date.getHours() |
|||
).padStart(2, "0")}:${String(date.getMinutes()).padStart(2, "0")}`; |
|||
}, |
|||
}, |
|||
}; |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.after-sale-list { |
|||
min-height: 100vh; |
|||
background-color: #f5f5f5; |
|||
} |
|||
|
|||
// 筛选区域 |
|||
.filter-section { |
|||
background-color: #fff; |
|||
padding: 20rpx 0; |
|||
margin-bottom: 20rpx; |
|||
} |
|||
|
|||
.filter-tabs { |
|||
display: flex; |
|||
justify-content: space-around; |
|||
padding: 0 30rpx; |
|||
} |
|||
|
|||
.filter-tab { |
|||
padding: 16rpx 24rpx; |
|||
border-radius: 20rpx; |
|||
transition: all 0.3s ease; |
|||
|
|||
&.active { |
|||
background-color: #007aff; |
|||
|
|||
.tab-text { |
|||
color: #fff; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.tab-text { |
|||
font-size: 28rpx; |
|||
color: #666; |
|||
font-weight: 500; |
|||
} |
|||
|
|||
// 列表区域 |
|||
.list-scroll { |
|||
height: calc(100vh - 120rpx); |
|||
} |
|||
|
|||
.list-content { |
|||
padding: 0 20rpx; |
|||
} |
|||
|
|||
.after-sale-item { |
|||
background-color: #fff; |
|||
border-radius: 12rpx; |
|||
margin-bottom: 20rpx; |
|||
padding: 30rpx; |
|||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.06); |
|||
} |
|||
|
|||
// 商品信息 |
|||
.product-info { |
|||
display: flex; |
|||
align-items: flex-start; |
|||
margin-bottom: 24rpx; |
|||
} |
|||
|
|||
.product-image { |
|||
width: 120rpx; |
|||
height: 120rpx; |
|||
border-radius: 8rpx; |
|||
margin-right: 20rpx; |
|||
flex-shrink: 0; |
|||
} |
|||
|
|||
.product-details { |
|||
flex: 1; |
|||
display: flex; |
|||
flex-direction: column; |
|||
} |
|||
|
|||
.product-title { |
|||
font-size: 30rpx; |
|||
font-weight: 600; |
|||
color: #333; |
|||
margin-bottom: 8rpx; |
|||
line-height: 1.4; |
|||
} |
|||
|
|||
.product-spec { |
|||
font-size: 26rpx; |
|||
color: #666; |
|||
margin-bottom: 12rpx; |
|||
} |
|||
|
|||
.product-meta { |
|||
display: flex; |
|||
flex-direction: column; |
|||
gap: 4rpx; |
|||
} |
|||
|
|||
.order-number { |
|||
font-size: 24rpx; |
|||
color: #999; |
|||
} |
|||
|
|||
.create-time { |
|||
font-size: 24rpx; |
|||
color: #999; |
|||
} |
|||
|
|||
// 售后信息 |
|||
.after-sale-info { |
|||
background-color: #f8f9fa; |
|||
border-radius: 8rpx; |
|||
padding: 20rpx; |
|||
margin-bottom: 24rpx; |
|||
} |
|||
|
|||
.info-row { |
|||
display: flex; |
|||
align-items: center; |
|||
margin-bottom: 12rpx; |
|||
|
|||
&:last-child { |
|||
margin-bottom: 0; |
|||
} |
|||
} |
|||
|
|||
.info-label { |
|||
font-size: 26rpx; |
|||
color: #666; |
|||
min-width: 140rpx; |
|||
flex-shrink: 0; |
|||
} |
|||
|
|||
.info-value { |
|||
font-size: 26rpx; |
|||
color: #333; |
|||
flex: 1; |
|||
} |
|||
|
|||
// 状态和操作 |
|||
.status-section { |
|||
display: flex; |
|||
justify-content: space-between; |
|||
align-items: center; |
|||
} |
|||
|
|||
.status-badge { |
|||
padding: 8rpx 16rpx; |
|||
border-radius: 16rpx; |
|||
font-size: 24rpx; |
|||
color: #fff; |
|||
font-weight: 500; |
|||
|
|||
&.status-pending { |
|||
background-color: #ff9500; |
|||
} |
|||
|
|||
&.status-processing { |
|||
background-color: #007aff; |
|||
} |
|||
|
|||
&.status-completed { |
|||
background-color: #34c759; |
|||
} |
|||
|
|||
&.status-cancelled { |
|||
background-color: #999; |
|||
} |
|||
|
|||
&.status-default { |
|||
background-color: #999; |
|||
} |
|||
} |
|||
|
|||
.action-buttons { |
|||
display: flex; |
|||
gap: 16rpx; |
|||
} |
|||
|
|||
.action-btn { |
|||
padding: 12rpx 24rpx; |
|||
border-radius: 20rpx; |
|||
font-size: 24rpx; |
|||
border: 1rpx solid #ddd; |
|||
background-color: #fff; |
|||
color: #666; |
|||
min-width: 120rpx; |
|||
|
|||
&.primary { |
|||
background-color: #007aff; |
|||
color: #fff; |
|||
border-color: #007aff; |
|||
} |
|||
} |
|||
|
|||
// 加载更多 |
|||
.load-more, |
|||
.no-more { |
|||
text-align: center; |
|||
padding: 30rpx; |
|||
} |
|||
|
|||
.load-text, |
|||
.no-more-text { |
|||
font-size: 26rpx; |
|||
color: #999; |
|||
} |
|||
|
|||
// 空状态 |
|||
.empty-state { |
|||
display: flex; |
|||
flex-direction: column; |
|||
align-items: center; |
|||
justify-content: center; |
|||
padding: 100rpx 0; |
|||
} |
|||
|
|||
.empty-image { |
|||
width: 200rpx; |
|||
height: 200rpx; |
|||
margin-bottom: 30rpx; |
|||
} |
|||
|
|||
.empty-text { |
|||
font-size: 28rpx; |
|||
color: #999; |
|||
} |
|||
</style> |
Loading…
Reference in new issue