This commit is contained in:
wanganmao
2022-10-13 19:08:15 +08:00
22 changed files with 380 additions and 218 deletions

View File

@@ -41,12 +41,14 @@
v-for="(child, childIndex) in item.children" v-for="(child, childIndex) in item.children"
:key="childIndex" :key="childIndex"
> >
<div class="menu-bar-item-parent">
<div <div
class="menu-bar-item-main" class="menu-bar-item-main"
:style="{ :style="{
background: child.check ? 'rgba(112, 185, 54, 0.1)' : '#ffffff', background: child.check ? 'rgba(112, 185, 54, 0.1)' : '#ffffff',
color: child.check ? '#70b936' : '#000000', color: child.check ? '#70b936' : '#000000',
height: '51px', height: '32px',
margin: '10px 0',
borderRadius: '0', borderRadius: '0',
}" }"
@click="childCheck(child, i)" @click="childCheck(child, i)"
@@ -60,6 +62,7 @@
</div> </div>
</div> </div>
</div> </div>
</div>
</template> </template>
<script> <script>
@@ -189,7 +192,9 @@ function menusStatusToFalsefather(menus) {
font-size: 13px; font-size: 13px;
z-index: 99999; z-index: 99999;
&-item { &-item {
position: relative;
width: 220px; width: 220px;
z-index: 99;
background: rgba(245, 245, 245, 0.6); background: rgba(245, 245, 245, 0.6);
&-child { &-child {
background-color: #ffffff; background-color: #ffffff;
@@ -275,4 +280,24 @@ function menusStatusToFalsefather(menus) {
position: relative; position: relative;
z-index: 99; z-index: 99;
} }
.menu-bar-item-child{
height: 50px;
display: block;
position: relative;
top: 0;
left: 0;
/* background: #ffffff; */
z-index: 999;
}
.menu-bar-item-parent{
height: 50px;
position: absolute;
z-index: 999;
left: 0;
top: 0;
background: #ffffff;
opacity: 1;
z-index: 100;
height: 50px;
}
</style> </style>

View File

@@ -7,25 +7,28 @@
</div> </div>
</a-modal> </a-modal>
<!-- 下载中心 --> <!-- 下载中心 -->
<DownloadCenter :isView="true" v-model:visible="downloadVisible" v-if="downloadVisible" @getCloseDown="getCloseDown"></DownloadCenter> <DownloadCenter
:isView="true"
v-model:visible="downloadVisible"
v-if="downloadVisible"
@getCloseDown="getCloseDown"
></DownloadCenter>
</div> </div>
</template> </template>
<script setup> <script setup>
import { ref, watch, h, computed } from 'vue' import { ref, watch, h, computed } from "vue";
import { useStore } from 'vuex'; import { useStore } from "vuex";
import { useRoute, useRouter } from 'vue-router'; import { useRoute, useRouter } from "vue-router";
import { Modal } from "ant-design-vue";
import { Modal } from 'ant-design-vue';
import AnswerApi from "@/views/Answer/api"; import AnswerApi from "@/views/Answer/api";
import { downloadFile } from "@/views/DataAnalyse/composables/downloadFile"; import { downloadFile } from "@/views/DataAnalyse/composables/downloadFile";
import { getSurveyInfo } from "@/api/publish"; import { getSurveyInfo } from "@/api/publish";
import { addDownloadCenter } from "@/api/download.js"; import { addDownloadCenter } from "@/api/download.js";
import DownloadCenter from "@/views/DownloadCenter/index.vue" import DownloadCenter from "@/views/DownloadCenter/index.vue";
const emit = defineEmits(['success', 'failed']) const emit = defineEmits(["success", "failed"]);
const props = defineProps({ const props = defineProps({
visible: { visible: {
type: Boolean, type: Boolean,
@@ -33,16 +36,16 @@ const props = defineProps({
}, },
sn: { sn: {
type: String, type: String,
default: '' default: "",
}, },
type: { type: {
type: [String, Number], type: [String, Number],
default: undefined default: undefined,
} },
}); });
const route = useRoute() const route = useRoute();
const store = useStore() const store = useStore();
const shown = ref(false); const shown = ref(false);
const showModal = async () => { const showModal = async () => {
@@ -51,25 +54,33 @@ const showModal = async () => {
const router = useRouter(); const router = useRouter();
const downloadVisible = ref(false); const downloadVisible = ref(false);
const download = async () => { const download = async () => {
const arr = [] const arr = [];
const keys = {} const keys = {};
const selectedList = checkedList.value.map(name =>keys[name] = 1) const selectedList = checkedList.value.map((name) => (keys[name] = 1));
arr.push(...selectedList) arr.push(...selectedList);
// arr.push(['type', props.type]) // arr.push(['type', props.type])
arr.push(['download_type', '5']) arr.push(["download_type", "5"]);
// const params = new URLSearchParams(arr) // const params = new URLSearchParams(arr)
const params = {download_type: '5',...keys} // const params = {download_type: '5',...keys}
const params = {
download_type: "5",
is_title: keys.is_title || 0,
is_in: keys.is_in || 0,
is_number: keys.is_number || 0,
is_if: keys.is_if || 0,
is_logic: keys.is_logic || 0,
};
// 下载中心 // 下载中心
addDownloadCenter(props.sn,params).then(res=>{ addDownloadCenter(props.sn, params).then((res) => {
store.dispatch('downloadCenter/changeCenterUrl',route.path) store.dispatch("downloadCenter/changeCenterUrl", route.path);
downloadVisible.value = true downloadVisible.value = true;
// store.dispatch('downloadCenter/changeCenterShow',true) // store.dispatch('downloadCenter/changeCenterShow',true)
shown.value = false; shown.value = false;
// router.push({ // router.push({
// path: "/downloadCenter", // path: "/downloadCenter",
// query: { path:'planet',sn:props.sn }, // query: { path:'planet',sn:props.sn },
// }); // });
}) });
// const pendingModal = Modal.info({ // const pendingModal = Modal.info({
// title: () => '导出任务进行中', // title: () => '导出任务进行中',
// okText: '取消', // okText: '取消',
@@ -110,28 +121,28 @@ const download = async () => {
// errorModal.destroy() // errorModal.destroy()
// }) // })
// }) // })
} };
const handleOk = () => { const handleOk = () => {
download() download();
}; };
const checkedList = ref(['is_title', 'is_in', 'is_number', 'is_if', 'is_logic']) const checkedList = ref(["is_title", "is_in", "is_number", "is_if", "is_logic"]);
const options = ref([ const options = ref([
{ label: '标题', value: 'is_title' }, { label: "标题", value: "is_title" },
{ label: '介绍语', value: 'is_in' }, { label: "介绍语", value: "is_in" },
{ label: '题号', value: 'is_number' }, { label: "题号", value: "is_number" },
{ label: '限定条件', value: 'is_if' }, { label: "限定条件", value: "is_if" },
{ label: '逻辑', value: 'is_logic' }, { label: "逻辑", value: "is_logic" },
]) ]);
const getCloseDown = () => { const getCloseDown = () => {
downloadVisible.value = false downloadVisible.value = false;
} };
watch( watch(
() => props.visible, () => props.visible,
(val) => { (val) => {
shown.value = val; shown.value = val;
if (val === true) { if (val === true) {
checkedList.value = ['is_title', 'is_in', 'is_number', 'is_if', 'is_logic'] checkedList.value = ["is_title", "is_in", "is_number", "is_if", "is_logic"];
} }
}, },
{ {
@@ -142,7 +153,6 @@ watch(
watch(shown, (val) => { watch(shown, (val) => {
emit("update:visible", val); emit("update:visible", val);
}); });
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

View File

@@ -99,7 +99,9 @@
<!-- 签名题 --> <!-- 签名题 -->
<div v-else-if="question.question_type === 22"></div> <div v-else-if="question.question_type === 22"></div>
<!-- 知情同意书 --> <!-- 知情同意书 -->
<div v-else-if="question.question_type === 23"></div> <div v-else-if="question.question_type === 23">
<div v-html="question.row?.[0]" />
</div>
<!-- 热区题 --> <!-- 热区题 -->
<div v-else-if="question.question_type === 25 || question.question_type === 26"> <div v-else-if="question.question_type === 25 || question.question_type === 26">
<div class="heat" v-html="question.row?.[0]" /> <div class="heat" v-html="question.row?.[0]" />

View File

@@ -4,7 +4,7 @@
<div class="action-part"> <div class="action-part">
<div class="image-upload"></div> <div class="image-upload"></div>
<div class="btn-wrapper"> <div class="btn-wrapper">
<Button type="link" size="small" style="color: #8C8C8C" @click="handleCancel">取消</Button> <Button type="link" size="small" style="color: #8c8c8c" @click="handleCancel">取消</Button>
<Divider type="vertical" /> <Divider type="vertical" />
<Button type="link" size="small" @click="handleCommit">发送</Button> <Button type="link" size="small" @click="handleCommit">发送</Button>
</div> </div>
@@ -12,56 +12,66 @@
</div> </div>
</template> </template>
<script> <script>
import { defineComponent, ref, computed } from "vue"; import { defineComponent, ref, computed, watch } from "vue";
import { Textarea, Button, Divider } from "ant-design-vue"; import { Textarea, Button, Divider } from "ant-design-vue";
export default defineComponent({ export default defineComponent({
props: ['content'], props: ["content"],
emits: ['update:content', 'cancel:content'], emits: ["update:content", "cancel:content"],
components: { Textarea, Button, Divider }, components: { Textarea, Button, Divider },
setup(props, { emit }) { setup(props, { emit }) {
const loading = ref(false);
const text = computed({ const text = computed({
get() { get() {
return props.content return props.content;
}, },
set(newValue) { set(newValue) {
emit('update:content', newValue) emit("update:content", newValue);
},
});
// 监听答案
watch(text, (newVal) => {
if (!newVal && loading.value) {
loading.value = false;
} }
}) });
/** /**
* 清空内容 * 清空内容
*/ */
function handleCancel() { function handleCancel() {
text.value = '' text.value = "";
emit('cancel:content') emit("cancel:content");
} }
/** /**
* 提交内容 * 提交内容
*/ */
function handleCommit() { function handleCommit() {
emit('commit:message', text.value) if (loading.value) return;
if (text.value) loading.value = true;
emit("commit:message", text.value);
} }
return { return {
text, text,
loading,
handleCancel, handleCancel,
handleCommit, handleCommit,
} };
} },
}) });
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.comment-textarea { .comment-textarea {
height: auto; height: auto;
border-right: 6px; border-right: 6px;
background: #F6F6F6; background: #f6f6f6;
:deep(.ant-input) { :deep(.ant-input) {
background: #F6F6F6; background: #f6f6f6;
border: none; border: none;
outline: none; outline: none;
&:focus { &:focus {
@@ -77,5 +87,4 @@ export default defineComponent({
justify-content: space-between; justify-content: space-between;
} }
} }
</style> </style>

View File

@@ -49,9 +49,9 @@
<slider-num-rate <slider-num-rate
rateType="slider" rateType="slider"
:param="{ :param="{
interval: config.score_interval, interval: config.score_interval*1,
max: config.max, max: config.max*1,
min: config.min, min: config.min*1,
}" }"
:value="value" :value="value"
:disabled="disabled" :disabled="disabled"
@@ -93,7 +93,7 @@ export default defineComponent({
setup(props, context) { setup(props, context) {
// 打分回调 // 打分回调
function changeValue(value) { function changeValue(value) {
if(props.disabled)return if (props.disabled) return;
context.emit("update:value", value); context.emit("update:value", value);
context.emit("change", value); context.emit("change", value);
} }

View File

@@ -12,11 +12,11 @@
</div> </div>
<div class="option"> <div class="option">
<span v-if="config.location === 1" class="label left answer-color">{{ <span v-if="config.location === 1" class="label left answer-color">{{
config.show_label config.show_label || "总和"
}}</span> }}</span>
<a-input-number type="number" :value="sum" disabled /> <a-input-number type="number" :value="sum" disabled />
<span v-if="config.location === 0" class="label right answer-color">{{ <span v-if="config.location === 0" class="label right answer-color">{{
config.show_label config.show_label || "总和"
}}</span> }}</span>
</div> </div>
</div> </div>

View File

@@ -464,11 +464,7 @@ export default defineComponent({
} }
.footer { .footer {
left: 0; margin-top: 48px;
bottom: 0;
width: 100%;
position: absolute;
padding: 20px 0;
:deep(.previous) { :deep(.previous) {
border: 1px solid $yili-default-color; border: 1px solid $yili-default-color;

View File

@@ -2,7 +2,7 @@
<div> <div>
<!-- 标题 --> <!-- 标题 -->
<div class="q-title"> <div class="q-title">
<div class="left"> <div class="">
<div v-html="title" class="answer-color"></div> <div v-html="title" class="answer-color"></div>
<!-- 问题提示 --> <!-- 问题提示 -->
<a-tooltip v-if="config.is_placeholder"> <a-tooltip v-if="config.is_placeholder">
@@ -69,8 +69,8 @@
<a-radio value="b" /> <a-radio value="b" />
</div> </div>
<div class="td option scrollbar"> <div class="td option scrollbar">
<img v-if="option.option_config.option_type === 2" :src="option.option" /> <a-image v-if="option.option_config.option_type === 2" :src="option.option" />
<div v-else v-html="option.option" /> <rich-text v-else :nodes="option.option" isPreview />
</div> </div>
<div class="td"> <div class="td">
<a-radio value="w" /> <a-radio value="w" />
@@ -85,8 +85,8 @@
<a-radio value="w" /> <a-radio value="w" />
</div> </div>
<div class="td option scrollbar"> <div class="td option scrollbar">
<img v-if="option.option_config.option_type === 2" :src="option.option" /> <a-image v-if="option.option_config.option_type === 2" :src="option.option" />
<div v-else v-html="option.option" /> <rich-text v-else :nodes="option.option" isPreview />
</div> </div>
<div class="td"> <div class="td">
<a-radio value="b" /> <a-radio value="b" />
@@ -104,8 +104,8 @@
<a-radio value="w" /> <a-radio value="w" />
</div> </div>
<div class="td option scrollbar"> <div class="td option scrollbar">
<img v-if="option.option_config.option_type === 2" :src="option.option" /> <a-image v-if="option.option_config.option_type === 2" :src="option.option" />
<div v-else v-html="option.option" /> <rich-text v-else :nodes="option.option" isPreview />
</div> </div>
</div> </div>
<div <div
@@ -120,8 +120,8 @@
<a-radio value="b" /> <a-radio value="b" />
</div> </div>
<div class="td option scrollbar"> <div class="td option scrollbar">
<img v-if="option.option_config.option_type === 2" :src="option.option" /> <a-image v-if="option.option_config.option_type === 2" :src="option.option" />
<div v-else v-html="option.option" /> <rich-text v-else :nodes="option.option" isPreview />
</div> </div>
</div> </div>
<div <div
@@ -130,8 +130,8 @@
:class="index % 2 === 0 ? '' : 'bg-gray answer-background10'" :class="index % 2 === 0 ? '' : 'bg-gray answer-background10'"
> >
<div class="td option scrollbar"> <div class="td option scrollbar">
<img v-if="option.option_config.option_type === 2" :src="option.option" /> <a-image v-if="option.option_config.option_type === 2" :src="option.option" />
<div v-else v-html="option.option" /> <rich-text v-else :nodes="option.option" isPreview />
</div> </div>
<div class="td"> <div class="td">
<a-radio value="b" /> <a-radio value="b" />
@@ -146,8 +146,8 @@
:class="index % 2 === 0 ? '' : 'bg-gray answer-background10'" :class="index % 2 === 0 ? '' : 'bg-gray answer-background10'"
> >
<div class="td option scrollbar"> <div class="td option scrollbar">
<img v-if="option.option_config.option_type === 2" :src="option.option" /> <a-image v-if="option.option_config.option_type === 2" :src="option.option" />
<div v-else v-html="option.option" /> <rich-text v-else :nodes="option.option" isPreview />
</div> </div>
<div class="td"> <div class="td">
<a-radio value="w" /> <a-radio value="w" />
@@ -192,9 +192,10 @@ import PfePagination from "@/components/PfePagination.vue";
import { defineComponent, ref, watch } from "vue"; import { defineComponent, ref, watch } from "vue";
import { message } from "ant-design-vue"; import { message } from "ant-design-vue";
import Remark from "@/views/Answer/components/Remark"; import Remark from "@/views/Answer/components/Remark";
import RichText from '@/components/RichText.vue';
export default defineComponent({ export default defineComponent({
components: { PfePagination, Remark }, components: { PfePagination, Remark, RichText },
props: { props: {
// 错误 // 错误
error: { error: {
@@ -328,10 +329,10 @@ export default defineComponent({
// 当前页答案 // 当前页答案
const currentOptions = allOptions.value[page.value - 1]; const currentOptions = allOptions.value[page.value - 1];
if (currentOptions.findIndex((option) => option.value === "b") === -1) { if (currentOptions.findIndex((option) => option.value === "b") === -1) {
return message.error("请选择高相关"); return message.error(`请选择${props.config.first_text}`);
} }
if (currentOptions.findIndex((option) => option.value === "w") === -1) { if (currentOptions.findIndex((option) => option.value === "w") === -1) {
return message.error("请选择不相关"); return message.error(`请选择${props.config.second_text}`);
} }
// 最后一页 // 最后一页
if (page.value === pages.value) { if (page.value === pages.value) {
@@ -366,7 +367,8 @@ export default defineComponent({
() => props.answer, () => props.answer,
() => { () => {
context.emit("changeAnswer", { context.emit("changeAnswer", {
options: allOptions.value, options: options.value,
mxdOptions: allOptions.value,
}); });
}, },
{ {
@@ -399,13 +401,8 @@ export default defineComponent({
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
.left {
width: 100%;
margin-right: 24px;
}
.iconfont { .iconfont {
color: #70b936; color: #3461ff;
cursor: pointer; cursor: pointer;
margin-left: 12px; margin-left: 12px;
} }
@@ -431,15 +428,20 @@ export default defineComponent({
.td { .td {
width: 106px; width: 106px;
padding: 12px 0; padding: 12px 10px;
text-align: center; // text-align: center;
overflow: auto; overflow: auto;
display: flex;
align-items: center;
justify-content: center;
} }
.option { .option {
flex: 1; flex: 1;
display: block;
text-align: center;
img { :deep(img) {
width: 87px; width: 87px;
// height: 119px; // height: 119px;
} }
@@ -456,11 +458,7 @@ export default defineComponent({
} }
.footer { .footer {
left: 0; margin-top: 48px;
bottom: 0;
width: 100%;
position: absolute;
padding: 20px 0;
:deep(.previous) { :deep(.previous) {
border: 1px solid $yili-default-color; border: 1px solid $yili-default-color;

View File

@@ -10,7 +10,7 @@
<template #content> <template #content>
<div v-html="label"></div> <div v-html="label"></div>
</template> </template>
<div v-html="label"></div> <div class="drag-item" v-html="label"></div>
</a-popover> </a-popover>
</div> </div>
</div> </div>
@@ -21,14 +21,14 @@
</div> </div>
<template #overlay> <template #overlay>
<a-menu> <a-menu>
<a-menu-item> <a-menu-item @click="exportData">
<a href="javascript:" @click="exportData">导出当前图表数据</a> <a href="javascript:">导出当前图表数据</a>
</a-menu-item> </a-menu-item>
<a-menu-item> <a-menu-item @click="downloadImg" v-if="hasChart">
<a href="javascript:" @click="downloadImg" v-if="hasChart">导出图片</a> <a href="javascript:">导出图片</a>
</a-menu-item> </a-menu-item>
<a-menu-item> <a-menu-item @click="removeChart">
<a href="javascript:" @click="removeChart">删除图表</a> <a href="javascript:">删除图表</a>
</a-menu-item> </a-menu-item>
</a-menu> </a-menu>
</template> </template>
@@ -131,6 +131,11 @@ export default defineComponent({
font-size: 14px; font-size: 14px;
margin-bottom: 0; margin-bottom: 0;
color: #70b936; color: #70b936;
.drag-item {
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
} }
} }
.action { .action {

View File

@@ -24,9 +24,9 @@
</template> </template>
<script setup> <script setup>
import { ref, computed, provide} from 'vue' import { ref, computed, provide, nextTick } from 'vue'
import { useStore } from "vuex"; import { useStore } from "vuex";
import { getDiagramAnalysis } from "@/api/data-analyse";
import Header from '@/views/DataAnalyse/diagram/components/Layouts/Header' import Header from '@/views/DataAnalyse/diagram/components/Layouts/Header'
import Main from '@/views/DataAnalyse/diagram/components/Layouts/Main' import Main from '@/views/DataAnalyse/diagram/components/Layouts/Main'
import Footer from '@/views/DataAnalyse/diagram/components/Layouts/Footer' import Footer from '@/views/DataAnalyse/diagram/components/Layouts/Footer'
@@ -116,7 +116,14 @@ function getDateName() {
const surveyName = computed(() => { const surveyName = computed(() => {
return store.state.common.surveyName; return store.state.common.surveyName;
}); });
var tabledata = ref(null)
function exportData () { function exportData () {
let params = {
...searchParams.value,
question_index: props.data.question_index,
type: 1
};
getDiagramAnalysis(props.sn, params).then((res) => {
let date = Date.now(); let date = Date.now();
date = date -= date % (60 * 1000); date = date -= date % (60 * 1000);
let imageUrl = '' let imageUrl = ''
@@ -126,13 +133,39 @@ function exportData() {
// 图片单选 多选 文件上传 不显示table数据 // 图片单选 多选 文件上传 不显示table数据
let isSpecial let isSpecial
if (!is_quick.value) { if (!is_quick.value) {
if([13, 14, 18].includes(props.data.question_type)) { if ([13, 14].includes(props.data.question_type)) {
isSpecial = true isSpecial = false
res.data[0].option.map(item => {
if (item.title.indexOf('<img') > -1) {
item.title = item.title.slice(0, item.title.length - 2) + `width="100" ` + item.title.slice(item.title.length - 2);
}
})
}
}
if ([18].includes(props.data.question_type)) {
res.data[0].option.map((el) => {
if (el.title.indexOf('img') != -1) {
el.title = el.title.slice(5)
} else {
el.title = el.title.substring(0, el.title.lastIndexOf('.'))
}
delete el.data
delete el.answer
return res.data[0].option
})
}
const colums = isSpecial ? [] : res.data[0].head
const data = isSpecial ? [] : res.data[0].option
if ([5, 9, 11, 26, 15, 16, 10, 17].includes(props.data.question_type)) {
if (data[0].option) {
colums[0].key = 'option_title'
data.map((item, index) => {
item.option.map((e, i) => {
item[e.index] = e.number
})
})
} }
} }
const colums = isSpecial ? [] :tableInstance.value.columns
const data = isSpecial ? [] : tableInstance.value.data
const html = generatorTable(imageUrl, colums, data, props.data); const html = generatorTable(imageUrl, colums, data, props.data);
const title = `${props.data.title}_数据详情表_${getDateName()}`; const title = `${props.data.title}_数据详情表_${getDateName()}`;
exportChart(props.sn, { exportChart(props.sn, {
@@ -145,6 +178,7 @@ function exportData() {
fileName: title fileName: title
} }
store.dispatch('common/fileDown', subdata) store.dispatch('common/fileDown', subdata)
})
}); });
} }
@@ -161,6 +195,7 @@ function fullScreen() {
position: relative; position: relative;
height: 640px; height: 640px;
padding: 24px 32px 24px 32px; padding: 24px 32px 24px 32px;
background: #fff;
border-radius: 6px; border-radius: 6px;
box-shadow: 0px 0px 6px 0px rgba(0,0,0,0.1); box-shadow: 0px 0px 6px 0px rgba(0,0,0,0.1);
} }

View File

@@ -1,4 +1,5 @@
export default function (imgUrl, columns, data, propsData) { export default function (imgUrl, columns, data, propsData) {
console.log('imgUrl, columns, data, propsData','---',imgUrl,'---', columns,'---', data,'---', propsData);
const str = [] const str = []
@@ -17,7 +18,12 @@ export default function (imgUrl, columns, data, propsData) {
data = data.map(item => { data = data.map(item => {
const arr = [] const arr = []
header.forEach(head => { header.forEach(head => {
const value = item[head] let value
if(item.value){
value = item.value[head]
}else{
value = item[head]
}
arr.push(value) arr.push(value)
}) })
return arr return arr
@@ -34,6 +40,7 @@ export default function (imgUrl, columns, data, propsData) {
const thead = columns.map(item => `<th>${item.title}</th>`).join('') const thead = columns.map(item => `<th>${item.title}</th>`).join('')
str.push(thead) str.push(thead)
str.push('</tr>') str.push('</tr>')
console.log('data',data);
data.forEach(row => { data.forEach(row => {
let tbody = ['<tr>'] let tbody = ['<tr>']
for (let k of row) { for (let k of row) {

View File

@@ -194,6 +194,7 @@ export default function useChartOption(source, type, enableLabel = true, other =
show: true, show: true,
minValueSpan: 5, minValueSpan: 5,
maxValueSpan: 8, maxValueSpan: 8,
width: 10,
handleSize: 4, handleSize: 4,
filterMode: 'filter', filterMode: 'filter',
backgroundColor: '#fff', backgroundColor: '#fff',
@@ -278,7 +279,7 @@ export default function useChartOption(source, type, enableLabel = true, other =
} }
}) })
const seriesData = sourceData.map(item =>item.number) const seriesData = sourceData.map(item =>item.number)
const tooltipText = sourceData.map(item =>item.title + ': ' + '\xa0' + item.number + '<br />') const tooltipText = sourceData.map(item =>item.title + ': ' + '\xa0' + item.number + '\xa0' + '' + item.rate + '' + '<br />')
defaultOption = { defaultOption = {
// legend: { // legend: {
// data: legendData // data: legendData

View File

@@ -97,35 +97,34 @@
rowKey="option_index"> rowKey="option_index">
<template v-for="(col,index) in c2" <template v-for="(col,index) in c2"
:key="index" :key="index"
#[col.key]="{ text}"> #[col.key]="data">
<div v-if="col.dataIndex === 'sort'"> <div v-if="col.dataIndex === 'sort'">
<div v-if="text.value=='1'" <div v-if="data.text.value=='1'"
style="color:rgb(175,52,52)"> style="color:rgb(175,52,52)">
{{ text.value }}</div> {{ data.text.value }}</div>
<div v-if="text.value=='2'" <div v-if="data.text.value=='2'"
style="color:rgb(223,160,124)"> style="color:rgb(223,160,124)">
{{ text.value }}</div> {{ data.text.value }}</div>
<div v-if="text.value=='3'" <div v-if="data.text.value=='3'"
style="color:rgb(238,215,144)"> style="color:rgb(238,215,144)">
{{ text.value }}</div> {{ data.text.value }}</div>
<div v-if="text.value!='3'&&text.value!='2'&&text.value!='1'"> <div v-if="data.text.value!='3'&&data.text.value!='2'&&data.text.value!='1'">
{{ text.value }}</div> {{ data.text.value }}</div>
</div> </div>
<div v-else-if="col.dataIndex === 'option_title'"> <div v-else-if="col.dataIndex === 'option_title'">
<div class="mxd-lc-detail-table-row" <div class="mxd-lc-detail-table-row"
v-if="text.type == 0 || text.type == 1" v-if="data.text.type == 0 || data.text.type == 1"
v-html="text.value"></div> v-html="data.text.value" :style="data.index <3 ? 'color:#47c4f5' : ''"></div>
<img v-if="text.type == 2" <img v-if="data.text.type == 2"
:src="text.value" :src="data.text.value"
style="width: 40px; height: 40px" /> style="width: 40px; height: 40px" />
</div> </div>
<div v-else> <div v-else>
<div v-if="text.value >= 0" <div v-if="data.text.value >= 0"
style="color: #52c19a">{{ text.value }}</div> style="color: #52c19a">{{ data.text.value == 0? '0': data.text.value}}</div>
<div v-else <div v-else
style="color: #923139">{{ text.value }}</div> style="color: #923139">{{ data.text.value == 0? '0': data.text.value }}</div>
</div> </div>
</template> </template>
</a-table> </a-table>
@@ -140,36 +139,38 @@
:pagination="false" :pagination="false"
rowKey="option_index" rowKey="option_index"
:scroll="{ y: 500, x:800 }"> :scroll="{ y: 500, x:800 }">
<template v-for="(col,index) in c1" <template v-for="(col,index) in c1"
:key="index" :key="index"
#[col.dataIndex]="{ text }"> #[col.dataIndex]=" data ">
<div v-if="col.dataIndex === 'sort'"> <div v-if="col.dataIndex === 'sort'">
<div v-if="text.value=='1'"
<div v-if="data.text.value=='1'"
style="color:rgb(175,52,52)"> style="color:rgb(175,52,52)">
{{ text.value }}</div> {{ data.text.value }}</div>
<div v-if="text.value=='2'" <div v-if="data.text.value=='2'"
style="color:rgb(223,160,124)"> style="color:rgb(223,160,124)">
{{ text.value }}</div> {{ data.text.value }}</div>
<div v-if="text.value=='3'" <div v-if="data.text.value=='3'"
style="color:rgb(238,215,144)"> style="color:rgb(238,215,144)">
{{ text.value }}</div> {{ data.text.value }}</div>
<div v-if="text.value!='3'&&text.value!='2'&&text.value!='1'"> <div v-if="data.text.value!='3'&&data.text.value!='2'&&data.text.value!='1'">
{{ text.value }}</div> {{ data.text.value }}</div>
</div> </div>
<div v-else-if="col.dataIndex === 'option_title'"> <div v-else-if="col.dataIndex === 'option_title'">
<div class="mxd-lc-detail-table-row" <div class="mxd-lc-detail-table-row"
v-if="text.type == 0 || text.type == 1" v-if="data.text.type == 0 || data.text.type == 1"
v-html="text.value"></div> v-html="data.text.value" :style="data.index <3 ? 'color:#47c4f5' : ''"></div>
<img v-if="text.type == 2" <img v-if="data.text.type == 2"
:src="text.value" :src="data.text.value"
style="width: 40px; height: 40px" /> style="width: 40px; height: 40px" />
</div> </div>
<div v-else> <div v-else>
<div v-if="text.value >= 0" <div v-if="data.text.value >= 0"
style="color: #52c19a">{{ text.value }}</div> style="color: #52c19a">{{ data.text.value == 0? '0': data.text.value}}</div>
<div v-else <div v-else
style="color: #923139">{{ text.value }}</div> style="color: #923139">{{ data.text.value == 0? '0': data.text.value }}</div>
</div> </div>
</template> </template>
</a-table> </a-table>
@@ -290,7 +291,7 @@ async function download (type) {
} }
watch(() => props.info, (info) => { watch(() => props.info, (info) => {
const data = JSON.parse(JSON.stringify(info.raw_data.data)) const data = JSON.parse(JSON.stringify(info.zero_data.data))
if (!info) return if (!info) return
fitChartData.value = info.fit_chart fitChartData.value = info.fit_chart
if (typeof info.fit === 'string') { if (typeof info.fit === 'string') {
@@ -307,12 +308,12 @@ watch(() => props.info, (info) => {
barData.value = barChartData; barData.value = barChartData;
const _c1 = [].concat(info.raw_data.columns) const _c1 = [].concat(info.raw_data.columns)
c1.value = [] c1.value = []
c1.value = _c1.map((item) => { c1.value = _c1.map((item,index) => {
if (item?.children) { if (item?.children) {
item.children.map((e) => { e.dataIndex = e.key; childrenlist.push(e.key) }) item.children.map((e,index) => { e.dataIndex = e.key;e.index =index; childrenlist.push(e.key) })
} }
if (item?.children) { if (item?.children) {
item.children.map((e) => { e.dataIndex = e.key; childrenlist.push(e.key) }) item.children.map((e,index) => { e.dataIndex = e.key;e.index =index;childrenlist.push(e.key) })
} else { } else {
item.slots = { customRender: item.key } item.slots = { customRender: item.key }
item.dataIndex = item.key item.dataIndex = item.key
@@ -347,7 +348,7 @@ watch(() => props.info, (info) => {
c2.value = [] c2.value = []
// 带children的key存进去 // 带children的key存进去
c2.value = _c2.map(item => { c2.value = _c2.map((item) => {
if (item?.children) { if (item?.children) {
item.children.map((e) => { e.dataIndex = e.key;childrenlist2.push(e.key) }) item.children.map((e) => { e.dataIndex = e.key;childrenlist2.push(e.key) })
} else { } else {

View File

@@ -7,17 +7,31 @@
</div> </div>
<a-button class="daochubtn" <a-button class="daochubtn"
type="primary" type="primary"
v-if="info && info.raw_data.columns.length >0"
@click="handleExportXlsx(responseData.columns, responseData.data)"> @click="handleExportXlsx(responseData.columns, responseData.data)">
导出分析结果 导出分析结果
</a-button> </a-button>
</div> </div>
<div>
<a-spin tip="Loading..." v-if="loading">
<a-alert
message="努力加载中..."
></a-alert>
</a-spin>
<div v-else-if=" !info || info.raw_data.columns.length <=0" class="empty-data">
<img class="empty-img"
:src="require('@/assets/img/publish/no-data.png')"
alt="" />
<div class="empty-text">由于样本量较小 暂无分析数据</div>
</div>
<a-tabs v-model:activeKey="activeKey" <a-tabs v-model:activeKey="activeKey"
@change="changeTab"> @change="changeTab">
<a-tab-pane v-for="item in tabList" <a-tab-pane v-for="item in tabList"
:key="item.key" :key="item.key"
:tab="item.title"> :tab="item.title">
<div class="component-container"> <div class="component-container">
<div v-if="!info" <div v-if="!info || info.raw_data.columns.length <=0"
class="empty-data"> class="empty-data">
<img class="empty-img" <img class="empty-img"
:src="require('@/assets/img/mxd/mxd_empty_data.png')" :src="require('@/assets/img/mxd/mxd_empty_data.png')"
@@ -36,6 +50,7 @@
</div> </div>
</a-tab-pane> </a-tab-pane>
</a-tabs> </a-tabs>
</div>
</div> </div>
</template> </template>
@@ -76,6 +91,7 @@ const responseData = ref({});
const activeKey = ref(""); const activeKey = ref("");
const tabList = ref([]); const tabList = ref([]);
const data = ref({}); const data = ref({});
const loading =ref(true);
const info = ref({ const info = ref({
fit: "", fit: "",
fit_chart: [], fit_chart: [],
@@ -188,7 +204,9 @@ function handleExportXlsx (columns, data) {
} }
const getData = () => { const getData = () => {
loading.value =true;
getAnalyseDetail(props.sn, props.id).then((res) => { getAnalyseDetail(props.sn, props.id).then((res) => {
loading.value =false;
responseData.value = res.data; responseData.value = res.data;
const columns = res.data.columns; const columns = res.data.columns;
const _data = res.data.data; const _data = res.data.data;
@@ -291,7 +309,7 @@ watchEffect(() => {
} }
.empty-text { .empty-text {
color: #4f90ff; color: $yili-default-color;;
} }
} }
.daochubtn { .daochubtn {

View File

@@ -68,7 +68,7 @@
<div <div
class="edit-inner" class="edit-inner"
v-if="editableData[record.id]" v-if="editableData[record.id]"
@mouseleave="handleSave(record.id)" @blur="handleSave(record.id)"
> >
<div class="inner-input"> <div class="inner-input">
<a-input <a-input
@@ -86,7 +86,7 @@
<div <div
v-else v-else
style="text-align: center" style="text-align: center"
@click.stop="handleEdit(record.status, record.id)" @click.stop="handleEdit(record.status, record.id,editableData)"
> >
{{ record.title }} {{ record.title }}
</div> </div>
@@ -115,8 +115,9 @@
<template #status_str="{ text, record }"> <template #status_str="{ text, record }">
<div <div
:class="{ :class="{
pending: record.status === 0, loading: record.status === 1,
ing: record.status === 1 || record.status === 2, conduct: record.status === 2 ,
error:record.status === 4,
success: record.status === 3, success: record.status === 3,
}" }"
> >
@@ -257,7 +258,6 @@ const columns = [
key: "finished_at", key: "finished_at",
slots: { customRender: "finished_at" }, slots: { customRender: "finished_at" },
sorter: true, sorter: true,
defaultSortOrder: "descend",
align: "center", align: "center",
}, },
{ {
@@ -271,20 +271,18 @@ const columns = [
const editableData = ref({}); const editableData = ref({});
function handleInput(e, id) { function handleInput(e, id) {
const splitValue = e.target.value.replace(/_/g, ""); const splitValue = e.target.value;
if (splitValue) {
editableData.value[id].title = splitValue; editableData.value[id].title = splitValue;
} else {
editableData.value[id].title = cloneDeep(
tableSource.value.filter((item) => item.id === id)[0].title
);
}
} }
function handleLeave(record) { function handleLeave(record) {
console.log("record", record); console.log("record", record);
} }
function handleEdit(status, key) { function handleEdit(status, key,) {
editableData.value={};
if (status === 3) { if (status === 3) {
//已完成 //已完成
editableData.value[key] = cloneDeep( editableData.value[key] = cloneDeep(
@@ -301,6 +299,16 @@ function handleSave(key) {
delete editableData.value[key]; delete editableData.value[key];
return; return;
} }
if(!(title && title.replaceAll(" ","") && title.length <20)){
editableData.value[key] = cloneDeep(
tableSource.value.filter((item) => item.id === key)[0]
);
delete editableData.value[key];
message.error("标题格式有误");
return;
}
updateTitle( updateTitle(
sn, sn,
editableData.value[key].id, editableData.value[key].id,
@@ -354,8 +362,7 @@ const handleAnalyse = async () => {
analysis_search_params.value.page = 1; analysis_search_params.value.page = 1;
await runResult(data); await runResult(data);
await runTableList(sn, { ...analysis_search_params.value }); await runTableList(sn, { ...analysis_search_params.value });
analysis_type.value = ""; questionIndex.value =null;
questionIndex.value = "";
}; };
// 分页修改页码 // 分页修改页码
@@ -541,6 +548,50 @@ onMounted(() => {
margin-right: 8px; margin-right: 8px;
} }
} }
.error{
color: #FF3939 ;
display: flex;
align-items: center;
justify-content: center;
.dot {
background: #FF3939 ;
width: 6px;
height: 6px;
display: block;
border-radius: 50%;
margin-right: 8px;
}
}
.conduct{
color: #32B0F6 ;
display: flex;
align-items: center;
justify-content: center;
.dot {
background: #32B0F6 ;
width: 6px;
height: 6px;
display: block;
border-radius: 50%;
margin-right: 8px;
}
}
.loading{
color: #8C8C8C ;
display: flex;
align-items: center;
justify-content: center;
.dot {
background: #8C8C8C ;
width: 6px;
height: 6px;
display: block;
border-radius: 50%;
margin-right: 8px;
}
}
.edit-inner { .edit-inner {
display: flex; display: flex;
align-items: center; align-items: center;

View File

@@ -19,7 +19,7 @@
<a-input-number <a-input-number
block block
:min="3" :min="3"
:max="infoConfig.options?.[0]?.length" :max="(infoConfig.options?.[0]?.length || 4 )-1"
class="input-number BPTO-footer-title" class="input-number BPTO-footer-title"
v-model:value="infoConfig.config.concept" v-model:value="infoConfig.config.concept"
@change="conceptInput(infoConfig.config.concept)" @change="conceptInput(infoConfig.config.concept)"
@@ -74,6 +74,7 @@
</span> </span>
<div class="right-btn ml-8"> <div class="right-btn ml-8">
<span> <span>
{{infoConfig.options[0].length }}{{ infoConfig.config.concept}}
<a-button <a-button
type="primary" type="primary"
@click="create" @click="create"
@@ -267,7 +268,6 @@ export default {
if (loading.value === false) { if (loading.value === false) {
loading.value = true; loading.value = true;
debugger;
message.info( message.info(
`该参数组合下建议您样本量不小于${Number.parseInt( `该参数组合下建议您样本量不小于${Number.parseInt(
500 / (infoConfig.value.config.concept * infoConfig.value.config.task) 500 / (infoConfig.value.config.concept * infoConfig.value.config.task)
@@ -297,7 +297,6 @@ export default {
}; };
const onInput = (name, value, isupdate) => { const onInput = (name, value, isupdate) => {
debugger;
if (!isupdate) { if (!isupdate) {
if (infoConfig.value.config[name] <= 0) { if (infoConfig.value.config[name] <= 0) {
infoConfig.value.config[name] = props.info.config[name]; infoConfig.value.config[name] = props.info.config[name];

View File

@@ -376,7 +376,7 @@ export function newQuesType (type, param) {
const initMaxdiff = () => { const initMaxdiff = () => {
result.options = [[]]; result.options = [[]];
for (let index1 = 1; index1 <= 3; index1++) { for (let index1 = 1; index1 <= 4; index1++) {
const maxdiff_option_config2 = new Option(); const maxdiff_option_config2 = new Option();
maxdiff_option_config2.option_index = index1; maxdiff_option_config2.option_index = index1;
maxdiff_option_config2.option = `<p>选项${index1}</p>`; maxdiff_option_config2.option = `<p>选项${index1}</p>`;
@@ -385,7 +385,7 @@ export function newQuesType (type, param) {
}; };
result.options[0].push(maxdiff_option_config2); result.options[0].push(maxdiff_option_config2);
} }
result.last_option_index = 2; result.last_option_index = 4;
} }
const init3D = () => { const init3D = () => {
result.last_option_index = 0; result.last_option_index = 0;

View File

@@ -139,7 +139,7 @@
<a-radio :value="false" :disabled="true" /> <a-radio :value="false" :disabled="true" />
</div> </div>
</template> </template>
<div class="delete" v-if="optionList.length > 3"> <div class="delete" v-if="optionList.length > 4">
<div @click="onRemove(item)"> <div @click="onRemove(item)">
<a>删除</a> <a>删除</a>
</div> </div>
@@ -319,9 +319,11 @@ export default {
}; };
optionList.value.push(newOption); optionList.value.push(newOption);
copyInfo.value.options[0] = optionList.value; copyInfo.value.options[0] = optionList.value;
copyInfo.value.config.task = Number.parseInt(
(optionList.value.length * 3) / copyInfo.value.config.concept
);
emitInfo(true); emitInfo(true);
}; };
const onUpLoadChange = (value) => { const onUpLoadChange = (value) => {
console.log("onUpLoadChange", value); console.log("onUpLoadChange", value);
value.forEach((element) => { value.forEach((element) => {
@@ -601,7 +603,7 @@ export default {
copyInfo.value.config["first_text"] = props.info.config["first_text"]; copyInfo.value.config["first_text"] = props.info.config["first_text"];
copyInfo.value.config["second_text"] = props.info.config["second_text"]; copyInfo.value.config["second_text"] = props.info.config["second_text"];
columns.value = getAnswerStyle(config.value.answer_style); columns.value = getAnswerStyle(config.value.answer_style);
message.error("标题不能相"); message.error("标题不能相");
return; return;
} }
emitInfo(isupdateV); emitInfo(isupdateV);

View File

@@ -165,6 +165,7 @@ import { useRoute } from "vue-router";
import ModelSuccess from "../../components/config/ModelSuccess.vue"; import ModelSuccess from "../../components/config/ModelSuccess.vue";
import ModelError from "../../components/config/ModelError.vue"; import ModelError from "../../components/config/ModelError.vue";
import { message, Modal } from "ant-design-vue"; import { message, Modal } from "ant-design-vue";
import moment from "moment";
//import Tooltip from "../Tooltip.vue"; //import Tooltip from "../Tooltip.vue";
export default { export default {
props: { props: {
@@ -316,7 +317,7 @@ export default {
{ {
type: 6, type: 6,
}, },
"生成设计模板.xlsx" "MXD生成设计模板.xlsx"
); );
}; };
@@ -400,7 +401,7 @@ export default {
url: copyConfig.value.config.file_url, url: copyConfig.value.config.file_url,
// sn: route.query.sn, // sn: route.query.sn,
// question_index: copyConfig.value.question_index // question_index: copyConfig.value.question_index
}); },`MXD生产设计_${ moment().format("YYYYMMDDHHmmss")}.xlsx`);
// infoConfig.value.config.file_name = data.data.config.file_name; // infoConfig.value.config.file_name = data.data.config.file_name;
// infoConfig.value.config.file_url = data.data.config.file_url; // infoConfig.value.config.file_url = data.data.config.file_url;

View File

@@ -186,7 +186,7 @@ export function cbc_shelves_import(params) {
/* Maxdiff导出设计*/ /* Maxdiff导出设计*/
const mxd_export = async (params) => { const mxd_export = async (params,name) => {
const url = params.url; const url = params.url;
// await request({ // await request({
// url: `/console/surveys/${params.sn}/questions/${params.question_index}/mxd_export`, // url: `/console/surveys/${params.sn}/questions/${params.question_index}/mxd_export`,
@@ -203,7 +203,8 @@ const mxd_export = async (params) => {
withCredentials: false, withCredentials: false,
responseType: 'arraybuffer' responseType: 'arraybuffer'
}) })
fileDownload(data, "", 'application/vnd.ms-excel');
fileDownload(data, name, 'application/vnd.ms-excel');
} }

View File

@@ -637,8 +637,9 @@ export default defineComponent({
verifyCode: data.verify, verifyCode: data.verify,
} }
const res = await store.dispatch('redpacket/offeringPrizes', subData) const res = await store.dispatch('redpacket/offeringPrizes', subData)
if (res.error_code === 0) { if (res.code === 0) {
message.success(res.message); // message.success(res.message);
message.success('操作成功');
actLists() actLists()
loading.value = true loading.value = true
const data = await store.dispatch('DocumentLibraryApi/getKey') const data = await store.dispatch('DocumentLibraryApi/getKey')