feat: 优化问卷分析图表展示功能
- 修复饼图组件显示问题,取消注释使图表正常显示 - 优化数据处理逻辑,支持问题索引1和2的数据处理 - 移除不必要的响应式包装,直接使用JSON对象提高性能 - 清理未使用的导入和函数,如showToast、surveys等 - 添加对空选项数组的条件判断,避免渲染空数据 - 移除控制台日志输出,提高代码整洁度 - 更新IDE图标主题为material-icon-theme - 优化图表配置结构,简化代码
This commit is contained in:
154
.vscode/settings.json
vendored
154
.vscode/settings.json
vendored
@@ -1,77 +1,77 @@
|
|||||||
{
|
{
|
||||||
"explorer.confirmDelete": false,
|
"explorer.confirmDelete": false,
|
||||||
"editor.fontSize": 16,
|
"editor.fontSize": 16,
|
||||||
"workbench.editorAssociations": {
|
"workbench.editorAssociations": {
|
||||||
"*.ipynb": "jupyter.notebook.ipynb"
|
"*.ipynb": "jupyter.notebook.ipynb"
|
||||||
},
|
},
|
||||||
"window.zoomLevel": 1,
|
"window.zoomLevel": 1,
|
||||||
"workbench.iconTheme": "vscode-icons",
|
"workbench.iconTheme": "material-icon-theme",
|
||||||
"prettier.enable": true,
|
"prettier.enable": true,
|
||||||
"editor.formatOnSave": false,
|
"editor.formatOnSave": false,
|
||||||
"javascript.format.insertSpaceBeforeFunctionParenthesis": true,
|
"javascript.format.insertSpaceBeforeFunctionParenthesis": true,
|
||||||
"typescript.format.insertSpaceBeforeFunctionParenthesis": true,
|
"typescript.format.insertSpaceBeforeFunctionParenthesis": true,
|
||||||
"prettier.singleQuote": true,
|
"prettier.singleQuote": true,
|
||||||
"emmet.syntaxProfiles": {
|
"emmet.syntaxProfiles": {
|
||||||
"vue-html": "html",
|
"vue-html": "html",
|
||||||
"vue": "html"
|
"vue": "html"
|
||||||
},
|
},
|
||||||
"files.associations": {
|
"files.associations": {
|
||||||
"*.html": "html",
|
"*.html": "html",
|
||||||
"*.vue": "vue",
|
"*.vue": "vue",
|
||||||
"*.ejs": "html",
|
"*.ejs": "html",
|
||||||
"*.js": "javascript"
|
"*.js": "javascript"
|
||||||
},
|
},
|
||||||
"vsicons.dontShowNewVersionMessage": true,
|
"vsicons.dontShowNewVersionMessage": true,
|
||||||
"autoimport.showNotifications": true,
|
"autoimport.showNotifications": true,
|
||||||
"path-intellisense.mappings": {
|
"path-intellisense.mappings": {
|
||||||
"@": "${workspaceRoot}/src",
|
"@": "${workspaceRoot}/src",
|
||||||
"/": "${workspaceRoot}/"
|
"/": "${workspaceRoot}/"
|
||||||
},
|
},
|
||||||
"[html]": {
|
"[html]": {
|
||||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||||
"editor.formatOnSave": true
|
"editor.formatOnSave": true
|
||||||
},
|
},
|
||||||
"[vue]": {
|
"[vue]": {
|
||||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||||
"editor.formatOnSave": true
|
"editor.formatOnSave": true
|
||||||
},
|
},
|
||||||
"css.validate": false, //用来校验CSS文件中的语法错误和潜在的问题
|
"css.validate": false, //用来校验CSS文件中的语法错误和潜在的问题
|
||||||
"less.validate": false, //用来校验LESS文件中的语法错误和潜在的问题
|
"less.validate": false, //用来校验LESS文件中的语法错误和潜在的问题
|
||||||
"scss.validate": false, //用来校验SCSS文件中的语法错误和潜在的问题
|
"scss.validate": false, //用来校验SCSS文件中的语法错误和潜在的问题
|
||||||
"editor.codeActionsOnSave": {
|
"editor.codeActionsOnSave": {
|
||||||
// 用于在保存文件时自动执行代码操作
|
// 用于在保存文件时自动执行代码操作
|
||||||
"source.fixAll.eslint": "explicit", // 自动执行ESlint
|
"source.fixAll.eslint": "explicit", // 自动执行ESlint
|
||||||
"source.fixAll.stylelint": "explicit" // 自动执行stylelint
|
"source.fixAll.stylelint": "explicit" // 自动执行stylelint
|
||||||
},
|
},
|
||||||
"eslint.validate": [
|
"eslint.validate": [
|
||||||
"javascript",
|
"javascript",
|
||||||
"javascriptreact",
|
"javascriptreact",
|
||||||
"typescript",
|
"typescript",
|
||||||
"typescriptreact",
|
"typescriptreact",
|
||||||
"html",
|
"html",
|
||||||
"markdown",
|
"markdown",
|
||||||
"yaml",
|
"yaml",
|
||||||
"toml",
|
"toml",
|
||||||
"xml",
|
"xml",
|
||||||
"gql",
|
"gql",
|
||||||
"graphql",
|
"graphql",
|
||||||
"astro"
|
"astro"
|
||||||
],
|
],
|
||||||
"eslint.nodePath": "./node_modules/@yl/yili-fe-lint-config/node_modules", // 指定ESLint可执行文件路径
|
"eslint.nodePath": "./node_modules/@yl/yili-fe-lint-config/node_modules", // 指定ESLint可执行文件路径
|
||||||
"eslint.options": {
|
"eslint.options": {
|
||||||
// 用于配置
|
// 用于配置
|
||||||
"overrideConfigFile": "./node_modules/@yl/yili-fe-lint-config/eslintrc.vue3.js" //该选项指定了 ESLint 应使用的配置文件路径。此项设置会覆盖所有其他位置查找的 ESLint 配置文件。
|
"overrideConfigFile": "./node_modules/@yl/yili-fe-lint-config/eslintrc.vue3.js" //该选项指定了 ESLint 应使用的配置文件路径。此项设置会覆盖所有其他位置查找的 ESLint 配置文件。
|
||||||
},
|
},
|
||||||
"stylelint.configBasedir": "./node_modules/@yl/yili-fe-lint-config/", //该选项用于定义 Stylelint 配置文件所基于的基础目录。当您的配置文件中使用 extends、plugins 或其他引用时,这个基础目录将作为解析路径的起点
|
"stylelint.configBasedir": "./node_modules/@yl/yili-fe-lint-config/", //该选项用于定义 Stylelint 配置文件所基于的基础目录。当您的配置文件中使用 extends、plugins 或其他引用时,这个基础目录将作为解析路径的起点
|
||||||
"stylelint.configFile": "./node_modules/@yl/yili-fe-lint-config/stylelintrc.js", // 该选项指定了 stylelint 应使用的配置文件路径。此项设置会覆盖所有其他位置查找的 stylelint 配置文件
|
"stylelint.configFile": "./node_modules/@yl/yili-fe-lint-config/stylelintrc.js", // 该选项指定了 stylelint 应使用的配置文件路径。此项设置会覆盖所有其他位置查找的 stylelint 配置文件
|
||||||
"stylelint.customSyntax": "postcss-scss", // 配置stylelint使用的预处理器
|
"stylelint.customSyntax": "postcss-scss", // 配置stylelint使用的预处理器
|
||||||
"stylelint.stylelintPath": "./node_modules/@yl/yili-fe-lint-config/node_modules/stylelint", // 指定stylelint安装路径
|
"stylelint.stylelintPath": "./node_modules/@yl/yili-fe-lint-config/node_modules/stylelint", // 指定stylelint安装路径
|
||||||
"stylelint.validate": [
|
"stylelint.validate": [
|
||||||
"html",
|
"html",
|
||||||
"css",
|
"css",
|
||||||
"scss",
|
"scss",
|
||||||
"less",
|
"less",
|
||||||
"vue"
|
"vue"
|
||||||
],
|
],
|
||||||
"typescript.tsdk": "node_modules\\typescript\\lib"
|
"typescript.tsdk": "node_modules\\typescript\\lib"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,6 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, useTemplateRef } from 'vue';
|
import { ref, useTemplateRef } from 'vue';
|
||||||
import { showToast } from 'vant';
|
|
||||||
import { useSetPieChart } from '@/hooks/chart/usePieChart';
|
import { useSetPieChart } from '@/hooks/chart/usePieChart';
|
||||||
import { surveys } from '@/components/Analysis/hooks/useSurvey';
|
|
||||||
import { questionTypeMap } from '@/utils/question/typeMapping';
|
|
||||||
|
|
||||||
// series 信息
|
// series 信息
|
||||||
const series = defineModel<any>('series', { required: true });
|
const series = defineModel<any>('series', { required: true });
|
||||||
@@ -19,7 +16,7 @@ useSetPieChart(pieChart, series, { title: false, legend: false });
|
|||||||
<div
|
<div
|
||||||
style="display: flex; height: 300px; width: 300px; justify-content: center; margin: 16px 0"
|
style="display: flex; height: 300px; width: 300px; justify-content: center; margin: 16px 0"
|
||||||
>
|
>
|
||||||
<!-- <span ref="pieChart" style="width: 100%; height: 300px"></span> -->
|
<span ref="pieChart" style="width: 100%; height: 300px"></span>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
import { ref } from 'vue';
|
|
||||||
|
|
||||||
const option = {
|
const option = {
|
||||||
// title: {
|
// title: {
|
||||||
// text: 'Referer of a Website',
|
// text: 'Referer of a Website',
|
||||||
@@ -36,13 +34,4 @@ const option = {
|
|||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
export const pieOption = ref<Partial<typeof option>>(option);
|
export const pieOption = option;
|
||||||
|
|
||||||
// 删除左侧的预览图
|
|
||||||
export function deleteLegend() {
|
|
||||||
delete pieOption.value.legend;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function deleteTitle() {
|
|
||||||
delete pieOption.value.title;
|
|
||||||
}
|
|
||||||
@@ -1,60 +1,36 @@
|
|||||||
import { onMounted, ref, type ShallowRef, watch } from 'vue';
|
import { onMounted, ref, type ShallowRef, watch } from 'vue';
|
||||||
import type { ECOption } from '@/utils/echarts';
|
import type { ECOption } from '@/utils/echarts';
|
||||||
import { chart } from '@/utils/echarts';
|
import { chart } from '@/utils/echarts';
|
||||||
import { deleteLegend, deleteTitle } from './data/pie';
|
import { pieOption } from './data/pie';
|
||||||
|
|
||||||
type dataOption = Partial<ECOption['data']>;
|
type dataOption = Partial<ECOption['data']>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 饼图的 option
|
* 饼图的 option
|
||||||
*/
|
*/
|
||||||
// const option = ref(pieOption);
|
|
||||||
|
|
||||||
function useSetPieChart(
|
function useSetPieChart(
|
||||||
dom: Readonly<ShallowRef<HTMLSpanElement | null>>,
|
dom: Readonly<ShallowRef<HTMLSpanElement | null>>,
|
||||||
series: any,
|
series: any,
|
||||||
opts: optsType = {}
|
opts: optsType = {}
|
||||||
): void {
|
): void {
|
||||||
// 图表实例
|
// 图表实例
|
||||||
let pieChart: any;
|
let chartInstance: any;
|
||||||
|
|
||||||
// 检测边界范围 dom 和 data 是否存在
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
if (!dom.value) {
|
// 检测边界范围 dom 和 series 是否存在
|
||||||
console.error('饼图DOM元素不存在');
|
if (!dom.value && !series) return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 在 dom 挂载之后,显示饼图
|
// 在 dom 挂载之后,显示饼图
|
||||||
pieChart = chart.init(dom.value);
|
chartInstance = chart.init(dom.value);
|
||||||
|
pieOption.series = JSON.parse(JSON.stringify(series.value));
|
||||||
|
|
||||||
if (series.value) {
|
// 设置图表选项
|
||||||
// 创建完整的配置对象
|
chartInstance.setOption(pieOption, opts);
|
||||||
const fullOption = {
|
|
||||||
series: [
|
|
||||||
{
|
|
||||||
type: 'pie',
|
|
||||||
radius: '50%',
|
|
||||||
data: series.value.data || []
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
// 设置图表选项
|
|
||||||
pieChart.setOption(fullOption, opts);
|
|
||||||
|
|
||||||
// 强制重绘以确保显示
|
|
||||||
setTimeout(() => {
|
|
||||||
pieChart.resize();
|
|
||||||
}, 100);
|
|
||||||
} else {
|
|
||||||
console.error('饼图数据不存在');
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// 如果 data 变动,重新生成图表w
|
// 如果 data 变动,重新生成图表w
|
||||||
watch(series, (value) => {
|
watch(series, (value) => {
|
||||||
pieChart.value.setOption(value, opts);
|
chartInstance.setOption(value, opts);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
const map = new Map<number, string>();
|
const map = new Map<number, string>();
|
||||||
|
|
||||||
map.set(1, '单选题');
|
map.set(1, '单选题');
|
||||||
map.set(5, '数值打分题');
|
map.set(2, "多选题")
|
||||||
map.set(9, '矩阵单选');
|
map.set(3, "图片上传题")
|
||||||
|
map.set(5, '数值打分题');
|
||||||
export { map as questionTypeMap };
|
map.set(9, '矩阵单选');
|
||||||
|
|
||||||
|
export { map as questionTypeMap };
|
||||||
|
|||||||
@@ -1,105 +1,112 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import LastSurvey from './components/LastSurvey/Index.vue';
|
import LastSurvey from './components/LastSurvey/Index.vue';
|
||||||
import Market from './components/Market/Index.vue';
|
import Market from './components/Market/Index.vue';
|
||||||
import CreateSurvey from './components/CreateSurvey/Index.vue';
|
import CreateSurvey from './components/CreateSurvey/Index.vue';
|
||||||
import NewSurvey from './components/NewSurvey/index.vue';
|
import NewSurvey from './components/NewSurvey/index.vue';
|
||||||
import { onMounted, ref } from 'vue';
|
import { onMounted, ref } from 'vue';
|
||||||
import utils from '@/assets/js/common';
|
import utils from '@/assets/js/common';
|
||||||
import { getUserInfo } from '@/api/common/index.js';
|
import { getUserInfo } from '@/api/common/index.js';
|
||||||
import { showFailToast } from 'vant';
|
import { showFailToast } from 'vant';
|
||||||
import appBridge from '@/assets/js/appBridge';
|
import appBridge from '@/assets/js/appBridge';
|
||||||
import ImageSlider from './components/ImageSlider/Index.vue';
|
import ImageSlider from './components/ImageSlider/Index.vue';
|
||||||
import MineTask from '@/components/Analysis/Index.vue';
|
import SearchBar from '@/components/Search/Index.vue';
|
||||||
import Navigation from '@/components/Navigation/Index.vue';
|
import Navigation from '@/components/Navigation/Index.vue';
|
||||||
|
import router from '@/router';
|
||||||
const contentShow = ref(false);
|
|
||||||
|
const contentShow = ref(false);
|
||||||
onMounted(async () => {
|
|
||||||
if (appBridge.isInReactNative()) {
|
onMounted(async () => {
|
||||||
const appToken = utils.getSessionStorage('xToken');
|
if (appBridge.isInReactNative()) {
|
||||||
getUserInfo(appToken)
|
const appToken = utils.getSessionStorage('xToken');
|
||||||
.then((res) => {
|
getUserInfo(appToken)
|
||||||
if (res.data) {
|
.then((res) => {
|
||||||
contentShow.value = true;
|
if (res.data) {
|
||||||
const token = res.data.data.token;
|
contentShow.value = true;
|
||||||
localStorage.setItem('plantToken', token);
|
const token = res.data.data.token;
|
||||||
utils.setSessionStorage('userInfo', res.data.data);
|
localStorage.setItem('plantToken', token);
|
||||||
} else {
|
utils.setSessionStorage('userInfo', res.data.data);
|
||||||
contentShow.value = false;
|
} else {
|
||||||
showFailToast(
|
contentShow.value = false;
|
||||||
error.response.data?.message || error.data?.message || error.message || '服务器错误'
|
showFailToast(
|
||||||
);
|
error.response.data?.message || error.data?.message || error.message || '服务器错误'
|
||||||
}
|
);
|
||||||
})
|
}
|
||||||
.catch((error) => {
|
})
|
||||||
contentShow.value = false;
|
.catch((error) => {
|
||||||
showFailToast(error?.response?.data?.message || error?.message || '服务器错误');
|
contentShow.value = false;
|
||||||
});
|
showFailToast(error?.response?.data?.message || error?.message || '服务器错误');
|
||||||
} else {
|
});
|
||||||
utils.setSessionStorage('xToken', 'f74ba36d7fc3468480648dedba5672ff');
|
} else {
|
||||||
contentShow.value = true;
|
utils.setSessionStorage('xToken', 'f74ba36d7fc3468480648dedba5672ff');
|
||||||
}
|
contentShow.value = true;
|
||||||
});
|
}
|
||||||
</script>
|
});
|
||||||
|
|
||||||
<template>
|
function handleSearchClick() {
|
||||||
<div v-if="contentShow" class="container-home">
|
router.push({ name: 'search' });
|
||||||
<div class="container-body">
|
}
|
||||||
<!-- 首页轮播图 -->
|
</script>
|
||||||
<image-slider />
|
|
||||||
<create-survey :createdNewPage="false" />
|
<template>
|
||||||
<!-- 最新问卷 -->
|
<div v-if="contentShow" class="container-home">
|
||||||
<!--<last-survey/>-->
|
<div class="container-body">
|
||||||
<!-- 模板市场 -->
|
<!-- 搜索栏 -->
|
||||||
<!-- <Market/> -->
|
<search-bar @click="handleSearchClick" />
|
||||||
<!--底部新建问卷-->
|
<!-- 首页轮播图 -->
|
||||||
<NewSurvey />
|
<image-slider />
|
||||||
|
<create-survey :createdNewPage="false" />
|
||||||
<!-- <mine-task /> -->
|
<!-- 最新问卷 -->
|
||||||
|
<!--<last-survey/>-->
|
||||||
<navigation />
|
<!-- 模板市场 -->
|
||||||
</div>
|
<!-- <Market/> -->
|
||||||
</div>
|
<!--底部新建问卷-->
|
||||||
</template>
|
<NewSurvey />
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<!-- <mine-task /> -->
|
||||||
.container-home {
|
|
||||||
overflow: hidden;
|
<navigation />
|
||||||
width: 100%;
|
</div>
|
||||||
|
</div>
|
||||||
//background: #f2f2f2;
|
</template>
|
||||||
//position: relative;
|
|
||||||
|
<style scoped lang="scss">
|
||||||
.home-pen {
|
.container-home {
|
||||||
//height: 200px;
|
overflow: hidden;
|
||||||
position: absolute;
|
width: 100%;
|
||||||
top: -10px;
|
|
||||||
left: 0;
|
//background: #f2f2f2;
|
||||||
z-index: 8;
|
//position: relative;
|
||||||
|
|
||||||
//width: 100%;
|
.home-pen {
|
||||||
background: #fff;
|
//height: 200px;
|
||||||
|
position: absolute;
|
||||||
//background: linear-gradient(180deg, rgba(242, 242, 242, 0) 0%, #ebffe9 100%);
|
top: -10px;
|
||||||
img {
|
left: 0;
|
||||||
width: 100%;
|
z-index: 8;
|
||||||
|
|
||||||
//height: 200px;
|
//width: 100%;
|
||||||
}
|
background: #fff;
|
||||||
}
|
|
||||||
}
|
//background: linear-gradient(180deg, rgba(242, 242, 242, 0) 0%, #ebffe9 100%);
|
||||||
|
img {
|
||||||
.container-body {
|
width: 100%;
|
||||||
padding: 0 10px 80px;
|
|
||||||
|
//height: 200px;
|
||||||
& > :first-child {
|
}
|
||||||
& > div {
|
}
|
||||||
display: flex;
|
}
|
||||||
flex-direction: column;
|
|
||||||
width: 50px;
|
.container-body {
|
||||||
height: 50px;
|
padding: 0 10px 80px;
|
||||||
margin: 10px;
|
|
||||||
}
|
& > :first-child {
|
||||||
}
|
& > div {
|
||||||
}
|
display: flex;
|
||||||
</style>
|
flex-direction: column;
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -1,117 +1,109 @@
|
|||||||
import {
|
import { getSurveysPage, deleteSurveys, saveTemplates } from '@/api/home';
|
||||||
getSurveysPage, deleteSurveys,
|
import { ref } from 'vue';
|
||||||
saveTemplates
|
import { showDialog, showConfirmDialog, showFailToast, showToast } from 'vant';
|
||||||
} from '@/api/home';
|
import { getSurveysDetail } from '@/api/design';
|
||||||
import { ref } from 'vue';
|
|
||||||
import {
|
const form = ref({
|
||||||
showDialog,
|
page: 0,
|
||||||
showConfirmDialog,
|
pageSize: 10,
|
||||||
showFailToast,
|
project_name: ''
|
||||||
showToast
|
});
|
||||||
} from 'vant';
|
|
||||||
import { getSurveysDetail } from '@/api/design';
|
const searchValue = ref('');
|
||||||
|
const survey = ref<SurveyItem[]>([]);
|
||||||
const form = ref({
|
const total = ref(0);
|
||||||
page: 0,
|
const loading = ref(false);
|
||||||
pageSize: 10,
|
const finished = ref(false);
|
||||||
project_name: ''
|
const currentSurvey = ref<SurveyItem>();
|
||||||
});
|
|
||||||
|
async function fetchSingleSurvey(sn: string) {
|
||||||
const searchValue = ref('');
|
const res = await getSurveysDetail(sn);
|
||||||
const survey = ref<SurveyItem[]>([]);
|
// console.log(res);
|
||||||
const total = ref(0);
|
if (res.data.code === 0) {
|
||||||
const loading = ref(false);
|
currentSurvey.value = res.data.data;
|
||||||
const finished = ref(false);
|
}
|
||||||
const currentSurvey = ref<SurveyItem>();
|
}
|
||||||
|
|
||||||
async function fetchSingleSurvey(sn: string) {
|
async function fetchSurveys() {
|
||||||
const res = await getSurveysDetail(sn);
|
const params = {
|
||||||
// console.log(res);
|
page: form.value.page,
|
||||||
if (res.data.code === 0) {
|
per_page: form.value.pageSize,
|
||||||
currentSurvey.value = res.data.data;
|
group_id: 0,
|
||||||
}
|
project_name: searchValue.value
|
||||||
}
|
};
|
||||||
|
const res = await getSurveysPage(params);
|
||||||
async function fetchSurveys() {
|
if (res.data.code === 0) {
|
||||||
const params = {
|
survey.value = survey.value.concat(res.data.data);
|
||||||
page: form.value.page,
|
total.value = res.data.meta.total;
|
||||||
per_page: form.value.pageSize,
|
survey.value.forEach((item) => {
|
||||||
group_id: 0,
|
const sceneName = JSON.parse(JSON.stringify(item.scene_name));
|
||||||
project_name: searchValue.value
|
|
||||||
};
|
const nameList = sceneName ? sceneName.split('-') : [];
|
||||||
const res = await getSurveysPage(params);
|
if (nameList.length > 0) {
|
||||||
if (res.data.code === 0) {
|
item.scene_name = nameList[1] ? nameList[1] : nameList[0];
|
||||||
survey.value = survey.value.concat(res.data.data);
|
}
|
||||||
total.value = res.data.meta.total;
|
|
||||||
survey.value.forEach((item) => {
|
const timeList = item.created_at.split(' ');
|
||||||
const sceneName = JSON.parse(JSON.stringify(item.scene_name));
|
if (nameList.length) {
|
||||||
const nameList = sceneName.split('-');
|
item.created_at = timeList[0];
|
||||||
if (nameList.length > 0) {
|
}
|
||||||
item.scene_name = nameList[1] ? nameList[1] : nameList[0];
|
});
|
||||||
}
|
loading.value = false;
|
||||||
|
// 数据全部加载完成
|
||||||
const timeList = item.created_at.split(' ');
|
if (survey.value.length >= total.value) {
|
||||||
if (nameList.length) {
|
finished.value = true;
|
||||||
item.created_at = timeList[0];
|
}
|
||||||
}
|
} else {
|
||||||
});
|
// Toast()
|
||||||
loading.value = false;
|
}
|
||||||
// 数据全部加载完成
|
}
|
||||||
if (survey.value.length >= total.value) {
|
|
||||||
finished.value = true;
|
function deleteItem(item: SurveyItem) {
|
||||||
}
|
showDialog({
|
||||||
} else {
|
title: `确认删除问卷${item.project_name} ?`,
|
||||||
// Toast()
|
showCancelButton: true,
|
||||||
}
|
confirmButtonColor: '#03B03C'
|
||||||
}
|
})
|
||||||
|
.then(async () => {
|
||||||
function deleteItem(item: SurveyItem) {
|
const res = await deleteSurveys(item.sn);
|
||||||
showDialog({
|
if (res.data.message) {
|
||||||
title: `确认删除问卷${item.project_name} ?`,
|
showToast(res.data.message);
|
||||||
showCancelButton: true,
|
} else {
|
||||||
confirmButtonColor: '#03B03C'
|
showToast('删除成功!');
|
||||||
})
|
}
|
||||||
.then(async () => {
|
form.value.page = 1;
|
||||||
const res = await deleteSurveys(item.sn);
|
survey.value = [];
|
||||||
if (res.data.message) {
|
await fetchSurveys();
|
||||||
showToast(res.data.message);
|
})
|
||||||
} else {
|
.catch(() => {
|
||||||
showToast('删除成功!');
|
// on cancel
|
||||||
}
|
});
|
||||||
form.value.page = 1;
|
}
|
||||||
survey.value = [];
|
|
||||||
await fetchSurveys();
|
// 保存为模板
|
||||||
})
|
async function saveTemplate(item: SurveyItem) {
|
||||||
.catch(() => {
|
const data = JSON.parse(JSON.stringify(item));
|
||||||
// on cancel
|
const res = await saveTemplates(item.sn, data);
|
||||||
});
|
if (res.data.code === 200 || res.data.code === 201) {
|
||||||
};
|
showConfirmDialog({
|
||||||
|
message: '模板保存成功,请前往模板市场查看!',
|
||||||
// 保存为模板
|
showCancelButton: false
|
||||||
async function saveTemplate(item: SurveyItem) {
|
});
|
||||||
const data = JSON.parse(JSON.stringify(item));
|
} else {
|
||||||
const res = await saveTemplates(item.sn, data);
|
showFailToast(res.data);
|
||||||
if (res.data.code === 200 || res.data.code === 201) {
|
}
|
||||||
showConfirmDialog({
|
}
|
||||||
message: '模板保存成功,请前往模板市场查看!',
|
|
||||||
showCancelButton: false
|
export {
|
||||||
});
|
form,
|
||||||
} else {
|
fetchSurveys,
|
||||||
showFailToast(res.data);
|
loading,
|
||||||
}
|
finished,
|
||||||
}
|
survey,
|
||||||
|
total,
|
||||||
export {
|
searchValue,
|
||||||
form,
|
deleteItem,
|
||||||
fetchSurveys,
|
saveTemplate,
|
||||||
loading,
|
currentSurvey,
|
||||||
finished,
|
fetchSingleSurvey
|
||||||
survey,
|
};
|
||||||
total,
|
|
||||||
searchValue,
|
|
||||||
deleteItem,
|
|
||||||
saveTemplate,
|
|
||||||
currentSurvey,
|
|
||||||
fetchSingleSurvey
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ const route = useRoute();
|
|||||||
* 如果当前问卷的数据不存在,重新获取数据
|
* 如果当前问卷的数据不存在,重新获取数据
|
||||||
*/
|
*/
|
||||||
if (!currentSurvey.value) fetchSingleSurvey(route.query.sn as string);
|
if (!currentSurvey.value) fetchSingleSurvey(route.query.sn as string);
|
||||||
|
// 重置 message 信息
|
||||||
|
aiInsightsConfig.value.message = '';
|
||||||
|
|
||||||
useFetchAnalysis(route.query.sn as string);
|
useFetchAnalysis(route.query.sn as string);
|
||||||
</script>
|
</script>
|
||||||
@@ -45,7 +47,7 @@ useFetchAnalysis(route.query.sn as string);
|
|||||||
</template>
|
</template>
|
||||||
</van-cell>
|
</van-cell>
|
||||||
|
|
||||||
<van-cell v-if="aiInsightsConfig.message.length > 0" class="ai-insight">
|
<van-cell v-if="aiInsightsConfig.message.length > 0" class="ai-insight" :key="route">
|
||||||
<template #extra>
|
<template #extra>
|
||||||
<!-- ai 洞察部分内容 -->
|
<!-- ai 洞察部分内容 -->
|
||||||
<div v-html="aiInsightsConfig.message" />
|
<div v-html="aiInsightsConfig.message" />
|
||||||
|
|||||||
@@ -1,19 +1,23 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<section v-for="analysis in questionAnalysis" :key="analysis.stem">
|
<section
|
||||||
<el-tag>{{ questionTypeMap.get(analysis.question_type as number) }}</el-tag>
|
v-for="analysis in questionAnalysis"
|
||||||
{{ analysis.stem }}
|
:key="analysis.stem"
|
||||||
|
v-if="analysis?.option.length"
|
||||||
<chart-msg :series="formatData(analysis)" />
|
>
|
||||||
</section>
|
<el-tag>{{ questionTypeMap.get(analysis.question_type as number) }}</el-tag>
|
||||||
</div>
|
{{ analysis.stem }}
|
||||||
</template>
|
|
||||||
|
<chart-msg :series="formatData(analysis)" />
|
||||||
<script setup lang="ts">
|
|
||||||
import { questionAnalysis } from '../../hooks/useAnalysis';
|
{{ analysis }}
|
||||||
import { questionTypeMap } from '@/utils/question/typeMapping';
|
</section>
|
||||||
import ChartMsg from '@/components/Analysis/Index.vue';
|
</div>
|
||||||
import { formatData, series } from './hooks/pieSeries';
|
</template>
|
||||||
|
|
||||||
console.log(`question analysis info`, questionAnalysis.value);
|
<script setup lang="ts">
|
||||||
</script>
|
import { questionAnalysis } from '../../hooks/useAnalysis';
|
||||||
|
import { questionTypeMap } from '@/utils/question/typeMapping';
|
||||||
|
import ChartMsg from '@/components/Analysis/Index.vue';
|
||||||
|
import { formatData } from './hooks/pieSeries';
|
||||||
|
</script>
|
||||||
|
|||||||
@@ -23,12 +23,12 @@ export const series = ref({
|
|||||||
});
|
});
|
||||||
|
|
||||||
export function formatData(data: any) {
|
export function formatData(data: any) {
|
||||||
const _series = ref(JSON.parse(JSON.stringify(series.value)));
|
const _series = JSON.parse(JSON.stringify(series.value));
|
||||||
|
|
||||||
// 当内容为单选的时候处理方式
|
// 当内容为单选的时候处理方式
|
||||||
if (data.question_index === 2) {
|
if (data.question_index === 2 || data.question_index === 1) {
|
||||||
const { option } = data;
|
const { option } = data;
|
||||||
_series.value.data = option.map((item: any) => {
|
_series.data = option.map((item: any) => {
|
||||||
return {
|
return {
|
||||||
value: item.number,
|
value: item.number,
|
||||||
name: item.title
|
name: item.title
|
||||||
|
|||||||
Reference in New Issue
Block a user