Files
ylst-pc/src/views/planetDesign/Logical/Index.vue
2022-12-05 15:45:14 +08:00

563 lines
15 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div class="logical">
<div class="logical-bar">
<div class="catalog">
<div style="padding: 0 12px 12px 12px">
<a-input
class="custom-input"
style="height: 32px"
allowClear
v-model:value="searchName"
placeholder="请输入题目名"
@change="searchInputHandle"
>
<template #prefix>
<i class="iconfont" style="color: #bfbfbf">&#xe6df;</i>
</template>
</a-input>
</div>
<div class="catalog-main scrollbar" outside="true">
<template v-if="contentLoading">
<div class="catalog-loading" v-show="contentLoading">
<a-spin />
</div>
</template>
<template v-else>
<div v-for="(item, itemIndex) in quesList" :key="itemIndex">
<div class="catalog-page">
{{ itemIndex + 1 }}{{ item.name }}
</div>
<template v-for="child in item.child" :key="child.id">
<a-tooltip>
<template #title>
<div v-html="child.stem"></div>
</template>
<div class="catalog-text" @click="skipToHandle(child)">
<i
class="iconfont catalog-text-icon"
:class="{
'iconfont-active': child.logics_has,
}"
style="margin-right: 8px"
v-html="getIcon(child)"
></i>
<span class="catalog-text-span">{{ child.title }}</span>
<p
v-show="![-1, -2, -3].includes(child.id)"
v-html="nodeHandle(child.stem)"
></p>
</div>
</a-tooltip>
</template>
<div class="catalog-line"></div>
</div>
</template>
</div>
</div>
</div>
<div class="logical-content" id="logicalContent">
<div class="logical-scroll" v-show="!contentLoading">
<div class="logical-content-main">
<div class="logical-content-main-title">
<div v-show="iframeShow" class="flex-align">
<span class="logical-iframe-main-title-line"></span>
<span style="font-size: 16px">逻辑预览</span>
</div>
<ModelMenuTitle
v-show="!iframeShow"
:titles="logicTitles"
:posLeft="100"
:lineWidth="60"
@check="
(e) => {
title = e.flag;
}
"
/>
<div style="flex: 1">
<div class="logical-content-main-show" @click="toLogicShow">
<i class="iconfont">&#xe766;</i>
<span>切换到{{ iframeShow ? "列表" : "预览" }}视图</span>
</div>
</div>
</div>
<div v-show="!iframeShow">
<LogicList
v-if="title === 'logic'"
:data="logicList"
:check="checQues"
/>
<RandomList v-if="title === 'random'" :data="processData" />
<!-- <RandomListV2 v-show="title === 'random'" :data="processData" /> -->
</div>
<div v-show="iframeShow">
<div class="logical-iframe" v-show="iframeShow">
<iframe
ref="iframe"
class="iframe"
name="logicalIframe"
src="static/reactFlow/index.html"
allowfullscreen="true"
/>
</div>
</div>
</div>
</div>
<div class="logical-empty" v-show="contentLoading">
<a-spin />
</div>
</div>
</div>
</template>
<script>
import { computed, ref } from "@vue/reactivity";
import ModelMenuTitle from "../../../components/ModelMenuTitle.vue";
import LogicList from "./fragment/LogicList.vue";
import RandomList from "./fragment/RandomListV2.vue";
import { useStore } from "vuex";
import {
basicQuesTypeList,
quickQuesTypeList,
advancedQuesTypeList,
} from "../../../utils/common";
import { getQuesByPages, nodeHandle } from "../Design/js/util";
import { useRoute } from "vue-router";
import { processControlQuesList } from "../api/api.js";
import { sendMessage } from "./util/util";
import { watch } from "@vue/runtime-core";
import Scroll from "../Design/js/scroll.js";
export default {
name: "logicalIndex",
components: { ModelMenuTitle, LogicList, RandomList },
setup(props, context) {
const processData = ref();
const store = useStore();
const title = ref("logic");
const contentLoading = ref(false);
const logicSrc = ref(
process.env.NODE_ENV === "production"
? `https://${window.location.host}/logic-view`
: "http://localhost:3000"
);
const logicRandomSrc = ref(
process.env.NODE_ENV === "production"
? `https://${window.location.host}/logic-view`
: "http://localhost:3000/question-groups"
);
const logicTitles = [
{
title: "逻辑列表",
flag: "logic",
},
{
title: "随机列表",
flag: "random",
},
];
const quesList = ref([]);
const oldQuesList = ref([]);
const {
logicList,
checQues,
searchName,
skipToHandle,
getIcon,
searchInputHandle,
} = domEventHandle(store, quesList, oldQuesList);
const sn = computed(() => useRoute().query.sn);
const surVeytitle = computed(
() => store.state.common.questionInfo.survey?.title || ""
);
watch(
() => store.state.common.questionInfo,
(val) => {
sendInfoToIframe(val);
// 记得要过滤掉选项隐藏的逻辑
logicList.value = JSON.parse(JSON.stringify(val?.logics || [])).filter(
(log) => log.skip_type !== 4
);
}
);
/**
* 将问题列表处理为{title: 分页开始-分页结束, child: []当前分页包含的所有题}
*/
const pageHandle = (dealQuestion) => {
const introduce = [
{
id: -1,
stem: "问卷标题",
title: "问卷标题",
flag: "title",
},
{
id: -2,
stem: "介绍语",
title: "介绍语",
flag: "introduce",
},
];
dealQuestion[0].unshift(...introduce);
const result = [];
dealQuestion.forEach((ques) => {
result.push({
name: `${ques[0]?.title || ""} ~ ${
ques[ques.length - 1]?.title || ""
}`,
child: ques,
});
});
result.push({
name: "结束语",
child: [{ id: -3, stem: "结束语", title: "结束语", flag: "end" }],
});
quesList.value = result;
oldQuesList.value = result;
};
const getQuestions = async () => {
contentLoading.value = true;
try {
const { data } = await processControlQuesList(sn.value);
data.survey.pages = data.survey.pages || [[]];
const combineList = getQuesByPages(data.questions, data.survey.pages);
data.questions = combineList;
store.commit(
"common/A_COMMON_SET_QUESTIONINFO",
JSON.stringify({
logics: data.logics,
questions: data.questions,
survey: data.survey,
})
);
store.commit("common/M_COMMON_SET_SURVEY_STATUS", data.survey.status);
store.commit(
"common/A_COMMON_SET_QUESSAVEPARAM",
JSON.stringify({
newLogics: [],
newQuestion: [],
newSurvey: {
pages: [],
version: "",
},
})
);
pageHandle(data.deal_questions);
processData.value = data;
} catch (error) {
console.log(error);
}
contentLoading.value = false;
};
getQuestions();
const iframeShow = ref(false);
const toLogicShow = () => {
iframeShow.value = !iframeShow.value;
};
// const onSendMessage = () => {
// sendInfoToIframe(store.state.common.questionInfo);
// logicList.value = JSON.parse(
// JSON.stringify(store.state.common.questionInfo?.logics || [])
// );
// };
return {
logicSrc,
logicRandomSrc,
contentLoading,
title,
logicTitles,
logicList,
checQues,
searchName,
surVeytitle,
quesList,
getIcon,
skipToHandle,
searchInputHandle,
processData,
nodeHandle,
iframeShow,
toLogicShow,
// onSendMessage
};
},
};
/**
* 页面事件统一处理
*/
function domEventHandle(store, quesList, oldQuesList) {
const searchName = ref("");
const logicList = ref([]);
const checQues = ref({});
const skipToHandle = (element) => {
if (element.question_index) {
checQues.value = {
...element
}
new Scroll(
document.getElementById(`${element.id}`),
20,
document.querySelector(".logical-content")
).animate();
}
};
const getIcon = (item) => {
let icon = "";
if (item.flag) {
switch (item.flag) {
case "title":
icon = "&#xe6a7;";
break;
case "introduce":
icon = "&#xe6cf;";
break;
case "end":
icon = "&#xe6cf;";
break;
default:
break;
}
return icon;
}
if (item.config.quick_type === 0) {
icon =
basicQuesTypeList?.find((x) =>
x?.childTypes.includes(item?.question_type)
)?.icon || "";
if (!icon) {
icon =
quickQuesTypeList?.find((x) => x?.type === item?.question_type)
?.icon || "";
}
} else {
icon =
quickQuesTypeList?.find(
(x) => x?.quickType === item?.config?.quick_type
)?.icon || "";
}
if (!icon) {
icon =
advancedQuesTypeList?.find((x) => x?.type === item?.question_type)
?.icon || "";
}
return icon;
};
const searchInputHandle = () => {
if (searchName.value.length > 0) {
quesList.value = JSON.parse(JSON.stringify(oldQuesList.value))
.map((x) => {
x.child = x.child.filter((x) =>
`${x.title || ""}${x.stem || ""}`.includes(searchName.value)
);
return x;
})
.filter((x) => x.child.length > 0);
} else {
quesList.value = JSON.parse(JSON.stringify(oldQuesList.value));
}
};
return {
logicList,
checQues,
searchName,
skipToHandle,
getIcon,
searchInputHandle,
};
}
/**
* 将数据发送给iframe窗口
*/
function sendInfoToIframe(questionInfo) {
if (!questionInfo.logics) return;
const newQuesList = questionInfo.questions.filter((ques) => ques.id);
newQuesList.forEach((ques) => {
ques.logics = questionInfo.logics.filter(
(log) => log.question_id === ques.id
);
});
sendMessage(newQuesList);
}
</script>
<style lang="scss" scoped>
.logical {
width: 100%;
height: 100%;
display: flex;
&-bar {
width: 240px;
height: 100%;
background: #ffffff;
padding: 32px 20px;
border-right: 1px solid #f5f5f5;
.catalog {
padding: 24px 0;
padding-top: 0;
&-main {
max-height: calc(100vh - 200px);
overflow-y: auto;
}
&-page {
padding-left: 12px;
margin-top: 31px;
font-weight: bold;
color: #434343;
font-size: 14px;
}
&-text {
display: flex;
align-items: center;
margin-top: 24px;
min-height: 37px;
font-size: 13px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #434343;
cursor: pointer;
padding-left: 12px;
&-span {
word-break: keep-all;
}
&-icon {
margin-right: 10px;
}
&:hover {
background: #f5f5f5;
}
&::v-deep p {
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
text-align: center;
margin: 0;
padding: 0;
}
}
&-line {
margin-top: 24px;
height: 1px;
background: #f5f5f5;
}
&-loading {
display: flex;
justify-content: center;
height: 100%;
font-size: 13px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
}
.iconfont {
color: #000000;
}
.iconfont-active {
color: $yili-default-color;
}
}
}
&-scroll {
min-width: 815px;
background: #ffffff;
border-radius: 6px;
// padding: 20px;
min-height: 100%;
// box-shadow: 0px 0px 6px 1px rgb(0 0 0 / 10%);
.logical-content-main-title {
:deep(.logical-title .logical-title-span) {
margin-right: 0px;
}
}
}
&-empty {
min-width: 500px;
height: 100%;
background: #ffffff;
border-radius: 6px;
display: flex;
align-items: center;
justify-content: center;
}
&-content {
padding: 18px 20px 10px 16px;
overflow-y: auto;
flex: 1;
&-main {
padding-bottom: 30px;
&-title {
display: flex;
align-items: center;
min-height: 42px;
}
&-show {
display: flex;
align-items: center;
justify-content: center;
width: 139px;
height: 32px;
background: #ffffff;
border-radius: 4px 4px 4px 4px;
border: 1px solid #dfe0e3;
float: right;
cursor: pointer;
&:hover {
color: $yili-default-color;
background-color: $yili-bkg-color;
}
.iconfont {
font-size: 11px;
margin-right: 5px;
}
}
}
}
&-iframe {
height: calc(100vh - 242px);
iframe {
height: 100%;
width: 100%;
border: none;
}
&-main {
height: 100%;
&-title {
display: flex;
align-items: center;
font-size: 16px;
font-weight: 600;
color: #434343;
&-line {
width: 4px;
height: 20px;
background: $yili-default-color;
margin-right: 12px;
}
}
}
&-full {
position: absolute;
right: 10px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
top: 9px;
background: #fefefe;
border-bottom: 1px solid #eee;
width: 26px;
height: 26px;
box-shadow: 0 0 2px 1px rgb(0 0 0 / 8%);
&:hover {
background: #f4f4f4;
}
}
}
}
.flex-align {
display: flex;
align-items: center;
}
</style>