chuangte_bike_newxcx/page_fenbao/tousu/index.vue

1277 lines
30 KiB
Vue
Raw Permalink Normal View History

2025-08-30 17:38:15 +08:00
<template>
<view class="pages">
<u-navbar title="订单投诉" :border-bottom="false" :background="bgc" title-color='#fff' back-icon-color="#fff" height='44'></u-navbar>
<image class="topbj" src="https://api.ccttiot.com/smartmeter/img/static/uxpj08dsLpZAnuQXy3md" mode=""></image>
<view class="tslb" @click="btnts">
投诉列表
</view>
<!-- 投诉类型选择 -->
<view class="complaint-section">
<view class="section-title">
选择投诉类型 <text class="required"></text>
</view>
<view class="complaint-tags">
<view
class="tag-item"
:class="{ active: selectedType === item.name }"
v-for="item in complaintTypes"
:key="item.id"
@click="selectComplaintType(item.name)"
>
{{ item.name }}
<view class="check-icon" v-if="selectedType === item.name"></view>
</view>
</view>
</view>
<!-- 问题描述 -->
<view class="problem-section">
<view class="section-title">
问题描述 <text class="required"></text>
</view>
<view class="input-container">
<textarea
class="custom-textarea"
v-model="textValue"
placeholder="输入问题描述"
:maxlength="500"
@input="updateWordCount"
></textarea>
<text class="word-count">{{ currentCount }}/500</text>
</view>
<!-- 图片上传 -->
<view class="upload-section">
<view class="upload-grid">
<view
class="upload-item"
v-for="(item, index) in imglist"
:key="index"
>
<image :src="item" mode="aspectFill" class="uploaded-img"></image>
<view class="delete-btn" @click="deleteImage(index)">×</view>
</view>
<view
class="upload-btn"
v-if="imglist.length < 4"
@click="chooseImage"
>
<image class="sc" src="https://api.ccttiot.com/smartmeter/img/static/udgL6KzisrZlMrk9AZb2" mode=""></image>
</view>
</view>
<view class="upload-tip">最多上传4张,上传问题截图可以让问题快速解决哦!</view>
</view>
</view>
<!-- 订单选择 -->
<view class="order-section">
<view class="section-title">选择要投诉的订单</view>
<view class="order-selector" @click="selectOrder">
<view class="order-info-display" v-if="selectedOrder">
<text class="order-no-display">{{ getOrderNo(selectedOrder) }}</text>
<!-- <text class="order-amount-display">{{ getOrderAmount(selectedOrder) }}</text> -->
</view>
<text class="order-text" v-else>请选择订单</text>
<text class="arrow"></text>
</view>
</view>
<!-- 退款选择 -->
<view class="refund-section">
<view class="refund-row">
<view class="section-title">选择退款</view>
<view class="radio-group">
<view
class="radio-item"
:class="{ active: refundChoice === 'yes' }"
@click="refundChoice = 'yes'"
>
<view class="radio-circle">
<view class="radio-dot" v-if="refundChoice === 'yes'"></view>
</view>
<text></text>
</view>
<view
class="radio-item"
:class="{ active: refundChoice === 'no' }"
@click="refundChoice = 'no'"
>
<view class="radio-circle">
<view class="radio-dot" v-if="refundChoice === 'no'"></view>
</view>
<text></text>
</view>
</view>
</view>
<!-- 退款金额输入 -->
<view class="refund-row" v-if="refundChoice === 'yes'">
<view class="section-title">退款金额</view>
<view class="refund-input-container">
<input
type="text"
v-model="refundAmount"
placeholder="请输入数值"
class="refund-input"
/>
<text class="currency-unit"></text>
</view>
</view>
</view>
<!-- 联系方式 -->
<view class="contact-section">
<view class="section-title">联系方式</view>
<input
type="text"
v-model="contact"
placeholder="请输入手机号以便我们回复您"
class="contact-input"
/>
</view>
<!-- 提交按钮 -->
<view class="submit-btn" @click="sub()">确定提交</view>
<!-- 订单选择弹窗 -->
<view class="order-modal" v-if="showOrderModal" @click="closeOrderModal">
<view class="modal-content" @click.stop>
<view class="modal-header">
<text class="modal-title">选择订单</text>
<text class="close-btn" @click="closeOrderModal">×</text>
</view>
<view class="order-list" @scroll="onOrderListScroll">
<view
class="order-item"
:class="{ selected: tempSelectedOrder && tempSelectedOrder.billId === order.billId }"
v-for="order in orderList"
:key="order.billId"
@click="selectOrderItem(order)"
>
<view class="order-info">
<text class="order-no">订单号{{ getOrderNo(order) }}</text>
<!-- <text class="order-amount">金额{{ getOrderAmount(order) }}</text> -->
<text class="order-time">{{ order.createTime }}</text>
</view>
<!-- <view class="order-status" :class="order.statusClass">
{{ order.statusText }}
</view> -->
</view>
<!-- 加载更多提示 -->
<view class="load-more" v-if="orderList.length > 0">
<view v-if="loading" class="loading-text">
<text>加载中...</text>
</view>
<view v-else-if="!hasMore" class="no-more-text">
<text>没有更多订单了</text>
</view>
<view v-else class="load-more-btn" @click="loadMoreOrders">
<text>点击加载更多</text>
</view>
</view>
<!-- 空状态 -->
<view class="empty-state" v-if="orderList.length === 0 && !loading">
<text>暂无订单数据</text>
</view>
</view>
<view class="modal-footer">
<view class="cancel-btn" @click="closeOrderModal">取消</view>
<view class="confirm-btn" @click="confirmOrderSelection">确定</view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
bgc: {
backgroundColor: " ",
},
textValue: '',
currentCount: 0,
imglist: [],
contact: '',
selectedType: '', // 选中的投诉类型(单选,存储文字)
complaintTypes: [
{ id: 1, name: '订单金额不对' },
{ id: 2, name: '订单结束不了' },
{ id: 3, name: '订单异常结束' }
],
selectedOrder: null,
refundChoice: 'no', // yes 或 no
refundAmount: '', // 退款金额
orderobj: {},
showOrderModal: false, // 是否显示订单选择弹窗
orderList: [], // 订单列表
tempSelectedOrder: null, // 临时选中的订单
currentPage: 1, // 当前页码
pageSize: 10, // 每页显示数量
totalPages: 1, // 总页数
loading: false, // 是否正在加载
hasMore: true, // 是否还有更多数据
searchKeyword: '', // 搜索关键词
searchTimer: null ,// 搜索防抖定时器
token:'',
flag:true
}
},
onLoad(option) {
if (option.obj) {
console.log('传入的订单数据:', JSON.parse(option.obj));
this.selectedOrder = JSON.parse(option.obj)
}
this.getqiniuyun()
},
methods: {
// 获取订单号(兼容多种字段名)
getOrderNo(order) {
// 优先使用原始的 no 字段,如果没有再使用其他字段
return order.no || order.billNo || order.orderNo || order.orderNumber || order.id || '未知订单号'
},
// 获取订单金额(兼容多种字段名)
getOrderAmount(order) {
return order.amount || order.money || order.totalAmount || '0.00'
},
// 获取订单ID兼容多种字段名
getOrderId(order) {
return order.billId || order.id || order.orderId || this.orderobj.billId || ''
},
// 点击跳转到投诉列表
btnts(){
uni.navigateTo({
url:'/page_fenbao/tousu/yhlist'
})
},
// 获取七牛云上传token
getqiniuyun(){
this.$u.get("/common/qiniuToken").then((res) => {
if (res.code == 200) {
this.token = res.data
}
})
},
// 选择投诉类型(单选)
selectComplaintType(name) {
this.selectedType = name
},
// 更新字数统计
updateWordCount() {
this.currentCount = this.textValue.length
},
// 选择图片
chooseImage() {
let _this = this
let math = 'static/' + _this.$u.guid(20)
uni.chooseImage({
count: 4 - this.imglist.length,
sizeType: ['compressed'],
sourceType: ['album', 'camera'],
success(res) {
const tempFilePaths = res.tempFilePaths[0]
wx.uploadFile({
url: 'https://up-z2.qiniup.com',
name: 'file',
filePath: tempFilePaths,
formData: {
token: _this.token, //后端返回的token
key: 'smartmeter/img/' + math
},
success: function(res) {
console.log(res, 'resres');
let str = JSON.parse(res.data)
let tempFilePaths = 'https://api.ccttiot.com/' + str.key
_this.imglist.push(tempFilePaths)
console.log(_this.imglist);
}
})
}
})
},
// 删除图片
deleteImage(index) {
this.imglist.splice(index, 1)
},
// 选择订单
selectOrder() {
this.loadOrderList()
this.showOrderModal = true
},
// 加载订单列表
loadOrderList() {
this.loading = true
this.currentPage = 1
// 调用真实API获取订单列表
this.$u.get("/app/order/mineList?pageNum=1&pageSize=10&suitType=1&status=&isAsc=desc&orderByColumn=createTime", {
pageNum: this.currentPage,
pageSize: this.pageSize
}).then((res) => {
if (res.code == 200) {
// 调试API返回的原始数据
console.log('API返回数据:', res)
// 处理订单数据
this.orderList = this.formatOrderData(res.rows || [])
this.totalPages = Math.ceil((res.total || 0) / this.pageSize)
this.hasMore = this.currentPage < this.totalPages
// 调试信息
console.log('订单数据:', {
总订单数: res.total,
当前页: this.currentPage,
每页数量: this.pageSize,
总页数: this.totalPages,
是否有更多: this.hasMore,
当前订单数: this.orderList.length
})
} else {
uni.showToast({
title: res.msg || '获取订单失败',
icon: 'none'
})
}
this.loading = false
}).catch((err) => {
console.error('获取订单失败:', err)
uni.showToast({
title: '获取订单失败',
icon: 'none'
})
this.loading = false
})
},
// 加载更多订单
loadMoreOrders() {
if (this.loading || !this.hasMore) return
this.loading = true
this.currentPage++
// 调用真实API获取更多订单
this.$u.get("/app/order/mineList?pageNum=1&pageSize=10&suitType=1&status=&isAsc=desc&orderByColumn=createTime", {
pageNum: this.currentPage,
pageSize: this.pageSize
}).then((res) => {
if (res.code == 200) {
// 处理订单数据并追加到现有列表
const newOrders = this.formatOrderData(res.rows || [])
this.orderList = [...this.orderList, ...newOrders]
// 更新总页数(以防后端返回的数据有变化)
this.totalPages = Math.ceil((res.total || 0) / this.pageSize)
this.hasMore = this.currentPage < this.totalPages
// 调试信息
console.log('加载更多订单:', {
总订单数: res.total,
当前页: this.currentPage,
每页数量: this.pageSize,
总页数: this.totalPages,
是否有更多: this.hasMore,
新增订单数: newOrders.length,
总订单数: this.orderList.length
})
} else {
uni.showToast({
title: res.msg || '获取更多订单失败',
icon: 'none'
})
}
this.loading = false
}).catch((err) => {
console.error('获取更多订单失败:', err)
uni.showToast({
title: '获取更多订单失败',
icon: 'none'
})
this.loading = false
})
},
// 格式化订单数据
formatOrderData(orderList) {
return orderList.map((order, index) => {
const derived = this.computeStatus(order)
return {
billId: order.billId || order.id || (this.currentPage * this.pageSize + index),
billNo: order.billNo || order.orderNo || order.orderNumber || order.no || `订单${order.id || index + 1}`,
amount: order.amount || order.money || order.totalAmount || '0.00',
createTime: order.createTime || order.createDate || order.orderTime || new Date().toLocaleString('zh-CN'),
statusClass: derived.status,
statusText: derived.statusText,
// 保留原始字段,用于显示
no: order.no,
orderNo: order.orderNo,
orderNumber: order.orderNumber
}
})
},
// 根据后端状态与是否完成计算前端展示状态
computeStatus(order) {
const status = String(order.status ?? order.orderStatus ?? '')
const isFinished = !!(order.isFinished)
// 规则:
// 2 + !isFinished => 已支付
// 2 + isFinished => 已完成
// 1 => 未支付
// 3 => 已退款
// 4 => 已取消(用户)
// 5 => 已取消(系统)
// 6 => 支付中
// 7 => 退款中
if (status === '2') {
return isFinished ? { statusClass: 'completed', statusText: '已完成' } : { statusClass: 'paid', statusText: '已支付' }
}
const map = {
'1': { statusClass: 'unpaid', statusText: '未支付' },
'3': { statusClass: 'refunded', statusText: '已退款' },
'4': { statusClass: 'cancelled-user', statusText: '已取消(用户)' },
'5': { statusClass: 'cancelled-system', statusText: '已取消(系统)' },
'6': { statusClass: 'paying', statusText: '支付中' },
'7': { statusClass: 'refunding', statusText: '退款中' }
}
return map[status] || { statusClass: 'processing', statusText: '处理中' }
},
// 选择订单项
selectOrderItem(order) {
this.tempSelectedOrder = order
},
// 确认订单选择
confirmOrderSelection() {
if (this.tempSelectedOrder) {
this.selectedOrder = this.tempSelectedOrder
console.log(this.selectedOrder);
this.closeOrderModal()
uni.showToast({
title: '订单选择成功',
icon: 'success'
})
} else {
uni.showToast({
title: '请选择订单',
icon: 'none'
})
}
},
// 关闭订单选择弹窗
closeOrderModal() {
this.showOrderModal = false
this.tempSelectedOrder = null
// 重置分页状态
this.currentPage = 1
this.orderList = []
this.hasMore = true
this.loading = false
// 重置搜索状态
this.searchKeyword = ''
if (this.searchTimer) {
clearTimeout(this.searchTimer)
this.searchTimer = null
}
},
// 获取订单状态文本
getStatusText(status) {
const statusMap = {
'completed': '已完成',
'processing': '处理中',
'cancelled': '已取消'
}
return statusMap[status] || '未知状态'
},
// 订单列表滚动事件
onOrderListScroll(e) {
const { scrollTop, scrollHeight, clientHeight } = e.target
// 当滚动到底部时自动加载更多
if (scrollHeight - scrollTop - clientHeight < 50 && this.hasMore && !this.loading) {
this.loadMoreOrders()
}
},
// 搜索输入事件
onSearchInput() {
// 清除之前的定时器
if (this.searchTimer) {
clearTimeout(this.searchTimer)
}
// 设置防抖定时器
this.searchTimer = setTimeout(() => {
this.searchOrders()
}, 500)
},
// 搜索订单
searchOrders() {
if (!this.searchKeyword.trim()) {
// 如果搜索框为空,重新加载所有订单
this.loadOrderList()
return
}
this.loading = true
this.currentPage = 1
// 调用搜索API如果您的API支持搜索参数
// 如果API不支持搜索可以在前端过滤
this.$u.get("/app/order/mineList?pageNum=1&pageSize=10&suitType=1&status=&isAsc=desc&orderByColumn=createTime", {
pageNum: this.currentPage,
pageSize: this.pageSize,
keyword: this.searchKeyword.trim() // 如果API支持搜索参数
}).then((res) => {
if (res.code == 200) {
let orderList = this.formatOrderData(res.rows || [])
// 如果API不支持搜索参数在前端过滤
if (!res.rows || res.rows.length === 0) {
// 重新获取所有订单并在前端过滤
this.$u.get("/app/order/mineList?pageNum=1&pageSize=10&suitType=1&status=&isAsc=desc&orderByColumn=createTime", {
pageNum: 1,
pageSize: 100 // 获取更多数据进行搜索
}).then((allRes) => {
if (allRes.code == 200) {
const allOrders = this.formatOrderData(allRes.rows || [])
orderList = allOrders.filter(order =>
(order.billNo || order.orderNo || order.orderNumber || '').toLowerCase().includes(this.searchKeyword.toLowerCase())
)
this.orderList = orderList
this.hasMore = false // 搜索时不分页
}
this.loading = false
})
} else {
this.orderList = orderList
this.hasMore = orderList.length === this.pageSize
this.loading = false
}
} else {
uni.showToast({
title: res.msg || '搜索失败',
icon: 'none'
})
this.loading = false
}
}).catch((err) => {
console.error('搜索失败:', err)
uni.showToast({
title: '搜索失败',
icon: 'none'
})
this.loading = false
})
},
// 提交
sub() {
if (!this.selectedType || this.selectedType.trim() === '') {
uni.showToast({
title: '请选择投诉类型',
icon: 'none',
duration: 2000
})
return
}
if (!this.selectedOrder) {
uni.showToast({
title: '请选择要投诉的订单',
icon: 'none',
duration: 2000
})
return
}
if (this.textValue.trim() === '') {
uni.showToast({
title: '请输入问题描述',
icon: 'none',
duration: 2000
})
return
}
if (this.contact.trim() === '') {
uni.showToast({
title: '请输入联系方式',
icon: 'none',
duration: 2000
})
return
}
// 验证退款金额
if (this.refundChoice === 'yes' && (!this.refundAmount || this.refundAmount.trim() === '')) {
uni.showToast({
title: '请输入退款金额',
icon: 'none',
duration: 2000
})
return
}
if(this.flag == true){
this.flag = false
let img = this.imglist.join(',')
// 构建提交数据
let data = {
title: this.selectedType,
content: this.textValue,
contact: this.contact,
needRefund: this.refundChoice == 'yes' ? true : false,
needRefundAmount: this.refundChoice == 'yes' ? this.refundAmount : '',
picture: img,
orderId: this.getOrderId(this.selectedOrder)
}
// 提交请求
this.$u.post("/app/complaint/add", data).then((res) => {
if (res.code == 200) {
uni.showToast({
title: '提交成功',
icon: 'success',
duration: 2000
})
setTimeout(() => {
this.flag = true
uni.navigateBack()
}, 1500)
} else {
this.flag = true
uni.showToast({
title: res.msg,
icon: 'none',
duration: 2000
})
}
})
}
}
}
}
</script>
<style lang="scss">
.topbj {
width: 750rpx;
height: 484rpx;
position: fixed;
top: 0;
left: 0;
z-index: -1;
filter: hue-rotate(430deg);
}
.tslb{
width: 100%;
margin-top: 210rpx;
text-align: right;
color: #fff;
font-size: 32rpx;
}
page {
background: #F5F5F5;
}
.pages {
box-sizing: border-box;
padding: 0 24rpx;
padding-bottom: 300rpx;
box-sizing: border-box;
}
// 通用样式
.section-title {
font-weight: 600;
font-size: 32rpx;
color: #333;
line-height: 45rpx;
margin-bottom: 20rpx;
.required {
font-size: 32rpx;
color: red;
vertical-align: top;
margin-left: 8rpx;
}
}
// 投诉类型选择
.complaint-section {
background: #FFFFFF;
border-radius: 16rpx;
padding: 28rpx;
margin-bottom: 12rpx;
box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.05);
margin-top: 20rpx;
.complaint-tags {
display: flex;
flex-wrap: wrap;
gap: 12rpx;
.tag-item {
position: relative;
padding: 12rpx 20rpx;
border: 1rpx solid #E0E0E0;
border-radius: 8rpx;
font-size: 26rpx;
color: #666;
transition: all 0.2s;
background: #FAFAFA;
cursor: pointer;
&:hover {
border-color: #4C97E7;
background: #F8F8F8;
}
&.active {
border-color: #4C97E7;
color: #4C97E7;
background: #F0F8F0;
box-shadow: 0 2rpx 8rpx rgba(72, 137, 59, 0.2);
}
.check-icon {
position: absolute;
bottom: -1rpx;
right: -1rpx;
width: 24rpx;
height: 24rpx;
background: #4C97E7;
color: white;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 16rpx;
font-weight: bold;
}
}
}
}
// 问题描述
.problem-section {
background: #FFFFFF;
border-radius: 16rpx;
padding: 28rpx;
margin-bottom: 12rpx;
box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.05);
.input-container {
position: relative;
width: 100%;
height: 160rpx;
background: #FFFFFF;
border: 1rpx solid #E0E0E0;
border-radius: 12rpx;
overflow: hidden;
margin-bottom: 20rpx;
.custom-textarea {
width: 100%;
height: 100%;
padding: 16rpx;
box-sizing: border-box;
font-size: 26rpx;
line-height: 1.5;
color: #333;
}
.word-count {
position: absolute;
right: 16rpx;
bottom: 16rpx;
font-size: 22rpx;
color: #999;
}
}
.upload-section {
.upload-grid {
display: flex;
flex-wrap: wrap;
gap: 12rpx;
margin-bottom: 12rpx;
.sc{
width: 142rpx;
height: 142rpx;
}
.upload-item {
position: relative;
width: 144rpx;
height: 144rpx;
.uploaded-img {
width: 100%;
height: 100%;
border-radius: 8rpx;
}
.delete-btn {
position: absolute;
top: -6rpx;
right: -6rpx;
width: 28rpx;
height: 28rpx;
background: rgba(0,0,0,0.6);
color: white;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 18rpx;
font-weight: bold;
}
}
.upload-btn {
// width: 120rpx;
// height: 120rpx;
// border: 2rpx dashed #D0D0D0;
// border-radius: 8rpx;
// display: flex;
// align-items: center;
// justify-content: center;
// background: #FAFAFA;
.upload-icon {
font-size: 40rpx;
color: #999;
}
}
}
.upload-tip {
font-size: 22rpx;
color: #999;
line-height: 1.4;
}
}
}
// 订单选择
.order-section {
background: #FFFFFF;
border-radius: 16rpx;
padding: 28rpx;
margin-bottom: 12rpx;
box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.05);
.order-selector {
display: flex;
justify-content: space-between;
align-items: center;
padding: 16rpx 0;
border-bottom: 1rpx solid #F0F0F0;
.order-text {
font-size: 26rpx;
color: #333;
}
.order-info-display {
display: flex;
flex-direction: column;
gap: 4rpx;
.order-no-display {
font-size: 26rpx;
color: #333;
font-weight: 500;
}
.order-amount-display {
font-size: 24rpx;
color: #666;
}
}
.arrow {
font-size: 26rpx;
color: #999;
}
}
}
// 退款选择
.refund-section {
background: #FFFFFF;
border-radius: 16rpx;
padding: 28rpx;
margin-bottom: 12rpx;
box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.05);
.refund-row {
display: flex;
justify-content: space-between;
align-items: center;
padding: 16rpx 0;
border-bottom: 1rpx solid #F0F0F0;
&:last-child {
border-bottom: none;
}
.section-title {
margin-bottom: 0;
font-size: 28rpx;
color: #666;
}
}
.radio-group {
display: flex;
gap: 60rpx;
.radio-item {
display: flex;
align-items: center;
gap: 12rpx;
.radio-circle {
width: 32rpx;
height: 32rpx;
border: 2rpx solid #E0E0E0;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
background: #FFFFFF;
.radio-dot {
width: 18rpx;
height: 18rpx;
background: #4C97E7;
border-radius: 50%;
}
}
text {
font-size: 26rpx;
color: #333;
}
&.active .radio-circle {
border-color: #4C97E7;
}
}
}
.refund-input-container {
display: flex;
align-items: center;
gap: 8rpx;
.refund-input {
width: 200rpx;
height: 60rpx;
background: #FFFFFF;
border: 1rpx solid #E0E0E0;
border-radius: 8rpx;
padding: 0 16rpx;
box-sizing: border-box;
font-size: 26rpx;
color: #333;
text-align: center;
}
.currency-unit {
font-size: 26rpx;
color: #666;
}
}
}
// 联系方式
.contact-section {
background: #FFFFFF;
border-radius: 16rpx;
padding: 28rpx;
margin-bottom: 12rpx;
box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.05);
.contact-input {
width: 100%;
height: 68rpx;
background: #FFFFFF;
border: 1rpx solid #E0E0E0;
border-radius: 12rpx;
padding: 0 20rpx;
box-sizing: border-box;
font-size: 26rpx;
color: #333;
}
}
// 提交按钮
.submit-btn {
width: 600rpx;
height: 88rpx;
background: #4C97E7;
color: #fff;
font-size: 32rpx;
font-weight: 500;
line-height: 88rpx;
text-align: center;
border-radius: 44rpx;
position: fixed;
left: 50%;
transform: translateX(-50%);
bottom: 60rpx;
box-shadow: 0 4rpx 16rpx rgba(72, 137, 59, 0.3);
z-index: 999;
}
// 订单选择弹窗
.order-modal {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
z-index: 1000;
display: flex;
align-items: center;
justify-content: center;
.modal-content {
width: 90%;
max-height: 80%;
background: #FFFFFF;
border-radius: 16rpx;
overflow: hidden;
.modal-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 32rpx;
border-bottom: 1rpx solid #F0F0F0;
.modal-title {
font-size: 32rpx;
font-weight: 600;
color: #333;
}
.close-btn {
font-size: 40rpx;
color: #999;
width: 60rpx;
height: 60rpx;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
background: #F5F5F5;
}
}
.search-section {
padding: 24rpx 32rpx;
border-bottom: 1rpx solid #F0F0F0;
.search-input-container {
position: relative;
.search-input {
width: 100%;
height: 72rpx;
background: #F8F8F8;
border: 1rpx solid #E0E0E0;
border-radius: 36rpx;
padding: 0 60rpx 0 24rpx;
box-sizing: border-box;
font-size: 26rpx;
color: #333;
}
.search-icon {
position: absolute;
right: 24rpx;
top: 50%;
transform: translateY(-50%);
font-size: 28rpx;
color: #999;
}
}
}
.order-list {
max-height: 600rpx;
overflow-y: auto;
.load-more {
padding: 32rpx 0;
text-align: center;
.loading-text {
color: #999;
font-size: 26rpx;
}
.no-more-text {
color: #999;
font-size: 26rpx;
}
.load-more-btn {
display: inline-block;
padding: 16rpx 32rpx;
background: #F5F5F5;
color: #666;
border-radius: 20rpx;
font-size: 26rpx;
&:active {
background: #E0E0E0;
}
}
}
.empty-state {
padding: 80rpx 0;
text-align: center;
color: #999;
font-size: 28rpx;
}
.order-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 24rpx;
border-bottom: 1rpx solid #F0F0F0;
cursor: pointer;
transition: background-color 0.2s;
&:hover {
background: #F8F8F8;
}
&.selected {
background: #F0F8F0;
}
&:last-child {
border-bottom: none;
}
.order-info {
flex: 1;
display: flex;
flex-direction: column;
gap: 8rpx;
.order-no {
font-size: 28rpx;
color: #333;
font-weight: 500;
}
.order-amount {
font-size: 26rpx;
color: #666;
}
.order-time {
font-size: 24rpx;
color: #999;
}
}
.order-status {
padding: 8rpx 16rpx;
border-radius: 20rpx;
font-size: 24rpx;
&.completed {
background: #E8F5E8;
color: #4C97E7;
}
&.paid {
background: #E6F4FF;
color: #1E88E5;
}
&.unpaid {
background: #FFF3E0;
color: #FB8C00;
}
&.refunded {
background: #E3F2FD;
color: #1976D2;
}
&.cancelled-user {
background: #FCE4EC;
color: #C2185B;
}
&.cancelled-system {
background: #F3E5F5;
color: #7B1FA2;
}
&.paying {
background: #E0F2F1;
color: #00796B;
}
&.refunding {
background: #FFFDE7;
color: #FBC02D;
}
&.processing {
background: #FFF3E0;
color: #FF9800;
}
}
}
}
.modal-footer {
display: flex;
padding: 32rpx;
gap: 20rpx;
border-top: 1rpx solid #F0F0F0;
.cancel-btn, .confirm-btn {
flex: 1;
height: 80rpx;
display: flex;
align-items: center;
justify-content: center;
border-radius: 40rpx;
font-size: 28rpx;
font-weight: 500;
}
.cancel-btn {
background: #F5F5F5;
color: #666;
}
.confirm-btn {
background: #4C97E7;
color: #FFFFFF;
}
}
}
}
</style>