Files
tra-app/src/pages/examination/components/feedback.vue
T

233 lines
5.5 KiB
Vue

<template>
<uni-popup ref="feedbackPopupRef" class="popup" :mask-click="false">
<view class="feedback_popup_div" :style="{ marginBottom: feedback_popup_bottom }">
<view class="title_div">
<view class="text">反馈</view>
<view class="popup_back_div" @click="openFeedback(false)">
<image :src="optionErrorIcon('#000000')" class="img"></image>
</view>
</view>
<view class="feedback_item_div">
<view
class="feedback_item"
:class="{ feedback_item_clidked: feedbackInfo.type.includes(feedback_type_item.value) }"
@click="feedback_item_click(feedback_type_item.value)"
v-for="feedback_type_item in feedbackTypeList"
>
{{ feedback_type_item.label }}
</view>
</view>
<view class="feedback_text_area_div">
<uv-textarea
height="124"
count
:maxlength="100"
placeholder="补充详细问题"
:adjustPosition="false"
v-model="feedbackInfo.text"
></uv-textarea>
</view>
<view class="feedback_button">
<uv-button
class="button"
type="primary"
:throttleTime="100"
text="提交"
color="#0066FF"
custom-style="color:#FFFFFF;borderRadius:16rpx;height:92rpx;"
@click="submit_feedback_fun()"
></uv-button>
</view>
</view>
</uni-popup>
</template>
<script setup>
import { ref, reactive, onMounted, onUnmounted, nextTick } from 'vue';
import { optionErrorIcon } from '@/common/imgSvg';
import { saveTraQnsFeedback } from '@/api/examination.js';
import common from '@/common/common';
import { setupKeyboardHeightListener } from '@/common/common';
const feedback_popup_bottom = ref('0px'); // 反馈框下距离
const feedbackPopupRef = ref(null);
const feedbackTypeList = reactive([
{
value: '01',
label: '题干纠错'
},
{
value: '02',
label: '答案纠错'
},
{
value: '03',
label: '解析纠错'
}
]);
const feedbackInfo = reactive({
type: [], // 反馈类型
text: '', // 反馈内容
examId: '', // 考试ID
qnsId: '' // 试题IDID
});
// 选择反馈类型
const feedback_item_click = (value) => {
if (feedbackInfo.type.includes(value)) {
feedbackInfo.type = feedbackInfo.type.filter((item) => item !== value); // 如果已存在,则从数组中移除
} else {
feedbackInfo.type.push(value); // 如果不存在,则添加到数组中
}
};
// 反馈提交
const submit_feedback_fun = (value) => {
// 首先判断反馈类型是否
if (feedbackInfo.type.length === 0) {
return common.msg('请选择类型');
}
if (feedbackInfo.text.trim() === '') {
return common.msg('请补充详细问题');
}
common.loading('提交反馈信息');
const startTime = Date.now();
saveTraQnsFeedback({
qnsId: feedbackInfo.qnsId,
fbContent: feedbackInfo.text.trim(),
fbTyp: feedbackInfo.type.join(',')
})
.then(async (res) => {
// 计算接口已经消耗的时间
const elapsedTime = Date.now() - startTime;
// 计算需要补充的延迟时间(确保总耗时至少400ms)
const delayTime = Math.max(0, 500 - elapsedTime);
// 如果需要,补充延迟
if (delayTime > 0) {
await new Promise((resolve) => setTimeout(resolve, delayTime));
}
common.hideLoading();
await nextTick(() => {
reset()
feedbackPopupRef.value.close();
setTimeout(() => {
common.msg('反馈信息提交成功');
}, 100);
});
})
.catch(() => {
common.hideLoading();
});
};
const reset = () => {
feedbackInfo.type = [];
feedbackInfo.text = '';
feedbackInfo.qnsId = '';
feedbackInfo.examId = '';
}
const openFeedback = (status) => {
if (status) {
feedbackPopupRef.value.open('bottom');
} else {
reset()
feedbackPopupRef.value.close();
}
};
// 组件挂载时设置监听
let removeListener = () => {};
onMounted(() => {
removeListener = setupKeyboardHeightListener((height) => {
feedback_popup_bottom.value = `${height}px`;
});
// 组件卸载时移除监听
});
onUnmounted(() => {
removeListener();
});
const open = (qnsId) => {
feedbackInfo.qnsId = qnsId;
openFeedback(true);
};
defineExpose({
open
});
</script>
<style scoped lang="scss">
.feedback_popup_div {
width: 100%;
height: 100%;
background-color: #ffffff;
padding: 10rpx 34rpx;
display: flex;
flex-direction: column;
align-items: center;
border-radius: 16rpx 16rpx 0px 0px;
position: relative;
.title_div {
width: 100%;
text-align: center;
padding: 30rpx 0;
font-family: PingFangSC;
font-weight: 600;
font-size: 34rpx;
color: #000000;
text-align: center;
font-style: normal;
border-bottom: 2rpx solid #efefef;
}
.popup_back_div {
width: 60rpx;
height: 60rpx;
position: absolute;
top: 30rpx;
right: 30rpx;
display: flex;
align-items: center;
justify-content: center;
.img {
width: 30rpx;
height: 30rpx;
}
}
.feedback_item.feedback_item_clidked {
border: 2rpx solid #0066ff !important;
background-color: #fff !important;
}
.feedback_item_div {
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
margin: 30rpx 0;
.feedback_item {
border: 2rpx solid #f0f0f0;
background-color: #f0f0f0;
border-radius: 16rpx;
padding: 26rpx 36rpx;
font-family: PingFangSC;
font-weight: 500;
font-size: 30rpx;
color: #000000;
text-align: center;
}
}
.feedback_text_area_div {
width: 100%;
margin-bottom: 40rpx;
}
.feedback_button {
width: 100%;
margin-bottom: 20rpx;
}
}
</style>