339 lines
8.4 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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