877 lines
25 KiB
Vue
877 lines
25 KiB
Vue
<!-- 在这个文件对每个tab对应的列表进行渲染 -->
|
||
<template>
|
||
<view class="content">
|
||
<!-- :enable-back-to-top="currentIndex===tabIndex" 在微信小程序上可以多加这一句,因为默认是允许点击返回顶部的,但是这个页面有多个scroll-view,会全部返回顶部,所以需要控制是当前index才允许点击返回顶部 -->
|
||
<!-- 如果当前页已经加载过数据或者当前切换到的tab是当前页,才展示当前页数据(懒加载) -->
|
||
<z-paging v-if="firstLoaded || isCurrentPage" ref="paging" v-model="dataList" @query="queryList" :fixed="false">
|
||
<!-- 搜索框 -->
|
||
<text-search v-model="searchKeyword" placeholder="搜索订单" @search="onSearch" @clear="onClear" />
|
||
|
||
<!-- 如果希望其他view跟着页面滚动,可以放在z-paging标签内 -->
|
||
<view class="order-item" v-for="(item, index) in dataList" :key="index" @click="itemClick(item)">
|
||
<view class="order-header">
|
||
<text class="order-no" @click.stop="copyOrderNo(item.order_no)">订单号:{{ item.order_no }}</text>
|
||
<text class="order-status">{{ item.order_status_text }}</text>
|
||
</view>
|
||
<view class="order-content">
|
||
<image class="product-cover" :src="item.product_cover" mode="aspectFill"></image>
|
||
<view class="product-info">
|
||
<text class="product-title">{{ item.product_title }}</text>
|
||
<text class="payment-amount">¥{{ item.payment_amount }}</text>
|
||
</view>
|
||
</view>
|
||
<view class="order-footer">
|
||
<text class="order-time">{{ item.payment_time }}</text>
|
||
<view class="order-actions">
|
||
<!-- 已发货状态 -->
|
||
<template v-if="item.order_status === 2">
|
||
<view class="btn default" @click.stop="applyAfterSale(item)">申请售后</view>
|
||
<view class="btn primary" @click.stop="confirmReceive(item)">确认收货</view>
|
||
</template>
|
||
|
||
<!-- 已收货状态 -->
|
||
<template v-else-if="item.order_status === 3">
|
||
<view class="btn default" v-if="item.is_invoice !== 1" @click.stop="applyInvoice(item)">申请发票
|
||
</view>
|
||
<view class="btn default" v-else>已申请发票</view>
|
||
<view class="btn default"
|
||
v-if="item.is_invoice !== 1 && isWithinSevenDays(item.receive_time)"
|
||
@click.stop="applyAfterSale(item)">
|
||
申请售后</view>
|
||
<view class="btn default" @click.stop="deleteOrder(item)">删除订单</view>
|
||
<view class="btn default" @click.stop="buyAgain(item)">再次购买</view>
|
||
</template>
|
||
|
||
<!-- 已取消状态 -->
|
||
<template v-else-if="item.order_status === 5">
|
||
<view class="btn default" @click.stop="buyAgain(item)">再次购买</view>
|
||
</template>
|
||
|
||
<!-- 申请售后状态 -->
|
||
<template v-else-if="item.order_status === 6">
|
||
<view class="btn default" @click.stop="cancelAfterSale(item)">取消售后</view>
|
||
</template>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<template #empty>
|
||
<no-data />
|
||
</template>
|
||
<template #loading>
|
||
<loading-data />
|
||
</template>
|
||
</z-paging>
|
||
|
||
<!-- 申请发票弹窗 -->
|
||
<view class="invoice-popup" v-if="showInvoicePopup">
|
||
<view class="popup-mask" @click="closeInvoicePopup"></view>
|
||
<view class="popup-content">
|
||
<view class="popup-header">
|
||
<text class="popup-title">申请发票</text>
|
||
<text class="popup-close" @click="closeInvoicePopup">×</text>
|
||
</view>
|
||
|
||
<view class="product-info-box">
|
||
<image class="product-popup-cover" :src="currentProduct.product_cover" mode="aspectFill"></image>
|
||
<view class="product-popup-info">
|
||
<text class="product-popup-title">{{ currentProduct.product_title }}</text>
|
||
<text class="product-popup-price">¥{{ currentProduct.payment_amount }}</text>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="form-item">
|
||
<view class="form-label">发票类型</view>
|
||
<view class="form-content radio-group">
|
||
<view v-for="(type, index) in invoiceTypes" :key="index" class="radio-item"
|
||
:class="{ active: invoiceForm.invoice_type === type.value }"
|
||
@click="invoiceForm.invoice_type = type.value">
|
||
<text>{{ type.label }}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="form-item">
|
||
<view class="form-label">发票抬头<text class="required">*</text></view>
|
||
<view class="form-content">
|
||
<input type="text" class="input" v-model="invoiceForm.invoice_title" placeholder="请输入发票抬头" />
|
||
</view>
|
||
</view>
|
||
|
||
<view class="form-item">
|
||
<view class="form-label">发票内容<text class="required">*</text></view>
|
||
<view class="form-content">
|
||
<input type="text" class="input" v-model="invoiceForm.invoice_content" placeholder="请输入发票内容" />
|
||
</view>
|
||
</view>
|
||
|
||
<view class="form-item">
|
||
<view class="form-label">申请邮箱<text class="required">*</text></view>
|
||
<view class="form-content">
|
||
<input type="text" class="input" v-model="invoiceForm.user_email" placeholder="请输入接收发票的邮箱" />
|
||
</view>
|
||
</view>
|
||
|
||
<view class="popup-footer">
|
||
<view class="btn default" @click="closeInvoicePopup">取消</view>
|
||
<view class="btn primary" @click="submitInvoice">提交申请</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 申请售后弹窗 -->
|
||
<view class="after-sale-popup" v-if="showAfterSalePopup">
|
||
<view class="popup-mask" @click="closeAfterSalePopup"></view>
|
||
<view class="popup-content">
|
||
<view class="popup-header">
|
||
<text class="popup-title">申请售后</text>
|
||
<text class="popup-close" @click="closeAfterSalePopup">×</text>
|
||
</view>
|
||
|
||
<view class="product-info-box">
|
||
<image class="product-popup-cover" :src="currentProduct.product_cover" mode="aspectFill"></image>
|
||
<view class="product-popup-info">
|
||
<text class="product-popup-title">{{ currentProduct.product_title }}</text>
|
||
<text class="product-popup-price">¥{{ currentProduct.payment_amount }}</text>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="form-item">
|
||
<view class="form-label">售后类型</view>
|
||
<view class="form-content radio-group">
|
||
<view v-for="(type, index) in afterSaleTypes" :key="index" class="radio-item"
|
||
:class="{ active: afterSaleForm.type === type.value }"
|
||
@click="afterSaleForm.type = type.value">
|
||
<text>{{ type.label }}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="form-item">
|
||
<view class="form-label">申请原因</view>
|
||
<view class="form-content radio-group">
|
||
<view v-for="(reason, index) in afterSaleReasons" :key="index" class="radio-item"
|
||
:class="{ active: afterSaleForm.reason === reason }" @click="afterSaleForm.reason = reason">
|
||
<text>{{ reason }}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="form-item">
|
||
<view class="form-label">申请说明<text class="required">*</text></view>
|
||
<view class="form-content">
|
||
<textarea class="input-textarea" v-model="afterSaleForm.remark" placeholder="请详细描述您的问题" />
|
||
</view>
|
||
</view>
|
||
|
||
<view class="form-item">
|
||
<view class="form-label">联系电话</view>
|
||
<view class="form-content">
|
||
<input type="text" class="input" v-model="afterSaleForm.phone" placeholder="请输入联系电话" />
|
||
</view>
|
||
</view>
|
||
|
||
<view class="popup-footer">
|
||
<view class="btn default" @click="closeAfterSalePopup">取消</view>
|
||
<view class="btn primary" @click="submitAfterSale">提交申请</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { ref, watch, nextTick, onMounted, reactive } from 'vue';
|
||
import { order_receive, apply_refund, cancel_refund, delete_order, apply_invoice } from '@/common/server/order';
|
||
import TextSearch from '@/components/youdas-container/text-search.vue';
|
||
// props定义
|
||
const props = defineProps({
|
||
// 当前组件的index,也就是当前组件是swiper中的第几个
|
||
tabIndex: {
|
||
type: Number,
|
||
default: 0
|
||
},
|
||
// 当前swiper切换到第几个index
|
||
currentIndex: {
|
||
type: Number,
|
||
default: 0
|
||
},
|
||
responseCallback: {
|
||
type: Function,
|
||
default: null
|
||
}
|
||
});
|
||
// tabIndex ['全部', '待发货', '待收货', '已收货', '售后']
|
||
// 数据
|
||
// v-model绑定的这个变量不要在分页请求结束中自己赋值!!!
|
||
const dataList = ref([]);
|
||
// 当前组件是否已经加载过了
|
||
const firstLoaded = ref(false);
|
||
// 是否滚动到当前页
|
||
const isCurrentPage = ref(false);
|
||
// ref引用
|
||
const paging = ref(null);
|
||
// 搜索关键词
|
||
const searchKeyword = ref('');
|
||
|
||
// 售后弹窗数据
|
||
const showAfterSalePopup = ref(false);
|
||
const currentProduct = ref({});
|
||
const afterSaleTypes = [
|
||
{ label: '退货退款', value: 1 },
|
||
{ label: '换货', value: 2 },
|
||
{ label: '其它', value: 3 }
|
||
];
|
||
const afterSaleReasons = ['不想要了', '材质与商品不符', '质量问题', '发错货', '其他原因'];
|
||
const afterSaleForm = reactive({
|
||
type: 1,
|
||
reason: '不想要了',
|
||
remark: '',
|
||
phone: ''
|
||
});
|
||
|
||
// 发票弹窗数据
|
||
const showInvoicePopup = ref(false);
|
||
const invoiceTypes = [
|
||
{ label: '个人', value: 1 },
|
||
{ label: '企业', value: 2 }
|
||
];
|
||
const invoiceForm = reactive({
|
||
invoice_type: 1,
|
||
invoice_title: '',
|
||
invoice_content: '',
|
||
user_email: ''
|
||
});
|
||
|
||
// 监听currentIndex变化
|
||
watch(
|
||
() => props.currentIndex,
|
||
(newVal) => {
|
||
if (newVal === props.tabIndex) {
|
||
// 懒加载,当滑动到当前的item时,才去加载
|
||
if (!firstLoaded.value) {
|
||
// 这里需要延迟渲染z-paging的原因是为了避免在一些平台上立即渲染可能引发的底层报错问题
|
||
nextTick(() => {
|
||
setTimeout(() => {
|
||
isCurrentPage.value = true;
|
||
}, 100);
|
||
});
|
||
}
|
||
}
|
||
},
|
||
{ immediate: true }
|
||
);
|
||
|
||
// 接收父组件传过来的刷新列表要求
|
||
const reload = () => {
|
||
nextTick(() => {
|
||
// 刷新列表数据(如果不希望列表pageNo被重置可以用refresh代替reload方法)
|
||
paging.value && paging.value.reload();
|
||
});
|
||
};
|
||
|
||
const queryList = (pageNo, pageSize) => {
|
||
if (!props.responseCallback) { paging.value.complete(false); return; };
|
||
|
||
const params = {
|
||
pageNo: pageNo,
|
||
pageSize: pageSize,
|
||
type: props.tabIndex,
|
||
keyword: searchKeyword.value // 添加搜索关键词参数
|
||
};
|
||
|
||
try {
|
||
props.responseCallback(params).then(res => {
|
||
if (paging.value) {
|
||
console.log(res);
|
||
|
||
paging.value.complete(res.list || []);
|
||
firstLoaded.value = true;
|
||
}
|
||
}).catch(err => {
|
||
if (paging.value) {
|
||
paging.value.complete(false);
|
||
}
|
||
console.error('获取新闻列表失败', err);
|
||
});
|
||
} catch (e) {
|
||
console.error('调用responseCallback异常', e);
|
||
if (paging.value) {
|
||
paging.value.complete(false);
|
||
}
|
||
}
|
||
};
|
||
|
||
// 搜索处理函数
|
||
const onSearch = (value) => {
|
||
searchKeyword.value = value;
|
||
// 刷新列表,重新搜索
|
||
reload();
|
||
};
|
||
|
||
// 清空搜索
|
||
const onClear = () => {
|
||
searchKeyword.value = '';
|
||
// 刷新列表,显示所有数据
|
||
reload();
|
||
};
|
||
|
||
// 点击项目
|
||
const itemClick = (item) => {
|
||
yds.navigateTo("/pages/mall/order-detail?order_no=" + item.order_no);
|
||
};
|
||
const applyInvoice = async (item) => {
|
||
currentProduct.value = item;
|
||
|
||
// 尝试从本地缓存获取上次的发票信息
|
||
try {
|
||
const cachedInvoiceData = uni.getStorageSync('lastInvoiceData');
|
||
if (cachedInvoiceData) {
|
||
// 使用缓存数据预填充表单
|
||
invoiceForm.invoice_type = cachedInvoiceData.invoice_type || 1;
|
||
invoiceForm.invoice_title = cachedInvoiceData.invoice_title || '';
|
||
invoiceForm.invoice_content = cachedInvoiceData.invoice_content || '';
|
||
invoiceForm.user_email = cachedInvoiceData.user_email || '';
|
||
} else {
|
||
// 无缓存数据时重置表单
|
||
invoiceForm.invoice_type = 1;
|
||
invoiceForm.invoice_title = '';
|
||
invoiceForm.invoice_content = '';
|
||
invoiceForm.user_email = '';
|
||
}
|
||
} catch (e) {
|
||
console.error('获取缓存发票数据失败', e);
|
||
// 发生错误时重置表单
|
||
invoiceForm.invoice_type = 1;
|
||
invoiceForm.invoice_title = '';
|
||
invoiceForm.invoice_content = '';
|
||
invoiceForm.user_email = '';
|
||
}
|
||
|
||
// 显示弹窗
|
||
showInvoicePopup.value = true;
|
||
};
|
||
// 复制订单号
|
||
const copyOrderNo = (orderNo) => {
|
||
uni.setClipboardData({
|
||
data: orderNo,
|
||
success: function () {
|
||
uni.showToast({
|
||
title: '订单号已复制',
|
||
icon: 'none'
|
||
});
|
||
}
|
||
});
|
||
};
|
||
|
||
// 通用确认弹窗方法
|
||
const showConfirmDialog = (title, content) => {
|
||
return new Promise((resolve) => {
|
||
uni.showModal({
|
||
title: title,
|
||
content: content,
|
||
confirmText: '取消',
|
||
cancelText: '确定',
|
||
success: function (res) {
|
||
resolve(!res.confirm);
|
||
}
|
||
});
|
||
});
|
||
};
|
||
|
||
// 通用API调用方法
|
||
const callApiWithLoading = async (apiFunc, successMsg) => {
|
||
try {
|
||
uni.showLoading({
|
||
title: '正在处理'
|
||
});
|
||
const res = await apiFunc();
|
||
uni.hideLoading();
|
||
|
||
if (res) {
|
||
uni.showToast({
|
||
title: successMsg,
|
||
icon: 'none'
|
||
});
|
||
// 刷新列表
|
||
reload();
|
||
return true;
|
||
} else {
|
||
uni.showToast({
|
||
title: '操作失败,请重试',
|
||
icon: 'none'
|
||
});
|
||
return false;
|
||
}
|
||
} catch (error) {
|
||
uni.hideLoading();
|
||
uni.showToast({
|
||
title: '网络异常,请重试',
|
||
icon: 'none'
|
||
});
|
||
return false;
|
||
}
|
||
};
|
||
|
||
// 确认收货
|
||
const confirmReceive = async (item) => {
|
||
const confirmed = await showConfirmDialog('确认提示', '您确定要确认收货吗?');
|
||
if (confirmed) {
|
||
await callApiWithLoading(() => order_receive(item.order_no), '确认收货成功');
|
||
}
|
||
};
|
||
|
||
// 申请售后
|
||
const applyAfterSale = (item) => {
|
||
currentProduct.value = item;
|
||
// 重置表单
|
||
afterSaleForm.type = 1;
|
||
afterSaleForm.reason = '不想要了';
|
||
afterSaleForm.remark = '';
|
||
afterSaleForm.phone = '';
|
||
// 显示弹窗
|
||
showAfterSalePopup.value = true;
|
||
};
|
||
|
||
// 删除订单
|
||
const deleteOrder = async (item) => {
|
||
const confirmed = await showConfirmDialog('删除提示', '您确定要删除此订单吗?');
|
||
if (confirmed) {
|
||
await callApiWithLoading(() => delete_order(item.order_no), '删除成功');
|
||
}
|
||
};
|
||
|
||
// 再次购买
|
||
const buyAgain = (item) => {
|
||
yds.navigateTo("/pages/mall/product-detail?id=" + item.product_id);
|
||
};
|
||
|
||
// 判断是否在收货后7天内
|
||
const isWithinSevenDays = (receiveTime) => {
|
||
if (!receiveTime) return false;
|
||
|
||
const receiveDate = new Date(receiveTime);
|
||
const currentDate = new Date();
|
||
|
||
// 计算日期差值(毫秒)
|
||
const diffTime = currentDate - receiveDate;
|
||
// 转换为天数
|
||
const diffDays = Math.floor(diffTime / (1000 * 60 * 60 * 24));
|
||
|
||
// 如果天数差值小于等于7,返回true
|
||
return diffDays <= 7;
|
||
};
|
||
|
||
// 取消售后
|
||
const cancelAfterSale = async (item) => {
|
||
const confirmed = await showConfirmDialog('取消提示', '您确定要取消售后申请吗?');
|
||
if (confirmed) {
|
||
await callApiWithLoading(() => cancel_refund(item.order_no), '取消售后成功');
|
||
}
|
||
};
|
||
|
||
// 关闭售后弹窗
|
||
const closeAfterSalePopup = () => {
|
||
showAfterSalePopup.value = false;
|
||
};
|
||
|
||
// 关闭发票弹窗
|
||
const closeInvoicePopup = () => {
|
||
showInvoicePopup.value = false;
|
||
};
|
||
|
||
// 提交发票申请
|
||
const submitInvoice = async () => {
|
||
// 表单验证
|
||
if (!invoiceForm.invoice_title) {
|
||
uni.showToast({
|
||
title: '请填写发票抬头',
|
||
icon: 'none'
|
||
});
|
||
return;
|
||
}
|
||
if (!invoiceForm.invoice_content) {
|
||
uni.showToast({
|
||
title: '请填写发票内容',
|
||
icon: 'none'
|
||
});
|
||
return;
|
||
}
|
||
if (!invoiceForm.user_email) {
|
||
uni.showToast({
|
||
title: '请填写申请邮箱',
|
||
icon: 'none'
|
||
});
|
||
return;
|
||
}
|
||
|
||
// 验证邮箱格式
|
||
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
||
if (!emailRegex.test(invoiceForm.user_email)) {
|
||
uni.showToast({
|
||
title: '请输入正确的邮箱格式',
|
||
icon: 'none'
|
||
});
|
||
return;
|
||
}
|
||
|
||
const result = await callApiWithLoading(
|
||
() => apply_invoice(
|
||
currentProduct.value.order_no,
|
||
invoiceForm.invoice_title,
|
||
invoiceForm.invoice_content,
|
||
invoiceForm.invoice_type,
|
||
invoiceForm.user_email
|
||
),
|
||
'申请发票成功,发票抬头文件会在48小时内发送到您的邮箱。'
|
||
);
|
||
|
||
// 如果申请成功,保存发票数据到本地存储
|
||
if (result) {
|
||
try {
|
||
// 保存发票信息到本地缓存,下次使用
|
||
uni.setStorageSync('lastInvoiceData', {
|
||
invoice_type: invoiceForm.invoice_type,
|
||
invoice_title: invoiceForm.invoice_title,
|
||
invoice_content: invoiceForm.invoice_content,
|
||
user_email: invoiceForm.user_email
|
||
});
|
||
} catch (e) {
|
||
console.error('保存发票数据到缓存失败', e);
|
||
}
|
||
}
|
||
|
||
// 关闭弹窗
|
||
closeInvoicePopup();
|
||
};
|
||
|
||
// 提交售后申请
|
||
const submitAfterSale = async () => {
|
||
// 表单验证
|
||
if (!afterSaleForm.remark) {
|
||
uni.showToast({
|
||
title: '请填写申请说明',
|
||
icon: 'none'
|
||
});
|
||
return;
|
||
}
|
||
|
||
// 准备提交信息
|
||
const extendInfo = JSON.stringify({
|
||
type: afterSaleForm.type,
|
||
reason: afterSaleForm.reason,
|
||
remark: afterSaleForm.remark,
|
||
phone: afterSaleForm.phone
|
||
});
|
||
|
||
await callApiWithLoading(
|
||
() => apply_refund(currentProduct.value.order_no, extendInfo),
|
||
'申请售后成功,客服会在24小时内联系您处理。'
|
||
);
|
||
|
||
// 关闭弹窗
|
||
closeAfterSalePopup();
|
||
};
|
||
|
||
// 暴露方法给父组件调用
|
||
defineExpose({
|
||
reload
|
||
});
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
/* 注意:父节点需要固定高度,z-paging的height:100%才会生效 */
|
||
.content {
|
||
height: 100%;
|
||
}
|
||
|
||
.order-item {
|
||
background-color: #ffffff;
|
||
border-radius: 12rpx;
|
||
margin: 20rpx 30rpx;
|
||
padding: 20rpx;
|
||
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
|
||
}
|
||
|
||
.order-header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
padding-bottom: 20rpx;
|
||
border-bottom: 1px solid #f5f5f5;
|
||
}
|
||
|
||
.order-no {
|
||
font-size: 24rpx;
|
||
color: #999999;
|
||
position: relative;
|
||
|
||
&::after {
|
||
content: "";
|
||
position: absolute;
|
||
left: 0;
|
||
bottom: -2rpx;
|
||
width: 100%;
|
||
height: 1rpx;
|
||
background-color: #999999;
|
||
opacity: 0.5;
|
||
}
|
||
}
|
||
|
||
.order-status {
|
||
font-size: 28rpx;
|
||
color: #ff6700;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.order-content {
|
||
display: flex;
|
||
padding: 20rpx 0;
|
||
}
|
||
|
||
.product-cover {
|
||
width: 160rpx;
|
||
height: 160rpx;
|
||
border-radius: 8rpx;
|
||
}
|
||
|
||
.product-info {
|
||
flex: 1;
|
||
padding-left: 20rpx;
|
||
display: flex;
|
||
flex-direction: column;
|
||
justify-content: space-between;
|
||
}
|
||
|
||
.product-title {
|
||
font-size: 28rpx;
|
||
color: #333333;
|
||
font-weight: 500;
|
||
line-height: 40rpx;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
display: -webkit-box;
|
||
-webkit-line-clamp: 2;
|
||
-webkit-box-orient: vertical;
|
||
}
|
||
|
||
.payment-amount {
|
||
font-size: 32rpx;
|
||
color: #ff6700;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.order-footer {
|
||
display: flex;
|
||
flex-direction: column;
|
||
padding-top: 15rpx;
|
||
border-top: 1px solid #f5f5f5;
|
||
}
|
||
|
||
.order-time {
|
||
font-size: 24rpx;
|
||
color: #999999;
|
||
}
|
||
|
||
.order-actions {
|
||
display: flex;
|
||
justify-content: flex-end;
|
||
margin-top: 20rpx;
|
||
flex-wrap: wrap;
|
||
}
|
||
|
||
/* 按钮样式 */
|
||
.btn {
|
||
display: inline-block;
|
||
font-size: 24rpx;
|
||
padding: 10rpx 24rpx;
|
||
margin-left: 16rpx;
|
||
border-radius: 8rpx;
|
||
text-align: center;
|
||
transition: all 0.15s ease;
|
||
-webkit-tap-highlight-color: transparent;
|
||
|
||
&:active {
|
||
transform: scale(0.95);
|
||
}
|
||
|
||
&.default {
|
||
background-color: #ffffff;
|
||
color: #333333;
|
||
border: 1px solid #dddddd;
|
||
}
|
||
|
||
&.primary {
|
||
background-color: #e94e42;
|
||
color: #ffffff;
|
||
border: 1px solid #e94e42;
|
||
}
|
||
}
|
||
|
||
/* 售后弹窗样式 */
|
||
.after-sale-popup,
|
||
.invoice-popup {
|
||
position: fixed;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
z-index: 1000;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
|
||
.popup-mask {
|
||
position: absolute;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
background-color: rgba(0, 0, 0, 0.5);
|
||
}
|
||
|
||
.popup-content {
|
||
position: relative;
|
||
width: 92%;
|
||
max-height: 90vh;
|
||
background-color: #fff;
|
||
border-radius: 12rpx;
|
||
padding: 30rpx;
|
||
box-sizing: border-box;
|
||
overflow-y: auto;
|
||
}
|
||
|
||
.popup-header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: 30rpx;
|
||
}
|
||
|
||
.popup-title {
|
||
font-size: 32rpx;
|
||
font-weight: 600;
|
||
color: #333;
|
||
}
|
||
|
||
.popup-close {
|
||
font-size: 40rpx;
|
||
color: #999;
|
||
padding: 0 10rpx;
|
||
}
|
||
|
||
.product-info-box {
|
||
display: flex;
|
||
padding: 20rpx;
|
||
background-color: #f8f8f8;
|
||
border-radius: 8rpx;
|
||
margin-bottom: 20rpx;
|
||
}
|
||
|
||
.product-popup-cover {
|
||
width: 120rpx;
|
||
height: 120rpx;
|
||
border-radius: 8rpx;
|
||
}
|
||
|
||
.product-popup-info {
|
||
flex: 1;
|
||
padding-left: 20rpx;
|
||
display: flex;
|
||
flex-direction: column;
|
||
justify-content: space-between;
|
||
}
|
||
|
||
.product-popup-title {
|
||
font-size: 26rpx;
|
||
color: #333;
|
||
line-height: 36rpx;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
display: -webkit-box;
|
||
-webkit-line-clamp: 2;
|
||
-webkit-box-orient: vertical;
|
||
}
|
||
|
||
.product-popup-price {
|
||
font-size: 28rpx;
|
||
color: #ff6700;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.form-item {
|
||
margin-bottom: 20rpx;
|
||
}
|
||
|
||
.form-label {
|
||
font-size: 28rpx;
|
||
color: #333;
|
||
margin-bottom: 10rpx;
|
||
|
||
.required {
|
||
color: #ff4d4f;
|
||
margin-left: 4rpx;
|
||
}
|
||
}
|
||
|
||
.form-content {
|
||
width: 100%;
|
||
}
|
||
|
||
.radio-group {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
margin: 0 -10rpx;
|
||
}
|
||
|
||
.radio-item {
|
||
margin: 10rpx;
|
||
padding: 10rpx 20rpx;
|
||
border: 1px solid #ddd;
|
||
border-radius: 8rpx;
|
||
font-size: 26rpx;
|
||
color: #666;
|
||
|
||
&.active {
|
||
border-color: #ff6700;
|
||
color: #ff6700;
|
||
background-color: rgba(255, 103, 0, 0.05);
|
||
}
|
||
}
|
||
|
||
.input {
|
||
width: 100%;
|
||
height: 80rpx;
|
||
border: 1px solid #ddd;
|
||
border-radius: 8rpx;
|
||
padding: 0 20rpx;
|
||
font-size: 28rpx;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
.input-textarea {
|
||
width: 100%;
|
||
height: 180rpx;
|
||
border: 1px solid #ddd;
|
||
border-radius: 8rpx;
|
||
padding: 20rpx;
|
||
font-size: 28rpx;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
.popup-footer {
|
||
display: flex;
|
||
justify-content: flex-end;
|
||
margin-top: 30rpx;
|
||
|
||
.btn {
|
||
margin-left: 20rpx;
|
||
min-width: 160rpx;
|
||
height: 70rpx;
|
||
line-height: 70rpx;
|
||
font-size: 28rpx;
|
||
}
|
||
}
|
||
</style>
|