优化问卷分析与界面展示
- 修复了图表数据为空时的渲染问题,添加了数据验证逻辑 - 优化了Analysis组件中的图表展示,增加了条件渲染 - 新增useScreen钩子函数用于响应式布局 - 改进了SurveyItem组件的标题样式,从h1调整为h3 - 优化了表格组件的宽度计算逻辑,提高了不同数据量下的展示效果 - 调整了多个组件的布局和样式,提升用户体验 - 清理了代码中的冗余注释和空白行,提高代码可读性
This commit is contained in:
@@ -36,7 +36,9 @@ const index = ref(0);
|
||||
// 当 keyword 变动的时候,标记脏数据
|
||||
watch(
|
||||
() => analysis.value,
|
||||
async () => {
|
||||
async (value) => {
|
||||
// 排除空数据渲染图标步骤
|
||||
|
||||
tableData.value = {
|
||||
...analysis.value,
|
||||
option: getTableData(analysis.value)
|
||||
@@ -46,6 +48,9 @@ watch(
|
||||
|
||||
series.value = formatData(dimension.value ? tableData.value : analysis.value, index.value);
|
||||
const pieChart = useTemplateRef<HTMLSpanElement>('pieChart');
|
||||
// console.log(`series value `, series.value);
|
||||
|
||||
if (!series.value?.data?.length) return;
|
||||
useSetPieChart(pieChart, series, { title: false, legend: false });
|
||||
},
|
||||
{ immediate: true }
|
||||
@@ -71,6 +76,7 @@ const changeChart = (i: number) => {
|
||||
|
||||
<!-- 图表部分 -->
|
||||
<div
|
||||
v-if="series?.data?.length"
|
||||
class="charts"
|
||||
:style="{
|
||||
display: 'flex',
|
||||
@@ -79,7 +85,13 @@ const changeChart = (i: number) => {
|
||||
margin: '16px 0'
|
||||
}"
|
||||
>
|
||||
<span ref="pieChart" style="width: 100%; height: v-bind(chartHeight + 'px')"></span>
|
||||
<span
|
||||
ref="pieChart"
|
||||
:style="{
|
||||
width: '100%',
|
||||
height: series?.data?.length ? chartHeight + 'px' : ''
|
||||
}"
|
||||
></span>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
@@ -8,7 +8,7 @@ const survey = defineModel<object>('survey', { required: true });
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<h1>{{ survey.project_name }}</h1>
|
||||
<h3>{{ survey.project_name }}</h3>
|
||||
<el-space spacer="|" direction="horizontal">
|
||||
<section class="flex items-center pt-1">
|
||||
<img :src="people" alt="" style="margin-right: 5px" />
|
||||
@@ -25,8 +25,8 @@ const survey = defineModel<object>('survey', { required: true });
|
||||
<style lang="scss" scoped module="item">
|
||||
@use '@/assets/css/theme';
|
||||
|
||||
h1 {
|
||||
margin: 17px 0 12px 0;
|
||||
h3 {
|
||||
margin: 10px 0 12px 0;
|
||||
font-weight: 800;
|
||||
line-height: 15px;
|
||||
text-align: left;
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
const template = defineModel('template', { required: true });
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<van-cell style="margin-bottom: 10px">
|
||||
<template #extra>
|
||||
@@ -18,6 +22,14 @@
|
||||
</van-cell>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const template = defineModel('template', { required: true });
|
||||
</script>
|
||||
<style lang="scss" scoped module="item">
|
||||
@use '@/assets/css/theme';
|
||||
|
||||
h3 {
|
||||
margin: 10px 0 12px 0;
|
||||
font-weight: 800;
|
||||
line-height: 15px;
|
||||
text-align: left;
|
||||
font-style: normal;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import { RowAlign, type ColumnStyle } from 'element-plus';
|
||||
import { type ColumnStyle } from 'element-plus';
|
||||
|
||||
const data = defineModel<unknown[]>('data', { default: [] });
|
||||
const props = defineModel<TablePropsType[]>('props');
|
||||
|
||||
2
src/components/YlTable/types/table.d.ts
vendored
2
src/components/YlTable/types/table.d.ts
vendored
@@ -1,6 +1,6 @@
|
||||
type TablePropsType = {
|
||||
prop: string;
|
||||
label: string;
|
||||
width?: string;
|
||||
width?: string | number;
|
||||
};
|
||||
|
||||
25
src/hooks/browser/useScreen.ts
Normal file
25
src/hooks/browser/useScreen.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { onMounted, onUnmounted, ref } from 'vue';
|
||||
|
||||
export function screenLayout() {
|
||||
// 当前视口的宽度
|
||||
const width = ref(window.innerWidth);
|
||||
// 当前视口的高度
|
||||
const height = ref(window.innerHeight);
|
||||
|
||||
const observer = new ResizeObserver((entries) => {
|
||||
entries.forEach((entry) => {
|
||||
const { width: _width, height: _height } = entry.contentRect;
|
||||
width.value = _width;
|
||||
height.value = _height;
|
||||
});
|
||||
});
|
||||
|
||||
// 当页面挂载的时候开始监听元素
|
||||
onMounted(() => observer.observe(document.body));
|
||||
// 当页面卸载的时候停止监听元素
|
||||
onUnmounted(() => observer.disconnect());
|
||||
return {
|
||||
width,
|
||||
height
|
||||
};
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
<script setup>
|
||||
import { fetchSurveys } from '@/hooks/request/useSurvey';
|
||||
import CreateSurvey from './components/CreateSurvey/Index.vue';
|
||||
import NewSurvey from './components/NewSurvey/index.vue';
|
||||
import { onMounted, ref } from 'vue';
|
||||
@@ -14,7 +15,8 @@ import MineTask from '@/views/Home/components/MineTask/Index.vue';
|
||||
import router from '@/router';
|
||||
|
||||
const contentShow = ref(false);
|
||||
|
||||
// 获取我的问卷数据
|
||||
const { surveys } = fetchSurveys();
|
||||
const keyword = ref('');
|
||||
onMounted(async () => {
|
||||
if (appBridge.isInReactNative()) {
|
||||
@@ -67,9 +69,8 @@ function handleSearchClick() {
|
||||
<!--底部新建问卷-->
|
||||
<NewSurvey />
|
||||
|
||||
<mine-task v-if="false" />
|
||||
<mine-task :surveys="surveys" v-if="surveys?.length > 0" />
|
||||
<home-recommend class="home_recommend" v-else />
|
||||
|
||||
<navigation />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -33,7 +33,7 @@ const props = ref<TablePropsType[]>([
|
||||
<template>
|
||||
<van-cell class="home_recommend">
|
||||
<template #extra>
|
||||
<div style="width: 88vw">
|
||||
<div style="width: 90vw">
|
||||
<yl-table :data="data?.surveyTrendDataVOS" :props="props" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,26 +1,39 @@
|
||||
<template>
|
||||
<el-card shadow="never" :body-style="{ padding: 0 }">
|
||||
<van-swipe :autoplay="5000" indicator-color="white">
|
||||
<van-swipe-item v-for="banner in banners">
|
||||
<el-image :src="banner.banner_address" fit="contain" @click="handleBannerClick(banner)" />
|
||||
</van-swipe-item>
|
||||
</van-swipe>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { banners } from '@/views/Home/components/ImageSlider/hooks/useSlider';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { bannerInfo } from '@/views/AD/hooks/useAD';
|
||||
|
||||
const router = useRouter();
|
||||
// const defineBanners = defineModel('banners');
|
||||
// 如果定义了 banner , 那么 banners 就不再初始化
|
||||
// defineBanners.value && updateBanners(defineBanners.value);
|
||||
const borderRadius = defineModel('borderRadius');
|
||||
|
||||
function handleBannerClick(banner: any) {
|
||||
const router = useRouter();
|
||||
// 把对应的信息给 AD 的 hooks
|
||||
bannerInfo.value = banner;
|
||||
router.push({ name: 'ad' });
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<van-swipe :autoplay="5000" indicator-color="white">
|
||||
<van-swipe-item v-for="banner in banners">
|
||||
<el-image
|
||||
class="img"
|
||||
:style="{ borderRadius: borderRadius + 'px' }"
|
||||
:src="banner.banner_address"
|
||||
fit="contain"
|
||||
@click="handleBannerClick(banner)"
|
||||
/>
|
||||
</van-swipe-item>
|
||||
</van-swipe>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@use '@/assets/css/theme' as *;
|
||||
|
||||
.img {
|
||||
border-radius: $card-radius;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
<script setup lang="ts">
|
||||
import { fetchSurveys } from '@/hooks/request/useSurvey';
|
||||
import QuestionList from './components/QuestionList.vue';
|
||||
import YlSwiper from '@/components/YlSwiper/Index.vue';
|
||||
|
||||
const { surveys } = fetchSurveys();
|
||||
const surveys = defineModel('surveys', { required: true });
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
@@ -1,13 +1,8 @@
|
||||
<script setup lang="ts">
|
||||
import YlSwiper from '@/components/YlSwiper/Index.vue';
|
||||
import { useFetchAnalysis } from '@/hooks/request/useSurvey';
|
||||
import { ref } from 'vue';
|
||||
import SurveyItem from '@/views/Survey/components/SurveyItem.vue';
|
||||
import LogicInfo from '@/views/Survey/views/Analysis/components/LogicInfo/Index.vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
import Wait from '@/views/Survey/views/Analysis/components/Wait/Index.vue';
|
||||
import AnalysisInfo from '@/views/Survey/views/Analysis/components/AnalysisInfo/Index.vue';
|
||||
import SearchBar from '@/components/Search/Index.vue';
|
||||
import { fetchSingleSurvey } from '@/hooks/request/useSurvey';
|
||||
|
||||
const survey = defineModel<SurveyItem>('survey');
|
||||
@@ -16,16 +11,6 @@ const { questionAnalysis } = useFetchAnalysis(survey.value?.sn as string);
|
||||
const { currentSurvey } = fetchSingleSurvey(survey.value?.sn as string);
|
||||
|
||||
const disableInsight = ref(true);
|
||||
const aiInsightsConfig = ref({
|
||||
visible: false,
|
||||
message: ''
|
||||
});
|
||||
|
||||
const postAnalysis = (sn: string) => {
|
||||
aiInsightsConfig.value.visible = true;
|
||||
};
|
||||
|
||||
const height = ref(`200px`);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -80,15 +65,6 @@ const height = ref(`200px`);
|
||||
.question-item-container {
|
||||
width: 90vw;
|
||||
|
||||
// display: flex;
|
||||
// justify-content: center;
|
||||
// flex-flow: column nowrap;
|
||||
// align-items: center;
|
||||
|
||||
.survey-item {
|
||||
width: 95%;
|
||||
}
|
||||
|
||||
.analysis-info {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,6 +93,9 @@ watch(keyword, async () => {
|
||||
// await handleSearch();
|
||||
// 重置状态
|
||||
loading.value = false
|
||||
|
||||
// 清空 banners
|
||||
banners.value = [];
|
||||
});
|
||||
|
||||
// 索引变动之后,立刻进行搜索 (没有进行防抖)
|
||||
|
||||
@@ -68,7 +68,6 @@ onUnmounted(() => {
|
||||
@use '@/assets/css/theme';
|
||||
|
||||
.title {
|
||||
overflow-wrap: break-word;
|
||||
color: rgba(0, 0, 0, 1);
|
||||
font-size: 14px;
|
||||
font-family: PingFangSC-Medium;
|
||||
@@ -76,7 +75,7 @@ onUnmounted(() => {
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
line-height: 20px;
|
||||
margin: 28px 297px 0 2px;
|
||||
margin: 28px 0 0 0;
|
||||
}
|
||||
|
||||
.search-container {
|
||||
@@ -88,7 +87,7 @@ onUnmounted(() => {
|
||||
}
|
||||
|
||||
.banner {
|
||||
padding: theme.$gap;
|
||||
padding: 0 theme.$gap;
|
||||
}
|
||||
|
||||
// 搜索结果外部布局
|
||||
|
||||
@@ -1,10 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
index,
|
||||
surveys as _surveys,
|
||||
lastIndex,
|
||||
keyword
|
||||
} from '@/views/HomeSearch/Hooks/useSurveySearch';
|
||||
import { index, surveys as _surveys, keyword } from '@/views/HomeSearch/Hooks/useSurveySearch';
|
||||
import SurveyItem from '@/components/SurveyItem/Index.vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { computed } from 'vue';
|
||||
@@ -53,5 +48,9 @@ const surveys = computed(() => {
|
||||
.list-item {
|
||||
margin-top: theme.$gap;
|
||||
}
|
||||
|
||||
.list-item:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -48,8 +48,7 @@ const { questionAnalysis } = useFetchAnalysis(sn.value);
|
||||
:survey="currentSurvey as SurveyItem"
|
||||
@post-analysis="postAnalysis(sn as string)"
|
||||
/>
|
||||
|
||||
<!-- 弹窗组件 -->
|
||||
<!-- 弹窗组件 -->
|
||||
<el-dialog
|
||||
:show-close="false"
|
||||
:close-on-click-modal="false"
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
v-if="analysis.head"
|
||||
/>
|
||||
</section>
|
||||
<!-- <section v-else>
|
||||
<!-- <section v-else>
|
||||
<empty-container />
|
||||
</section> -->
|
||||
</div>
|
||||
@@ -38,14 +38,17 @@ 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[]) => {
|
||||
const getTableHeadProps = (values: any[], option: any[]): TablePropsType[] => {
|
||||
const head = [];
|
||||
|
||||
if (values && values.length > 0) {
|
||||
@@ -54,12 +57,13 @@ const getTableHeadProps = (values: any[], option: any[]) => {
|
||||
head.push({
|
||||
label: item.title,
|
||||
prop: item.key,
|
||||
width: 120
|
||||
width: values.length < 3 ? width.value / values.length : 120
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
if (option && option.length > 0 && option[0].option) {
|
||||
|
||||
if (option.length > 0 && option[0].option) {
|
||||
head.unshift({
|
||||
label: '选项',
|
||||
prop: 'option',
|
||||
|
||||
Reference in New Issue
Block a user