优化问卷分析和空状态展示

- 改进EmptyContainer组件,添加自定义错误信息和图片支持
- 新增emptyImg.png资源用于空状态展示
- 优化问卷分析页面,添加无数据时的友好提示
- 修改Survey组件生命周期钩子,从onMounted改为onBeforeMount
- 重构问卷列表加载逻辑,优化用户体验
- 添加loading状态,提升交互体验
- 完善表格组件条件渲染逻辑,避免空数据渲染问题
- 优化代码结构和类型定义,提高代码可维护性
This commit is contained in:
Huangzhe
2025-05-21 18:20:00 +08:00
parent ecd4f3e8d8
commit 182b090bc8
6 changed files with 512 additions and 482 deletions

BIN
src/assets/img/emptyImg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@@ -7,13 +7,13 @@
@click="() => $router.push({ name: 'search' })" @click="() => $router.push({ name: 'search' })"
/> --> /> -->
</div> </div>
<div class="new-survey-container"> <div class="new-survey-container" v-loading="requestLoading">
<div style="margin-bottom: 80px"> <div style="margin-bottom: 80px">
<van-list <van-list
@load="handleLoadSurveys"
v-model:loading="loading" v-model:loading="loading"
:finished="finished" :finished="finished"
finished-text="没有更多了" finished-text="没有更多了"
@load="onLoad"
> >
<div v-for="item in survey" v-if="survey.length > 0" :key="item" class="new-survey_item"> <div v-for="item in survey" v-if="survey.length > 0" :key="item" class="new-survey_item">
<survey-item :survey="item" :is-analysis="true" :disable-action-button="false" /> <survey-item :survey="item" :is-analysis="true" :disable-action-button="false" />
@@ -26,38 +26,44 @@
</template> </template>
<script setup> <script setup>
import { onMounted } from 'vue'; import { onBeforeMount, ref } from 'vue';
import NavSearch from '@/components/Search/Index.vue'; import NavSearch from '@/components/Search/Index.vue';
import NewSurvey from '@/views/Home/components/NewSurvey/index.vue'; import NewSurvey from '@/views/Home/components/NewSurvey/index.vue';
import EmptyContainer from '@/views/Survey/components/EmptyContainer.vue'; import EmptyContainer from '@/views/Survey/components/EmptyContainer.vue';
import SurveyItem from '@/views/Survey/components/SurveyItem.vue'; import SurveyItem from '@/views/Survey/components/SurveyItem.vue';
import { import {
form,
fetchSurveys, fetchSurveys,
loading, loading,
finished, finished,
survey, survey,
requestLoading,
searchValue searchValue
} from '@/views/Survey/hooks/useSurveyData'; } from '@/views/Survey/hooks/useSurveyData';
// 初始化 From 内容
const form = ref({
page: 0,
pageSize: 10,
project_name: ''
});
const blurs = () => { const blurs = () => {
form.value.page = 1; form.value.page = 1;
form.value.project_name = searchValue.value; form.value.project_name = searchValue.value;
survey.value = []; survey.value = [];
fetchSurveys(); requestLoading.value = true;
fetchSurveys(form.value);
}; };
const onLoad = () => { onBeforeMount(() => {
// 异步更新数据 // 刚进入的时候
setTimeout(() => { handleLoadSurveys();
form.value.page = form.value.page + 1;
fetchSurveys();
}, 500);
};
onMounted(() => {
// fetchSurveys();
}); });
function handleLoadSurveys() {
form.value.page = form.value.page + 1;
fetchSurveys(form.value);
}
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">

View File

@@ -1,25 +1,42 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, useCssModule } from 'vue';
</script>
const errorMsg = defineModel<string>('errorMsg', { default: ' - 更多任务期待您的创建 - ' });
<template> const showButton = defineModel<boolean>('showButton', { default: false });
<el-empty> const imgSrc = defineModel<string>('imgSrc');
<template #image>
const emit = defineEmits(['handle-click']);
</template> const style = useCssModule();
<template #description> </script>
<el-text> - 更多任务期待您的创建 - </el-text>
</template> <template>
<el-button type="primary" class="btn" >+ 新建问卷</el-button> <el-empty>
</el-empty> <template #image v-if="imgSrc">
</template> <slot>
<!-- 如果放了图片默认展示图片位置 -->
<style scoped lang="scss"> <img :src="imgSrc" alt="" :class="style.img" />
.btn{ </slot>
color: #fff; </template>
background-color: var(--primary-color); <template #description>
border: solid 1px var(--primary-color); <el-text>{{ errorMsg }}</el-text>
font-weight: 400; </template>
border-radius: 8px; <el-button v-if="showButton" @click="emit('handle-click')" type="primary" class="btn">
} + 新建问卷
</style> </el-button>
</el-empty>
</template>
<style scoped lang="scss" module>
.img {
width: 35vw;
height: auto;
}
.btn {
color: #fff;
background-color: var(--primary-color);
border: solid 1px var(--primary-color);
font-weight: 400;
border-radius: 8px;
}
</style>

View File

@@ -1,348 +1,354 @@
<script setup lang="ts"> <script setup lang="ts">
import png11 from '@/assets/img/home/11.png'; import png11 from '@/assets/img/home/11.png';
import png13 from '@/assets/img/home/13.png'; import png13 from '@/assets/img/home/13.png';
import png14 from '@/assets/img/home/14.png'; import png14 from '@/assets/img/home/14.png';
import png15 from '@/assets/img/home/15.png'; import png15 from '@/assets/img/home/15.png';
import png16 from '@/assets/img/home/16.png'; import png16 from '@/assets/img/home/16.png';
import png17 from '@/assets/img/home/17.png'; import png17 from '@/assets/img/home/17.png';
import png18 from '@/assets/img/home/18.png'; import png18 from '@/assets/img/home/18.png';
import png31 from '@/assets/img/home/31.png'; import png31 from '@/assets/img/home/31.png';
import { showDialog, showFailToast, showSuccessToast } from 'vant'; import { showDialog, showFailToast, showSuccessToast } from 'vant';
import { finish } from '@/api/survey'; import { finish } from '@/api/survey';
import { copySurveys } from '@/api/home'; import { copySurveys } from '@/api/home';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import { import {
form, fetchSurveys,
fetchSurveys, deleteItem,
deleteItem, saveTemplate,
saveTemplate, currentSurvey
currentSurvey } from '@/views/Survey/hooks/useSurveyData';
} from '@/views/Survey/hooks/useSurveyData'; import ai from '@/assets/img/analysis/ai.svg';
import ai from '@/assets/img/analysis/ai.svg'; import { ref } from 'vue';
// router const form = ref({
const router = useRouter(); page: 0,
pageSize: 10,
const emit = defineEmits(['post-analysis', 'post-surveys']); project_name: ''
const survey = defineModel<SurveyItem>('survey', { required: true }); });
const isAnalysis = defineModel('isAnalysis', { default: false, type: Boolean });
// 禁用 action 功能 // router
const disableActionButton = defineModel('disableActionButton', { default: false, type: Boolean }); const router = useRouter();
const postAnalysis = defineModel<Function>('post-analysis'); const emit = defineEmits(['post-analysis', 'post-surveys']);
function setImg(code: number) { const survey = defineModel<SurveyItem>('survey', { required: true });
const imageMap: { [key: number]: string } = { const isAnalysis = defineModel('isAnalysis', { default: false, type: Boolean });
11: png11, // 禁用 action 功能
13: png13, const disableActionButton = defineModel('disableActionButton', { default: false, type: Boolean });
14: png14,
15: png15, const postAnalysis = defineModel<Function>('post-analysis');
16: png16, function setImg(code: number) {
17: png17, const imageMap: { [key: number]: string } = {
18: png18, 11: png11,
31: png31 13: png13,
}; 14: png14,
// 默认返回 png11 如果 code 不存在 15: png15,
return imageMap[code] || png11; 16: png16,
} 17: png17,
18: png18,
function editItem(item: SurveyItem) { 31: png31
router.push({ };
path: '/create', // 默认返回 png11 如果 code 不存在
query: { return imageMap[code] || png11;
sn: item.sn }
}
}); function editItem(item: SurveyItem) {
} router.push({
path: '/create',
function toPreview(item: SurveyItem) { query: {
router.push({ sn: item.sn
path: '/preview', }
query: { });
sn: item.sn, }
name: item.project_name,
source: 0 function toPreview(item: SurveyItem) {
} router.push({
}); path: '/preview',
} query: {
sn: item.sn,
/** name: item.project_name,
* 跳转 统计分析 页面 source: 0
* @param item }
*/ });
function toAnalysis(item: SurveyItem) { }
// 设置当前的节点信息
currentSurvey.value = item; /**
// 跳转 * 跳转 统计分析 页面
router.push({ * @param item
path: '/analysis', */
query: { function toAnalysis(item: SurveyItem) {
sn: item.sn // 设置当前的节点信息
} currentSurvey.value = item;
}); // 跳转
} router.push({
path: '/analysis',
function toPublish(item: SurveyItem) { query: {
if (item.status === 1) { sn: item.sn
showDialog({ }
title: `确定要取消投放${item.project_name}?`, });
showCancelButton: true }
})
.then(() => { function toPublish(item: SurveyItem) {
finish(item.sn).then((res) => { if (item.status === 1) {
if (res.data) { showDialog({
// 把数据改掉 title: `确定要取消投放${item.project_name}?`,
item.status = 2; showCancelButton: true
} })
}); .then(() => {
}) finish(item.sn).then((res) => {
.catch(() => { if (res.data) {
// on cancel // 把数据改掉
}); item.status = 2;
} else { }
router.push({ });
path: '/publish', })
query: { .catch(() => {
sn: item.sn // on cancel
} });
}); } else {
} router.push({
} path: '/publish',
query: {
function copyItem(item: SurveyItem) { sn: item.sn
showDialog({ }
title: `确认复制问卷${item.project_name} ?`, });
showCancelButton: true, }
confirmButtonColor: '#03B03C' }
})
.then(async () => { function copyItem(item: SurveyItem) {
const res = await copySurveys(item.sn); showDialog({
if (res.data.code === 200 || res.data.code === 201) { title: `确认复制问卷${item.project_name} ?`,
showSuccessToast('复制成功'); showCancelButton: true,
form.value.page = 1; confirmButtonColor: '#03B03C'
survey.value = []; })
await fetchSurveys(); .then(async () => {
} else { const res = await copySurveys(item.sn);
showFailToast(res.data); if (res.data.code === 200 || res.data.code === 201) {
} showSuccessToast('复制成功');
}) form.value.page = 1;
.catch(() => { survey.value = [];
// on cancel await fetchSurveys(form.value);
}); } else {
} showFailToast(res.data);
</script> }
})
<template> .catch(() => {
<section style="width: 100%"> // on cancel
<!-- 问卷详情 --> });
<div class="survey_item_info"> }
<div style="position: relative"> </script>
<div style="display: flex; justify-content: space-between; margin: 10px 0">
<div class="survey_item_info_title"> <template>
<el-text style="max-width: 100px"> <section style="width: 100%">
<b v-html="survey.project_name"></b> <!-- 问卷详情 -->
</el-text> <div class="survey_item_info">
<el-text class="wrap">{{ survey.answer_num }}</el-text> <div style="position: relative">
<el-text class="wrap" v-if="survey.is_time" style="text-wrap: nowrap"> <div style="display: flex; justify-content: space-between; margin: 10px 0">
{{ `${survey.start_time} ${survey.end_time ?? '无限期'}` }} <div class="survey_item_info_title">
</el-text> <el-text style="max-width: 100px">
</div> <b v-html="survey.project_name"></b>
</el-text>
<!-- AI 洞察图片 --> <el-text class="wrap">{{ survey.answer_num }}</el-text>
<img <el-text class="wrap" v-if="survey.is_time" style="text-wrap: nowrap">
v-if="!isAnalysis" {{ `${survey.start_time} ${survey.end_time ?? '无限期'}` }}
:src="ai" </el-text>
class="survey_item_info_title-survey" </div>
@click="emit('post-analysis')"
/> <!-- AI 洞察图片 -->
</div> <img
<div class="survey_item_info_status"> v-if="!isAnalysis"
<el-space spacer="|"> :src="ai"
<!--报名签到--> class="survey_item_info_title-survey"
<div class="flex align-center"> @click="emit('post-analysis')"
<img />
src="@/assets/img/publish/user.png" </div>
alt="Content Icon" <div class="survey_item_info_status">
style="width: 15px; height: 15px" <el-space spacer="|">
/> <!--报名签到-->
<el-text size="small">{{ survey.owner ?? '未知用户' }}</el-text> <div class="flex align-center">
</div> <img
<!-- 问卷来源 --> src="@/assets/img/publish/user.png"
<div class="flex align-center"> alt="Content Icon"
<img v-if="survey.source === 1" src="@/assets/img/publish/phone.png" alt="" /> style="width: 15px; height: 15px"
<img v-else src="@/assets/img/publish/pc.png" alt="" /> />
<el-text size="small"> <el-text size="small">{{ survey.owner ?? '未知用户' }}</el-text>
{{ survey.source === 1 ? '移动端' : 'PC端' }} </div>
</el-text> <!-- 问卷来源 -->
</div> <div class="flex align-center">
<!-- 问卷时间 --> <img v-if="survey.source === 1" src="@/assets/img/publish/phone.png" alt="" />
<div class="flex align-center"> <img v-else src="@/assets/img/publish/pc.png" alt="" />
<img src="@/assets/img/publish/time.png" alt="" /> <el-text size="small">
<el-text size="small"> 创建时间 {{ survey.created_at }}</el-text> {{ survey.source === 1 ? '移动端' : 'PC端' }}
</div> </el-text>
</el-space> </div>
</div> <!-- 问卷时间 -->
<div v-if="isAnalysis" class="survey_item_status"> <div class="flex align-center">
<img v-if="survey.status === 0" src="@/assets/img/publish/edit.png" alt="" /> <img src="@/assets/img/publish/time.png" alt="" />
<img v-else-if="survey.status === 1" src="@/assets/img/publish/publish.png" alt="" /> <el-text size="small"> 创建时间 {{ survey.created_at }}</el-text>
<img v-else-if="survey.status === 2" src="@/assets/img/publish/end.png" alt="" /> </div>
</div> </el-space>
</div> </div>
<!--问卷描述--> <div v-if="isAnalysis" class="survey_item_status">
<el-space class="survey_item_info_desc" spacer="|"> <img v-if="survey.status === 0" src="@/assets/img/publish/edit.png" alt="" />
<section> <img v-else-if="survey.status === 1" src="@/assets/img/publish/publish.png" alt="" />
<el-text size="small">回收数量</el-text> <img v-else-if="survey.status === 2" src="@/assets/img/publish/end.png" alt="" />
<el-text> {{ survey.answer_num }}</el-text> </div>
</section> </div>
<section> <!--问卷描述-->
<el-text size="small">回收数量进度</el-text> <el-space class="survey_item_info_desc" spacer="|">
<el-text>{{ survey.recycle_progress }}</el-text> <section>
</section> <el-text size="small">回收数量</el-text>
<section> <el-text> {{ survey.answer_num }}</el-text>
<el-text size="small">投放时间进度</el-text> </section>
<el-text> {{ survey.recycle_time }}</el-text> <section>
</section> <el-text size="small">回收数量进度</el-text>
</el-space> <el-text>{{ survey.recycle_progress }}</el-text>
</div> </section>
<!-- action 功能位置 --> <section>
<div v-if="!disableActionButton" class="survey_item_action"> <el-text size="small">投放时间进度</el-text>
<div> <el-text> {{ survey.recycle_time }}</el-text>
<el-button :disabled="survey.source === 0" @click="editItem(survey)"> 编辑 </el-button> </section>
<el-button style="border: 1px solid #71b73c" @click="toAnalysis(survey)"> </el-space>
<el-text style="color: #71b73c">统计</el-text> </div>
</el-button> <!-- action 功能位置 -->
<div v-if="!disableActionButton" class="survey_item_action">
<el-button color="#6fb937" @click="toPublish(survey)"> <div>
<el-text style="color: white"> <el-button :disabled="survey.source === 0" @click="editItem(survey)"> 编辑 </el-button>
{{ survey.status === 1 ? '结束投放' : '开启投放' }} <el-button style="border: 1px solid #71b73c" @click="toAnalysis(survey)">
</el-text> <el-text style="color: #71b73c">统计</el-text>
</el-button> </el-button>
</div>
<!-- 移除 PC 端不能操作 --> <el-button color="#6fb937" @click="toPublish(survey)">
<!-- v-if="survey.source === 1" --> <el-text style="color: white">
<el-dropdown placement="top-end" trigger="click" active-color="#71b73c"> {{ survey.status === 1 ? '结束投放' : '开启投放' }}
<van-icon class-prefix="mobilefont" name="gengduo" size="0.7rem"></van-icon> </el-text>
<template #dropdown> </el-button>
<el-dropdown-menu </div>
active-color="#71b73c" <!-- 移除 PC 端不能操作 -->
:close-on-click-overlay="false" <!-- v-if="survey.source === 1" -->
:close-on-click-outside="false" <el-dropdown placement="top-end" trigger="click" active-color="#71b73c">
> <van-icon class-prefix="mobilefont" name="gengduo" size="0.7rem"></van-icon>
<el-dropdown-item @click="toPreview(survey)"> 预览 </el-dropdown-item> <template #dropdown>
<el-dropdown-item @click="copyItem(survey)"> 复制 </el-dropdown-item> <el-dropdown-menu
<el-dropdown-item @click="deleteItem(survey)"> 删除 </el-dropdown-item> active-color="#71b73c"
<el-dropdown-item @click="saveTemplate(survey)"> 存为模板 </el-dropdown-item> :close-on-click-overlay="false"
</el-dropdown-menu> :close-on-click-outside="false"
</template> >
</el-dropdown> <el-dropdown-item @click="toPreview(survey)"> 预览 </el-dropdown-item>
</div> <el-dropdown-item @click="copyItem(survey)"> 复制 </el-dropdown-item>
</section> <el-dropdown-item @click="deleteItem(survey, form)"> 删除 </el-dropdown-item>
</template> <el-dropdown-item @click="saveTemplate(survey)"> 存为模板 </el-dropdown-item>
</el-dropdown-menu>
<style scoped lang="scss"> </template>
@import '@/assets/css/base'; </el-dropdown>
@import '@/assets/css/main'; </div>
</section>
.survey_item_info { </template>
.survey_item_info_status {
display: flex; <style scoped lang="scss">
margin-bottom: 15px; @import '@/assets/css/base';
color: #666; @import '@/assets/css/main';
img { .survey_item_info {
height: 12px; .survey_item_info_status {
margin-right: 3px; display: flex;
} margin-bottom: 15px;
} color: #666;
.survey_item_status { img {
position: absolute; height: 12px;
top: -20px; margin-right: 3px;
right: -20px; }
} }
.survey_item_info_title { .survey_item_status {
display: flex; position: absolute;
top: -20px;
.el-text { right: -20px;
font-size: 15px; }
&:first-child { .survey_item_info_title {
display: inline-block; display: flex;
max-width: 200px;
overflow: hidden; .el-text {
text-overflow: ellipsis; font-size: 15px;
white-space: nowrap;
font-weight: 500; &:first-child {
font-size: 14px; display: inline-block;
color: #000; max-width: 200px;
} overflow: hidden;
} text-overflow: ellipsis;
white-space: nowrap;
.wrap { font-weight: 500;
margin-left: 5px; font-size: 14px;
padding: 1px 3px; color: #000;
border: 0.5px solid rgba(192, 192, 192, 0.35); }
border-radius: 6px; }
font-size: 12px;
text-wrap: nowrap; .wrap {
color: #333333; margin-left: 5px;
} padding: 1px 3px;
& > :nth-child(3) { border: 0.5px solid rgba(192, 192, 192, 0.35);
padding: 0 4px; border-radius: 6px;
border-radius: 6px; font-size: 12px;
font-size: 12px; text-wrap: nowrap;
color: #333333; color: #333333;
margin-left: 7px; }
border: 0.5px solid rgba(192, 192, 192, 0.35); & > :nth-child(3) {
} padding: 0 4px;
} border-radius: 6px;
font-size: 12px;
.survey_item_info_desc { color: #333333;
display: flex; margin-left: 7px;
flex-flow: row wrap; border: 0.5px solid rgba(192, 192, 192, 0.35);
align-items: center; }
justify-content: space-around; }
border-radius: 8px;
background-color: #f6f7f8; .survey_item_info_desc {
overflow: hidden; display: flex;
text-overflow: ellipsis; flex-flow: row wrap;
padding: 14px 30px; align-items: center;
box-sizing: border-box; justify-content: space-around;
color: #828282; border-radius: 8px;
//font-weight: 400; background-color: #f6f7f8;
font-size: 12px; overflow: hidden;
text-overflow: ellipsis;
section { padding: 14px 30px;
display: flex; box-sizing: border-box;
flex-flow: column nowrap; color: #828282;
align-items: center; //font-weight: 400;
justify-content: center; font-size: 12px;
& > :nth-last-child(-n + 1) { section {
font-size: 20px; display: flex;
font-weight: bold; flex-flow: column nowrap;
color: $theme-color; align-items: center;
} justify-content: center;
}
} & > :nth-last-child(-n + 1) {
} font-size: 20px;
font-weight: bold;
.survey_item_action { color: $theme-color;
display: flex; }
align-items: center; }
justify-content: space-between; }
padding: 5px; }
margin-top: 10px;
font-weight: 400; .survey_item_action {
display: flex;
.el-button { align-items: center;
width: 18vw; justify-content: space-between;
border-radius: 8px; padding: 5px;
} margin-top: 10px;
font-weight: 400;
.el-space {
display: flex; .el-button {
justify-content: space-evenly; width: 18vw;
} border-radius: 8px;
} }
</style>
.el-space {
display: flex;
justify-content: space-evenly;
}
}
</style>

View File

@@ -1,18 +1,13 @@
import { getSurveysPage, deleteSurveys, saveTemplates } from '@/api/home'; import { getSurveysPage, deleteSurveys, saveTemplates } from '@/api/home';
import { ref } from 'vue'; import { ref } from 'vue';
import { showDialog, showConfirmDialog, showFailToast, showToast } from 'vant'; import { showDialog, showConfirmDialog, showFailToast, showToast } from 'vant';
import { getSurveysDetail } from '@/api/design'; import { getSurveysDetail } from '@/api/design';
const form = ref({
page: 0,
pageSize: 10,
project_name: ''
});
const searchValue = ref(''); const searchValue = ref('');
const survey = ref<SurveyItem[]>([]); const survey = ref<SurveyItem[]>([]);
const total = ref(0); const total = ref(0);
const loading = ref(false); const loading = ref(false);
const requestLoading = ref(false);
const finished = ref(false); const finished = ref(false);
const currentSurvey = ref<SurveyItem>(); const currentSurvey = ref<SurveyItem>();
@@ -25,10 +20,11 @@ async function fetchSingleSurvey(sn: string) {
} }
} }
async function fetchSurveys() { async function fetchSurveys(form: any) {
requestLoading.value = true;
const params = { const params = {
page: form.value.page, page: form.page,
per_page: form.value.pageSize, per_page: form.pageSize,
group_id: 0, group_id: 0,
project_name: searchValue.value project_name: searchValue.value
}; };
@@ -57,9 +53,10 @@ async function fetchSurveys() {
} else { } else {
// Toast() // Toast()
} }
requestLoading.value = false;
} }
function deleteItem(item: SurveyItem) { function deleteItem(item: SurveyItem, form: any) {
showDialog({ showDialog({
title: `确认删除问卷 "${item.project_name}" ?`, title: `确认删除问卷 "${item.project_name}" ?`,
showCancelButton: true, showCancelButton: true,
@@ -72,9 +69,9 @@ function deleteItem(item: SurveyItem) {
} else { } else {
showToast('删除成功!'); showToast('删除成功!');
} }
form.value.page = 1; form.page = 1;
survey.value = []; survey.value = [];
await fetchSurveys(); await fetchSurveys(form);
}) })
.catch(() => { .catch(() => {
// on cancel // on cancel
@@ -96,7 +93,6 @@ async function saveTemplate(item: SurveyItem) {
} }
export { export {
form,
fetchSurveys, fetchSurveys,
loading, loading,
finished, finished,
@@ -106,5 +102,6 @@ export {
deleteItem, deleteItem,
saveTemplate, saveTemplate,
currentSurvey, currentSurvey,
requestLoading,
fetchSingleSurvey fetchSingleSurvey
}; };

View File

@@ -1,80 +1,84 @@
<template> <template>
<div style="width: 100%"> <div style="width: 100%">
<!-- 优先去上级传递的数值 --> <!-- 优先去上级传递的数值 -->
<section v-for="analysis in questionAnalysis" :key="analysis.stem" class="mt10"> <section v-for="analysis in questionAnalysis" :key="analysis.stem" class="mt10">
<!-- {{ analysis }} --> <!-- {{ analysis }} -->
<!-- 问题标题 --> <!-- 问题标题 -->
<el-tag type="success" size="small">{{ <el-tag type="success" size="small">{{
questionTypeMap.get(analysis.question_type as number) questionTypeMap.get(analysis.question_type as number)
}}</el-tag> }}</el-tag>
<el-text>{{ analysis.stem }}</el-text> <el-text>{{ analysis.stem }}</el-text>
<!-- 问题图表部分 --> <!-- 问题图表部分 -->
<chart-msg <chart-msg
v-if="showChart.includes(analysis.question_type)" v-if="showChart.includes(analysis.question_type)"
:dimension="analysis.option && analysis.option[0].option" :dimension="analysis.option && analysis.option[0].option"
:analysis="analysis" :analysis="analysis"
/> />
<!-- 问题表格部分 --> <!-- 问题表格部分 -->
<yl-table <yl-table
class="mt10" v-if="getTableData(analysis).length > 0"
:props="getTableHeadProps(analysis.head, analysis.option)" class="mt10"
:data="getTableData(analysis)" :props="getTableHeadProps(analysis.head, analysis.option)"
v-if="analysis.head" :data="getTableData(analysis)"
/> />
</section> <section v-else>
<!-- <section v-else> <empty-container :error-msg="'本题暂无有效答题数据'" :img-src="emptyImg" />
<empty-container /> </section>
</section> --> </section>
</div> <!-- <section v-else>
</template> <empty-container />
</section> -->
<script setup lang="ts"> </div>
// 空白容器 </template>
import EmptyContainer from '@/views/Survey/components/EmptyContainer.vue';
import { questionTypeMap } from '@/utils/question/typeMapping'; <script setup lang="ts">
import ChartMsg from '@/components/Analysis/Index.vue'; // 空白容器
import { getTableData } from './hooks/pieSeries'; import EmptyContainer from '@/views/Survey/components/EmptyContainer.vue';
import YlTable from '@/components/YlTable/Index.vue'; import { questionTypeMap } from '@/utils/question/typeMapping';
import { ref } from 'vue'; import ChartMsg from '@/components/Analysis/Index.vue';
import { screenLayout } from '@/hooks/browser/useScreen'; import { getTableData } from './hooks/pieSeries';
// questionTypeMap 自己去对应 import YlTable from '@/components/YlTable/Index.vue';
const showChart = ref([1, 2, 5, 106, 9, 10]); import { ref } from 'vue';
import { screenLayout } from '@/hooks/browser/useScreen';
// 接受上级传递的 questionAnalysis 数据 import emptyImg from '@/assets/img/emptyImg.png';
const questionAnalysis = defineModel<any[]>('questionAnalysis'); // questionTypeMap 自己去对应
const showChart = ref([1, 2, 5, 106, 9, 10]);
const { width } = screenLayout();
// 接受上级传递的 questionAnalysis 数据
// 构建表头 const questionAnalysis = defineModel<any[]>('questionAnalysis');
const getTableHeadProps = (values: any[], option: any[]): TablePropsType[] => {
const head = []; const { width } = screenLayout();
if (values && values.length > 0) { // 构建表头
values.forEach((item: any) => { const getTableHeadProps = (values: any[], option: any[]): TablePropsType[] => {
if (item.key !== 'option') { const head = [];
head.push({
label: item.title, if (values && values.length > 0) {
prop: item.key, values.forEach((item: any) => {
width: values.length < 3 ? width.value / values.length : 120 if (item.key !== 'option') {
}); head.push({
} label: item.title,
}); prop: item.key,
} width: values.length < 3 ? width.value / values.length : 120
});
if (option.length > 0 && option[0].option) { }
head.unshift({ });
label: '选项', }
prop: 'option',
width: 150 if (option.length > 0 && option[0].option) {
}); head.unshift({
} label: '选项',
return head; prop: 'option',
}; width: 150
</script> });
<style scoped lang="scss"> }
.mt10 { return head;
margin-top: 10px; };
} </script>
</style> <style scoped lang="scss">
.mt10 {
margin-top: 10px;
}
</style>