jwyu 1 éve
szülő
commit
5addb3fc9b

BIN
src/assets/img/smartReport/icon12.png


BIN
src/assets/img/smartReport/icon13.png


BIN
src/assets/img/smartReport/icon14.png


BIN
src/assets/img/smartReport/icon15.png


+ 6 - 5
src/routes/modules/oldRoutes.js

@@ -52,6 +52,12 @@ export default [
   	name:'AI问答',
   	hidden:false
   },
+  // 智能研报编辑页
+  {
+    path: "/smartReportEdit",
+    name: "智能报告",
+    component: () => import("@/views/smartReport/editReport.vue"),
+  },
 
   // 主页
   {
@@ -240,11 +246,6 @@ export default [
         name: "智能研报",
         component: () => import("@/views/smartReport/reportList.vue"),
       },
-      {
-        path: "smartReportEdit",
-        name: "智能报告",
-        component: () => import("@/views/smartReport/editReport.vue"),
-      }
     ],
   },
 

+ 6 - 1
src/views/smartReport/components/ImgComp.vue

@@ -1,5 +1,10 @@
 <template>
-    <div class="report-comp-item img-comp" style="min-height:100px;background:#f5f5f5;margin:10px 0" :comp-type="compData.compType">这是一个图片组件</div>
+    <div 
+        class="report-comp-item img-comp" 
+        style=""
+    >
+        <img :src="compData.content" alt="">
+    </div>
 </template>
 
 <script>

+ 139 - 0
src/views/smartReport/components/ImgEdit.vue

@@ -0,0 +1,139 @@
+<template>
+    <div class="img-edit-wrap" @paste="handleListenPaste">
+        <div style="font-size:16px;margin-bottom:20px">图片上传</div>
+        <div class="main-box">
+            <input type="file" size="small" name="file" @change="fileSelected" id="file" class="true-file" style="display:none;">
+            <div class="upload-box" @click="clickinput">
+                <img class="bg" :src="content" alt="" v-if="content">
+                <img src="~@/assets/img/smartReport/icon15.png" alt="">
+                <div>点击上传图片</div>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script>
+import { bannerupload } from 'api/api.js';
+import { async } from '@antv/x6/lib/registry/marker/async';
+export default {
+    name:'ImgEdit',
+    props:{
+        content:''
+    },
+    created() {
+        window.addEventListener('paste',this.handleListenPaste)
+    },
+     
+    destroyed(){
+        window.removeEventListener('paste',this.handleListenPaste)
+    },
+    methods: {
+        clickinput(){  //上传模拟点击
+			$(`#file`).click();
+		},
+        fileSelected(){  //选择文件上传
+			const that = this;
+		    if( document.getElementById('file').files[0] ){
+		        let hostfile = document.getElementById('file').files[0];
+		        let size = Math.floor(hostfile.size / 1024 / 1024);
+		        if( size>200 ){
+		            that.$message.warning('上传文件大小不能大于200M!');
+		            hostfile = {};
+		            return false
+		        }
+		        if( hostfile.name.toLowerCase().includes('.png') || hostfile.name.toLowerCase().includes('.jpg') || hostfile.name.toLowerCase().includes('.jpeg') ){
+		        	let form = new FormData();
+		        	form.append('file',hostfile);  //hostfile.name
+					bannerupload(form).then((res) => {
+						if( res.Ret === 200 ){
+							that.$emit('imgChange', res.Data.ResourceUrl)
+                            that.content=res.Data.ResourceUrl
+						}
+						$("#file").val('');
+						hostfile = {};
+					});
+				}else{
+					that.$message.warning('上传文件格式不正确!');
+		        }
+		    } 
+		},
+
+        handleListenPaste:_.throttle(async function(e){
+            if(!e.clipboardData) return
+            const clipboardDataItems = e.clipboardData.items
+            const clipboardDataFirstItem = clipboardDataItems[0]
+            if(clipboardDataFirstItem){
+                for (const item of clipboardDataItems) {
+                    if (item.kind === 'file' && item.type.indexOf('image') !== -1) {
+                        const imageFile = item.getAsFile()
+                        // if (imageFile) this.$refs[`pptPage_${this.currentIndex}`][0].handlePaste(imageFile,addPositions[0])
+                        return
+                    }
+                }
+            }
+            //clipboardData中没有图片,从navigator.clipboard.read里获取图片
+            let clipboardItems = null
+            try{
+                clipboardItems = await navigator.clipboard.read()
+            }catch(error){
+                this.$message.warning("剪贴板读取不到文件!")
+                return
+            }
+            const blob = await checkClipboardItems(clipboardItems)
+            // this.$refs[`pptPage_${this.currentIndex}`][0].handlePaste(blob,addPositions[0])
+
+        },1000),
+
+        checkClipboardItems(){
+            for(const Item of clipboard){
+                for(const type of Item.types){
+                    if(type.includes('image')){
+                        return Item.getType(type)
+                    }
+                }
+            }
+            return null
+        }
+    },
+
+
+
+}
+</script>
+
+<style lang="scss" scoped>
+div{
+    box-sizing: border-box;
+}
+
+.main-box{
+    width: 100%;
+    height: calc(100vh - 150px);
+    border-radius: 4px;
+    border: 1px solid var(--gary-gy-5-line, #C8CDD9);
+    background: #FFF;
+    padding: 30px;
+    .upload-box{
+        cursor: pointer;
+        width: 120px;
+        height: 120px;
+        display: flex;
+        flex-direction: column;
+        align-items: center;
+        justify-content: center;
+        border: 1px dashed var(--gary-gy-5-line, #C8CDD9);
+        background: var(--gary-gy-1-bottom-bk, #F8F8F8);
+        color: #999;
+        position: relative;
+        .bg{
+            width: 100%;
+            height: 100%;
+            position: absolute;
+            left: 0;
+            top: 0;
+            z-index: 10;
+            object-fit: cover;
+        }
+    }
+}
+</style>

+ 6 - 1
src/views/smartReport/components/TextComp.vue

@@ -1,5 +1,10 @@
 <template>
-    <div class="report-comp-item text-comp" style="min-height:100px;background:#f5f5f5;margin:10px 0" :comp-type="compData.compType">这是一个富文本组件</div>
+    <div 
+        class="report-comp-item text-comp" 
+        style="" 
+    >
+        <div class="rich-text-box" v-html="compData.content"></div>
+    </div>
 </template>
 
 <script>

+ 107 - 0
src/views/smartReport/components/TextEdit.vue

@@ -0,0 +1,107 @@
+<template>
+    <div class="text-edit-wrap">
+        <div style="font-size:16px;margin-bottom:20px">文本编辑</div>
+        <froala
+			id="froala-editor"
+			ref="froalaEditor"
+			:tag="'textarea'"
+			:config="froalaConfig"
+			v-model="html"
+		/>
+    </div>
+</template>
+
+<script>
+import VueFroala from 'vue-froala-wysiwyg';
+export default {
+    name:'TextEdit',
+    props:{
+        content:''
+    },
+    data() {
+        const that = this;
+        return {
+            html:this.content||'',
+            editor: null,
+            lastEditRange: null,
+            froalaConfig:{
+                toolbarButtons: [
+                    "textColor",
+                    "bold",
+                    "italic",
+                    "underline",
+                    "strikeThrough",
+                    "subscript",
+                    "superscript",
+                    "fontFamily",
+                    "fontSize",
+                    "color",
+                    "inlineClass",
+                    "inlineStyle",
+                    "paragraphStyle",
+                    "lineHeight",
+                    "paragraphFormat",
+                    "align",
+                    "formatOL",
+                    "formatUL",
+                    "outdent",
+                    "indent",
+                    "quote",
+                    "specialCharacters",
+                    "insertHR",
+                    "selectAll",
+                    "clearFormatting",
+                    "html",
+                    "undo",
+                    "redo",
+                ],
+                height: 800,
+                fontSize: ["12", "14", "16", "18", "20", "24", "28", "32", "36", "40"],
+                fontSizeDefaultSelection: "16",
+                theme: "dark", //主题
+                placeholderText: "请输入内容",
+                language: "zh_cn", //国际化
+                imageDefaultWidth: false,
+                quickInsertEnabled: false,
+                toolbarVisibleWithoutSelection: true, //是否开启 不选中模式
+                toolbarSticky: false, //操作栏是否自动吸顶
+                saveInterval: 0,
+                events: {
+                    //this.editor 定义在vue data 中
+                    initialized: function () {
+                        // this.editor = editor;
+                        that.editor = this;
+                        // that.editor.html.set(that.value);
+                        // that.setHtml()
+                    },
+                    keyup: function (e, editor) {
+                        //添加事件,在每次按键按下时,都记录一下最后停留位置
+                        that.$nextTick(function () {
+                            that.lastEditRange = getSelection().getRangeAt(0);
+                        });
+                    },
+                    click: function (e, editor) {
+                        //添加事件,在每次鼠标点击时,都记录一下最后停留位置
+                        that.$nextTick(function () {
+                            that.lastEditRange = getSelection().getRangeAt(0);
+                        });
+                    },
+                    //内容改变事件
+                    contentChanged: function () {
+                        that.lastEditRange = getSelection().getRangeAt(0) || 0;
+                        that.$emit('textChange', that.html)
+                    },
+                },
+            }
+        }
+    },
+    methods: {
+        
+    },
+    components:{}
+}
+</script>
+
+<style>
+
+</style>

+ 0 - 101
src/views/smartReport/components/WrapComp.vue

@@ -1,101 +0,0 @@
-<template>
-    <div class="report-comp-item chart-comp" style="min-height:100px;background:#f5f5f5;margin:10px 0" :comp-type="compData.compType">
-        <draggable
-            :list="conList"
-            :group="{ name: 'component', pull: true, put: true }"
-            animation="300"
-            tag="div"
-            @add="handleAdd"
-        >
-            <template v-for="comp in compData.child">
-                <component :is="getComponentName(comp)" :key="comp.id" :compData="comp"/>
-            </template>
-        </draggable>
-    </div>
-</template>
-
-<script>
-import draggable from 'vuedraggable'
-import TextComp from './TextComp.vue'
-import ChartComp from './ChartComp.vue'
-import ImgComp from './ImgComp.vue'
-import WrapComp from './WrapComp.vue'
-import _ from 'lodash'
-export default {
-    props:{
-        compData:{}
-    },
-    components: {
-        draggable,
-        TextComp,
-        ChartComp,
-        ImgComp,
-        WrapComp
-    },
-    data() {
-        return {
-            compList:[
-                {
-                    compId:0,
-                    compType:'wrap'
-                },
-                {
-                    compId:1,
-                    compType:'text'
-                },
-                {
-                    compId:2,
-                    compType:'chart'
-                },
-                {
-                    compId:3,
-                    compType:'img'
-                },
-            ],
-            
-        }
-    },
-    methods: {
-        getComponentName(item){
-            const temMap=new Map([
-                ['wrap',WrapComp],
-                ['text',TextComp],
-                ['chart',ChartComp],
-                ['img',ImgComp]
-            ])
-            return temMap.get(item.compType)
-        },
-        findComp(el){
-            const compType=el.getAttribute('comp-type')
-            console.log(compType);
-            return this.compList.find(item=>item.compType===compType)
-        },
-        // 生产随机id
-        getCompId(type){
-            return type+new Date().getTime()
-        },
-
-        handleAdd(e){
-            console.log('child-onAdd操作------------------->', e);
-
-            const {item,newDraggableIndex}=e
-            const comp=this.findComp(item)
-            // 非注册组件返回
-            if(!comp){
-                this.conList.splice(newDraggableIndex,1)
-                return
-            }
-            const tempCompData={
-                ...comp,
-                id:this.getCompId(comp.compType)
-            }
-            this.conList.splice(newDraggableIndex,1,tempCompData)
-            this.$emit('childAdd',{list:this.conList,data:this.props.compData})
-        }
-    },
-}
-</script>
-
-<style>
-
-</style>

+ 335 - 55
src/views/smartReport/editReport.vue

@@ -67,7 +67,7 @@
                     :sort="false"
                     tag="ul"
                 >
-                    <li class="comp-item" :comp-type="comp.compType" v-for="comp in compList" :key="comp.id">
+                    <li class="comp-item" :comp-data="JSON.stringify(comp)" v-for="comp in compList" :key="comp.id">
                         <img :src="comp.icon">
                     </li>
                 </draggable>
@@ -79,19 +79,51 @@
                         class="report-html-wrap"
                         animation="300"
                         tag="div"
-                        @add="handleAdd"
+                        handle=".drag-btn_p"
+                        @add="handleParentAdd"
+                        @remove="handleParentRemove"
                     >
-                        <div class="report-drag-item-wrap" v-for="item in conList" :key="item.id">
+                        <div 
+                            :class="['report-drag-item-wrap',activeId===item.id?'blue-bg':'']" 
+                            v-for="item,index in conList" 
+                            :key="item.id"
+                            :comp-type="item.compType"
+                            @click="handleChoose(item,index)"
+                        >
+                            <div class="opt-btn-box">
+                                <div class="drag-btn drag-btn_p"></div>
+                                <div class="del-btn"></div>
+                            </div>
+                            <div 
+                                v-if="item.child&&!item.child.length"
+                                class="report-drag-item-wrap_content"
+                                :data-id="item.id"
+                            >
+                                <component :is="getComponentName(item)" :compData="item"/>
+                            </div>
                             <draggable
                                 :list="item.child"
-                                :group="{ name: 'component', pull: true, put: true }"
+                                :group="{ name: 'component', pull: true, put: item.child&&item.child.length<3?true:false }"
                                 animation="300"
                                 tag="div"
                                 class="report-drag-item-wrap_child-wrap"
-                                @add="handleChildAdd"
+                                @add="handleChildAdd($event,item)"
+                                @remove="handleChildRemove"
+                                handle=".drag-btn_c"
                             >
-                                <div class="report-drag-item-wrap_child" v-for="child in item.child" :key="child.id">
-                                {{child.type}}
+                                <div 
+                                    :class="['report-drag-item-wrap_child_content',activeId===child.id?'blue-bg':'']" 
+                                    v-for="child,cindex in item.child" 
+                                    :key="child.id"
+                                    :comp-type="child.compType"
+                                    :data-id="child.id"
+                                    @click.stop="handleChoose(child,index,cindex)"
+                                >
+                                    <div class="opt-btn-box2">
+                                        <div class="drag-btn drag-btn_c"></div>
+                                        <div class="del-btn"></div>
+                                    </div>
+                                    <component :is="getComponentName(child)" :compData="child"/>
                                 </div>
                             </draggable>
                         </div>
@@ -99,7 +131,22 @@
                 </div>
             </div>
 
-            <div class="right-action-wrap">
+            <div class="right-action-wrap" v-show="activeId">
+                <div class="close-icon" @click="activeId=''">
+                    <img src="~@/assets/img/smartReport/icon14.png" alt="">
+                </div>
+                <TextEdit 
+                    v-if="activeCompType==='text'"
+                    :key="activeId"
+                    :content="activeContent" 
+                    @textChange="handleTextChange" 
+                />
+                <ImgEdit 
+                    v-if="activeCompType==='img'"
+                    :key="activeId"
+                    :content="activeContent" 
+                    @imgChange="handleTextChange" 
+                />
             </div>
         </div>
     </div>
@@ -110,8 +157,9 @@ import draggable from 'vuedraggable'
 import TextComp from './components/TextComp.vue'
 import ChartComp from './components/ChartComp.vue'
 import ImgComp from './components/ImgComp.vue'
-import WrapComp from './components/WrapComp.vue'
 import _ from 'lodash'
+import TextEdit from './components/TextEdit.vue'
+import ImgEdit from './components/ImgEdit.vue'
 export default {
     name:"smartReportEdit",
     components: {
@@ -119,46 +167,128 @@ export default {
         TextComp,
         ChartComp,
         ImgComp,
-        WrapComp
+        TextEdit,
+        ImgEdit
     },
     data() {
         return {
             compList:[
-                {
+                {   
                     compId:1,
                     compType:'text',
                     icon:require('@/assets/img/smartReport/icon10.png')
                 },
                 {
-                    compId:3,
+                    compId:2,
                     compType:'img',
                     icon:require('@/assets/img/smartReport/icon11.png')
-                },
+                }
             ],
-            conList:[]
+            conList:[],
+            activeId:'',
+            activeCompType:'',
+            activeContent:'',
+            activePindex:'',
+            activeCindex:'',
         }
     },
     methods: {
-        getComponentName(item){
-            const temMap=new Map([
-                ['wrap',WrapComp],
-                ['text',TextComp],
-                ['chart',ChartComp],
-                ['img',ImgComp]
-            ])
-            return temMap.get(item.compType)
-        },
-        findComp(el){
-            const compType=el.getAttribute('comp-type')
-            return this.compList.find(item=>item.compType===compType)
-        },
-        // 生产随机id
-        getCompId(type){
-            return type+new Date().getTime()
+        handleParentAdd(e){
+            console.log('container-onAdd操作------------------->');
+
+            const {item,newDraggableIndex}=e
+
+            const hasid=item.getAttribute('data-id')
+            console.log(hasid);
+            if(hasid) return
+
+            // 要添加的元素数据
+            const compData=JSON.parse(item.getAttribute('comp-data'))
+            // console.log(compData);
+            // 非注册组件返回
+            // if(!comp){
+            //     this.conList.splice(newDraggableIndex,1)
+            //     return
+            // }
+            const tempCompData={
+                compId:compData.compId,
+                compType:compData.compType,
+                id:this.getCompId(compData.compType),
+                child:[]
+            }
+            // console.log(tempCompData);
+            this.conList.splice(newDraggableIndex,1,tempCompData)
+            // this.activeId=tempCompData.id
         },
 
-        handleChildAdd(e){
-            console.log('child-onAdd操作------------------->', e);
+        handleChildAdd(e,parent){
+            console.log('child-onAdd操作------------------->');
+            // console.log(parent);
+            const {item,newDraggableIndex}=e
+
+            const compData=JSON.parse(item.getAttribute('comp-data'))
+
+            // console.log(compData,newDraggableIndex);
+
+            const index=this.conList.findIndex(_e=>_e.id===parent.id)
+            if(index>-1){
+                let obj=_.cloneDeep(this.conList[index]) 
+
+                console.log(obj);
+
+                if(obj.child&&obj.child.length===1&&obj.id){
+                    if(compData){
+                        obj={
+                            child:[
+                                {
+                                    compId:obj.compId,
+                                    compType:obj.compType,
+                                    id:obj.id,
+                                    content:obj.content,
+                                    child:[]
+                                },
+                                {
+                                    compId:compData.compId,
+                                    compType:compData.compType,
+                                    content:'',
+                                    id:this.getCompId(compData.compType),
+                                    child:[]
+                                }
+                            ]
+                        }
+                    }else{
+                        const temItem=_.cloneDeep(obj.child[0])
+                        obj={
+                            child:[
+                                {
+                                    compId:obj.compId,
+                                    compType:obj.compType,
+                                    id:obj.id,
+                                    content:obj.content,
+                                    child:[]
+                                },
+                                {
+                                    ...temItem
+                                }
+                            ]
+                        }
+                    }
+                    
+                }else{
+                    obj.child.splice(newDraggableIndex,1,{
+                        compId:compData.compId,
+                        compType:compData.compType,
+                        id:this.getCompId(compData.compType),
+                        child:[]
+                    })
+                }
+                // obj={child:[]}
+                console.log(obj);
+
+                this.conList.splice(index,1,obj)
+            }
+            // console.log(this.conList);
+
             // console.log(list,data);
             // this.conList.forEach(item=>{
             //     if(item.id===data.id){
@@ -167,24 +297,68 @@ export default {
             // })
         },
 
-        handleAdd(e){
-            console.log('container-onAdd操作------------------->', e);
+        // 移除事件 
+        handleChildRemove(e){
+            console.log('child-remove操作------------------->');
+            // 如果都移除了则删除这个
+            this.conList=this.conList.filter(_item=>!(_item.child&&_item.child.length===0&&!_item.id))
+            // 如果child只剩一个了则移出来
+            this.conList=this.conList.map(_item=>{
+                if(_item.child&&_item.child.length===1){
+                    return _item.child[0]
+                }else{
+                    return _item
+                }
+            })
+        },
 
-            const {item,newDraggableIndex}=e
-            const comp=this.findComp(item)
-            // 非注册组件返回
-            if(!comp){
-                this.conList.splice(newDraggableIndex,1)
-                return
-            }
-            const tempCompData={
-                ...comp,
-                id:this.getCompId(comp.compType),
-                child:[]
+        handleParentRemove(e){
+            console.log('container-remove操作------------------->');
+        },
+
+        // 富文本编辑组件数据变化
+        handleTextChange(e){
+            console.log(e);
+            this.activeContent=e
+            if(this.activeCindex>=0&&this.activeCindex!==''){
+                if(this.conList[this.activePindex].child[this.activeCindex].content){
+                    this.conList[this.activePindex].child[this.activeCindex].content=e
+                }else{
+                    this.$set(this.conList[this.activePindex].child[this.activeCindex],'content',e)
+                }
+            }else{
+                if(this.conList[this.activePindex].content){
+                    this.conList[this.activePindex].content=e
+                }else{
+                    this.$set(this.conList[this.activePindex],'content',e)
+                }
             }
-            console.log(tempCompData);
-            this.conList.splice(newDraggableIndex,1,tempCompData)
+        },
+
+        // 当前再编辑哪个
+        handleChoose(item,index,cindex){
+            //{item:数据,index:父序号,cindex:子序号}
+            if(!item.id) return
+            this.activeId=item.id
+            this.activeCompType=item.compType
+            this.activeContent=item.content||''
+            this.activePindex=index
+            this.activeCindex=cindex>=0?cindex:''
+        },
+
+        getComponentName(item){
+            const temMap=new Map([
+                ['text',TextComp],
+                ['chart',ChartComp],
+                ['img',ImgComp]
+            ])
+            return temMap.get(item.compType)
+        },
+        // 生产随机id
+        getCompId(type){
+            return type+new Date().getTime()
         }
+        
     },
 }
 </script>
@@ -194,6 +368,9 @@ div{
     box-sizing: border-box;
 }
 .edit-smart-report-page{
+    background: var(--unnamed, #F2F6FA);
+    min-width: 100vw;
+    min-height: 100vh;
     .top-action-wrap{
         position: sticky;
         top: 0px;
@@ -203,6 +380,7 @@ div{
         display: flex;
         justify-content: space-between;
         align-content: center;
+        padding: 0 24px;
         .title{
             line-height: 60px;
             font-size: 16px;
@@ -233,7 +411,7 @@ div{
     }
     .main-wrap{
         display: flex;
-
+        justify-content: center;
     }
 }
 .report-action-wrap{
@@ -241,6 +419,7 @@ div{
     flex-shrink: 0;
     margin-left: 90px;
     margin-right: 60px;
+    margin-top: 30px;
     position: relative;
     .report-comp-wrap{
             position: absolute;
@@ -252,7 +431,7 @@ div{
             border-radius: 4px;
             overflow: hidden;
             .comp-item{
-                cursor: pointer;
+                cursor: move;
                 height: 40px;
                 display: flex;
                 align-items: center;
@@ -297,7 +476,7 @@ div{
         border: 1px solid var(--gary-gy-5-line, #C8CDD9);
         background: #FFF;
         padding: 20px 20px 20px 64px;
-        height: 80vh;
+        height: calc(100vh - 180px);
         position: relative;
         overflow-y: auto;
         
@@ -308,26 +487,127 @@ div{
 
 .main-wrap{
     .report-html-wrap{
-        min-height: 50vh;
+        min-height: 100%;
         .report-drag-item-wrap{
             width: 100%;
             padding: 20px;
-            min-height: 200px;
+            min-height: 80px;
             border: 1px dashed #0052D9;
+            position: relative;
+            &:hover{
+                .opt-btn-box{
+                    display: block;
+                }
+            }
+            .opt-btn-box{
+                display: none;
+                position: absolute;
+                left: -36px;
+                padding-right: 8px;
+                top: 0;
+                .drag-btn::after{
+                    content: '';
+                    display: block;
+                    width: 28px;
+                    height: 28px;
+                    background-image: url('~@/assets/img/smartReport/icon12.png');
+                    background-size: cover;
+                    cursor: pointer;
+                }
+                .del-btn::after{
+                    content: '';
+                    display: block;
+                    width: 28px;
+                    height: 28px;
+                    background-image: url('~@/assets/img/smartReport/icon13.png');
+                    background-size: cover;
+                    cursor: pointer;
+                }
+            }
         }
         .report-drag-item-wrap_child-wrap{
             display: flex;
             gap: 20px;
         }
-        .report-drag-item-wrap_child{
-            min-height: 200px;
+        .report-drag-item-wrap_child_content{
+            min-height: 80px;
             border: 1px dashed #0052D9;
             flex: 1;
-            
+            position: relative;
+            &:hover{
+                .opt-btn-box2{
+                    display: block;
+                }
+            }
+            .opt-btn-box2{
+                display: none;
+                position: absolute;
+                right: -15px;
+                top: 0;
+                .drag-btn::after{
+                    content: '';
+                    display: block;
+                    width: 28px;
+                    height: 28px;
+                    background-image: url('~@/assets/img/smartReport/icon12.png');
+                    background-size: cover;
+                    cursor: pointer;
+                }
+                .del-btn::after{
+                    content: '';
+                    display: block;
+                    width: 28px;
+                    height: 28px;
+                    background-image: url('~@/assets/img/smartReport/icon13.png');
+                    background-size: cover;
+                    cursor: pointer;
+                }
+            }
         }
         .blue-bg{
             background: var(--brand-brand-1-light, #ECF2FE);
         }
     }
 }
+
+.main-wrap{
+    .right-action-wrap{
+        height: calc(100vh - 60px);
+        overflow: hidden;
+        flex: 1;
+        position: relative;
+        padding-top: 30px;
+        padding-left: 75px;
+        padding-right: 30px;
+        padding-bottom: 30px;
+        &::before{
+            display: block;
+            content: '';
+            width: 1px;
+            height: 100vh;
+            background-color: #C8CDD9;
+            position: absolute;
+            left: 15px;
+            top: 0;
+        }
+        .close-icon{
+            width: 20px;
+            height: 20px;
+            border-radius: 4px;
+            background: #FFF;
+            box-shadow: 0px 4px 4px 0px rgba(0, 0, 0, 0.25);
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            cursor: pointer;
+            position: absolute;
+            left: 5px;
+            top: 22px;
+            img{
+                width: 16px;
+                height: 16px;
+            }
+        }
+    }
+}
 </style>