lsc 2 年之前
父節點
當前提交
37f077ac3f

+ 1 - 1
dist/index.html

@@ -25,4 +25,4 @@
       height: 100%;
       width: 100%;
       background: #e6eaf0;
-    }</style><link href=./static/css/app.f79e1afaf764eb3d89183685a87f5317.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=./static/js/manifest.093df9138434d51e559a.js></script><script type=text/javascript src=./static/js/vendor.70beac01daea730bb60f.js></script><script type=text/javascript src=./static/js/app.1aac3c92c66377cf948a.js></script></body></html><script>document.domain = document.domain.split(".").slice(-2).join(".");</script>
+    }</style><link href=./static/css/app.c4c90af300987a1677984fcdc4fa3069.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=./static/js/manifest.39a9f69d36ef7d211bbe.js></script><script type=text/javascript src=./static/js/vendor.fcf402c88fe84bcdbaed.js></script><script type=text/javascript src=./static/js/app.c433dd89ece62e63702c.js></script></body></html><script>document.domain = document.domain.split(".").slice(-2).join(".");</script>

File diff suppressed because it is too large
+ 0 - 0
dist/static/css/app.c4c90af300987a1677984fcdc4fa3069.css


File diff suppressed because it is too large
+ 0 - 0
dist/static/css/app.c4c90af300987a1677984fcdc4fa3069.css.map


File diff suppressed because it is too large
+ 0 - 0
dist/static/css/app.f79e1afaf764eb3d89183685a87f5317.css.map


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/0.495dd6dd7e801967b64f.js


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/0.495dd6dd7e801967b64f.js.map


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/0.f867c3655b998d260981.js.map


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/app.1aac3c92c66377cf948a.js


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/app.1aac3c92c66377cf948a.js.map


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/app.c433dd89ece62e63702c.js


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/app.c433dd89ece62e63702c.js.map


+ 2 - 2
dist/static/js/manifest.093df9138434d51e559a.js → dist/static/js/manifest.39a9f69d36ef7d211bbe.js

@@ -1,2 +1,2 @@
-!function(e){var n=window.webpackJsonp;window.webpackJsonp=function(r,c,a){for(var i,u,f,s=0,l=[];s<r.length;s++)u=r[s],t[u]&&l.push(t[u][0]),t[u]=0;for(i in c)Object.prototype.hasOwnProperty.call(c,i)&&(e[i]=c[i]);for(n&&n(r,c,a);l.length;)l.shift()();if(a)for(s=0;s<a.length;s++)f=o(o.s=a[s]);return f};var r={},t={4:0};function o(n){if(r[n])return r[n].exports;var t=r[n]={i:n,l:!1,exports:{}};return e[n].call(t.exports,t,t.exports,o),t.l=!0,t.exports}o.e=function(e){var n=t[e];if(0===n)return new Promise(function(e){e()});if(n)return n[2];var r=new Promise(function(r,o){n=t[e]=[r,o]});n[2]=r;var c=document.getElementsByTagName("head")[0],a=document.createElement("script");a.type="text/javascript",a.charset="utf-8",a.async=!0,a.timeout=12e4,o.nc&&a.setAttribute("nonce",o.nc),a.src=o.p+"static/js/"+e+"."+{0:"f867c3655b998d260981",1:"994623639438b244a74c"}[e]+".js";var i=setTimeout(u,12e4);function u(){a.onerror=a.onload=null,clearTimeout(i);var n=t[e];0!==n&&(n&&n[1](new Error("Loading chunk "+e+" failed.")),t[e]=void 0)}return a.onerror=a.onload=u,c.appendChild(a),r},o.m=e,o.c=r,o.d=function(e,n,r){o.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},o.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return o.d(n,"a",n),n},o.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},o.p="./",o.oe=function(e){throw console.error(e),e}}([]);
-//# sourceMappingURL=manifest.093df9138434d51e559a.js.map
+!function(e){var n=window.webpackJsonp;window.webpackJsonp=function(r,c,a){for(var i,u,f,s=0,l=[];s<r.length;s++)u=r[s],t[u]&&l.push(t[u][0]),t[u]=0;for(i in c)Object.prototype.hasOwnProperty.call(c,i)&&(e[i]=c[i]);for(n&&n(r,c,a);l.length;)l.shift()();if(a)for(s=0;s<a.length;s++)f=o(o.s=a[s]);return f};var r={},t={4:0};function o(n){if(r[n])return r[n].exports;var t=r[n]={i:n,l:!1,exports:{}};return e[n].call(t.exports,t,t.exports,o),t.l=!0,t.exports}o.e=function(e){var n=t[e];if(0===n)return new Promise(function(e){e()});if(n)return n[2];var r=new Promise(function(r,o){n=t[e]=[r,o]});n[2]=r;var c=document.getElementsByTagName("head")[0],a=document.createElement("script");a.type="text/javascript",a.charset="utf-8",a.async=!0,a.timeout=12e4,o.nc&&a.setAttribute("nonce",o.nc),a.src=o.p+"static/js/"+e+"."+{0:"495dd6dd7e801967b64f",1:"994623639438b244a74c"}[e]+".js";var i=setTimeout(u,12e4);function u(){a.onerror=a.onload=null,clearTimeout(i);var n=t[e];0!==n&&(n&&n[1](new Error("Loading chunk "+e+" failed.")),t[e]=void 0)}return a.onerror=a.onload=u,c.appendChild(a),r},o.m=e,o.c=r,o.d=function(e,n,r){o.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},o.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return o.d(n,"a",n),n},o.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},o.p="./",o.oe=function(e){throw console.error(e),e}}([]);
+//# sourceMappingURL=manifest.39a9f69d36ef7d211bbe.js.map

File diff suppressed because it is too large
+ 0 - 0
dist/static/js/manifest.39a9f69d36ef7d211bbe.js.map


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/vendor.fcf402c88fe84bcdbaed.js


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/vendor.fcf402c88fe84bcdbaed.js.map


File diff suppressed because it is too large
+ 835 - 208
package-lock.json


+ 2 - 0
package.json

@@ -11,6 +11,7 @@
   },
   "dependencies": {
     "axios": "^0.21.1",
+    "cacache": "^16.1.1",
     "clipboard": "^2.0.10",
     "echarts": "^5.0.2",
     "element-ui": "^2.15.1",
@@ -18,6 +19,7 @@
     "hevue-img-preview": "^5.0.3",
     "jquery": "^3.6.0",
     "js-pinyin": "^0.1.9",
+    "jsmind": "^0.4.8",
     "qs": "^6.10.1",
     "v-viewer": "^1.6.4",
     "vant": "^2.12.10",

+ 439 - 0
src/assets/js/jsmind.menu.js

@@ -0,0 +1,439 @@
+/*
+ * Released under BSD License
+ * Copyright (c) 2019-2020 Allen_sun_js@hotmail.com
+ *
+ * Project Home:
+ *  https://github.com/allensunjian
+ */
+
+(function ($w, temp) {
+  var obj = null
+
+
+  var Jm = $w[temp], name = 'menu', $d = $w['document'], menuEvent = 'oncontextmenu', clickEvent = 'onclick', $c = function (tag) { return $d.createElement(tag); }, _noop = function () { }, logger = (typeof console === 'undefined') ? { log: _noop, debug: _noop, error: _noop, warn: _noop, info: _noop } : console;
+
+    var $t = function (n, t) { if (n.hasChildNodes()) { n.firstChild.nodeValue = t; } else { n.appendChild($d.createTextNode(t)); } };
+
+    var $h = function (n, t) {
+        if (t instanceof HTMLElement) {
+            t.innerHTML = "";
+            n.appendChild(t)
+        } else {
+            n.innerHTML = t;
+        }
+    };
+
+  if (!Jm || Jm[name]) return;
+
+  Jm.menu = function (_jm) {
+    obj = this
+    this._get_menu_options(_jm, function () {
+
+      this.init(_jm);
+
+      this._mount_events()
+    })
+  }
+  Jm.menu.prototype = {
+
+    defaultDataMap: {
+      funcMap: {
+        edit: {
+          isDepNode: true,
+             // defaultFn不受到中台变量的控制,始终会先于fn去执行
+          defaultFn: function (node) {
+            var f = this._menu_default_mind_methods._menu_begin_edit.call(this.jm);
+            f && this._menu_default_mind_methods._menu_edit_node_begin(this.jm.view, node);
+          },
+          fn: _noop,
+          text: 'edit node'
+        },
+        addChild: {
+          isDepNode: true,
+          fn: function (nodeid,text) {
+              var selected_node = this.get_selected_node();
+              if (selected_node) {
+                  var node = this.add_node(selected_node, nodeid, text);
+                  if (node) {
+                      this.select_node(nodeid);
+                      this.begin_edit(nodeid);
+                      obj._mount_events();
+                  }
+              }
+          },
+          text: 'append child'
+        },
+        addBrother: {
+          isDepNode: true,
+          fn: function (nodeid,text) {
+              var selected_node = this.get_selected_node();
+              if (selected_node && !selected_node.isroot) {
+                  var node = this.insert_node_after(selected_node, nodeid, text);
+                  if (node) {
+                      this.select_node(nodeid);
+                      this.begin_edit(nodeid);
+                      obj._mount_events();
+                 }
+              }
+          },
+          text: 'append brother'
+        },
+        delete: {
+          isDepNode: true,
+          fn: function () {
+            this.shortcut.handle_delnode.call(this.shortcut, this);
+          },
+          text: 'delete node'
+        },
+        showAll: {
+          sDepNode: false,
+          fn: function () {
+            this.expand_all(this)
+          },
+          text: 'show all'
+        },
+        hideAll: {
+          isDepNode: false,
+          fn: function () {
+            this.collapse_all(this)
+          },
+          text: 'hide all'
+        },
+        screenshot: {
+          isDepNode: false,
+          fn: function () {
+            if (!this.screenshot) {
+              logger.error('[jsmind] screenshot dependent on jsmind.screenshot.js !');
+              return;
+            }
+              this.screenshot.shootDownload();
+          },
+          text: 'load mind picture'
+        },
+        showNode: {
+          isDepNode: true,
+          fn: function (node) {
+              this.expand_node(node);
+          },
+          text: 'show target node'
+        },
+        hideNode: {
+          isDepNode: true,
+          fn: function (node) {
+              this.collapse_node(node);
+          },
+          text: 'hide target node'
+        },
+      },
+      menuStl: {
+          'width': '150px',
+          'padding': '12px 0',
+          'position': 'fixed',
+          'z-index': '10',
+          'background': '#fff',
+          'box-shadow': '0 2px 12px 0 rgba(0,0,0,0.1)',
+          'border-radius': '5px',
+          'font-size': '12px',
+          'display': 'none'
+      },
+      menuItemStl:{
+          padding: '5px 15px',
+          cursor: 'pointer',
+          display: 'block',
+          'text-align': 'center',
+          'transition':'all .2s'
+      },
+      injectionList:['edit','addChild','delete']
+    },
+
+    init: function (_jm) {
+      this._create_menu(_jm);
+      this._get_injectionList(_jm);
+      this.menuOpts.switchMidStage && Jm.util.dom.add_event(_jm.view.e_editor , 'blur', function () {
+            this._menu_default_mind_methods._menu_edit_node_end.call(_jm.view);
+            if(typeof this.menuOpts.editCaller == 'function') {
+                this.menuOpts.editCaller($w.menu._update_node_info, this._menu_default_mind_methods._menu_update_edit_node)
+                return
+            }
+            this._menu_default_mind_methods._menu_update_edit_node();
+        }.bind(this));
+    },
+
+    _event_contextMenu (e) {
+        e.preventDefault();
+        this.menu.style.left = e.clientX + 'px';
+        this.menu.style.top = e.clientY + 'px';
+        this.menu.style.display = 'block';
+        this.selected_node = this.jm.get_selected_node();
+    } ,
+
+    _event_hideMenu() {
+      this.menu.style.display = 'none'
+    },
+
+    _mount_events () {
+      var items = document.getElementsByTagName('jmnode')
+      for(let i = 0; i < items.length; i++) {
+        items[i][menuEvent] = this._event_contextMenu.bind(this);
+      }
+      $w[clickEvent] = this._event_hideMenu.bind(this);
+    },
+
+    _create_menu (_jm) {
+      var d = $c('menu');
+      this._set_menu_wrap_syl(d);
+      this.menu = d;
+      this.e_panel = _jm.view.e_panel;
+      this.e_panel.appendChild(d);
+    },
+
+    _create_menu_item (j, text, fn, isDepNode,cb, defaultFn) {
+      var d = $c('menu-item'),_this = this;
+      this._set_menu_item_syl(d);
+      d.innerText = text;
+      d.addEventListener('click', function () {
+        if (this.selected_node || !isDepNode) {
+            defaultFn.call(_this, this.selected_node);
+          if (!_this._get_mid_opts()) {
+              cb(this.selected_node, _noop)
+              fn.call(j,Jm.util.uuid.newid(), this.menuOpts.newNodeText || 'New Node');
+              return;
+          }
+            cb(this.selected_node,_this._mid_stage_next(function () {
+                var retArgs = [this.selected_node],
+                    argus = Array.prototype.slice.call(arguments[0],0);
+                argus[1] = this.menuOpts.newNodeText || 'New Node';
+                if (argus[0]) {
+                    retArgs = argus
+                }
+                fn.apply(j,retArgs);
+            }.bind(this)))
+          return
+        }
+        alert(this.menuOpts.tipContent || 'Continue with node selected!')
+      }.bind(this))
+      d.addEventListener('mouseover', function () {
+          d.style.background = 'rgb(179, 216, 255)'
+      }.bind(this))
+      d.addEventListener('mouseleave', function () {
+          d.style.background = '#fff'
+      }.bind(this))
+      return d
+    },
+
+    _set_menu_wrap_syl (d) {
+      var os = this._get_option_sty('menu',this._get_mixin_sty);
+      d.style.cssText = this._format_cssText(os);
+    },
+
+    _set_menu_item_syl (d) {
+        var os = this._get_option_sty('menuItem',this._get_mixin_sty);
+      d.style.cssText = this._format_cssText(os)
+    },
+
+    _format_cssText (o) {
+      var text = '';
+      Object.keys(o).forEach(function (k) {
+        text += k +':'+o[k] +';'
+      })
+      return text;
+    },
+
+     _empty_object (o) {
+       return Object.keys(o).length == 0? true :false
+     },
+
+    _get_option_sty (type, fn) {
+      var sty = this.menuOpts.style,
+          menu = this.defaultDataMap.menuStl,
+          menuItem = this.defaultDataMap.menuItemStl,
+          o = {menu,menuItem}
+          
+      if (!sty) return o[type];
+      if (!sty[type]) return o[type];
+      if (!sty[type] || this._empty_object(sty[type])) return o[type];
+      return fn( o[type],sty[type])
+    },
+
+    _get_mixin_sty (dSty, oSty) {
+      var o = {};
+      Object.keys(oSty).forEach(function (k) {
+          o[k] = oSty[k];
+      })
+      Object.keys(dSty).forEach(function (k) {
+          if (!o[k]) o[k] = dSty[k];
+      })
+        return o
+    },
+
+    _get_menu_options (j, fn) {
+      var options = j.options;
+      if (!options.menuOpts) return;
+      if (!options.menuOpts.showMenu) return;
+      this.menuOpts = j.options.menuOpts
+      fn.call(this)
+    },
+
+    _get_injectionDetail () {
+      var iLs = this.menuOpts.injectionList,
+          dLs = this.defaultDataMap.injectionList;
+      if (!iLs) return dLs;
+      if (!Array.isArray(iLs)) {
+          logger.error('[jsmind] injectionList must be a Array');
+          return;
+      }
+      if (iLs.length == 0) return dLs;
+      return iLs
+    },
+
+    _get_injectionList (j) {
+      var list = this._get_injectionDetail(),
+          _this = this;
+      list.forEach(function (k) {
+        var o = null,
+            text = "",
+            callback = _noop,
+            defaultFn = _noop;
+
+        if (typeof k == 'object') {
+            o = _this.defaultDataMap.funcMap[k.target];
+            text = k.text;
+            k.callback && (callback = k.callback);
+        } else {
+            o = _this.defaultDataMap.funcMap[k];
+            text = o.text;
+        }
+
+        if (o.defaultFn)  defaultFn = o.defaultFn;
+        _this.menu.appendChild(_this._create_menu_item(j ,text, o.fn, o.isDepNode,callback, defaultFn));
+      })
+    },
+
+    _get_mid_opts () {
+       var b = this.menuOpts.switchMidStage;
+       if (!b) return false;
+       if (typeof b !== 'boolean') {
+         logger.error('[jsmind] switchMidStage must be Boolean');
+         return false;
+       }
+        return b
+    },
+
+    _switch_view_db_event () {
+        Jm.prototype.dblclick_handle = _noop;
+        Jm.shortcut_provider.prototype.handler = _noop;
+        Jm.view_provider.prototype.edit_node_end = _noop;
+    },
+
+    _mid_stage_next (fn) {
+     return function () {
+         fn(arguments);
+     }
+    },
+
+    _reset_mind_event_edit () {},
+
+    _menu_default_mind_methods: {
+        _menu_begin_edit: function () {
+            var f = this.get_editable();
+            if (!f) {
+              logger.error('fail, this mind map is not editable.');
+            }
+            return f;
+        },
+        _menu_edit_node_begin (scope, node) {
+            if (!node.topic) {
+                logger.warn("don't edit image nodes");
+                return;
+            }
+            if (scope.editing_node != null) {
+                this._menu_default_mind_methods._menu_edit_node_end.call(scope);
+            }
+            scope.editing_node = node;
+            var view_data = node._data.view;
+            var element = view_data.element;
+            var topic = node.topic;
+            var ncs = getComputedStyle(element);
+            scope.e_editor.value = topic;
+            scope.e_editor.style.width = (element.clientWidth - parseInt(ncs.getPropertyValue('padding-left')) - parseInt(ncs.getPropertyValue('padding-right'))) + 'px';
+            element.innerHTML = '';
+            element.appendChild(scope.e_editor);
+            element.style.zIndex = 5;
+            scope.e_editor.focus();
+            scope.e_editor.select();
+        },
+        _menu_edit_node_end: function () {
+            if (this.editing_node != null) {
+                var node = this.editing_node;
+                this.editing_node = null;
+                var view_data = node._data.view;
+                var element = view_data.element;
+                var topic = this.e_editor.value;
+                element.style.zIndex = 'auto';
+                element.removeChild(this.e_editor);
+                $w.menu._update_node_info = {id: node.id, topic: topic};
+                if (Jm.util.text.is_empty(topic) || node.topic === topic) {
+                        if (this.opts.support_html) {
+                        $h(element, node.topic);
+                    } else {
+                        $t(element, node.topic);
+                    }
+                }
+            }
+        },
+        _menu_update_edit_node: function () {
+            var info = $w.menu._update_node_info;
+            $w.menu.jm.update_node(info.id, info.topic);
+        }
+    }
+
+  }
+  var plugin = new Jm.plugin('menu',function (_jm) {
+
+    $w.menu = new Jm.menu(_jm);
+
+    $w.menu.jm = _jm;
+
+    if($w.menu.menuOpts) _jm.menu = $w.menu;
+
+  })
+
+  Jm.register_plugin(plugin)
+
+  function preventMindEventDefault() {
+
+      Jm.menu.prototype._switch_view_db_event();
+
+  }
+  Jm.preventMindEventDefault = preventMindEventDefault
+
+
+  // eslint-disable-next-line no-unused-vars
+  function reBuild () {
+    if (obj !== null) {
+      obj._mount_events()
+    }
+  }
+  // export reBuild
+  if (typeof module !== 'undefined' && typeof exports === 'object') {
+      module.exports = {
+        reBuild,
+        init: function (opt) {
+          Jm = opt
+        }
+      };
+  }
+  // exports = {
+  //   reBuild,
+  //   // init: function (opt) {
+  //   //   console.log(opt)
+  //   // }
+  // };
+
+  // $w['render'] = function () {
+  //   if (obj !== null) {
+  //     obj._mount_events()
+  //   }
+  // }
+
+})(window, 'jsMind')

二進制
src/assets/nominddata.png


二進制
src/assets/tree.png


+ 92 - 16
src/components/pages/evaluation.vue

@@ -20,9 +20,9 @@
         "
       >
         <div class="pb_head top">
-          <span>评价体系设置</span>
+          <span>目标管理设置</span>
           <div class="student_button">
-            <el-button type="primary" class="bgColor" @click="addED">添加评价体系</el-button>
+            <el-button type="primary" class="bgColor" @click="addED">添加目标管理</el-button>
           </div>
         </div>
         <div class="student_head">
@@ -65,31 +65,31 @@
       </div>
     </div>
     <el-dialog
-      title="添加评价体系"
+      title="添加目标管理"
       :visible.sync="dialogVisible"
       :append-to-body="true"
-      width="1000px"
+      width="1200px"
       :before-close="handleClose"
       class="dialog_diy"
     >
       <div>
         <div class="e_add_top">
           <div class="e_add_title">
-            <span>评价体系名称</span>
-            <el-input v-model="eTitle" placeholder="请输入名称"></el-input>
+            <span>目标管理名称</span>
+            <el-input v-model="eTitle" placeholder="请输入名称" @change="setMindData"></el-input>
           </div>
         </div>
         <div class="e_add_content">
           <div class="e_add_list">
             <div class="e_add_list_title">
-              <span>一级目</span>
+              <span>一级目</span>
               <img src="../../assets/add.png" @click="addE(1)" alt />
             </div>
             <div class="e_add_list_body">
               <div class="e_add_list_child" v-for="(item,index) in eJson" :key="index">
                 <span
                   :class="{active:item.id == fid}"
-                  v-if="item.name.length<11"
+                  v-if="item.name.length<8"
                   @click="checkF(item.id)"
                 >{{item.name}}</span>
                 <el-tooltip
@@ -111,7 +111,7 @@
           </div>
           <div class="e_add_list">
             <div class="e_add_list_title">
-              <span>二级目</span>
+              <span>二级目</span>
               <img src="../../assets/add.png" @click="addE(2)" v-if="fid != ''" alt />
             </div>
             <div class="e_add_list_body">
@@ -122,7 +122,7 @@
               >
                 <span
                   :class="{active:item.id == sid}"
-                  v-if="item.name.length<11"
+                  v-if="item.name.length<8"
                   @click="checkS(item.id)"
                 >{{item.name}}</span>
                 <el-tooltip
@@ -144,7 +144,7 @@
           </div>
           <div class="e_add_list">
             <div class="e_add_list_title">
-              <span>三级目</span>
+              <span>三级目</span>
               <img src="../../assets/add.png" @click="addE(3)" v-if="sid != ''" alt />
             </div>
             <div class="e_add_list_body">
@@ -155,7 +155,7 @@
               >
                 <span
                   :class="{active:item.id == tid}"
-                  v-if="item.name.length<11"
+                  v-if="item.name.length<8"
                   @click="checkT(item.id)"
                 >{{item.name}}</span>
                 <el-tooltip
@@ -175,6 +175,7 @@
             </div>
             <!-- <div class="e_add_list_btn">添加二级标题</div> -->
           </div>
+          <Mind :showBar="false" :mindData="data"></Mind>
         </div>
       </div>
       <span slot="footer" class="dialog-footer">
@@ -206,9 +207,40 @@
 </template>
 
 <script>
+import Mind from "../tools/jsmind";
 export default {
+  components: {
+    Mind,
+  },
   data() {
     return {
+      data: {
+        meta: {
+          name: "example",
+          author: "dd@163.com",
+          version: "0.2",
+        },
+        format: "node_array",
+        data: [
+          { id: "root", isroot: true, topic: "" },
+          // { id: "easy", parentid: "root", topic: "Easy" },
+          // { id: "easy1", parentid: "easy", topic: "Easy to show" },
+          // { id: "easy2", parentid: "easy", topic: "Easy to edit" },
+          // { id: "easy3", parentid: "easy", topic: "Easy to store" },
+          // { id: "easy4", parentid: "easy", topic: "Easy to embed" },
+          // { id: "open", parentid: "root", topic: "Open Source" },
+          // { id: "open1", parentid: "open", topic: "on GitHub" },
+          // { id: "open2", parentid: "open", topic: "BSD License" },
+          // { id: "powerful", parentid: "root", topic: "Powerful" },
+          // {
+          //   id: "powerful1",
+          //   parentid: "powerful",
+          //   topic: "Base on Javascript",
+          // },
+          // { id: "powerful2", parentid: "powerful", topic: "Base on HTML5" },
+          // { id: "powerful3", parentid: "powerful", topic: "Depends on you" },
+        ],
+      },
       page: 1,
       total: 0,
       dialogVisible: false,
@@ -286,6 +318,7 @@ export default {
         this.dialogVisible3 = false;
         this.eName = "";
       }
+      this.setMindData();
     },
     checkF(id) {
       if (this.fid == id) {
@@ -322,6 +355,7 @@ export default {
       }
       delete this.eJson[id];
       this.$forceUpdate();
+      this.setMindData();
     },
     deleteS(id) {
       if (JSON.stringify(this.eJson[this.fid].child[id].child) != "{}") {
@@ -333,6 +367,7 @@ export default {
       }
       delete this.eJson[this.fid].child[id];
       this.$forceUpdate();
+      this.setMindData();
     },
     deleteT(id) {
       if (this.tid == id) {
@@ -340,10 +375,11 @@ export default {
       }
       delete this.eJson[this.fid].child[this.sid].child[id];
       this.$forceUpdate();
+      this.setMindData();
     },
     addEJson() {
       if (this.eTitle == "") {
-        this.$message.error("请填写评价体系标题");
+        this.$message.error("请填写目标管理标题");
         return;
       }
       let params = [
@@ -368,7 +404,7 @@ export default {
     },
     updateEJson() {
       if (this.eTitle == "") {
-        this.$message.error("请填写评价体系标题");
+        this.$message.error("请填写目标管理标题");
         return;
       }
       let params = [
@@ -448,6 +484,7 @@ export default {
     addED() {
       this.update = false;
       this.init();
+      this.setMindData();
       this.dialogVisible = true;
     },
     checkE(res) {
@@ -457,6 +494,45 @@ export default {
       this.eid = res.id;
       this.update = true;
       this.dialogVisible = true;
+      this.$forceUpdate();
+      setTimeout(() => {
+        this.setMindData();
+      }, 0);
+    },
+    setMindData() {
+      this.data.data = [];
+      this.data.data.push({ id: "root", isroot: true, topic: this.eTitle });
+      let _eJson = Object.keys(this.eJson);
+      let _e = this.eJson;
+      for (let i = 0; i < _eJson.length; i++) {
+        let element = _e[_eJson[i]];
+        this.data.data.push({
+          id: element.id,
+          parentid: "root",
+          topic: element.name,
+        });
+        let _eJsonc = Object.keys(element.child);
+        let _e2 = element.child;
+        for (let j = 0; j < _eJsonc.length; j++) {
+          let _ec = _e2[_eJsonc[j]];
+          this.data.data.push({
+            id: _ec.id,
+            parentid: element.id,
+            topic: _ec.name,
+          });
+          let _eJsonz = Object.keys(_ec.child);
+          let _e3 = _ec.child;
+          for (let z = 0; z < _eJsonz.length; z++) {
+            let _ez = _e3[_eJsonz[z]];
+            this.data.data.push({
+              id: _ez.id,
+              parentid: _ec.id,
+              topic: _ez.name,
+            });
+          }
+        }
+      }
+      this.$forceUpdate();
     },
   },
   created() {
@@ -620,7 +696,6 @@ export default {
   width: 400px;
 }
 
-
 .e_add_btn {
 }
 .e_add_content {
@@ -632,7 +707,7 @@ export default {
 .e_add_list {
   background: #fff;
   height: 500px;
-  width: 240px;
+  width: 210px;
   position: relative;
   margin: 15px 5px 0 0;
   flex-shrink: 0;
@@ -651,6 +726,7 @@ export default {
   align-items: center;
   justify-content: center;
   height: 57px;
+  background: #f6f6f6;
 }
 .e_add_list_title span {
   overflow: hidden;

+ 551 - 0
src/components/tools/jsmind.vue

@@ -0,0 +1,551 @@
+<template>
+  <!-- 普通菜单 -->
+  <div class="jsmind_layout">
+    <span class="jsmind_title">目标树</span>
+    <div class="noMind" v-if="mindV">
+      <img src="../../assets/nominddata.png" alt />
+    </div>
+    <!-- <div class="jsmind_toolbar" v-if="showBar">
+      <el-upload
+        class="pad"
+        :multiple="false"
+        ref="upload"
+        action="action"
+        :before-upload="beforeUpload"
+        :http-request="upload"
+      >
+        <el-button type="primary" size="medium">导入</el-button>
+      </el-upload>
+      <el-button @click="save_nodearray_file" size="medium">保存</el-button>
+      <el-button @click="screen_shot" size="medium">下载导图</el-button>
+      <el-button @click="get_nodearray_data" size="medium">获取数据</el-button>
+      <el-button @click="addNode" size="medium">新增节点</el-button>
+      <el-button @click="addBrotherNode" size="medium">新增兄弟节点</el-button>
+      <el-button @click="editNode" size="medium">编辑节点</el-button>
+      <el-button @click="removeNode" size="medium">删除节点</el-button>
+      <el-button @click="zoomIn" size="medium" :disabled="isZoomIn">放大</el-button>
+      <el-button @click="zoomOut" size="medium" :disabled="isZoomOut" class="pad">缩小</el-button>
+      <span>展开:</span>
+      <el-select
+        v-model="level"
+        placeholder="展开节点"
+        @change="expand_to_level"
+        class="pad pad-left"
+        size="medium"
+      >
+        <el-option
+          v-for="item in nodeOptions"
+          :key="item.value"
+          :label="item.label"
+          :value="item.value"
+        ></el-option>
+      </el-select>
+      <span>主题:</span>
+      <el-select v-model="localTheme" placeholder="选择主题" @change="set_theme" size="medium">
+        <el-option
+          v-for="item in themeOptions"
+          :key="item.value"
+          :label="item.label"
+          :value="item.value"
+        ></el-option>
+      </el-select>
+    </div>-->
+    <div id="jsmind_container" ref="container"></div>
+    <!-- <el-drawer title="编辑节点" :visible.sync="dialogVisible" size="500px">
+      <el-form label-width="80px" class="form-con">
+        <el-form-item label="字体大小">
+          <el-input-number
+            controls-position="right"
+            v-model.number="nodeOption.fontSize"
+            class="ele-width"
+            :min="1"
+            :max="30"
+            maxlength="2"
+          ></el-input-number>
+        </el-form-item>
+        <el-form-item label="字体粗细">
+          <el-select v-model="nodeOption.fontWeight" class="ele-width">
+            <el-option value="normal" label="常规"></el-option>
+            <el-option value="bold" label="粗体"></el-option>
+            <el-option value="bolder" label="更粗"></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="字体样式">
+          <el-select v-model="nodeOption.fontStyle" class="ele-width">
+            <el-option value="normal" label="标准"></el-option>
+            <el-option value="italic" label="斜体"></el-option>
+            <el-option value="oblique" label="倾斜"></el-option>
+          </el-select>
+        </el-form-item>
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="背景颜色">
+              <el-color-picker v-model="nodeOption.bgColor" show-alpha size="mini"></el-color-picker>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="字体颜色">
+              <el-color-picker v-model="nodeOption.fontColor" show-alpha size="mini"></el-color-picker>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-form-item label="节点内容">
+          <el-input
+            type="textarea"
+            :rows="2"
+            v-model="nodeOption.content"
+            class="ele-width"
+            maxlength="64"
+          ></el-input>
+        </el-form-item>
+      </el-form>
+      <template v-slot:footer>
+        <div class="right mr-10">
+          <el-button type="primary" class="common-btn" @click="sureEditNode" size="medium">确 定</el-button>
+        </div>
+      </template>
+    </el-drawer>-->
+  </div>
+</template>
+
+<script>
+import "jsmind/style/jsmind.css";
+import jsMind from "jsmind/js/jsmind.js";
+window.jsMind = jsMind;
+
+require("jsmind/js/jsmind.draggable.js");
+require("jsmind/js/jsmind.screenshot.js");
+export default {
+  props: {
+    showBar: {
+      // 是否显示工具栏,显示启用编辑
+      type: Boolean,
+      default: true,
+    },
+    theme: {
+      // 主题
+      type: String,
+      default: "primary",
+    },
+    lineColor: {
+      // 线条颜色
+      type: String,
+      default: "skyblue",
+    },
+    mindData: {
+      type: Object,
+      default: {},
+    },
+  },
+  data() {
+    return {
+      mindV: false,
+      i: 0,
+      mind: {},
+      jm: null,
+      isZoomIn: false,
+      isZoomOut: false,
+      level: 0,
+      nodeOptions: [
+        { value: 1, label: "展开到一级节点" },
+        { value: 2, label: "展开到二级节点" },
+        { value: 3, label: "展开到三级节点" },
+        { value: 0, label: "展开全部节点" },
+        { value: -1, label: "隐藏全部节点" },
+      ],
+      themeOptions: [
+        { value: "default", label: "default" },
+        { value: "primary", label: "primary" },
+        { value: "warning", label: "warning" },
+        { value: "danger", label: "danger" },
+        { value: "success", label: "success" },
+        { value: "info", label: "info" },
+        { value: "greensea", label: "greensea" },
+        { value: "nephrite", label: "nephrite" },
+        { value: "belizehole", label: "belizehole" },
+        { value: "wisteria", label: "wisteria" },
+        { value: "asphalt", label: "asphalt" },
+        { value: "orange", label: "orange" },
+        { value: "pumpkin", label: "pumpkin" },
+        { value: "pomegranate", label: "pomegranate" },
+        { value: "clouds", label: "clouds" },
+        { value: "asbestos", label: "asbestos" },
+      ],
+      localTheme: this.theme,
+      dialogVisible: false,
+      nodeOption: {
+        content: "",
+        bgColor: "",
+        fontColor: "",
+        fontSize: "",
+        fontWeight: "",
+        fontStyle: "",
+      },
+    };
+  },
+  watch: {
+    mindData: {
+      handler: function (cur, old) {
+        this.mind = cur;
+        if (cur.data[0].topic === "" && cur.data.length === 1) {
+          this.mindV = true;
+        } else {
+          this.mindV = false;
+        }
+        if (this.jm) {
+          this.jm.show(this.mind);
+        } else {
+          this.open_empty();
+        }
+      },
+      deep: true, //对象内部的属性监听,也叫深度监听
+    },
+  },
+  created() {},
+  mounted() {
+    this.getData();
+    // this.mouseWheel();
+  },
+  methods: {
+    beforeUpload(file) {
+      // 上传文件之前钩子
+      if (file) {
+        jsMind.util.file.read(file, (jsmindData) => {
+          const mind = jsMind.util.json.string2json(jsmindData);
+          if (mind) {
+            this.jm.show(mind);
+            this.$message({ type: "success", message: "打开成功" });
+          } else {
+            this.prompt_info("不能打开mindmap文件");
+          }
+        });
+      } else {
+        this.prompt_info("请先选择文件");
+        return false;
+      }
+    },
+    upload() {},
+    getData() {
+      //   this.$API({
+      //     name: "getMind",
+      //   })
+      //     .then((res) => {
+      //       this.mind = res.data;
+      //       this.open_empty();
+      //     })
+      //     .catch((error) => {
+      //       this.$message.error(error);
+      //     });
+      if (
+        !this.mind.data ||
+        (this.mind.data[0].topic === "" && this.mind.data.length === 1)
+      ) {
+        this.mindV = true;
+      } else {
+        this.mindV = false;
+      }
+      this.mind = this.mindData;
+      this.open_empty();
+    },
+    open_empty() {
+      const options = {
+        container: "jsmind_container", // 必选,容器ID
+        editable: this.showBar, // 可选,是否启用编辑
+        theme: this.localTheme, // 可选,主题
+        view: {
+          line_width: 2, // 思维导图线条的粗细
+          // line_color: this.lineColor, // 思维导图线条的颜色
+        },
+        shortcut: {
+          enable: true, // 禁用快捷键
+        },
+        layout: {
+          hspace: 20, // 节点之间的水平间距
+          vspace: 10, // 节点之间的垂直间距
+          pspace: 13, // 节点与连接线之间的水平间距(用于容纳节点收缩/展开控制器)
+        },
+        mode: "side", // 显示模式,子节点只分布在根节点右侧
+      };
+      this.jm = jsMind.show(options, this.mind);
+      // 改变窗口大小重置画布
+      window.onresize = () => {
+        this.jm.resize();
+      };
+      this.getDepth(this.jm.mind.root, 1);
+      this.$forceUpdate();
+    },
+    // 获取层级数 i
+    getDepth(obj, k) {
+      this.i = Math.max(this.i, k);
+      if (obj.children) {
+        obj.children.forEach((v) => {
+          this.getDepth(v, k + 1);
+        });
+      }
+    },
+    save_nodearray_file() {
+      const mindData = this.jm.get_data("node_array");
+      const mindName = mindData.meta.name;
+      const mindStr = jsMind.util.json.json2string(mindData);
+      jsMind.util.file.save(mindStr, "text/jsmind", mindName + ".jm");
+    },
+    screen_shot() {
+      this.jm.screenshot.shootDownload();
+    },
+    expand_all() {
+      this.jm.expand_all();
+    },
+    collapse_all() {
+      this.jm.collapse_all();
+    },
+    expand_to_level(num) {
+      switch (num) {
+        case -1:
+          this.collapse_all();
+          break;
+        case 0:
+          this.expand_all();
+          break;
+        default:
+          this.jm.expand_to_depth(num);
+          break;
+      }
+    },
+    zoomIn() {
+      if (this.jm.view.zoomIn()) {
+        this.isZoomOut = false;
+      } else {
+        this.isZoomIn = true;
+      }
+    },
+    zoomOut() {
+      debugger;
+      if (this.jm.view.zoomOut()) {
+        this.isZoomIn = false;
+      } else {
+        this.isZoomOut = true;
+      }
+    },
+    prompt_info(msg) {
+      this.$message({ type: "warning", message: msg });
+    },
+    get_nodearray_data() {
+      const mindData = this.jm.get_data("node_array");
+      const mindString = jsMind.util.json.json2string(mindData);
+      this.$message({ type: "info", message: mindString });
+    },
+    set_theme(themeName) {
+      this.jm.set_theme(themeName);
+    },
+    scrollFunc(e) {
+      e = e || window.event;
+      if (e.wheelDelta) {
+        if (e.wheelDelta > 0) {
+          this.zoomIn();
+        } else {
+          this.zoomOut();
+        }
+      } else if (e.detail) {
+        if (e.detail > 0) {
+          this.zoomIn();
+        } else {
+          this.zoomOut();
+        }
+      }
+      this.jm.resize();
+    },
+    // 鼠标滚轮放大缩小
+    mouseWheel() {
+      if (document.addEventListener) {
+        document.addEventListener("domMouseScroll", this.scrollFunc, false);
+      }
+      this.$refs.container.onmousewheel = this.scrollFunc;
+    },
+    // 新增节点
+    addNode() {
+      let selectedNode = this.jm.get_selected_node();
+      if (!selectedNode) {
+        this.$message({ type: "warning", message: "请先选择一个节点!" });
+        return;
+      }
+      let nodeid = jsMind.util.uuid.newid();
+      let topic = "new Node";
+      let newNode = this.jm.add_node(selectedNode, nodeid, topic);
+      if (newNode) {
+        this.jm.select_node(nodeid);
+        this.jm.begin_edit(nodeid);
+        this.getDepth(this.jm.mind.root, 1);
+      }
+    },
+    // 新增兄弟节点
+    addBrotherNode() {
+      let selectedNode = this.jm.get_selected_node();
+      if (!selectedNode) {
+        this.$message({ type: "warning", message: "请先选择一个节点!" });
+        return;
+      } else if (selectedNode.isroot) {
+        this.$message({
+          type: "warning",
+          message: "不能在根节点添加,请重新选择节点!",
+        });
+        return;
+      }
+      let nodeid = jsMind.util.uuid.newid();
+      let topic = "new Node";
+      let newNode = this.jm.insert_node_after(selectedNode, nodeid, topic);
+      if (newNode) {
+        this.jm.select_node(nodeid);
+        this.jm.begin_edit(nodeid);
+      }
+    },
+    // 获取选中标签的 ID
+    get_selected_nodeid() {
+      let selectedNode = this.jm.get_selected_node();
+      if (selectedNode) {
+        return selectedNode.id;
+      } else {
+        return null;
+      }
+    },
+    // 删除节点
+    removeNode() {
+      let selectedId = this.get_selected_nodeid();
+      if (!selectedId) {
+        this.$message({
+          type: "warning",
+          message: "请先选择一个节点!",
+        });
+        return;
+      }
+      this.jm.remove_node(selectedId);
+      this.i = 0;
+      this.getDepth(this.jm.mind.root, 1);
+    },
+    // 编辑节点
+    editNode() {
+      let selectedId = this.get_selected_nodeid();
+      if (!selectedId) {
+        this.$message({ type: "warning", message: "请先选择一个节点!" });
+        return;
+      }
+      let nodeObj = this.jm.get_node(selectedId);
+      this.nodeOption.content = nodeObj.topic;
+      this.nodeOption.bgColor = nodeObj.data["background-color"];
+      this.nodeOption.fontColor = nodeObj.data["foreground-color"];
+      this.nodeOption.fontSize = nodeObj.data["font-size"];
+      this.nodeOption.fontWeight = nodeObj.data["font-weight"];
+      this.nodeOption.fontStyle = nodeObj.data["font-style"];
+      this.dialogVisible = true;
+    },
+    sureEditNode() {
+      let selectedId = this.get_selected_nodeid();
+      this.jm.update_node(selectedId, this.nodeOption.content);
+      this.jm.set_node_font_style(
+        selectedId,
+        this.nodeOption.fontSize,
+        this.nodeOption.fontWeight,
+        this.nodeOption.fontStyle
+      );
+      this.jm.set_node_color(
+        selectedId,
+        this.nodeOption.bgColor,
+        this.nodeOption.fontColor
+      );
+      this.nodeOption = {
+        content: "",
+        bgColor: "",
+        fontColor: "",
+        fontSize: "",
+        fontWeight: "",
+        fontStyle: "",
+      };
+      this.dialogVisible = false;
+    },
+  },
+  beforeDestroy() {
+    // document.removeEventListener("domMouseScroll", this.scrollFunc, false);
+  },
+};
+</script>
+
+<style scoped>
+.jsmind_layout {
+  display: flex;
+  flex-direction: column;
+  width: 500px;
+  /* height: calc(100% - 40px); */
+  height: 500px;
+  margin: 15px 5px 0 0;
+  background: #fff;
+  overflow: hidden;
+  flex-shrink: 0;
+  position: relative;
+}
+.jsmind_title {
+  position: absolute;
+  top: 20px;
+  left: 20px;
+  font-size: 20px;
+  color: #8d8d8d;
+}
+.noMind {
+  position: absolute;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  width: 100%;
+  height: 100%;
+  z-index: 999;
+  background: #fff;
+}
+.jsmind_layout .jsmind_toolbar {
+  width: 100%;
+  padding: 0 10px 10px 10px;
+  height: auto;
+  flex-shrink: 0;
+  display: flex;
+  align-items: center;
+  flex-wrap: wrap;
+  background-color: #f8f9fa;
+  box-shadow: 0 0 4px #b8b8b8;
+}
+.jsmind_layout >>> .el-button--medium,
+.jsmind_layout >>> .el-input--medium {
+  margin-top: 10px;
+}
+.jsmind_layout #jsmind_container {
+  /* flex: 1 1 auto; */
+  height: 100%;
+}
+.jsmind_layout >>> .jsmind-inner {
+  /* overflow: hidden auto !important; */
+  /* height: auto; */
+}
+.jsmind_layout >>> .el-upload-list {
+  display: none !important;
+}
+/* 隐藏滚动条 */
+.jsmind_layout .jsmind-inner::-webkit-scrollbar {
+  display: none;
+}
+.jsmind_layout .pad {
+  margin-right: 10px;
+}
+.jsmind_layout .pad-left {
+  margin-left: 10px;
+}
+.jsmind_layout >>> jmnode.selected {
+  background-color: #b9b9b9;
+  color: #fff;
+  box-shadow: 2px 2px 8px #777;
+}
+.jsmind_layout >>> jmnode:hover {
+  box-shadow: 2px 2px 8px #777;
+}
+.jsmind_layout .form-con {
+  padding-top: 20px;
+}
+.jsmind_layout .ele-width {
+  width: 96%;
+}
+</style>

+ 3 - 3
src/main.js

@@ -15,12 +15,12 @@ import VueCookies from 'vue-cookies'
 import Viewer from 'v-viewer'
 import 'viewerjs/dist/viewer.css'
 import Clipboard from "clipboard";
-import hevueImgPreview from 'hevue-img-preview'
+// import hevueImgPreview from 'hevue-img-preview'
 
 const echarts = require('echarts');
 
-
-Vue.use(VideoPlayer).use(VueCookies).use(Viewer).use(hevueImgPreview)
+//.use(hevueImgPreview)
+Vue.use(VideoPlayer).use(VueCookies).use(Viewer)
 Vue.config.productionTip = false
 Vue.prototype.$store = store; // 将store实例挂在vue原型上
 Vue.prototype.ajax = ajax

Some files were not shown because too many files changed in this diff