Bladeren bron

add path&adv bar

cnwangzd@gmail.com 3 jaren geleden
bovenliggende
commit
5e00dd85de

File diff suppressed because it is too large
+ 0 - 1
app/matrix/m3graph/css/app.09bfc523.css


File diff suppressed because it is too large
+ 1 - 0
app/matrix/m3graph/css/app.a3952eaa.css


File diff suppressed because it is too large
+ 1 - 1
app/matrix/m3graph/index.html


File diff suppressed because it is too large
+ 0 - 1
app/matrix/m3graph/js/app.a4dfff03.js


File diff suppressed because it is too large
+ 1 - 0
app/matrix/m3graph/js/app.a7ca9dce.js


File diff suppressed because it is too large
+ 344 - 0
app/matrix/m3graph/js/chunk-vendors.991a932f.js


File diff suppressed because it is too large
+ 0 - 344
app/matrix/m3graph/js/chunk-vendors.cb9cb244.js


+ 1 - 1
src/components/MainView.vue

@@ -1,6 +1,6 @@
 <template>
 
-  <IndexView></IndexView>
+  <IndexView :global="global"></IndexView>
   
 </template>
 

+ 12 - 8
src/components/graph/GraphHandler.vue

@@ -81,7 +81,7 @@ const {mxEditor,mxGraph,mxConstants,mxPanningHandler,mxGraphHandler,mxGuide,mxEd
 export default {
   name: "GraphView",
   props: {
-    model: Array,
+    graphData: Object,
     global: Object
   },
   data() {
@@ -175,11 +175,11 @@ export default {
     };
   },
   watch: {
-        model:{
+        graphData:{
           handler(){
-              //this.initData();
+              this.setGraphData();
           },
-          deep: true
+          immediate: true
         },
         'graph.control.refresh.enable':{
             handler(val){
@@ -203,15 +203,16 @@ export default {
         },
   },
   created(){
-    //this.initData();
     this.init();
   },
   mounted(){
+
+      this.initGraph();
+
       this.eventHub.$on("graph-position",(v)=>{
           this.onCellPosition(v.row,v.hFlag,v.vFlag);
       })
 
-      this.initGraph();
   },
   methods: {
     // 初始化
@@ -238,10 +239,13 @@ export default {
 
     },
     // 加载图数据
-    initData(){
+    setGraphData(){
         
-        if(_.isEmpty(this.model)) {
+        if(_.isEmpty(this.graphData)) {
             return false;
+        } else {
+            this.graph.data = this.graphData;
+            this.onReload();
         }
     },
     // 初始化图板

+ 13 - 4
src/components/graph/index.vue

@@ -1,19 +1,25 @@
 <template>
     <div class="container">
-        <SearchBar ref="searchBarRef"></SearchBar>
-        <GraphHandler :model="model"
+        <SearchBar @graph-data="onSetData" ref="searchBarRef"></SearchBar>
+        <GraphHandler :graphData="graphData" 
+            :global="global"
             @control-show="onControlShow"></GraphHandler>
     </div>
 </template>
 
 <script>
 import GraphHandler from './GraphHandler';
-import SearchBar from './SearchBar';
+import SearchBar from './searchbar/index';
 
 export default {
     name: "Index",
     props: {
-        model: Object
+        global: Object
+    },
+    data(){
+        return {
+            graphData: null
+        }
     },
     components:{
         GraphHandler,
@@ -22,6 +28,9 @@ export default {
     methods:{
         onControlShow(data){
             this.$refs.searchBarRef.control.show = data;
+        },
+        onSetData(data){
+            this.graphData = data;
         }
     }
 }

+ 175 - 0
src/components/graph/searchbar/AdvBar.vue

@@ -0,0 +1,175 @@
+<template>
+    <el-container class="adv-bar">
+        <el-header style="display:flex;height:35px;line-height:35px;padding:0px;">
+            <el-button type="text" :icon="controlStatus" @click="control.show=!control.show"></el-button>
+            <template v-if="control.show">
+                <el-input placeholder="搜索实体、活动关键字" class="input" disabled></el-input>
+                <el-button type="text" @click="$emit('toggle-view','SearchBar')">
+                    <span class="el-icon-close" style="font-size:14px;font-weight: 900;"></span>
+                </el-button>
+                <el-button type="success" class="search" :loading="search.loading" @click="onSearch">
+                    <span class="el-icon-search"></span>
+                </el-button>
+            </template>
+        </el-header>
+        <transition name="fade">
+            <el-main style="width:100%;height:30vh;border-top:1px solid #409EFF;" v-show="control.show">
+                <Editor
+                    v-model="search.term"
+                    @init="onEditorInit"
+                    :lang="editor.lang.value"
+                    :theme="editor.theme.value"
+                    width="100%"
+                    height="80%"
+                    style="border:1px solid #f2f2f2;">
+                </Editor>
+            </el-main>
+        </transition>
+    </el-container>
+</template>
+
+<script>
+import _ from 'lodash';
+
+export default {
+    name: "AdvBar",
+    components:{
+        Editor:require("vue2-ace-editor"),
+    },
+    data(){
+        return {
+            control: {
+                show: true
+            },
+            search: {
+                loading: false,
+                term: "",
+                result: null
+            },
+            selected: null,
+            editor: {
+                data: null,
+                loading: false,
+                lang: {
+                    value: "sql",
+                    list: []
+                },
+                theme: {
+                    value: "chrome",
+                    list: this.m3.EDITOR_THEME
+                }
+            }
+        }
+    },
+    watch: {
+        'search.term':function(val){
+            if(_.isEmpty(val)){
+                this.onClear();
+            }
+        }
+    },
+    computed:{
+        controlStatus(){
+            if(this.control.show){
+                return 'el-icon-arrow-left';
+            } else {
+                return 'el-icon-arrow-right';
+            }
+        },
+        searchResultStatus(){
+            return this.control.show && this.entity.search.result && this.entity.search.result.length > 0;
+        }
+    },
+    filters: {
+        pickIcon(item){
+            let icon = item.icon;
+            return `/static/assets/images/entity/png/${icon}.png`;
+        }
+    },
+    methods: {
+        onEditorInit(){
+            require("brace/ext/language_tools"); //language extension prerequsite...
+            require(`brace/mode/${this.editor.lang.value}`); //language
+            require(`brace/snippets/${this.editor.lang.value}`); //snippet
+            require(`brace/theme/${this.editor.theme.value}`); //language
+        },
+        onEntityTreeSelected(data){
+            this.search.term = data.alias;
+            this.onSearch();
+        },
+        onClear(){
+            this.search.selected = null;
+            this.search.result = null;
+        },
+        onSearch() {
+
+            this.search.loading = true;
+            
+            if(_.isEmpty(this.search.term)){
+                return false;
+            }
+
+            this.m3.callFS("/matrix/m3graph/graphService.js", encodeURIComponent(this.search.term)).then( res=>{
+            
+                this.$emit("graph-data",res.message[0].graph);
+
+                this.search.loading = false;
+
+                this.control.show = false;
+
+            }).catch(()=>{
+                this.search.loading = false;
+            });
+            
+        }
+    }
+}
+</script>
+
+<style scoped>
+    .adv-bar.el-container{
+        position: absolute;
+        left: 10px;
+        top: 10px;
+        z-index: 1000;
+        background: #f2f2f2;
+    }
+    .adv-bar .el-header{
+        text-align: center;
+        border: 1px solid #f2f2f2;
+    }
+    .adv-bar .el-button+.el-button {
+        margin-left: 0px;
+    }
+    .adv-bar .el-button{
+        color: #777777;
+        width: 50px;
+        border-radius: 0px!important;
+    }
+
+    .adv-bar .input{
+        width: auto;
+        min-width: 83vw;
+    }
+
+    .adv-bar .search span{
+        color: #ffffff;
+    }
+
+    .adv-bar .el-divider__text {
+        background-color: transparent;
+        color: #777777;
+    }
+</style>
+<style>
+    .adv-bar .el-input-group__append, .el-input-group__prepend{
+        border: unset!important;
+    }
+    .adv-bar .el-input--mini .el-input__inner {
+        height: 33px!important;
+        line-height: 33px!important;
+        border: transparent!important;
+        background: transparent!important;
+        border-radius: 0px!important;
+    }
+</style>

+ 352 - 0
src/components/graph/searchbar/PathBar.vue

@@ -0,0 +1,352 @@
+<template>
+    <el-container class="path-bar">
+        <el-header style="display:flex;height:35px;line-height:35px;padding:0px;">
+            <el-button type="text" :icon="controlStatus" @click="control.show=!control.show"></el-button>
+            <template v-if="control.show">
+                <div style="width:84%;">
+                    <el-radio-group v-model="entity.path.type">
+                        <el-radio-button label="all">全路径</el-radio-button>
+                        <el-radio-button label="short">最短路径</el-radio-button>
+                        <el-radio-button label="long">最长路径</el-radio-button>
+                        <el-radio-button label="">关键路径</el-radio-button>
+                    </el-radio-group>
+                </div>
+                <div>
+                    <el-divider direction="vertical"></el-divider>
+                </div>
+                <el-button type="text" @click="$emit('toggle-view','SearchBar')">
+                    <span class="el-icon-close" style="font-size:14px;font-weight: 900;"></span>
+                </el-button>
+                <el-tooltip content="路劲查询" open-delay="500" placement="top">
+                    <el-button type="success" class="search" :loading="entity.search.loading">
+                        <span class="el-icon-search"></span>
+                    </el-button>
+                </el-tooltip>
+                
+            </template>
+        </el-header>
+        <el-main style="width:100%;height:40vh;padding:0px;border-top:1px solid #409EFF;" v-show="searchResultStatus">
+            <div class="div-hover-effect" style="display:flex;padding:10px;cursor:pointer;" 
+                v-for="(item,index) in entity.search.result"
+                :key="index"
+                @click="onEntitySelect(item)"
+                draggable="true" 
+                @dragstart="onEntityDragStart(item,$event)">
+                <el-image :src="item | pickIcon" style="width:15%;height:15%;max-width:48px;min-width:48px;" slot="suffix">
+                    <div slot="error" class="image-slot">
+                        <i class="el-icon-picture-outline"></i>
+                    </div>
+                </el-image>
+                <div style="height:48px;line-height:48px;width:80%;padding-left:10px;">{{ item.value }}</div>
+                <el-tooltip content="拖动到画布">
+                    <el-button type="text" icon="el-icon-menu" style="padding-left:10px;cursor:pointer;"></el-button>
+                </el-tooltip>
+                <el-tooltip content="实体分析">
+                    <el-button type="text" icon="el-icon-postcard" style="padding-left:10px;cursor:pointer;" @click="onEntityDiagnosis(item)">
+                    </el-button>
+                </el-tooltip>
+            </div>
+            <el-button type="text" icon="el-icon-down"></el-button>
+        </el-main>
+    </el-container>
+</template>
+
+<script>
+
+import _ from 'lodash';
+
+export default {
+    name: "PathBar",
+    data(){
+        return {
+            control: {
+                show: true
+            },
+            entity: {
+                search: {
+                    loading: false,
+                    term: "",
+                    result: null
+                },
+                path: {
+                    type: "all"
+                },
+                selected: null
+            }
+        }
+    },
+    watch: {
+        'entity.search.term':function(val){
+            if(_.isEmpty(val)){
+                this.onEntityClear();
+            }
+        }
+    },
+    computed:{
+        controlStatus(){
+            if(this.control.show){
+                return 'el-icon-arrow-left';
+            } else {
+                return 'el-icon-arrow-right';
+            }
+        },
+        searchResultStatus(){
+            return this.control.show && this.entity.search.result && this.entity.search.result.length > 0;
+        }
+    },
+    filters: {
+        pickIcon(item){
+            let icon = item.icon;
+            return `/static/assets/images/entity/png/${icon}.png`;
+        }
+    },
+    methods: {
+        onEntityTreeSelected(data){
+            this.entity.search.term = data.alias;
+            this.onEntitySearch();
+        },
+        onEntityClear(){
+            this.entity.search.selected = null;
+            this.entity.search.result = null;
+        },
+        onEntitySearch() {
+
+            this.entity.search.loading = true;
+            
+            if(_.isEmpty(this.entity.search.term)){
+                return false;
+            }
+
+            let param = encodeURIComponent(this.entity.search.term);
+            this.m3.callFS("/matrix/m3graph/entity-search-by-term.js",param).then( rtn=>{
+                
+                let entitys = rtn.message;
+
+                if(_.isEmpty(entitys)){
+                    this.$message({
+                        type: "info",
+                        message: "没有匹配数据!"
+                    })
+
+                    this.entity.search.result = [];
+
+                    this.entity.search.loading = false;
+
+                    return false;
+                }
+
+                this.entity.search.result = entitys;
+
+                this.entity.search.result = _.map(this.entity.search.result,(v)=>{
+                    return _.extend(v,{ cell: {edge:false} } );
+                })
+
+                this.entity.search.loading = false;
+
+            } )
+            
+        },
+        onEntitySelect(){
+
+        },
+        onEntityDragStart(item,event){
+            event.dataTransfer.setData("Text",JSON.stringify(item));
+        },
+        onEntityDragEnd(){
+
+        },
+        ononEntityDiagnosis(){
+
+        },
+        onFileNew(){
+            /* this.deleteCells(true);
+            this.file.doc = null; */
+        },
+        onFileOpen(auto){
+            /* try{
+                
+                let editor = inst.app.$refs.graphViewRef.$refs.graphViewContainerInst.model.editor;
+
+                // 选择文件打开
+                if(!auto){
+                    this.file.doc = this.$refs.dfsOpen.node;
+                }
+                
+                let xml = fsHandler.fsContent(this.file.doc.parent, this.file.doc.name);
+                let doc = mxUtils.parseXml(xml);
+                let codec = new mxCodec(doc);
+                codec.decode(doc.documentElement, editor.graph.getModel());
+            } catch(err){
+                console.error(err);
+            } finally {
+                this.file.dialogOpen.visible = false;
+                inst.app.$refs.graphViewRef.$refs.graphViewContainerInst.toCenter();
+            } */
+            
+        },
+        onFileOpenTo(auto){
+            /* // 新建图
+            let graph = new mxGraph();
+            let parent = graph.getDefaultParent();
+            
+            try{
+                
+                
+
+                // 选择文件打开
+                if(!auto){
+                    this.file.doc = this.$refs.dfsOpen.node;
+                }
+                
+                let xml = fsHandler.fsContent(this.file.doc.parent, this.file.doc.name);
+                let doc = mxUtils.parseXml(xml);
+                let codec = new mxCodec(doc);
+                codec.decode(doc.documentElement, graph.getModel());
+
+                // 合并到当前图
+                let editor = inst.app.$refs.graphViewRef.$refs.graphViewContainerInst.model.editor;
+                editor.graph.getModel().mergeChildren(graph.getModel().getRoot(), editor.graph.getDefaultParent());
+
+                // Executes the layout handler
+                _.delay(()=>{
+                    inst.app.$refs.graphViewRef.$refs.graphViewContainerInst.executeLayout();
+                },500)
+            } catch(err){
+                console.error(err);
+            } finally {
+                this.file.dialogOpenTo.visible = false;
+            } */
+            
+        },
+        onFileSave(){
+            /* if(this.file.doc){
+                let editor = inst.app.$refs.graphViewRef.$refs.graphViewContainerInst.model.editor;
+                let enc = new mxCodec(mxUtils.createXmlDocument());
+                let node = enc.encode(editor.graph.getModel());
+                let xml = mxUtils.getPrettyXml(node);
+                let attr = _.extend(this.file.doc, {});
+                let rtn = fsHandler.fsNew('file',this.file.doc.parent, this.file.doc.name, xml, attr);
+                if(rtn == 1){
+                    this.$message({
+                        type:"success",
+                        message: "保存成功!"
+                    })
+                }
+            } else {
+                this.file.dialogSaveAs.visible = true;
+            } */
+        },
+        onFileSaveAs(){
+            
+            /* let editor = inst.app.$refs.graphViewRef.$refs.graphViewContainerInst.model.editor;
+
+            let enc = new mxCodec(mxUtils.createXmlDocument());
+            let node = enc.encode(editor.graph.getModel());
+            let xml = mxUtils.getPrettyXml(node);
+            let attr = {};
+            
+            let parent = this.$refs.dfsSaveas.node.fullname;
+            let name = this.$refs.dfsSaveas.fileName;
+            let rtn = fsHandler.fsNew('file',parent, name, xml, attr);
+            if(rtn == 1){
+                this.$message({
+                    type:"success",
+                    message: "保存成功!"
+                })
+                
+                this.file.doc = {parent:parent, name:name, fullname: [parent,name].join("/")};
+            }
+
+            this.file.dialogSaveAs.visible = false; */
+        },
+        onSaveAsPdf(){
+            // mxUtils.printScreen(inst.app.$refs.graphViewRef.$refs.graphViewContainerInst.model.editor.graph);
+        },
+        onFileClose(){
+            // this.deleteCells(true);
+            // this.file.doc = null;
+        },
+        onFilePrint(){
+            // inst.app.$refs.graphViewRef.$refs.graphViewContainerInst.model.editor.execute('print');
+        },
+        onFileDelete(){
+            /* if(this.file.doc){
+
+                this.$confirm(`确认要删除该设计文档:${this.file.doc.name}?`, '提示', {
+                    confirmButtonText: '确定',
+                    cancelButtonText: '取消',
+                    type: 'warning'
+                }).then(() => {
+                    let rtn = fsHandler.fsDelete(this.file.doc.parent,this.file.doc.name);
+
+                    if (rtn == 1){
+                        this.$message({
+                            type: "success",
+                            message: "删除成功!"
+                        });
+                        this.deleteCells(true);
+                        this.file.doc = null;
+                        localStorage.setItem("CLASS-DESIGN-OPEN-FILE",'');
+                        this.summaryInfo();
+                    } else {
+                        this.$message({
+                            type: "error",
+                            message: "删除失败 " + rtn.message
+                        })
+                    } 
+                }).catch(() => {
+                    
+                });
+            } */
+        }
+    }
+}
+</script>
+
+<style scoped>
+    .path-bar.el-container{
+        position: absolute;
+        left: 10px;
+        top: 10px;
+        z-index: 1000;
+        background: #f2f2f2;
+    }
+    .path-bar .el-header{
+        text-align: center;
+        border: 1px solid #f2f2f2;
+    }
+    .path-bar .el-button+.el-button {
+        margin-left: 0px;
+    }
+    .path-bar .el-button{
+        color: #777777;
+        width: 50px;
+        border-radius: 0px!important;
+    }
+
+    .path-bar .input{
+        width: auto;
+        min-width: 10vw;
+    }
+
+    .path-bar .search span{
+        color: #ffffff;
+    }
+</style>
+<style>
+    .path-bar .el-radio-button__orig-radio:checked+.el-radio-button__inner {
+        color: #252d47;
+        background-color: transparent;
+        border-color: transparent;
+        box-shadow: -1px 0 0 0 #252d47;
+    }
+
+    .path-bar .el-radio-button__inner {
+        background: transparent;
+        border: unset;
+    }
+
+    .path-bar .el-radio-button:first-child .el-radio-button__inner {
+        border-left: unset;
+    }
+</style>

+ 25 - 12
src/components/graph/SearchBar.vue

@@ -23,13 +23,13 @@
                         </el-dropdown>
                     </template>
                 </el-input>
-                <el-button type="text" class="path">
-                    路径
+                <el-button type="text" class="path" @click="$emit('toggle-view','PathBar')">
+                    <el-image src="/static/assets/images/tools/png/path-blue.png" style="width:16px;"></el-image>
                 </el-button>
-                <el-button type="text" class="adv">
+                <el-button type="text" class="adv" @click="$emit('toggle-view','AdvBar')">
                     高级
                 </el-button>
-                <el-button type="success" class="search">
+                <el-button type="success" class="search" :loading="entity.search.loading">
                     <span class="el-icon-search"></span>
                 </el-button>
                 <el-dropdown trigger="click">
@@ -50,14 +50,18 @@
                 </el-dropdown>
             </template>
         </el-header>
-        <el-main style="width:30vw;height:40vh;padding:0px;border-top:1px solid #409EFF;" v-show="control.show && entity.search.result">
+        <el-main style="width:100%;height:40vh;padding:0px;border-top:1px solid #409EFF;" v-show="searchResultStatus">
             <div class="div-hover-effect" style="display:flex;padding:10px;cursor:pointer;" 
                 v-for="(item,index) in entity.search.result"
                 :key="index"
                 @click="onEntitySelect(item)"
                 draggable="true" 
                 @dragstart="onEntityDragStart(item,$event)">
-                <!-- <el-image :src="item | pickIcon" style="width:15%;height:15%;max-width:48px;min-width:48px;" slot="suffix"></el-image> -->
+                <el-image :src="item | pickIcon" style="width:15%;height:15%;max-width:48px;min-width:48px;" slot="suffix">
+                    <div slot="error" class="image-slot">
+                        <i class="el-icon-picture-outline"></i>
+                    </div>
+                </el-image>
                 <div style="height:48px;line-height:48px;width:80%;padding-left:10px;">{{ item.value }}</div>
                 <el-tooltip content="拖动到画布">
                     <el-button type="text" icon="el-icon-menu" style="padding-left:10px;cursor:pointer;"></el-button>
@@ -69,14 +73,11 @@
             </div>
             <el-button type="text" icon="el-icon-down"></el-button>
         </el-main>
-        <el-footer style="width:30vw;padding:0px;border-top:1px solid #409EFF;height:auto;" v-if="entity.selected">
-            
-        </el-footer>
     </el-container>
 </template>
 
 <script>
-import ActionView from './ActionView';
+import ActionView from '../ActionView';
 import _ from 'lodash';
 
 export default {
@@ -88,6 +89,7 @@ export default {
             },
             entity: {
                 search: {
+                    loading: false,
                     term: "",
                     result: null
                 },
@@ -109,6 +111,9 @@ export default {
             } else {
                 return 'el-icon-arrow-right';
             }
+        },
+        searchResultStatus(){
+            return this.control.show && this.entity.search.result && this.entity.search.result.length > 0;
         }
     },
     filters: {
@@ -130,13 +135,16 @@ export default {
             this.entity.search.result = null;
         },
         onEntitySearch() {
+
+            this.entity.search.loading = true;
             
             if(_.isEmpty(this.entity.search.term)){
                 return false;
             }
 
             let param = encodeURIComponent(this.entity.search.term);
-            this.m3.callFS("/matrix/graph/entity-search-by-term.js",param).then( rtn=>{
+            this.m3.callFS("/matrix/m3graph/entity-search-by-term.js",param).then( rtn=>{
+                
                 let entitys = rtn.message;
 
                 if(_.isEmpty(entitys)){
@@ -147,6 +155,8 @@ export default {
 
                     this.entity.search.result = [];
 
+                    this.entity.search.loading = false;
+
                     return false;
                 }
 
@@ -155,6 +165,9 @@ export default {
                 this.entity.search.result = _.map(this.entity.search.result,(v)=>{
                     return _.extend(v,{ cell: {edge:false} } );
                 })
+
+                this.entity.search.loading = false;
+
             } )
             
         },
@@ -338,7 +351,7 @@ export default {
 
     .search-bar .input{
         width: auto;
-        min-width: 30vw;
+        min-width: 10vw;
     }
 
     .search-bar .search span{

+ 34 - 0
src/components/graph/searchbar/index.vue

@@ -0,0 +1,34 @@
+<template>
+    <component v-bind:is="currentView" 
+        transition="fade" transition-mode="out-in"
+        @toggle-view="onToggleView"
+        @graph-data="onSetData"></component>
+</template>
+
+<script>
+import SearchBar from '../searchbar/SearchBar';
+import PathBar from '../searchbar/PathBar';
+import AdvBar from '../searchbar/AdvBar';
+
+export default {
+    name: "index",
+    components: {
+        SearchBar,
+        PathBar,
+        AdvBar
+    },
+    data(){
+        return {
+            currentView: 'SearchBar'
+        }
+    },
+    methods:{
+        onToggleView(data){
+            this.currentView = data;
+        },
+        onSetData(data){
+            this.$emit("graph-data", data);
+        }
+    }
+}
+</script>