添加逻辑并测试连接数据库

This commit is contained in:
not-like-juvenile
2026-01-28 19:13:13 +08:00
parent 1cca27096a
commit 76eb96ec0c
8 changed files with 1795 additions and 23 deletions

View 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>