PortalDesignerDialog.vue 11.3 KB
<template>
  <el-dialog
   v-if="dialogVisible"
    class="form-editor-dialog"
    fullscreen
    destroy-on-close
    :close-on-click-modal="false"
    :visible.sync="dialogVisible"
  >
    <el-container class="fullheight ">
      <el-header class="header" style="height: 45px">
        <div class="navbar-default box-shadow flex">
          <el-page-header @back="close">
            <template v-slot:content>门户首页设计器</template>
          </el-page-header>
          <div>
            <ht-submit-button
              request-method="POST"
              url="${portal}/portal/sysIndexLayoutManage/sysIndexLayoutManage/v1/saveLayout"
              :model="layoutObj"
              scope-name="editForm"
              :is-submit="isSubmit"
              @before-save-data="beforeSaveData"
              @after-save-data="afterSaveData"
              >{{ $t('eip.common.save') }}</ht-submit-button
            >
            <!-- <el-button type="default" @click="handleUpload">导入json</el-button>
          <el-button type="default" @click="handleClear">清除</el-button>
          <el-button type="default" @click="handlePreview">预览</el-button>
          <el-button  type="default"  @click="handleGenerateJson">生成json</el-button>
            <el-button  type="default" @click="handleGenerateCode">生成代码</el-button>-->
            <!-- <el-button type="danger" @click="close">关闭</el-button> -->
          </div>
        </div>
      </el-header>
      <el-container class="dialog-container">
        <el-aside class="controler-container" width="300px"  v-show="asideShow">
          <ColumnPanel :columnMap="columnMap" :type="type" @updateDataImage="handleUpdateDataImage"/>
        </el-aside>
        <div
        class="navbar-collapse"
        :class="{'navbar-collapse-right': !asideShow}"
        @click="asideShow = !asideShow"
      >
        <div class="navbar-collapse-bg">
          <i
            class="navbar-collapse-arrow"
            :class="{
              'el-icon-arrow-left': asideShow,
              'el-icon-arrow-right': !asideShow
            }"
          ></i>
        </div>
      </div>
        <el-main class="widget-form-container">
          <!-- <DesignPanel
            ref="widgetForm"
            :data="widgetForm"
            :select.sync="widgetFormSelect"
            :layoutType="layoutObj.layoutType"
            @delete-column="handleDeleteColumn"
          /> -->
          <new-design-panel
            :data="widgetForm"
            :select.sync="widgetFormSelect"
            :layoutType="type"
            :layoutObj="layoutObj"
            @delete-column="handleDeleteColumn"
          ></new-design-panel>
        </el-main>
        <div
        class="navbar-collapse"
        :class="{'navbar-collapse-left': rightAsideShow}"
        @click="rightAsideShow = !rightAsideShow"
      >
        <div class="navbar-collapse-bg">
          <i
            class="navbar-collapse-arrow"
            :class="{
              'el-icon-arrow-right': rightAsideShow,
              'el-icon-arrow-left': !rightAsideShow
            }"
          ></i>
        </div>
      </div>
        <el-aside width="400px" class="property-container" v-show="rightAsideShow">
          <LayoutConfigPanel
            :data="widgetFormSelect"
            :layoutObj.sync="layoutObj"
            :layoutType="type"
            @update-type="updateLayoutType"
            style="height: 100%"
          />
        </el-aside>
      </el-container>
    </el-container>
  </el-dialog>
</template>
<script>
  import ColumnPanel from '@/components/portal/ColumnPanel.vue'
  import LayoutConfigPanel from '@/components/portal/LayoutConfigPanel.vue'
  import DesignPanel from '@/components/portal/DesignPanel.vue'
  import NewDesignPanel from '@/components/portal/NewDesignPanel.vue'
  import portal from '@/api/portal.js'
  let Base64 = require('js-base64').Base64
  export default {
    components: {ColumnPanel, DesignPanel, LayoutConfigPanel, NewDesignPanel},
    data() {
      return {
        dialogVisible: false,
        widgetForm: {
          topBottomLayout: [],
          header: [],
          main: {
            left: [],
            center: [],
            right: [],
            layoutCol: 'two',
          },
          bottom: [],
          mobileList: [],
          list: [],
        },
        widgetFormSelect: null,
        isSubmit: true,
        columnMap: {},
        layoutObj: {
          name: '',
          alias: '',
          memo: '',
          gutter: 24,
        },
        type:0,
        asideShow: true,
        rightAsideShow: true,
      }
    },
    methods: {
      showDialog(layoutId, layoutType) {
        this.type = layoutType
        this.dialogVisible = true
        this.widgetForm = {
          topBottomLayout: [],
          header: [],
          main: {
            left: [],
            center: [],
            right: [],
            layoutCol: 'two',
          },
          bottom: [],
          mobileList: [],
          list: [],
        }
        this.loadData(layoutId, layoutType)
      },
      loadData(layoutId, layoutType) {
        portal
          .getLayoutManageDesignData(layoutId, layoutType)
          .then((response) => {
            this.columnMap = response.columnMap
            if (!response.sysIndexLayout) {
              //如果为空,说明现在新建
              this.layoutObj = {name: '', alias: '', memo: '',gutter: 24}
              this.layoutObj.layoutType = layoutType
            } else {
              this.layoutObj = response.sysIndexLayout
              let json = JSON.parse(Base64.decode(this.layoutObj.designHtml))
              const isOldLayout = json.list.length&&json.list.some(item=>!['one','two','three'].includes(item.type))
              this.widgetForm = {
                topBottomLayout: [],
                header: [],
                main: {
                  left: [],
                  center: [],
                  right: [],
                  layoutCol: 'two',
                },
                bottom: [],
                mobileList: [],
                ...json,
                list:isOldLayout ? [] : json.list
              }
              if (json.list && json.list.length > 0) {
                this.widgetFormSelect = json.list[0]
              }
              if(layoutType==1&&json.mobileList&&json.mobileList.length>0){
                if(json.mobileList&&json.mobileList.filter(it=>it.key)&&json.mobileList.filter(it=>it.key).length>0){
                  this.widgetFormSelect = json.mobileList.filter(it=>it.key)[0]
                }
              }
            }
          })
      },
      handleGenerateJson() {
        this.jsonTemplate = this.widgetForm
        this.$message(JSON.stringify(this.widgetForm))
      },
      beforeSaveData() {
        if(this.widgetForm.list && this.widgetForm.list.length < 1 && this.type !==1){
          this.isSubmit = false
         this.$message.warning('至少添加一个布局') 
        }else{
          this.isSubmit = true
          this.layoutObj.type = 'column' //栏目类
          this.widgetForm.mobileList&&this.widgetForm.mobileList.length>0?this.widgetForm.mobileList=this.widgetForm.mobileList.filter(item=>item.key):''
          this.layoutObj.designHtml = Base64.encode(JSON.stringify(this.widgetForm))
        }
        
      },
      afterSaveData() {
        this.close()
        this.$emit('close', null)
      },
      close() {
        this.dialogVisible = false
      },
      handleDeleteColumn(index, type, main) {
        if (main) {
          this.widgetForm.main[type].splice(index, 1)
        } else {
          this.widgetForm[type].splice(index, 1)
        }
      },
      updateLayoutType(item) {
        const typeMap = {
          twoOne: [16, 8],
          equalRatio: [12, 12],
          oneTwo: [8, 16],
        }
        if (this.widgetFormSelect) {
          this.$set(
            this.widgetFormSelect.columns[0],
            'span',
            typeMap[item.key][0]
          )
          this.$set(
            this.widgetFormSelect.columns[1],
            'span',
            typeMap[item.key][1]
          )
        }
      },
      handleUpdateDataImage(hasSnapshotIdArr){
        if(this.widgetForm.list&&this.widgetForm.list.length > 0){
          //front
          this.widgetForm.list.forEach((item,index)=>{
            item.columns.forEach((item2,index2)=>{
              item2.list.forEach((item3,index3)=>{
                if(!item3['snapshotId']){
                  let curItem = hasSnapshotIdArr.find(fItem=>fItem.alias==item3.alias)
                  if(curItem){
                    this.$set(this.widgetForm.list[index].columns[index2].list[index3],'snapshotId',curItem.snapshotId)
                  }
                }
              })
            })
          })
        }
        if(this.widgetForm.mobileList&&this.widgetForm.mobileList.length>0){
          //mobile
          this.widgetForm.mobileList.forEach((item,index)=>{
            if(!item['snapshotId']){
              let curItem = hasSnapshotIdArr.find(fItem=>fItem.alias==item.alias)
              if(curItem){
                this.$set(this.widgetForm.mobileList[index],'snapshotId',curItem.snapshotId)
              }
            }
          })
        }
      }
    },
  }
</script>
<style lang="scss" scoped>
@mixin scrollbarMin(){
  scrollbar-width: thin;
  &::-webkit-scrollbar {
    width: 8px;
  }

  &::-webkit-scrollbar-thumb {
    background-color: #c1c1c1;
    border-radius: 4px;
  }
}
.dialog-container{
  height: calc(100% - 45px);
}
  .navbar-default {
    padding: 0 36px;
    height: 100%;
    background-image: none;
    background: #fff;
    border-radius: 0px;
    box-shadow: 0px 2px 5px rgba(86, 96, 117, 0.15);
    border-bottom: 1px solid #ededed;
    justify-content: space-between;
  }

  .navbar-default span {
    color: #666;
    font-size: 14px;
    line-height: 48px;
    font-weight: bold;
    margin-left: 20px;
  }

  .navbar-default button {
    margin-right: 10px;
  }
  .header {
    padding: 0;
    background: #fff;
    z-index: 7;
  }

  .controler-container {
    margin-right: 3px;
    box-shadow: 2px 0 5px #ededed;
    @include scrollbarMin()
  }

  .property-container {
    margin-left: 3px;
    box-shadow: -2px 0 5px #ededed;
  }

  .widget-form-container {
    background: #fafafa;
    position: relative;
    padding: 24px!important;
    box-sizing: border-box;
    margin-top: 1px;
    margin-left: -8px;
    margin-right: -8px;
    @include scrollbarMin()
  }

  .footer-container {
    border-top: 1px solid #ededed;
  }
  .form-editor-dialog >>> .el-dialog__header {
    display: none;
  }

  .form-editor-dialog >>> .el-dialog__body {
    padding: 0;
    height: 100%;
  }
  .navbar-collapse {
    margin-top: 40px;
    width: 10px;
    z-index: 999;
  }
  .navbar-collapse-bg {
    margin-left: 1px;
    height: 28px;
    border-top: 8px solid transparent;
    border-bottom: 8px solid transparent;
    border-left: 10px solid #fff;
    border-right: none;
    position: relative;
  }
  .navbar-collapse-left { 
    .navbar-collapse-bg {
      margin-right: 1px;
      border-top: 8px solid transparent;
      border-bottom: 8px solid transparent;
      border-right: 10px solid #fff;
      border-left: none;
      .navbar-collapse-arrow {
        left: 0;
      }
    }
  }
  .navbar-collapse-bg:hover {
    cursor: pointer;
  }
  .navbar-collapse-arrow {
    position: absolute;
    left: -12px;
    top: 7px;
  }
</style>