feat(survey): 优化问卷列表和分析页面
- 更新了多个图片资源 - 优化了问卷分析页面的图表展示逻辑 - 调整了导航栏和重定向页面的样式 - 统一了空容器组件的样式 - 优化了问卷列表页面的布局
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 6.3 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 6.5 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 7.1 KiB After Width: | Height: | Size: 17 KiB |
@@ -6,29 +6,32 @@ import {
|
|||||||
getTableData,
|
getTableData,
|
||||||
setDimensionData
|
setDimensionData
|
||||||
} from '@/views/Survey/views/Analysis/components/AnalysisInfo/hooks/pieSeries';
|
} from '@/views/Survey/views/Analysis/components/AnalysisInfo/hooks/pieSeries';
|
||||||
|
import EmptyContainer from '@/views/Survey/components/EmptyContainer.vue';
|
||||||
|
|
||||||
// series 信息
|
|
||||||
const tableData = ref([]);
|
const tableData = ref([]);
|
||||||
const analysis = defineModel<any>('analysis');
|
const analysis = defineModel<any>('analysis');
|
||||||
|
|
||||||
// console.log('analysis', analysis.value);
|
// series 信息
|
||||||
|
|
||||||
const series = ref([]);
|
const series = ref([]);
|
||||||
const dimension = defineModel('dimension');
|
const dimension = defineModel('dimension');
|
||||||
// 图标高度
|
// 图标高度
|
||||||
const chartHeight = computed(() => {
|
const chartHeight = computed(() => {
|
||||||
// 需要增加的高度, 由于字多了他就会高度异常,所有要指定一个动态高度
|
// 需要增加的高度, 由于字多了他就会高度异常,所有要指定一个动态高度
|
||||||
let addHeight = 0;
|
let addHeight = 0;
|
||||||
const optionLength = analysis.value?.option?.length;
|
// const optionLength = analysis.value?.option?.length;
|
||||||
|
|
||||||
// 做一些额外的检测, 如果 option 下面的title 字段超过 8 个,就把 addHeight 增加
|
// 做一些额外的检测, 如果 option 下面的title 字段超过 8 个,就把 addHeight 增加
|
||||||
analysis.value?.option?.forEach((item: any) => {
|
analysis.value?.option?.forEach((item: any) => {
|
||||||
|
console.log(item);
|
||||||
|
|
||||||
if (item.title?.length > 8) {
|
if (item.title?.length > 8) {
|
||||||
addHeight += 9;
|
addHeight += 2;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
console.log(`addHeight`, addHeight);
|
||||||
// 每三个选项高度增加 20px, 默认 300px
|
// 每三个选项高度增加 20px, 默认 300px
|
||||||
return dimension.value ? 280 : 280 + (optionLength - 1) * addHeight;
|
return dimension.value ? 280 : 280 + addHeight;
|
||||||
});
|
});
|
||||||
|
|
||||||
const index = ref(0);
|
const index = ref(0);
|
||||||
@@ -37,18 +40,17 @@ const index = ref(0);
|
|||||||
watch(
|
watch(
|
||||||
() => analysis.value,
|
() => analysis.value,
|
||||||
async (value) => {
|
async (value) => {
|
||||||
// 排除空数据渲染图标步骤
|
|
||||||
|
|
||||||
tableData.value = {
|
tableData.value = {
|
||||||
...analysis.value,
|
...analysis.value,
|
||||||
option: getTableData(analysis.value)
|
option: getTableData(analysis.value)
|
||||||
};
|
};
|
||||||
|
|
||||||
// console.log(`图标的高度是`, chartHeight.value);
|
// console.log(`tableData.value`, tableData.value);
|
||||||
|
|
||||||
series.value = formatData(dimension.value ? tableData.value : analysis.value, index.value);
|
series.value = formatData(dimension.value ? tableData.value : analysis.value, index.value);
|
||||||
|
// console.log(`series value`, series.value);
|
||||||
|
|
||||||
const pieChart = useTemplateRef<HTMLSpanElement>('pieChart');
|
const pieChart = useTemplateRef<HTMLSpanElement>('pieChart');
|
||||||
// console.log(`series value `, series.value);
|
|
||||||
|
|
||||||
if (!series.value?.data?.length) return;
|
if (!series.value?.data?.length) return;
|
||||||
useSetPieChart(pieChart, series, { title: false, legend: false });
|
useSetPieChart(pieChart, series, { title: false, legend: false });
|
||||||
@@ -60,12 +62,42 @@ const changeChart = (i: number) => {
|
|||||||
index.value = i;
|
index.value = i;
|
||||||
|
|
||||||
series.value = formatData(tableData.value, index.value);
|
series.value = formatData(tableData.value, index.value);
|
||||||
|
// console.log(`series value. by changeChart`, series.value);
|
||||||
|
|
||||||
if (series.value.data.length <= 0) {
|
if (series.value.data.length <= 0) {
|
||||||
series.value.data = [{ value: 0, name: 0 }];
|
series.value.data = [{ value: 0, name: 0 }];
|
||||||
}
|
}
|
||||||
// const pieChart = useTemplateRef<HTMLSpanElement>('pieChart');
|
// const pieChart = useTemplateRef<HTMLSpanElement>('pieChart');
|
||||||
// useSetPieChart(pieChart, series, { title: false, legend: false });
|
// useSetPieChart(pieChart, series, { title: false, legend: false });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const chartVisible = computed(() => {
|
||||||
|
/**
|
||||||
|
* 针对特殊题型做处理,
|
||||||
|
* 首先就是矩阵的题目 question_type 为 8 9 10
|
||||||
|
*
|
||||||
|
* */
|
||||||
|
|
||||||
|
if (
|
||||||
|
analysis.value.question_type === 8 ||
|
||||||
|
analysis.value.question_type === 9 ||
|
||||||
|
analysis.value.question_type === 10
|
||||||
|
) {
|
||||||
|
// console.log(`series.value on matrix`, series.value?.data);
|
||||||
|
const data = series.value?.data as { name: any; value: any }[];
|
||||||
|
|
||||||
|
// 过滤后的 data 数据,
|
||||||
|
const filterData = data.filter((item) => item.value != 0 && item.name != 0);
|
||||||
|
return filterData.length;
|
||||||
|
// series.value?.data.forEach((item: any`1[]) => {
|
||||||
|
// if (item.value > 0) {
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
|
||||||
|
return series.value?.data?.length;
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -85,7 +117,7 @@ const changeChart = (i: number) => {
|
|||||||
|
|
||||||
<!-- 图表部分 -->
|
<!-- 图表部分 -->
|
||||||
<div
|
<div
|
||||||
v-if="series?.data?.length"
|
v-if="chartVisible"
|
||||||
class="charts"
|
class="charts"
|
||||||
:style="{
|
:style="{
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
@@ -98,10 +130,14 @@ const changeChart = (i: number) => {
|
|||||||
ref="pieChart"
|
ref="pieChart"
|
||||||
:style="{
|
:style="{
|
||||||
width: '100%',
|
width: '100%',
|
||||||
height: series?.data?.length ? chartHeight + 'px' : ''
|
height: chartVisible ? chartHeight + 'px' : ''
|
||||||
}"
|
}"
|
||||||
></span>
|
></span>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- 图标没有实例就开始展示空图标 -->
|
||||||
|
<div v-else>
|
||||||
|
<empty-container :error-msg="'本题暂无有效答题数据'" />
|
||||||
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -17,14 +17,14 @@ const navigation = ref([
|
|||||||
icon: 'home-o',
|
icon: 'home-o',
|
||||||
inactive: ''
|
inactive: ''
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
title: '伊调研',
|
// title: '伊调研',
|
||||||
// link: {
|
// // link: {
|
||||||
// name: 'home',
|
// // name: 'home',
|
||||||
// path: '/home'
|
// // path: '/home'
|
||||||
// },
|
// // },
|
||||||
icon: yl
|
// icon: yl
|
||||||
},
|
// },
|
||||||
{
|
{
|
||||||
title: '我的',
|
title: '我的',
|
||||||
link: {
|
link: {
|
||||||
@@ -66,7 +66,7 @@ watch(activeTab, (value) => {
|
|||||||
<template>
|
<template>
|
||||||
<van-tabbar v-model="activeTab" class="navigation">
|
<van-tabbar v-model="activeTab" class="navigation">
|
||||||
<template v-for="(item, index) in navigation" :key="item.title">
|
<template v-for="(item, index) in navigation" :key="item.title">
|
||||||
<span
|
<!-- <span
|
||||||
v-if="index === 1"
|
v-if="index === 1"
|
||||||
style="
|
style="
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -77,8 +77,8 @@ watch(activeTab, (value) => {
|
|||||||
>
|
>
|
||||||
<img :src="item.icon" alt="" style="width: 30px; height: 30px" />
|
<img :src="item.icon" alt="" style="width: 30px; height: 30px" />
|
||||||
{{ item.title }}
|
{{ item.title }}
|
||||||
</span>
|
</span> -->
|
||||||
<van-tabbar-item v-else :icon="item.icon" :name="item.title">
|
<van-tabbar-item :icon="item.icon" :name="item.title">
|
||||||
{{ item.title }}
|
{{ item.title }}
|
||||||
</van-tabbar-item>
|
</van-tabbar-item>
|
||||||
</template>
|
</template>
|
||||||
@@ -87,7 +87,7 @@ watch(activeTab, (value) => {
|
|||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.navigation {
|
.navigation {
|
||||||
padding: 3px 0;
|
padding: 10px 0;
|
||||||
// width: 100vw;
|
// width: 100vw;
|
||||||
// background-color: white;
|
// background-color: white;
|
||||||
// display: flex;
|
// display: flex;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<!-- title 标题和搜索栏 -->
|
<!-- title 标题和搜索栏 -->
|
||||||
<header class="header">
|
<header class="header">
|
||||||
<van-nav-bar
|
<van-nav-bar
|
||||||
:class="[$route.meta.pureBGC ? '' : 'navbar-header']"
|
:class="redirectHeaderStyle"
|
||||||
:title="$route.meta.title"
|
:title="$route.meta.title"
|
||||||
left-arrow
|
left-arrow
|
||||||
safe-area-inset-top
|
safe-area-inset-top
|
||||||
@@ -31,27 +31,40 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup lang="ts">
|
||||||
import { RiShareForwardBoxFill } from 'vue-icons-plus/ri';
|
import { RiShareForwardBoxFill } from 'vue-icons-plus/ri';
|
||||||
import { RouterView, useRoute } from 'vue-router';
|
import { RouterView, useRoute } from 'vue-router';
|
||||||
import appBridge from '@/assets/js/appBridge';
|
import appBridge from '@/assets/js/appBridge';
|
||||||
import { computed } from 'vue';
|
import { computed } from 'vue';
|
||||||
|
import type { CSSProperties } from 'vue';
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
// console.log(route.meta.pureBGC);
|
// console.log(route.meta.pureBGC);
|
||||||
|
/**
|
||||||
|
* 控制 body 的 style
|
||||||
|
*/
|
||||||
const redirectBodyStyle = computed(() => {
|
const redirectBodyStyle = computed(() => {
|
||||||
|
// 背景色控制
|
||||||
|
const bgc = route.meta.bgc as string;
|
||||||
|
// 是否纯色背景
|
||||||
const pureBGC = route.meta.pureBGC;
|
const pureBGC = route.meta.pureBGC;
|
||||||
const bgc = route.meta.bgc;
|
// style 样式
|
||||||
|
const style = {} as CSSProperties;
|
||||||
|
|
||||||
// 如果存在 bgc 优先选取 bgc, 如果没有则使用 pureBGC
|
if (bgc) style.background = bgc;
|
||||||
// pureBGC 为兼容处理
|
else if (pureBGC) style.background = '#fff';
|
||||||
|
|
||||||
if (bgc) return { background: bgc };
|
return style;
|
||||||
|
});
|
||||||
|
|
||||||
return {
|
/**
|
||||||
background: pureBGC ? '#fff' : ''
|
* 控制 header 的 style
|
||||||
};
|
*/
|
||||||
|
const redirectHeaderStyle = computed(() => {
|
||||||
|
const css = [];
|
||||||
|
if (route.meta.header?.bgc === 'green') css.push('green-header');
|
||||||
|
else css.push('navbar-header');
|
||||||
|
return css;
|
||||||
});
|
});
|
||||||
|
|
||||||
function goBack() {
|
function goBack() {
|
||||||
@@ -97,8 +110,13 @@ const handlePopState = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.green-header {
|
||||||
|
background-color: theme.$theme-color;
|
||||||
|
}
|
||||||
|
|
||||||
.redirect-body {
|
.redirect-body {
|
||||||
overflow: scroll;
|
overflow: scroll;
|
||||||
|
width: 100vw;
|
||||||
height: calc(100vh - var(--sticky-top-height) - 1px);
|
height: calc(100vh - var(--sticky-top-height) - 1px);
|
||||||
background: transparent;
|
background: transparent;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,7 +53,15 @@ const router = createRouter({
|
|||||||
{
|
{
|
||||||
path: '/create',
|
path: '/create',
|
||||||
name: 'create',
|
name: 'create',
|
||||||
meta: { title: '问卷编辑' },
|
meta: {
|
||||||
|
title: '问卷编辑',
|
||||||
|
pureBGC: true,
|
||||||
|
bgc: '#71b73c',
|
||||||
|
header: {
|
||||||
|
bgc: 'green',
|
||||||
|
pureBGC: false
|
||||||
|
}
|
||||||
|
},
|
||||||
component: () => import('../views/Survey/views/Create/Index.vue')
|
component: () => import('../views/Survey/views/Create/Index.vue')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,43 +1,45 @@
|
|||||||
<template>
|
<template>
|
||||||
<!-- survey container -->
|
<section>
|
||||||
<div class="survey-search">
|
<!-- survey container -->
|
||||||
<nav-search
|
<div class="survey-search">
|
||||||
v-model:value="searchValue"
|
<nav-search
|
||||||
@search="handleSearchClick"
|
v-model:value="searchValue"
|
||||||
@cancel="handleCancelClick"
|
@search="handleSearchClick"
|
||||||
/>
|
@cancel="handleCancelClick"
|
||||||
<!-- <nav-search
|
/>
|
||||||
|
<!-- <nav-search
|
||||||
placeholder="请输入关键词"
|
placeholder="请输入关键词"
|
||||||
v-model:value="searchValue"
|
v-model:value="searchValue"
|
||||||
@click="() => $router.push({ name: 'search' })"
|
@click="() => $router.push({ name: 'search' })"
|
||||||
/> -->
|
/> -->
|
||||||
</div>
|
|
||||||
<div v-loading="requestLoading" class="new-survey-container">
|
|
||||||
<div style="margin-bottom: 80px">
|
|
||||||
<van-list v-model:loading="loading" :finished="finished" @load="handleLoadSurveys">
|
|
||||||
<template #finished>
|
|
||||||
<!-- 如果存在搜索文字的话,显示没有更多了 -->
|
|
||||||
<span v-if="searchValue">
|
|
||||||
<el-text>无符合要求的结果</el-text>
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template v-if="survey.length > 0">
|
|
||||||
<div v-for="item in survey" :key="item" class="new-survey_item">
|
|
||||||
<survey-item :survey="item" :is-analysis="true" :disable-action-button="false" />
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<!-- 如果问卷等于0的话,显示空容器 -->
|
|
||||||
<empty-container
|
|
||||||
v-if="survey.length === 0 && !searchValue"
|
|
||||||
:img-src="emptyImg"
|
|
||||||
:show-button="true"
|
|
||||||
@handle-click="handleEmptyClick"
|
|
||||||
/>
|
|
||||||
<NewSurvey v-model:show="showModel" />
|
|
||||||
</van-list>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div v-loading="requestLoading" class="new-survey-container">
|
||||||
|
<div style="margin-bottom: 80px">
|
||||||
|
<van-list v-model:loading="loading" :finished="finished" @load="handleLoadSurveys">
|
||||||
|
<template #finished>
|
||||||
|
<!-- 如果存在搜索文字的话,显示没有更多了 -->
|
||||||
|
<span v-if="searchValue">
|
||||||
|
<el-text>无符合要求的结果</el-text>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template v-if="survey.length > 0">
|
||||||
|
<div v-for="item in survey" :key="item" class="new-survey_item">
|
||||||
|
<survey-item :survey="item" :is-analysis="true" :disable-action-button="false" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<!-- 如果问卷等于0的话,显示空容器 -->
|
||||||
|
<empty-container
|
||||||
|
v-if="survey.length === 0 && !searchValue"
|
||||||
|
:img-src="emptyImg"
|
||||||
|
:show-button="true"
|
||||||
|
@handle-click="handleEmptyClick"
|
||||||
|
/>
|
||||||
|
<NewSurvey v-model:show="showModel" />
|
||||||
|
</van-list>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useCssModule } from 'vue';
|
import { useCssModule } from 'vue';
|
||||||
|
import emptyImg from '@/assets/img/emptyImg.png';
|
||||||
|
|
||||||
const errorMsg = defineModel<string>('errorMsg', { default: ' - 更多任务期待您的创建 - ' });
|
const errorMsg = defineModel<string>('errorMsg', { default: ' - 更多任务期待您的创建 - ' });
|
||||||
const showButton = defineModel<boolean>('showButton', { default: false });
|
const showButton = defineModel<boolean>('showButton', { default: false });
|
||||||
const imgSrc = defineModel<string>('imgSrc');
|
const imgSrc = defineModel<string>('imgSrc', { default: emptyImg });
|
||||||
|
|
||||||
const emit = defineEmits(['handle-click']);
|
const emit = defineEmits(['handle-click']);
|
||||||
const style = useCssModule();
|
const style = useCssModule();
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ function setImg(code: number) {
|
|||||||
|
|
||||||
const isShortTitle = ref(false);
|
const isShortTitle = ref(false);
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
console.log(titleRef.value);
|
// console.log(titleRef.value);
|
||||||
if (titleRef.value) {
|
if (titleRef.value) {
|
||||||
const offsetWidth = titleRef.value.$el.offsetWidth;
|
const offsetWidth = titleRef.value.$el.offsetWidth;
|
||||||
isShortTitle.value = 130 <= offsetWidth;
|
isShortTitle.value = 130 <= offsetWidth;
|
||||||
@@ -302,6 +302,11 @@ function copyItem(item: SurveyItem) {
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
top: -25px;
|
top: -25px;
|
||||||
right: -25px;
|
right: -25px;
|
||||||
|
|
||||||
|
img {
|
||||||
|
transform: translate(50%, 50%);
|
||||||
|
width: 98px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.survey_item_info_title {
|
.survey_item_info_title {
|
||||||
|
|||||||