添加逻辑并测试连接数据库
This commit is contained in:
451
pages/mall/delivery/feedback.uvue
Normal file
451
pages/mall/delivery/feedback.uvue
Normal file
@@ -0,0 +1,451 @@
|
||||
<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>
|
||||
Reference in New Issue
Block a user