1277 lines
30 KiB
Vue
1277 lines
30 KiB
Vue
<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> |