<template>
|
<view class="refund-container">
|
<!-- 订单信息 -->
|
<view class="order-card">
|
<view class="hospital-info">
|
<image :src="order.hospitalLogo" mode="aspectFit" class="logo" />
|
<view class="info">
|
<text class="name">{{ order.hospitalName }}</text>
|
<text class="department">{{ order.departmentName }}</text>
|
</view>
|
</view>
|
|
<view class="amount-info">
|
<text class="label">支付金额</text>
|
<text class="amount">¥{{ order.amount }}</text>
|
</view>
|
</view>
|
|
<!-- 退款表单 -->
|
<view class="refund-form card">
|
<view class="section-title">退款信息</view>
|
|
<!-- 退款金额 -->
|
<view class="form-item">
|
<text class="label required">退款金额</text>
|
<view class="amount-input">
|
<text class="currency">¥</text>
|
<input
|
type="digit"
|
v-model="refundAmount"
|
:maxlength="10"
|
placeholder="请输入退款金额"
|
/>
|
</view>
|
<text class="max-amount">最多可退 ¥{{ order.amount }}</text>
|
</view>
|
|
<!-- 退款原因 -->
|
<view class="form-item">
|
<text class="label required">退款原因</text>
|
<picker
|
mode="selector"
|
:range="refundReasons"
|
range-key="label"
|
@change="onReasonChange"
|
>
|
<view class="picker">
|
<text>{{ selectedReason?.label || '请选择退款原因' }}</text>
|
<text class="iconfont icon-arrow-right"></text>
|
</view>
|
</picker>
|
</view>
|
|
<!-- 退款说明 -->
|
<view class="form-item">
|
<text class="label">退款说明</text>
|
<textarea
|
v-model="refundDesc"
|
placeholder="请输入退款说明(选填)"
|
:maxlength="200"
|
class="desc-textarea"
|
/>
|
<text class="word-count">{{ refundDesc.length }}/200</text>
|
</view>
|
|
<!-- 上传凭证 -->
|
<view class="form-item">
|
<text class="label">上传凭证</text>
|
<view class="upload-list">
|
<view
|
class="image-item"
|
v-for="(image, index) in uploadImages"
|
:key="index"
|
>
|
<image :src="image" mode="aspectFill" @tap="previewImage(index)" />
|
<text class="delete" @tap.stop="deleteImage(index)">×</text>
|
</view>
|
<view
|
class="upload-btn"
|
v-if="uploadImages.length < 3"
|
@tap="chooseImage"
|
>
|
<text class="iconfont icon-add"></text>
|
<text>上传图片</text>
|
</view>
|
</view>
|
<text class="upload-tip">最多上传3张图片,每张不超过5MB</text>
|
</view>
|
</view>
|
|
<!-- 退款说明 -->
|
<view class="notice-card">
|
<view class="section-title">退款说明</view>
|
<view class="notice-list">
|
<view class="notice-item">
|
<text class="dot"></text>
|
<text class="content">退款申请提交后,工作人员将在1-3个工作日内进行审核</text>
|
</view>
|
<view class="notice-item">
|
<text class="dot"></text>
|
<text class="content">退款金额将原路退回到支付账户</text>
|
</view>
|
<view class="notice-item">
|
<text class="dot"></text>
|
<text class="content">如有疑问,请联系客服:+853 2837 1333</text>
|
</view>
|
</view>
|
</view>
|
|
<!-- 底部按钮 -->
|
<view class="bottom-bar">
|
<button
|
class="submit-btn primary-btn"
|
:disabled="!canSubmit"
|
@tap="submitRefund"
|
>提交申请</button>
|
</view>
|
</view>
|
</template>
|
|
<script setup>
|
import { ref, computed } from 'vue'
|
|
// 订单信息
|
const order = ref({
|
id: 1,
|
hospitalName: '青岛镜湖医院',
|
hospitalLogo: '/static/hospital/kiang-wu.jpg',
|
departmentName: '心内科',
|
amount: 360.00
|
})
|
|
// 退款金额
|
const refundAmount = ref('')
|
|
// 退款原因列表
|
const refundReasons = [
|
{ value: 1, label: '预约时间冲突' },
|
{ value: 2, label: '重复预约' },
|
{ value: 3, label: '身体原因无法就医' },
|
{ value: 4, label: '其他原因' }
|
]
|
const selectedReason = ref(null)
|
|
// 退款说明
|
const refundDesc = ref('')
|
|
// 上传图片
|
const uploadImages = ref([])
|
|
// 是否可以提交
|
const canSubmit = computed(() => {
|
const amount = Number(refundAmount.value)
|
return amount > 0 &&
|
amount <= order.value.amount &&
|
selectedReason.value
|
})
|
|
// 选择退款原因
|
const onReasonChange = (e) => {
|
selectedReason.value = refundReasons[e.detail.value]
|
}
|
|
// 选择图片
|
const chooseImage = () => {
|
uni.chooseImage({
|
count: 3 - uploadImages.value.length,
|
sizeType: ['compressed'],
|
sourceType: ['album', 'camera'],
|
success: (res) => {
|
uploadImages.value.push(...res.tempFilePaths)
|
}
|
})
|
}
|
|
// 预览图片
|
const previewImage = (index) => {
|
uni.previewImage({
|
urls: uploadImages.value,
|
current: index
|
})
|
}
|
|
// 删除图片
|
const deleteImage = (index) => {
|
uploadImages.value.splice(index, 1)
|
}
|
|
// 提交退款
|
const submitRefund = () => {
|
if (!canSubmit.value) return
|
|
uni.showModal({
|
title: '确认提交',
|
content: '确定要提交退款申请吗?',
|
success: (res) => {
|
if (res.confirm) {
|
uni.showLoading({
|
title: '提交中...'
|
})
|
|
// 这里调用退款API
|
setTimeout(() => {
|
uni.hideLoading()
|
uni.showToast({
|
title: '提交成功',
|
icon: 'success'
|
})
|
setTimeout(() => {
|
uni.navigateBack()
|
}, 1500)
|
}, 1000)
|
}
|
}
|
})
|
}
|
</script>
|
|
<style lang="scss">
|
.refund-container {
|
min-height: 100vh;
|
background: $bg-color;
|
padding-bottom: 120rpx;
|
|
.order-card {
|
background: #fff;
|
padding: 30rpx;
|
margin-bottom: 20rpx;
|
|
.hospital-info {
|
display: flex;
|
align-items: center;
|
margin-bottom: 20rpx;
|
|
.logo {
|
width: 80rpx;
|
height: 80rpx;
|
border-radius: $radius-sm;
|
margin-right: 20rpx;
|
}
|
|
.info {
|
flex: 1;
|
|
.name {
|
font-size: 32rpx;
|
color: $text-primary;
|
font-weight: bold;
|
margin-bottom: 8rpx;
|
display: block;
|
}
|
|
.department {
|
font-size: 26rpx;
|
color: $text-regular;
|
}
|
}
|
}
|
|
.amount-info {
|
.label {
|
font-size: 26rpx;
|
color: $text-regular;
|
margin-right: 12rpx;
|
}
|
|
.amount {
|
font-size: 36rpx;
|
color: $danger;
|
font-weight: bold;
|
}
|
}
|
}
|
|
.refund-form {
|
background: #fff;
|
padding: 30rpx;
|
margin-bottom: 20rpx;
|
|
.form-item {
|
margin-bottom: 30rpx;
|
|
.label {
|
font-size: 28rpx;
|
color: $text-primary;
|
margin-bottom: 16rpx;
|
display: block;
|
|
&.required::before {
|
content: '*';
|
color: $danger;
|
margin-right: 4rpx;
|
}
|
}
|
|
.amount-input {
|
display: flex;
|
align-items: center;
|
height: 88rpx;
|
background: $bg-color;
|
border-radius: $radius-lg;
|
padding: 0 30rpx;
|
margin-bottom: 12rpx;
|
|
.currency {
|
font-size: 36rpx;
|
color: $text-primary;
|
margin-right: 12rpx;
|
}
|
|
input {
|
flex: 1;
|
height: 100%;
|
font-size: 32rpx;
|
color: $text-primary;
|
}
|
}
|
|
.max-amount {
|
font-size: 24rpx;
|
color: $text-secondary;
|
}
|
|
.picker {
|
height: 88rpx;
|
background: $bg-color;
|
border-radius: $radius-lg;
|
padding: 0 30rpx;
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
|
text {
|
font-size: 28rpx;
|
color: $text-primary;
|
|
&.icon-arrow-right {
|
font-size: 24rpx;
|
color: $text-secondary;
|
}
|
}
|
}
|
|
.desc-textarea {
|
width: 100%;
|
height: 200rpx;
|
background: $bg-color;
|
border-radius: $radius-lg;
|
padding: 20rpx;
|
font-size: 28rpx;
|
margin-bottom: 12rpx;
|
}
|
|
.word-count {
|
font-size: 24rpx;
|
color: $text-secondary;
|
text-align: right;
|
display: block;
|
}
|
|
.upload-list {
|
display: flex;
|
flex-wrap: wrap;
|
gap: 20rpx;
|
margin-bottom: 12rpx;
|
|
.image-item {
|
position: relative;
|
width: 160rpx;
|
height: 160rpx;
|
|
image {
|
width: 100%;
|
height: 100%;
|
border-radius: $radius-sm;
|
}
|
|
.delete {
|
position: absolute;
|
top: -20rpx;
|
right: -20rpx;
|
width: 40rpx;
|
height: 40rpx;
|
line-height: 36rpx;
|
text-align: center;
|
background: rgba(0,0,0,0.5);
|
border-radius: 50%;
|
color: #fff;
|
font-size: 32rpx;
|
}
|
}
|
|
.upload-btn {
|
width: 160rpx;
|
height: 160rpx;
|
background: $bg-color;
|
border-radius: $radius-sm;
|
display: flex;
|
flex-direction: column;
|
align-items: center;
|
justify-content: center;
|
|
.iconfont {
|
font-size: 48rpx;
|
color: $text-secondary;
|
margin-bottom: 8rpx;
|
}
|
|
text {
|
font-size: 24rpx;
|
color: $text-secondary;
|
}
|
}
|
}
|
|
.upload-tip {
|
font-size: 24rpx;
|
color: $text-secondary;
|
}
|
}
|
}
|
|
.notice-card {
|
background: #fff;
|
padding: 30rpx;
|
margin-bottom: 20rpx;
|
|
.notice-list {
|
.notice-item {
|
display: flex;
|
align-items: flex-start;
|
margin-bottom: 16rpx;
|
|
&:last-child {
|
margin-bottom: 0;
|
}
|
|
.dot {
|
width: 12rpx;
|
height: 12rpx;
|
background: $primary-color;
|
border-radius: 50%;
|
margin-top: 12rpx;
|
margin-right: 12rpx;
|
flex-shrink: 0;
|
}
|
|
.content {
|
flex: 1;
|
font-size: 26rpx;
|
color: $text-regular;
|
line-height: 1.6;
|
}
|
}
|
}
|
}
|
|
.bottom-bar {
|
position: fixed;
|
left: 0;
|
right: 0;
|
bottom: 0;
|
padding: 20rpx 30rpx;
|
background: #fff;
|
box-shadow: $shadow-lg;
|
|
.submit-btn {
|
width: 100%;
|
|
&[disabled] {
|
opacity: 0.6;
|
}
|
}
|
}
|
}
|
</style>
|