From 7c463c8bf258a20d55fe0d6336ab5e49899c2d85 Mon Sep 17 00:00:00 2001 From: linsheng0116 <1401679367@qq.com> Date: Mon, 20 Jan 2025 13:03:43 +0800 Subject: [PATCH] =?UTF-8?q?2025.1.8=20=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kcui/src/api/file.js | 8 + kcui/src/view/Home.vue | 224 ++++++++++++--------- .../java/com/main/woka/Common/util/KcInfo.java | 4 +- .../java/com/main/woka/Filter/SaTokenFilter.java | 3 +- .../woka/Web/Controller/KcTlFileController.java | 151 +++++++++++++- src/main/resources/Mapper/KcInfoRelationMapper.xml | 2 +- 6 files changed, 285 insertions(+), 107 deletions(-) diff --git a/kcui/src/api/file.js b/kcui/src/api/file.js index 42f6744..0eae896 100644 --- a/kcui/src/api/file.js +++ b/kcui/src/api/file.js @@ -19,4 +19,12 @@ export function addFile(file, config = {}) { data: formData, ...finalConfig }); +} + +export function addNode(data) { + return request({ + url: '/file/addNode', + method: 'post', + data:data + }) } \ No newline at end of file diff --git a/kcui/src/view/Home.vue b/kcui/src/view/Home.vue index bcbc787..f81713c 100644 --- a/kcui/src/view/Home.vue +++ b/kcui/src/view/Home.vue @@ -8,6 +8,33 @@
+ + + @@ -16,6 +43,7 @@ import {getgraphInfo, test, userLogin} 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} from "@/api/file"; export default { // eslint-disable-next-line vue/multi-word-component-names @@ -29,6 +57,17 @@ export default { links: [] }, config, + visGraph: null, // 组件中保存VisGraph实例 + isModalVisible: false, + newBranchContent: '', + selectedNode: null, + + newBranchValue: '', + newBranchFileId: '', + newBranchLevel: null, + newBranchParentId: '', + newBranchRelation:'' + } }, methods:{ @@ -65,10 +104,77 @@ export default { // this.goCenter(); } this.loading = false; + }, // 创建全局绘图客户端对象 createGraph() { - this.visGraph = new VisGraph(document.getElementById('graph-panel'), this.config) + const configWithEvents = { + ...this.config, + node: { + ...this.config.node, + ondblClick: (event, node) => { + this.showPopup(node); + } + } + }; + this.visGraph = new VisGraph(document.getElementById('graph-panel'), configWithEvents); + }, + showPopup(node) { + this.selectedNode = node; + this.newBranchParentId = node.properties.docId; + this.newBranchLevel = node.properties.level - 1; + this.isModalVisible = true; // 显示模态框 + }, + 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) { @@ -123,103 +229,15 @@ export default { var allOne = nodeList[0].docId for (let a = 0; a < nodeList.length; a++) { - if (nodeList[a].group == '0') { - const aaa = {name: nodeList[a].name, docId: nodeList[a].docId, parent: allOne} - nodes.push({ - id: nodeList[a].id, - label: nodeList[a].name, - properties: aaa, - size: 450, - color: '227,203,0', - font: 'normal 70px Arial', - fontColor: '255,255,255' - }) - } - if (nodeList[a].group == '1') { - const aaa = {name: nodeList[a].name, docId: nodeList[a].docId, parent: allOne} - nodes.push({ - id: nodeList[a].id, - label: nodeList[a].name, - properties: aaa, - size: 350, - width:350, - height:300, - color: '47,47,230', - font: 'normal 68px Arial', - fontColor: '255,255,255' - }) - } - if (nodeList[a].group == '2') { - const aaa = {name: nodeList[a].name, docId: nodeList[a].docId, parent: allOne} - nodes.push({ - id: nodeList[a].id, - label: nodeList[a].name, - properties: aaa, - size: 300, - width:300, - height:250, - color: '255,138,0', - font: 'normal 50px Arial', - fontColor: '255,255,255' - }) - } - if (nodeList[a].group == '3') { - const aaa = {name: nodeList[a].name, docId: nodeList[a].docId, parent: allOne} - nodes.push({ - id: nodeList[a].id, - label: nodeList[a].name, - properties: aaa, - size: 250, - width:250, - height:250, - color: '30,255,0', - font: 'normal 40px Arial', - fontColor: '0,0,0' - }) - } - if (nodeList[a].group == '4') { - const aaa = {name: nodeList[a].name, docId: nodeList[a].docId, parent: allOne} - nodes.push({ - id: nodeList[a].id, - label: nodeList[a].name, - properties: aaa, - size: 200, - width:200, - height:200, - color: '248,143,248', - font: 'normal 32px Arial', - fontColor: '255,255,255' - }) - } - if (nodeList[a].group == '5') { - const aaa = {name: nodeList[a].name, docId: nodeList[a].docId, parent: allOne} - nodes.push({ - id: nodeList[a].id, - label: nodeList[a].name, - properties: aaa, - size: 150, - width:150, - height:150, - color: '65,154,255', - font: 'normal 30px Arial', - fontColor: '255,255,255' - }) - } - if (nodeList[a].group == '6') { - const aaa = {name: nodeList[a].name, docId: nodeList[a].docId, parent: allOne} - nodes.push({ - id: nodeList[a].id, - label: nodeList[a].name, - properties: aaa, - size: 100, - width:100, - height:100, - color: '0,228,255', - font: 'normal 28px Arial', - fontColor: '0,0,0' - }) - } + 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 }, + ...style // 展开 style 对象以应用样式属性 + }); } @@ -242,7 +260,19 @@ export default { } 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: 100, width: 100, height: 100, color: '0,228,255', font: 'normal 28px Arial', fontColor: '0,0,0' } + ]; + return styles[group] || {}; + }, doLogin(){ userLogin().then((res)=>{ console.log(res); diff --git a/src/main/java/com/main/woka/Common/util/KcInfo.java b/src/main/java/com/main/woka/Common/util/KcInfo.java index 47c1ca9..343af4b 100644 --- a/src/main/java/com/main/woka/Common/util/KcInfo.java +++ b/src/main/java/com/main/woka/Common/util/KcInfo.java @@ -18,13 +18,11 @@ public class KcInfo { private Long isGraph; private Long level; private Long groupId; - + private Integer fileId; public Integer getFileId() {return fileId;} public void setFileId(Integer fileId) {this.fileId = fileId;} - private Integer fileId; - public Long getId() { return id; } diff --git a/src/main/java/com/main/woka/Filter/SaTokenFilter.java b/src/main/java/com/main/woka/Filter/SaTokenFilter.java index fe7aa37..54ecdea 100644 --- a/src/main/java/com/main/woka/Filter/SaTokenFilter.java +++ b/src/main/java/com/main/woka/Filter/SaTokenFilter.java @@ -4,7 +4,6 @@ import cn.dev33.satoken.interceptor.SaInterceptor; import cn.dev33.satoken.router.SaRouter; import cn.dev33.satoken.stp.StpUtil; import org.springframework.context.annotation.Configuration; -import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @@ -21,7 +20,7 @@ public class SaTokenFilter implements WebMvcConfigurer { // SaRouter.match("/admin/**", r -> StpUtil.checkRoleOr("admin", "super-admin")); // // 权限校验 -- 不同模块校验不同权限 // SaRouter.match("/user/**", r -> StpUtil.checkPermission("user")); - })).excludePathPatterns("/user/doLogin"); //开放 + })).excludePathPatterns("/user/doLogin").excludePathPatterns("/file/**"); //开放 } } diff --git a/src/main/java/com/main/woka/Web/Controller/KcTlFileController.java b/src/main/java/com/main/woka/Web/Controller/KcTlFileController.java index 8f73fca..2558370 100644 --- a/src/main/java/com/main/woka/Web/Controller/KcTlFileController.java +++ b/src/main/java/com/main/woka/Web/Controller/KcTlFileController.java @@ -1,25 +1,27 @@ package com.main.woka.Web.Controller; import com.main.woka.Common.core.AjaxResult; -import com.main.woka.Common.util.KcTlFile; -import com.main.woka.Common.util.Neo4jUtil; -import com.main.woka.Common.util.WebSocket; +import com.main.woka.Common.util.*; import com.main.woka.Web.Mapper.KcFileMapper; import com.main.woka.Web.Mapper.KcInfoRelationMapper; import com.main.woka.Web.Service.impl.KcTlFileServiceImpl; import com.main.woka.Web.Service.impl.PdfUtil; +import org.neo4j.driver.v1.StatementResult; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import java.io.File; import java.io.FileInputStream; +import java.io.FileWriter; import java.io.IOException; +import java.nio.file.Paths; import java.sql.Timestamp; import java.text.SimpleDateFormat; -import java.util.Date; +import java.util.*; @RestController @RequestMapping("/file") @@ -113,6 +115,147 @@ public class KcTlFileController extends BaseController { return subDir.getPath(); } + @PostMapping("/addNode") + public AjaxResult addNode(@RequestBody Map