应用系统定制开发Vue项目里面使用jsmind.js插件来制作思维导图页面完成需求

提示:应用系统定制开发文章写完后,应用系统定制开发目录可以自动生成,应用系统定制开发如何生成可参考右边的帮助文档

目录


前言

应用系统定制开发在做的一个项目中,应用系统定制开发需要制作一个类似于Xmind应用系统定制开发的里面的一种的操作页面,应用系统定制开发里面是可编辑的节点,应用系统定制开发这里就不好使用echarts应用系统定制开发里面的树图,应用系统定制开发最后找到了这个jsmind.js的插件,应用系统定制开发就是用于生产页面版的应用系统定制开发思维树图之类的,应用系统定制开发官方文档篇幅属实有限,应用系统定制开发而且页面是根据需求来改动的,应用系统定制开发以此记录这个页面的实现。


一、应用系统定制开发最终页面效果展示

如图, 应用系统定制开发这个页面需要能动态添应用系统定制开发加自定义的节点,应用系统定制开发且每个节点的数据是可应用系统定制开发以下拉选择并且每一个应用系统定制开发都有对应的自定义设置的权重,应用系统定制开发我们先根据需求整理大应用系统定制开发体功能思路。

一、先使用jsmind应用系统定制开发插件来生成一个基本的模块。

二、应用系统定制开发根节点的模型组名是固定的,应用系统定制开发这里不应该让它能编辑,应用系统定制开发同时第一级的模型名节应用系统定制开发点分为两大类,应用系统定制开发我们可以在点击开始建模后初始化时生成一个固定的根节点以及两个不同类型的模型名一级节点的卡片。

三、通过自定义右键菜单来添加三个功能,分别是 添加同级、添加子级以及删除卡片。

四、动态获取一级子节点的模型名数据以及对应的二级子节点的标签分类数据以及三级子节点的标签名数据,其中每个数据中都是带有对应的权重的。

五、当每一个卡片节点切换时,对应的子节点的数据也需要动态切换。

六、当每一个卡片重新设置权重时,对应的卡片选项中的权重也要进行关联。

二、jsmind.js

官方链接:  

1.项目引入并使用

通过 npm install jsmind --save 安装插件

在 vue 页面文件里面引入并使用( 只需在当前这个需要制作的页面文件中使用即可 ):

  1. import 'jsmind/style/jsmind.css';
  2. import jsMind from 'jsmind/js/jsmind.js';
  3. require('jsmind/js/jsmind.draggable.js');
  4. require('jsmind/js/jsmind.screenshot.js');

2.基本使用

代码如下(示例):

基本的使用以及其他的一些功能可以参考下这篇博客,我当初也是从这里进行参考的。


三、功能实现

 由于目前的页面已基本完成,所以不可能每部分的代码都是十分清晰的,且由于当时以实现功能为首要目标,代码中存在大量的冗余,尽量在进行优化,主要细说一下每一步的思路以及解决方案和遇到的问题。每个模块的代码由于功能的上下连接,单独模块放出来意义不大,且很难读懂,有些地方附上一些关键代码,其他整个文件代码到时候放在最后。

一、基本的架构及交互

由设计图可知,该页面需先输入根节点的模型组名然后点击开始建模按钮后,生成基本的架构思维图。这里主要是要注意一点,点击开始建模按钮之前,先判断用户是否有输入,同时,开始建模按钮点击之后,就应该禁用掉,点击了重新建模按钮之后,再放开开始建模按钮。

由于第二子级的标签分类是固定的,所以先按照分类写成固定数据,但是第三子级的标签名得通过不同的分类来进行瓜分,所以这个数据方面还是有点复杂的,参考性不高,更多只是个人记录。数据分类结构如下:

  1. resultData: {
  2. personList: [],
  3. relationList: [],
  4. labelTypeList: {
  5. pointType: [
  6. { label: '自身属性标签', value: 'property', weight: 1 },
  7. { label: '自身行为标签', value: 'action', weight: 1 }
  8. ],
  9. relationType: [
  10. { label: '实质关系标签', value: 'substance', weight: 1 },
  11. { label: '疑似关系标签', value: 'suspected', weight: 1 },
  12. { label: '增强关系标签', value: 'strengthen', weight: 1 }
  13. ]
  14. },
  15. labelNameList: {
  16. pointLabel: [], // 当前选中的模型 所有的个人标签
  17. relationLabel: [], // 当前选中的模型 所有的关系标签
  18. // 五大类的标签名列表数据
  19. propertyLabelList: [],
  20. actionLabelList: [],
  21. substanceLabelList: [],
  22. suspectedLabelList: [],
  23. strengthenLabelList: []
  24. }
  25. }

二、生成思维导图以及添加右键自定义菜单

上面的 initModelChart() 方法就是初始化生成图形,同时,我们需要给每一个卡片添加点击事件,并且卡片里面的是html元素,这里我们需要在一个js文件里面进行原生html的生成,方便添加。

用于生成卡片节点元素以及其他元素的js文件, createDom.js :

  1. /* eslint-disable no-useless-escape */
  2. class CreateDom {
  3. // 获取根卡片 模型组名
  4. static getModelRootDom(modelInfo) {
  5. return `
  6. <div class="model-edit-card" style="background-color: ${modelInfo.bgc}" >
  7. <div class="model-info">
  8. <p class="model-title-p">模型组名</p>
  9. <div class="model-name-info">
  10. <p><span>${modelInfo.modelName}</span></p>
  11. </div>
  12. </div>
  13. </div>
  14. `;
  15. }
  16. // 获取子级卡片 模型名/标签
  17. static getModelCardDom(modelInfo) {
  18. let selectList = ``;
  19. for (let i = 0; i < modelInfo.modelSelectList.length; i++) {
  20. selectList += `<option value="${modelInfo.modelSelectList[i].value}">${modelInfo.modelSelectList[i].label}</option>`;
  21. }
  22. return `
  23. <div class="model-edit-card" style="background-color: ${modelInfo.bgc}" >
  24. <div class="model-info">
  25. <p class="model-title-p">${modelInfo.modelTitle}</p>
  26. <div class="model-name-info">
  27. <select class="select-model-list" data-type='${modelInfo.modelType}' data-title='${modelInfo.modelTitle}' >
  28. ${selectList}
  29. </select>
  30. </div>
  31. </div>
  32. <div class="model-weight" >
  33. <p>权重</p>
  34. <input
  35. type='text'
  36. data-label='${modelInfo.selectOption}'
  37. data-model='${modelInfo.selectModelId}'
  38. data-level='${modelInfo.level}'
  39. data-type='${modelInfo.modelType}'
  40. class="model-weight-input"
  41. placeholder=""
  42. onkeyup="!/^(\d+\.?)?\d{0,1}$/.test(this.value)?(this.value=this.value.substring(0, this.value.length-1)): ''"
  43. value=${modelInfo.modelWeight}>
  44. </input>
  45. </div>
  46. </div>
  47. `;
  48. }
  49. // 生成自定义右键菜单
  50. static getContextMenu() {
  51. return `
  52. <el-menu
  53. class="context-menu"
  54. v-show="showMenu"
  55. :style="{
  56. left: menuStyle.left,
  57. top: menuStyle.top,
  58. bottom: menuStyle.bottom,
  59. right: menuStyle.right
  60. }"
  61. ref="context">
  62. <slot>
  63. <el-menu-item @click="addBrother">插入平级</el-menu-item>
  64. <el-menu-item @click="addChild">插入子级</el-menu-item>
  65. <el-menu-item @click="delCard">删除卡片</el-menu-item>
  66. </slot>
  67. </el-menu>
  68. `;
  69. }
  70. // 获取固定的初始化数据
  71. static getInitData(params) {
  72. return [
  73. {
  74. id: 'point', // 必选 ID, 所有节点的 id 不应该重复,否则 重复id的结节将被忽略
  75. topic: CreateDom.getModelCardDom({ bgc: '#0FA984', modelTitle: '模型名', modelSelectList: params.personList, modelType: 'point', selectOption: params.personList[0].label, selectModelId: params.personList[0].value, level: 1, modelWeight: 1 }), // 必填 节点上显示的内容
  76. direction: 'right', // 可选 节点的方向 此数据仅在第一层节点上有效,目前仅支持 left 和 right 两种,默认为 right
  77. expanded: true, // [可选] 该节点是否是展开状态,默认为 true
  78. level: 1,
  79. type: 'point',
  80. title: '模型名',
  81. children: []
  82. },
  83. {
  84. id: 'relation', // 必选 ID, 所有节点的 id 不应该重复,否则 重复id的结节将被忽略
  85. topic: CreateDom.getModelCardDom({ bgc: '#0FA984', modelTitle: '模型名', modelSelectList: params.relationList, modelType: 'relation', selectOption: params.relationList[0].label, selectModelId: params.relationList[0].value, level: 1, modelWeight: 1 }), // 必填 节点上显示的内容
  86. direction: 'right', // 可选 节点的方向 此数据仅在第一层节点上有效,目前仅支持 left 和 right 两种,默认为 right
  87. expanded: true, // [可选] 该节点是否是展开状态,默认为 true
  88. level: 1,
  89. type: 'relation',
  90. title: '模型名',
  91. children: []
  92. }
  93. ];
  94. }
  95. }
  96. export default CreateDom;

在vue文件里面引入

import CreateDom from '@/tools/CreateDom.js';

其中 initModelChart 方法的代码:

  1. data() {
  2. return {
  3. mind: {
  4. // 元数据 定义思维导图的名称、 作者、版本等信息
  5. meta: {
  6. name: '建模导图',
  7. author: 'ck',
  8. version: '0.2'
  9. },
  10. // 数据格式声明
  11. format: 'node_tree',
  12. // 数据内容
  13. data: {
  14. id: 'root',
  15. topic: '',
  16. direction: 'right',
  17. expanded: true,
  18. children: []
  19. }
  20. },
  21. options: {
  22. container: 'create-model-chart', // [必选] 容器的ID
  23. editable: true, // [可选] 是否启用编辑
  24. theme: '', // [可选] 主题
  25. support_html: true,
  26. mode: 'full', // 显示模式
  27. view: {
  28. engine: 'canvas', // 思维导图各节点之间线条的绘制引擎
  29. hmargin: 120, // 思维导图距容器外框的最小水平距离
  30. vmargin: 50, // 思维导图距容器外框的最小垂直距离
  31. line_width: 4, // 思维导图线条的粗细
  32. line_color: '#FFCC73', // 思维导图线条的颜色
  33. draggable: true, // 当容器不能完全容纳思维导图时,是否允许拖动画布代替鼠标滚动
  34. hide_scrollbars_when_draggable: true // 当设置 draggable = true 时,是否隐藏滚动条
  35. },
  36. layout: {
  37. hspace: 100, // 节点之间的水平间距
  38. vspace: 20, // 节点之间的垂直间距
  39. pspace: 20 // 节点与连接线之间的水平间距(用于容纳节点收缩/展开控制器)
  40. },
  41. shortcut: {
  42. enable: false // 是否启用快捷键 默认为true
  43. },
  44. menuOpts: {
  45. showMenu: true,
  46. injectionList: [
  47. { target: 'addBrother', text: '添加同级卡片', callback: function (node) { console.log(node); } },
  48. { target: 'delete', text: '删除卡片', callback: function (node) { console.log(node); } }
  49. ]
  50. },
  51. isShow: true
  52. }
  53. }
  54. }
  55. initModelChart() {
  56. this.mind.data.topic = CreateDom.getModelRootDom(this.rootModel);
  57. this.mind.data.children = CreateDom.getInitData(this.resultData);
  58. this.$nextTick(() => {
  59. this.jm = jsMind.show(this.options, this.mind);
  60. this.chartLoading = false;
  61. // let testSelect = this.jm.get_node('easy');
  62. // console.log(testSelect, 'tes');
  63. const modelChart = document.getElementById('create-model-chart');
  64. modelChart.addEventListener('mousedown', e => {
  65. e.stopPropagation();
  66. this.showMenu = false;
  67. // console.log(e, '99666');
  68. // this.showTheMenu(e);
  69. let selectCardId = '';
  70. if (Array.isArray(e.path)) {
  71. e.path.map(item => {
  72. if (item.localName == 'jmnode') {
  73. // console.log(item.attributes[0].nodeValue, '3030');
  74. selectCardId = item.attributes[0].nodeValue;
  75. }
  76. });
  77. // console.log(selectCardId, 'sed');
  78. if (selectCardId == 'root') {
  79. this.showMenu = false;
  80. return this.$message.warning('根节点无法编辑');
  81. } else if (!selectCardId) {
  82. this.showMenu = false;
  83. return false;
  84. }
  85. this.theSelectNode = this.jm.get_node(selectCardId);
  86. // console.log(this.theSelectNode, '2200');
  87. // console.log(selectCardId, '0022');
  88. this.clickSelectCard(selectCardId);
  89. this.findClickCardIndex(this.theSelectNode.data.type, this.theSelectNode.data.level, this.theSelectNode.id);
  90. }
  91. });
  92. this.addSelectChangeFunc();
  93. this.addInputBlurFunc();
  94. });
  95. }

其中,给每个节点添加点击事件,由于有后续添加的节点,所以最好绑定在父节点上面,通过事件捕获,找到是卡片的节点,给这个卡片添加对应的操作。相关的操作方法代码放在整体里面,这里不做详细展示,主要是看如何通过原生js找到节点位置并对该选中的节点进行添加自定义的鼠标右键菜单, 这里即是 clickSelectCard 这个方法,代码如下:

  1. clickSelectCard(nodeId) {
  2. this.editor = this.jm.view.e_editor;
  3. // jsmind 添加自定义菜单事件
  4. this.jm.view.add_event(this.editor, 'contextmenu', (e) => {
  5. const selectedNode = this.jm.get_node(nodeId);
  6. // && selectedNode.data.type
  7. if (selectedNode) {
  8. e.preventDefault();
  9. const el = document.querySelector('.context-menu .el-menu-item');
  10. const width = parseFloat(window.getComputedStyle(el).width);
  11. const height = parseFloat(window.getComputedStyle(el).height) * 3 + 12;
  12. const windowHeight = window.innerHeight;
  13. const windowWidth = window.innerWidth;
  14. // 极限位置 避免越界
  15. if (e.clientY + height > windowHeight) {
  16. // console.log('23');
  17. this.menuStyle.left = e.clientX + 'px';
  18. this.menuStyle.top = 'unset';
  19. this.menuStyle.bottom = 0;
  20. } else if (e.clientX + width > windowWidth) {
  21. // console.log('24');
  22. this.menuStyle.top = e.clientY + 'px';
  23. this.menuStyle.left = 'unset';
  24. this.menuStyle.right = 0;
  25. } else {
  26. // console.log('25');
  27. this.menuStyle.left = e.clientX - 210 + 'px';
  28. this.menuStyle.top = e.clientY - 150 + 'px';
  29. this.menuStyle.bottom = 'unset';
  30. }
  31. this.showMenu = true;
  32. } else {
  33. this.showMenu = false;
  34. }
  35. });
  36. }

这里的菜单位置可能不太对,需要自己来进行调整。

三、自定义菜单的添加平级、添加子级、删除卡片的功能

这里主要通过找到是哪一个节点右键了,根据这个节点来做相应的功能,其中菜单的元素代码如下:

  1. <el-menu
  2. class="context-menu"
  3. v-show="showMenu"
  4. :style="{
  5. left: menuStyle.left,
  6. top: menuStyle.top,
  7. bottom: menuStyle.bottom,
  8. right: menuStyle.right,
  9. }"
  10. ref="context">
  11. <slot>
  12. <el-menu-item @click="addBrother">插入平级</el-menu-item>
  13. <el-menu-item @click="addChild">插入子级</el-menu-item>
  14. <el-menu-item @click="deleteCard">删除卡片</el-menu-item>
  15. </slot>
  16. </el-menu>
  17. .context-menu {
  18. position: absolute;
  19. width: 8.3333rem;
  20. z-index: 32;
  21. }

由于添加同级和添加子级都是用的同一个api,官方里面的往元素后面添加节点的方法其实并不是添加子级,这里添加子级只需要把当前选中的卡片节点的id设置为父级id即可。

这里先写一个方法返回添加节点时需要的对象数据,如下:

  1. // 添加卡片的方法 获得相关的数据对象
  2. whileCardAddFunc(type, node) {
  3. var funcObj = {};
  4. console.log(node, 'node');
  5. // type 进行 同级 bother 或者 子级 children 的分类 this.resultData.personList[0].label
  6. if (type == 'bother') {
  7. if (node.data.level == '1') {
  8. node.data.type == 'point' ? this.pointLevel1Index++ : this.relationLevel1Index++;
  9. funcObj.parentId = node.parent.id;
  10. funcObj.id = new Date().getTime() + parseFloat(Math.random() * 1000);
  11. funcObj.topic = CreateDom.getModelCardDom({ bgc: '#0FA984', modelTitle: '模型名', modelSelectList: node.data.type == 'point' ? this.resultData.personList : this.resultData.relationList, modelType: node.data.type, selectOption: node.data.type == 'point' ? this.resultData.personList[0].label : this.resultData.relationList[0].label, selectModelId: node.data.type == 'point' ? this.resultData.personList[0].value : this.resultData.relationList[0].value, level: 1, modelWeight: 1 });
  12. funcObj.data = {
  13. direction: 1,
  14. expanded: true,
  15. level: 1,
  16. type: node.data.type,
  17. children: []
  18. };
  19. // 判断是 个人模型 还是 关系 模型 往 已选则的 list 里面进行 push 一个
  20. this.addLabelValueWeight(node.data.type, 1, funcObj.id);
  21. } else if (node.data.level == '2') {
  22. node.data.type == 'point' ? this.pointLevel2Index++ : this.relationLevel2Index++;
  23. funcObj.parentId = node.parent.id;
  24. funcObj.id = new Date().getTime() + parseFloat(Math.random() * 1000);
  25. funcObj.topic = CreateDom.getModelCardDom({ bgc: '#5B9BD5', modelTitle: '标签分类', modelSelectList: node.data.type == 'point' ? this.resultData.labelTypeList.pointType : this.resultData.labelTypeList.relationType, modelType: node.data.type, selectOption: node.data.type == 'point' ? this.resultData.labelTypeList.pointType[0].label : this.resultData.labelTypeList.relationType[0].label, selectModelId: node.data.type == 'point' ? this.resultData.labelTypeList.pointType[0].value : this.resultData.labelTypeList.relationType[0].value, level: 2, modelWeight: this.findTheCardWeight(node.data.type, 2) });
  26. funcObj.data = {
  27. direction: 'right',
  28. expanded: true,
  29. level: 2,
  30. type: node.data.type,
  31. children: []
  32. };
  33. this.addLabelValueWeight(node.data.type, 2, funcObj.id);
  34. } else if (node.data.level == '3') {
  35. let optionList = this.getLabelNameListBySort(node.data.type, node.data.type == 'point' ? this.selectPonitLabelSort : this.selectRelationLabelSort);
  36. node.data.type == 'point' ? this.pointLevel3Index++ : this.relationLevel3Index++;
  37. funcObj.parentId = node.parent.id;
  38. funcObj.id = new Date().getTime() + parseFloat(Math.random() * 1000);
  39. funcObj.topic = CreateDom.getModelCardDom({ bgc: '#E3950E', modelTitle: '标签名', modelSelectList: optionList, modelType: node.data.type, selectOption: optionList.length > 0 ? optionList[0].label : '', selectModelId: optionList.length > 0 ? optionList[0].value : '', level: 3, modelWeight: this.findTheCardWeight(node.data.type, 3, optionList.length > 0 ? optionList[0].label : '') });
  40. funcObj.data = {
  41. level: 3,
  42. type: node.data.type
  43. };
  44. this.addLabelValueWeight(node.data.type, 3, funcObj.id);
  45. }
  46. } else if (type == 'children') {
  47. if (node.data.level == '1') {
  48. console.log(this.findTheCardWeight(node.data.type, 2), 'classWei');
  49. node.data.type == 'point' ? this.pointLevel2Index++ : this.relationLevel2Index++;
  50. funcObj.afterId = node.id;
  51. funcObj.id = new Date().getTime() + parseFloat(Math.random() * 1000);
  52. funcObj.topic = CreateDom.getModelCardDom({ bgc: '#5B9BD5', modelTitle: '标签分类', modelSelectList: node.data.type == 'point' ? this.resultData.labelTypeList.pointType : this.resultData.labelTypeList.relationType, modelType: node.data.type, selectOption: node.data.type == 'point' ? this.resultData.labelTypeList.pointType[0].label : this.resultData.labelTypeList.relationType[0].label, selectModelId: node.data.type == 'point' ? this.resultData.labelTypeList.pointType[0].value : this.resultData.labelTypeList.relationType[0].value, level: 2, modelWeight: this.findTheCardWeight(node.data.type, 2) });
  53. funcObj.data = {
  54. direction: 'right',
  55. expanded: true,
  56. level: 2,
  57. type: node.data.type,
  58. children: []
  59. };
  60. this.addLabelValueWeight(node.data.type, 2, funcObj.id);
  61. } else if (node.data.level == '2') {
  62. let optionsList = this.getLabelNameListBySort(node.data.type, node.data.type == 'point' ? this.selectPonitLabelSort : this.selectRelationLabelSort);
  63. node.data.type == 'point' ? this.pointLevel3Index++ : this.relationLevel3Index++;
  64. funcObj.afterId = node.id;
  65. funcObj.id = new Date().getTime() + parseFloat(Math.random() * 1000);
  66. funcObj.topic = CreateDom.getModelCardDom({ bgc: '#E3950E', modelTitle: '标签名', modelSelectList: optionsList, modelType: node.data.type, selectOption: optionsList.length > 0 ? optionsList[0].label : '', selectModelId: optionsList.length > 0 ? optionsList[0].value : '', level: 3, modelWeight: this.findTheCardWeight(node.data.type, 3, optionsList.length > 0 ? optionsList[0].label : '') });
  67. funcObj.data = {
  68. level: 3,
  69. type: node.data.type
  70. };
  71. this.addLabelValueWeight(node.data.type, 3, funcObj.id);
  72. } else if (node.data.level == '3') {
  73. funcObj.error = true;
  74. funcObj.msg = '无法再进行下一级的分类添加';
  75. }
  76. }
  77. let copyObj = JSON.parse(JSON.stringify(funcObj));
  78. // console.log(copyObj, '30369');
  79. return copyObj;
  80. }

由于最后第三级的标签名卡片是不能再往后面添加子级了,所以设置一个error为true,并返回一个msg,这里需要注意的是,我们需要设置 options 里面的 editable 属性为 true,开启编辑,否则是无法进行节点卡片的添加的,这样有一个不好的地方就是双击卡片会变成html元素的input输入框,在使用时需要注意。

添加同级卡片的方法:

  1. // 添加同级卡片
  2. addBrother() {
  3. // parent_node, node_id, topic, data
  4. let cardObj = this.whileCardAddFunc('bother', this.theSelectNode);
  5. // console.log(cardObj, 'cla');
  6. this.jm.add_node(cardObj.parentId, cardObj.id, cardObj.topic, cardObj.data);
  7. this.showMenu = false;
  8. this.addSelectChangeFunc();
  9. this.addInputBlurFunc();
  10. }

添加子级卡片的方法:

  1. // 添加子卡片
  2. addChild() {
  3. // node_after, node_id, topic, data
  4. // 判断是哪个层级 1 模型名 2 标签分类 3 标签名
  5. let cardObj = this.whileCardAddFunc('children', this.theSelectNode);
  6. // console.log(cardObj, '6688');
  7. if (cardObj.error) {
  8. this.showMenu = false;
  9. return this.$message.warning(cardObj.msg);
  10. }
  11. this.jm.add_node(cardObj.afterId, cardObj.id, cardObj.topic, cardObj.data);
  12. this.showMenu = false;
  13. this.addSelectChangeFunc();
  14. this.addInputBlurFunc();
  15. }

这里最后的两个方法,是卡片里面的select下拉框的切换方法和权重input输入框的blur方法,在生成新的卡片时,需要给所有的卡片重新绑定事件,否则新生成的卡片是不带下拉框的change和输入框的blur事件的,这里使用 onchange和 onblur 方法来进行监听, 重新设置时会覆盖掉原来的方法,不推荐使用 addEventListener,因为不会覆盖,会重复执行。

删除卡片的方法:

  1. let that = this;
  2. // let deleteNode = JSON.parse(JSON.stringify(this.theSelectNode));
  3. let deleteNode = StringTools.cloneDeepObj(that.theSelectNode);
  4. this.$confirm(
  5. '删除此节点卡片(包含所有子级卡片), 是否继续?',
  6. '提示',
  7. {
  8. confirmButtonText: '确定',
  9. cancelButtonText: '取消',
  10. type: 'warning'
  11. }
  12. ).then(() => {
  13. // 删除卡片
  14. if (deleteNode.data.type == 'point') {
  15. if (deleteNode.data.level == 1) {
  16. if (that.haveSelectPointModelAndWeight.length <= 1) {
  17. return that.$message.warning('至少保留一个个人模型名卡片');
  18. }
  19. that.haveSelectPointModelAndWeight.map((item, index) => {
  20. if (item.boxId == deleteNode.id) {
  21. that.haveSelectPointModelAndWeight.splice(index, 1);
  22. }
  23. });
  24. } else if (deleteNode.data.level == 2) {
  25. that.haveSelectPointModelAndWeight[that.haveSelectPointIndex].children.map((item, index) => {
  26. if (item.boxId == deleteNode.id) {
  27. that.haveSelectPointModelAndWeight[that.haveSelectPointIndex].children.splice(index, 1);
  28. }
  29. });
  30. } else if (deleteNode.data.level == 3) {
  31. that.haveSelectPointModelAndWeight[that.haveSelectPointIndex].children[that.haveSelectPointLabelClassIndex].children.map((item, index) => {
  32. if (item.boxId == deleteNode.id) {
  33. that.haveSelectPointModelAndWeight[this.haveSelectPointIndex].children[that.haveSelectPointLabelClassIndex].children.splice(index, 1);
  34. }
  35. });
  36. }
  37. } else {
  38. if (deleteNode.data.level == 1) {
  39. if (that.haveSelectRelationModelAndWeight.length <= 1) {
  40. return that.$message.warning('至少保留一个关系模型名卡片');
  41. }
  42. that.haveSelectRelationModelAndWeight.map((item, index) => {
  43. if (item.boxId == deleteNode.id) {
  44. that.haveSelectRelationModelAndWeight.splice(index, 1);
  45. }
  46. });
  47. } else if (deleteNode.data.level == 2) {
  48. that.haveSelectRelationModelAndWeight[that.haveSelectRelationIndex].children.map((item, index) => {
  49. if (item.boxId == deleteNode.id) {
  50. that.haveSelectRelationModelAndWeight[that.haveSelectRelationIndex].children.splice(index, 1);
  51. }
  52. });
  53. } else if (deleteNode.data.level == 3) {
  54. that.haveSelectRelationModelAndWeight[that.haveSelectRelationIndex].children[that.haveSelectPointLabelClassIndex].children.map((item, index) => {
  55. if (item.boxId == deleteNode.id) {
  56. that.haveSelectRelationModelAndWeight[that.haveSelectRelationIndex].children[that.haveSelectRelationLabelNameIndex].children.splice(index, 1);
  57. }
  58. });
  59. }
  60. }
  61. setTimeout(() => {
  62. that.jm.remove_node(that.theSelectNode.id);
  63. }, 50);
  64. that.showMenu = false;
  65. }).catch(() => {});

主要是调用 remove_node 这个api进行删除,上面一大堆代码只是用来同步移除已保存的数据,主要思路就是找到卡片数据在对应的数据树里的位置,进行删除。

四、给所有的卡片添加

这一步是整个功能的难点,一步步进行剖析,首先我们需要找到选中切换的卡片,进行类型判断,然后再进行级别判断,切换了第一子级的话,那么第三子级的数据得同步更改,切换了第二子级,第三子级的数据也需要进行更改,切换了第三子级,那么只需要更改保存的数据即可。这里的难点在于我们的select里面的options是原生html生成的,更新的话,需要用到 update_node 这个api,这时需要第三子级的卡片添加一些自定义的属性来进行对第一子级和第二子级的数据绑定,要清晰的知道每一个卡片是属于哪一个位置,方便后面保存时拿到整个树形的数据。

事件代码如下:

  1. // 给所有的select下拉框添加change事件
  2. addSelectChangeFunc() {
  3. let that = this;
  4. let allSelectDom = document.querySelectorAll('.select-model-list');
  5. // console.log(allSelectDom, 'cmcnc');
  6. for (let i = 0; i < allSelectDom.length; i++) {
  7. // 先清除change事件 selectFunction(allSelectDom[i])
  8. // allSelectDom[i].removeEventListener('change', selectFunction);
  9. // 使用 onchange 生成的新卡片也需要添加 这个change监听事件 用 onchange 进行覆盖 不会重复执行
  10. allSelectDom[i].onchange = async (e) => {
  11. // console.log(allSelectDom[i], 'lbn');
  12. console.log(e, 'echa');
  13. let selectLevel = allSelectDom[i].dataset.title == '模型名' ? 1 : (allSelectDom[i].dataset.title == '标签分类' ? 2 : 3);
  14. // 从节点上面查到到当前选中的option 进行 权重 input 的 自定义属性的更新
  15. e.path.map((item, index) => {
  16. if (item.className == 'model-edit-card') {
  17. e.path[index].children[1].children[1].dataset.label = allSelectDom[i].options[allSelectDom[i].selectedIndex].text;
  18. e.path[index].children[1].children[1].dataset.model = allSelectDom[i].value;
  19. e.path[index].children[1].children[1].value = that.findTheCardWeight(allSelectDom[i].dataset.type, selectLevel, allSelectDom[i].options[allSelectDom[i].selectedIndex].text);
  20. }
  21. });
  22. // 获取选中的 label 值
  23. // console.log(allSelectDom[i].options[allSelectDom[i].selectedIndex].text, '9966');
  24. // 判断切换的是哪种下拉框
  25. if (allSelectDom[i].dataset.title == '模型名') {
  26. if (allSelectDom[i].dataset.type == 'point') {
  27. this.haveSelectPointModelAndWeight[this.haveSelectPointIndex].label = allSelectDom[i].options[allSelectDom[i].selectedIndex].text;
  28. this.haveSelectPointModelAndWeight[this.haveSelectPointIndex].value = allSelectDom[i].value;
  29. this.haveSelectPointModelAndWeight[this.haveSelectPointIndex].weight = 1;
  30. // 选则的是人员模型
  31. let personLabel = await that.$http.getAllLabelName({ modelId: allSelectDom[i].value, modelType: 'point' });
  32. if (personLabel.data.flag == 1) {
  33. that.resultData.labelNameList.propertyLabelList = [];
  34. that.resultData.labelNameList.actionLabelList = [];
  35. that.resultData.labelNameList.pointLabel = personLabel.data.data.labelFields;
  36. that.resultData.labelNameList.pointLabel.map(item => {
  37. if (item.type == 'property') {
  38. let labelObj = {
  39. label: item.fieldnamecn,
  40. value: item.id
  41. };
  42. that.resultData.labelNameList.propertyLabelList.push(labelObj);
  43. } else if (item.type == 'action') {
  44. let actionObj = {
  45. label: item.fieldnamecn,
  46. value: item.id
  47. };
  48. that.resultData.labelNameList.actionLabelList.push(actionObj);
  49. }
  50. });
  51. if (that.theSelectNode.children.length > 0) {
  52. let pointOptionsList = that.getLabelNameListBySort('point', that.selectPonitLabelSort);
  53. console.log(pointOptionsList, 'pointOp');
  54. that.theSelectNode.children.map(item => {
  55. if (item.children.length > 0) {
  56. item.children.map(ele => {
  57. that.jm.update_node(ele.id, CreateDom.getModelCardDom({ bgc: '#E3950E', modelTitle: '标签名', modelSelectList: pointOptionsList, modelType: 'point', level: 3, selectOption: pointOptionsList.length > 0 ? pointOptionsList[0].label : '', selectModelId: pointOptionsList.length > 0 ? pointOptionsList[0].value : '', modelWeight: this.findTheCardWeight('poiny', 3, pointOptionsList.length > 0 ? pointOptionsList[0].label : '') }));
  58. });
  59. }
  60. });
  61. }
  62. // console.log(that.theSelectNode, '000333');
  63. // console.log(that.resultData.labelNameList.propertyLabelList, 'propl');
  64. // console.log(that.resultData.labelNameList.actionLabelList, 'actl');
  65. }
  66. } else {
  67. this.haveSelectRelationModelAndWeight[this.haveSelectRelationIndex].label = allSelectDom[i].options[allSelectDom[i].selectedIndex].text;
  68. this.haveSelectRelationModelAndWeight[this.haveSelectRelationIndex].value = allSelectDom[i].value;
  69. this.haveSelectRelationModelAndWeight[this.haveSelectRelationIndex].weight = 1;
  70. // 选则的是关系模型
  71. let initRelationLabel = await that.$http.getAllLabelName({ modelId: allSelectDom[i].value, modelType: 'relation' });
  72. if (initRelationLabel.data.flag == 1) {
  73. that.resultData.labelNameList.substanceLabelList = [];
  74. that.resultData.labelNameList.suspectedLabelList = [];
  75. that.resultData.labelNameList.strengthenLabelList = [];
  76. that.resultData.labelNameList.relationLabel = initRelationLabel.data.data.labelFields;
  77. that.resultData.labelNameList.relationLabel.map(ele => {
  78. if (ele.type == 'substance') {
  79. let substanceObj = {
  80. label: ele.fieldnamecn,
  81. value: ele.id
  82. };
  83. that.resultData.labelNameList.substanceLabelList.push(substanceObj);
  84. } else if (ele.type == 'suspected') {
  85. let suspectedObj = {
  86. label: ele.fieldnamecn,
  87. value: ele.id
  88. };
  89. that.resultData.labelNameList.suspectedLabelList.push(suspectedObj);
  90. } else if (ele.type == 'strengthen') {
  91. let strengthenObj = {
  92. label: ele.fieldnamecn,
  93. value: ele.id
  94. };
  95. that.resultData.labelNameList.strengthenLabelList.push(strengthenObj);
  96. }
  97. });
  98. if (that.theSelectNode.children.length > 0) {
  99. let relationOptionsList = that.getLabelNameListBySort('relation', that.selectRelationLabelSort);
  100. console.log(relationOptionsList, 'relaOp');
  101. that.theSelectNode.children.map(item => {
  102. if (item.children.length > 0) {
  103. item.children.map(ele => {
  104. that.jm.update_node(ele.id, CreateDom.getModelCardDom({ bgc: '#E3950E', modelTitle: '标签名', modelSelectList: relationOptionsList, modelType: 'relation', level: 3, selectOption: relationOptionsList.length > 0 ? relationOptionsList[0].label : '', selectModelId: relationOptionsList.length > 0 ? relationOptionsList[0].value : '', modelWeight: this.findTheCardWeight('relation', 3, relationOptionsList.length > 0 ? relationOptionsList[0].label : '') }));
  105. });
  106. }
  107. });
  108. }
  109. }
  110. }
  111. that.addSelectChangeFunc();
  112. that.addInputBlurFunc();
  113. } else if (allSelectDom[i].dataset.title == '标签分类') {
  114. if (allSelectDom[i].dataset.type == 'point') {
  115. this.haveSelectPointModelAndWeight[this.haveSelectPointIndex].children[this.haveSelectPointLabelClassIndex].label = allSelectDom[i].options[allSelectDom[i].selectedIndex].text;
  116. this.haveSelectPointModelAndWeight[this.haveSelectPointIndex].children[this.haveSelectPointLabelClassIndex].value = allSelectDom[i].value;
  117. this.haveSelectPointModelAndWeight[this.haveSelectPointIndex].children[this.haveSelectPointLabelClassIndex].weight = 1;
  118. that.selectPonitLabelSort = allSelectDom[i].value;
  119. if (that.theSelectNode.children.length > 0) {
  120. if (allSelectDom[i].value == 'property') {
  121. let propertyClassOptionsList = that.getLabelNameListBySort('point', 'property');
  122. console.log(propertyClassOptionsList, 'properOpt');
  123. that.theSelectNode.children.map(item => {
  124. that.jm.update_node(item.id, CreateDom.getModelCardDom({ bgc: '#E3950E', modelTitle: '标签名', modelSelectList: propertyClassOptionsList, modelType: 'point', level: 3, selectOption: propertyClassOptionsList.length > 0 ? propertyClassOptionsList[0].label : '', selectModelId: propertyClassOptionsList.length > 0 ? propertyClassOptionsList[0].value : '', modelWeight: this.findTheCardWeight('poiny', 3, propertyClassOptionsList.length > 0 ? propertyClassOptionsList[0].label : '') }));
  125. });
  126. } else if (allSelectDom[i].value == 'action') {
  127. let actionClassOptionsList = that.getLabelNameListBySort('point', 'action');
  128. console.log(actionClassOptionsList, 'actionOpi');
  129. that.theSelectNode.children.map(item => {
  130. that.jm.update_node(item.id, CreateDom.getModelCardDom({ bgc: '#E3950E', modelTitle: '标签名', modelSelectList: actionClassOptionsList, modelType: 'point', level: 3, selectOption: actionClassOptionsList.length > 0 ? actionClassOptionsList[0].label : '', selectModelId: actionClassOptionsList.length > 0 ? actionClassOptionsList[0].value : '', modelWeight: this.findTheCardWeight('poiny', 3, actionClassOptionsList.length > 0 ? actionClassOptionsList[0].label : '') }));
  131. });
  132. }
  133. }
  134. } else if (allSelectDom[i].dataset.type == 'relation') {
  135. this.haveSelectRelationModelAndWeight[this.haveSelectRelationIndex].children[this.haveSelectRelationLabelClassIndex].label = allSelectDom[i].options[allSelectDom[i].selectedIndex].text;
  136. this.haveSelectRelationModelAndWeight[this.haveSelectRelationIndex].children[this.haveSelectRelationLabelClassIndex].value = allSelectDom[i].value;
  137. this.haveSelectRelationModelAndWeight[this.haveSelectRelationIndex].children[this.haveSelectRelationLabelClassIndex].weight = 1;
  138. that.selectRelationLabelSort = allSelectDom[i].value;
  139. let relationClassOptionsList = that.getLabelNameListBySort('relation', that.selectRelationLabelSort);
  140. console.log(relationClassOptionsList, 'relaClssOpi');
  141. console.log(that.theSelectNode, '30251');
  142. if (that.theSelectNode.children.length > 0) {
  143. if (allSelectDom[i].value == 'substance') {
  144. that.theSelectNode.children.map(item => {
  145. that.jm.update_node(item.id, CreateDom.getModelCardDom({ bgc: '#E3950E', modelTitle: '标签名', modelSelectList: relationClassOptionsList, modelType: item.data.type, level: 3, selectOption: relationClassOptionsList.length > 0 ? relationClassOptionsList[0].label : '', selectModelId: relationClassOptionsList.length > 0 ? relationClassOptionsList[0].value : '', modelWeight: this.findTheCardWeight('relation', 3, relationClassOptionsList.length > 0 ? relationClassOptionsList[0].label : '') }));
  146. });
  147. } else if (allSelectDom[i].value == 'suspected') {
  148. that.theSelectNode.children.map(item => {
  149. that.jm.update_node(item.id, CreateDom.getModelCardDom({ bgc: '#E3950E', modelTitle: '标签名', modelSelectList: relationClassOptionsList, modelType: item.data.type, level: 3, selectOption: relationClassOptionsList.length > 0 ? relationClassOptionsList[0].label : '', selectModelId: relationClassOptionsList.length > 0 ? relationClassOptionsList[0].value : '', modelWeight: this.findTheCardWeight('relation', 3, relationClassOptionsList.length > 0 ? relationClassOptionsList[0].label : '') }));
  150. });
  151. } else if (allSelectDom[i].value == 'strengthen') {
  152. that.theSelectNode.children.map(item => {
  153. that.jm.update_node(item.id, CreateDom.getModelCardDom({ bgc: '#E3950E', modelTitle: '标签名', modelSelectList: relationClassOptionsList, modelType: item.data.type, level: 3, selectOption: relationClassOptionsList.length > 0 ? relationClassOptionsList[0].label : '', selectModelId: relationClassOptionsList.length > 0 ? relationClassOptionsList[0].value : '', modelWeight: this.findTheCardWeight('relation', 3, relationClassOptionsList.length > 0 ? relationClassOptionsList[0].label : '') }));
  154. });
  155. }
  156. }
  157. }
  158. that.addSelectChangeFunc();
  159. that.addInputBlurFunc();
  160. } else if (allSelectDom[i].dataset.title == '标签名') {
  161. if (allSelectDom[i].dataset.type == 'point') {
  162. this.haveSelectPointModelAndWeight[this.haveSelectPointIndex].children[this.haveSelectPointLabelClassIndex].children[this.haveSelectPointLabelNameIndex].label = allSelectDom[i].options[allSelectDom[i].selectedIndex].text;
  163. this.haveSelectPointModelAndWeight[this.haveSelectPointIndex].children[this.haveSelectPointLabelClassIndex].children[this.haveSelectPointLabelNameIndex].value = allSelectDom[i].value;
  164. this.haveSelectPointModelAndWeight[this.haveSelectPointIndex].children[this.haveSelectPointLabelClassIndex].children[this.haveSelectPointLabelNameIndex].weight = 1;
  165. } else {
  166. this.haveSelectRelationModelAndWeight[this.haveSelectRelationIndex].children[this.haveSelectRelationLabelClassIndex].children[this.haveSelectRelationLabelNameIndex].label = allSelectDom[i].options[allSelectDom[i].selectedIndex].text;
  167. this.haveSelectRelationModelAndWeight[this.haveSelectRelationIndex].children[this.haveSelectRelationLabelClassIndex].children[this.haveSelectRelationLabelNameIndex].value = allSelectDom[i].value;
  168. this.haveSelectRelationModelAndWeight[this.haveSelectRelationIndex].children[this.haveSelectRelationLabelClassIndex].children[this.haveSelectRelationLabelNameIndex].weight = 1;
  169. }
  170. }
  171. };
  172. }
  173. }

整个事件较为复制,考虑的因素较多,同时也要添加一些自定义的属性来方便区分。

五、给所有的权重input添加失去焦点事件

这里还有一个就是每一个可选择的下拉框都对应的一个权重设置,通过失去焦点事件,来找到对应的位置更改数据,这里需要注意一下input输入框只能输入带小数点的数字,这里通过

οnkeyup="!/^(\d+\.?)?\d{0,1}$/.test(this.value)?(this.value=this.value.substring(0, this.value.length-1)): ''" 实现,

事件代码如下:

  1. // 给所有的 权重设置框 设置 失去焦点的监听事件
  2. addInputBlurFunc() {
  3. let that = this;
  4. let allInput = document.querySelectorAll('.model-weight-input');
  5. for (let i = 0; i < allInput.length; i++) {
  6. // 使用 onblur 生成的新卡片也需要添加 这个blur监听事件 用 onblur 进行覆盖 不会重复执行
  7. allInput[i].onblur = (e) => {
  8. console.log(allInput[i].value, 'inputVa');
  9. console.log(allInput[i].dataset, 'inputDs');
  10. if (allInput[i].dataset.type == 'point') {
  11. if (allInput[i].dataset.level == 1) {
  12. this.haveSelectPointModelAndWeight.map(item => {
  13. if (item.label == allInput[i].dataset.label) {
  14. item.weight = allInput[i].value;
  15. }
  16. });
  17. console.log(this.haveSelectPointModelAndWeight);
  18. } else if (allInput[i].dataset.level == 2) {
  19. this.haveSelectPointModelAndWeight[this.haveSelectPointIndex].children.map(item => {
  20. if (item.label == allInput[i].dataset.label) {
  21. item.weight = allInput[i].value;
  22. }
  23. });
  24. } else if (allInput[i].dataset.level == 3) {
  25. this.haveSelectPointModelAndWeight[this.haveSelectPointIndex].children[this.haveSelectPointLabelClassIndex].children.map(item => {
  26. if (item.label == allInput[i].dataset.label) {
  27. item.weight = allInput[i].value;
  28. }
  29. });
  30. }
  31. } else if (allInput[i].dataset.type == 'relation') {
  32. if (allInput[i].dataset.level == 1) {
  33. this.haveSelectRelationModelAndWeight.map(item => {
  34. if (item.label == allInput[i].dataset.label) {
  35. item.weight = allInput[i].value;
  36. }
  37. });
  38. console.log(this.haveSelectRelationModelAndWeight);
  39. } else if (allInput[i].dataset.level == 2) {
  40. this.haveSelectRelationModelAndWeight[this.haveSelectRelationIndex].children.map(item => {
  41. if (item.label == allInput[i].dataset.label) {
  42. item.weight = allInput[i].value;
  43. }
  44. });
  45. } else if (allInput[i].dataset.level == 3) {
  46. this.haveSelectRelationModelAndWeight[this.haveSelectRelationIndex].children[this.haveSelectRelationLabelClassIndex].children.map(item => {
  47. if (item.label == allInput[i].dataset.label) {
  48. item.weight = allInput[i].value;
  49. }
  50. });
  51. console.log(this.haveSelectRelationModelAndWeight);
  52. }
  53. }
  54. };
  55. }
  56. }

六、总结

此页面算是又重新使用原生js来写功能了,好多东西遗忘了需要一点点百度,而且页面虽然看起来简单,但是里面的关联逻辑还是相对来说比较复杂的,主要是数据这一块比较麻烦,核心逻辑就是所有的树形数据需要一一对应,不管是切换还是重新设置权重,都需要先找到对应的卡片再进行修改,再就是jsmind插件的相关介绍属实太少,便以此为记录,对自己也是一个提升了。

完整页面代码

主页面vue文件

  1. <template>
  2. <!-- 隐毒人员分析模型 =====> 新建模型 页面 -->
  3. <div class="hidden-model-new white-box" @contextmenu="hideMouse" >
  4. <BaseForm
  5. :form="searchForm"
  6. :showBtn="searchShowBtn"
  7. size="mini"
  8. :disableModel="disableModel"
  9. @click-start-model-btn="clickStartBtn"
  10. @click-reset-model-btn="clickResetModelBtn"
  11. class="flex-form"
  12. type="search-mode">
  13. <el-form-item label="模型名称:" prop="modelName">
  14. <el-input
  15. v-model="searchForm.modelName"
  16. placeholder="请输入"
  17. clearable
  18. ></el-input>
  19. </el-form-item>
  20. </BaseForm>
  21. <el-empty class="model-empty" v-if="showNull" description="请输入模型名称后点击开始建模按钮" :image-size="200"></el-empty>
  22. <div v-else class="create-model-div" id="create-model-chart" v-loading="chartLoading"
  23. element-loading-text="初始化中..."
  24. element-loading-spinner="el-icon-loading" >
  25. <p class="start-create-model-btn" @click="saveModelBtn" >保存模型</p>
  26. </div>
  27. <el-menu
  28. class="context-menu"
  29. v-show="showMenu"
  30. :style="{
  31. left: menuStyle.left,
  32. top: menuStyle.top,
  33. bottom: menuStyle.bottom,
  34. right: menuStyle.right,
  35. }"
  36. ref="context">
  37. <slot>
  38. <el-menu-item @click="addBrother">插入平级</el-menu-item>
  39. <el-menu-item @click="addChild">插入子级</el-menu-item>
  40. <el-menu-item @click="deleteCard">删除卡片</el-menu-item>
  41. </slot>
  42. </el-menu>
  43. </div>
  44. </template>
  45. <script>
  46. import BaseForm from '@/components/base/BaseForm';
  47. import CreateDom from '@/tools/CreateDom.js';
  48. import axios from 'axios';
  49. import StringTools from '@/tools/StringTools';
  50. // import '@/tools/jsmind.menu.js';
  51. import 'jsmind/style/jsmind.css';
  52. import jsMind from 'jsmind/js/jsmind.js';
  53. require('jsmind/js/jsmind.draggable.js');
  54. require('jsmind/js/jsmind.screenshot.js');
  55. export default {
  56. name: 'NewPersonModel',
  57. components: {
  58. BaseForm
  59. },
  60. data() {
  61. return {
  62. searchForm: {
  63. modelName: ''
  64. },
  65. searchShowBtn: {
  66. startModel: true,
  67. resetModel: true
  68. },
  69. disableModel: false,
  70. showNull: true,
  71. mind: {
  72. // 元数据 定义思维导图的名称、 作者、版本等信息
  73. meta: {
  74. name: '建模导图',
  75. author: 'ck',
  76. version: '0.2'
  77. },
  78. // 数据格式声明
  79. format: 'node_tree',
  80. // 数据内容
  81. data: {
  82. id: 'root',
  83. topic: '',
  84. direction: 'right',
  85. expanded: true,
  86. children: []
  87. }
  88. },
  89. options: {
  90. container: 'create-model-chart', // [必选] 容器的ID
  91. editable: true, // [可选] 是否启用编辑
  92. theme: '', // [可选] 主题
  93. support_html: true,
  94. mode: 'full', // 显示模式
  95. view: {
  96. engine: 'canvas', // 思维导图各节点之间线条的绘制引擎
  97. hmargin: 120, // 思维导图距容器外框的最小水平距离
  98. vmargin: 50, // 思维导图距容器外框的最小垂直距离
  99. line_width: 4, // 思维导图线条的粗细
  100. line_color: '#FFCC73', // 思维导图线条的颜色
  101. draggable: true, // 当容器不能完全容纳思维导图时,是否允许拖动画布代替鼠标滚动
  102. hide_scrollbars_when_draggable: true // 当设置 draggable = true 时,是否隐藏滚动条
  103. },
  104. layout: {
  105. hspace: 100, // 节点之间的水平间距
  106. vspace: 20, // 节点之间的垂直间距
  107. pspace: 20 // 节点与连接线之间的水平间距(用于容纳节点收缩/展开控制器)
  108. },
  109. shortcut: {
  110. enable: false // 是否启用快捷键 默认为true
  111. },
  112. menuOpts: {
  113. showMenu: true,
  114. injectionList: [
  115. { target: 'addBrother', text: '添加同级卡片', callback: function (node) { console.log(node); } },
  116. { target: 'delete', text: '删除卡片', callback: function (node) { console.log(node); } }
  117. ]
  118. },
  119. isShow: true
  120. },
  121. rootModel: {
  122. bgc: '#0FA984',
  123. modelName: ''
  124. },
  125. theSelectNode: null,
  126. showMenu: false,
  127. menuStyle: {},
  128. resultData: {
  129. personList: [],
  130. relationList: [],
  131. labelTypeList: {
  132. pointType: [
  133. { label: '自身属性标签', value: 'property', weight: 1 },
  134. { label: '自身行为标签', value: 'action', weight: 1 }
  135. ],
  136. relationType: [
  137. { label: '实质关系标签', value: 'substance', weight: 1 },
  138. { label: '疑似关系标签', value: 'suspected', weight: 1 },
  139. { label: '增强关系标签', value: 'strengthen', weight: 1 }
  140. ]
  141. },
  142. labelNameList: {
  143. pointLabel: [], // 当前选中的模型 所有的个人标签
  144. relationLabel: [], // 当前选中的模型 所有的关系标签
  145. propertyLabelList: [],
  146. actionLabelList: [],
  147. substanceLabelList: [],
  148. suspectedLabelList: [],
  149. strengthenLabelList: []
  150. }
  151. },
  152. pointLevel1Index: 0, // 个人模型名的 索引 这些索引用于区分是哪一个select被更改了
  153. relationLevel1Index: 0, // 关系模型名的 索引
  154. pointLevel2Index: 0, // 个人模型名 标签类名 的 索引
  155. relationLevel2Index: 0, // 关系模型名 标签类名 的 索引
  156. pointLevel3Index: 0, // 个人模型名 标签名 的 索引
  157. relationLevel3Index: 0, // 关系模型名 标签名 的 索引
  158. chartLoading: false,
  159. selectPonitLabelSort: '', // 个人模型对应的选中的标签分类
  160. selectRelationLabelSort: '', // 关系模型对应的选中的标签分类
  161. // 已选取的 个人 模型名以及对应的权重 添加的子节点以及继续添加的子节点都在 children 或 children.children
  162. haveSelectPointModelAndWeight: [],
  163. // 已选取的 关系 模型名以及对应的权重
  164. haveSelectRelationModelAndWeight: [],
  165. haveSelectPointIndex: 0, // 选中的 个人 模型的 索引
  166. haveSelectRelationIndex: 0, // 选中的 关系 模型的 索引
  167. haveSelectPointLabelClassIndex: 0, // 选中的 个人模型 标签分类的 索引
  168. haveSelectRelationLabelClassIndex: 0, // 选中的 关系模型 标签分类的 索引
  169. haveSelectPointLabelNameIndex: 0, // 选中的 个人模型 标签名的 索引
  170. haveSelectRelationLabelNameIndex: 0 // 选中的 关系模型 标签名的 索引
  171. };
  172. },
  173. created() {},
  174. mounted() {
  175. // 初始化 .querySelector('.create-model-div')
  176. // document.oncontextmenu = function () {
  177. // return false;
  178. // };
  179. },
  180. watch: {
  181. // showNull: function(newVal, oldVal) {
  182. // if (!newVal) {
  183. // const modelChart = document.getElementById('create-model-chart');
  184. // console.log(modelChart, 'mkmk');
  185. // }
  186. // }
  187. },
  188. methods: {
  189. // 禁止鼠标右键 使用自定义右键
  190. hideMouse(e) {
  191. e.preventDefault();
  192. // return false;
  193. },
  194. clickStartBtn() {
  195. if (!this.searchForm.modelName) {
  196. this.showNull = true;
  197. return this.$message.error('请先输入模型名称');
  198. }
  199. this.showNull = false; // 未建模之前空白部分的显示 设置 false 显示树形部分
  200. this.chartLoading = true; // 树形的加载
  201. this.disableModel = true; // 禁用开始建模按钮
  202. this.rootModel.modelName = this.searchForm.modelName; // 根节点的内容设置
  203. let that = this;
  204. // 发起请求 获取 个人 和 关系 两大类的一级子节点的数据
  205. axios.all([that.getPersonModelNameList(), that.getRelationModelNameList()]).then(
  206. axios.spread(async function(person, relation) {
  207. that.resultData.personList = [];
  208. that.resultData.relationList = [];
  209. if (person.data && relation.data.flag == 1) {
  210. person.data.map(item => {
  211. let obj = {};
  212. obj.label = item.modelName;
  213. obj.value = item.modelId;
  214. obj.type = 'point';
  215. that.resultData.personList.push(obj);
  216. });
  217. relation.data.data.map(ele => {
  218. let obj1 = {};
  219. obj1.label = ele.modelName;
  220. obj1.value = ele.modelId;
  221. obj1.type = 'relation';
  222. that.resultData.relationList.push(obj1);
  223. });
  224. that.haveSelectPointModelAndWeight.push({ label: that.resultData.personList[0].label, value: that.resultData.personList[0].value, weight: 1, index: that.pointLevel1Index, children: [], boxId: 'point' });
  225. that.haveSelectRelationModelAndWeight.push({ label: that.resultData.relationList[0].label, value: that.resultData.relationList[0].value, weight: 1, index: that.relationLevel1Index, children: [], boxId: 'relation' });
  226. // 获取所有的标签名数据 个人模型
  227. let personLabel = await that.$http.getAllLabelName({ modelId: that.resultData.personList[0].value, modelType: 'point' });
  228. // 获取所有的标签名数据 关系模型
  229. let initRelationLabel = await that.$http.getAllLabelName({ modelId: that.resultData.relationList[0].value, modelType: 'relation' });
  230. // 初始化 模型对应的标签
  231. if (personLabel.data.flag == 1) {
  232. that.resultData.labelNameList.pointLabel = personLabel.data.data.labelFields;
  233. that.resultData.labelTypeList.pointType[0].weight = personLabel.data.data.property;
  234. that.resultData.labelTypeList.pointType[1].weight = personLabel.data.data.action;
  235. }
  236. if (initRelationLabel.data.flag == 1) {
  237. that.resultData.labelNameList.relationLabel = initRelationLabel.data.data.labelFields;
  238. that.resultData.labelTypeList.relationType[0].weight = initRelationLabel.data.data.substance;
  239. that.resultData.labelTypeList.relationType[1].weight = initRelationLabel.data.data.suspected;
  240. that.resultData.labelTypeList.relationType[2].weight = initRelationLabel.data.data.strengthen;
  241. }
  242. that.resultData.labelNameList.propertyLabelList = [];
  243. that.resultData.labelNameList.actionLabelList = [];
  244. that.resultData.labelNameList.substanceLabelList = [];
  245. that.resultData.labelNameList.suspectedLabelList = [];
  246. that.resultData.labelNameList.strengthenLabelList = [];
  247. that.resultData.labelNameList.pointLabel.map(item => {
  248. if (item.type == 'property') {
  249. let labelObj = {
  250. label: item.fieldnamecn,
  251. value: item.id,
  252. weight: item.weight
  253. };
  254. that.resultData.labelNameList.propertyLabelList.push(labelObj);
  255. } else if (item.type == 'action') {
  256. let actionObj = {
  257. label: item.fieldnamecn,
  258. value: item.id,
  259. weight: item.weight
  260. };
  261. that.resultData.labelNameList.actionLabelList.push(actionObj);
  262. }
  263. });
  264. that.resultData.labelNameList.relationLabel.map(ele => {
  265. if (ele.type == 'substance') {
  266. let substanceObj = {
  267. label: ele.fieldnamecn,
  268. value: ele.id,
  269. weight: ele.weight
  270. };
  271. that.resultData.labelNameList.substanceLabelList.push(substanceObj);
  272. } else if (ele.type == 'suspected') {
  273. let suspectedObj = {
  274. label: ele.fieldnamecn,
  275. value: ele.id,
  276. weight: ele.weight
  277. };
  278. that.resultData.labelNameList.suspectedLabelList.push(suspectedObj);
  279. } else if (ele.type == 'strengthen') {
  280. let strengthenObj = {
  281. label: ele.fieldnamecn,
  282. value: ele.id,
  283. weight: ele.weight
  284. };
  285. that.resultData.labelNameList.strengthenLabelList.push(strengthenObj);
  286. }
  287. });
  288. that.selectPonitLabelSort = that.resultData.labelTypeList.pointType[0].value; // 默认选中第一个
  289. that.selectRelationLabelSort = that.resultData.labelTypeList.relationType[0].value; // 默认选中第一个
  290. // 加载思维图
  291. that.initModelChart();
  292. }
  293. })
  294. );
  295. },
  296. initModelChart() {
  297. this.mind.data.topic = CreateDom.getModelRootDom(this.rootModel);
  298. this.mind.data.children = CreateDom.getInitData(this.resultData);
  299. this.$nextTick(() => {
  300. this.jm = jsMind.show(this.options, this.mind);
  301. this.chartLoading = false;
  302. // let testSelect = this.jm.get_node('easy');
  303. // console.log(testSelect, 'tes');
  304. const modelChart = document.getElementById('create-model-chart');
  305. modelChart.addEventListener('mousedown', e => {
  306. e.stopPropagation();
  307. this.showMenu = false;
  308. // console.log(e, '99666');
  309. // this.showTheMenu(e);
  310. let selectCardId = '';
  311. if (Array.isArray(e.path)) {
  312. e.path.map(item => {
  313. if (item.localName == 'jmnode') {
  314. // console.log(item.attributes[0].nodeValue, '3030');
  315. selectCardId = item.attributes[0].nodeValue;
  316. }
  317. });
  318. // console.log(selectCardId, 'sed');
  319. if (selectCardId == 'root') {
  320. this.showMenu = false;
  321. return this.$message.warning('根节点无法编辑');
  322. } else if (!selectCardId) {
  323. this.showMenu = false;
  324. return false;
  325. }
  326. this.theSelectNode = this.jm.get_node(selectCardId);
  327. // console.log(this.theSelectNode, '2200');
  328. // console.log(selectCardId, '0022');
  329. this.clickSelectCard(selectCardId);
  330. this.findClickCardIndex(this.theSelectNode.data.type, this.theSelectNode.data.level, this.theSelectNode.id);
  331. }
  332. });
  333. this.addSelectChangeFunc();
  334. this.addInputBlurFunc();
  335. });
  336. },
  337. clickResetModelBtn() {
  338. if (!this.disableModel) {
  339. return this.$message.error('请先进行建模');
  340. }
  341. this.searchForm.modelName = '';
  342. this.disableModel = false;
  343. this.showNull = true;
  344. this.showMenu = false;
  345. },
  346. // 添加同级卡片
  347. addBrother() {
  348. // parent_node, node_id, topic, data
  349. let cardObj = this.whileCardAddFunc('bother', this.theSelectNode);
  350. // console.log(cardObj, 'cla');
  351. this.jm.add_node(cardObj.parentId, cardObj.id, cardObj.topic, cardObj.data);
  352. this.showMenu = false;
  353. this.addSelectChangeFunc();
  354. this.addInputBlurFunc();
  355. },
  356. // 添加子卡片
  357. addChild() {
  358. // node_after, node_id, topic, data
  359. // 判断是哪个层级 1 模型名 2 标签分类 3 标签名
  360. let cardObj = this.whileCardAddFunc('children', this.theSelectNode);
  361. // console.log(cardObj, '6688');
  362. if (cardObj.error) {
  363. this.showMenu = false;
  364. return this.$message.warning(cardObj.msg);
  365. }
  366. this.jm.add_node(cardObj.afterId, cardObj.id, cardObj.topic, cardObj.data);
  367. this.showMenu = false;
  368. this.addSelectChangeFunc();
  369. this.addInputBlurFunc();
  370. },
  371. // 删除卡片
  372. deleteCard() {
  373. let that = this;
  374. // let deleteNode = JSON.parse(JSON.stringify(this.theSelectNode));
  375. let deleteNode = StringTools.cloneDeepObj(that.theSelectNode);
  376. this.$confirm(
  377. '删除此节点卡片(包含所有子级卡片), 是否继续?',
  378. '提示',
  379. {
  380. confirmButtonText: '确定',
  381. cancelButtonText: '取消',
  382. type: 'warning'
  383. }
  384. ).then(() => {
  385. // 删除卡片
  386. if (deleteNode.data.type == 'point') {
  387. if (deleteNode.data.level == 1) {
  388. if (that.haveSelectPointModelAndWeight.length <= 1) {
  389. return that.$message.warning('至少保留一个个人模型名卡片');
  390. }
  391. that.haveSelectPointModelAndWeight.map((item, index) => {
  392. if (item.boxId == deleteNode.id) {
  393. that.haveSelectPointModelAndWeight.splice(index, 1);
  394. }
  395. });
  396. } else if (deleteNode.data.level == 2) {
  397. that.haveSelectPointModelAndWeight[that.haveSelectPointIndex].children.map((item, index) => {
  398. if (item.boxId == deleteNode.id) {
  399. that.haveSelectPointModelAndWeight[that.haveSelectPointIndex].children.splice(index, 1);
  400. }
  401. });
  402. } else if (deleteNode.data.level == 3) {
  403. that.haveSelectPointModelAndWeight[that.haveSelectPointIndex].children[that.haveSelectPointLabelClassIndex].children.map((item, index) => {
  404. if (item.boxId == deleteNode.id) {
  405. that.haveSelectPointModelAndWeight[this.haveSelectPointIndex].children[that.haveSelectPointLabelClassIndex].children.splice(index, 1);
  406. }
  407. });
  408. }
  409. } else {
  410. if (deleteNode.data.level == 1) {
  411. if (that.haveSelectRelationModelAndWeight.length <= 1) {
  412. return that.$message.warning('至少保留一个关系模型名卡片');
  413. }
  414. that.haveSelectRelationModelAndWeight.map((item, index) => {
  415. if (item.boxId == deleteNode.id) {
  416. that.haveSelectRelationModelAndWeight.splice(index, 1);
  417. }
  418. });
  419. } else if (deleteNode.data.level == 2) {
  420. that.haveSelectRelationModelAndWeight[that.haveSelectRelationIndex].children.map((item, index) => {
  421. if (item.boxId == deleteNode.id) {
  422. that.haveSelectRelationModelAndWeight[that.haveSelectRelationIndex].children.splice(index, 1);
  423. }
  424. });
  425. } else if (deleteNode.data.level == 3) {
  426. that.haveSelectRelationModelAndWeight[that.haveSelectRelationIndex].children[that.haveSelectPointLabelClassIndex].children.map((item, index) => {
  427. if (item.boxId == deleteNode.id) {
  428. that.haveSelectRelationModelAndWeight[that.haveSelectRelationIndex].children[that.haveSelectRelationLabelNameIndex].children.splice(index, 1);
  429. }
  430. });
  431. }
  432. }
  433. setTimeout(() => {
  434. that.jm.remove_node(that.theSelectNode.id);
  435. }, 50);
  436. that.showMenu = false;
  437. }).catch(() => {});
  438. },
  439. clickSelectCard(nodeId) {
  440. this.editor = this.jm.view.e_editor;
  441. // jsmind 添加自定义菜单事件
  442. this.jm.view.add_event(this.editor, 'contextmenu', (e) => {
  443. const selectedNode = this.jm.get_node(nodeId);
  444. // && selectedNode.data.type
  445. if (selectedNode) {
  446. e.preventDefault();
  447. const el = document.querySelector('.context-menu .el-menu-item');
  448. const width = parseFloat(window.getComputedStyle(el).width);
  449. const height = parseFloat(window.getComputedStyle(el).height) * 3 + 12;
  450. const windowHeight = window.innerHeight;
  451. const windowWidth = window.innerWidth;
  452. // 极限位置 避免越界
  453. if (e.clientY + height > windowHeight) {
  454. // console.log('23');
  455. this.menuStyle.left = e.clientX + 'px';
  456. this.menuStyle.top = 'unset';
  457. this.menuStyle.bottom = 0;
  458. } else if (e.clientX + width > windowWidth) {
  459. // console.log('24');
  460. this.menuStyle.top = e.clientY + 'px';
  461. this.menuStyle.left = 'unset';
  462. this.menuStyle.right = 0;
  463. } else {
  464. // console.log('25');
  465. this.menuStyle.left = e.clientX - 210 + 'px';
  466. this.menuStyle.top = e.clientY - 150 + 'px';
  467. this.menuStyle.bottom = 'unset';
  468. }
  469. this.showMenu = true;
  470. } else {
  471. this.showMenu = false;
  472. }
  473. });
  474. },
  475. // 找到当前点击的卡片的隶属位置的 index 索引
  476. findClickCardIndex(type, level, selectBoxId) {
  477. if (type == 'point') {
  478. if (level == 1) {
  479. // console.log(selectBoxId, 'seid');
  480. // console.log(this.haveSelectPointModelAndWeight, 'liii');
  481. this.haveSelectPointModelAndWeight.map((item, index) => {
  482. if (item.boxId == selectBoxId) {
  483. this.haveSelectPointIndex = index;
  484. }
  485. });
  486. // console.log(this.haveSelectPointIndex, 'hindex');
  487. } else if (level == 2) {
  488. this.haveSelectPointModelAndWeight[this.haveSelectPointIndex].children.map((item, index) => {
  489. if (item.boxId == selectBoxId) {
  490. this.haveSelectPointLabelClassIndex = index;
  491. }
  492. });
  493. } else if (level == 3) {
  494. this.haveSelectPointModelAndWeight[this.haveSelectPointIndex].children[this.haveSelectPointLabelClassIndex].children.map((item, index) => {
  495. this.haveSelectPointLabelNameIndex = index;
  496. });
  497. }
  498. } else if (type == 'relation') {
  499. if (level == 1) {
  500. this.haveSelectRelationModelAndWeight.map((item, index) => {
  501. if (item.boxId == selectBoxId) {
  502. this.haveSelectRelationIndex = index;
  503. }
  504. });
  505. } else if (level == 2) {
  506. this.haveSelectRelationModelAndWeight[this.haveSelectRelationIndex].children.map((item, index) => {
  507. if (item.boxId == selectBoxId) {
  508. this.haveSelectRelationLabelClassIndex = index;
  509. }
  510. });
  511. } else if (level == 3) {
  512. this.haveSelectRelationModelAndWeight[this.haveSelectRelationIndex].children[this.haveSelectRelationLabelClassIndex].children.map((item, index) => {
  513. if (item.boxId == selectBoxId) {
  514. this.haveSelectRelationLabelNameIndex = index;
  515. }
  516. });
  517. }
  518. }
  519. },
  520. // 添加卡片的方法 获得相关的数据对象
  521. whileCardAddFunc(type, node) {
  522. var funcObj = {};
  523. console.log(node, 'node');
  524. // type 进行 同级 bother 或者 子级 children 的分类 this.resultData.personList[0].label
  525. if (type == 'bother') {
  526. if (node.data.level == '1') {
  527. node.data.type == 'point' ? this.pointLevel1Index++ : this.relationLevel1Index++;
  528. funcObj.parentId = node.parent.id;
  529. funcObj.id = new Date().getTime() + parseFloat(Math.random() * 1000);
  530. funcObj.topic = CreateDom.getModelCardDom({ bgc: '#0FA984', modelTitle: '模型名', modelSelectList: node.data.type == 'point' ? this.resultData.personList : this.resultData.relationList, modelType: node.data.type, selectOption: node.data.type == 'point' ? this.resultData.personList[0].label : this.resultData.relationList[0].label, selectModelId: node.data.type == 'point' ? this.resultData.personList[0].value : this.resultData.relationList[0].value, level: 1, modelWeight: 1 });
  531. funcObj.data = {
  532. direction: 1,
  533. expanded: true,
  534. level: 1,
  535. type: node.data.type,
  536. children: []
  537. };
  538. // 判断是 个人模型 还是 关系 模型 往 已选则的 list 里面进行 push 一个
  539. this.addLabelValueWeight(node.data.type, 1, funcObj.id);
  540. } else if (node.data.level == '2') {
  541. node.data.type == 'point' ? this.pointLevel2Index++ : this.relationLevel2Index++;
  542. funcObj.parentId = node.parent.id;
  543. funcObj.id = new Date().getTime() + parseFloat(Math.random() * 1000);
  544. funcObj.topic = CreateDom.getModelCardDom({ bgc: '#5B9BD5', modelTitle: '标签分类', modelSelectList: node.data.type == 'point' ? this.resultData.labelTypeList.pointType : this.resultData.labelTypeList.relationType, modelType: node.data.type, selectOption: node.data.type == 'point' ? this.resultData.labelTypeList.pointType[0].label : this.resultData.labelTypeList.relationType[0].label, selectModelId: node.data.type == 'point' ? this.resultData.labelTypeList.pointType[0].value : this.resultData.labelTypeList.relationType[0].value, level: 2, modelWeight: this.findTheCardWeight(node.data.type, 2) });
  545. funcObj.data = {
  546. direction: 'right',
  547. expanded: true,
  548. level: 2,
  549. type: node.data.type,
  550. children: []
  551. };
  552. this.addLabelValueWeight(node.data.type, 2, funcObj.id);
  553. } else if (node.data.level == '3') {
  554. let optionList = this.getLabelNameListBySort(node.data.type, node.data.type == 'point' ? this.selectPonitLabelSort : this.selectRelationLabelSort);
  555. node.data.type == 'point' ? this.pointLevel3Index++ : this.relationLevel3Index++;
  556. funcObj.parentId = node.parent.id;
  557. funcObj.id = new Date().getTime() + parseFloat(Math.random() * 1000);
  558. funcObj.topic = CreateDom.getModelCardDom({ bgc: '#E3950E', modelTitle: '标签名', modelSelectList: optionList, modelType: node.data.type, selectOption: optionList.length > 0 ? optionList[0].label : '', selectModelId: optionList.length > 0 ? optionList[0].value : '', level: 3, modelWeight: this.findTheCardWeight(node.data.type, 3, optionList.length > 0 ? optionList[0].label : '') });
  559. funcObj.data = {
  560. level: 3,
  561. type: node.data.type
  562. };
  563. this.addLabelValueWeight(node.data.type, 3, funcObj.id);
  564. }
  565. } else if (type == 'children') {
  566. if (node.data.level == '1') {
  567. console.log(this.findTheCardWeight(node.data.type, 2), 'classWei');
  568. node.data.type == 'point' ? this.pointLevel2Index++ : this.relationLevel2Index++;
  569. funcObj.afterId = node.id;
  570. funcObj.id = new Date().getTime() + parseFloat(Math.random() * 1000);
  571. funcObj.topic = CreateDom.getModelCardDom({ bgc: '#5B9BD5', modelTitle: '标签分类', modelSelectList: node.data.type == 'point' ? this.resultData.labelTypeList.pointType : this.resultData.labelTypeList.relationType, modelType: node.data.type, selectOption: node.data.type == 'point' ? this.resultData.labelTypeList.pointType[0].label : this.resultData.labelTypeList.relationType[0].label, selectModelId: node.data.type == 'point' ? this.resultData.labelTypeList.pointType[0].value : this.resultData.labelTypeList.relationType[0].value, level: 2, modelWeight: this.findTheCardWeight(node.data.type, 2) });
  572. funcObj.data = {
  573. direction: 'right',
  574. expanded: true,
  575. level: 2,
  576. type: node.data.type,
  577. children: []
  578. };
  579. this.addLabelValueWeight(node.data.type, 2, funcObj.id);
  580. } else if (node.data.level == '2') {
  581. let optionsList = this.getLabelNameListBySort(node.data.type, node.data.type == 'point' ? this.selectPonitLabelSort : this.selectRelationLabelSort);
  582. node.data.type == 'point' ? this.pointLevel3Index++ : this.relationLevel3Index++;
  583. funcObj.afterId = node.id;
  584. funcObj.id = new Date().getTime() + parseFloat(Math.random() * 1000);
  585. funcObj.topic = CreateDom.getModelCardDom({ bgc: '#E3950E', modelTitle: '标签名', modelSelectList: optionsList, modelType: node.data.type, selectOption: optionsList.length > 0 ? optionsList[0].label : '', selectModelId: optionsList.length > 0 ? optionsList[0].value : '', level: 3, modelWeight: this.findTheCardWeight(node.data.type, 3, optionsList.length > 0 ? optionsList[0].label : '') });
  586. funcObj.data = {
  587. level: 3,
  588. type: node.data.type
  589. };
  590. this.addLabelValueWeight(node.data.type, 3, funcObj.id);
  591. } else if (node.data.level == '3') {
  592. funcObj.error = true;
  593. funcObj.msg = '无法再进行下一级的分类添加';
  594. }
  595. }
  596. let copyObj = JSON.parse(JSON.stringify(funcObj));
  597. // console.log(copyObj, '30369');
  598. return copyObj;
  599. },
  600. // 添加已生成的card对应的 label value weight 的方法 再加上对应卡片的id boxId
  601. addLabelValueWeight(type, level, boxId) {
  602. if (type == 'point') {
  603. if (level == 1) {
  604. this.haveSelectPointModelAndWeight.push({ label: this.resultData.personList[0].label, value: this.resultData.personList[0].value, weight: 1, index: this.pointLevel1Index, children: [], boxId: boxId });
  605. } else if (level == 2) {
  606. console.log(this.haveSelectPointIndex, 'poindex');
  607. console.log(this.haveSelectPointModelAndWeight[this.haveSelectPointIndex], '7755');
  608. this.haveSelectPointModelAndWeight[this.haveSelectPointIndex].children.push({ label: this.resultData.labelTypeList.pointType[0].label, value: this.resultData.labelTypeList.pointType[0].value, weight: 1, index: this.pointLevel2Index, children: [], boxId: boxId });
  609. } else if (level == 3) {
  610. if (this.selectPonitLabelSort == 'property') {
  611. let propertyLi = this.resultData.labelNameList.propertyLabelList;
  612. this.haveSelectPointModelAndWeight[this.haveSelectPointIndex].children[this.haveSelectPointLabelClassIndex].children.push({ label: propertyLi.length > 0 ? propertyLi[0].label : '', value: propertyLi.length > 0 ? propertyLi[0].value : '', weight: 1, index: this.pointLevel3Index, boxId: boxId });
  613. } else if (this.selectPonitLabelSort == 'action') {
  614. let actionLi = this.resultData.labelNameList.actionLabelList;
  615. this.haveSelectPointModelAndWeight[this.haveSelectPointIndex].children[this.haveSelectPointLabelClassIndex].children.push({ label: actionLi.length > 0 ? actionLi[0].label : '', value: actionLi.length > 0 ? actionLi[0].value : '', weight: 1, index: this.pointLevel3Index, boxId: boxId });
  616. }
  617. }
  618. } else if (type == 'relation') {
  619. if (level == 1) {
  620. this.haveSelectRelationModelAndWeight.push({ label: this.resultData.relationList[0].label, value: this.resultData.relationList[0].value, weight: 1, index: this.relationLevel1Index, children: [], boxId: boxId });
  621. } else if (level == 2) {
  622. this.haveSelectRelationModelAndWeight[this.haveSelectRelationIndex].children.push({ label: this.resultData.labelTypeList.relationType[0].label, value: this.resultData.labelTypeList.relationType[0].value, weight: 1, index: this.relationLevel2Index, children: [], boxId: boxId });
  623. } else if (level == 3) {
  624. if (this.selectRelationLabelSort == 'substance') {
  625. let substanceLi = this.resultData.labelNameList.substanceLabelList;
  626. this.haveSelectRelationModelAndWeight[this.haveSelectRelationIndex].children[this.haveSelectRelationLabelClassIndex].children.push({ label: substanceLi.length > 0 ? substanceLi[0].label : '', value: substanceLi.length > 0 ? substanceLi[0].value : '', weight: 1, index: this.relationLevel3Index, boxId: boxId });
  627. } else if (this.selectRelationLabelSort == 'suspected') {
  628. let suspectedLi = this.resultData.labelNameList.suspectedLabelList;
  629. this.haveSelectRelationModelAndWeight[this.haveSelectRelationIndex].children[this.haveSelectRelationLabelClassIndex].children.push({ label: suspectedLi.length > 0 ? suspectedLi[0].label : '', value: suspectedLi.length > 0 ? suspectedLi[0].value : '', weight: 1, index: this.relationLevel3Index, boxId: boxId });
  630. } else if (this.selectRelationLabelSort == 'strengthen') {
  631. let strengthenLi = this.resultData.labelNameList.strengthenLabelList;
  632. this.haveSelectRelationModelAndWeight[this.haveSelectRelationIndex].children[this.haveSelectRelationLabelClassIndex].children.push({ label: strengthenLi.length > 0 ? strengthenLi[0].label : '', value: strengthenLi.length > 0 ? strengthenLi[0].value : '', weight: 1, index: this.relationLevel3Index, boxId: boxId });
  633. }
  634. }
  635. }
  636. },
  637. // 找到当前的对应的权重
  638. findTheCardWeight(type, level, labelName) {
  639. let weightNum = 1;
  640. if (type == 'point') {
  641. if (level == 1) {
  642. weightNum = 1;
  643. } else if (level == 2) {
  644. this.selectPonitLabelSort == 'property' ? (weightNum = this.resultData.labelTypeList.pointType[0].weight) : (weightNum = this.resultData.labelTypeList.pointType[1].weight);
  645. } else if (level == 3) {
  646. let theList = this.getLabelNameListBySort('point', this.selectPonitLabelSort);
  647. theList.map(item => {
  648. if (item.label == labelName) {
  649. weightNum = item.weight;
  650. }
  651. });
  652. }
  653. } else {
  654. if (level == 1) {
  655. weightNum = 1;
  656. } else if (level == 2) {
  657. console.log(this.selectRelationLabelSort, 'resort');
  658. console.log(this.resultData.labelTypeList.relationType, '5252');
  659. this.selectRelationLabelSort == 'substance' ? (weightNum = this.resultData.labelTypeList.relationType[0].weight) : (this.selectRelationLabelSort == 'suspected' ? (weightNum = this.resultData.labelTypeList.relationType[1].weight) : (weightNum = this.resultData.labelTypeList.relationType[2].weight));
  660. } else if (level == 3) {
  661. let theList = this.getLabelNameListBySort('relation', this.selectRelationLabelSort);
  662. theList.map(item => {
  663. if (item.label == labelName) {
  664. weightNum = item.weight;
  665. }
  666. });
  667. }
  668. }
  669. return weightNum;
  670. },
  671. // 更改已生成的 card 对应的 label value weight 方法 暂不使用
  672. editLabelValueWeight(type, level, index, newVal) {
  673. if (type == 'point') {
  674. if (level == 1) {
  675. this.haveSelectPointModelAndWeight[index].label = newVal.label;
  676. this.haveSelectPointModelAndWeight[index].value = newVal.value;
  677. this.haveSelectPointModelAndWeight[index].weight = newVal.weight;
  678. } else if (level == 2) {
  679. this.haveSelectPointLabelClassAndWeight[index].label = newVal.label;
  680. this.haveSelectPointLabelClassAndWeight[index].value = newVal.value;
  681. this.haveSelectPointLabelClassAndWeight[index].weight = newVal.weight;
  682. } else if (level == 3) {
  683. this.haveSelectPointLabelNameAndWeight[index].label = newVal.label;
  684. this.haveSelectPointLabelNameAndWeight[index].value = newVal.value;
  685. this.haveSelectPointLabelNameAndWeight[index].weight = newVal.weight;
  686. }
  687. } else if (type == 'relation') {
  688. if (level == 1) {
  689. this.haveSelectRelationModelAndWeight[index].label = newVal.label;
  690. this.haveSelectRelationModelAndWeight[index].value = newVal.value;
  691. this.haveSelectRelationModelAndWeight[index].weight = newVal.weight;
  692. } else if (level == 2) {
  693. this.haveSelectRelationLabelClassAndWeight[index].label = newVal.label;
  694. this.haveSelectRelationLabelClassAndWeight[index].value = newVal.value;
  695. this.haveSelectRelationLabelClassAndWeight[index].weight = newVal.weight;
  696. } else if (level == 3) {
  697. this.haveSelectRelationLabelNameAndWeight[index].label = newVal.label;
  698. this.haveSelectRelationLabelNameAndWeight[index].value = newVal.value;
  699. this.haveSelectRelationLabelNameAndWeight[index].weight = newVal.weight;
  700. }
  701. }
  702. },
  703. getPersonModelNameList() {
  704. return this.$http.getAllPersonModelName();
  705. },
  706. getRelationModelNameList() {
  707. return this.$http.getAllRelationModelName();
  708. },
  709. // 获取当前选中的模型名的标签
  710. async getSelectModelLabelName(params) {
  711. return await this.$http.getAllLabelName(params);
  712. },
  713. // 给所有的select下拉框添加change事件
  714. addSelectChangeFunc() {
  715. let that = this;
  716. let allSelectDom = document.querySelectorAll('.select-model-list');
  717. // console.log(allSelectDom, 'cmcnc');
  718. for (let i = 0; i < allSelectDom.length; i++) {
  719. // 先清除change事件 selectFunction(allSelectDom[i])
  720. // allSelectDom[i].removeEventListener('change', selectFunction);
  721. // 使用 onchange 生成的新卡片也需要添加 这个change监听事件 用 onchange 进行覆盖 不会重复执行
  722. allSelectDom[i].onchange = async (e) => {
  723. // console.log(allSelectDom[i], 'lbn');
  724. console.log(e, 'echa');
  725. let selectLevel = allSelectDom[i].dataset.title == '模型名' ? 1 : (allSelectDom[i].dataset.title == '标签分类' ? 2 : 3);
  726. // 从节点上面查到到当前选中的option 进行 权重 input 的 自定义属性的更新
  727. e.path.map((item, index) => {
  728. if (item.className == 'model-edit-card') {
  729. e.path[index].children[1].children[1].dataset.label = allSelectDom[i].options[allSelectDom[i].selectedIndex].text;
  730. e.path[index].children[1].children[1].dataset.model = allSelectDom[i].value;
  731. e.path[index].children[1].children[1].value = that.findTheCardWeight(allSelectDom[i].dataset.type, selectLevel, allSelectDom[i].options[allSelectDom[i].selectedIndex].text);
  732. }
  733. });
  734. // 获取选中的 label 值
  735. // console.log(allSelectDom[i].options[allSelectDom[i].selectedIndex].text, '9966');
  736. // 判断切换的是哪种下拉框
  737. if (allSelectDom[i].dataset.title == '模型名') {
  738. if (allSelectDom[i].dataset.type == 'point') {
  739. this.haveSelectPointModelAndWeight[this.haveSelectPointIndex].label = allSelectDom[i].options[allSelectDom[i].selectedIndex].text;
  740. this.haveSelectPointModelAndWeight[this.haveSelectPointIndex].value = allSelectDom[i].value;
  741. this.haveSelectPointModelAndWeight[this.haveSelectPointIndex].weight = 1;
  742. // 选则的是人员模型
  743. let personLabel = await that.$http.getAllLabelName({ modelId: allSelectDom[i].value, modelType: 'point' });
  744. if (personLabel.data.flag == 1) {
  745. that.resultData.labelNameList.propertyLabelList = [];
  746. that.resultData.labelNameList.actionLabelList = [];
  747. that.resultData.labelNameList.pointLabel = personLabel.data.data.labelFields;
  748. that.resultData.labelNameList.pointLabel.map(item => {
  749. if (item.type == 'property') {
  750. let labelObj = {
  751. label: item.fieldnamecn,
  752. value: item.id
  753. };
  754. that.resultData.labelNameList.propertyLabelList.push(labelObj);
  755. } else if (item.type == 'action') {
  756. let actionObj = {
  757. label: item.fieldnamecn,
  758. value: item.id
  759. };
  760. that.resultData.labelNameList.actionLabelList.push(actionObj);
  761. }
  762. });
  763. if (that.theSelectNode.children.length > 0) {
  764. let pointOptionsList = that.getLabelNameListBySort('point', that.selectPonitLabelSort);
  765. console.log(pointOptionsList, 'pointOp');
  766. that.theSelectNode.children.map(item => {
  767. if (item.children.length > 0) {
  768. item.children.map(ele => {
  769. that.jm.update_node(ele.id, CreateDom.getModelCardDom({ bgc: '#E3950E', modelTitle: '标签名', modelSelectList: pointOptionsList, modelType: 'point', level: 3, selectOption: pointOptionsList.length > 0 ? pointOptionsList[0].label : '', selectModelId: pointOptionsList.length > 0 ? pointOptionsList[0].value : '', modelWeight: this.findTheCardWeight('poiny', 3, pointOptionsList.length > 0 ? pointOptionsList[0].label : '') }));
  770. });
  771. }
  772. });
  773. }
  774. // console.log(that.theSelectNode, '000333');
  775. // console.log(that.resultData.labelNameList.propertyLabelList, 'propl');
  776. // console.log(that.resultData.labelNameList.actionLabelList, 'actl');
  777. }
  778. } else {
  779. this.haveSelectRelationModelAndWeight[this.haveSelectRelationIndex].label = allSelectDom[i].options[allSelectDom[i].selectedIndex].text;
  780. this.haveSelectRelationModelAndWeight[this.haveSelectRelationIndex].value = allSelectDom[i].value;
  781. this.haveSelectRelationModelAndWeight[this.haveSelectRelationIndex].weight = 1;
  782. // 选则的是关系模型
  783. let initRelationLabel = await that.$http.getAllLabelName({ modelId: allSelectDom[i].value, modelType: 'relation' });
  784. if (initRelationLabel.data.flag == 1) {
  785. that.resultData.labelNameList.substanceLabelList = [];
  786. that.resultData.labelNameList.suspectedLabelList = [];
  787. that.resultData.labelNameList.strengthenLabelList = [];
  788. that.resultData.labelNameList.relationLabel = initRelationLabel.data.data.labelFields;
  789. that.resultData.labelNameList.relationLabel.map(ele => {
  790. if (ele.type == 'substance') {
  791. let substanceObj = {
  792. label: ele.fieldnamecn,
  793. value: ele.id
  794. };
  795. that.resultData.labelNameList.substanceLabelList.push(substanceObj);
  796. } else if (ele.type == 'suspected') {
  797. let suspectedObj = {
  798. label: ele.fieldnamecn,
  799. value: ele.id
  800. };
  801. that.resultData.labelNameList.suspectedLabelList.push(suspectedObj);
  802. } else if (ele.type == 'strengthen') {
  803. let strengthenObj = {
  804. label: ele.fieldnamecn,
  805. value: ele.id
  806. };
  807. that.resultData.labelNameList.strengthenLabelList.push(strengthenObj);
  808. }
  809. });
  810. if (that.theSelectNode.children.length > 0) {
  811. let relationOptionsList = that.getLabelNameListBySort('relation', that.selectRelationLabelSort);
  812. console.log(relationOptionsList, 'relaOp');
  813. that.theSelectNode.children.map(item => {
  814. if (item.children.length > 0) {
  815. item.children.map(ele => {
  816. that.jm.update_node(ele.id, CreateDom.getModelCardDom({ bgc: '#E3950E', modelTitle: '标签名', modelSelectList: relationOptionsList, modelType: 'relation', level: 3, selectOption: relationOptionsList.length > 0 ? relationOptionsList[0].label : '', selectModelId: relationOptionsList.length > 0 ? relationOptionsList[0].value : '', modelWeight: this.findTheCardWeight('relation', 3, relationOptionsList.length > 0 ? relationOptionsList[0].label : '') }));
  817. });
  818. }
  819. });
  820. }
  821. }
  822. }
  823. that.addSelectChangeFunc();
  824. that.addInputBlurFunc();
  825. } else if (allSelectDom[i].dataset.title == '标签分类') {
  826. if (allSelectDom[i].dataset.type == 'point') {
  827. this.haveSelectPointModelAndWeight[this.haveSelectPointIndex].children[this.haveSelectPointLabelClassIndex].label = allSelectDom[i].options[allSelectDom[i].selectedIndex].text;
  828. this.haveSelectPointModelAndWeight[this.haveSelectPointIndex].children[this.haveSelectPointLabelClassIndex].value = allSelectDom[i].value;
  829. this.haveSelectPointModelAndWeight[this.haveSelectPointIndex].children[this.haveSelectPointLabelClassIndex].weight = 1;
  830. that.selectPonitLabelSort = allSelectDom[i].value;
  831. if (that.theSelectNode.children.length > 0) {
  832. if (allSelectDom[i].value == 'property') {
  833. let propertyClassOptionsList = that.getLabelNameListBySort('point', 'property');
  834. console.log(propertyClassOptionsList, 'properOpt');
  835. that.theSelectNode.children.map(item => {
  836. that.jm.update_node(item.id, CreateDom.getModelCardDom({ bgc: '#E3950E', modelTitle: '标签名', modelSelectList: propertyClassOptionsList, modelType: 'point', level: 3, selectOption: propertyClassOptionsList.length > 0 ? propertyClassOptionsList[0].label : '', selectModelId: propertyClassOptionsList.length > 0 ? propertyClassOptionsList[0].value : '', modelWeight: this.findTheCardWeight('poiny', 3, propertyClassOptionsList.length > 0 ? propertyClassOptionsList[0].label : '') }));
  837. });
  838. } else if (allSelectDom[i].value == 'action') {
  839. let actionClassOptionsList = that.getLabelNameListBySort('point', 'action');
  840. console.log(actionClassOptionsList, 'actionOpi');
  841. that.theSelectNode.children.map(item => {
  842. that.jm.update_node(item.id, CreateDom.getModelCardDom({ bgc: '#E3950E', modelTitle: '标签名', modelSelectList: actionClassOptionsList, modelType: 'point', level: 3, selectOption: actionClassOptionsList.length > 0 ? actionClassOptionsList[0].label : '', selectModelId: actionClassOptionsList.length > 0 ? actionClassOptionsList[0].value : '', modelWeight: this.findTheCardWeight('poiny', 3, actionClassOptionsList.length > 0 ? actionClassOptionsList[0].label : '') }));
  843. });
  844. }
  845. }
  846. } else if (allSelectDom[i].dataset.type == 'relation') {
  847. this.haveSelectRelationModelAndWeight[this.haveSelectRelationIndex].children[this.haveSelectRelationLabelClassIndex].label = allSelectDom[i].options[allSelectDom[i].selectedIndex].text;
  848. this.haveSelectRelationModelAndWeight[this.haveSelectRelationIndex].children[this.haveSelectRelationLabelClassIndex].value = allSelectDom[i].value;
  849. this.haveSelectRelationModelAndWeight[this.haveSelectRelationIndex].children[this.haveSelectRelationLabelClassIndex].weight = 1;
  850. that.selectRelationLabelSort = allSelectDom[i].value;
  851. let relationClassOptionsList = that.getLabelNameListBySort('relation', that.selectRelationLabelSort);
  852. console.log(relationClassOptionsList, 'relaClssOpi');
  853. console.log(that.theSelectNode, '30251');
  854. if (that.theSelectNode.children.length > 0) {
  855. if (allSelectDom[i].value == 'substance') {
  856. that.theSelectNode.children.map(item => {
  857. that.jm.update_node(item.id, CreateDom.getModelCardDom({ bgc: '#E3950E', modelTitle: '标签名', modelSelectList: relationClassOptionsList, modelType: item.data.type, level: 3, selectOption: relationClassOptionsList.length > 0 ? relationClassOptionsList[0].label : '', selectModelId: relationClassOptionsList.length > 0 ? relationClassOptionsList[0].value : '', modelWeight: this.findTheCardWeight('relation', 3, relationClassOptionsList.length > 0 ? relationClassOptionsList[0].label : '') }));
  858. });
  859. } else if (allSelectDom[i].value == 'suspected') {
  860. that.theSelectNode.children.map(item => {
  861. that.jm.update_node(item.id, CreateDom.getModelCardDom({ bgc: '#E3950E', modelTitle: '标签名', modelSelectList: relationClassOptionsList, modelType: item.data.type, level: 3, selectOption: relationClassOptionsList.length > 0 ? relationClassOptionsList[0].label : '', selectModelId: relationClassOptionsList.length > 0 ? relationClassOptionsList[0].value : '', modelWeight: this.findTheCardWeight('relation', 3, relationClassOptionsList.length > 0 ? relationClassOptionsList[0].label : '') }));
  862. });
  863. } else if (allSelectDom[i].value == 'strengthen') {
  864. that.theSelectNode.children.map(item => {
  865. that.jm.update_node(item.id, CreateDom.getModelCardDom({ bgc: '#E3950E', modelTitle: '标签名', modelSelectList: relationClassOptionsList, modelType: item.data.type, level: 3, selectOption: relationClassOptionsList.length > 0 ? relationClassOptionsList[0].label : '', selectModelId: relationClassOptionsList.length > 0 ? relationClassOptionsList[0].value : '', modelWeight: this.findTheCardWeight('relation', 3, relationClassOptionsList.length > 0 ? relationClassOptionsList[0].label : '') }));
  866. });
  867. }
  868. }
  869. }
  870. that.addSelectChangeFunc();
  871. that.addInputBlurFunc();
  872. } else if (allSelectDom[i].dataset.title == '标签名') {
  873. if (allSelectDom[i].dataset.type == 'point') {
  874. this.haveSelectPointModelAndWeight[this.haveSelectPointIndex].children[this.haveSelectPointLabelClassIndex].children[this.haveSelectPointLabelNameIndex].label = allSelectDom[i].options[allSelectDom[i].selectedIndex].text;
  875. this.haveSelectPointModelAndWeight[this.haveSelectPointIndex].children[this.haveSelectPointLabelClassIndex].children[this.haveSelectPointLabelNameIndex].value = allSelectDom[i].value;
  876. this.haveSelectPointModelAndWeight[this.haveSelectPointIndex].children[this.haveSelectPointLabelClassIndex].children[this.haveSelectPointLabelNameIndex].weight = 1;
  877. } else {
  878. this.haveSelectRelationModelAndWeight[this.haveSelectRelationIndex].children[this.haveSelectRelationLabelClassIndex].children[this.haveSelectRelationLabelNameIndex].label = allSelectDom[i].options[allSelectDom[i].selectedIndex].text;
  879. this.haveSelectRelationModelAndWeight[this.haveSelectRelationIndex].children[this.haveSelectRelationLabelClassIndex].children[this.haveSelectRelationLabelNameIndex].value = allSelectDom[i].value;
  880. this.haveSelectRelationModelAndWeight[this.haveSelectRelationIndex].children[this.haveSelectRelationLabelClassIndex].children[this.haveSelectRelationLabelNameIndex].weight = 1;
  881. }
  882. }
  883. };
  884. }
  885. },
  886. // 根据 标签分类 来 获取 对应的标签名列表
  887. getLabelNameListBySort(modelType, attr) {
  888. let list = [];
  889. if (modelType == 'point') {
  890. if (attr == 'property') {
  891. list = this.resultData.labelNameList.propertyLabelList;
  892. } else if (attr == 'action') {
  893. list = this.resultData.labelNameList.actionLabelList;
  894. }
  895. } else if (modelType == 'relation') {
  896. if (attr == 'substance') {
  897. list = this.resultData.labelNameList.substanceLabelList;
  898. } else if (attr == 'suspected') {
  899. list = this.resultData.labelNameList.suspectedLabelList;
  900. } else if (attr == 'strengthen') {
  901. list = this.resultData.labelNameList.strengthenLabelList;
  902. }
  903. }
  904. return list;
  905. },
  906. // select 更改后 进行 卡片节点的更新 主要是针对 card 权重对应的自定义 data-label 属性 进行更新
  907. // 此方法会重新渲染 select 下拉框 导致失去监听的事件 有问题 不使用 改为 从 dom 树里面查找修改
  908. updataCardNode(id, type, level, label, model) {
  909. console.log(label, 'newlab');
  910. console.log(model, 'newVal');
  911. if (type == 'point') {
  912. if (level == 1) {
  913. // , selectModelId: model
  914. this.jm.update_node(id, CreateDom.getModelCardDom({ bgc: '#0FA984', modelTitle: '模型名', modelSelectList: this.resultData.personList, modelType: type, selectOption: label }));
  915. } else if (level == 2) {
  916. this.jm.update_node(id, CreateDom.getModelCardDom({ bgc: '#0FA984', modelTitle: '标签分类', modelSelectList: this.resultData.labelTypeList.pointType, modelType: type, selectOption: label, selectModelId: model }));
  917. } else if (level == 3) {
  918. this.jm.update_node(id, CreateDom.getModelCardDom({ bgc: '#0FA984', modelTitle: '标签名', modelSelectList: this.getLabelNameListBySort(type, this.selectPonitLabelSort), modelType: type, selectOption: label, selectModelId: model }));
  919. }
  920. } else if (type == 'relation') {
  921. if (level == 1) {
  922. this.jm.update_node(id, CreateDom.getModelCardDom({ bgc: '#0FA984', modelTitle: '模型名', modelSelectList: this.resultData.relationList, modelType: type, selectOption: label, selectModelId: model }));
  923. } else if (level == 2) {
  924. this.jm.update_node(id, CreateDom.getModelCardDom({ bgc: '#0FA984', modelTitle: '标签分类', modelSelectList: this.resultData.labelTypeList.relationType, modelType: type, selectOption: label, selectModelId: model }));
  925. } else if (level == 3) {
  926. this.jm.update_node(id, CreateDom.getModelCardDom({ bgc: '#0FA984', modelTitle: '标签名', modelSelectList: this.getLabelNameListBySort(type, this.selectRelationLabelSort), modelType: type, selectOption: label, selectModelId: model }));
  927. }
  928. }
  929. },
  930. // 给所有的 权重设置框 设置 失去焦点的监听事件
  931. addInputBlurFunc() {
  932. let that = this;
  933. let allInput = document.querySelectorAll('.model-weight-input');
  934. for (let i = 0; i < allInput.length; i++) {
  935. // 使用 onblur 生成的新卡片也需要添加 这个blur监听事件 用 onblur 进行覆盖 不会重复执行
  936. allInput[i].onblur = (e) => {
  937. console.log(allInput[i].value, 'inputVa');
  938. console.log(allInput[i].dataset, 'inputDs');
  939. if (allInput[i].dataset.type == 'point') {
  940. if (allInput[i].dataset.level == 1) {
  941. this.haveSelectPointModelAndWeight.map(item => {
  942. if (item.label == allInput[i].dataset.label) {
  943. item.weight = allInput[i].value;
  944. }
  945. });
  946. console.log(this.haveSelectPointModelAndWeight);
  947. } else if (allInput[i].dataset.level == 2) {
  948. this.haveSelectPointModelAndWeight[this.haveSelectPointIndex].children.map(item => {
  949. if (item.label == allInput[i].dataset.label) {
  950. item.weight = allInput[i].value;
  951. }
  952. });
  953. } else if (allInput[i].dataset.level == 3) {
  954. this.haveSelectPointModelAndWeight[this.haveSelectPointIndex].children[this.haveSelectPointLabelClassIndex].children.map(item => {
  955. if (item.label == allInput[i].dataset.label) {
  956. item.weight = allInput[i].value;
  957. }
  958. });
  959. }
  960. } else if (allInput[i].dataset.type == 'relation') {
  961. if (allInput[i].dataset.level == 1) {
  962. this.haveSelectRelationModelAndWeight.map(item => {
  963. if (item.label == allInput[i].dataset.label) {
  964. item.weight = allInput[i].value;
  965. }
  966. });
  967. console.log(this.haveSelectRelationModelAndWeight);
  968. } else if (allInput[i].dataset.level == 2) {
  969. this.haveSelectRelationModelAndWeight[this.haveSelectRelationIndex].children.map(item => {
  970. if (item.label == allInput[i].dataset.label) {
  971. item.weight = allInput[i].value;
  972. }
  973. });
  974. } else if (allInput[i].dataset.level == 3) {
  975. this.haveSelectRelationModelAndWeight[this.haveSelectRelationIndex].children[this.haveSelectRelationLabelClassIndex].children.map(item => {
  976. if (item.label == allInput[i].dataset.label) {
  977. item.weight = allInput[i].value;
  978. }
  979. });
  980. console.log(this.haveSelectRelationModelAndWeight);
  981. }
  982. }
  983. };
  984. }
  985. },
  986. // 保存模型
  987. saveModelBtn() {
  988. // console.log(this.jm.get_data('node_tree'), 'save');
  989. // console.log(this.haveSelectPointModelAndWeight, 'savePoi');
  990. // console.log(this.haveSelectRelationModelAndWeight, 'saveRela');
  991. let modelData = {
  992. modelGroupName: this.searchForm.modelName,
  993. pointModelData: this.haveSelectPointModelAndWeight,
  994. relationModelData: this.haveSelectRelationModelAndWeight
  995. };
  996. console.log(modelData);
  997. }
  998. // select change事件函数
  999. // changeSelectFunc(e) {
  1000. // console.log(e, '8787');
  1001. // }
  1002. }
  1003. };
  1004. </script>
  1005. <style lang="less" scoped>
  1006. .hidden-model-new {
  1007. position: relative;
  1008. z-index: 3;
  1009. padding: 2.5rem 0 0 2.33rem !important;
  1010. .create-model-box {
  1011. display: flex;
  1012. align-items: center;
  1013. justify-content: space-around;
  1014. width: 100%;
  1015. height: 92%;
  1016. // background-color: turquoise;
  1017. }
  1018. .create-model-div {
  1019. width: 100%;
  1020. height: 92%;
  1021. position: relative;
  1022. bottom: 0;
  1023. left: 0;
  1024. z-index: 0;
  1025. .start-create-model-btn {
  1026. position: absolute;
  1027. bottom: 4%;
  1028. right: 3%;
  1029. width: 10.83rem;
  1030. height: 3rem;
  1031. line-height: 3rem;
  1032. background: #FFFFFF;
  1033. border-radius: 0.17rem;
  1034. border: 0.08rem solid #2364D9;
  1035. text-align: center;
  1036. font-size: 1.33rem;
  1037. font-family: PingFangSC-Semibold, PingFang SC;
  1038. font-weight: 600;
  1039. color: #2364D9;
  1040. cursor: pointer;
  1041. z-index: 9;
  1042. }
  1043. // background-color: yellowgreen;
  1044. }
  1045. .model-empty {
  1046. position: absolute;
  1047. top: 50%;
  1048. left: 50%;
  1049. transform: translate(-50%, -50%);
  1050. }
  1051. .context-menu {
  1052. position: absolute;
  1053. width: 8.3333rem;
  1054. z-index: 32;
  1055. }
  1056. }
  1057. ::v-deep {
  1058. .model-edit-card {
  1059. display: flex;
  1060. width: 20rem;
  1061. height: 8.33rem;
  1062. border-radius: 0.83rem;
  1063. box-sizing: border-box;
  1064. padding: 0.75rem 1.08rem 0 1.17rem;
  1065. justify-content: space-between;
  1066. position: relative;
  1067. // margin-bottom: 2rem;
  1068. .model-info {
  1069. flex: 1;
  1070. .model-title-p {
  1071. text-align: center;
  1072. font-size: 1.5rem;
  1073. font-family: PingFangSC-Regular, PingFang SC;
  1074. font-weight: 400;
  1075. color: #FFFFFF;
  1076. margin-bottom: 0.3rem;
  1077. }
  1078. .model-name-info {
  1079. p {
  1080. display: flex;
  1081. height: 4.42rem;
  1082. background: #FFFFFF;
  1083. justify-content: center;
  1084. align-items: center;
  1085. span {
  1086. text-align: center;
  1087. font-size: 1.33rem;
  1088. }
  1089. }
  1090. .select-model-list {
  1091. width: 100%;
  1092. height: 4.42rem;
  1093. // & > .el-input {
  1094. // width: 100%;
  1095. // }
  1096. // .el-input__inner {
  1097. // height: 4.42rem;
  1098. // }
  1099. }
  1100. }
  1101. }
  1102. .model-weight {
  1103. width: 4.33rem;
  1104. margin-left: 0.75rem;
  1105. p {
  1106. font-size: 1.5rem;
  1107. font-family: PingFangSC-Regular, PingFang SC;
  1108. font-weight: 400;
  1109. color: #FFFFFF;
  1110. text-align: center;
  1111. margin-bottom: 0.3rem;
  1112. }
  1113. .model-weight-input {
  1114. width: 4.33rem;
  1115. height: 4.2rem;
  1116. text-align: center;
  1117. }
  1118. }
  1119. .chart-switch-icon {
  1120. position: absolute;
  1121. top: 50%;
  1122. right: -15px;
  1123. transform: translateY(-50%);
  1124. cursor: pointer;
  1125. }
  1126. }
  1127. jmnode {
  1128. padding: 0;
  1129. border-radius: 0.83rem;
  1130. }
  1131. }
  1132. </style>

 StringTools.js 里面的 cloneDeepObj 方法

  1. // 对象的深拷贝
  2. static cloneDeepObj(obj) {
  3. // 浅拷贝子节点
  4. let handleChild = (child) => {
  5. if (typeof child === 'object') {
  6. if (Array.isArray(child)) { // 数组
  7. return [...child];
  8. } else if (child) { // 对象
  9. return { ...child };
  10. } else { // null
  11. return child;
  12. }
  13. } else { // 值类型
  14. return child;
  15. }
  16. };
  17. let arr = [];
  18. let target = { result: obj };
  19. let current = target;
  20. let temp = null;
  21. if (typeof current === 'object') {
  22. if (Array.isArray(current)) { // 数组
  23. current.forEach((item, index) => {
  24. let child = handleChild(item);
  25. current[index] = child;
  26. arr.push(child);
  27. });
  28. } else if (current) { // 对象
  29. let objKeys = Object.keys(current);
  30. objKeys.forEach(key => {
  31. let child = handleChild(current[key]);
  32. current[key] = child;
  33. arr.push(child);
  34. });
  35. } else { // null
  36. temp = current;
  37. }
  38. }
  39. current = arr.shift();
  40. return target.result;
  41. }

 BaseForm 表单组件

  1. <template>
  2. <!-- 表单组件 可在使用时 添加 flex-form 类名来进行单排排序 用于头部筛选搜索 :label-width="labelWidth" -->
  3. <el-form ref="form-element" :rules="rules" :model="form" :size="size" :data-type="type">
  4. <slot :data="form"></slot>
  5. <el-form-item class="btn-item">
  6. <el-button
  7. v-show="showBtn.search"
  8. @click="clickSearchBtn"
  9. type="primary"
  10. icon="el-icon-search"
  11. >查询</el-button
  12. >
  13. <el-button v-show="showBtn.cancel" @click="clickCancelBtn"
  14. >取消</el-button
  15. >
  16. <el-button type="primary" v-show="showBtn.law" @click="clickLawBtn"
  17. ><i class="icon iconfont">&#xe7a4;</i> 规律分析</el-button
  18. >
  19. <el-button
  20. type="primary"
  21. v-show="showBtn.call"
  22. @click="clickCallBtn"
  23. ><i class="icon iconfont">&#xe7a4;</i> 通话分析</el-button
  24. >
  25. <el-button
  26. type="primary"
  27. v-show="showBtn.message"
  28. @click="clickMessageBtn"
  29. ><i class="icon iconfont">&#xe7a4;</i> 短信分析</el-button
  30. >
  31. <el-button
  32. v-show="showBtn.reset"
  33. @click="resetForm"
  34. type="warning"
  35. icon="el-icon-refresh-right"
  36. >重置</el-button
  37. >
  38. <el-button
  39. v-show="showBtn.add"
  40. @click="clickAddBtn"
  41. type="primary"
  42. icon="el-icon-plus"
  43. class="old-btn"
  44. >新增</el-button
  45. >
  46. <el-button
  47. v-show="showBtn.startModel"
  48. @click="clickStartModelBtn"
  49. type="primary"
  50. icon="el-icon-plus"
  51. :disabled="disableModel"
  52. >开始建模</el-button
  53. >
  54. <el-button
  55. v-show="showBtn.resetModel"
  56. @click="clickResetModelBtn"
  57. type="danger"
  58. icon="el-icon-refresh"
  59. :disabled="showBtn.disableResetModel"
  60. >重新建模</el-button
  61. >
  62. <el-button
  63. v-show="showBtn.refresh"
  64. @click="clickRefreshBtn"
  65. type="primary"
  66. icon="el-icon-refresh"
  67. class="old-btn"
  68. >刷新</el-button
  69. >
  70. <el-button
  71. type="primary"
  72. v-show="showBtn.save"
  73. @click="clickSaveBtn"
  74. >保存</el-button
  75. >
  76. <el-button
  77. type="success"
  78. v-show="showBtn.import"
  79. @click="clickImportBtn"
  80. class="old-btn"
  81. ><i class="icon iconfont">&#xe7a5;</i> 导入</el-button
  82. >
  83. <el-button type="warning" v-show="showBtn.out" @click="clickOutBtn"
  84. class="old-btn"
  85. ><i class="icon iconfont">&#xe7aa;</i> 导出</el-button
  86. >
  87. <el-button type="primary" v-show="showBtn.outModel" @click="clickOutModelBtn"
  88. ><i class="icon iconfont">&#xe7aa;</i> 导出模板</el-button
  89. >
  90. <el-button
  91. type="danger"
  92. v-show="showBtn.remove"
  93. @click="clickRemoveBtn"
  94. icon="el-icon-delete"
  95. class="old-btn"
  96. >删除</el-button
  97. >
  98. <el-button
  99. type="primary"
  100. v-show="showBtn.sure"
  101. @click="clickSureBtn"
  102. >确认提交</el-button
  103. >
  104. <el-button
  105. type="primary"
  106. v-show="showBtn.submit"
  107. @click="clickSubmitBtn"
  108. icon="el-icon-circle-check"
  109. >提交</el-button
  110. >
  111. <el-button
  112. type="primary"
  113. v-show="showBtn.submit2"
  114. @click="clickSubmit2Btn"
  115. >提交</el-button
  116. >
  117. <el-button type="success" v-show="showBtn.statistics" @click="clickStatisticsBtn"
  118. ><i class="icon iconfont">&#xeac5;</i> 生成报告</el-button
  119. >
  120. <el-button type="success" v-show="showBtn.checkStatic" @click="clickCheckBtn"
  121. ><i class="icon iconfont">&#xe7a4;</i> 查看报告</el-button
  122. >
  123. <el-button
  124. type="primary"
  125. v-show="showBtn.reply"
  126. @click="clickReplyBtn"
  127. icon=""
  128. >回复</el-button
  129. >
  130. <el-button
  131. type="warning"
  132. v-show="showBtn.comeback"
  133. @click="clickComebackBtn"
  134. ><i class="icon iconfont">&#xe7ad;</i> 返回</el-button
  135. >
  136. <el-button
  137. class="login-btn"
  138. v-show="showBtn.login"
  139. @click="loginBtn"
  140. >登录</el-button
  141. >
  142. </el-form-item>
  143. </el-form>
  144. </template>
  145. <script>
  146. export default {
  147. name: 'BaseForm',
  148. props: {
  149. form: {
  150. // 表单每一项的对象属性
  151. type: Object,
  152. default: () => {
  153. return {};
  154. }
  155. },
  156. rules: {
  157. // 表单校验规则
  158. type: Object,
  159. default: () => {
  160. return {};
  161. }
  162. },
  163. labelWidth: {
  164. // label项的宽度
  165. type: String,
  166. default: () => {
  167. return '90px';
  168. }
  169. },
  170. size: {
  171. // 表单大小
  172. type: String,
  173. default: () => {
  174. return 'medium';
  175. }
  176. },
  177. showBtn: {
  178. // 操作按钮的显示
  179. type: Object,
  180. default: () => {
  181. return {
  182. search: false,
  183. cancel: false,
  184. law: false,
  185. call: false,
  186. message: false,
  187. reset: false,
  188. add: false,
  189. refresh: false,
  190. save: false,
  191. import: false,
  192. out: false,
  193. remove: false,
  194. sure: false,
  195. submit: false,
  196. submit2: false,
  197. comeback: false,
  198. login: false,
  199. reply: false,
  200. statistics: false,
  201. checkStatic: false,
  202. startModel: false,
  203. disableModel: false,
  204. disableResetModel: false
  205. };
  206. }
  207. },
  208. // 自定义的重置按钮点击事件
  209. theReset: {
  210. type: Boolean,
  211. default: () => {
  212. return false;
  213. }
  214. },
  215. type: {
  216. type: String,
  217. default: () => {
  218. return 'normal';
  219. }
  220. },
  221. disableModel: {
  222. type: Boolean,
  223. default: () => {
  224. return false;
  225. }
  226. }
  227. },
  228. created() {},
  229. data() {
  230. return {};
  231. },
  232. methods: {
  233. clickSearchBtn() {
  234. this.$emit('click-search-btn');
  235. },
  236. clickCancelBtn() {
  237. this.$emit('click-cancel-btn');
  238. },
  239. clickLawBtn() {
  240. this.$emit('click-law-btn');
  241. },
  242. clickCallBtn() {
  243. this.$emit('click-call-btn');
  244. },
  245. clickMessageBtn() {
  246. this.$emit('click-message-btn');
  247. },
  248. resetForm() {
  249. if (this.theReset) {
  250. return this.$emit('click-reset-btn');
  251. }
  252. this.$refs['form-element'].resetFields();
  253. },
  254. clickAddBtn() {
  255. this.$emit('click-add-btn');
  256. },
  257. clickRefreshBtn() {
  258. this.$emit('click-refresh-btn');
  259. },
  260. clickSaveBtn() {
  261. if (this.rules) {
  262. this.$refs['form-element'].validate(valid => {
  263. // 通过验证
  264. if (valid) {
  265. return this.$emit('click-save-btn', true);
  266. } else {
  267. return this.$emit('click-save-btn', false);
  268. }
  269. });
  270. } else {
  271. this.$emit('click-save-btn');
  272. }
  273. },
  274. clickCheckBtn() {
  275. this.$emit('click-check-btn');
  276. },
  277. clickImportBtn() {
  278. this.$emit('click-import-btn');
  279. },
  280. clickOutBtn() {
  281. this.$emit('click-out-btn');
  282. },
  283. clickOutModelBtn() {
  284. this.$emit('click-out-model');
  285. },
  286. clickRemoveBtn() {
  287. this.$emit('click-remove-btn');
  288. },
  289. clickSureBtn() {
  290. this.$emit('click-sure-btn');
  291. },
  292. clickSubmitBtn() {
  293. this.$emit('click-submit-btn');
  294. },
  295. clickSubmit2Btn() {
  296. if (this.rules) {
  297. this.$refs['form-element'].validate(valid => {
  298. // 通过验证
  299. if (valid) {
  300. return this.$emit('click-submit2-btn', true);
  301. } else {
  302. return this.$emit('click-submit2-btn', false);
  303. }
  304. });
  305. } else {
  306. this.$emit('click-submit2-btn');
  307. }
  308. },
  309. clickStatisticsBtn() {
  310. this.$emit('click-statistics-btn');
  311. },
  312. clickReplyBtn() {
  313. this.$emit('click-reply-btn');
  314. },
  315. clickComebackBtn() {
  316. this.$emit('click-comeback-btn');
  317. },
  318. loginBtn() {
  319. this.$refs['form-element'].validate(valid => {
  320. // 通过验证
  321. if (valid) {
  322. this.$emit('login-btn', this.form);
  323. }
  324. });
  325. },
  326. clickStartModelBtn() {
  327. this.$emit('click-start-model-btn');
  328. },
  329. clickResetModelBtn() {
  330. this.$emit('click-reset-model-btn');
  331. }
  332. }
  333. };
  334. </script>
  335. <style lang="less" scoped>
  336. @import '~@/assets/css/common.less';
  337. .btn-item {
  338. text-align: center;
  339. margin-top: 2.75rem;
  340. ::v-deep .el-form-item__content {
  341. //margin-left: 30px !important;
  342. .el-button--mini,
  343. .el-button--mini.is-round {
  344. padding-left: 10px;
  345. padding-right: 10px;
  346. }
  347. .el-button--primary {
  348. background-color: @theme-backgroundColor-primary;
  349. border-color: @theme-backgroundColor-primary;
  350. .icon {
  351. font-size: 1rem;
  352. }
  353. }
  354. .el-button--warning {
  355. background-color: @theme-backgroundColor-warning;
  356. border-color: @theme-backgroundColor-warning;
  357. .icon {
  358. font-size: 1rem;
  359. }
  360. }
  361. .el-button--success {
  362. background-color: @theme-backgroundColor-success;
  363. border-color: @theme-backgroundColor-success;
  364. .icon {
  365. font-size: 1rem;
  366. }
  367. }
  368. }
  369. }
  370. .login-btn {
  371. width: 13.33rem;
  372. height: 3.33rem;
  373. background: #00c1fe;
  374. border-radius: 2px;
  375. color: #ffffff;
  376. font-size: 16px;
  377. font-family: PingFangSC-Regular, PingFang SC;
  378. border: none;
  379. margin-left: auto;
  380. margin-right: auto;
  381. }
  382. .old-btn {
  383. display: none!important;
  384. }
  385. .el-form[data-type='search-mode'] {
  386. /deep/ .el-form-item {
  387. border: 1px solid #E6E6E6;
  388. border-radius: 2px;
  389. margin-bottom: 2rem!important;
  390. &.btn-item {
  391. border: none;
  392. }
  393. .el-input {
  394. width: 13.5rem!important;
  395. }
  396. label {
  397. background: #F0F0F0;
  398. padding: 0 1em 0 1em;
  399. min-width: 7em;
  400. text-align: center;
  401. }
  402. .el-input__inner {
  403. border: none;
  404. }
  405. }
  406. }
  407. </style>

CreateDom.js 在前面已经放了,这里就不再放了。 

网站建设定制开发 软件系统开发定制 定制软件开发 软件开发定制 定制app开发 app开发定制 app开发定制公司 电商商城定制开发 定制小程序开发 定制开发小程序 客户管理系统开发定制 定制网站 定制开发 crm开发定制 开发公司 小程序开发定制 定制软件 收款定制开发 企业网站定制开发 定制化开发 android系统定制开发 定制小程序开发费用 定制设计 专注app软件定制开发 软件开发定制定制 知名网站建设定制 软件定制开发供应商 应用系统定制开发 软件系统定制开发 企业管理系统定制开发 系统定制开发