123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599 |
- <!DOCTYPE html>
- <html lang="zh-CN">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>知识图谱系统</title>
- <script src="./js/vue.js"></script>
- <link rel="stylesheet" href="./elementUI/theme-chalk/index.css">
- <script src="./elementUI/index.js"></script>
- <script src="./js/axios.js"></script>
- <!-- 引入 Day.js 库 -->
- <script src="./js/dayjs/dayjs.min.js"></script>
- <!-- 引入中文语言包 -->
- <script src="./js/dayjs/zh-cn.js"></script>
- <!-- 引入插件 localeData 用于获取星期几 -->
- <script src="./js/dayjs/localeData.js"></script>
- <!-- 引入jquery -->
- <!-- <script type="module" src="./js/home.js"></script> -->
- <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
- <!-- 引入echarts -->
- <script src="./js/echarts.min.js"></script>
- <script src="https://udify.app/embed.min.js" id="H0Nrc4d1ldWJpJaJ" defer>
- </script>
- <style>
- /*vue未加载好使隐藏页面*/
- [v-cloak] {
- display: none;
- }
- #dify-chatbot-bubble-button {
- background-color: #1C64F2 !important;
- }
- #dify-chatbot-bubble-window {
- width: 24rem !important;
- height: 40rem !important;
- }
- </style>
- <script>
- window.difyChatbotConfig = {
- token: 'H0Nrc4d1ldWJpJaJ'
- }
- </script>
- </head>
- <body>
- <div id="app" v-cloak>
- <el-container v-cloak>
- <el-header>
- <div class="logo" contenteditable="false">知识图谱系统</div>
- <div class="time">{{nowDate}}</div>
- <div class="user-area">
- <span class="icon-avatar"></span>
- <span class="user-identity">管理员</span>
- <span class="icon-dropdown-down"></span>
- </div>
- </el-header>
- <el-container>
- <el-aside :width="isCollapse?'69px':'268px'">
- <div :class="isCollapse? 'collapse-sign collapse-sign-open': 'collapse-sign collapse-sign-close'"
- @click="isCollapse=!isCollapse"></div>
- <el-menu :default-active="currentPage.id" :collapse-transition="false" :collapse="isCollapse"
- background-color="#D5E9FE" text-color="#000000" active-text-color="#FFFFFF">
- <el-submenu v-for="menu in menuData" :key="menu.id" :index="menu.id">
- <template slot="title">
- <i class="menu-label"><img :src="menu.label" alt="图标"></i>
- <span class="menu-title-text">{{menu.title}}</span>
- </template>
- <el-menu-item v-for="i in menu.children" @click="menuSelect(i)" class="submenu" :key="i.id" :index="i.id">
- <span class="submenu-text">{{i.title}}</span>
- </el-menu-item>
- </el-submenu>
- </el-menu>
- </el-aside>
- <el-main>
- <div class="tags">
- <el-tabs v-model="editableTabsValue" @tab-click="tabClick" type="card" :editable="false">
- <el-tab-pane :key="item.name" v-for="(item, index) in editableTabs" :closable="false" :label="item.title"
- :name="item.name">
- <span slot="label">
- {{item.title}}
- <i :class="item.name==currentPage.id?'icon-close-blue':'icon-close-gray'"
- @click.stop="removeTab(index)"></i>
- </span>
- </el-tab-pane>
- </el-tabs>
- <div class="padding"></div>
- </div>
- <div class="content">
- <iframe ref="iframe" v-show="currentPage.url" :src="currentPage.url" frameborder="0"></iframe>
- <el-empty v-show="!currentPage.url" description="这里什么都没有"></el-empty>
- </div>
- </el-main>
- </el-container>
- </el-container>
- <!-- 对话框 -->
- <el-dialog :title="dialogData.title" :visible.sync="dialogVisible" ref="dialogRef"
- :width="dialogData.width?dialogData.width:'686px'" height="491px" :center="false" :close-on-click-modal="false">
- <template #default>
- <div v-if="dialogData.opType=='addEntity'" class="addEntity">
- <div class="tools">
- <span>导出模板</span>
- <span>导入</span>
- <span @click="addEntityAddRow" class="add-row add-row"><span class="icon-add"></span>新增行</span>
- </div>
- <div class="content">
- <el-table border :data="tableData" style="width: 100%" height="230">
- <el-table-column type="index" label="序号" width="73"></el-table-column>
- <el-table-column prop="name" label="实体名称">
- <template slot-scope="scope">
- <el-input type="text" v-model="tableData[scope.$index].name" placeholder="请输入实体名称">
- </template>
- </el-table-column>
- <el-table-column prop="label" label="实体类型" width="152">
- <template slot-scope="scope">
- <el-select v-model="tableData[scope.$index].label" placeholder="请选择">
- <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value">
- </el-option>
- </el-select>
- </template>
- </el-table-column>
- <el-table-column label="操作" width="103">
- <template slot-scope="scope">
- <el-button @click.native.prevent="deleteRow(scope.$index,tableData)" type="text" size="small">
- 删除
- </el-button>
- </template>
- </el-table-column>
- </el-table>
- </div>
- </div>
- <div v-if="dialogData.opType=='modifyEntityName-dropdown'" class="modifyEntityName-dropdown">
- <div class="tools">
- <el-select v-model="selectedName" placeholder="请选择">
- <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value">
- </el-option>
- </el-select>
- <el-input v-model="searchInp" placeholder="请输入实体名称"></el-input>
- <el-button type="primary" @click="getNode">搜索</el-button>
- </div>
- <div class="content">
- <el-table border :data="nodeTable" style="width: 100%" height="230">
- <el-table-column type="index" label="序号" width="73"></el-table-column>
- <el-table-column prop="oldName" label="原实体名称"></el-table-column>
- <el-table-column prop="name" label="实体名称" width="152">
- <template slot-scope="scope">
- <el-input type="text" v-model="scope.row.name" placeholder="请输入实体名称">
- </template>
- </el-table-column>
- <el-table-column prop="type" label="实体类型"></el-table-column>
- <el-table-column label="操作" width="103">
- <template slot-scope="scope">
- <el-button @click.native.prevent="updateEntityName([scope.row],scope.$index)" type="text"
- size="small">
- 确认
- </el-button>
- <el-button @click.native.prevent="deleteRow(scope.$index,nodeTable)" type="text" size="small">
- 删除
- </el-button>
- </template>
- </el-table-column>
- </el-table>
- </div>
- </div>
- <!-- 下拉框删除实体 -->
- <div v-if="dialogData.opType=='deleteEntity-dropdown'" class="modifyEntityName-dropdown">
- <div class="tools">
- <el-select v-model="selectedName" placeholder="请选择">
- <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value">
- </el-option>
- </el-select>
- <el-input v-model.trim="searchInp" placeholder="请输入实体名称"></el-input>
- <el-button type="primary" @click="getNode">搜索</el-button>
- </div>
- <div class="content">
- <el-table border :data="nodeTable" style="width: 100%" height="230">
- <el-table-column type="index" label="序号" width="73"></el-table-column>
- <el-table-column prop="oldName" label="实体名称"></el-table-column>
- <el-table-column label="操作" width="160">
- <template slot-scope="scope">
- <el-button @click.native.prevent="deleteEntityFunc([scope.row.nodeId],scope.$index)" type="text"
- size="small">
- 删除
- </el-button>
- </template>
- </el-table-column>
- </el-table>
- </div>
- </div>
- <!-- 下拉新增关系 -->
- <div v-if="dialogData.opType=='addRelationship-dropdown'" class="addEntity">
- <div class="tools">
- <span>导出模板</span>
- <span>导入</span>
- <span @click="addRelationshipDropdownAddRow" class="add-row"><span class="icon-add"></span>新增行</span>
- </div>
- <div class="content">
- <el-table border :data="addRelationshipDropdown" style="width: 100%" height="250">
- <el-table-column type="index" label="序号" width="70"></el-table-column>
- <el-table-column label="起始实体类型">
- <template slot-scope="scope">
- <el-select v-model="scope.row.startLabel" placeholder="请选择">
- <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value">
- </el-option>
- </el-select>
- </template>
- </el-table-column>
- <el-table-column prop="startName" label="起始实体名称" width="150">
- <template slot-scope="scope">
- <el-autocomplete v-model.trim="scope.row.startName"
- :fetch-suggestions="(queryString,cb)=>{querySearchAsync(queryString,cb,scope.row.startLabel)}"
- @select="handleSelect($event, scope.row,'start')" placeholder="请选择起始实体"
- :popper-append-to-body="false"></el-autocomplete>
- </template>
- </el-table-column>
- <el-table-column label="目标实体类型">
- <template slot-scope="scope">
- <el-select v-model="scope.row.endLabel" placeholder="请选择">
- <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value">
- </el-option>
- </el-select>
- </template>
- </el-table-column>
- <el-table-column prop="endName" label="目标实体名称" width="150">
- <template slot-scope="scope">
- <el-autocomplete v-model.trim="scope.row.endName" placeholder="请选择起目标实体"
- :fetch-suggestions="((queryString,cb)=>{querySearchAsync(queryString,cb,scope.row.endLabel)})"
- @select="handleSelect($event, scope.row,'end')"></el-autocomplete>
- </template>
- </el-table-column>
- <el-table-column prop="relationshipType" width="170" label="关系名称">
- <template slot-scope="scope">
- <el-input type="text" v-model="scope.row.relationshipType" placeholder="请输入关系(边)名称">
- </template>
- </el-table-column>
- <el-table-column label="操作" width="100">
- <template slot-scope="scope">
- <el-button @click.native.prevent="deleteRow(scope.$index,addRelationshipDropdown)" type="text"
- size="small">
- 删除
- </el-button>
- </template>
- </el-table-column>
- </el-table>
- </div>
- </div>
- <div v-if="dialogData.opType=='modifyRelationshipName-dropdown'" class="modifyEntityName-dropdown">
- <div class="tools">
- <el-input v-model.trim="searchRelationshipName" placeholder="请输入关系名称"></el-input>
- <el-button type="primary" @click="findRelationshipType">搜索</el-button>
- </div>
- <div class="content">
- <el-table border :data="modifyRelationshipNameDropdown" style="width: 100%" height="230">
- <el-table-column type="index" label="序号" width="73"></el-table-column>
- <el-table-column prop="oldRelationshipType" label="原关系名称"></el-table-column>
- <el-table-column prop="newRelationshipType" label="修改为">
- <template slot-scope="scope">
- <el-input type="text" v-model="scope.row.newRelationshipType" placeholder="请输入关系名称">
- </template>
- </el-table-column>
- <el-table-column label="操作" width="103">
- <template slot-scope="scope">
- <el-button @click.native.prevent="updateRelationshipType(modifyRelationshipNameDropdown,scope.$index)"
- type="text" size="small">
- 确认
- </el-button>
- </template>
- </el-table-column>
- </el-table>
- </div>
- </div>
- <!-- 下拉属性新增 -->
- <div v-if="dialogData.opType=='addProperty-dropdown'" class="modifyEntityName-dropdown">
- <div class="tools-2">
- <div class="tools-2-up">
- <div class="left">
- <span>实体类型:</span>
- <el-select v-model="addPropertyDropdown.label" placeholder="请选择">
- <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value">
- </el-option>
- </el-select>
- <span style="margin-left: 10px;">实体名称:</span>
- <!-- <el-autocomplete v-model.trim="addPropertyDropdown.name"
- :fetch-suggestions="((queryString,cb)=>{querySearchAsync(queryString,cb,addPropertyDropdown.label)})"
- @select="handleSelect($event,addPropertyDropdown,'addProperty-dropdown')"
- placeholder="请输入实体名称"></el-autocomplete> -->
- <el-select class="select-entity-name" v-model.trim="addPropertyDropdown.nodeId" filterable remote
- placeholder="请输入实体名称" @change="addPropertyDropdownValueChange"
- :remote-method="((query)=>addPropertyDropdownRemoteMethod(query,addPropertyDropdown.label))"
- :loading="false">
- <el-option v-for="item in addPropertyDropdownOptions" :key="item.nodeId" :label="item.name"
- :value="item.nodeId">
- </el-option>
- </el-select>
- </div>
- <div class="right">
- <span class="blue">导出模板</span>
- <span class="blue">导出</span>
- <span @click="addPropertyDropdownAddRow()" class="blue add-row"><span class="icon-add"></span>新增行</span>
- </div>
- </div>
- <div class="tools-2-down"> <span>请添加实体:<span class="blue">{{addPropertyDropdown.name}}</span> 相关的属性值</span>
- </div>
- </div>
- <div class="content">
- <el-table border :data="addPropertyDropdown.property" style="width: 100%" height="230">
- <el-table-column type="index" label="序号" width="73"></el-table-column>
- <el-table-column prop="key" label="属性名称">
- <template slot-scope="scope">
- <el-input type="text" v-model="scope.row.key" placeholder="请输入属性名称">
- </template>
- </el-table-column>
- <el-table-column prop="value" label="属性值">
- <template slot-scope="scope">
- <el-input type="text" v-model="scope.row.value" placeholder="请输入关系名称">
- </template>
- </el-table-column>
- <el-table-column label="操作" width="103">
- <template slot-scope="scope">
- <el-button @click.native.prevent="deleteRow(scope.$index,addPropertyDropdown.property)" type="text"
- size="small">
- 删除
- </el-button>
- </template>
- </el-table-column>
- </el-table>
- </div>
- </div>
- <!-- 右键属性新增 -->
- <div v-if="dialogData.opType=='addProperty'" class="modifyEntityName-dropdown">
- <div class="tools-2">
- <div class="tools-2-up">
- <div class="left">
- <span>实体名称:{{addProperty.name}}</span>
- </div>
- <div class="right">
- <span @click="addPropertyAddRow()" class="blue add-row"><span class="icon-add"></span>新增行</span>
- </div>
- </div>
- <div class="tools-2-down"></div>
- </div>
- <div class="content">
- <el-table border :data="addProperty.property" style="width: 100%" height="230">
- <el-table-column type="index" label="序号" width="73"></el-table-column>
- <el-table-column prop="key" label="属性名称">
- <template slot-scope="scope">
- <el-input type="text" v-model="scope.row.key" placeholder="请输入属性名称">
- </template>
- </el-table-column>
- <el-table-column prop="value" label="属性值">
- <template slot-scope="scope">
- <el-input type="text" v-model="scope.row.value" placeholder="请输入关系名称">
- </template>
- </el-table-column>
- <el-table-column label="操作" width="103">
- <template slot-scope="scope">
- <el-button @click.native.prevent="deleteRow(scope.$index,addProperty.property)" type="text"
- size="small">
- 删除
- </el-button>
- </template>
- </el-table-column>
- </el-table>
- </div>
- </div>
- <!-- 删除关系 -->
- <div v-if="dialogData.opType=='deleteRelationship'" class="deleteRelationship">
- <div class="content">
- 是否确认删除{{deleteRelationship.startName}}(起始节点)→{{deleteRelationship.endName}}(目标节点)之间的关系:{{deleteRelationship.relationshipType}}
- ?
- </div>
- </div>
- <!-- 修改关系 -->
- <div v-if="dialogData.opType=='modifyRelationship'" class="modifyRelationship">
- <div class="content">
- <div class="up">原关系名称:{{modifyRelationship.oldVal}}</div>
- <div class="down">修改为:<el-input v-model.trim="modifyRelationship.newVal"></el-input></div>
- </div>
- </div>
- <!-- 修改关系实体名称-右键 -->
- <div v-if="dialogData.opType=='modifyEntityName'" class="modifyEntityName">
- <div class="content">
- <div class="up">原实体名称:{{modifyEntityName.oldName}}</div>
- <div class="center">实体名称:<el-input v-model.trim="modifyEntityName.name"></el-input></div>
- <div class="down">实体类型:
- <el-select v-model="modifyEntityName.label" placeholder="请选择">
- <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value">
- </el-option>
- </el-select>
- </div>
- </div>
- </div>
- <!-- 右键删除实体 -->
- <div v-if="dialogData.opType=='deleteEntity'" class="deleteRelationship">
- <div class="content">
- 删除实体节点提交保存后会将数据库中节点所有一层以内的关系及属性一同删除。是否确认删除实体-{{deleteEntity.name}} ?
- </div>
- </div>
- <!-- 右键删除实体属性 -->
- <div v-if="dialogData.opType=='deleteProperty'" class="deleteRelationship">
- <div class="content">
- 是否确认删除实体{{deleteProperty.name}}的属性-{{deleteProperty.propertyName}} ?
- </div>
- </div>
- <!-- //右键新增关系-->
- <div v-if="dialogData.opType=='addRelationship'" class="modifyEntityName">
- <div class="content">
- <div class="up">起始实体名称:{{addRelationship.startName}}</div>
- <div class="center">
- 目标实体类型:<el-select v-model="addRelationship.endLabel" placeholder="请选择">
- <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value">
- </el-option>
- </el-select>
- </div>
- <div class="center">
- 目标实体名称: <el-autocomplete v-model.trim="addRelationship.endName"
- :fetch-suggestions="((queryString,cb)=>{querySearchAsync(queryString,cb,addRelationship.endLabel)})"
- @select="handleSelect($event, addRelationship,'addRelationship')"
- placeholder="请输入实体名称"></el-autocomplete>
- </div>
- <div class="down">关系名称:<el-input v-model.trim="addRelationship.relationshipType"
- placeholder="请输入关系名称"></el-input>
- </div>
- </div>
- </div>
- <div v-if="dialogData.opType=='modifyProperty-dropdown'" class="modifyProperty-dropdown">
- <div class="tools">
- <el-select v-model="modifyPropertyDropdown.label" placeholder="请选择">
- <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value">
- </el-option>
- </el-select>
- <el-autocomplete v-model="modifyPropertyDropdown.name" :fetch-suggestions="querySearchAsync2"
- @select="handleSelect($event, modifyPropertyDropdown.properties,'modifyProperty-dropdown')"
- placeholder="请输入实体名称">
- </el-autocomplete>
- </div>
- <div class="content">
- <el-table border :data="modifyPropertyDropdown.properties" style="width: 100%" height="230">
- <el-table-column type="index" label="序号" width="73"></el-table-column>
- <el-table-column label="原属性名称" prop="oldPropertyName"></el-table-column>
- <el-table-column prop="key" label="属性名称" width="130">
- <template slot-scope="scope">
- <el-input type="text" v-model="scope.row.newPropertyName" placeholder="请输入属性名称">
- </template>
- </el-table-column>
- <el-table-column label="原属性值" prop="oldPropertyValue"></el-table-column>
- <el-table-column prop="value" label="属性值">
- <template slot-scope="scope">
- <el-input type="text" v-model="scope.row.newPropertyValue" placeholder="请输入属性值">
- </template>
- </el-table-column>
- <el-table-column label="操作" width="103">
- <template slot-scope="scope">
- <el-button
- @click.native.prevent="modifyPropertyDropdownConfirm(scope.$index,modifyPropertyDropdown.properties)"
- type="text" size="small">
- 确定
- </el-button>
- </template>
- </el-table-column>
- </el-table>
- </div>
- </div>
- <!-- 右键修改实体属性 -->
- <div v-if="dialogData.opType=='modifyProperty'" class="modifyEntityName">
- <div class="content">
- <div class="up">
- <span>原属性名称:{{modifyProperty.oldPropertyName}}</span>
- <span>原属性值:{{modifyProperty.oldPropertyValue}}</span>
- </div>
- <div class="center">
- 属性名称:<el-input v-model.trim="modifyProperty.newPropertyName" placeholder="请输入属性名称"></el-input>
- 属性值:<el-input v-model.trim="modifyProperty.newPropertyValue" placeholder="请输入属性值"></el-input>
- </div>
- <!-- <div class="down">
- 属性类型:<el-input v-model.trim="addRelationship.relationshipType"
- placeholder="请输入关系名称"></el-input>
- </div> -->
- </div>
- </div>
- <div v-if="dialogData.opType=='merge-entity'" class="merge-entity">
- <div class="content">
- <div class="text">
- 确认实体-{{mergeEntity.firstName}}、实体-{{mergeEntity.secondName}}是否需要合并,合并后实体的关系及属性一同合并。
- </div>
- <div class="input">
- 合并后的名称:<el-input v-model.trim="mergeEntity.newName" placeholder="请输入实体名称"></el-input>
- </div>
- </div>
- </div>
- <div v-show="dialogData.opType==='entityLink'" class="entityLink" id="entityLink">
- </div>
- </template>
- <span slot="footer" class="dialog-footer" v-show="dialogData.showFooter">
- <el-button @click="dialogVisible = false" class="cancel">取 消</el-button>
- <el-button type="primary" @click="dialogSubmit" class="confirm">确 定</el-button>
- </span>
- </el-dialog>
- </div>
- </body>
- <script>
- let myChart = null
- let timer = null //计时器标志
- const api = {
- createEntity: "/entity/createEntity",//批量新增实体
- getNode: "/kg/getNode",
- updateEntityName: "/entity/updateEntityName",
- deleteEntity: "/entity/deleteEntity",
- createRelationship: "/relationship/createRelationship",
- findRelationshipType: "/relationship/findRelationshipType", //根据名称模糊查询关系
- updateRelationshipType: "/relationship/updateRelationshipType",
- createEntityProperty: "/property/createEntityProperty", //批量新增实体属性
- deleteRelationship: "/relationship/deleteRelationship",//批量删除关系
- findEntityListByName: "/entity/findEntityListByName", //实体列表查询(根据标签和名字模糊查询实体)
- updateEntityProperty: "/property/updateEntityProperty", //更新实体属性
- deleteEntityProperty: "/property/deleteEntityProperty", //删除实体属性
- mergeEntity: "/entity/mergeEntity",//实体合并
- }
- const vm = new Vue({
- el: "#app",
- name: "home",
- data() {
- return {
- mergeEntity: { //实体合并的数据
- "firstId": -1,
- "firstLabel": "",
- "firstName": "",
- "newLabel": "",
- "newName": "",
- "secondId": -1,
- "secondLabel": "",
- "secondName": ""
- },
- dialogVisible: false,
- dialogData: { title: "提示", opType: "", showFooter: true, width: "" },
- modifyProperty: { //右键修改属性
- "label": "",
- "newPropertyName": "",
- "newPropertyValue": "",
- "nodeId": -1,
- "oldPropertyName": "",
- "oldPropertyValue": "",
- },
- modifyPropertyDropdown: { //下拉框修改属性
- name: "",
- label: "疾病",
- properties: []
- },
- deleteProperty: {//右键删除属性
- "label": "",
- "nodeId": -1,
- "name": "",
- "propertyName": ""
- },
- addRelationship: {//右键新增关系
- "endId": null,
- "endLabel": "疾病",
- "endName": "",
- "property": {},
- "relationshipType": "",
- "startId": null,
- "startLabel": "",
- "startName": ""
- },
- modifyEntityName: { // 修改关系实体名称-右键 的值
- "oldName": "",
- "name": "",
- "nodeId": -1,
- "label": "",
- },
- deleteEntity: { name: "", nodeId: "" },//右键删除实体
- deleteRelationship: {
- "endId": null,
- "endLabel": "",
- "endName": "",
- "property": {},
- "relationshipType": "",
- "startId": null,
- "startLabel": "",
- "startName": "",
- },
- entityLink: { //实体链接数据
- nodes: [],
- links: []
- },
- modifyRelationship: { oldVal: "", newVal: "" },//右键修改关系名称
- tableData: [
- { "label": "疾病", "name": "" }
- ],
- options: [
- { "label": "疾病", "value": "疾病" },
- { "label": "药品", "value": "药品" },
- { "label": "症状", "value": "症状" },
- // { "label": "手术和操作", "value": "手术和操作" },
- { "label": "实验室检查", "value": "实验室检查" },
- { "label": "辅助检查", "value": "辅助检查" },
- ],
- addPropertyDropdown: {
- "label": "疾病",
- "nodeId": null,
- "name": "",
- "property": [{ key: "", value: "" }]
- },
- addPropertyDropdownOptions: [],
- addProperty: { //右键属性新增的数据
- "label": "",
- "nodeId": -1,
- "name": "",
- "property": [{ key: "", value: "" }]
- },
- addRelationshipDropdown: [{ //下拉框添加关系
- "endId": null,
- "endName": "",
- "endLabel": "疾病",
- "property": {},
- "relationshipType": "",
- "startId": null,
- "startName": "",
- "startLabel": "疾病"
- }],
- modifyRelationshipNameDropdown: [],//下拉框的修改关系名称
- searchRelationshipName: "",
- selectedName: "",
- searchInp: "",
- nodeTable: [],
- nowDate: "", //当前的日期时间
- isCollapse: false,
- editableTabsValue: 'knowledgeGraph',
- editableTabs: [
- {
- title: '知识图谱查询',
- name: 'knowledgeGraph',
- content: './knowledgeGraph.html'
- },
- ],
- currentPage: {
- id: "knowledgeGraph",
- url: "./knowledgeGraph.html",
- title: "知识图谱查询",
- children: null
- },
- menuData: [
- {
- id: "1",
- url: "",
- title: "知识图谱查询",
- label: "/images/layer8@2x.png",
- children: [
- {
- id: "knowledgeGraph",
- url: "./knowledgeGraph.html",
- title: "知识图谱查询",
- children: null
- }
- ]
- },
- {
- id: "2",
- url: "",
- title: "图谱知识管理",
- label: "./images/layer9@2x.png",
- children: [
- {
- id: "knowledgeUpdate",
- url: "./knowledgeUpdate.html",
- title: "知识更新",
- children: null
- }
- ]
- },
- {
- id: "3",
- url: "",
- title: "系统管理",
- label: "./images/layer10@2x.png",
- children: [
- {
- id: "userManage",
- url: "",
- title: "用户管理",
- children: null
- },
- {
- id: "permissionManage",
- url: "",
- title: "权限管理",
- children: null
- }
- ]
- },
- {
- id: "4",
- url: "",
- title: "统计分析",
- label: "./images/layer11@2x.png",
- children: [
- {
- id: "graphDataStatistics",
- url: "./graphDataStatistics.html",
- title: "图谱数据统计",
- children: null
- },
- {
- id: "operationLog",
- url: "",
- title: "操作日志",
- children: null
- },
- ]
- },
- ]
- }
- },
- methods: {
- menuSelect: function (item) {
- this.currentPage = { ...item }
- const { id, title, url } = item
- this.editableTabsValue = id
- const isExist = this.editableTabs.some((el) => {
- if (el.name == id) return true;
- })
- if (!isExist) {
- this.editableTabs.push({
- name: id,
- title: title,
- content: url,
- })
- }
- },
- removeTab(tabIndex) {
- //console.log("removeTab", tabIndex)
- //判断删除的是否是当前页面
- const isActiveTab = this.editableTabs[tabIndex].name === this.editableTabsValue
- this.editableTabs.splice(tabIndex, 1)//删除当前tab页
- if (this.editableTabs.length === 0) {
- this.currentPage = {}
- return;
- }
- if (!isActiveTab) return; //不是当前页面直接结束
- if (tabIndex > 0) {
- const { title, name, content } = this.editableTabs[tabIndex - 1]
- this.currentPage.id = name
- this.currentPage.title = title
- this.currentPage.url = content
- this.editableTabsValue = name
- } else {
- const { title, name, content } = this.editableTabs[0]
- this.currentPage.id = name
- this.currentPage.title = title
- this.currentPage.url = content
- this.editableTabsValue = name
- }
- },
- tabClick(tabElement) {
- //console.log("tabClick", tabElement)
- const index = tabElement.index
- const { title, name, content } = this.editableTabs[index]
- this.currentPage.id = name
- this.currentPage.title = title
- this.currentPage.url = content
- this.editableTabsValue = name
- },
- getNowDate() {
- // 获取当前时间并格式化为 2024年12月10日/星期二/15:23 的格式
- const formattedDate = dayjs().format('YYYY年MM月DD日/星期dd/HH:mm');
- return formattedDate
- },
- sendChildWindowMessage: function (operation, data) {
- const iframe = this.$refs.iframe
- if (operation == "update-graph") {
- setTimeout(() => {
- iframe.contentWindow.postMessage({ operation, data }, "*")
- }, 1000)
- } else {
- iframe.contentWindow.postMessage({ operation, data }, "*")
- }
- },
- receiveIframeMsg() {
- const iframe = this.$refs.iframe
- window.addEventListener("message", (event) => {
- //console.log("receiveIframeMsg", event)
- const { opType } = event.data
- if (opType) {
- this.dialogData.title = event.data.title
- this.dialogData.opType = opType
- this.dialogData.showFooter = event.data.showFooter
- this.dialogData.width = event.data.width
- this.dialogVisible = event.data.dialogVisible
- if (opType == 'modifyEntityName-dropdown') {
- this.selectedName = event.data.data.selectedName
- this.searchInp = event.data.data.searchInp
- } else if (opType == 'deleteEntity-dropdown') {
- this.selectedName = event.data.data.selectedName
- this.searchInp = event.data.data.searchInp
- } else if (opType == 'deleteRelationship') {
- this.deleteRelationship = event.data.data
- } else if (opType == "modifyRelationship") {//右键修改关系名称
- this.modifyRelationship.oldVal = event.data.data.relationshipType
- } else if (opType == "modifyEntityName") { //右键修改实体名称
- this.modifyEntityName.oldName = event.data.data.properties.name
- this.modifyEntityName.nodeId = event.data.data.nodeId
- this.modifyEntityName.label = event.data.data.type
- } else if (opType == "deleteEntity") { //右键删除实体
- this.deleteEntity.name = event.data.data.properties.name
- this.deleteEntity.nodeId = event.data.data.nodeId
- } else if (opType == 'addRelationship') { //右键新增关系
- this.addRelationship.startId = event.data.data.nodeId
- this.addRelationship.startName = event.data.data.properties.name
- this.addRelationship.startLabel = event.data.data.type
- } else if (opType == 'addProperty') { //右键新增属性
- this.addProperty.nodeId = event.data.data.nodeId
- this.addProperty.name = event.data.data.properties.name
- this.addProperty.label = event.data.data.type
- } else if (opType == 'deleteProperty') { //右键删除属性
- this.deleteProperty.nodeId = event.data.data.nodeId
- this.deleteProperty.label = event.data.data.type
- this.deleteProperty.name = event.data.data.properties.parentName
- this.deleteProperty.propertyName = event.data.data.properties.name
- } else if (opType === 'modifyProperty') { //右键修改属性
- this.modifyProperty.label = event.data.data.type
- this.modifyProperty.oldPropertyName = event.data.data.properties.name
- this.modifyProperty.oldPropertyValue = event.data.data.properties.value
- this.modifyProperty.nodeId = event.data.data.nodeId
- } else if (opType === 'merge-entity') { //实体合并
- this.mergeEntity = { ...event.data.data }
- } else if (opType == 'entityLink') { //实体链接
- this.entityLink = { ...this.$options.data().entityLink }
- this.entityLink.categories = event.data.data.categories
- event.data.data.entityNode.forEach((el, index) => {
- el.name = index
- el.symbolSize = 80
- el.symbol = 'circle'
- el.itemStyle = {}
- this.entityLink.nodes.push(el)
- })
- this.$nextTick(() => {
- this.drawGraph()
- })
- } else if (opType == "addRelationship-dropdown") {
- this.dialogData.width = '900px'
- } else if (opType == "addProperty-dropdown") {
- this.dialogData.width = '800px'
- }
- }
- })
- },
- addEntityAddRow() {
- this.tableData.push({ "label": "疾病", "name": "" })
- },
- deleteRow(index, tableData) {
- tableData.splice(index, 1)
- },
- dialogSubmit() {
- switch (this.dialogData.opType) {
- case "addEntity":
- axios.post("/api" + api.createEntity, this.tableData).then((res) => {
- //console.log("createEntity", res.data)
- if (res.data.code == '0') {
- //重置this.tableData的数据
- this.tableData = [...this.$options.data().tableData]
- this.dialogVisible = false
- this.sendChildWindowMessage("update-graph", "")
- }
- }).catch(err => {
- console.log("createEntity接口出错", err)
- })
- break
- case "modifyEntityName-dropdown":
- this.updateEntityName(this.nodeTable, -1)
- break
- case "addRelationship-dropdown":
- axios.post("/api" + api.createRelationship, this.addRelationshipDropdown).then(res => {
- const { msg, code, data } = res.data
- if (res.data.code == '0') {
- this.addRelationshipDropdown = [...this.$options.data().addRelationshipDropdown]
- //console.log("addRelationshipDropdown", this.$options.data().addRelationshipDropdown)
- this.dialogVisible = false
- this.sendChildWindowMessage("update-graph", "")
- }
- }).catch(err => {
- console.log("createRelationship接口错误", err)
- })
- break
- case 'addProperty-dropdown':
- const data = [
- {
- "label": "string",
- "nodeId": 0,
- "property": {}
- }
- ]
- data[0].label = this.addPropertyDropdown.label
- data[0].nodeId = this.addPropertyDropdown.nodeId
- this.addPropertyDropdown.property.forEach(el => {
- data[0].property[el.key] = el.value
- })
- axios.post("/api" + api.createEntityProperty, data).then(res => {
- const { msg, code, data } = res.data
- if (res.data.code == '0') {
- //this.addPropertyDropdown.property = []
- //this.dialogVisible = false
- this.addPropertyDropdown = { ...this.$options.data().addPropertyDropdown }
- this.sendChildWindowMessage("update-graph", "")
- }
- }).catch(err => {
- console.log("createEntityProperty接口错误", err)
- })
- break
- case 'deleteRelationship': //删除关系
- axios.post("/api" + api.deleteRelationship, [this.deleteRelationship]).then(res => {
- const { msg, code, data } = res.data
- if (res.data.code == '0') {
- this.dialogVisible = false
- this.sendChildWindowMessage("update-graph", "")
- }
- }).catch(err => {
- console.log("createEntityProperty接口错误", err)
- })
- break
- case "modifyRelationship": //右键修改关系
- axios.post("/api" + api.updateRelationshipType, [{
- "newRelationshipType": this.modifyRelationship.newVal,
- "oldRelationshipType": this.modifyRelationship.oldVal
- }]).then(res => {
- const { data, msg, code } = res.data
- if (code == '0') {
- this.modifyRelationship = { ...this.$options.data().modifyRelationship }
- //this.tableData.splice(index, 1)
- this.sendChildWindowMessage("update-graph", "")
- this.dialogVisible = false
- }
- }).catch(err => {
- console.log("updateRelationshipType接口出错", err)
- })
- break
- case "modifyEntityName":
- axios.post("/api" + api.updateEntityName, [this.modifyEntityName]).then(res => {
- const { data, msg, code } = res.data
- if (code == '0') {
- this.dialogVisible = false
- this.modifyEntityName = { ...this.$options.data().modifyEntityName }
- this.sendChildWindowMessage("update-graph", "")
- }
- }).catch(err => {
- console.log("updateEntityName接口出错", err)
- })
- break
- case "deleteEntity":
- axios.post("/api" + api.deleteEntity, [this.deleteEntity.nodeId]).then(res => {
- const { data, msg, code } = res.data
- if (code == '0') {
- this.deleteEntity = { ...this.$options.data().deleteEntity }
- this.dialogVisible = false
- this.sendChildWindowMessage("update-graph", "")
- }
- }).catch(err => {
- console.log("deleteEntity接口出错", err)
- })
- break
- case "addRelationship": //右键新增关系
- axios.post("/api" + api.createRelationship, [this.addRelationship]).then(res => {
- const { msg, code, data } = res.data
- if (res.data.code == '0') {
- this.addRelationship = { ...this.$options.data().addRelationship }
- this.dialogVisible = false
- this.sendChildWindowMessage("update-graph", "")
- }
- }).catch(err => {
- console.log("createRelationship接口错误", err)
- })
- break
- case "addProperty":
- const addPropertyTemp = [
- {
- "label": "string",
- "nodeId": 0,
- "property": {}
- }
- ]
- addPropertyTemp[0].label = this.addProperty.label
- addPropertyTemp[0].nodeId = this.addProperty.nodeId
- this.addProperty.property.forEach(el => {
- addPropertyTemp[0].property[el.key] = el.value
- })
- axios.post("/api" + api.createEntityProperty, addPropertyTemp).then(res => {
- const { msg, code, data } = res.data
- if (res.data.code == '0') {
- this.addProperty.property = [{ kye: "", value: "" }]
- this.dialogVisible = false
- this.sendChildWindowMessage("update-graph", "")
- }
- }).catch(err => {
- console.log("createEntityProperty接口错误", err)
- })
- break
- case "deleteProperty":
- axios.post("/api" + api.deleteEntityProperty, [this.deleteProperty]).then(res => {
- const { msg, code, data } = res.data
- if (res.data.code == '0') {
- this.deleteProperty = {}
- this.dialogVisible = false
- this.sendChildWindowMessage("update-graph", "")
- }
- }).catch(err => {
- console.log("deleteEntityProperty接口错误", err)
- })
- break
- case "modifyProperty"://右键修改属性
- axios.post("/api" + api.updateEntityProperty, this.modifyProperty).then(res => {
- const { data, msg, code } = res.data
- if (code == '0') {
- this.dialogVisible = false
- this.sendChildWindowMessage("update-graph", "")
- }
- }).catch(err => {
- console.log("updateEntityProperty接口出错", err)
- })
- break
- case "merge-entity":
- axios.post("/api" + api.mergeEntity, this.mergeEntity).then(res => {
- const { data, msg, code } = res.data
- if (code == '0') {
- this.dialogVisible = false
- this.sendChildWindowMessage("update-graph", "")
- }
- }).catch(err => {
- console.log("mergeEntity接口出错", err)
- })
- break
- case "entityLink":
- const relationshipList = []
- this.entityLink.links.forEach((el) => {
- relationshipList.push({
- "endId": this.entityLink.nodes[el.target].nodeId,
- "endLabel": this.entityLink.nodes[el.target].type,
- "property": {},
- "relationshipType": el.value,
- "startId": this.entityLink.nodes[el.source].nodeId,
- "startLabel": this.entityLink.nodes[el.source].type
- })
- })
- axios.post("/api" + api.createRelationship, relationshipList).then(res => {
- const { msg, code, data } = res.data
- if (res.data.code == '0') {
- this.dialogVisible = false
- this.sendChildWindowMessage("update-graph", "")
- return
- }
- }).catch(err => {
- console.log("createRelationship接口错误", err)
- })
- break
- default:
- this.dialogVisible = false
- this.sendChildWindowMessage("update-graph", "")
- }
- },
- addPropertyDropdownValueChange(value) {
- for (let i = 0; i < this.addPropertyDropdownOptions.length; i++) {
- const option = this.addPropertyDropdownOptions[i]
- if (option.nodeId === value) {
- this.addPropertyDropdown.name = option.name
- break
- }
- }
- // this.addPropertyDropdownOptions
- },
- addPropertyDropdownRemoteMethod(name, label) {
- axios.post("/api" + api.getNode, {
- "inputStr": name,
- "labelName": label
- }).then(res => {
- const { msg, code, data } = res.data
- if (code == '0') {
- this.addPropertyDropdownOptions = data
- // data.forEach((el, index) => {
- // this.addPropertyDropdownOptions.push(
- // { oldName: el.name, name: "", nodeId: el.nodeId, type: el.label })
- // })
- }
- }).catch(err => {
- console.log("addPropertyDropdownRemoteMethod的getNode接口出错了", err)
- })
- },
- getNode() {
- axios.post("/api" + api.getNode, {
- "inputStr": this.searchInp,
- "labelName": this.selectedName
- }).then(res => {
- const { msg, code, data } = res.data
- if (code == '0') {
- this.nodeTable = []
- data.forEach((el, index) => {
- this.nodeTable.push(
- { oldName: el.name, name: "", nodeId: el.nodeId, type: el.label })
- })
- }
- }).catch(err => {
- console.log("getNode接口出错了", err)
- })
- },
- updateEntityName(data, index) {
- this.$confirm("确定修改实体名称吗?", "修改实体名称提示", {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
- type: 'warning'
- }).then(() => {
- axios.post("/api" + api.updateEntityName, data).then(res => {
- const { data, msg, code } = res.data
- if (code == '0') {
- if (index >= 0) {
- this.nodeTable.splice(index, 1)
- } else {
- //this.nodeTable = []
- this.nodeTable.splice(0, this.nodeTable.length)
- }
- this.sendChildWindowMessage("update-graph", "")
- }
- }).catch(err => {
- console.log("updateEntityName接口出错", err)
- })
- }).catch(err => {
- })
- },
- deleteEntityFunc(data, index) {
- this.$confirm('确定删除该实体吗?', '删除实体提示', {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
- type: 'warning'
- }).then(() => {
- axios.post("/api" + api.deleteEntity, data).then(res => {
- const { data, msg, code } = res.data
- if (code == '0') {
- if (index >= 0) {
- this.nodeTable.splice(index, 1)
- } else {
- this.nodeTable.splice(0, this.nodeTable.length)
- }
- this.sendChildWindowMessage("update-graph", "")
- }
- }).catch(err => {
- console.log("deleteEntity接口出错", err)
- })
- }).catch(err => {
- })
- },
- addRelationshipDropdownAddRow() {
- this.addRelationshipDropdown.push(this.$options.data().addRelationshipDropdown[0])
- },
- querySearchAsync(queryString, cb, label) {
- //console.log("label", label)
- axios.post("/api" + api.getNode, {
- "inputStr": queryString,
- "labelName": label || "疾病"
- }).then(res => {
- const { msg, code, data } = res.data
- if (code == '0') {
- var restaurants = []
- data.forEach((el, index) => {
- restaurants.push(
- { value: el.name, nodeId: el.nodeId, label: el.label })
- })
- cb(restaurants)
- }
- }).catch(err => {
- console.log("querySearchAsync的getNode接口出错了", err)
- })
- },
- querySearchAsync2(query, cb) {
- if (!query) {
- cb([])
- return
- }
- axios.post("/api" + api.findEntityListByName, {
- "label": this.modifyPropertyDropdown.label,
- "name": query
- }).then(res => {
- const { msg, code, data } = res.data
- if (code == '0') {
- var restaurants = []
- data.forEach((el, index) => {
- restaurants.push(
- { value: el.properties.name, nodeId: el.id, label: el.labels[0], properties: el.properties })
- })
- cb(restaurants)
- }
- }).catch(err => {
- console.log("findEntityListByName的getNode接口出错了", err)
- })
- },
- handleSelect(item, row, flag) {
- if (flag == 'start') {
- row.startId = item.nodeId
- row.startLabel = item.label
- } else if (flag == 'end') {
- row.endId = item.nodeId
- row.endLabel = item.label
- } else if (flag == 'addProperty-dropdown') { //下拉框新增属性
- row.label = item.label
- row.nodeId = item.nodeId
- this.addPropertyDropdown.property = []
- this.addPropertyDropdownAddRow()
- } else if (flag == 'addRelationship') {
- row.endLabel = item.label
- row.endId = item.nodeId
- } else if (flag == 'modifyProperty-dropdown') { //下拉修改属性
- row.splice(0, row.length)
- for (let i in item.properties) {
- if (i == 'name' || i == 'is_deleted') continue;
- const property = {
- "label": item.label,
- "name": item.value,
- "newPropertyName": "",
- "newPropertyValue": "",
- "nodeId": item.nodeId,
- "oldPropertyName": i,
- "oldPropertyValue": item.properties[i],
- }
- row.push(property)
- }
- }
- //console.log("handleSelect-2", item, row, flag);
- },
- findRelationshipType() {
- axios.post("/api" + api.findRelationshipType, { "relationshipType": this.searchRelationshipName }).then(res => {
- const { data, msg, code } = res.data
- if (code === '0') {
- this.modifyRelationshipNameDropdown = []
- data.forEach((el, index) => {
- this.modifyRelationshipNameDropdown.push({
- "newRelationshipType": "",
- "oldRelationshipType": el
- })
- })
- }
- }).catch(err => {
- console.log("findRelationshipType接口出错了", err)
- })
- },
- updateRelationshipType(tableData, index) {
- this.$confirm('确定修改此关系名称吗?', '提示', {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
- type: 'warning'
- }).then(() => {
- axios.post("/api" + api.updateRelationshipType, [tableData[index]]).then(res => {
- const { data, msg, code } = res.data
- if (code == '0') {
- tableData.splice(index, 1)
- this.sendChildWindowMessage("update-graph", "")
- }
- }).catch(err => {
- console.log("updateRelationshipType接口出错", err)
- })
- }).catch(() => {
- });
- },
- addPropertyDropdownAddRow() {
- this.addPropertyDropdown.property.push(this.$options.data().addPropertyDropdown.property[0])
- },
- addPropertyAddRow() {
- this.addProperty.property.push({ key: "", value: "" })
- },
- modifyPropertyDropdownConfirm(index, tableData) {
- this.$confirm('确定修改此属性吗?', '提示', {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
- type: 'warning'
- }).then(() => {
- axios.post("/api" + api.updateEntityProperty, tableData[index]).then(res => {
- const { data, msg, code } = res.data
- if (code == '0') {
- tableData.splice(index, 1)
- this.sendChildWindowMessage("update-graph", "")
- }
- }).catch(err => {
- console.log("updateEntityProperty接口出错")
- })
- }).catch(() => {
- });
- },
- drawGraph() {
- if (myChart) {
- myChart.dispose();
- myChart = null
- }
- myChart = echarts.init(document.getElementById("entityLink"));
- const options = {
- color: ['#dd7172', '#E57373', '#0EB1EE', '#9D96F5', '#ACC68E', '#EDAA77', '#14BBB3', '#538FFF', '#1390FB', '#C7B02E',],
- grid: {
- containLabel: true, // 保证标签和内容在图表区域内
- //top: 1000
- },
- tooltip: {
- formatter: function (x) {
- return x.data.label;
- }
- },
- series: [{
- categories: this.entityLink.categories,
- type: 'graph',
- layout: 'circular',
- roam: 'none',
- force: {
- repulsion: 1000,
- edgeLength: [50, 150],
- layoutAnimation: true
- },
- //center: ['50%', '50%'],
- //radius: ['30%', '50%'],
- edgeSymbol: ['none', 'arrow'],
- edgeSymbolSize: 10,
- data: this.entityLink.nodes,
- links: this.entityLink.links,
- lineStyle: {
- normal: {
- color: 'target',
- cursor: 'default',
- width: 2,
- curveness: 0.3 // 设置弯曲度,避免重叠
- },
- },
- edgeLabel: {
- normal: {
- show: true,
- formatter: function (x) {
- return x.data.value; //横线关系
- }
- }
- },
- label: {
- normal: {
- show: true,
- textStyle: {
- cursor: 'pointer',
- },
- color: '#000', //label字体颜色
- formatter: function (x) {
- var tmp = x.data.label;
- if (tmp.length >= 12) {
- tmp = tmp.substring(0, 12);
- tmp = tmp + "...";
- }
- return tmp;
- }
- }
- },
- }]
- }
- myChart.setOption(options)
- var startNode = null;
- myChart.on('mousedown', (params) => {
- //console.log('mousedown', params)
- if (params && params.dataType === 'node') {
- startNode = { ...params }; // 记录开始拖动的节点
- }
- });
- // 监听鼠标移动事件
- myChart.getDom().addEventListener('mousemove', (event) => {
- //console.log("mousemove-event", event)
- if (startNode) {
- var rect = myChart.getDom().getBoundingClientRect();
- var mouseX = event.clientX - rect.left;
- var mouseY = event.clientY - rect.top;
- // 动态更新光标位置的线条
- myChart.setOption({
- graphic: [
- {
- type: 'line',
- shape: {
- x1: startNode.event.offsetX, // 节点的 x 坐标
- y1: startNode.event.offsetY, // 节点的 y 坐标
- x2: mouseX, // 光标的 x 坐标
- y2: mouseY // 光标的 y 坐标
- },
- style: {
- stroke: '#FF0000', // 线条颜色
- lineWidth: 2 // 线条宽度
- }
- }
- ]
- }, false);
- }
- });
- myChart.getDom().addEventListener('mouseup', (event) => {
- //console.log("mouseup-event", event)
- startNode = null
- const option = myChart.getOption()
- myChart.setOption({
- graphic: [
- {
- style: {
- lineWidth: 0 // 线条宽度
- }
- }
- ]
- }, false)
- })
- myChart.getDom().addEventListener('mouseleave', (event) => {
- //console.log("mouseup-event", event)
- startNode = null
- const option = myChart.getOption()
- myChart.setOption({
- graphic: [
- {
- style: {
- lineWidth: 0 // 线条宽度
- }
- }
- ]
- }, false)
- })
- myChart.on('dblclick', (event) => {
- //console.log("dblclick", event)
- if (event && event.dataType === 'edge') {
- this.$prompt('输入关系名', '关系修改提示', {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
- inputValue: event.data.value,
- type: 'warning'
- }).then(({ value }) => {
- this.entityLink.links[event.dataIndex].value = value
- // 更新图表
- myChart.setOption({
- series: [{
- type: 'graph',
- links: this.entityLink.links
- }]
- }, false);
- }).catch((err) => {
- console.log("修改关系错误", err)
- })
- }
- });
- myChart.on('mouseup', (params) => {
- //console.log('mouseup', params)
- params.event.event.stopPropagation()
- if (startNode && params && params.dataType === 'node' && params.data.nodeId !== startNode.data.nodeId) {
- let isReverseLink = false //是否有相反方向的线
- let isLink = false //是否存在连线
- this.entityLink.links.forEach(el => {
- if (el.source === params.data.name && el.target === startNode.data.name) {
- isReverseLink = true
- }
- if (el.source === startNode.data.name && el.target === params.data.name) {
- isLink = true
- }
- })
- if (isLink) { //存在连线直接跳过
- myChart.setOption({ //销毁连线
- graphic: [
- {
- style: {
- lineWidth: 0 // 线条宽度
- }
- }
- ],
- }, false);
- startNode = null
- return
- }
- this.$prompt('请输入关系', '连接关系', {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
- type: 'info'
- }).then(({ value }) => {
- // 创建正式的连线
- //console.log("输入的关系", value)
- this.entityLink.links.push({
- source: startNode.data.name,
- target: params.data.name,
- value: value,
- lineStyle: {
- curveness: isReverseLink ? 0.3 : -0.3,
- }
- });
- // 更新图表,移除临时连线
- myChart.setOption({
- graphic: [
- {
- style: {
- lineWidth: 0 // 线条宽度
- }
- }
- ],
- series: [{
- type: 'graph',
- data: this.entityLink.nodes,
- links: this.entityLink.links
- }]
- }, false);
- }).catch((err) => {
- console.log("连线报错", err)
- myChart.setOption({
- graphic: [
- {
- style: {
- lineWidth: 0 // 线条宽度
- }
- }
- ],
- }, false);
- }).finally(() => {
- // 重置
- startNode = null;
- })
- } else {
- myChart.setOption({ //隐藏连接线
- graphic: [
- {
- style: {
- lineWidth: 0 // 线条宽度
- }
- }
- ]
- }, false)
- startNode = null;
- }
- });
- }
- },
- watch: {
- isCollapse: {
- handler(newVal, oldVal) {
- setTimeout(() => {
- this.sendChildWindowMessage("left-collapse", this.isCollapse)
- }, 200)
- }
- },
- "searchInp": {
- handler() {
- this.getNode()
- }
- },
- "selectedName": {
- handler() {
- this.getNode()
- }
- },
- searchRelationshipName(newVal) {
- if (newVal) {
- this.findRelationshipType()
- }
- },
- },
- computed: {
- },
- created() {
- // 使用 day.js 插件
- dayjs.extend(dayjs_plugin_localeData);
- dayjs.locale('zh-cn'); // 设置为中文
- timer = setInterval(() => {
- this.nowDate = this.getNowDate()
- }, 1000)
- this.receiveIframeMsg()
- },
- mounted() {
- //console.log("jquery", $)
- },
- destroyed() {
- //销毁定时器
- clearInterval(timer)
- }
- })
- </script>
- </html>
|