You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

631 lines
17 KiB

<script setup>
import { ref, computed, onMounted, watch, nextTick, onUnmounted } from "vue";
import { useDataStore } from '@/store/dataList.js'
import { addFeedbackAPI, getFeedbackAPI } from "../api/AIxiaocaishen"
import feedback from "../assets/img/Feedback/feedback.png";
import feedbackImg from "../assets/img/Feedback/feedbackImg.png";
import feedbackSuccess from "../assets/img/Feedback/feedbackSuccess.png";
import noFeedback from "../assets/img/Feedback/noFeedback.png";
import border from "../assets/img/Feedback/border.png";
import success from "../assets/img/Feedback/success.png";
import failure from "../assets/img/Feedback/failure.png";
import save from "../assets/img/Feedback/save.png";
import back from "../assets/img/Feedback/back.png";
import purpleDot from "../assets/img/Feedback/purpleDot.png";
import moment from 'moment';
const dataStore = useDataStore()
const feedbackContent = ref("");
const uploadUrl = import.meta.env.VITE_APP_IMG_API_BASE_URL;
const feedbackFileList = ref([]);
const isHistoryFeedback = ref(false);
const submitSuccessDialogVisible = ref(false)
const submitFailureDialogVisible = ref(false)
const submitFailureContent = ref('')
const feedbackSubmit = async () => {
console.log(feedbackContent.value)
console.log(feedbackFileList.value)
if (feedbackContent.value == '' && feedbackFileList.value.length == 0) {
submitFailureDialogVisible.value = true;
submitFailureContent.value = '请输入反馈内容或上传图片';
} else {
try {
let img1 = ''
let img2 = ''
let img3 = '';
if (feedbackFileList.value[0]) {
img1 = feedbackFileList.value[0].url;
}
if (feedbackFileList.value[1]) {
img2 = feedbackFileList.value[1].url;
}
if (feedbackFileList.value[2]) {
img3 = feedbackFileList.value[2].url;
}
console.log(img1, img2, img3);
const result = await addFeedbackAPI({
token: localStorage.getItem('localToken'),
content: feedbackContent.value,
image1: img1,
image2: img2,
image3: img3,
})
console.log(result)
feedbackHistory();
submitSuccessDialogVisible.value = true;
} catch (error) {
submitFailureDialogVisible.value = true;
submitFailureContent.value = '反馈提交异常(错误代码:' + error.response.status + '),建议尝试更换网络环境后重新提交。';
}
}
}
const feedbackHistoryList = ref([])
const feedbackHistory = async () => {
try {
const result = await getFeedbackAPI({
token: localStorage.getItem('localToken'),
})
console.log(result)
if (result.data.length > 0) {
isHistoryFeedback.value = true;
feedbackHistoryList.value = result.data;
} else {
isHistoryFeedback.value = false;
}
} catch (error) {
console.log(error)
}
}
const submitSuccessConfirm = () => {
feedbackContent.value = '';
feedbackFileList.value = [];
if (localStorage.getItem('feedbackContent')) {
localStorage.removeItem('feedbackContent');
}
if (localStorage.getItem('feedbackFileList')) {
localStorage.removeItem('feedbackFileList');
}
submitSuccessDialogVisible.value = false;
}
const submitFailureConfirm = () => {
submitFailureDialogVisible.value = false;
}
// 字数限制提示弹窗
const feedbackContentOverLengthDialogVisible = ref(false)
const feedbackContentLengthJudge = () => {
console.log('字数判断');
console.log(feedbackContent.value.length)
if (feedbackContent.value.length >= 2000) {
feedbackContentOverLengthDialogVisible.value = true;
}
}
const feedbackContentOverLengthConfirm = () => {
feedbackContentOverLengthDialogVisible.value = false;
}
const feedbackContentChange = () => {
console.log('内容改变');
console.log(feedbackContent.value)
localStorage.setItem('feedbackContent', feedbackContent.value);
}
const check = function (file, fileList) {
console.log('调用check方法');
console.log(fileList);
console.log(fileList.length);
}
const successChange = function (file, fileList) {
console.log('调用successChange方法');
console.log(fileList);
console.log(fileList.response);
if (fileList.response.code == 200) {
feedbackFileList.value.push(fileList.response.data)
}
console.log(feedbackFileList.value);
localStorage.setItem('feedbackFileList', JSON.stringify(feedbackFileList.value));
}
const dialogImageUrl = ref('')
const dialogVisible = ref(false)
const handleRemove = (uploadFile, uploadFiles) => {
console.log(uploadFile, uploadFiles)
feedbackFileList.value = uploadFiles;
console.log('调用handleRemove方法');
console.log(feedbackFileList.value);
console.log(feedbackFileList.value.length);
localStorage.setItem('feedbackFileList', JSON.stringify(feedbackFileList.value));
}
const handlePictureCardPreview = (uploadFile) => {
dialogImageUrl.value = uploadFile.url
dialogVisible.value = true
}
// 返回弹窗
const feedbackBackDialogVisible = ref(false)
const feedbackBack = () => {
if(feedbackContent.value == '' && feedbackFileList.value.length == 0) {
dataStore.isFeedback = false;
return;
}
feedbackBackDialogVisible.value = true;
}
// 确人保存
const feedbackBackConfirm = () => {
feedbackBackDialogVisible.value = false;
dataStore.isFeedback = false;
}
// 取消保存
const feedbackBackCancel = () => {
if (localStorage.getItem('feedbackContent')) {
localStorage.removeItem('feedbackContent');
}
if (localStorage.getItem('feedbackFileList')) {
localStorage.removeItem('feedbackFileList');
}
feedbackBackDialogVisible.value = false;
dataStore.isFeedback = false;
}
onMounted(() => {
feedbackHistory()
if (localStorage.getItem('feedbackContent')) {
feedbackContent.value = localStorage.getItem('feedbackContent')
} else {
feedbackContent.value = '';
}
if (localStorage.getItem('feedbackFileList')) {
feedbackFileList.value = JSON.parse(localStorage.getItem('feedbackFileList'));
} else {
feedbackFileList.value = [];
}
console.log(uploadUrl)
})
</script>
<template>
<el-container>
<div>
<div @click="feedbackBack">
<img :src="back" alt="返回按钮" class="backImg">
</div>
</div>
<el-scrollbar>
<el-header>
<div class="feedbackImgClass">
<img :src="feedback" alt="用户反馈" class="img">
<img :src="feedbackImg" alt="用户反馈" class="img">
</div>
</el-header>
<el-main>
<div class="card">
<div class="feedbackTitle header-item">
填写反馈内容
</div>
<div class="header-item">
<el-input class="feedbackContent" v-model="feedbackContent" :rows="5" type="textarea"
maxlength="2000" show-word-limit placeholder="请描写您想反馈的内容..." @change="feedbackContentChange"
@input="feedbackContentLengthJudge" />
</div>
<div class="feedbackTitle header-item">
照片上传
</div>
<div class="header-item">
<el-upload class="uploadImg" :action="uploadUrl" list-type="picture-card" :auto-upload="true"
:on-success="successChange" accept=".png, .jpg, .jpeg, .ico," :on-change="check"
:file-list="feedbackFileList" :on-preview="handlePictureCardPreview"
:on-remove="handleRemove" :limit="3">
<el-icon>
<Plus />
</el-icon>
<template #tip>
<div class="el-upload__tip">
最多上传三张
</div>
</template>
</el-upload>
</div>
<div>
<div class="feedbackSubmitBtn" @click="feedbackSubmit"> </div>
</div>
</div>
<div class="card">
<div class="feedbackTitle">
历史反馈内容
</div>
<div v-if="isHistoryFeedback">
<div v-for="(item, index) in feedbackHistoryList" :key="index" class="feedbackHistory">
<div class="feedbackHistoryItem">
<div class="feedbackHistoryTitle">
<img :src="purpleDot" alt="紫点" class="purpleDot">
{{ moment(item.created_at).format('YYYY-MM-DD HH:mm') }}
<div class="feedbackSuccess">
<div class="feedbackSuccessWord">
反馈成功
</div>
<img class="feedbackSuccessImg" :src="feedbackSuccess" alt="成功">
</div>
</div>
<div class="feedbackHistoryContent">
{{ item.content }}
</div>
<div class="feedbackHistoryImg">
<el-image v-if="item.image1" :src="item.image1" alt="图片错误"
class="feedbackHistoryImgItem" :preview-src-list="[item.image1]" />
<el-image v-if="item.image2" :src="item.image2" alt="图片错误"
class="feedbackHistoryImgItem" :preview-src-list="[item.image2]" />
<el-image v-if="item.image3" :src="item.image3" alt="图片错误"
class="feedbackHistoryImgItem" :preview-src-list="[item.image3]" />
</div>
</div>
</div>
</div>
<div v-else>
<div class="noFeedback">
<img class="noFeedbackImg" :src="noFeedback" alt="暂无历史提交">
暂无记录
</div>
</div>
</div>
</el-main>
</el-scrollbar>
</el-container>
<el-dialog v-model="dialogVisible">
<img w-full :src="dialogImageUrl" alt="Preview Image" />
</el-dialog>
<el-dialog v-model="feedbackBackDialogVisible" class="save-dialog">
<div class="imgLine">
<img class="dialogImg" :src="save" alt="保存">
</div>
<div class="feedbackBackTitle">
系统提示
</div>
<div class="feedbackBackAttention">
检测到为保存内容,离开将丢失修改,请选择是否保留此次编辑?
</div>
<div class="feedbackBackBtnGroup">
<el-button class="feedbackBackBtn nosave" plain @click="feedbackBackCancel" type="primary">不保留</el-button>
<el-button class="feedbackBackBtn save" @click="feedbackBackConfirm" type="primary">保留</el-button>
</div>
</el-dialog>
<el-dialog v-model="feedbackContentOverLengthDialogVisible" class="save-dialog">
<div class="feedbackContentOverLengthTitle">
温馨提示
</div>
<div class="feedbackContentOverLengthContent">
当前输入字数已达上限!
</div>
<div class="feedbackBackBtnGroup">
<el-button class="feedbackContentOverLengthBtn confirm" type="primary"
@click="feedbackContentOverLengthConfirm">确认</el-button>
</div>
</el-dialog>
<el-dialog v-model="submitSuccessDialogVisible" class="save-dialog">
<div class="imgLine">
<img class="dialogImg" :src="success" alt="成功">
</div>
<div class="feedbackSuccessTitle">
提交成功
</div>
<div class="feedbackBackAttention">
——感谢您的反馈——
</div>
<div class="feedbackBackBtnGroup">
<el-button class="feedbackBackBtn confirm" @click="submitSuccessConfirm" type="primary">确定</el-button>
</div>
</el-dialog>
<el-dialog v-model="submitFailureDialogVisible" class="save-dialog">
<div class="imgLine">
<img class="dialogImg" :src="failure" alt="失败">
</div>
<div class="feedbackFailureTitle">
提交失败
</div>
<div class="feedbackBackAttention">
{{ submitFailureContent }}
</div>
<div class="feedbackBackBtnGroup">
<el-button class="feedbackBackBtn confirm" @click="submitFailureConfirm" type="primary">确定</el-button>
</div>
</el-dialog>
</template>
<style scoped>
.backImg{
width: 40px;
height: 40px;
margin-left: 10px;
}
.el-container {
display: flex;
flex-direction: column;
overflow: auto;
}
.el-header {
height: auto;
padding: 0;
}
.el-main {
height: auto;
padding: 0;
display: flex;
flex-direction: column;
gap: 20px;
overflow: hidden;
}
.card {
background-color: white;
padding: 20px;
height: auto;
border-radius: 15px;
}
.header-item {
margin: 10px 0;
}
.feedbackImgClass {
display: flex;
justify-content: space-between;
align-items: center;
margin: 0 20px;
}
.img {
max-width: 50%;
height: auto;
object-fit: contain;
}
.feedbackSubmitBtn {
width: 60%;
height: 50px;
text-align: center;
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto;
background: linear-gradient(90deg, #cac4fe, #b9d0fc, #a7dbfc);
border-radius: 60px;
color: #4423FF;
font-weight: bold;
font-size: 25px;
cursor: pointer;
}
.feedbackTitle {
font-size: 25px;
font-weight: bold;
}
.feedbackContent {
font-size: 20px;
}
@media (max-width: 768px) {
.feedbackTitle {
font-size: 20px;
}
.feedbackContent {
font-size: 15px;
}
}
.noFeedback {
margin: 20px 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.noFeedbackImg {
width: 200px;
height: 200px;
}
.feedbackBackTitle {
width: 100%;
text-align: center;
font-size: 25px;
font-weight: bold;
color: #2961FF
}
.feedbackBackAttention {
font-size: 15px;
font-weight: bold;
margin: 10px 5px;
text-align: center;
}
.feedbackBackBtnGroup {
display: flex;
align-items: center;
justify-content: center;
margin: 20px auto;
width: 75%;
}
.feedbackBackBtn {
margin: 0 auto;
font-weight: bold;
border-radius: 20px;
}
.save {
background: #816CF6;
border: none;
}
.nosave {
color: #816CF6;
background: white;
border: none;
}
.confirm {
background: #816CF6;
border: none;
}
.feedbackContentOverLengthTitle {
font-size: 25px;
font-weight: bold;
width: 100%;
text-align: center;
margin: 20px 0;
color: #2961FF;
}
.feedbackContentOverLengthContent {
font-size: 15px;
font-weight: bold;
width: 100%;
text-align: center;
margin: 20px 0;
}
.imgLine {
width: 100%;
display: flex;
}
.dialogImg {
max-width: 300px;
width: 50%;
height: 50%;
margin: 0 auto;
}
.feedbackSuccessTitle {
width: 100%;
text-align: center;
font-size: 25px;
font-weight: bold;
color: #2961FF
}
.feedbackFailureTitle {
width: 100%;
text-align: center;
font-size: 25px;
font-weight: bold;
color: #ff4646
}
.purpleDot {
margin: 0px 5px 0px 0px;
width: 20px;
height: 20px;
}
.feedbackHistoryTitle {
display: flex;
}
.feedbackSuccess {
margin-left: auto;
display: flex;
}
.feedbackSuccessWord {
padding: 3px 0 0 0;
color: #4221FF;
font-weight: bold;
}
.feedbackSuccessImg {
width: 30px;
height: auto;
margin: 0 5px;
}
.feedbackHistoryContent {
min-height: 50px;
margin: 0 0 0 25px;
font-weight: bold;
}
.feedbackHistoryImg {
display: flex;
margin: 0px 0px 0px 20px;
}
.feedbackHistoryImgItem {
width: 100px;
height: auto;
margin: 5px 10px;
}
</style>
<style>
.uploadImg .el-upload {
width: 150px;
height: 150px;
}
@media (max-width: 768px) {
.uploadImg .el-upload {
width: 100px;
height: 100px;
}
}
.feedbackContentOverLengthBtn {
margin: 0 auto;
color: white;
&:hover,
&:active,
&:focus {
color: white !important;
}
}
.save-dialog {
background: linear-gradient(90deg, #cac4fe, #b9d0fc, #a7dbfc);
border-radius: 20px;
}
</style>