451 lines
10 KiB
Plaintext
451 lines
10 KiB
Plaintext
<template>
|
||
<view class="feedback-container">
|
||
<!-- 顶部导航栏 -->
|
||
<view class="header-bar">
|
||
<view class="nav-left" @click="goBack">
|
||
<text class="nav-icon">←</text>
|
||
</view>
|
||
<text class="page-title">意见反馈</text>
|
||
<view class="nav-right"></view>
|
||
</view>
|
||
|
||
<!-- 表单区域 -->
|
||
<view class="form-wrapper">
|
||
<!-- 问题类型 -->
|
||
<view class="form-item">
|
||
<text class="label">问题类型</text>
|
||
<picker mode="selector" :range="feedbackTypes" @change="onTypeChange" :value="selectedTypeIndex">
|
||
<view class="picker-input">{{ feedbackTypes[selectedTypeIndex] }}</view>
|
||
</picker>
|
||
</view>
|
||
|
||
<!-- 标题 -->
|
||
<view class="form-item">
|
||
<text class="label">标题</text>
|
||
<input
|
||
type="text"
|
||
placeholder="请简要描述问题"
|
||
v-model="title"
|
||
class="input-field"
|
||
maxlength="50"
|
||
/>
|
||
</view>
|
||
|
||
<!-- 内容 -->
|
||
<view class="form-item">
|
||
<text class="label">详细内容</text>
|
||
<textarea
|
||
placeholder="请描述具体问题、发生时间、订单号等信息(至少10字)"
|
||
v-model="content"
|
||
class="textarea-field"
|
||
maxlength="500"
|
||
auto-height
|
||
/>
|
||
</view>
|
||
|
||
<!-- 上传截图(可选) -->
|
||
<view class="form-item">
|
||
<text class="label">上传截图(可选)</text>
|
||
<view class="upload-area" @click="chooseImage">
|
||
<text class="upload-icon">🖼️</text>
|
||
<text class="upload-text">点击上传截图</text>
|
||
<text class="upload-tip">支持 JPG/PNG,最多3张</text>
|
||
</view>
|
||
|
||
<!-- 已上传图片预览 -->
|
||
<view class="preview-list" v-if="previewImages.length > 0">
|
||
<view class="preview-item" v-for="(img, index) in previewImages" :key="index">
|
||
<image :src="img" class="preview-img" mode="aspectFill" />
|
||
<text class="remove-btn" @click="removeImage(index)">×</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 关联订单号(下拉选择) -->
|
||
<view class="form-item">
|
||
<text class="label">关联订单号(可选)</text>
|
||
<picker mode="selector" :range="orderOptions" @change="onOrderChange" :value="selectedOrderIndex">
|
||
<view class="picker-input">
|
||
{{ selectedOrderIndex === -1 ? '请选择订单' : orderOptions[selectedOrderIndex] }}
|
||
</view>
|
||
</picker>
|
||
</view>
|
||
|
||
<!-- 提交按钮 -->
|
||
<view class="submit-section">
|
||
<button
|
||
class="submit-btn"
|
||
:disabled="!isValid || isSubmitting"
|
||
@click="submitFeedback"
|
||
>
|
||
{{ isSubmitting ? '提交中...' : '提交反馈' }}
|
||
</button>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 底部提示 -->
|
||
<view class="footer-tip">
|
||
<text>您的反馈将被优先处理,我们将在24小时内回复</text>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script lang="uts">
|
||
export default {
|
||
data() {
|
||
return {
|
||
// 表单数据
|
||
title: '',
|
||
content: '',
|
||
selectedTypeIndex: 0,
|
||
selectedOrderIndex: -1, // -1 表示未选择
|
||
previewImages: [] as string[],
|
||
|
||
// 配置
|
||
feedbackTypes: [
|
||
'订单问题',
|
||
'配送异常',
|
||
'系统故障',
|
||
'账号/认证问题',
|
||
'车辆/设备问题',
|
||
'收入结算问题',
|
||
'其他'
|
||
],
|
||
|
||
// 模拟历史订单(实际项目中应从接口获取)
|
||
orders: [
|
||
{ id: 'ORD20250122001', status: '已完成', created_at: '2025-01-22 14:30' },
|
||
{ id: 'ORD20250122002', status: '配送中', created_at: '2025-01-22 13:15' },
|
||
{ id: 'ORD20250122003', status: '已取消', created_at: '2025-01-22 10:45' },
|
||
{ id: 'ORD20250122004', status: '待接单', created_at: '2025-01-22 09:20' }
|
||
],
|
||
|
||
isSubmitting: false
|
||
}
|
||
},
|
||
computed: {
|
||
// 订单选项:格式为 "ORDxxx - 状态 - 时间"
|
||
orderOptions() {
|
||
if (this.orders.length === 0) return ['无可用订单']
|
||
return this.orders.map(order =>
|
||
`${order.id} - ${order.status} - ${order.created_at.split(' ')[0]}`
|
||
)
|
||
},
|
||
|
||
isValid() {
|
||
return this.title.trim().length >= 2 &&
|
||
this.content.trim().length >= 10 &&
|
||
this.selectedTypeIndex >= 0
|
||
}
|
||
},
|
||
methods: {
|
||
goBack() {
|
||
uni.navigateBack()
|
||
},
|
||
|
||
onTypeChange(e: UniEvent<HTMLInputElement>) {
|
||
this.selectedTypeIndex = e.detail.value as number
|
||
},
|
||
|
||
onOrderChange(e: UniEvent<HTMLInputElement>) {
|
||
const index = e.detail.value as number
|
||
this.selectedOrderIndex = index
|
||
// 如果选择了有效订单,自动填充 orderId 字段(可选)
|
||
if (index >= 0 && index < this.orders.length) {
|
||
// 实际业务中可绑定 order.id 到某个字段,此处仅作示意
|
||
} else {
|
||
// 未选择时清空
|
||
}
|
||
},
|
||
|
||
chooseImage() {
|
||
if (this.previewImages.length >= 3) {
|
||
uni.showToast({
|
||
title: '最多上传3张图片',
|
||
icon: 'none'
|
||
})
|
||
return
|
||
}
|
||
|
||
uni.chooseImage({
|
||
count: 3 - this.previewImages.length,
|
||
sizeType: ['compressed'],
|
||
sourceType: ['album', 'camera'],
|
||
success: (res) => {
|
||
const tempFilePaths = res.tempFilePaths
|
||
const newImages = [...this.previewImages, ...tempFilePaths]
|
||
if (newImages.length > 3) {
|
||
this.previewImages = newImages.slice(0, 3)
|
||
} else {
|
||
this.previewImages = newImages
|
||
}
|
||
}
|
||
})
|
||
},
|
||
|
||
removeImage(index: number) {
|
||
this.previewImages.splice(index, 1)
|
||
},
|
||
|
||
submitFeedback() {
|
||
if (!this.isValid) {
|
||
let errorMsg = ''
|
||
if (this.title.trim().length < 2) {
|
||
errorMsg = '请填写标题(至少2字)'
|
||
} else if (this.content.trim().length < 10) {
|
||
errorMsg = '请填写详细内容(至少10字)'
|
||
} else if (this.selectedTypeIndex < 0) {
|
||
errorMsg = '请选择问题类型'
|
||
}
|
||
uni.showToast({
|
||
title: errorMsg,
|
||
icon: 'none'
|
||
})
|
||
return
|
||
}
|
||
|
||
if (this.isSubmitting) return
|
||
|
||
this.isSubmitting = true
|
||
|
||
// 模拟提交
|
||
uni.showLoading({ title: '提交中...' })
|
||
|
||
setTimeout(() => {
|
||
uni.hideLoading()
|
||
uni.showToast({
|
||
title: '反馈已提交成功!',
|
||
icon: 'success'
|
||
})
|
||
// 1.5秒后返回上一页
|
||
setTimeout(() => {
|
||
uni.navigateBack()
|
||
}, 1500)
|
||
}, 1000)
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style scoped>
|
||
.feedback-container {
|
||
background-color: #f8f9fa;
|
||
min-height: 100vh;
|
||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||
}
|
||
|
||
/* 顶部导航 */
|
||
.header-bar {
|
||
background-color: #fff;
|
||
padding: 20rpx 30rpx;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
border-bottom: 1rpx solid #e9ecef;
|
||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
|
||
}
|
||
|
||
.nav-left {
|
||
display: flex;
|
||
align-items: center;
|
||
cursor: pointer;
|
||
padding: 10rpx;
|
||
border-radius: 8rpx;
|
||
transition: background-color 0.2s ease;
|
||
}
|
||
|
||
.nav-left:hover {
|
||
background-color: #f0f0f0;
|
||
}
|
||
|
||
.nav-left:active {
|
||
background-color: #e0e0e0;
|
||
}
|
||
|
||
.nav-icon {
|
||
font-size: 36rpx;
|
||
color: #333;
|
||
}
|
||
|
||
.page-title {
|
||
font-size: 32rpx;
|
||
font-weight: bold;
|
||
color: #333;
|
||
text-align: center;
|
||
flex: 1;
|
||
}
|
||
|
||
.nav-right {
|
||
width: 60rpx;
|
||
height: 1rpx;
|
||
}
|
||
|
||
/* 表单区域 */
|
||
.form-wrapper {
|
||
padding: 30rpx;
|
||
background-color: #fff;
|
||
}
|
||
|
||
.form-item {
|
||
margin-bottom: 30rpx;
|
||
}
|
||
|
||
.label {
|
||
display: block;
|
||
font-size: 28rpx;
|
||
color: #333;
|
||
margin-bottom: 12rpx;
|
||
font-weight: 500;
|
||
}
|
||
|
||
/* 输入框统一样式 */
|
||
.input-field,
|
||
.textarea-field,
|
||
.picker-input {
|
||
width: 100%;
|
||
padding: 20rpx 24rpx;
|
||
border: 1rpx solid #e0e0e0;
|
||
border-radius: 12rpx;
|
||
font-size: 28rpx;
|
||
color: #333;
|
||
background-color: #fafafa;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
.textarea-field {
|
||
min-height: 180rpx;
|
||
height: auto;
|
||
padding: 24rpx;
|
||
line-height: 1.6;
|
||
}
|
||
|
||
.picker-input {
|
||
background-color: #fff;
|
||
text-align: right;
|
||
color: #666;
|
||
padding-right: 40rpx;
|
||
position: relative;
|
||
}
|
||
|
||
.picker-input::after {
|
||
content: '▼';
|
||
position: absolute;
|
||
right: 24rpx;
|
||
top: 50%;
|
||
transform: translateY(-50%);
|
||
font-size: 24rpx;
|
||
color: #999;
|
||
}
|
||
|
||
/* 上传区域 */
|
||
.upload-area {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
padding: 40rpx 20rpx;
|
||
border: 2rpx dashed #e0e0e0;
|
||
border-radius: 16rpx;
|
||
background-color: #f8f9fa;
|
||
cursor: pointer;
|
||
transition: all 0.3s;
|
||
}
|
||
|
||
.upload-area:hover {
|
||
border-color: #74b9ff;
|
||
background-color: #e8f4fd;
|
||
}
|
||
|
||
.upload-icon {
|
||
font-size: 60rpx;
|
||
color: #999;
|
||
margin-bottom: 16rpx;
|
||
}
|
||
|
||
.upload-text {
|
||
font-size: 28rpx;
|
||
color: #666;
|
||
margin-bottom: 10rpx;
|
||
}
|
||
|
||
.upload-tip {
|
||
font-size: 24rpx;
|
||
color: #999;
|
||
}
|
||
|
||
/* 图片预览 */
|
||
.preview-list {
|
||
display: flex;
|
||
gap: 20rpx;
|
||
margin-top: 20rpx;
|
||
flex-wrap: wrap;
|
||
}
|
||
|
||
.preview-item {
|
||
position: relative;
|
||
width: 120rpx;
|
||
height: 120rpx;
|
||
border-radius: 12rpx;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.preview-img {
|
||
width: 100%;
|
||
height: 100%;
|
||
}
|
||
|
||
.remove-btn {
|
||
position: absolute;
|
||
top: 8rpx;
|
||
right: 8rpx;
|
||
width: 32rpx;
|
||
height: 32rpx;
|
||
background-color: rgba(0, 0, 0, 0.7);
|
||
color: white;
|
||
font-size: 24rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
border-radius: 50%;
|
||
z-index: 1;
|
||
}
|
||
|
||
/* 提交按钮 */
|
||
.submit-section {
|
||
margin-top: 40rpx;
|
||
}
|
||
|
||
.submit-btn {
|
||
width: 100%;
|
||
height: 88rpx;
|
||
background: linear-gradient(135deg, #74b9ff 0%, #0984e3 100%);
|
||
color: white;
|
||
font-size: 32rpx;
|
||
font-weight: bold;
|
||
border-radius: 44rpx;
|
||
border: none;
|
||
box-shadow: 0 8rpx 20rpx rgba(116, 185, 255, 0.3);
|
||
transition: all 0.3s;
|
||
}
|
||
|
||
.submit-btn:disabled {
|
||
background: #cccccc; /* 禁用时灰色背景 */
|
||
color: #999;
|
||
cursor: not-allowed; /* 禁用时显示禁止光标 */
|
||
}
|
||
|
||
.submit-btn:active {
|
||
transform: scale(0.98);
|
||
box-shadow: 0 4rpx 12rpx rgba(116, 185, 255, 0.2);
|
||
}
|
||
|
||
/* 底部提示 */
|
||
.footer-tip {
|
||
text-align: center;
|
||
padding: 30rpx;
|
||
color: #999;
|
||
font-size: 24rpx;
|
||
background-color: #fff;
|
||
border-top: 1rpx solid #e9ecef;
|
||
}
|
||
</style> |