|
|
<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); const token = localStorage.getItem("localToken"); if (feedbackContent.value == "" && feedbackFileList.value.length == 0) { submitFailureDialogVisible.value = true; submitFailureContent.value = "请输入反馈内容或上传图片"; } else if (!token) { submitFailureDialogVisible.value = true; submitFailureContent.value = "token已失效,请重新登录!"; } 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: token, 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>
|