<template> <div class="h-full w-full flex"> <LeftMenu v-model:active="menuActive" :menus="menus" @change="menuChange" /> <div class="flex-1 h-full overflow-y-auto p-4"> <template v-if="!menuActive"> <div v-for="(item, index) in menus.slice(1)" :key="index"> <template v-if="item.content && item.content != '<p><br></p>'"> <div class="font-bold mt-2 mb-2">{{ item.title }}:</div> <div class="p-4 bg-gray-50 rounded"> <div v-html="item.content"></div> </div> </template> </div> <el-empty v-if=" !menus .slice(1) .filter(v => v.content && v.content != '<p><br></p>').length " :image="emptyImg" class="" > <template #description> <el-button v-if="menus[1]" type="primary" link plain @click=" menuActive = 1; menuChange(1, menus[1]); " >暂未填写,去填写</el-button > </template> </el-empty> </template> <template v-else-if="menuActive"> <Editor v-model:value="menus[menuActive].content" :key="menuActive" /> </template> <template v-if="menuActive"> <div class="flex justify-end py-4"> <el-popconfirm title="是否确认清空内容?" @confirm="menus[menuActive].content = ''" > <template #reference> <el-button type="warning" plain>清空内容</el-button> </template> </el-popconfirm> <el-button type="primary" plain @click=" menuActive = 0; menuChange(0, menus[0]); " >去预览</el-button > </div> <div class="p-4 rounded bg-gray-50"> <div class="flex items-center space-x-2"> <span class="font-bold">系统建议:</span> <el-input v-model.trim="searchVal" clearable placeholder="请输入标题搜索" class="w-fit" ></el-input> <el-button type="primary">搜索</el-button> </div> <div class="space-y-4 pt-6"> <el-collapse v-model="collapseActive" accordion class="py-4" @change="collapseChange" > <!-- v-for="(item, index) in menus[menuActive]?.articleList" --> <div v-for="(item, index) in filterArticleList" :key="index" class="bg-white px-4 py-2 rounded flex items-center" > <CirclePlusFilled class="w-6 cursor-pointer text-blue-500 mr-4" @click="addArticle(item)" /> <el-collapse-item :name="index" class="flex-1"> <template #title> <div class="font-bold"> {{ item.label }} </div> </template> <div class="flex-1"> <div class="text-gray-500"> <div v-html="item.content"></div> </div> </div> </el-collapse-item> </div> </el-collapse> <!-- <el-collapse-item title="Consistency" name="1"></el-collapse-item> --> </div> </div> </template> </div> </div> </template> <script setup> import { computed, watch, markRaw, ref, inject, onMounted, provide, defineAsyncComponent, nextTick } from "vue"; import { useRoute, useRouter } from "vue-router"; import emptyImg from "@/assets/icon-empty-left.png"; import LeftMenu from "./LeftMenu.vue"; import { Search, CirclePlusFilled } from "@element-plus/icons-vue"; import Editor from "@/components/Editor.vue"; import { request, deduplicateArrayByKeys } from "@/utils"; const getArticle = inject("getArticle"); const getNodeRelationship = inject("getNodeRelationship"); const getBatchNodeRelationships = inject("getBatchNodeRelationships"); const parentState = inject("parentState"); const diseaseMangeNode = inject("diseaseMangeNode"); const updateStateValueForKey = inject("updateStateValueForKey"); const menus = ref([]); watch( () => menus.value, () => { updateStateValueForKey( "personalizeInterventions", menus.value .filter(v => v.id) .map(v => { return { id: v.id, title: v.label, content: v.content }; }) ); }, { deep: true } ); const menuActive = ref(0); const searchVal = ref(""); const filterArticleList = computed(() => menus.value[menuActive.value].articleList.filter(v => v.label.includes(searchVal.value) ) ); const waitDefaultAppend = []; const init = async () => { const personalizeInterventions = parentState.value.personalizeInterventions; let articleList = await getNodeRelationship( diseaseMangeNode.value, "干预方式" ); articleList = articleList .map(v => { return { id: v.mId, label: v.mProperties.name, articleId: v.mProperties["文章ID"] }; }) .sort((a, b) => a.sort - b.sort); let temp = await getBatchNodeRelationships( articleList.map(v => v.id).join(), "类别属于" ); await Promise.all( parentState.value.etiologies .filter(v => v.id) .map(async v => { const data = await getNodeRelationship(v.id, "推荐干预方式"); waitDefaultAppend.push( ...(data || []).map(v => { return { id: v.mId, label: v.mProperties.name, articleId: v.mProperties["文章ID"] }; }) ); }) ); let classify = []; temp.forEach(async v => { let findClassify = classify.find(v2 => v2.id == v.mId); // let findArticle = waitDefaultAppend.find(v2 => v.nId == v2.id)?.articleId || '' // let appendContent = findArticle ? await getArticle(findArticle).content : '' let appendContent = ""; if (findClassify) { findClassify.articleList.push(articleList.find(v2 => v2.id == v.nId)); findClassify.content += appendContent; } else { classify.push({ id: v.mId, label: v.mProperties.name, title: v.mProperties.name, content: (personalizeInterventions.find(v2 => v2.id == v.mId)?.content || "") + appendContent, articleList: [articleList.find(v2 => v2.id == v.nId)], sort: v.mProperties["排序"] }); } }); // temp = temp.map(v => { // return { // id: v.mId, // label: v.mProperties.name, // title: v.mProperties.name, // content: personalizeInterventions.find(v2 => v2.id == v.mId)?.content || "", // articleList: [], // sort: v.mProperties["排序"] // }; // }).forEach(v => { // }) // .sort((a, b) => a.sort - b.sort) // deduplicateArrayByKeys(, ['id']) menus.value = classify.sort((a, b) => a.sort - b.sort); menus.value = [{ label: "干预方案预览", fixed: true }, ...menus.value]; // console.log(); // menus.value = data // .map(v => { // return { // id: v.mId, // label: v.mProperties.name, // title: v.mProperties.name, // content: personalizeInterventions.find(v2 => v2.id == v.mId)?.content || "", // articleList: [], // sort: v.mProperties["排序"] // }; // }) // .sort((a, b) => a.sort - b.sort); // menus.value = [{ label: "干预方案预览", fixed: true }, ...menus.value]; }; init(); const menuChange = async (i, menu) => { if (menu.id && !menu.articleList.length) { const data = await getNodeRelationship(menu.id, "干预方式"); menu.articleList = (data || []).map(v => { return { id: v.mId, label: v.mProperties.name, articleId: v.mProperties["文章ID"], content: "" }; }); } searchVal.value = ""; }; const collapseActive = ref(); const collapseChange = async idx => { if ( idx != undefined && !menus.value[menuActive.value].articleList[idx].content ) { const detail = await getArticle( menus.value[menuActive.value]?.articleList[idx].articleId ); menus.value[menuActive.value].articleList[idx].content = detail.content; } }; const addArticle = async item => { if (!item.content) { const detail = await getArticle(item.articleId); item.content = detail.content; } menus.value[menuActive.value].content += item.content; }; </script> <style lang="scss" scoped></style>