1 |
- {"ast":null,"code":"import _objectSpread from \"/Users/zyh/Desktop/demo001/node_modules/@babel/runtime/helpers/esm/objectSpread2.js\";\nimport \"core-js/modules/es.array.find.js\";\nimport \"core-js/modules/es.array.for-each.js\";\nimport \"core-js/modules/es.array.includes.js\";\nimport \"core-js/modules/es.array.push.js\";\nimport \"core-js/modules/es.function.name.js\";\nimport \"core-js/modules/es.iterator.constructor.js\";\nimport \"core-js/modules/es.iterator.find.js\";\nimport \"core-js/modules/es.iterator.for-each.js\";\nimport \"core-js/modules/es.object.to-string.js\";\nimport \"core-js/modules/es.string.includes.js\";\nimport \"core-js/modules/es.string.starts-with.js\";\nimport \"core-js/modules/web.dom-collections.for-each.js\";\nimport { Graph, Shape, Addon } from '@antv/x6';\nimport { register } from '@antv/x6-vue-shape';\nimport { ElMessage } from 'element-ui';\n\n// 自定义Vue节点组件\nvar FlowNode = {\n template: \"\\n <div :class=\\\"['custom-node', node.type]\\\">\\n <div class=\\\"node-label\\\">{{ node.label }}</div>\\n </div>\\n \",\n props: {\n node: {\n type: Object,\n required: true\n }\n }\n};\n\n// 注册自定义Vue节点\nregister({\n shape: 'flow-node',\n component: FlowNode,\n width: 120,\n height: 60,\n ports: {\n groups: {\n \"in\": {\n position: 'top',\n attrs: {\n circle: {\n r: 4,\n magnet: true,\n stroke: '#C2C8D5',\n strokeWidth: 1,\n fill: '#fff'\n }\n }\n },\n out: {\n position: 'bottom',\n attrs: {\n circle: {\n r: 4,\n magnet: true,\n stroke: '#C2C8D5',\n strokeWidth: 1,\n fill: '#fff'\n }\n }\n }\n }\n }\n});\nexport default {\n name: 'X6EmployeeFlow',\n data: function data() {\n return {\n graph: null,\n selectedNode: null,\n flowNodes: [{\n id: 'start',\n type: 'start',\n label: '开始',\n x: 400,\n y: 50,\n url: '/process/start'\n }, {\n id: 'interview',\n type: 'condition',\n label: '面试',\n x: 400,\n y: 150,\n url: '/interview'\n }, {\n id: 'pass',\n type: 'process',\n label: '发录用通知书',\n x: 600,\n y: 150,\n url: '/offer'\n }, {\n id: 'prepare',\n type: 'process',\n label: '准备入职材料',\n x: 600,\n y: 250,\n url: '/prepare'\n }, {\n id: 'verify',\n type: 'condition',\n label: '材料核实',\n x: 600,\n y: 350,\n url: '/verify'\n }, {\n id: 'onboard',\n type: 'process',\n label: '办理入职',\n x: 600,\n y: 450,\n url: '/onboard'\n }, {\n id: 'reject',\n type: 'process',\n label: '发送拒绝通知',\n x: 200,\n y: 250,\n url: '/reject'\n }, {\n id: 'archive',\n type: 'process',\n label: '归档简历',\n x: 200,\n y: 350,\n url: '/archive'\n }, {\n id: 'end',\n type: 'end',\n label: '结束',\n x: 400,\n y: 550,\n url: '/process/end'\n }],\n flowEdges: [{\n source: 'start',\n target: 'interview',\n label: ''\n }, {\n source: 'interview',\n target: 'pass',\n label: '通过'\n }, {\n source: 'interview',\n target: 'reject',\n label: '不通过'\n }, {\n source: 'pass',\n target: 'prepare',\n label: ''\n }, {\n source: 'prepare',\n target: 'verify',\n label: ''\n }, {\n source: 'verify',\n target: 'onboard',\n label: '材料无误'\n }, {\n source: 'reject',\n target: 'archive',\n label: ''\n }, {\n source: 'onboard',\n target: 'end',\n label: ''\n }, {\n source: 'archive',\n target: 'end',\n label: ''\n }]\n };\n },\n mounted: function mounted() {\n this.initGraph();\n },\n beforeDestroy: function beforeDestroy() {\n if (this.graph) {\n this.graph.dispose();\n }\n },\n methods: {\n initGraph: function initGraph() {\n var _this = this;\n // 创建画布\n this.graph = new Graph({\n container: this.$refs.graphContainer,\n width: 800,\n height: 600,\n grid: {\n visible: true,\n type: 'doubleMesh',\n size: 10,\n args: [{\n color: '#E7E8EA',\n thickness: 1\n }, {\n color: '#CBCFD3',\n thickness: 1,\n factor: 4\n }]\n },\n connecting: {\n router: {\n name: 'manhattan',\n args: {\n padding: 20\n }\n },\n connector: {\n name: 'rounded',\n args: {\n radius: 8\n }\n },\n anchor: 'center',\n connectionPoint: 'anchor',\n allowBlank: false,\n snap: {\n radius: 20\n },\n createEdge: function createEdge() {\n return new Shape.Edge({\n attrs: {\n line: {\n stroke: '#409EFF',\n strokeWidth: 2,\n targetMarker: {\n name: 'block',\n width: 12,\n height: 8\n }\n }\n },\n zIndex: 0,\n label: {\n attrs: {\n label: {\n fill: '#409EFF',\n fontSize: 12\n }\n }\n }\n });\n }\n },\n highlighting: {\n magnetAvailable: {\n name: 'stroke',\n args: {\n padding: 3,\n attrs: {\n 'stroke-width': 2,\n stroke: '#409EFF'\n }\n }\n }\n },\n mousewheel: {\n enabled: true,\n zoomAtMousePosition: true,\n modifiers: 'ctrl',\n minScale: 0.5,\n maxScale: 3\n },\n interacting: {\n nodeMovable: true,\n edgeMovable: false,\n edgeLabelMovable: true\n }\n });\n\n // 添加缩放控制\n var scroller = new Addon.Scroller({\n graph: this.graph,\n autoResize: true,\n pageVisible: false,\n pageBreak: false\n });\n\n // 添加小地图\n new Addon.MiniMap({\n graph: this.graph,\n container: document.createElement('div'),\n width: 150,\n height: 100,\n padding: 10\n });\n\n // 渲染节点\n this.renderNodes();\n\n // 渲染连线\n this.renderEdges();\n\n // 节点点击事件\n this.graph.on('node:click', function (_ref) {\n var node = _ref.node;\n var nodeId = node.id;\n var nodeData = _this.flowNodes.find(function (n) {\n return n.id === nodeId;\n });\n if (nodeData) {\n _this.selectedNode = _objectSpread({}, nodeData);\n }\n });\n\n // 画布点击事件,关闭面板\n this.graph.on('blank:click', function () {\n _this.selectedNode = null;\n });\n\n // 自动调整画布大小\n scroller.center();\n },\n renderNodes: function renderNodes() {\n var _this2 = this;\n // 创建节点\n this.flowNodes.forEach(function (node) {\n var fillColor, strokeColor;\n\n // 根据节点类型设置不同样式\n switch (node.type) {\n case 'start':\n case 'end':\n fillColor = '#409EFF';\n strokeColor = '#409EFF';\n break;\n case 'condition':\n fillColor = '#FFF';\n strokeColor = '#E6A23C';\n break;\n case 'process':\n default:\n fillColor = '#FFF';\n strokeColor = '#409EFF';\n break;\n }\n\n // 计算节点宽度根据文本长度\n var width = Math.max(80, node.label.length * 16);\n\n // 创建节点形状\n var nodeShape = node.type === 'condition' ? 'flow-node-diamond' // 条件节点用菱形\n : node.type === 'start' || node.type === 'end' ? 'flow-node-circle' // 开始/结束用圆形\n : 'flow-node-rect'; // 其它用矩形\n\n // 添加节点到画布\n _this2.graph.addNode({\n id: node.id,\n x: node.x - width / 2,\n y: node.y - 30,\n width: node.type === 'condition' ? 80 : width,\n height: node.type === 'condition' ? 80 : 60,\n shape: nodeShape,\n attrs: {\n body: {\n fill: fillColor,\n stroke: strokeColor,\n strokeWidth: 2,\n rx: node.type === 'process' ? 6 : 0,\n ry: node.type === 'process' ? 6 : 0\n },\n label: {\n text: node.label,\n fill: node.type === 'start' || node.type === 'end' ? '#FFF' : '#333',\n fontSize: 14,\n fontWeight: 500\n }\n },\n data: {\n type: node.type,\n url: node.url\n },\n ports: {\n groups: {\n \"in\": {\n position: 'top',\n attrs: {\n circle: {\n r: 4,\n magnet: true,\n stroke: strokeColor,\n fill: '#FFF'\n }\n }\n },\n out: {\n position: 'bottom',\n attrs: {\n circle: {\n r: 4,\n magnet: true,\n stroke: strokeColor,\n fill: '#FFF'\n }\n }\n }\n },\n items: [{\n id: \"\".concat(node.id, \"-in\"),\n group: 'in'\n }, {\n id: \"\".concat(node.id, \"-out\"),\n group: 'out'\n }]\n }\n });\n });\n },\n renderEdges: function renderEdges() {\n var _this3 = this;\n // 绘制连线\n this.flowEdges.forEach(function (edge) {\n var _this3$flowNodes$find;\n // 确定连线样式\n var isConditionEdge = ((_this3$flowNodes$find = _this3.flowNodes.find(function (n) {\n return n.id === edge.source;\n })) === null || _this3$flowNodes$find === void 0 ? void 0 : _this3$flowNodes$find.type) === 'condition';\n var strokeColor = isConditionEdge ? '#E6A23C' : '#409EFF';\n var strokeDasharray = edge.label.includes('不通过') ? '5,2' : undefined;\n _this3.graph.addEdge({\n source: {\n cell: edge.source,\n port: \"\".concat(edge.source, \"-out\")\n },\n target: {\n cell: edge.target,\n port: \"\".concat(edge.target, \"-in\")\n },\n label: edge.label,\n attrs: {\n line: {\n stroke: strokeColor,\n strokeWidth: 2,\n targetMarker: {\n name: 'block',\n width: 12,\n height: 8,\n fill: strokeColor\n },\n strokeDasharray: strokeDasharray\n }\n },\n labels: [{\n attrs: {\n text: {\n text: edge.label,\n fill: strokeColor,\n fontSize: 12,\n textAnchor: 'middle',\n textVerticalAnchor: 'middle'\n },\n rect: {\n fill: '#FFF',\n stroke: strokeColor,\n strokeWidth: 0.5,\n rx: 3,\n ry: 3,\n refWidth: '100%',\n refHeight: '100%',\n refX: 0,\n refY: 0\n }\n },\n position: {\n distance: 0.5\n }\n }]\n });\n });\n },\n zoomGraph: function zoomGraph(delta) {\n var zoom = this.graph.zoom();\n if (delta > 0 && zoom < 2 || delta < 0 && zoom > 0.5) {\n this.graph.zoom(delta);\n }\n },\n resetGraph: function resetGraph() {\n this.graph.zoomTo(1);\n this.graph.centerContent();\n },\n openNodeUrl: function openNodeUrl() {\n var _this4 = this;\n if (!this.selectedNode) return;\n var url = this.selectedNode.url;\n if (url) {\n if (url.startsWith('http')) {\n window.open(url, '_blank');\n } else {\n this.$router.push(url)[\"catch\"](function (err) {\n if (err.name !== 'NavigationDuplicated') {\n ElMessage({\n type: 'info',\n message: \"\\u6B63\\u5728\\u8DF3\\u8F6C\\u5230\".concat(_this4.selectedNode.label, \"\\u9875\\u9762...\")\n });\n }\n });\n }\n }\n },\n closePanel: function closePanel() {\n this.selectedNode = null;\n },\n addNewNode: function addNewNode() {\n // 打开节点添加对话框\n this.$confirm('此功能将在完整版中提供节点添加与编辑功能,确认查看设计方案?', '新增节点', {\n confirmButtonText: '确定',\n cancelButtonText: '取消',\n type: 'warning'\n }).then(function () {\n // 显示设计方案信息\n ElMessage({\n type: 'success',\n message: '完整版将支持:1.拖拽添加新节点 2.编辑节点属性 3.保存自定义流程 4.流程模板管理',\n duration: 5000\n });\n })[\"catch\"](function () {});\n }\n }\n};","map":{"version":3,"names":["Graph","Shape","Addon","register","ElMessage","FlowNode","template","props","node","type","Object","required","shape","component","width","height","ports","groups","position","attrs","circle","r","magnet","stroke","strokeWidth","fill","out","name","data","graph","selectedNode","flowNodes","id","label","x","y","url","flowEdges","source","target","mounted","initGraph","beforeDestroy","dispose","methods","_this","container","$refs","graphContainer","grid","visible","size","args","color","thickness","factor","connecting","router","padding","connector","radius","anchor","connectionPoint","allowBlank","snap","createEdge","Edge","line","targetMarker","zIndex","fontSize","highlighting","magnetAvailable","mousewheel","enabled","zoomAtMousePosition","modifiers","minScale","maxScale","interacting","nodeMovable","edgeMovable","edgeLabelMovable","scroller","Scroller","autoResize","pageVisible","pageBreak","MiniMap","document","createElement","renderNodes","renderEdges","on","_ref","nodeId","nodeData","find","n","_objectSpread","center","_this2","forEach","fillColor","strokeColor","Math","max","length","nodeShape","addNode","body","rx","ry","text","fontWeight","items","concat","group","_this3","edge","_this3$flowNodes$find","isConditionEdge","strokeDasharray","includes","undefined","addEdge","cell","port","labels","textAnchor","textVerticalAnchor","rect","refWidth","refHeight","refX","refY","distance","zoomGraph","delta","zoom","resetGraph","zoomTo","centerContent","openNodeUrl","_this4","startsWith","window","open","$router","push","err","message","closePanel","addNewNode","$confirm","confirmButtonText","cancelButtonText","then","duration"],"sources":["src/views/X6EmployeeFlow.vue"],"sourcesContent":["<template>\n <div class=\"x6-flow-container\">\n <div class=\"flow-header\">\n <h2>员工入职流程图 (X6版本)</h2>\n <div class=\"flow-actions\">\n <el-button size=\"small\" type=\"primary\" @click=\"zoomGraph(0.1)\">\n <i class=\"el-icon-zoom-in\"></i>\n </el-button>\n <el-button size=\"small\" type=\"primary\" @click=\"zoomGraph(-0.1)\">\n <i class=\"el-icon-zoom-out\"></i>\n </el-button>\n <el-button size=\"small\" type=\"success\" @click=\"resetGraph\">\n <i class=\"el-icon-refresh\"></i>\n </el-button>\n <el-button size=\"small\" type=\"warning\" @click=\"addNewNode\">\n 新增节点\n </el-button>\n </div>\n </div>\n \n <!-- 图形容器 -->\n <div class=\"graph-container\">\n <div id=\"x6-graph-container\" ref=\"graphContainer\"></div>\n \n <!-- 信息面板 -->\n <div class=\"node-info-panel\" v-if=\"selectedNode\">\n <h3>节点详情</h3>\n <div class=\"info-item\">\n <span class=\"label\">ID:</span>\n <span class=\"value\">{{ selectedNode.id }}</span>\n </div>\n <div class=\"info-item\">\n <span class=\"label\">名称:</span>\n <span class=\"value\">{{ selectedNode.label }}</span>\n </div>\n <div class=\"info-item\">\n <span class=\"label\">类型:</span>\n <span class=\"value\">{{ selectedNode.type }}</span>\n </div>\n <div class=\"info-item\">\n <span class=\"label\">链接:</span>\n <span class=\"value\">{{ selectedNode.url }}</span>\n </div>\n <div class=\"actions\">\n <el-button size=\"small\" type=\"primary\" @click=\"openNodeUrl\">\n 打开链接\n </el-button>\n <el-button size=\"small\" type=\"danger\" @click=\"closePanel\">\n 关闭\n </el-button>\n </div>\n </div>\n </div>\n </div>\n</template>\n\n<script>\nimport { Graph, Shape, Addon } from '@antv/x6'\nimport { register } from '@antv/x6-vue-shape'\nimport { ElMessage } from 'element-ui'\n\n// 自定义Vue节点组件\nconst FlowNode = {\n template: `\n <div :class=\"['custom-node', node.type]\">\n <div class=\"node-label\">{{ node.label }}</div>\n </div>\n `,\n props: {\n node: {\n type: Object,\n required: true\n }\n }\n}\n\n// 注册自定义Vue节点\nregister({\n shape: 'flow-node',\n component: FlowNode,\n width: 120,\n height: 60,\n ports: {\n groups: {\n in: {\n position: 'top',\n attrs: {\n circle: {\n r: 4,\n magnet: true,\n stroke: '#C2C8D5',\n strokeWidth: 1,\n fill: '#fff'\n }\n }\n },\n out: {\n position: 'bottom',\n attrs: {\n circle: {\n r: 4,\n magnet: true,\n stroke: '#C2C8D5',\n strokeWidth: 1,\n fill: '#fff'\n }\n }\n }\n }\n }\n})\n\nexport default {\n name: 'X6EmployeeFlow',\n data() {\n return {\n graph: null,\n selectedNode: null,\n flowNodes: [\n { \n id: 'start', \n type: 'start', \n label: '开始', \n x: 400, \n y: 50,\n url: '/process/start'\n },\n { \n id: 'interview', \n type: 'condition', \n label: '面试', \n x: 400, \n y: 150,\n url: '/interview'\n },\n { \n id: 'pass', \n type: 'process', \n label: '发录用通知书', \n x: 600, \n y: 150,\n url: '/offer'\n },\n { \n id: 'prepare', \n type: 'process', \n label: '准备入职材料', \n x: 600, \n y: 250,\n url: '/prepare'\n },\n { \n id: 'verify', \n type: 'condition', \n label: '材料核实', \n x: 600, \n y: 350,\n url: '/verify'\n },\n { \n id: 'onboard', \n type: 'process', \n label: '办理入职', \n x: 600, \n y: 450,\n url: '/onboard'\n },\n { \n id: 'reject', \n type: 'process', \n label: '发送拒绝通知', \n x: 200, \n y: 250,\n url: '/reject'\n },\n { \n id: 'archive', \n type: 'process', \n label: '归档简历', \n x: 200, \n y: 350,\n url: '/archive'\n },\n { \n id: 'end', \n type: 'end', \n label: '结束', \n x: 400, \n y: 550,\n url: '/process/end'\n }\n ],\n flowEdges: [\n { source: 'start', target: 'interview', label: '' },\n { source: 'interview', target: 'pass', label: '通过' },\n { source: 'interview', target: 'reject', label: '不通过' },\n { source: 'pass', target: 'prepare', label: '' },\n { source: 'prepare', target: 'verify', label: '' },\n { source: 'verify', target: 'onboard', label: '材料无误' },\n { source: 'reject', target: 'archive', label: '' },\n { source: 'onboard', target: 'end', label: '' },\n { source: 'archive', target: 'end', label: '' }\n ]\n }\n },\n mounted() {\n this.initGraph()\n },\n beforeDestroy() {\n if (this.graph) {\n this.graph.dispose()\n }\n },\n methods: {\n initGraph() {\n // 创建画布\n this.graph = new Graph({\n container: this.$refs.graphContainer,\n width: 800,\n height: 600,\n grid: {\n visible: true,\n type: 'doubleMesh',\n size: 10,\n args: [\n {\n color: '#E7E8EA',\n thickness: 1\n },\n {\n color: '#CBCFD3',\n thickness: 1,\n factor: 4\n }\n ]\n },\n connecting: {\n router: {\n name: 'manhattan',\n args: {\n padding: 20\n }\n },\n connector: {\n name: 'rounded',\n args: {\n radius: 8\n }\n },\n anchor: 'center',\n connectionPoint: 'anchor',\n allowBlank: false,\n snap: {\n radius: 20\n },\n createEdge() {\n return new Shape.Edge({\n attrs: {\n line: {\n stroke: '#409EFF',\n strokeWidth: 2,\n targetMarker: {\n name: 'block',\n width: 12,\n height: 8\n }\n }\n },\n zIndex: 0,\n label: {\n attrs: {\n label: {\n fill: '#409EFF',\n fontSize: 12\n }\n }\n }\n })\n }\n },\n highlighting: {\n magnetAvailable: {\n name: 'stroke',\n args: {\n padding: 3,\n attrs: {\n 'stroke-width': 2,\n stroke: '#409EFF'\n }\n }\n }\n },\n mousewheel: {\n enabled: true,\n zoomAtMousePosition: true,\n modifiers: 'ctrl',\n minScale: 0.5,\n maxScale: 3\n },\n interacting: {\n nodeMovable: true,\n edgeMovable: false,\n edgeLabelMovable: true\n }\n })\n\n // 添加缩放控制\n const scroller = new Addon.Scroller({\n graph: this.graph,\n autoResize: true,\n pageVisible: false,\n pageBreak: false\n })\n\n // 添加小地图\n new Addon.MiniMap({\n graph: this.graph,\n container: document.createElement('div'),\n width: 150,\n height: 100,\n padding: 10\n })\n\n // 渲染节点\n this.renderNodes()\n \n // 渲染连线\n this.renderEdges()\n \n // 节点点击事件\n this.graph.on('node:click', ({ node }) => {\n const nodeId = node.id\n const nodeData = this.flowNodes.find(n => n.id === nodeId)\n if (nodeData) {\n this.selectedNode = { ...nodeData }\n }\n })\n \n // 画布点击事件,关闭面板\n this.graph.on('blank:click', () => {\n this.selectedNode = null\n })\n\n // 自动调整画布大小\n scroller.center()\n },\n \n renderNodes() {\n // 创建节点\n this.flowNodes.forEach(node => {\n let fillColor, strokeColor\n \n // 根据节点类型设置不同样式\n switch (node.type) {\n case 'start':\n case 'end':\n fillColor = '#409EFF'\n strokeColor = '#409EFF'\n break\n case 'condition':\n fillColor = '#FFF'\n strokeColor = '#E6A23C'\n break\n case 'process':\n default:\n fillColor = '#FFF'\n strokeColor = '#409EFF'\n break\n }\n \n // 计算节点宽度根据文本长度\n let width = Math.max(80, node.label.length * 16)\n \n // 创建节点形状\n const nodeShape = node.type === 'condition'\n ? 'flow-node-diamond' // 条件节点用菱形\n : (node.type === 'start' || node.type === 'end')\n ? 'flow-node-circle' // 开始/结束用圆形\n : 'flow-node-rect' // 其它用矩形\n \n // 添加节点到画布\n this.graph.addNode({\n id: node.id,\n x: node.x - width / 2,\n y: node.y - 30,\n width: node.type === 'condition' ? 80 : width,\n height: node.type === 'condition' ? 80 : 60,\n shape: nodeShape,\n attrs: {\n body: {\n fill: fillColor,\n stroke: strokeColor,\n strokeWidth: 2,\n rx: node.type === 'process' ? 6 : 0,\n ry: node.type === 'process' ? 6 : 0\n },\n label: {\n text: node.label,\n fill: node.type === 'start' || node.type === 'end' ? '#FFF' : '#333',\n fontSize: 14,\n fontWeight: 500\n }\n },\n data: {\n type: node.type,\n url: node.url\n },\n ports: {\n groups: {\n in: {\n position: 'top',\n attrs: {\n circle: {\n r: 4,\n magnet: true,\n stroke: strokeColor,\n fill: '#FFF'\n }\n }\n },\n out: {\n position: 'bottom',\n attrs: {\n circle: {\n r: 4,\n magnet: true,\n stroke: strokeColor,\n fill: '#FFF'\n }\n }\n }\n },\n items: [\n { id: `${node.id}-in`, group: 'in' },\n { id: `${node.id}-out`, group: 'out' }\n ]\n }\n })\n })\n },\n \n renderEdges() {\n // 绘制连线\n this.flowEdges.forEach(edge => {\n // 确定连线样式\n const isConditionEdge = this.flowNodes.find(n => n.id === edge.source)?.type === 'condition'\n const strokeColor = isConditionEdge ? '#E6A23C' : '#409EFF'\n const strokeDasharray = edge.label.includes('不通过') ? '5,2' : undefined\n \n this.graph.addEdge({\n source: { cell: edge.source, port: `${edge.source}-out` },\n target: { cell: edge.target, port: `${edge.target}-in` },\n label: edge.label,\n attrs: {\n line: {\n stroke: strokeColor,\n strokeWidth: 2,\n targetMarker: {\n name: 'block',\n width: 12,\n height: 8,\n fill: strokeColor\n },\n strokeDasharray\n }\n },\n labels: [\n {\n attrs: {\n text: {\n text: edge.label,\n fill: strokeColor,\n fontSize: 12,\n textAnchor: 'middle',\n textVerticalAnchor: 'middle'\n },\n rect: {\n fill: '#FFF',\n stroke: strokeColor,\n strokeWidth: 0.5,\n rx: 3,\n ry: 3,\n refWidth: '100%',\n refHeight: '100%',\n refX: 0,\n refY: 0\n }\n },\n position: {\n distance: 0.5\n }\n }\n ]\n })\n })\n },\n \n zoomGraph(delta) {\n const zoom = this.graph.zoom()\n if ((delta > 0 && zoom < 2) || (delta < 0 && zoom > 0.5)) {\n this.graph.zoom(delta)\n }\n },\n \n resetGraph() {\n this.graph.zoomTo(1)\n this.graph.centerContent()\n },\n \n openNodeUrl() {\n if (!this.selectedNode) return\n \n const url = this.selectedNode.url\n if (url) {\n if (url.startsWith('http')) {\n window.open(url, '_blank')\n } else {\n this.$router.push(url).catch(err => {\n if (err.name !== 'NavigationDuplicated') {\n ElMessage({\n type: 'info',\n message: `正在跳转到${this.selectedNode.label}页面...`\n })\n }\n })\n }\n }\n },\n \n closePanel() {\n this.selectedNode = null\n },\n \n addNewNode() {\n // 打开节点添加对话框\n this.$confirm('此功能将在完整版中提供节点添加与编辑功能,确认查看设计方案?', '新增节点', {\n confirmButtonText: '确定',\n cancelButtonText: '取消',\n type: 'warning'\n }).then(() => {\n // 显示设计方案信息\n ElMessage({\n type: 'success',\n message: '完整版将支持:1.拖拽添加新节点 2.编辑节点属性 3.保存自定义流程 4.流程模板管理',\n duration: 5000\n })\n }).catch(() => {})\n }\n }\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.x6-flow-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n background-color: #f7f9fc;\n padding: 20px;\n border-radius: 8px;\n box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05);\n}\n\n.flow-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 20px;\n padding-bottom: 10px;\n border-bottom: 1px solid #ebeef5;\n \n h2 {\n margin: 0;\n color: #2c3e50;\n font-size: 22px;\n font-weight: 600;\n }\n \n .flow-actions {\n display: flex;\n gap: 10px;\n }\n}\n\n.graph-container {\n position: relative;\n flex: 1;\n min-height: 600px;\n border: 1px solid #ebeef5;\n border-radius: 4px;\n background-color: #fff;\n overflow: hidden;\n}\n\n#x6-graph-container {\n width: 100%;\n height: 100%;\n}\n\n// 自定义节点样式\n:global(.flow-node-rect) {\n &:hover {\n filter: drop-shadow(0px 4px 10px rgba(64, 158, 255, 0.3));\n }\n}\n\n:global(.flow-node-diamond) {\n &:hover {\n filter: drop-shadow(0px 4px 10px rgba(230, 162, 60, 0.3));\n }\n}\n\n:global(.flow-node-circle) {\n &:hover {\n filter: drop-shadow(0px 4px 10px rgba(64, 158, 255, 0.4));\n }\n}\n\n// 节点信息面板\n.node-info-panel {\n position: absolute;\n top: 20px;\n right: 20px;\n width: 250px;\n background-color: #fff;\n border-radius: 8px;\n box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);\n padding: 15px;\n z-index: 100;\n \n h3 {\n margin-top: 0;\n margin-bottom: 15px;\n font-size: 16px;\n color: #2c3e50;\n border-bottom: 1px solid #ebeef5;\n padding-bottom: 10px;\n }\n \n .info-item {\n display: flex;\n margin-bottom: 10px;\n \n .label {\n width: 60px;\n color: #606266;\n font-weight: 600;\n }\n \n .value {\n flex: 1;\n color: #303133;\n word-break: break-all;\n }\n }\n \n .actions {\n display: flex;\n justify-content: flex-end;\n margin-top: 15px;\n gap: 10px;\n }\n}\n\n// 响应式布局\n@media screen and (max-width: 768px) {\n .x6-flow-container {\n padding: 10px;\n }\n \n .flow-header {\n flex-direction: column;\n align-items: flex-start;\n \n h2 {\n margin-bottom: 10px;\n font-size: 18px;\n }\n }\n \n .node-info-panel {\n width: calc(100% - 40px);\n top: auto;\n bottom: 20px;\n }\n}\n\n// 自定义Vue节点组件样式\n.custom-node {\n width: 100%;\n height: 100%;\n border-radius: 6px;\n display: flex;\n align-items: center;\n justify-content: center;\n \n &.start, &.end {\n background-color: #409EFF;\n color: #fff;\n border-radius: 30px;\n }\n \n &.condition {\n background-color: #fff;\n border: 2px solid #E6A23C;\n color: #E6A23C;\n transform: rotate(45deg);\n \n .node-label {\n transform: rotate(-45deg);\n }\n }\n \n &.process {\n background-color: #fff;\n border: 2px solid #409EFF;\n color: #303133;\n }\n \n .node-label {\n font-size: 14px;\n font-weight: 500;\n text-align: center;\n padding: 0 6px;\n }\n}\n</style> "],"mappings":"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","ignoreList":[]},"metadata":{},"sourceType":"module","externalDependencies":[]}
|