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

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

View File

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

View File

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

View File

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