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