|
|
|
@ -69,7 +69,66 @@ |
|
|
|
</div> |
|
|
|
<div class="rightList"> |
|
|
|
<img src="../assets/img/rightList.png" style="width: 100%;height: 95%;position: absolute;z-index: 1;"/> |
|
|
|
<div class="rightListContent" v-if="this.userType==0"> |
|
|
|
<div class="tupu"> |
|
|
|
<div style="color: white; margin:0 15px 5px 15px;">关键字: |
|
|
|
<input style="background-color: transparent; border: none; border-bottom: 1px solid white; color: white; outline: none;" placeholder="请输入关键字" v-model="keywords"/> |
|
|
|
<div @click="getInfo1" |
|
|
|
style="width: 3vw;height: 1.5vw;background-color: #001c3a;float: right;text-align: center;border-radius:1vw;"> |
|
|
|
查询 |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<div style="width: 100%;height: 80%;"> |
|
|
|
<div class="gContainer"> |
|
|
|
<div id="graph-panel" style="width: 100%;height: 100%;"></div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<!-- 弹窗 --> |
|
|
|
<el-dialog |
|
|
|
:visible.sync="isModalVisible" |
|
|
|
title="添加分支内容" |
|
|
|
width="30%" |
|
|
|
top="15vh" |
|
|
|
append-to-body |
|
|
|
custom-class="custom-dialog" |
|
|
|
> |
|
|
|
<el-form label-width="80px"> |
|
|
|
<el-form-item label="fileId"> |
|
|
|
<el-input v-model="newBranchFileId"></el-input> |
|
|
|
</el-form-item> |
|
|
|
<el-form-item label="类型"> |
|
|
|
<el-select v-model="typeValue" placeholder="请选择类型"> |
|
|
|
<el-option label="图文" value="tw"></el-option> |
|
|
|
<el-option label="视频" value="sp"></el-option> |
|
|
|
<el-option label="动画" value="dh"></el-option> |
|
|
|
<el-option label="计算模块" value="jsmk"></el-option> |
|
|
|
</el-select> |
|
|
|
</el-form-item> |
|
|
|
<el-form-item label="节点名称"> |
|
|
|
<el-input v-model="newBranchContent"></el-input> |
|
|
|
</el-form-item> |
|
|
|
<el-form-item label="节点内容"> |
|
|
|
<el-input type="textarea" v-model="newBranchValue"></el-input> |
|
|
|
</el-form-item> |
|
|
|
<el-form-item label="父级节点ID"> |
|
|
|
<el-input v-model="newBranchParentId" disabled></el-input> |
|
|
|
</el-form-item> |
|
|
|
<el-form-item label="关系"> |
|
|
|
<el-input v-model="newBranchRelation" |
|
|
|
@input="newBranchRelation = $event.target.value.replace(/[^a-zA-Z\u4e00-\u9fa5]/g, '')"></el-input> |
|
|
|
</el-form-item> |
|
|
|
<el-form-item label="层级"> |
|
|
|
<el-input-number v-model="newBranchLevel" controls-position="right" :min="1"></el-input-number> |
|
|
|
</el-form-item> |
|
|
|
</el-form> |
|
|
|
<span slot="footer" class="dialog-footer"> |
|
|
|
<el-button @click="closeModal">取 消</el-button> |
|
|
|
<el-button type="primary" @click="addNewBranch">提 交</el-button> |
|
|
|
</span> |
|
|
|
</el-dialog> |
|
|
|
|
|
|
|
|
|
|
|
<div class="rightListContent" v-if="this.userType==0"> |
|
|
|
<div class="oneRight" v-for="item in contentList" :key="item"> |
|
|
|
<div style="width: 8%;">{{ item.id }}</div> |
|
|
|
<div style="width: 22%;">{{ item.name }}</div> |
|
|
|
@ -113,6 +172,11 @@ |
|
|
|
import headInfo from '@/components/Head.vue'; |
|
|
|
import Foot from "@/components/Foot.vue"; |
|
|
|
import {getDocList, getTwInfo} from "@/api/kcInfo"; |
|
|
|
import {getgraphInfo, test} from "@/api/login"; |
|
|
|
import VisGraph from '@/assets/js/graphvis.min.20241008.js' |
|
|
|
import LayoutFactory from '@/assets/js/graphvis.layout.min.js' |
|
|
|
import {config} from '@/assets/defaultConfig.js' |
|
|
|
import {addNode, getFileIdByDocId} from "@/api/file"; |
|
|
|
|
|
|
|
export default { |
|
|
|
// eslint-disable-next-line vue/multi-word-component-names |
|
|
|
@ -141,6 +205,26 @@ export default { |
|
|
|
totalPage: 0, |
|
|
|
pagesList: [], |
|
|
|
onePagesList: [], |
|
|
|
|
|
|
|
infos: [], |
|
|
|
demoData: {}, |
|
|
|
graphData: { |
|
|
|
nodes: [], |
|
|
|
links: [] |
|
|
|
}, |
|
|
|
config, |
|
|
|
visGraph: null, // 组件中保存VisGraph实例 |
|
|
|
isModalVisible: false, |
|
|
|
newBranchContent: '', |
|
|
|
selectedNode: null, |
|
|
|
|
|
|
|
newBranchValue: '', |
|
|
|
newBranchFileId: '', |
|
|
|
newBranchLevel: null, |
|
|
|
newBranchParentId: '', |
|
|
|
newBranchRelation: '', |
|
|
|
typeValue: '', |
|
|
|
keywords: '', |
|
|
|
} |
|
|
|
|
|
|
|
}, |
|
|
|
@ -215,12 +299,277 @@ export default { |
|
|
|
console.log(res.data) |
|
|
|
}) |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
goBook() { |
|
|
|
this.$router.push({name: 'Book', query: {id: '1'}}) |
|
|
|
}, |
|
|
|
onCreated(editor) { |
|
|
|
this.editor = Object.seal(editor) // 一定要用 Object.seal() ,否则会报错 |
|
|
|
}, |
|
|
|
getInfo() { |
|
|
|
this.graphData = undefined; |
|
|
|
this.demoData = {} |
|
|
|
|
|
|
|
if (this.keywords != '' && this.keywords != undefined) { |
|
|
|
this.visGraph.clearAll(); |
|
|
|
let params = { |
|
|
|
nodename: this.keywords, |
|
|
|
}; |
|
|
|
getgraphInfo(params).then((res) => { |
|
|
|
this.zhengl(res.data); |
|
|
|
}) |
|
|
|
} else { |
|
|
|
|
|
|
|
let params = {}; |
|
|
|
getgraphInfo(params).then((res) => { |
|
|
|
this.zhengl(res.data); |
|
|
|
}) |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
}, |
|
|
|
getInfo1() { |
|
|
|
this.graphData = undefined; |
|
|
|
this.demoData = {} |
|
|
|
|
|
|
|
if (this.keywords != '' && this.keywords != undefined) { |
|
|
|
this.visGraph.clearAll(); |
|
|
|
let params = { |
|
|
|
nodename: this.keywords, |
|
|
|
}; |
|
|
|
getgraphInfo(params).then((res) => { |
|
|
|
this.zhengl(res.data); |
|
|
|
}) |
|
|
|
} else { |
|
|
|
this.visGraph.clearAll(); |
|
|
|
let params = {}; |
|
|
|
getgraphInfo(params).then((res) => { |
|
|
|
this.zhengl(res.data); |
|
|
|
}) |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
async drawGraphData() { |
|
|
|
this.graphData = this.demoData; |
|
|
|
if (this.visGraph === null) { |
|
|
|
this.createGraph(); |
|
|
|
// this.genrateGraphData(); |
|
|
|
this.visGraph.drawData(this.graphData); |
|
|
|
this.visGraph.incremaNodesCodinate(this.graphData.nodes); |
|
|
|
this.reLayout(); |
|
|
|
} else { |
|
|
|
this.createGraph(); |
|
|
|
this.visGraph.drawData(this.graphData); |
|
|
|
this.visGraph.incremaNodesCodinate(this.graphData.nodes); |
|
|
|
this.reLayout(); |
|
|
|
} |
|
|
|
this.loading = false; |
|
|
|
|
|
|
|
}, |
|
|
|
// 创建全局绘图客户端对象 |
|
|
|
createGraph() { |
|
|
|
const configWithEvents = { |
|
|
|
...this.config, |
|
|
|
node: { |
|
|
|
...this.config.node, |
|
|
|
ondblClick: (event, node) => { |
|
|
|
this.showPopup(node); |
|
|
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
this.visGraph = new VisGraph(document.getElementById('graph-panel'), configWithEvents); |
|
|
|
}, |
|
|
|
async showPopup(node) { |
|
|
|
this.selectedNode = node; |
|
|
|
this.newBranchParentId = node.properties.docId; |
|
|
|
this.newBranchLevel = parseInt(node.properties.level) + 1; |
|
|
|
|
|
|
|
try { |
|
|
|
const response = await this.getFileIdByDocId({docId: node.properties.docId}); |
|
|
|
this.newBranchFileId = response.fileId; |
|
|
|
} catch (error) { |
|
|
|
console.error('Failed to fetch file ID:', error); |
|
|
|
alert('无法获取文件ID,请稍后再试。'); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
this.isModalVisible = true; // 显示模态框 |
|
|
|
}, |
|
|
|
getFileIdByDocId(data) { |
|
|
|
return getFileIdByDocId(data); |
|
|
|
}, |
|
|
|
closeModal() { |
|
|
|
this.isModalVisible = false; |
|
|
|
this.newBranchContent = ''; |
|
|
|
this.selectedNode = null; |
|
|
|
}, |
|
|
|
async addNewBranch() { |
|
|
|
const content = this.newBranchContent.trim(); |
|
|
|
const value = this.newBranchValue.trim(); |
|
|
|
const fileId = this.newBranchFileId.trim(); |
|
|
|
const relation = this.newBranchRelation.trim(); |
|
|
|
|
|
|
|
if (this.selectedNode && content && value) { |
|
|
|
// 构造数据 |
|
|
|
const data = { |
|
|
|
fileId: fileId, |
|
|
|
txtName: content, |
|
|
|
TxtValue: value, |
|
|
|
relation: relation, |
|
|
|
parentId: this.newBranchParentId, |
|
|
|
level: this.newBranchLevel |
|
|
|
}; |
|
|
|
|
|
|
|
try { |
|
|
|
await addNode(data); |
|
|
|
|
|
|
|
// 创建新节点 |
|
|
|
const newNodeId = Date.now().toString(); // 使用时间戳作为唯一ID |
|
|
|
const newNode = { |
|
|
|
id: newNodeId, |
|
|
|
label: content, |
|
|
|
properties: {name: content, docId: newNodeId, level: this.newBranchLevel}, |
|
|
|
...this.getNodeStyle(this.newBranchLevel) // 根据层级应用样式 |
|
|
|
}; |
|
|
|
const newLink = { |
|
|
|
source: this.selectedNode.id, |
|
|
|
target: newNodeId, |
|
|
|
type: '', |
|
|
|
}; |
|
|
|
this.graphData.nodes.push(newNode); |
|
|
|
this.graphData.links.push(newLink); |
|
|
|
|
|
|
|
// 刷新图谱 |
|
|
|
this.visGraph.drawData(this.graphData); |
|
|
|
this.reLayout(); |
|
|
|
this.closeModal(); // 关闭模态框 |
|
|
|
} catch (error) { |
|
|
|
console.error('Failed to add new branch:', error); |
|
|
|
alert('Failed to add new branch. Please try again.'); |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
// 执行布局算法 |
|
|
|
reLayout(alpha) { |
|
|
|
var that = this; |
|
|
|
if (alpha == null) { |
|
|
|
that.visLayout = null; |
|
|
|
that.visLayout = new LayoutFactory(this.visGraph.getGraphData()).createLayout('fastFR'); |
|
|
|
that.visLayout.resetConfig({ |
|
|
|
label: { |
|
|
|
show: true |
|
|
|
}, |
|
|
|
friction: 0.8, |
|
|
|
linkDistance: 400, |
|
|
|
linkStrength: 0.2, |
|
|
|
charge: -1000, |
|
|
|
gravity: 0.01, |
|
|
|
noverlap: true, |
|
|
|
size: [that.visGraph.stage.width, that.visGraph.stage.height] |
|
|
|
}); |
|
|
|
} else { |
|
|
|
that.visLayout.alpha += (alpha > 1 ? 0.2 : alpha); //继续运动 |
|
|
|
} |
|
|
|
|
|
|
|
runLayout();//开始继续动画执行 |
|
|
|
|
|
|
|
//通过动画帧控制控制布局算法的执行,有动画效果 |
|
|
|
function runLayout() { |
|
|
|
cancelAnimationFrame(that.layoutLoopName);//停止动画控制 |
|
|
|
that.visLayout.runLayout(); //运行布局算法 |
|
|
|
that.visGraph.refresh(); |
|
|
|
if (that.visLayout.alpha > 0.05) { |
|
|
|
that.layoutLoopName = requestAnimationFrame(runLayout); |
|
|
|
} else { |
|
|
|
if (that.visGraph.currentNode && that.visGraph.currentNode.isDragging) { |
|
|
|
that.visLayout.alpha = 0.1; //继续运动 |
|
|
|
that.layoutLoopName = requestAnimationFrame(runLayout); |
|
|
|
} else { |
|
|
|
that.visLayout.alpha = 0; //停止运动 |
|
|
|
cancelAnimationFrame(that.layoutLoopName); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// this.autoLayout(); |
|
|
|
}, |
|
|
|
zhengl(data) { |
|
|
|
const nodes = [] |
|
|
|
const links = [] // 存放节点和关系 |
|
|
|
|
|
|
|
var nodeList = data.nodes; |
|
|
|
var lineList = data.links; |
|
|
|
var allOne = "" |
|
|
|
|
|
|
|
console.log(nodeList) |
|
|
|
if (nodeList != undefined) { |
|
|
|
allOne = nodeList[0].docId |
|
|
|
for (let a = 0; a < nodeList.length; a++) { |
|
|
|
const group = parseInt(nodeList[a].group, 10); |
|
|
|
const style = this.getNodeStyle(group); |
|
|
|
|
|
|
|
nodes.push({ |
|
|
|
id: nodeList[a].id, |
|
|
|
label: nodeList[a].name, |
|
|
|
properties: {name: nodeList[a].name, docId: nodeList[a].docId, parent: allOne, leve: nodeList[a].group}, |
|
|
|
...style // 展开 style 对象以应用样式属性 |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// var allOne = nodeList[0].docId |
|
|
|
|
|
|
|
|
|
|
|
if (lineList != undefined) { |
|
|
|
for (let b = 0; b < lineList.length; b++) { |
|
|
|
|
|
|
|
var bbb = {name: lineList[b].relate} |
|
|
|
links.push({ |
|
|
|
source: lineList[b].source, |
|
|
|
target: lineList[b].target, |
|
|
|
type: lineList[b].relate, |
|
|
|
properties: bbb, |
|
|
|
color: '202,202,202', |
|
|
|
lineWidth: 3, |
|
|
|
}) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
this.demoData = { |
|
|
|
"nodes": nodes, |
|
|
|
"links": links |
|
|
|
} |
|
|
|
this.drawGraphData(); |
|
|
|
}, |
|
|
|
getNodeStyle(group) { |
|
|
|
const styles = [ |
|
|
|
{size: 450, color: '227,203,0', font: 'normal 70px Arial', fontColor: '255,255,255'}, |
|
|
|
{size: 350, width: 350, height: 300, color: '47,47,230', font: 'normal 68px Arial', fontColor: '255,255,255'}, |
|
|
|
{size: 300, width: 300, height: 250, color: '255,138,0', font: 'normal 50px Arial', fontColor: '255,255,255'}, |
|
|
|
{size: 250, width: 250, height: 250, color: '30,255,0', font: 'normal 40px Arial', fontColor: '0,0,0'}, |
|
|
|
{size: 200, width: 200, height: 200, color: '248,143,248', font: 'normal 32px Arial', fontColor: '255,255,255'}, |
|
|
|
{size: 150, width: 150, height: 150, color: '65,154,255', font: 'normal 30px Arial', fontColor: '255,255,255'}, |
|
|
|
{size: 120, width: 120, height: 120, color: '0,228,255', font: 'normal 28px Arial', fontColor: '0,0,0'} |
|
|
|
]; |
|
|
|
|
|
|
|
return styles[group] || {}; |
|
|
|
}, |
|
|
|
testInfo() { |
|
|
|
test().then((res) => { |
|
|
|
console.log(res); |
|
|
|
}) |
|
|
|
} |
|
|
|
|
|
|
|
}, |
|
|
|
mounted() { |
|
|
|
this.userType = localStorage.getItem("type"); |
|
|
|
this.userName = localStorage.getItem("name"); |
|
|
|
this.getContentList(); |
|
|
|
this.getInfo(); |
|
|
|
} |
|
|
|
} |
|
|
|
</script> |
|
|
|
@ -326,6 +675,27 @@ export default { |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
.tupu { |
|
|
|
width: 100%; |
|
|
|
height: 100%; |
|
|
|
position: absolute; |
|
|
|
z-index: 3; |
|
|
|
top: 1%; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
.gContainer { |
|
|
|
position: relative; |
|
|
|
display: flex; |
|
|
|
flex-direction: column; |
|
|
|
align-items: center; |
|
|
|
justify-content: center; |
|
|
|
overflow: hidden; |
|
|
|
width: 100%; |
|
|
|
height: 32vw; |
|
|
|
border-radius:2vw; |
|
|
|
} |
|
|
|
|
|
|
|
.oneRight { |
|
|
|
width: 98%; |
|
|
|
height: 5vw; |
|
|
|
|