|
@@ -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>
|