|
@@ -1,9 +1,69 @@
|
|
|
<template>
|
|
<template>
|
|
|
<view class="container">
|
|
<view class="container">
|
|
|
- <!-- 退款商品 -->
|
|
|
|
|
- <view class="section-item product-selector">
|
|
|
|
|
- <text class="section-label">退款商品</text>
|
|
|
|
|
- <text class="arrow-right">></text>
|
|
|
|
|
|
|
+ <!-- 退款商品选择 -->
|
|
|
|
|
+ <view class="section-block product-section">
|
|
|
|
|
+ <text class="section-title">选择退款商品</text>
|
|
|
|
|
+ <view class="product-list">
|
|
|
|
|
+ <view
|
|
|
|
|
+ v-for="(product, index) in orderInfo.products"
|
|
|
|
|
+ :key="index"
|
|
|
|
|
+ :class="['product-item', { 'product-item-selected': selectedProducts.includes(index) }]"
|
|
|
|
|
+ >
|
|
|
|
|
+ <!-- 商品主体信息 -->
|
|
|
|
|
+ <view class="product-main" @click="toggleProductSelect(index)">
|
|
|
|
|
+ <view class="product-checkbox">
|
|
|
|
|
+ <view :class="['checkbox-icon', { checked: selectedProducts.includes(index) }]">
|
|
|
|
|
+ <text v-if="selectedProducts.includes(index)">✓</text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="product-image">
|
|
|
|
|
+ <image v-if="product.image" :src="product.image" mode="aspectFill"></image>
|
|
|
|
|
+ <view v-else class="image-placeholder"></view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="product-detail">
|
|
|
|
|
+ <view class="name-container" @click.stop="showProductName(product.name)">
|
|
|
|
|
+ <text class="product-name">{{ product.name }}</text>
|
|
|
|
|
+ <text v-if="product.name.length > 12" class="expand-tip">...</text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="product-meta">
|
|
|
|
|
+ <text class="product-price">¥{{ (product.price || 0).toFixed(2) }}</text>
|
|
|
|
|
+ <text class="product-quantity-label">购买数量:x{{ product.quantity }}</text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 退款数量选择器(仅当商品被选中时显示,独立一行) -->
|
|
|
|
|
+ <view v-if="selectedProducts.includes(index)" class="refund-quantity-selector">
|
|
|
|
|
+ <view class="selector-row">
|
|
|
|
|
+ <text class="selector-label">退款数量</text>
|
|
|
|
|
+ <view class="quantity-control">
|
|
|
|
|
+ <view
|
|
|
|
|
+ :class="['control-btn', (product.refundQuantity || 1) > 1 ? '' : 'disabled']"
|
|
|
|
|
+ @click.stop="decreaseQuantity(index)"
|
|
|
|
|
+ >
|
|
|
|
|
+ <text>-</text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="quantity-display">
|
|
|
|
|
+ <text class="quantity-text">{{ product.refundQuantity || 1 }}</text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view
|
|
|
|
|
+ :class="['control-btn', (product.refundQuantity || 1) < product.quantity ? '' : 'disabled']"
|
|
|
|
|
+ @click.stop="increaseQuantity(index)"
|
|
|
|
|
+ >
|
|
|
|
|
+ <text>+</text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="refund-amount-preview">
|
|
|
|
|
+ <text class="preview-label">退款金额</text>
|
|
|
|
|
+ <text class="preview-value">¥{{ ((product.price || 0) * (product.refundQuantity || 1)).toFixed(2) }}</text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="selected-tip">
|
|
|
|
|
+ 已选择 {{ selectedProducts.length }} 件商品,共 {{ refundQuantity }} 件
|
|
|
|
|
+ </view>
|
|
|
</view>
|
|
</view>
|
|
|
|
|
|
|
|
<!-- 退款原因 -->
|
|
<!-- 退款原因 -->
|
|
@@ -24,30 +84,80 @@
|
|
|
<text class="section-title">退款信息</text>
|
|
<text class="section-title">退款信息</text>
|
|
|
<view class="info-row">
|
|
<view class="info-row">
|
|
|
<text class="info-label">订单编号:</text>
|
|
<text class="info-label">订单编号:</text>
|
|
|
- <text class="info-value">2601081537467989</text>
|
|
|
|
|
|
|
+ <text class="info-value">{{ orderInfo.orderNo || '-' }}</text>
|
|
|
</view>
|
|
</view>
|
|
|
<view class="info-row">
|
|
<view class="info-row">
|
|
|
<text class="info-label">订单总金额:</text>
|
|
<text class="info-label">订单总金额:</text>
|
|
|
- <text class="info-value">0.44</text>
|
|
|
|
|
|
|
+ <text class="info-value">¥{{ (orderInfo.totalAmount || 0).toFixed(2) }}</text>
|
|
|
</view>
|
|
</view>
|
|
|
<view class="info-row">
|
|
<view class="info-row">
|
|
|
<text class="info-label">退款数量:</text>
|
|
<text class="info-label">退款数量:</text>
|
|
|
- <text class="info-value">1</text>
|
|
|
|
|
|
|
+ <text class="info-value">{{ refundQuantity }}</text>
|
|
|
</view>
|
|
</view>
|
|
|
<view class="info-row">
|
|
<view class="info-row">
|
|
|
<text class="info-label">退款总金额:</text>
|
|
<text class="info-label">退款总金额:</text>
|
|
|
- <text class="info-value">0.44</text>
|
|
|
|
|
|
|
+ <text class="info-value refund-amount">¥{{ refundAmount.toFixed(2) }}</text>
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
|
|
|
|
|
|
|
+ <!-- 提示信息 -->
|
|
|
|
|
+ <view class="section-block tip-section">
|
|
|
|
|
+ <text class="tip-text">• 请选择需要退款的商品</text>
|
|
|
|
|
+ <text class="tip-text">• 退款申请提交后,工作人员将尽快处理</text>
|
|
|
|
|
+ <text class="tip-text">• 退款金额将原路返回至您的支付账户</text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+
|
|
|
<!-- 确认提交按钮 -->
|
|
<!-- 确认提交按钮 -->
|
|
|
<button class="submit-btn" @click="submitRefund">确认提交</button>
|
|
<button class="submit-btn" @click="submitRefund">确认提交</button>
|
|
|
</view>
|
|
</view>
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
|
<script setup lang="ts">
|
|
|
-import { ref, onMounted } from 'vue';
|
|
|
|
|
|
|
+import { ref, computed, onMounted } from 'vue';
|
|
|
|
|
+import { onLoad } from '@dcloudio/uni-app';
|
|
|
import { checkAuth } from '../../utils/auth';
|
|
import { checkAuth } from '../../utils/auth';
|
|
|
|
|
+import { getOrderDetail } from '../../api/order';
|
|
|
|
|
+import type { OrderInfo } from '../../api/order';
|
|
|
|
|
+import { post } from '../../utils/request';
|
|
|
|
|
+
|
|
|
|
|
+// 路由参数
|
|
|
|
|
+const orderId = ref<number>(0);
|
|
|
|
|
+
|
|
|
|
|
+// 订单信息
|
|
|
|
|
+const orderInfo = ref<OrderInfo>({
|
|
|
|
|
+ id: 0,
|
|
|
|
|
+ orderNo: '',
|
|
|
|
|
+ outTradeNo: '',
|
|
|
|
|
+ hahaOrderNo: '',
|
|
|
|
|
+ deviceId: '',
|
|
|
|
|
+ totalAmount: 0,
|
|
|
|
|
+ payStatus: '',
|
|
|
|
|
+ status: 0,
|
|
|
|
|
+ createTime: '',
|
|
|
|
|
+ products: []
|
|
|
|
|
+});
|
|
|
|
|
+
|
|
|
|
|
+// 选中的商品索引列表
|
|
|
|
|
+const selectedProducts = ref<number[]>([]);
|
|
|
|
|
+
|
|
|
|
|
+// 退款数量(根据选中商品的退款数量计算)
|
|
|
|
|
+const refundQuantity = computed(() => {
|
|
|
|
|
+ return selectedProducts.value.reduce((sum, index) => {
|
|
|
|
|
+ const product = orderInfo.value.products[index];
|
|
|
|
|
+ return sum + (product.refundQuantity || 1);
|
|
|
|
|
+ }, 0);
|
|
|
|
|
+});
|
|
|
|
|
+
|
|
|
|
|
+// 退款金额(根据选中商品的退款数量计算)
|
|
|
|
|
+const refundAmount = computed(() => {
|
|
|
|
|
+ return selectedProducts.value.reduce((sum, index) => {
|
|
|
|
|
+ const product = orderInfo.value.products[index];
|
|
|
|
|
+ if (product) {
|
|
|
|
|
+ return sum + (product.price || 0) * (product.refundQuantity || 1);
|
|
|
|
|
+ }
|
|
|
|
|
+ return sum;
|
|
|
|
|
+ }, 0);
|
|
|
|
|
+});
|
|
|
|
|
|
|
|
const selectedReason = ref('');
|
|
const selectedReason = ref('');
|
|
|
|
|
|
|
@@ -63,14 +173,143 @@ const handleReasonChange = (e: any) => {
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
- * 页面加载时检查登录状态
|
|
|
|
|
|
|
+ * 切换商品选中状态
|
|
|
|
|
+ */
|
|
|
|
|
+const toggleProductSelect = (index: number) => {
|
|
|
|
|
+ const selectedIndex = selectedProducts.value.indexOf(index);
|
|
|
|
|
+ if (selectedIndex > -1) {
|
|
|
|
|
+ // 取消选中:清除退款数量
|
|
|
|
|
+ orderInfo.value.products[index].refundQuantity = undefined;
|
|
|
|
|
+ selectedProducts.value.splice(selectedIndex, 1);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 选中:初始化退款数量为 1
|
|
|
|
|
+ if (!orderInfo.value.products[index].refundQuantity) {
|
|
|
|
|
+ orderInfo.value.products[index].refundQuantity = 1;
|
|
|
|
|
+ }
|
|
|
|
|
+ selectedProducts.value.push(index);
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 显示商品全称
|
|
|
|
|
+ */
|
|
|
|
|
+const showProductName = (productName: string) => {
|
|
|
|
|
+ uni.showModal({
|
|
|
|
|
+ title: '商品名称',
|
|
|
|
|
+ content: productName,
|
|
|
|
|
+ showCancel: false,
|
|
|
|
|
+ confirmText: '知道了'
|
|
|
|
|
+ });
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 减少退款数量
|
|
|
|
|
+ */
|
|
|
|
|
+const decreaseQuantity = (index: number) => {
|
|
|
|
|
+ const product = orderInfo.value.products[index];
|
|
|
|
|
+ if (product.refundQuantity && product.refundQuantity > 1) {
|
|
|
|
|
+ product.refundQuantity--;
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 增加退款数量
|
|
|
|
|
+ */
|
|
|
|
|
+const increaseQuantity = (index: number) => {
|
|
|
|
|
+ const product = orderInfo.value.products[index];
|
|
|
|
|
+ if ((product.refundQuantity || 1) < product.quantity) {
|
|
|
|
|
+ if (!product.refundQuantity) {
|
|
|
|
|
+ product.refundQuantity = 2;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ product.refundQuantity++;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 显示商品详情
|
|
|
|
|
+ */
|
|
|
|
|
+const showProductDetail = () => {
|
|
|
|
|
+ // TODO: 跳转到商品详情页或弹出商品详情弹窗
|
|
|
|
|
+ uni.showToast({
|
|
|
|
|
+ title: '商品详情功能开发中',
|
|
|
|
|
+ icon: 'none'
|
|
|
|
|
+ });
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 加载订单详情
|
|
|
|
|
+ */
|
|
|
|
|
+const loadOrderDetail = async () => {
|
|
|
|
|
+ if (!orderId.value) {
|
|
|
|
|
+ uni.showToast({
|
|
|
|
|
+ title: '订单 ID 缺失',
|
|
|
|
|
+ icon: 'none'
|
|
|
|
|
+ });
|
|
|
|
|
+ setTimeout(() => {
|
|
|
|
|
+ uni.navigateBack();
|
|
|
|
|
+ }, 1500);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ const detail = await getOrderDetail({ orderId: orderId.value });
|
|
|
|
|
+ orderInfo.value = detail;
|
|
|
|
|
+
|
|
|
|
|
+ // 默认不选中任何商品(移除之前的默认全选逻辑)
|
|
|
|
|
+ selectedProducts.value = [];
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error('加载订单详情失败:', error);
|
|
|
|
|
+ uni.showToast({
|
|
|
|
|
+ title: '加载订单详情失败',
|
|
|
|
|
+ icon: 'none'
|
|
|
|
|
+ });
|
|
|
|
|
+ setTimeout(() => {
|
|
|
|
|
+ uni.navigateBack();
|
|
|
|
|
+ }, 1500);
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 页面加载时检查登录状态并加载订单详情
|
|
|
*/
|
|
*/
|
|
|
onMounted(() => {
|
|
onMounted(() => {
|
|
|
// 检查登录状态,未登录会自动跳转到登录页
|
|
// 检查登录状态,未登录会自动跳转到登录页
|
|
|
checkAuth();
|
|
checkAuth();
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
-const submitRefund = () => {
|
|
|
|
|
|
|
+/**
|
|
|
|
|
+ * 监听页面加载参数
|
|
|
|
|
+ */
|
|
|
|
|
+onLoad((options) => {
|
|
|
|
|
+ if (options && options.orderId) {
|
|
|
|
|
+ orderId.value = parseInt(options.orderId as string);
|
|
|
|
|
+ loadOrderDetail();
|
|
|
|
|
+ } else {
|
|
|
|
|
+ uni.showToast({
|
|
|
|
|
+ title: '订单 ID 缺失',
|
|
|
|
|
+ icon: 'none'
|
|
|
|
|
+ });
|
|
|
|
|
+ setTimeout(() => {
|
|
|
|
|
+ uni.navigateBack();
|
|
|
|
|
+ }, 1500);
|
|
|
|
|
+ }
|
|
|
|
|
+});
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 提交退款申请
|
|
|
|
|
+ */
|
|
|
|
|
+const submitRefund = async () => {
|
|
|
|
|
+ // 校验是否选择了商品
|
|
|
|
|
+ if (selectedProducts.value.length === 0) {
|
|
|
|
|
+ uni.showToast({
|
|
|
|
|
+ title: '请选择要退款的商品',
|
|
|
|
|
+ icon: 'none'
|
|
|
|
|
+ });
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 校验退款原因
|
|
|
if (!selectedReason.value) {
|
|
if (!selectedReason.value) {
|
|
|
uni.showToast({
|
|
uni.showToast({
|
|
|
title: '请选择退款原因',
|
|
title: '请选择退款原因',
|
|
@@ -78,15 +317,48 @@ const submitRefund = () => {
|
|
|
});
|
|
});
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- uni.showToast({
|
|
|
|
|
- title: '退款申请提交成功',
|
|
|
|
|
- icon: 'success'
|
|
|
|
|
|
|
+
|
|
|
|
|
+ // 映射前端退款原因到后端描述
|
|
|
|
|
+ const reasonMap: Record<string, string> = {
|
|
|
|
|
+ '1': '订单扣款错误',
|
|
|
|
|
+ '2': '扣款金额与实际金额不符',
|
|
|
|
|
+ '3': '商品过期或变质',
|
|
|
|
|
+ '4': '其他'
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ const reasonText = reasonMap[selectedReason.value] || '用户申请退款';
|
|
|
|
|
+
|
|
|
|
|
+ // 构建选中的商品信息(包含退款数量)
|
|
|
|
|
+ const selectedProductIds = selectedProducts.value.map(index => {
|
|
|
|
|
+ const product = orderInfo.value.products[index];
|
|
|
|
|
+ return {
|
|
|
|
|
+ productId: product.id,
|
|
|
|
|
+ productName: product.name,
|
|
|
|
|
+ quantity: product.refundQuantity || 1, // 使用用户选择的退款数量
|
|
|
|
|
+ price: product.price
|
|
|
|
|
+ };
|
|
|
});
|
|
});
|
|
|
-
|
|
|
|
|
- setTimeout(() => {
|
|
|
|
|
- uni.navigateBack();
|
|
|
|
|
- }, 1500);
|
|
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ // 调用后端退款 API
|
|
|
|
|
+ const result = await post('/payment/refund', {
|
|
|
|
|
+ orderId: orderId.value,
|
|
|
|
|
+ reason: reasonText,
|
|
|
|
|
+ products: selectedProductIds // 传递选中的商品信息
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ uni.showToast({
|
|
|
|
|
+ title: '退款申请成功',
|
|
|
|
|
+ icon: 'success'
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ setTimeout(() => {
|
|
|
|
|
+ uni.navigateBack();
|
|
|
|
|
+ }, 1500);
|
|
|
|
|
+ } catch (error: any) {
|
|
|
|
|
+ console.error('退款申请失败:', error);
|
|
|
|
|
+ // 错误提示已在 request 拦截器中处理
|
|
|
|
|
+ }
|
|
|
};
|
|
};
|
|
|
</script>
|
|
</script>
|
|
|
|
|
|
|
@@ -95,6 +367,264 @@ const submitRefund = () => {
|
|
|
min-height: 100vh;
|
|
min-height: 100vh;
|
|
|
background-color: #f5f5f5;
|
|
background-color: #f5f5f5;
|
|
|
padding-top: 20rpx;
|
|
padding-top: 20rpx;
|
|
|
|
|
+ padding-bottom: 40rpx;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/* 商品选择区域 */
|
|
|
|
|
+.product-section {
|
|
|
|
|
+ margin-bottom: 20rpx;
|
|
|
|
|
+ padding-bottom: 20rpx;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.product-list {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ gap: 20rpx;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.product-item {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ background-color: #ffffff;
|
|
|
|
|
+ border-radius: 12rpx;
|
|
|
|
|
+ padding: 24rpx;
|
|
|
|
|
+ border: 2rpx solid transparent;
|
|
|
|
|
+ transition: all 0.3s ease;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.product-item-selected {
|
|
|
|
|
+ border-color: #07c160;
|
|
|
|
|
+ background-color: #f6ffed;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.product-item:active {
|
|
|
|
|
+ background-color: #fafafa;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.product-main {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.product-checkbox {
|
|
|
|
|
+ margin-right: 20rpx;
|
|
|
|
|
+ flex-shrink: 0;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.checkbox-icon {
|
|
|
|
|
+ width: 44rpx;
|
|
|
|
|
+ height: 44rpx;
|
|
|
|
|
+ border-radius: 50%;
|
|
|
|
|
+ border: 3rpx solid #dddddd;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+ transition: all 0.3s ease;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.checkbox-icon.checked {
|
|
|
|
|
+ background-color: #07c160;
|
|
|
|
|
+ border-color: #07c160;
|
|
|
|
|
+ box-shadow: 0 4rpx 12rpx rgba(7, 193, 96, 0.3);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.checkbox-icon text {
|
|
|
|
|
+ color: #ffffff;
|
|
|
|
|
+ font-size: 26rpx;
|
|
|
|
|
+ font-weight: bold;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.product-image {
|
|
|
|
|
+ width: 140rpx;
|
|
|
|
|
+ height: 140rpx;
|
|
|
|
|
+ border-radius: 12rpx;
|
|
|
|
|
+ overflow: hidden;
|
|
|
|
|
+ flex-shrink: 0;
|
|
|
|
|
+ margin-right: 20rpx;
|
|
|
|
|
+ background-color: #f5f5f5;
|
|
|
|
|
+ box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.06);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.product-image image {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ height: 100%;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.image-placeholder {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ height: 100%;
|
|
|
|
|
+ background: linear-gradient(135deg, #f5f5f5 0%, #e0e0e0 100%);
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+ color: #999999;
|
|
|
|
|
+ font-size: 40rpx;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.product-detail {
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+ min-width: 0;
|
|
|
|
|
+ gap: 8rpx;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.name-container {
|
|
|
|
|
+ position: relative;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ cursor: pointer;
|
|
|
|
|
+ max-width: 100%;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.product-name {
|
|
|
|
|
+ font-size: 28rpx;
|
|
|
|
|
+ color: #333333;
|
|
|
|
|
+ line-height: 1.4;
|
|
|
|
|
+ overflow: hidden;
|
|
|
|
|
+ text-overflow: ellipsis;
|
|
|
|
|
+ white-space: nowrap;
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ min-width: 0;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.expand-tip {
|
|
|
|
|
+ font-size: 26rpx;
|
|
|
|
|
+ color: #1890ff;
|
|
|
|
|
+ margin-left: 8rpx;
|
|
|
|
|
+ flex-shrink: 0;
|
|
|
|
|
+ padding: 4rpx 12rpx;
|
|
|
|
|
+ background-color: #e6f7ff;
|
|
|
|
|
+ border-radius: 6rpx;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.product-meta {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ justify-content: space-between;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ flex-wrap: wrap;
|
|
|
|
|
+ gap: 8rpx;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.product-price {
|
|
|
|
|
+ font-size: 32rpx;
|
|
|
|
|
+ color: #ff4400;
|
|
|
|
|
+ font-weight: 600;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.product-quantity {
|
|
|
|
|
+ font-size: 24rpx;
|
|
|
|
|
+ color: #999999;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.product-quantity-label {
|
|
|
|
|
+ font-size: 24rpx;
|
|
|
|
|
+ color: #999999;
|
|
|
|
|
+ background-color: #f5f5f5;
|
|
|
|
|
+ padding: 4rpx 12rpx;
|
|
|
|
|
+ border-radius: 6rpx;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/* 退款数量选择器 */
|
|
|
|
|
+.refund-quantity-selector {
|
|
|
|
|
+ margin-top: 20rpx;
|
|
|
|
|
+ margin-left: 56rpx;
|
|
|
|
|
+ padding: 20rpx 24rpx;
|
|
|
|
|
+ background-color: #fafffe;
|
|
|
|
|
+ border-radius: 12rpx;
|
|
|
|
|
+ border: 1rpx solid #d9f7be;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.selector-row {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ justify-content: space-between;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.selector-label {
|
|
|
|
|
+ font-size: 28rpx;
|
|
|
|
|
+ color: #52c41a;
|
|
|
|
|
+ font-weight: 500;
|
|
|
|
|
+ flex-shrink: 0;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.quantity-control {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ gap: 16rpx;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.control-btn {
|
|
|
|
|
+ width: 60rpx;
|
|
|
|
|
+ height: 60rpx;
|
|
|
|
|
+ border-radius: 12rpx;
|
|
|
|
|
+ background-color: #ffffff;
|
|
|
|
|
+ border: 2rpx solid #e0e0e0;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+ font-size: 36rpx;
|
|
|
|
|
+ color: #333333;
|
|
|
|
|
+ transition: all 0.2s;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.control-btn:active {
|
|
|
|
|
+ background-color: #f0f0f0;
|
|
|
|
|
+ transform: scale(0.95);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.control-btn.disabled {
|
|
|
|
|
+ background-color: #fafafa;
|
|
|
|
|
+ border-color: #f0f0f0;
|
|
|
|
|
+ color: #cccccc;
|
|
|
|
|
+ cursor: not-allowed;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.control-btn.disabled:active {
|
|
|
|
|
+ background-color: #fafafa;
|
|
|
|
|
+ transform: none;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.quantity-display {
|
|
|
|
|
+ min-width: 80rpx;
|
|
|
|
|
+ height: 60rpx;
|
|
|
|
|
+ text-align: center;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+ background-color: #ffffff;
|
|
|
|
|
+ border: 2rpx solid #07c160;
|
|
|
|
|
+ border-radius: 12rpx;
|
|
|
|
|
+ padding: 0 16rpx;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.quantity-text {
|
|
|
|
|
+ font-size: 32rpx;
|
|
|
|
|
+ color: #07c160;
|
|
|
|
|
+ font-weight: 600;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/* 退款金额预览 */
|
|
|
|
|
+.refund-amount-preview {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ justify-content: space-between;
|
|
|
|
|
+ margin-top: 16rpx;
|
|
|
|
|
+ padding-top: 16rpx;
|
|
|
|
|
+ border-top: 1rpx dashed #d9f7be;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.preview-label {
|
|
|
|
|
+ font-size: 26rpx;
|
|
|
|
|
+ color: #999999;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.preview-value {
|
|
|
|
|
+ font-size: 30rpx;
|
|
|
|
|
+ color: #ff4400;
|
|
|
|
|
+ font-weight: 600;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/* 退款商品选择器 */
|
|
/* 退款商品选择器 */
|
|
@@ -203,4 +733,43 @@ radio-group {
|
|
|
.submit-btn::after {
|
|
.submit-btn::after {
|
|
|
border: none;
|
|
border: none;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+/* 商品信息 */
|
|
|
|
|
+.product-info {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ gap: 16rpx;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.refund-amount {
|
|
|
|
|
+ color: #ff4400;
|
|
|
|
|
+ font-weight: 500;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/* 提示信息 */
|
|
|
|
|
+.tip-section {
|
|
|
|
|
+ background-color: #fffbea;
|
|
|
|
|
+ border: 1rpx solid #ffe58f;
|
|
|
|
|
+ border-radius: 8rpx;
|
|
|
|
|
+ padding: 24rpx 30rpx;
|
|
|
|
|
+ margin: 30rpx;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.tip-text {
|
|
|
|
|
+ display: block;
|
|
|
|
|
+ font-size: 24rpx;
|
|
|
|
|
+ color: #faad14;
|
|
|
|
|
+ line-height: 1.8;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.selected-tip {
|
|
|
|
|
+ text-align: right;
|
|
|
|
|
+ font-size: 26rpx;
|
|
|
|
|
+ color: #07c160;
|
|
|
|
|
+ margin-top: 20rpx;
|
|
|
|
|
+ padding: 16rpx 20rpx;
|
|
|
|
|
+ background-color: #f6ffed;
|
|
|
|
|
+ border-radius: 8rpx;
|
|
|
|
|
+ font-weight: 500;
|
|
|
|
|
+}
|
|
|
</style>
|
|
</style>
|