<template>
  <div class="container">
    <div class="left-board">
      <el-scrollbar class="left-scrollbar">
        <div class="components-list">
          <div v-for="(item, listIndex) in leftComponents" :key="listIndex" class="components-part">
            <div class="components-title">{{ item.title }}</div>
            <!--            :group="{ name: 'componentsGroup', pull: 'clone', put: false }"-->
            <draggable
              class="components-draggable"
              :list="item.list"
              :clone="cloneComponent"
              draggable=".components-item"
              filter=".disabled"
              :sort="false"
              :group="{ name: 'componentsGroup', pull: 'clone', put: false }"
              @end="onEnd"
            >
              <div v-for="(element, index) in item.list" :key="index" class="components-item" :class="{ disabled: element.__config__.dragDisabled }" @click="addComponent(element)">
                <div class="components-body">
                  <!--                  <i :class="element.__config__.tagIcon" />-->
                  <img :src="`icon/${element.__config__.tagIcon}`" alt="" width="20" />
                  {{ element.__config__.label }}
                </div>
              </div>
            </draggable>
          </div>
        </div>
      </el-scrollbar>
    </div>
    <div class="center-board" @click="cancelSelection">
      <div class="action-bar">
        <el-button icon="el-icon-view" type="text" @click="preview" size="medium"> 预览</el-button>
        <el-button icon="el-icon-video-play" type="text" @click="showJson" size="medium"> Json预览</el-button>
        <!-- <el-button icon="el-icon-view" type="text" @click="showJson" size="medium">
          查看json</el-button> -->
        <el-button icon="el-icon-delete" type="text" @click="empty" size="medium">清空</el-button>
      </div>
      <el-scrollbar class="center-scrollbar">
        <el-row class="center-board-row" :gutter="formConf.gutter">
          <el-form :size="formConf.size" :label-position="formConf.labelPosition" :disabled="formConf.disabled" :label-width="formConf.labelWidth + 'px'">
            <!--            <grid-layout-->
            <!--              :layout.sync="layout"-->
            <!--              :col-num="24"-->
            <!--              :row-height="30"-->
            <!--              :is-draggable="true"-->
            <!--              :is-resizable="true"-->
            <!--              :is-mirrored="false"-->
            <!--              :vertical-compact="true"-->
            <!--              :margin="[10, 10]"-->
            <!--              :use-css-transforms="true"-->
            <!--            >-->

            <!--              <grid-item v-for="(element,index) in layout"-->
            <!--                         :x="element.x"-->
            <!--                         :y="element.y"-->
            <!--                         :w="element.w"-->
            <!--                         :h="element.h" :minH="element.minH"-->
            <!--                         :i="element.i"-->
            <!--                         :key="element.i"-->
            <!--                         @resized="resizeEvent" @move="moveEvent"-->
            <!--                         @moved="movedEvent"-->
            <!--              >-->
            <!--                <draggable class="drawing-board" :list="drawingList" :animation="340"   @end='onCenterEnd'>-->
            <!--                <draggable-item :key="drawingList[index].renderKey"-->
            <!--                                  :drawing-list="drawingList" :element="drawingList[index]" :index="index" :active-id="activeId"-->
            <!--                                  :form-conf="formConf" @activeItem="activeFormItem" @copyItem="drawingItemCopy"-->
            <!--                                  @deleteItem="drawingItemDelete" :put="shouldClone" :end='onTableEnd' />-->
            <!--                </draggable>-->
            <!--              </grid-item>-->
            <!--            </grid-layout>-->

            <!--            <grid-layout :layout.sync="drawingList" :col-num="24"  :is-draggable="true"-->
            <!--              :is-resizable="true" :is-mirrored="false" :vertical-compact="true" :margin="[10, 10]" :use-css-transforms="true">-->
            <!--               <grid-item v-for="(element, index) in drawingList" :x="element.x" :y="element.y" :w="element.w" :h="element.h" :i="index" :key="index">-->
            <!--&lt;!&ndash;                 <draggable-item :key="element.renderKey"&ndash;&gt;-->
            <!--&lt;!&ndash;                                 :drawing-list="drawingList" :element="element" :index="index" :active-id="activeId"&ndash;&gt;-->
            <!--&lt;!&ndash;                                 :form-conf="formConf" @activeItem="activeFormItem" @copyItem="drawingItemCopy"&ndash;&gt;-->
            <!--&lt;!&ndash;                                 @deleteItem="drawingItemDelete" :put="shouldClone" :end='onTableEnd' />&ndash;&gt;-->
            <!--              </grid-item>-->
            <!--            </grid-layout>-->
            <draggable class="drawing-board" :list="drawingList" :animation="340" group="componentsGroup" @end="onCenterEnd">
              <draggable-item
                v-for="(element, index) in drawingList"
                :key="element.renderKey"
                :drawing-list="drawingList"
                :element="element"
                :index="index"
                :active-id="activeId"
                :form-conf="formConf"
                @activeItem="activeFormItem"
                @copyItem="drawingItemCopy"
                @deleteItem="drawingItemDelete"
                :put="shouldClone"
                :end="onTableEnd"
              />
            </draggable>
            <div v-show="!drawingList.length" class="empty-info">
              <img src="@/assets/images/emptyElement.png" alt="" class="empty-img" />
            </div>
          </el-form>
        </el-row>
      </el-scrollbar>
    </div>
    <right-panel
      :active-id="activeId"
      :active-data="activeData"
      :form-conf="formConf"
      :table-list="tableList"
      :cube-list="cubeList"
      :relationData="relationData"
      :allTabelList="allTabelData"
      :drawList="drawingList"
      :show-field="!!drawingList.length"
      @tag-change="tagChange"
      :logicData="logicData"
      :modelType="modelType"
      :dbLinkId="dbLinkId"
      :dbSourceId="dbSourceId"
      :columnModelId="columnModelId"
      @relationChange="relationChange"
      @changeType="changeType"
    />
    <json-drawer size="550px" :visible.sync="jsonDrawerVisible" :jsonData="formData" @refresh="refreshJson" />
    <Preview :visible.sync="previewVisible" :form-data="formData" :relation-data="relationData" />
  </div>
</template>

<script>
import VueGridLayout from 'vue-grid-layout'
import draggable from 'vuedraggable'
import { debounce } from 'throttle-debounce'
import render from '@/components/Generator/render/render'
import JsonDrawer from './JsonDrawer'
import RightPanel from './RightPanel'
import Preview from '../preview'
import { formConf, inputComponents, layoutComponents, selectComponents, systemComponents } from '@/components/Generator/generator/config'
import { noTableAllowList, noVModelList, webPeculiarList } from '@/components/Generator/generator/comConfig'
import { deepClone } from '@/components/Generator/utils'
import DraggableItem from './DraggableItem'
import { getIdGlobal, saveDrawingList, saveIdGlobal } from '@/components/Generator/utils/db'

const emptyActiveData = { style: {}, autosize: {} }
let oldActiveId
let tempActiveData
const idGlobal = getIdGlobal()

export default {
  components: {
    draggable,
    render,
    JsonDrawer,
    RightPanel,
    DraggableItem,
    Preview,
    GridLayout: VueGridLayout.GridLayout,
    GridItem: VueGridLayout.GridItem
  },
  props: ['conf', 'modelType', 'relationList', 'logicList', 'cubeList', 'dbLinkId', 'tableList', 'dbSourceId', 'allTabelData', 'columnModelId'],
  data() {
    return {
      idGlobal: 100,
      formConf,
      inputComponents,
      selectComponents,
      systemComponents,
      allComponents: [...inputComponents, ...selectComponents, ...systemComponents],
      layoutComponents,
      labelWidth: 100,
      drawingList: [],
      drawingData: {},
      activeId: null,
      drawerVisible: false,
      previewVisible: false,
      formData: {},
      relationData: [{ relationName: '', fieldName: [], fieldList: [], tablesList: [], relationList: [] }],
      logicData: [{ hostval: '', op: '', setType: '', deVal: [], logicOpList: [] }],
      dialogVisible: false,
      jsonDrawerVisible: false,
      generateConf: null,
      showFileName: false,
      activeData: {},
      saveDrawingListDebounce: debounce(340, saveDrawingList),
      saveIdGlobalDebounce: debounce(340, saveIdGlobal),
      isDrawingListChange: true,
      showTip: true,
      activeItem: {},
      activeTableItem: {},
      leftComponents: [
        {
          title: '基础控件',
          list: inputComponents
        },
        {
          title: '高级控件',
          list: selectComponents
        },
        // {
        //   title: '布局控件',
        //   list: layoutComponents
        // }
        {
          title: '系统控件',
          list: systemComponents
        }
      ],
      layout: [],
      layouKey: 0,
      map: []
    }
  },
  computed: {},
  watch: {
    // eslint-disable-next-line func-names
    'activeData.__config__.label': function (val, oldVal) {
      // if (
      //   this.activeData.placeholder === undefined
      //   || !this.activeData.__config__.tag
      //   || oldActiveId !== this.activeId
      // ) {
      //   return
      // }
      // this.activeData.placeholder = this.activeData.placeholder.replace(oldVal, '') + val
    },
    activeId: {
      handler(val) {
        oldActiveId = val
      },
      immediate: true
    },
    drawingList: {
      handler(val) {
        this.saveDrawingListDebounce(val)
        if (val.length === 0) this.idGlobal = 1
        // if (!this.isDrawingListChange) {
        //   this.isDrawingListChange = true
        //   return
        // }
        this.$emit('drawingListChange')
      },
      deep: true
    },
    idGlobal: {
      handler(val) {
        this.formConf.idGlobal = val
        // this.saveIdGlobalDebounce(val)
      },
      immediate: true
    }
  },
  created() {
    if (this.relationList && this.relationList.length) {
      this.relationData = deepClone(this.relationList)
    }
    if (this.logicList && this.logicList.length) {
      this.logicData = deepClone(this.logicList)
    }
    if (typeof this.conf === 'object' && this.conf !== null) {
      // let copyFields = deepClone(this.conf.fields)
      // let tableChildren = copyFields.filter((item,k)=> item.fatherBoxConfig && item.__fathervModel__)
      // //将子表数据格式化
      // if (tableChildren &&tableChildren.length){
      //   let NewList = this.getfilterList(tableChildren,'__fathervModel__')
      //   let tabelBox = NewList.map((item,k)=>{
      //     return {
      //       __config__:item.fatherBoxConfig,
      //       __vModel__:item.__fathervModel__,
      //       actionText:item.fatherActionText
      //     }
      //   })
      //   let formList = copyFields.filter((item,k)=> !item.fatherBoxConfig && !item.__fathervModel__)
      //   copyFields = formList.concat(tabelBox)
      // }
      this.isDrawingListChange = false
      this.conf.fields = this.conf.fields.map((item) => {
        const find = this.allComponents.find((i) => i?.__config__?.jnpfKey === item?.__config__?.jnpfKey)
        if (find) {
          item.__config__ = { ...find.__config__, ...item.__config__ }
          item.__config__.tag = find.__config__.tag
          return { ...find, ...item }
        } else {
          return item
        }
      })
      this.drawingList = g.Copy(this.conf.fields)
      this.layout = this.drawingList.map((item, index) => {
        let x = item.x ? item.x : 0
        let y = item.y ? item.y : index
        let h = item.h ? item.h : 2
        let w = item.w ? item.w : item.__config__.span
        let i = item.i ? item.i : this.getEncode()
        // !item.x ? item.x = item.x || 0 : item.x
        // !item.y ? item.y = item.y || index : item.y
        // item.h = item.h ||  2
        // item.w = item.w || item.__config__.span
        // item.i = item.i || index
        return { x: x, y: y, w: w, h: h, minH: 2, i: i }
      })
      this.layouKey = this.drawingList.length
      Object.assign(this.formConf, this.conf)
      this.idGlobal = this.formConf.idGlobal
      if (this.drawingList.length) this.activeFormItem(this.drawingList[0])
    } else {
      this.drawingList = []
      this.idGlobal = 1
      this.mapFieldsList()
    }
    // if (this.modelType == 1 || this.modelType == 6) this.leftComponents[1].list = [...this.leftComponents[1].list, ...webPeculiarList]
  },
  mounted() {
    // fix: firefox 下 拖拽 会新打卡一个选项卡
    // https://github.com/JakHuang/form-generator/issues/15
    document.body.ondrop = (event) => {
      event.preventDefault()
      event.stopPropagation()
    }
    this.map = JSON.parse(JSON.stringify(this.layout))
  },
  methods: {
    cancelSelection(event) {
      this.activeId = null
    },
    getfilterList(arr, u_key) {
      let map = new Map()
      arr.forEach((item, index) => {
        if (!map.has(item[u_key])) {
          map.set(item[u_key], item)
        }
      })
      return [...map.values()]
    },
    //遍历数据集生成组件
    mapFieldsList() {
      //获取选择的数据集的所有字段
      let formItemList = this.$store.state.generator.formItemList
      //获取基本控件
      let inputList = this.inputComponents
      let _this = this
      function getList(data) {
        data.forEach((item, index) => {
          if (item.children && item.children.length) {
            getList(item.children)
          } else {
            _this.$nextTick(() => {
              //寻找相近的类型生成表单组件
              inputList.forEach((element, key) => {
                if (item.viewDataType === 'STRING' && element.__config__.jnpfKey === 'comInput') {
                  _this.addComponent(element, item.id, item.columnName, item.columnTitle, item.viewDataType, item.isRequiredType, item.columnAttr)
                }
                if (item.viewDataType === 'NUMBER' && element.__config__.jnpfKey === 'numInput') {
                  _this.addComponent(element, item.id, item.columnName, item.columnTitle, item.viewDataType, item.isRequiredType, item.columnAttr)
                }
                if (item.viewDataType === 'DATETIME' && element.__config__.jnpfKey === 'date') {
                  _this.addComponent(element, item.id, item.columnName, item.columnTitle, item.viewDataType, item.isRequiredType, item.columnAttr)
                }
              })
            })
          }
        })
      }
      getList(formItemList)
    },
    // 供父组件使用 获取表单JSON
    getData() {
      return new Promise((resolve, reject) => {
        if (!this.drawingList.length) {
          reject({ msg: '表单不允许为空', target: 1 })
          return
        }
        const loop = (list) => {
          for (let i = 0; i < list.length; i++) {
            const e = list[i]
            const config = e.__config__
            if (this.$store.getters.hasTable && config.layout === 'colFormItem' && !noVModelList.includes(config.jnpfKey) && !e.__vModel__) {
              this.activeData = e
              this.activeId = e.__config__.formId
              reject({ msg: `请选择${config.label}的控件字段`, target: 1 })
              break
            }
            if (config.jnpfKey === 'billRule') {
              if (!config.rule) {
                reject({ msg: '单据组件“选择模板”属性为必填项', target: 1 })
                break
              }
            }
            if (config.jnpfKey === 'relationForm') {
              if (!e.modelId) {
                reject({ msg: '关联表单控件“关联功能”属性为必填项', target: 1 })
                break
              }
              if (!e.relationField) {
                reject({ msg: '关联表单控件“显示字段”属性为必填项', target: 1 })
                break
              }
            }
            if (config.jnpfKey === 'relationFlow' && !e.flowId) {
              reject({ msg: '关联流程表单控件“关联流程”属性为必填项', target: 1 })
              break
            }
            if (config.layout === 'rowFormItem' && !config.children.length) {
              reject({ msg: `您的${config.label}控件中没有组件`, target: 1 })
              break
            }
            if (config && config.children && Array.isArray(config.children)) {
              loop(config.children)
            }
          }
        }
        loop(this.drawingList)
        if (this.drawingList.find((i) => i.varRepeat))
          return this.$message({
            message: '检测到变量命名重复，请重新输入',
            type: 'warning'
          })
        this.getLogicFil()
        this.getRelationFil()
        this.AssembleFormData()
        resolve({ formData: this.formData, relationData: this.relationData, logicData: this.logicData, target: 1 })
      })
    },
    getLogicFil() {
      this.drawingList.forEach((i, j) => {
        delete i.__logic__
      })
      this.logicData.forEach((v, k) => {
        if (v.hostval && v.op) {
          this.drawingList.forEach((i, j) => {
            if (v.hostval === i.__vModel__) {
              i.__logic__ = {
                op: v.op,
                setType: v.setType,
                deVal: v.deVal
              }
            }
          })
        }
      })
    },
    getRelationFil() {
      this.relationData.forEach((v, k) => {
        //未选择关联表
        if (!v.relationName) {
          delete this.relationData[k]
        } else {
          //选择关联表 且有关联字段
          if (v.relationList && v.relationList.length) {
            //是否整个分组都未绑定组件
            if (v.relationList.every((target) => !target.drawId)) {
              delete this.relationData[k]
            } else {
              //保留绑定过组件的关联字段
              // let drawIdList = v.relationList.map((o,i)=>{
              //   if (o.drawId){
              //     return o.fieldId
              //   }
              // }).filter( l => l !== undefined)
              // v.fieldName = v.fieldName.filter(p=>{
              //   return drawIdList.includes(p.value)
              // })
              // 未关联组件的删除
              // v.relationList.forEach((item,i)=>{
              //   if (!item.drawId){
              //     delete v.relationList[i]
              //   }
              // })
            }
          } else {
            delete this.relationData[k]
          }
        }
      })
      this.relationData = this.relationData.filter(Boolean)
    },
    //  阻止表格中嵌套行容器
    shouldClone(to, from, target, event, conf) {
      const targetConf = target._underlying_vm_
      const isRowContainer = conf.__config__.cmpType === 'common' && conf.__config__.rowType === 'layout'
      if (isRowContainer) return true
      if (conf.cmpType === 'custom') return false
      if (conf.__config__.rowType === 'table') {
        if (noTableAllowList.includes(targetConf.__config__.jnpfKey)) {
          // if (this.showTip) {
          //   this.$message.warning(`子表内暂不支持使用该组件`)
          //   this.showTip = false
          // }
          return false
        }
        if (targetConf.__config__.layout === 'rowFormItem') return false
        if (this.$store.getters.hasTable) {
          if (!conf.__config__.tableName) {
            if (this.showTip) {
              this.$message.warning(`子表请先关联数据表`)
              this.showTip = false
            }
            return false
          }
        }
        this.activeItem = targetConf
        this.activeTableItem = conf
      }
      return true
    },
    activeFormItem(element) {
      this.activeData = element
      this.activeId = element.__config__.formId
    },
    onEnd(obj) {
      if (!tempActiveData) return
      this.showTip = true
      if (obj.from !== obj.to) {
        this.activeData = tempActiveData
        this.activeId = this.idGlobal
      }
      if (obj.to.className.indexOf('table') > -1) {
        this.$set(this.activeItem.__config__, 'isSubTable', true)
        if (this.$store.getters.hasTable) {
          this.$set(this.activeItem.__config__, 'relationTable', this.activeTableItem.__config__.tableName)
          this.activeItem.__vModel__ = ''
        }
      }
    },
    onCenterEnd(obj) {
      this.showTip = true
      if (obj.from == obj.to) return
      if (obj.to.className.indexOf('table') > -1) {
        this.$set(this.activeItem.__config__, 'isSubTable', true)
        if (this.$store.getters.hasTable) {
          this.$set(this.activeItem.__config__, 'relationTable', this.activeTableItem.__config__.tableName)
          this.activeItem.__vModel__ = ''
        }
      }
    },
    onTableEnd(obj, target, conf) {
      if (obj.from == obj.to) return
      if (obj.to.className.indexOf('table') < 0) {
        this.$set(this.activeData.__config__, 'isSubTable', false)
        this.$set(this.activeData.__config__, 'isRequiredType', false)
        this.$set(this.activeData.__config__, 'relationTable', '')
        if (this.$store.getters.hasTable) this.activeData.__vModel__ = ''
      }
    },
    //添加组件
    addComponent(item, id, columnName, columnTitle, viewDataType, isRequiredType, columnAttr) {
      if (item.__config__.jnpfKey === 'serialNumber') {
        let serialRow = this.drawingList
          .map((z) => z.__config__.jnpfKey)
          .flat()
          .find((i) => i === item.__config__.jnpfKey && item.__config__.jnpfKey === 'serialNumber')
        if (serialRow) return this.$message.warning('表单中仅可添加一个流水号控件')
      }
      if (item.__config__.dragDisabled) return
      const clone = this.cloneComponent(item)
      // clone.x = 0
      // clone.y = this.layouKey
      // clone.h = clone.h || 2
      // clone.minH = clone.minH || 2
      // clone.w = clone.w || clone.__config__.span
      // clone.i = this.getEncode()
      if (id) clone.__vModel__ = id
      if (columnName) clone.__vModelName__ = columnName
      if (columnTitle) clone.__config__.label = columnTitle
      if (viewDataType) clone.__config__.viewDataType = viewDataType
      isRequiredType ? (clone.__config__.isRequiredType = isRequiredType) : (clone.__config__.isRequiredType = false)
      //计算属性字段不可编辑
      if (columnAttr === 'VIRTUAL') clone.disabled = true
      // console.log(clone.__config__.formId)
      // console.log(this.drawingList)
      // if (this.drawingList.length){
      //   this.drawingList.forEach((item,index)=>{
      //     console.log(item.__config__.formId,'item.__config__.formId')
      //     if (item.__config__.formId === this.activeId){
      //       console.log(index,'index')
      //       this.drawingList.splice(index,0,clone)
      //       this.layout.splice(index,0,clone)
      //
      //       this.$forceUpdate();
      //     }
      //   })
      // }else {
      //
      // }
      this.drawingList.push(clone)
      this.layout.push(clone)
      this.$forceUpdate()
      this.activeFormItem(clone)
      this.layouKey += 1
    },
    getEncode() {
      return 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
        return (c === 'x' ? (Math.random() * 12) | 0 : 'r&0x3' | '0x8').toString(12)
      })
    },
    cloneComponent(origin) {
      if (origin.__config__.jnpfKey === 'serialNumber') {
        let serialRow = this.drawingList
          .map((z) => z.__config__.jnpfKey)
          .flat()
          .find((i) => i === origin.__config__.jnpfKey && origin.__config__.jnpfKey === 'serialNumber')
        if (serialRow) return this.$message.warning('表单中仅可添加一个流水号控件')
      }
      const clone = deepClone(origin)
      const config = clone.__config__
      config.span = this.formConf.span // 生成代码时，会根据span做精简判断
      this.createIdAndKey(clone)
      // clone.placeholder !== undefined && (clone.placeholder += config.label)
      tempActiveData = clone
      return tempActiveData
    },
    createIdAndKey(item) {
      const config = item.__config__
      config.formId = ++this.idGlobal
      config.renderKey = +new Date() // 改变renderKey后可以实现强制更新组件
      if (config.layout === 'colFormItem') {
        if (!this.$store.getters.hasTable) {
          // 分割线和按钮不加vModel
          if (noVModelList.indexOf(config.jnpfKey) > -1) return
          item.__vModel__ = ''
          item.__vModelName__ = `COL_${this.idGlobal}`
        } else {
          if (noVModelList.indexOf(config.jnpfKey) > -1) return
          item.__vModel__ = ''
          item.__vModelName__ = ''
        }
      } else if (config.layout === 'rowFormItem') {
        if (config.jnpfKey === 'table') {
          // config.tableName = this.dbLinkId
          item.__vModel__ = `${config.jnpfKey}Field${this.idGlobal}`
          item.__vModelName__ = ''
        }
        config.componentName = `row${this.idGlobal}`
        !Array.isArray(config.children) && (config.children = [])
        // delete config.label // rowFormItem无需配置label属性
      }
      if (Array.isArray(config.children)) {
        config.children = config.children.map((childItem) => this.createIdAndKey(childItem))
      }
      return item
    },
    AssembleFormData() {
      this.formData = {
        ...this.formConf,
        fields: deepClone(this.drawingList)
      }
    },
    empty() {
      this.$confirm('若数据集存在必填项将不会被清空，确定要清空所有组件吗？', '提示', { type: 'warning' })
        .then(() => {
          // this.drawingList = []
          //必填项不会被清空
          this.drawingList = this.drawingList
            .map((i) => {
              if (i.__config__.isRequiredType) {
                return i
              }
            })
            .filter((l) => l !== undefined)
          // this.layout = []
          this.layout = this.layout
            .map((i) => {
              if (i.__config__.isRequiredType) {
                return i
              }
            })
            .filter((l) => l !== undefined)
          this.idGlobal = 1
          this.layouKey = 0
        })
        .catch(() => {})
    },
    drawingItemCopy(item, parent) {
      let clone = deepClone(item)
      clone = this.createIdAndKey(clone)
      parent.push(clone)
      this.activeFormItem(clone)
    },
    drawingItemDelete(index, parent, element) {
      if (element.__config__.jnpfKey === 'table' && element.dbLinkId) {
        let deleteCube = this.$store.state.generator.deleteCubeList
        deleteCube.push(element.dbLinkId)
        this.$store.commit('generator/UPDATE_DELETECUBE_LIST', deleteCube)
      }
      parent.splice(index, 1)
      this.$nextTick(() => {
        const len = this.drawingList.length
        if (len) {
          this.activeFormItem(this.drawingList[len - 1])
        }
      })
    },
    preview() {
      if (this.drawingList.find((i) => i.varRepeat))
        return this.$message({
          message: '检测到变量命名重复，请重新输入',
          type: 'warning'
        })
      this.getLogicFil()
      this.getRelationFil()
      this.AssembleFormData()
      if (!this.relationData || !this.relationData.length) {
        this.relationData = [{ relationName: '', fieldName: [], fieldList: [], tablesList: [], relationList: [] }]
      }
      this.previewVisible = true
    },
    showJson() {
      this.AssembleFormData()
      this.jsonDrawerVisible = true
    },
    tagChange(newTag) {
      newTag = this.cloneComponent(newTag)
      const config = newTag.__config__
      newTag.__vModel__ = this.activeData.__vModel__
      config.formId = this.activeId
      config.span = this.activeData.__config__.span
      this.activeData.__config__.tag = config.tag
      this.activeData.__config__.tagIcon = config.tagIcon
      this.activeData.__config__.document = config.document
      if (typeof this.activeData.__config__.defaultValue === typeof config.defaultValue) {
        config.defaultValue = this.activeData.__config__.defaultValue
      }
      Object.keys(newTag).forEach((key) => {
        if (this.activeData[key] !== undefined) {
          newTag[key] = this.activeData[key]
        }
      })
      this.activeData = newTag
      this.updateDrawingList(newTag, this.drawingList)
    },
    updateDrawingList(newTag, list) {
      const index = list.findIndex((item) => item.__config__.formId === this.activeId)
      if (index > -1) {
        list.splice(index, 1, newTag)
      } else {
        list.forEach((item) => {
          if (Array.isArray(item.__config__.children)) this.updateDrawingList(newTag, item.__config__.children)
        })
      }
    },
    refreshJson(data) {
      this.drawingList = deepClone(data.fields)
      delete data.fields
      this.formConf = data
    },
    relationChange(vmodel) {
      const loop = (list) => {
        for (let i = 0; i < list.length; i++) {
          const config = list[i].__config__
          if (list[i].relationField && list[i].relationField === list[i].__vModel__) {
            list[i].showField = ''
          }
          if (config && config.children && Array.isArray(config.children)) {
            loop(config.children)
          }
        }
      }
      loop(this.drawingList)
    },
    changeType(data) {
      let { oldActiveData, newData } = data
      this.activeData = this.cloneComponent(newData)
      this.activeData.__config__.formId = oldActiveData.__config__.formId
      this.activeData.__config__.viewDataType = oldActiveData.__config__.viewDataType
      this.activeData.__config__.isRequiredType = oldActiveData.__config__.isRequiredType
      this.activeData.__config__.isSubTable = oldActiveData.__config__.isSubTable
      this.activeData.__config__.relationTable = oldActiveData.__config__.relationTable
      this.activeData.__config__.span = oldActiveData.__config__.span
      this.activeData.__vModel__ = oldActiveData.__vModel__
      this.activeData.__config__.label = oldActiveData.__config__.label
      this.activeData.__vModelName__ = oldActiveData.__vModelName__
      this.updateDrawingList(this.activeData, this.drawingList)
    },
    resizeEvent(i, newH, newW, newHPx, newWPx) {
      this.drawingList.forEach((item, index) => {
        if (item.i === i) {
          item.w = newW
          item.h = newH
        }
      })
      // console.log("RESIZE i=" + i + ", H=" + newH + ", W=" + newW + ", H(px)=" + newHPx + ", W(px)=" + newWPx);
    },
    moveEvent(i, newX, newY) {
      //找到被移动的对象
      const finditem = this.map.find((item) => item.x === newX && item.y === newY && item.i !== i)
      if (!finditem) return
      this.changePositions(
        //找到移动的对象
        this.layout.find((item) => item.i === i),
        finditem
      )
    },
    movedEvent: function (i, newX, newY) {
      let arr = deepClone(this.layout)
      let arr1 = deepClone(this.drawingList)
      this.drawingList = this.assign(arr, arr1)
      this.$forceUpdate()
    },
    //在移动过程中谁跟谁调换了顺序
    changePositions(item1, item2) {
      // 定义中间变量交换
      const temp = deepClone(item1)
      let num
      let num1
      //   注意：修改的是影响显示的实际数组 layout
      this.layout.forEach((item, index) => {
        // 找到 item1,将 item1 的信息换成item2
        if (item.i === item1.i) {
          item.x = item2.x
          item.y = item2.y
          num = index
        }
        if (item.i === item2.i) {
          item.x = temp.x
          item.y = temp.y
          num1 = index
        }
      })
      // 实现交换后，及时同步 数据映射
      this.map = deepClone(this.layout)
      //数组元素交换位置
      this.layout = this.swapArray(this.map, num, num1)
    },
    //数组元素交换位置
    swapArray(arr, index1, index2) {
      arr[index1] = arr.splice(index2, 1, arr[index1])[0]
      return arr
    },
    //合并数组
    assign(arr1, arr2) {
      let arr3 = []
      arr1.forEach((element) => {
        arr2.forEach((item) => {
          if (element.i === item.i) {
            arr3.push(Object.assign(item, element))
          }
        })
      })
      return arr3
    }
  }
}
</script>

<style lang="scss">
@import '../styles/index';
@import '../styles/home';
</style>
<style lang="scss" scoped>
::v-deep .el-input-number--small {
  line-height: 32px;
  width: 100% !important;
}
::v-deep .el-form-item--small .el-form-item__label {
  line-height: 33px;
}
::v-deep .el-form-item--small .el-form-item__content {
  line-height: 33px;
}
::v-deep .drawing-board .el-switch {
  height: 32px;
}
::v-deep .el-input-number[data-append] {
  --el-input-number-append-offset-x: 32px;
  position: relative;
}
::v-deep .el-input-number[data-prepend] {
  --el-input-number-prepend-offset-x: 65px;
  position: relative;
}
::v-deep .el-input-number[data-prepend]::before {
  content: attr(data-prepend);
  height: 91%;
  display: flex;
  align-items: center;
  position: absolute;
  top: 2px;
  left: 0;
  color: #909399;
  background-color: #f5f7fa;
  border: 1px solid #dcdfe6;
  border-top: none;
  border-bottom: none;
  padding: 0 20px;
  z-index: 1;
}
::v-deep .el-input-number[data-prepend] .el-input__inner {
  padding-left: calc(var(--el-input-number-prepend-offset-x) + 12px);
}
::v-deep .el-input-number[data-append]::after {
  content: attr(data-append);
  height: 91%;
  display: flex;
  align-items: center;
  position: absolute;
  top: 2px;
  right: var(--el-input-number-append-offset-x);
  color: #909399;
  background-color: #f5f7fa;
  border: 1px solid #dcdfe6;
  border-top: none;
  border-bottom: none;
  padding: 0 20px;
}
::v-deep .el-input-number[data-append] .el-input__inner {
  padding-right: calc(var(--el-input-number-append-offset-x) + 12px);
}
</style>
