zdtap-uniapp-main/pagesMy/feedback.vue

339 lines
8.4 KiB
Vue
Raw Normal View History

<template>
<view class="page">
<view class="page-content">
<!-- 反馈内容区域 -->
<view class="section">
<view class="section-title">反馈内容</view>
<view class="feedback-content">
<textarea
v-model="form.reviewContent"
maxlength="100"
placeholder="写下您的反馈内容或者建议,我们会尽快完善"
class="textarea-box"
></textarea>
<view class="word-count">{{form.reviewContent.length}}/100</view>
</view>
</view>
<!-- 图片上传区域 -->
<view class="section">
<view class="section-title">上传图片</view>
<view class="upload-content">
<view class="img-box" @click="handleUpload">
<image v-if="form.reviewImg" :src="form.reviewImg" mode="aspectFill" class="preview-image"></image>
<view v-else class="upload-placeholder">
<text class="cuIcon-camerafill"></text>
<text class="upload-text">添加图片</text>
</view>
</view>
<text class="upload-tip">请上传相关问题的截图选填</text>
</view>
</view>
<!-- 提交按钮 -->
<view class="save-btn" @click="submit">
提交反馈
</view>
</view>
</view>
</template>
<script>
import { base_url } from '@/api/config.js';
import { addFeedback } from '@/api/user.js';
import { getToken } from '@/utils/auth.js';
export default {
data() {
return {
form: {
reviewContent: '',
reviewImg: ''
}
};
},
methods: {
submit() {
if (!this.form.reviewContent) {
uni.showToast({
title: '请输入反馈内容',
icon: 'none'
});
return;
}
const data = {
content: this.form.reviewContent,
pics: this.form.reviewImg
};
addFeedback(data).then(res => {
uni.showToast({
title: '提交成功',
icon: 'success'
});
setTimeout(() => {
uni.switchTab({
url: '/pages/index/my'
});
}, 1000);
}).catch(err => {
uni.showToast({
title: '提交失败',
icon: 'none'
});
});
},
handleUpload() {
uni.getSetting({
success: (res) => {
if (!res.authSetting['scope.camera']) {
uni.authorize({
scope: 'scope.camera',
success: () => {
this.chooseAndUploadImage();
},
fail: () => {
uni.showToast({
title: '拒绝授权',
icon: 'none'
});
uni.showModal({
title: '是否重新授权拍照、相册的功能',
success(res) {
if (res.confirm) {
uni.openSetting({
success() {
console.log('开启权限成功');
},
fail() {
console.log('开启权限失败');
}
});
}
}
});
}
});
} else {
this.chooseAndUploadImage();
}
}
});
},
// 选择并上传图片
chooseAndUploadImage() {
uni.chooseImage({
count: 1,
success: (res) => {
uni.showLoading({
title: '上传中...',
mask: true
});
const token = getToken();
console.log('当前token:', token);
uni.uploadFile({
url: base_url + '/api/bar/common/upload',
filePath: res.tempFilePaths[0],
name: 'file',
header: {
'Authorization': token,
'Content-Type': 'multipart/form-data'
},
formData: {
type: 'image'
},
success: (uploadFileRes) => {
console.log('上传响应原始数据:', uploadFileRes);
try {
// 检查状态码
if (uploadFileRes.statusCode !== 200) {
throw new Error(`服务器响应错误: ${uploadFileRes.statusCode}`);
}
let result;
try {
result = JSON.parse(uploadFileRes.data);
} catch (parseError) {
console.error('解析响应数据失败,原始数据:', uploadFileRes.data);
throw new Error('服务器响应格式错误');
}
console.log('解析后的响应数据:', result);
if (result.code === 200) {
const imageUrl = result.data || result.url;
if (!imageUrl) {
throw new Error('未获取到图片地址');
}
this.form.reviewImg = imageUrl;
uni.showToast({
title: '上传成功',
icon: 'success'
});
} else {
throw new Error(result.msg || '上传失败');
}
} catch (error) {
console.error('处理上传响应错误:', error);
uni.showToast({
title: error.message || '上传失败',
icon: 'none'
});
}
},
fail: (err) => {
console.error('上传请求失败:', err);
uni.showToast({
title: '上传失败',
icon: 'none'
});
},
complete: () => {
uni.hideLoading();
}
});
}
});
}
}
};
</script>
<style lang="scss" scoped>
.page {
min-height: 100vh;
background: #F7F7F7;
.page-content {
padding: 24rpx 32rpx;
}
.section {
background: #FFFFFF;
border-radius: 16rpx;
margin-bottom: 24rpx;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.04);
.section-title {
font-size: 32rpx;
font-weight: 600;
padding: 32rpx;
color: #333333;
position: relative;
&::after {
content: '';
position: absolute;
left: 32rpx;
bottom: 0;
width: 48rpx;
height: 4rpx;
background: #19367A;
border-radius: 2rpx;
}
}
}
.feedback-content {
padding: 32rpx;
position: relative;
.textarea-box {
width: 100%;
height: 240rpx;
font-size: 28rpx;
color: #333333;
line-height: 1.6;
padding: 24rpx;
background: #F7F7F7;
border-radius: 12rpx;
box-sizing: border-box;
&::placeholder {
color: #999999;
}
}
.word-count {
position: absolute;
right: 48rpx;
bottom: 48rpx;
font-size: 24rpx;
color: #999999;
}
}
.upload-content {
padding: 32rpx;
.img-box {
width: 200rpx;
height: 200rpx;
background: #F7F7F7;
border-radius: 12rpx;
overflow: hidden;
margin-bottom: 16rpx;
transition: all 0.3s ease;
&:active {
transform: scale(0.98);
}
.preview-image {
width: 100%;
height: 100%;
object-fit: cover;
}
.upload-placeholder {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
color: #19367A;
.cuIcon-camerafill {
font-size: 48rpx;
margin-bottom: 12rpx;
}
.upload-text {
font-size: 24rpx;
}
}
}
.upload-tip {
font-size: 24rpx;
color: #999999;
}
}
.save-btn {
width: 686rpx;
height: 88rpx;
background: linear-gradient(135deg, #19367A, #2C4C99);
border-radius: 44rpx;
color: #FFFFFF;
font-size: 32rpx;
font-weight: 600;
letter-spacing: 2rpx;
display: flex;
align-items: center;
justify-content: center;
margin: 48rpx auto;
box-shadow: 0 4rpx 16rpx rgba(25, 54, 122, 0.2);
transition: all 0.3s ease;
&:active {
transform: scale(0.98);
box-shadow: 0 2rpx 8rpx rgba(25, 54, 122, 0.1);
}
}
}
</style>