cxmo 1 жил өмнө
parent
commit
bdd77a635e

+ 2 - 0
src/api/modules/chartApi.js

@@ -1178,7 +1178,9 @@ const chartFrameInterface = {
     /**
      * 获取我的框架列表
      * @param {Object} params 
+     * @param {Number} params.AdminId
      * @param {String} params.Keyword 筛选关键词
+     * @param {Number} params.Visibility 0所有用户 1自己用户
      * @returns 
      */
     getMyFrameList:params=>{

+ 2 - 2
src/utils/svgToblob.js

@@ -1,10 +1,10 @@
 /* 针对系统中众多svg的图表/沙盘想要复制粘到微信中 */		
   import bus from '@/api/bus.js';
 
-  export const copyBlob = (url,callback=null,ratio=1) => {
+  export const copyBlob = (url,callback=null,ratio=1,urlType='svg') => {
     const copyImg = new Image()
     copyImg.crossOrigin = 'anonymous';
-    copyImg.src = svgToBase64(url);
+    copyImg.src = urlType==='svg'?svgToBase64(url):url;
 
     copyImg.onload = ()=> {
       const canvas = document.createElement('canvas');

+ 1 - 1
src/views/chartFrame_manage/common/graph.js

@@ -15,7 +15,7 @@ const viewConfig = {
         return false
     },
     highlighting:{},
-    connecting:{},
+    /* connecting:{}, */
     history:false,//关闭画布撤销/重做能力。
     keyboard:false,
     clipboard: false,

+ 14 - 0
src/views/chartFrame_manage/components/frameContainer.vue

@@ -22,6 +22,11 @@
                 </el-dropdown-item>
             </el-dropdown-menu>
         </div>
+        <!-- 内容空提示 -->
+        <div class="empty" v-if="!FrameworkContent.length&&$route.path!=='/editframe'">
+            <tableNoData text="框架内无节点"/>
+        </div>
+        <!-- 操作提示 -->
     </div>
 </template>
 
@@ -81,6 +86,9 @@ export default {
             //如果是编辑页,加载完成后清楚历史数据
             window.location.pathname.startsWith('/editframe')&&this.graph.cleanHistory()
         },
+        dispose(){
+            this.graph&&this.graph.dispose()
+        },
         editNode(node){
             //获取视口范围
             const position = this.graph.getContentArea()
@@ -222,6 +230,12 @@ export default {
     .x6-port-body {
         display: none;
     }
+    .empty{
+        position:absolute;
+        left:50%;
+        top:0;
+        transform: translateX(-50%);
+    }
 }
 </style>
 <style scoped lang="scss">

+ 22 - 0
src/views/chartFrame_manage/css/customTree.scss

@@ -19,6 +19,28 @@
         }
         .el-tree-node__content {
             margin-bottom: 7px !important;
+            &:hover {
+                background-color: #f0f4ff !important;
+              }
+        }
+        .el-tree-node__children {
+            .el-tree-node {
+              margin-bottom: 0px !important;
+              padding-left: 18px;
+            }
+        
+            .el-tree-node__content {
+              margin-bottom: 5px !important;
+              padding-left: 0 !important;
+        
+              &:hover {
+                background-color: #f0f4ff !important;
+              }
+            }
+        }
+        .el-tree-node.is-current>.el-tree-node__content {
+            background-color: #f0f4ff !important;
+            color: #409eff;
         }
         .expanded.el-icon-caret-right:before {
             content: url('~@/assets/img/set_m/down.png') !important;

+ 0 - 3
src/views/chartFrame_manage/frameEditor.vue

@@ -94,9 +94,6 @@ export default {
         },
         goToList(item) {
             window.open(`/mychart?frameId=${item.classifyId}`);
-        },
-        getGraphObject(){
-
         },
         async saveFrame(){
             if(!this.frameDetail.FrameworkName.length){

+ 153 - 66
src/views/chartFrame_manage/index.vue

@@ -18,14 +18,14 @@
                     placeholder="请输入框架名称"
                     v-model="searchText"
                     :remote-method="searchHandle"
-                    value-key="frameId"
+                    value-key="ChartFrameworkId"
                     clearable
                     >
                     <i slot="prefix" class="el-input__icon el-icon-search"></i>
                     <el-option
                         v-for="item in searchOptions"
-                        :key="item.frameId"
-                        :label="item.name"
+                        :key="item.ChartFrameworkId"
+                        :label="item.FrameworkName"
                         :value="item"
                     />
                 </el-select>
@@ -38,7 +38,7 @@
                             ref="catalogTree"
                             class="catalog-tree other-tree"
                             empty-text="暂无分类"
-                            :data="mockPublic"
+                            :data="publicFrameList"
                             node-key="nodeKeyId"
                             :expand-on-click-node="false"
                             @current-change="(data,node)=>{nodeChange(data,node)}"
@@ -79,26 +79,20 @@
                                 </span>
                                 <el-dropdown-menu slot="dropdown">
                                     <el-dropdown-item 
-                                        :command="{key:'own'}" 
-                                        :class="item.IsPublic === 0 ? 'el-dropdown-menu-item-chat-act' : ''"
+                                        :command="{key:'own',value:item}" 
                                         class="el-dropdown-menu-item-chat"
                                         >
                                         <div style="display: flex;align-items: center;">
-                                            <img v-if="item.IsPublic === 0" src="~@/assets/img/chart_m/Group_act.png">
-                                            <img v-else src="~@/assets/img/chart_m/Group.png">
+                                            <img src="~@/assets/img/chart_m/Group.png">
                                             <span style="margin-left:5px">仅自己可见</span>
-                                            
                                         </div>
-                                        
                                     </el-dropdown-item>
                                     <el-dropdown-item 
-                                        :command="{key:'public'}" 
-                                        :class="item.IsPublic === 1 ? 'el-dropdown-menu-item-chat-act' : ''"
+                                        :command="{key:'public',value:item}" 
                                         class="el-dropdown-menu-item-chat"
                                         >
                                         <div style="display: flex;align-items: center;">
-                                            <img v-if="item.IsPublic === 1" src="~@/assets/img/chart_m/User_act.png">
-                                            <img v-else src="~@/assets/img/chart_m/User.png">
+                                            <img src="~@/assets/img/chart_m/User.png">
                                             <span style="margin-left:5px">所有人可见</span>
                                         </div>
                                         
@@ -130,7 +124,7 @@
                 <div class="list" v-if="model==='list'">
                     <div class="list-item" 
                         v-for="item in currentList" :key="item.nodeKeyId"
-                        @click="changeModel('frame',item)"
+                        @click="nodeChange(item,{level:2})"
                         >
                         <div class="item-title text_oneLine">
                             <span>{{item.name}}</span>
@@ -138,6 +132,10 @@
                         <div style="height:1px;background:#ECECEC;margin:0 -10px;"></div>
                         <div class="item-image" 
                             :style="`background-image:url(${item.CoverImg?item.CoverImg:require('@/assets/img/document_m/default-img.png')})`"></div>
+                        <div style="height:1px;background:#ECECEC;margin:10px -10px;"></div>
+                        <div class="item-time">
+                            创建时间:{{item.CreateTime}}
+                        </div>
                     </div>
                     <div class="empty" v-if="currentList.length===0">
                         <tableNoData text="暂无数据"/>
@@ -149,7 +147,7 @@
                         <span class="title text_oneLine">{{currentFrame.FrameworkName}}</span>
                         <div class="tool">
                             <el-button type="text" @click="handleOption('edit',currentFrame)" v-if="frameType==='my'">编辑</el-button>
-                            <el-button type="text" @click="handleOption('copy',currentFrame)">复制图片</el-button>
+                            <el-button type="text" @click="handleOption('copy',currentFrame)" :disabled="!currentFrame.FrameworkContent">复制图片</el-button>
                             <el-button type="text" @click="handleOption('del',currentFrame)" style="color:red;"
                                 v-if="frameType==='my'">删除</el-button>
                         </div>
@@ -235,6 +233,7 @@ import draggable from 'vuedraggable';
 import FrameContainer from './components/frameContainer.vue';
 import chartDetail from '@/views/mychart_manage/components/chartDetailDia.vue';
 import { mychartInterface,chartFrameInterface } from '@/api/api.js';
+import {copyBlob} from '@/utils/svgToblob.js';
 export default {
     components:{ draggable, FrameContainer,chartDetail},
     directives: {
@@ -261,50 +260,28 @@ export default {
     data() {
         return {
             isSlideLeft:false,//控制左侧目录栏是否显示
+
+            /* drag 我的框架相关 */
+            dragStartIndex:0,
+            dragFrame:null,
+            prevFrame:null,
+            nextFrame:null,
+
+            /* search */
             searchText:'',
             searchOptions:[],
-            mockPublic:[
-                {
-                    catalogId:1,
-                    name:'XXX的框架',
-                    nodeKeyId:1,
-                    children:[{
-                        frameId:1,
-                        name:'黄金稳住了吗?aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
-                        nodeKeyId:'1-1',
-                        updateTime:'2023/10/13'
-                    }]
-                },
-                {
-                    catalogId:2,
-                    name:'aaa的框架',
-                    nodeKeyId:2,
-                    children:[]
-                }
-            ],
+            
+            /* select frame*/
+            model:'frame',
+            frameType:'my',
             publicFrameList:[],
             currentList:[],
-            mockFrameList:[
-                {
-                    frameId:2,
-                    name:'框架1',
-                    IsPublic:0,
-                    updateTime:'2023/10/10'
-                },
-                {
-                    frameId:3,
-                    name:'框架2',
-                    IsPublic:1,
-                    updateTime:'2023/10/11'
-                }
-            ],
             myFrameList:[],
             currentFrame:{},
+            /* frame node */
+            myETADetailDialogShow:false,
             modifyFrame:{},
             isRenameDialogShow:false,
-            model:'frame',
-            frameType:'my',
-            myETADetailDialogShow:false,
             chartClassify:0,
             classifyUserId:0,
             chartCode:'',
@@ -313,8 +290,19 @@ export default {
             myETAClassArr:[],
             copyToClassify:[],
             modeId:0,
+            lockLoding:null,
         };
     },
+    watch:{
+        searchText(newVal){
+            newVal&&this.chooseFrame(newVal)
+        }
+    },
+    computed:{
+        adminId(){
+            return Number(localStorage.getItem('AdminId'))
+        }
+    },
     methods: {
         slideHandle(){
             this.isSlideLeft = !this.isSlideLeft;
@@ -323,40 +311,111 @@ export default {
             chartFrameInterface.getPublicFrameList().then(res=>{
                 if(res.Ret!==200) return 
                 this.publicFrameList = res.Data||[]
+                this.publicFrameList = this.publicFrameList.map(list=>{
+                    list.name = list.MenuName
+                    list.nodeKeyId = 'list'+list.AdminId
+                    if(list.Frameworks){
+                        list.children = list.Frameworks.map(item=>{
+                            return {
+                                ...item,
+                                ...{
+                                    nodeKeyId:'item'+item.ChartFrameworkId,
+                                    name:item.FrameworkName
+                                }
+                            }
+                        })
+                    }
+                    return list
+                })
             })
         },
         async getMyList(type){
-            const res = await chartFrameInterface.getMyFrameList()
+            const res = await chartFrameInterface.getMyFrameList({AdminId:this.adminId})
             if(res.Ret!==200) return 
             this.myFrameList = res.Data||[]
             if(type!=='init') return 
             //如果是其他页面跳转来的
             if(this.$route.query.frameId){
-                this.currentFrame = this.myFrameList.find(i=>i.frameId===Number(this.$route.query.frameId))||{}
+                this.currentFrame = this.myFrameList.find(i=>i.ChartFrameworkId===Number(this.$route.query.frameId))||{}
             }else{
                 //否则选择myFrameList的第一个
                 this.currentFrame = this.myFrameList[0]||{}
             }
-            this.$nextTick(()=>{
-                this.$refs.container.init()
+            this.handleInitGraph()
+        },
+        searchHandle(keyword){
+            chartFrameInterface.getMyFrameList({
+                AdminId:this.adminId,
+                Keyword:keyword,
+            }).then(res=>{
+                if(res.Ret!==200) return
+                this.searchOptions = res.Data||[]
             })
         },
-        searchHandle(){},
         nodeChange(data,node){
             this.frameType = 'public'
             this.changeModel(node.level===2?'frame':'list',data)
+            this.$nextTick(()=>{
+                this.$refs.catalogTree.setCurrentKey(data.nodeKeyId)
+            })
         },
         changeModel(type,data){
+            if(type==='frame'&&this.frameType==='my'&&data.ChartFrameworkId===this.currentFrame.ChartFrameworkId) return 
             this.model = type
+            //销毁画布
+            this.$refs.container&&this.$refs.container.dispose()
             if(type==='frame'){
                 this.currentFrame = data
+                this.handleInitGraph()
             }else{
                 this.currentList = data.children||[]
             }
         },
-        menuDragStart(){},
-        menuDragenter(){},
-        menuDragOver(){},
+        handleInitGraph(){
+            //判断一下框架内容是否是合法的JSON,否则置为空
+            try{
+                JSON.parse(this.currentFrame.FrameworkContent)
+            }catch(e){
+                this.currentFrame.FrameworkContent = ''
+            }
+            this.$nextTick(()=>{
+                //若框架有内容,才加载画布
+                this.currentFrame.FrameworkContent&&this.$refs.container.init()
+            })
+        },
+        menuDragStart({oldIndex}){
+            this.dragStartIndex = oldIndex
+            this.dragFrame = this.myFrameList[oldIndex]
+        },
+        menuDragenter({newIndex}){
+            //置顶
+            if(newIndex===0){
+                this.prevFrame=null
+                this.nextFrame=this.myFrameList[newIndex+1]
+            }
+            //置底
+            if(newIndex===this.myFrameList.length-1){
+                this.prevFrame = this.myFrameList[newIndex-1]
+                this.nextFrame = null
+            }
+            if(newIndex!==0&&newIndex!==this.myFrameList.length-1){
+                this.prevFrame = this.myFrameList[newIndex-1]
+                this.nextFrame = this.myFrameList[newIndex+1]
+            }
+        },
+        menuDragOver({newIndex}){
+            if(newIndex===this.drageStartIndex) return
+            if(!this.dragFrame) return
+            chartFrameInterface.moveFrame({
+                ChartFrameworkId:this.dragFrame.ChartFrameworkId,
+                PrevChartFrameworkId:this.prevFrame?this.prevFrame.ChartFrameworkId:0,
+                NextChartFrameworkId:this.nextFrame?this.nextFrame.ChartFrameworkId:0,
+            }).then(res=>{
+                if(res.Ret!==200) return 
+                this.$message.success("移动成功")
+                this.getMyList()
+            })
+        },
         handleCommand(command){
             if(command.key==='edit'){
                 this.modifyFrame = _.cloneDeep(this.currentFrame)
@@ -365,6 +424,17 @@ export default {
             if(command.key==='del'){
                 this.deleteFrame(this.currentFrame)
             }
+            if(['own','public'].includes(command.key)){
+                chartFrameInterface.changePublicFrame({
+                    ChartFrameworkId:command.value.ChartFrameworkId,
+                    IsPublic:command.key==='own'?0:1
+                }).then(res=>{
+                    if(res.Ret!==200) return
+                    this.getPublicList()
+                    this.getMyList()
+                    this.$message.success(`操作成功`)
+                })
+            }
         },
         chooseFrame(item){
             this.frameType = 'my'
@@ -373,7 +443,7 @@ export default {
         handleOption(type,data){
             const optionMap = {
                 'edit':this.handleEditFrame,
-                'copy':this.copyFrame,
+                'copy':this.copyFrameImg,
                 'del':this.deleteFrame,
             }
             optionMap[type](data)
@@ -381,17 +451,33 @@ export default {
         handleEditFrame(data){
             this.$router.push({path:'/editframe',query:{frameId:data.ChartFrameworkId}})
         },
-        copyFrame(data){},
+        copyFrameImg(data){
+            this.lockLoding = this.$loading({
+                lock: true,
+                text: '复制图片中...',
+                target: '.frame-container-wrap',
+                spinner: 'el-icon-loading',
+                background: 'rgba(255, 255, 255, 0.8)'
+            });
+            copyBlob(data.FrameworkImg,()=>{
+                this.lockLoding && this.lockLoding.close();
+            },1,'normal')
+        },
         deleteFrame(data){
             this.$confirm("删除后不可恢复,确认删除吗?","提示",{
                 confirmButtonText:"确定",
                 cancelButtonText:"取消",
                 type:"warning"
             }).then(()=>{
-                //删除
-                this.$message.success("删除成功")
-                this.getPublicList()
-                this.getMyList()
+                chartFrameInterface.deleteFrame({
+                    ChartFrameworkId:data.ChartFrameworkId
+                }).then(res=>{
+                    if(res.Ret!==200) return
+                    this.$message.success("删除成功")
+                    this.getPublicList()
+                    this.getMyList()
+                    this.currentFrame = {}
+                })
             }).catch(()=>{})
         },
         renameFrame(){
@@ -401,6 +487,7 @@ export default {
             this.getPublicList()
             this.getMyList()
         },
+        //点击框架内节点
         handleShowDialog({id,userId}){
             //请求接口看有没有数据
             mychartInterface.myList({

+ 80 - 0
src/views/mychart_manage/components/classifyDeleteCheck.vue

@@ -0,0 +1,80 @@
+<template>
+    <el-dialog custom-class="classify-delete-wrap"
+        :visible.sync="hintDialogShow"
+        :close-on-click-modal="false"
+        :modal-append-to-body="false"
+        :append-to-body="false"
+        @close="$emit('close')"
+        center
+        width="400px"
+        v-dialogDrag
+    >
+        <div slot="title" style="display: flex; align-items: center;">
+            <i style="color:#FF8A00;font-size: 16px;" class="el-icon-warning"></i>
+            <span style="font-size: 16px;color:#333;margin-left: 5px;">提示</span>
+        </div>
+        <div class="dialog-container">
+            <p>该图分类已添加节点链接,不允许删除!</p>
+            <div class="frame-list">
+                <p class="frame-item" v-for="(item,index) in detailArr" :key="index" @click="goToFrameList(item)">
+                    {{index+1}}、{{item.FrameworkName}}({{item.NodeName}})
+                </p>
+            </div>
+        </div>
+        <div class="dialog-footer">
+            <el-button @click="$emit('close')">取消</el-button>
+            <el-button type="primary" @click="$emit('close')">确定</el-button>
+        </div>
+    </el-dialog>
+</template>
+
+<script>
+export default {
+    props:{
+        hintDialogShow:{
+            type:Boolean,
+            default:false
+        },
+        detailArr:{
+            type:Array,
+            default:[]
+        }
+    },
+    data() {
+        return {
+
+        };
+    },
+    methods: {
+        goToFrameList(item){
+            window.open(`/chartframe?frameId=${item.ChartFrameworkId}`);
+        }
+    },
+};
+</script>
+
+<style lang="scss">
+.classify-delete-wrap{
+    .el-dialog__header{
+        background-color: transparent;
+        border-bottom:1px solid #ECECEC;
+        .el-dialog__headerbtn>i{
+            color: #C0C4CC;
+        }
+
+    }
+    .dialog-container{
+        .frame-item{
+            cursor: pointer;
+            text-decoration: underline;
+            &:hover{
+                color:#0052D9;
+            }
+        }
+    }
+    .dialog-footer{
+        padding:25px 0;
+        text-align: right;
+    }
+}
+</style>

+ 51 - 8
src/views/mychart_manage/index.vue

@@ -261,6 +261,13 @@
       @close="chartCallBack"
       @remove="removeCallBack"
     />
+
+    <!-- 删除确认弹窗 -->
+    <ClassifyDeleteCheck 
+        :hintDialogShow="hintDialogShow"
+        :detailArr="detailArr"
+        @close="hintDialogShow=false"
+    />
   </div>
 </template>
 
@@ -270,14 +277,16 @@ import { mychartInterface } from '@/api/api.js';
 import pubDialog from '@/components/pubDialog.vue';
 import chooseChart from './components/chooseChart.vue';
 import chartDetail from './components/chartDetailDia.vue';
+import ClassifyDeleteCheck from './components/classifyDeleteCheck.vue';
 export default {
   name: '',
   components: {
     chooseChart,
     pubDialog,
     draggable,
-    chartDetail
-  },
+    chartDetail,
+    ClassifyDeleteCheck
+},
   directives: {
     drag(el, bindings) {
       el.onmousedown = function (e) {
@@ -374,6 +383,9 @@ export default {
       haveMove: false,
 
       chart_lang: 'ch',
+
+      hintDialogShow:false,
+      detailArr:[]
     };
   },
   computed: {
@@ -690,8 +702,8 @@ export default {
     /* 编辑 删除*/
     dealAction(key) {
       // this.isRightClick = false;
-      key === 'del' &&
-        this.$confirm(
+      key === 'del' && this.handleDeleteClassify()
+        /* this.$confirm(
           '若删除该分类,则分类下关联的所有图表将被全部删除, 是否继续?',
           '提示',
           {
@@ -710,17 +722,48 @@ export default {
                 this.$message.success('删除成功');
                 this.getClassify();
                 this.getPublicClassify();
-                // if (this.rightClick_classify === this.select_classify)
-                //   this.select_classify = '';
               });
           })
-          .catch(() => {});
-
+          .catch(() => {}); */
       const obj = this.classifyList.find(
         (x) => x.MyChartClassifyId === this.select_classify
       );
       key === 'edit' && this.editClassify(obj);
     },
+    async handleDeleteClassify(){
+        const res = await mychartInterface.getFrameNode({
+            MyChartClassifyId:this.select_classify
+        })
+        if(res.Ret!==200) return
+        this.detailArr = res.Data||[]
+        if(this.detailArr.length){
+            this.hintDialogShow = true
+            return
+        }
+        this.$confirm(
+          '若删除该分类,则分类下关联的所有图表将被全部删除, 是否继续?',
+          '提示',
+          {
+            confirmButtonText: '确定',
+            cancelButtonText: '取消',
+            type: 'warning',
+          }
+        )
+          .then(() => {
+            mychartInterface
+              .delClassify({
+                MyChartClassifyId: this.select_classify,
+              })
+              .then((res) => {
+                if (res.Ret !== 200) return;
+                this.$message.success('删除成功');
+                this.getClassify();
+                this.getPublicClassify();
+              });
+          })
+          .catch(() => {});
+      
+    },
 
     /* 右键菜单打开 */
     // rightClickHandle({ MyChartClassifyId }, e) {