<script lang="ts">
import Vue from 'vue'
import { saveForm, getFormInfo, getMyFields, saveMyFields } from '@/api/form'
import guide from '@/views/components/guidePopover.vue'
import draggable from 'vuedraggable'
import countryCode from '@/lib/countryCode.json'
import {
  pcTextArr,
  pcaTextArr
} from 'element-china-area-data'

export default Vue.extend({
  name: 'Edit',
  components: {
    draggable,
    guide
  },
  data() {
    return {
      quickComp: [
        {
          id: 'quick_input',
          quick: true,
          field_name: '',
          field_type: 'input',
          field_label: '单行输入框',
          field_data: {
            value: '',
            width: 6,
            placeholder: '请输入',
            pattern: '',
            options: [],
            max: 10,
            min: 0,
            step: 1,
            rows: [2, 4],
            rangeSeparator: '至',
            endPlaceholder: '结束时间'
          },
          is_required: 0
        },
        {
          id: 'quick_textarea',
          quick: true,
          field_name: '',
          field_type: 'textarea',
          field_label: '多行输入框',
          field_data: {
            value: '',
            width: 6,
            placeholder: '请输入',
            pattern: '',
            options: [],
            max: 10,
            min: 0,
            step: 1,
            rows: [2, 4],
            rangeSeparator: '至',
            endPlaceholder: '结束时间'
          },
          is_required: 0
        },
        {
          id: 'quick_select',
          quick: true,
          field_name: '',
          field_type: 'select',
          field_label: '下拉选择框',
          field_data: {
            value: '',
            width: 6,
            placeholder: '请选择',
            pattern: '',
            options: [
              { label: '姜母鸭', value: '姜母鸭' },
              { label: '白切鸡', value: '白切鸡' },
              { label: '红烧肉', value: '红烧肉' }
            ],
            max: 10,
            min: 0,
            step: 1,
            rows: [2, 4],
            rangeSeparator: '至',
            endPlaceholder: '结束时间'
          },
          is_required: 0
        },
        {
          id: 'quick_checkbox',
          quick: true,
          field_name: '',
          field_type: 'checkbox',
          field_label: '多选列表',
          field_data: {
            value: '',
            width: 6,
            placeholder: '请选择',
            pattern: '',
            options: [
              { label: '姜母鸭', value: '姜母鸭' },
              { label: '白切鸡', value: '白切鸡' },
              { label: '红烧肉', value: '红烧肉' }
            ],
            max: 10,
            min: 0,
            step: 1,
            rows: [2, 4],
            rangeSeparator: '至',
            endPlaceholder: '结束时间'
          },
          is_required: 0
        },
        {
          id: 'quick_radio',
          quick: true,
          field_name: '',
          field_type: 'radio',
          field_label: '单选列表',
          field_data: {
            value: '',
            width: 6,
            placeholder: '请选择',
            pattern: '',
            options: [
              { label: '姜母鸭', value: '姜母鸭' },
              { label: '白切鸡', value: '白切鸡' },
              { label: '红烧肉', value: '红烧肉' }
            ],
            max: 10,
            min: 0,
            step: 1,
            rows: [2, 4],
            rangeSeparator: '至',
            endPlaceholder: '结束时间'
          },
          is_required: 0
        },
        {
          id: 'quick_number',
          quick: true,
          field_name: '',
          field_type: 'number',
          field_label: '数字输入',
          field_data: {
            value: '',
            width: 6,
            placeholder: '请选择',
            pattern: '',
            options: [],
            max: 10,
            min: 0,
            step: 1,
            rows: [2, 4],
            rangeSeparator: '至',
            endPlaceholder: '结束时间'
          },
          is_required: 0
        },
        {
          id: 'quick_slider',
          quick: true,
          field_name: '',
          field_type: 'slider',
          field_label: '数字滑块',
          field_data: {
            value: '',
            width: 6,
            placeholder: '请选择',
            pattern: '',
            options: [],
            max: 10,
            min: 0,
            step: 1,
            rows: [2, 4],
            rangeSeparator: '至',
            endPlaceholder: '结束时间'
          },
          is_required: 0
        },
        {
          id: 'quick_time',
          quick: true,
          field_name: '',
          field_type: 'time',
          field_label: '时间选择',
          field_data: {
            value: '',
            width: 6,
            placeholder: '请选择',
            pattern: '',
            options: [],
            max: 10,
            min: 0,
            step: 1,
            rows: [2, 4],
            rangeSeparator: '至',
            endPlaceholder: '结束时间'
          },
          is_required: 0
        },
        {
          id: 'quick_timeRange',
          quick: true,
          field_name: '',
          field_type: 'timeRange',
          field_label: '时间范围选择',
          field_data: {
            value: '',
            width: 6,
            placeholder: '请选择',
            pattern: '',
            options: [],
            max: 10,
            min: 0,
            step: 1,
            rows: [2, 4],
            rangeSeparator: '至',
            endPlaceholder: '结束时间'
          },
          is_required: 0
        },
        {
          id: 'quick_date',
          quick: true,
          field_name: '',
          field_type: 'date',
          field_label: '日期选择',
          field_data: {
            value: '',
            width: 6,
            placeholder: '请选择',
            pattern: '',
            options: [],
            max: 10,
            min: 0,
            step: 1,
            rows: [2, 4],
            rangeSeparator: '至',
            endPlaceholder: '结束时间'
          },
          is_required: 0
        },
        {
          id: 'quick_dateRange',
          quick: true,
          field_name: '',
          field_type: 'dateRange',
          field_label: '日期范围选择',
          field_data: {
            value: '',
            width: 6,
            placeholder: '请选择',
            pattern: '',
            options: [],
            max: 10,
            min: 0,
            step: 1,
            rows: [2, 4],
            rangeSeparator: '至',
            endPlaceholder: '结束时间'
          },
          is_required: 0
        }
      ],
      customComp: [],
      systemComp: [
        {
          id: 'first_name',
          field_name: 'first_name',
          field_type: 'input',
          field_label: '请在下方输入名字',
          field_data: {
            value: '',
            width: 3,
            placeholder: '请输入名字'
          },
          is_required: 0
        },
        {
          id: 'last_name',
          field_name: 'last_name',
          field_type: 'input',
          field_label: '请在下方输入姓氏',
          field_data: {
            value: '',
            width: 3,
            placeholder: '请输入姓氏'
          },
          is_required: 0
        },
        {
          id: 'id_type',
          field_name: 'id_type',
          field_type: 'select',
          field_label: '请在下方选择证件类型',
          field_data: {
            value: '',
            width: 2,
            options: [
              { label: '身份证', value: 'id_card' },
              { label: '护照', value: 'passport' },
              { label: '驾驶证', value: 'drivers_license' },
              { label: '港澳通行证', value: 'hongkong_macau_pass' }
            ],
            placeholder: '请选择'
          },
          is_required: 0
        },
        {
          id: 'id_number',
          field_name: 'id_number',
          field_type: 'input',
          field_label: '请在下方输入证件号码',
          field_data: {
            value: '',
            width: 4,
            placeholder: '请输入证件号码'
          },
          is_required: 0
        },
        {
          id: 'mobile_country_code',
          field_name: 'mobile_country_code',
          field_type: 'phone',
          field_label: '请在下方输入手机国家代码',
          field_data: {
            value: '',
            country: 'CN',
            width: 2,
            placeholder: '请输入手机国家代码'
          },
          is_required: 0
        },
        {
          id: 'mobile',
          field_name: 'mobile',
          field_type: 'input',
          field_label: '请在下方输入手机号码',
          field_data: {
            value: '',
            country: 'CN',
            width: 4,
            placeholder: '请输入手机号'
          },
          is_required: 0
        },
        {
          id: 'email',
          field_name: 'email',
          field_type: 'input',
          field_label: '请在下方输入邮箱',
          field_data: {
            value: '',
            width: 6,
            placeholder: '请输入邮箱',
            codePlaceholder: '请输入验证码'
          },
          is_required: 0
        },
        {
          id: 'company',
          field_name: 'company',
          field_type: 'input',
          field_label: '请在下方输入公司名称',
          field_data: {
            value: '',
            width: 2,
            placeholder: '请输入公司名称'
          },
          is_required: 0
        },
        {
          id: 'department',
          field_name: 'department',
          field_type: 'input',
          field_label: '请在下方输入部门名称',
          field_data: {
            value: '',
            width: 2,
            placeholder: '请输入部门名称'
          },
          is_required: 0
        },
        {
          id: 'position',
          field_name: 'position',
          field_type: 'select',
          field_label: '请在下方选择职位',
          field_data: {
            value: '',
            width: 2,
            options: [
              { label: '职位', value: '职位' }
            ],
            placeholder: '请选择'
          },
          is_required: 0
        },
        {
          id: 'country',
          field_name: 'country',
          field_type: 'select',
          field_label: '请在下方选择国家',
          field_data: {
            value: '',
            width: 2,
            options: [
              { label: '国家', value: '国家' }
            ],
            placeholder: '请选择'
          },
          is_required: 0
        },
        {
          id: 'province',
          field_name: 'province',
          field_type: 'select',
          field_label: '请在下方选择省份',
          field_data: {
            value: '',
            width: 2,
            options: [
              { label: '省份', value: '省份' }
            ],
            placeholder: '请选择'
          },
          is_required: 0
        },
        {
          id: 'city',
          field_name: 'city',
          field_type: 'select',
          field_label: '请在下方选择市',
          field_data: {
            value: '',
            width: 2,
            options: [
              { label: '市', value: '市' }
            ],
            placeholder: '请选择'
          },
          is_required: 0
        },
        {
          id: 'address',
          field_name: 'address',
          field_type: 'input',
          field_label: '请在下方输入地址',
          field_data: {
            value: '',
            width: 6,
            placeholder: '请输入地址'
          },
          is_required: 0
        },
        {
          id: 'industry',
          field_name: 'industry',
          field_type: 'select',
          field_label: '请在下方选择行业',
          field_data: {
            value: '',
            width: 2,
            options: [
              { label: '行业', value: '行业' }
            ],
            placeholder: '请选择'
          },
          is_required: 0
        }
      ],
      formData: [],
      trashData: [],
      formInfo: {
        name: '未命名表单',
        desc: '从右侧拖动组件到表单区域',
        id: ''
      },
      copyData: {},
      isDrag: false,
      currentKey: '',
      currentData: {},
      hoverKey: '',
      selectInput: '',
      pcTextArr,
      pcaTextArr,
      countryCode,
      CompType: 'sys',
      loading: false,
      copyShow: false,
      copyFormShow: false,
      inForm: false
    }
  },
  mounted() {
    this.init()
  },

  beforeDestroy() {
    console.log('destroy')
    document.removeEventListener('keydown', this.KeyHandel)
  },
  watch: {
    $route() {
      this.init()
    }
  },
  methods: {
    init() {
      if (this.$route.params.id) {
        this.loading = true
        this.formInfo.id = this.$route.params.id
        getFormInfo(this.formInfo.id).then(res => {
          this.formData = res.data.fields
          this.formInfo.name = res.data.template_name
          this.formInfo.desc = res.data.description
          this.loading = false
        }).catch(() => {
          this.loading = false
        })
      }
      getMyFields().then(res => {
        this.customComp = res.data
      }).catch(() => {
      })
      document.addEventListener('keydown', this.KeyHandel)
    },
    async save() {
      if (this.loading) {
        return
      }
      this.loading = true
      for (let i = 0; i < this.formData.length; i++) {
        const item = this.formData[i]
        if (item.quick) {
          try {
            const data = await saveMyFields('', item.field_label, item.field_type, item.field_data, item.is_required)
            console.log(data)
            item.id = data.data
          } catch (e) {
            console.log(e)
            this.$notify({
              title: '快速组件保存失败',
              message: '也许你已经创建过名为"' + item.field_label + '"的组件了，请直接在"我的组件"使用',
              type: 'error'
            })
            this.loading = false
            return
          }
        }
      }
      console.log(this.formData)
      saveForm(this.formInfo.id, this.formInfo.name, this.formInfo.desc, this.formData).then(res => {
        this.loading = false
        this.$notify({
          title: '保存成功',
          message: '表单已保存完成',
          type: 'success'
        })
      }).catch(() => {
        this.loading = false
      })
    },
    cloneForm() {
      if (this.loading) { return }
      this.loading = true
      saveForm('', this.formInfo.name + '(副本)', this.formInfo.desc, this.formData).then(res => {
        console.log(res.data)
        this.loading = false
        this.$router.push({ path: '/preRegister/edit/' + res.data })
      }).catch(() => {
        this.loading = false
      })
    },
    choseComp(element) {
      this.currentKey = element.id
      this.currentData = element
    },
    removeComp(element) {
      this.$confirm('确定删除吗？', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
        callback: action => {
          if (action === 'confirm') {
            const index = this.getIndexByKey(element.id)
            this.formData.splice(index, 1)
            this.currentKey = ''
          }
        }
      })
    },
    addSelectItem() {
      if (this.selectInput.length === 0) { return }
      this.currentData.field_data.options.push({
        label: this.selectInput,
        value: this.selectInput
      })
      this.selectInput = ''
    },
    removeSelectItem(index) {
      this.currentData.field_data.options.splice(index, 1)
    },
    cloneItem(item) {
      const newItem = JSON.parse(JSON.stringify(item))
      newItem.id = newItem.id + '_' + new Date().getTime()
      return newItem
    },
    removeTrash(element) {
      const index = this.getIndexByKey(element.id)
      this.trashData.splice(index, 1)
    },
    hover(element) {
      if (this.isDrag) return
      this.hoverKey = element.id
    },
    blur(element) {
      this.hoverKey = ''
    },
    getIndexByKey(id) {
      return this.formData.indexOf(this.formData.find(item => item.id === id))
    },
    handleStart() {
      this.isDrag = true
      this.formData.forEach(item => {
        item.hover = false
      })
    },
    handleEnd() {
      this.isDrag = false
    },
    KeyHandel(e) {
      const index = this.getIndexByKey(this.currentKey)
      if (e.ctrlKey) {
        if (e.key === 's') {
          this.save()
          e.preventDefault()
          return
        }
        if (!this.inForm) {
          return
        }
        if (index === -1) {
          e.preventDefault()
          return
        }
        if (e.key === 'd') {
          this.formData.splice(index + 1, 0, this.cloneItem(this.currentData))
        }
        if (e.key === 'c') {
          navigator.clipboard.writeText(JSON.stringify(this.currentData))
          this.copyData = JSON.parse(JSON.stringify(this.currentData))
        }
        if (e.key === 'v') {
          navigator.clipboard.readText().then(text => {
            const copyData = JSON.parse(text)
            if (copyData.field_label) {
              this.copyData = JSON.parse(JSON.stringify(copyData))
            }
          }).catch(err => {
            this.$notify({
              title: '权限不足',
              message: '请授予剪贴板权限，否则只能在此表单内粘贴数据，无法粘贴至其它表单',
              type: 'warning'
            })
          }).finally(e => {
            if (this.copyData.field_label) {
              this.formData.splice(index + 1, 0, this.cloneItem(this.copyData))
            }
          })
        }
        if (e.key === 'x') {
          navigator.clipboard.writeText(JSON.stringify(this.currentData))
          this.copyData = JSON.parse(JSON.stringify(this.currentData))
          this.trashData.unshift(this.currentData)
          this.formData.splice(index, 1)
          if (index > 0) {
            this.currentData = this.formData[index - 1]
            this.currentKey = this.formData[index - 1].id
          } else {
            this.currentKey = ''
            this.currentData = {}
          }
        }
        e.preventDefault()
      }
      if (e.key === 'Delete') {
        if (!this.inForm) {
          return
        }
        if (index === -1) {
          e.preventDefault()
          return
        }
        this.formData.splice(index, 1)
        if (index > 0) {
          this.currentData = this.formData[index - 1]
          this.currentKey = this.formData[index - 1].id
        } else {
          this.currentKey = ''
          this.currentData = {}
        }
        e.preventDefault()
      }
    },
    cloneToMe(currentData) {
      if (this.loading) { return }
      this.loading = true
      this.copyShow = false
      saveMyFields('', currentData.field_label, currentData.field_type, currentData.field_data, currentData.is_required).then(res => {
        // this.currentData.id = res.data
        this.currentData.quick = false
        this.loading = false
        this.$notify({
          title: '复制成功',
          message: '已成功复制至我的组件',
          type: 'success'
        })
      }).catch(err => {
        this.loading = false
        this.$notify({
          title: '出错了',
          message: err.message,
          type: 'error'
        })
      })
    }
  }
})
</script>

<template>
  <div v-loading="loading" class="main-box">
    <div class="comp-lib">
      <div class="title">
        <div :class="['tab-item', CompType==='sys'?'active':'']" @click="CompType='sys'">系统组件</div>
        <div :class="['tab-item', CompType==='my'?'active':'']" @click="CompType='my'">我的组件</div>
        <div :class="['tab-item', CompType==='quick'?'active':'']" @click="CompType='quick'">快速组件</div>
      </div>
      <div v-permission="'preReg.editEdit'" class="list">
        <draggable v-model="CompType==='sys'?systemComp:CompType==='my'?customComp:quickComp" :options="{sort:false}" :group="{name:'form',put:false,pull:'clone'}" :clone="cloneItem" class="drag-list">
          <transition-group class="drag-cont">
            <div v-for="(element) in CompType==='sys'?systemComp:CompType==='my'?customComp:quickComp" :key="element.id" :style="{gridColumn:'span '+element.field_data.width}">
              <div v-if="element.field_type==='tips'" :class="[element.field_type,'form-item']">
                <div class="tips">{{ element.field_label }}</div>
              </div>
              <div v-if="element.field_type==='input'" :class="[element.field_type,'form-item']">
                <div class="tips">{{ element.field_label }}</div>
                <el-input v-model="element.field_data.value" :placeholder="element.field_data.placeholder" />
              </div>
              <div v-if="element.field_type==='email'" :class="[element.field_type,'form-item']">
                <div class="tips">{{ element.field_label }}</div>
                <div>
                  <el-input v-model="element.field_data.value" :placeholder="element.field_data.placeholder" />
                </div>
                <div class="code-input">
                  <el-input v-model="element.field_data.value" :placeholder="element.field_data.codePlaceholder" />
                  <el-button>获取验证码</el-button>
                </div>
              </div>
              <div v-if="element.field_type==='phone'" :class="[element.field_type,'form-item','select']">
                <div class="tips">{{ element.field_label }}</div>
                <div class="phone-input">
                  <el-select v-model="element.field_data.value" :placeholder="element.field_data.placeholder">
                    <el-option v-for="(item,index) in countryCode" :key="item.country_code+index" :value="item.phone_code" :label="'+'+item.phone_code+'('+item.chinese_name+')'" />
                  </el-select>
                </div>
              </div>
              <div v-if="element.field_type==='select'" :class="[element.field_type,'form-item']">
                <div class="tips">{{ element.field_label }}</div>
                <el-select v-model="element.field_data.value" :placeholder="element.field_data.placeholder">
                  <el-option v-for="item in element.field_data.options" :key="item.value" :label="item.label" :value="item.value" />
                </el-select>
              </div>
              <div v-if="element.field_type==='checkbox'" :class="[element.field_type,'form-item']">
                <div class="tips">{{ element.field_label }}</div>
                <el-checkbox-group v-model="element.field_data.value">
                  <el-checkbox v-for="item in element.field_data.options" :key="item.value" :label="item.label" />
                </el-checkbox-group>
              </div>
              <div v-if="element.field_type==='radio'" :class="[element.field_type,'form-item']">
                <div class="tips">{{ element.field_label }}</div>
                <el-radio-group v-model="element.field_data.value">
                  <el-radio v-for="item in element.field_data.options" :key="item.value" :label="item.label" />
                </el-radio-group>
              </div>
              <div v-if="element.field_type==='number'" :class="[element.field_type,'form-item']">
                <div class="tips">{{ element.field_label }}</div>
                <el-input-number v-model="element.field_data.value" :max="element.field_data.max" :min="element.field_data.min" :step="element.field_data.step" prefix-icon="el-icon-user" :placeholder="element.field_data.placeholder" />
              </div>
              <div v-if="element.field_type==='slider'" :class="[element.field_type,'form-item']">
                <div class="tips">{{ element.field_label }}</div>
                <el-slider v-model="element.field_data.value" :max="element.field_data.max" :min="element.field_data.min" :step="element.field_data.step" prefix-icon="el-icon-user" :placeholder="element.field_data.placeholder" />
              </div>
              <div v-if="element.field_type==='textarea'" :class="[element.field_type,'form-item']">
                <div class="tips">{{ element.field_label }}</div>
                <el-input v-model="element.field_data.value" type="textarea" :placeholder="element.field_data.placeholder" :autosize="{ minRows: element.field_data.minRows, maxRows: element.field_data.maxRows}" />
              </div>
              <div v-if="element.field_type==='region'" :class="[element.field_type,'form-item']">
                <div class="tips">{{ element.field_label }}</div>
                <el-cascader
                  :placeholder="element.field_data.placeholder"
                  size="large"
                  :options="element.field_data.range===2?pcTextArr:pcaTextArr"
                  value="element.field_data.value"
                />
              </div>
              <div v-if="element.field_type==='time'" :class="[element.field_type,'form-item']">
                <div class="tips">{{ element.field_label }}</div>
                <el-time-picker v-model="element.field_data.value" :placeholder="element.field_data.placeholder" />
              </div>
              <div v-if="element.field_type==='timeRange'" :class="[element.field_type,'form-item','view',{'active':element.id===hoverKey||element.id===currentKey}]">
                <div class="tips">{{ element.field_label }}</div>
                <el-time-picker v-model="element.field_data.value" is-range :start-placeholder="element.field_data.placeholder" :end-placeholder="element.field_data.endPlaceholder" :range-separator="element.field_data.rangeSeparator" />
              </div>
              <div v-if="element.field_type==='date'" :class="[element.field_type,'form-item']">
                <div class="tips">{{ element.field_label }}</div>
                <el-date-picker v-model="element.field_data.value" :placeholder="element.field_data.placeholder" />
              </div>
              <div v-if="element.field_type==='dateRange'" :class="[element.field_type,'form-item']">
                <div class="tips">{{ element.field_label }}</div>
                <el-date-picker v-model="element.field_data.value" type="daterange" :start-placeholder="element.field_data.placeholder" :end-placeholder="element.field_data.endPlaceholder" :range-separator="element.field_data.rangeSeparator" />
              </div>
            </div>
          </transition-group>
        </draggable>
      </div>
    </div>
    <div class="form-view" @mouseenter="inForm=true" @mouseleave="inForm=false">
      <div class="scroll-view">
        <div v-permission="'preReg.editEdit'" class="form-cont">
          <div :class="['form-head',getIndexByKey(currentKey) === -1?'active':'']" @click="currentKey=''">
            <div class="title">{{ formInfo.name }}</div>
            <div class="tips">{{ formInfo.desc }}</div>
          </div>
          <draggable v-model="formData" :group="{name:'form'}" :options="{sort:true,animation:300}" class="form-body" @start="handleStart" @end="handleEnd">
            <transition-group class="drag-cont">
              <div v-for="element in formData" :key="element.id" :style="{gridColumn:'span '+element.field_data.width}" :class="[element.is_required?'required':'']" @click="choseComp(element)" @mouseenter="hover(element)" @mouseleave="blur(element)">
                <div v-if="element.field_type==='tips'" :class="[element.field_type,'form-item','view',{'active':element.id===hoverKey||element.id===currentKey}]">
                  <div class="tips">{{ element.field_label }}</div>
                </div>
                <div v-if="element.field_type==='input'" :class="[element.field_type,'form-item','view',{'active':element.id===hoverKey||element.id===currentKey}]">
                  <div class="tips">{{ element.field_label }}</div>
                  <el-input :value="element.field_data.value" :placeholder="element.field_data.placeholder" />
                </div>
                <div v-if="element.field_type==='email'" :class="[element.field_type,'form-item','view',{'active':element.id===hoverKey||element.id===currentKey}]">
                  <div class="tips">{{ element.field_label }}</div>
                  <div>
                    <el-input v-model="element.field_data.value" :placeholder="element.field_data.placeholder" />
                  </div>
                  <div class="code-input">
                    <el-input v-model="element.field_data.value" :placeholder="element.field_data.codePlaceholder" />
                    <el-button>获取验证码</el-button>
                  </div>
                </div>
                <div v-if="element.field_type==='phone'" :class="[element.field_type,'form-item','select','view',{'active':element.id===hoverKey||element.id===currentKey}]">
                  <div class="tips">{{ element.field_label }}</div>
                  <div class="phone-input">
                    <el-select v-model="element.field_data.value" :placeholder="element.field_data.placeholder">
                      <el-option v-for="(item,index) in countryCode" :id="item.country_code+index" :label="'+'+item.phone_code+'('+item.chinese_name+')'" :value="item.country_code" />
                    </el-select>
                  </div>
                </div>
                <div v-if="element.field_type==='select'" :class="[element.field_type,'form-item','view',{'active':element.id===hoverKey||element.id===currentKey}]">
                  <div class="tips">{{ element.field_label }}</div>
                  <el-select v-model="element.field_data.value" :placeholder="element.field_data.placeholder">
                    <el-option v-for="item in element.field_data.options" :id="item.value" :label="item.label" :value="item.value" />
                  </el-select>
                </div>
                <div v-if="element.field_type==='checkbox'" :class="[element.field_type,'form-item','view',{'active':element.id===hoverKey||element.id===currentKey}]">
                  <div class="tips">{{ element.field_label }}</div>
                  <el-checkbox-group :value="element.field_data.value">
                    <el-checkbox v-for="item in element.field_data.options" :id="item.value" :label="item.label" />
                  </el-checkbox-group>
                </div>
                <div v-if="element.field_type==='radio'" :class="[element.field_type,'form-item','view',{'active':element.id===hoverKey||element.id===currentKey}]">
                  <div class="tips">{{ element.field_label }}</div>
                  <el-radio-group :value="element.field_data.value">
                    <el-radio v-for="item in element.field_data.options" :id="item.value" :label="item.label" />
                  </el-radio-group>
                </div>
                <div v-if="element.field_type==='number'" :class="[element.field_type,'form-item','view',{'active':element.id===hoverKey||element.id===currentKey}]">
                  <div class="tips">{{ element.field_label }}</div>
                  <el-input-number :value="element.field_data.value" :max="element.field_data.max" :min="element.field_data.min" :step="element.field_data.step" prefix-icon="el-icon-user" :placeholder="element.field_data.placeholder" />
                </div>
                <div v-if="element.field_type==='slider'" :class="[element.field_type,'form-item','view',{'active':element.id===hoverKey||element.id===currentKey}]">
                  <div class="tips">{{ element.field_label }}</div>
                  <el-slider :value="element.field_data.value" :max="element.field_data.max" :min="element.field_data.min" :step="element.field_data.step" prefix-icon="el-icon-user" :placeholder="element.field_data.placeholder" />
                </div>
                <div v-if="element.field_type==='textarea'" :class="[element.field_type,'form-item','view',{'active':element.id===hoverKey||element.id===currentKey}]">
                  <div class="tips">{{ element.field_label }}</div>
                  <el-input :value="element.field_data.value" type="textarea" :placeholder="element.field_data.placeholder" :autosize="{ minRows: element.field_data.minRows, maxRows: element.field_data.maxRows}" />
                </div>
                <div v-if="element.field_type==='region'" :class="[element.field_type,'form-item','view',{'active':element.id===hoverKey||element.id===currentKey}]">
                  <div class="tips">{{ element.field_label }}</div>
                  <el-cascader
                    :placeholder="element.field_data.placeholder"
                    size="large"
                    :options="element.field_data.range===2?pcTextArr:pcaTextArr"
                    :value="element.field_data.value"
                  />
                </div>
                <div v-if="element.field_type==='time'" :class="[element.field_type,'form-item','view',{'active':element.id===hoverKey||element.id===currentKey}]">
                  <div class="tips">{{ element.field_label }}</div>
                  <el-time-picker :value="element.field_data.value" :placeholder="element.field_data.placeholder" />
                </div>
                <div v-if="element.field_type==='timeRange'" :class="[element.field_type,'form-item','view',{'active':element.id===hoverKey||element.id===currentKey}]">
                  <div class="tips">{{ element.field_label }}</div>
                  <el-time-picker is-range :value="element.field_data.value" :start-placeholder="element.field_data.placeholder" :end-placeholder="element.field_data.endPlaceholder" :range-separator="element.field_data.rangeSeparator" />
                </div>
                <div v-if="element.field_type==='date'" :class="[element.field_type,'form-item','view',{'active':element.id===hoverKey||element.id===currentKey}]">
                  <div class="tips">{{ element.field_label }}</div>
                  <el-date-picker :value="element.field_data.value" :placeholder="element.field_data.placeholder" />
                </div>
                <div v-if="element.field_type==='dateRange'" :class="[element.field_type,'form-item','view',{'active':element.id===hoverKey||element.id===currentKey}]">
                  <div class="tips">{{ element.field_label }}</div>
                  <el-date-picker :value="element.field_data.value" type="daterange" :start-placeholder="element.field_data.placeholder" :end-placeholder="element.field_data.endPlaceholder" :range-separator="element.field_data.rangeSeparator" />
                </div>
              </div>
            </transition-group>
          </draggable>
        </div>
      </div>
    </div>
    <div class="comp-edit">
      <template v-if="getIndexByKey(currentKey) === -1">
        <div class="button">
          <el-popover
            v-model="copyFormShow"
            width="300"
            placement="bottom"
            trigger="click"
            title="确定复制表单？"
            popper-class="copy-popover"
          >
            <div class="body">
              <div class="content">
                <div>创建一个新的表单，并且将当前表单的组件复制到新表单中。</div>
              </div>
              <div class="button-list">
                <el-button size="mini" @click="copyFormShow=false">取消</el-button>
                <el-button v-permission="'preReg.copy'" type="primary" size="mini" @click="cloneForm()">复制</el-button>
              </div>
            </div>
            <el-button slot="reference" type="primary" icon="el-icon-document-copy" circle />
          </el-popover>
          <el-button v-permission="'preReg.save'" type="primary" @click="save">保存表单<span class="mini-text"> (Ctrl+S)</span></el-button>
        </div>
        <div class="title">表单设定</div>
        <div class="body">
          <div class="tips">表单名称</div>
          <el-input v-permission="'preReg.editName'" v-model="formInfo.name" placeholder="请输入表单名称" />
          <div class="tips">表单介绍</div>
          <el-input v-permission="'preReg.editDesc'" v-model="formInfo.desc" type="textarea" placeholder="请输入表单介绍" />
        </div>
      </template>
      <template v-else>
        <div />
        <div class="title">
          <span class="el-icon-arrow-left icon" @click="currentKey=''" />
          组件设定
        </div>
        <div class="body">

          <div class="tips">
            表单项介绍
            <guide
              video="/static/guide/表单项介绍.jpg"
              title="表单项介绍"
              text="展示在输入框上方的大段文本，用于介绍和提示该处应输入的内容。"
            />
          </div>
          <el-input v-model="currentData.field_label" type="textarea" placeholder="请输入表单项介绍" />

          <template>
            <div class="tips">是否必填</div>
            <el-switch v-model="currentData.is_required" :active-value="1" :inactive-value="0" />
          </template>

          <template v-if="['input','select','textarea','time','date','region','email','phone'].includes(currentData.field_type)">
            <div class="tips">
              提示文字
              <guide
                video="/static/guide/提示文字.jpg"
                title="提示文字"
                text="用户输入内容前，展示在输入框中的简短文本，用于提示该处应输入的内容。"
              />
            </div>
            <el-input v-model="currentData.field_data.placeholder" placeholder="请输入提示文字" />
          </template>

          <template v-if="['input','textarea'].includes(currentData.field_type)">
            <div class="tips">验证规则</div>
            <el-input v-model="currentData.field_data.pattern" :rows="3" type="textarea" placeholder="规则正则表达式" />
            <el-select v-model="currentData.field_data.pattern" class="pattern-select" placeholder="选择预设规则">
              <el-option label="不做判断" value="" />
              <el-option label="国内手机号" value="^1\d{10}$" />
              <el-option label="国内身份证号码" value="^[1-9]\d{5}(19\d{2}|20\d{2})((0[1-9])|(1[0-2]))((0[1-9])|([1-2]\d)|(3[0-1]))\d{3}(\d|X|x)$" />
              <el-option label="电子邮箱" value="^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$" />
            </el-select>
          </template>

          <template v-if="currentData.field_type==='region'">
            <div class="tips">
              地区范围
            </div>
            <el-radio-group v-model="currentData.field_data.range" size="small">
              <el-radio-button :label="2">省/市</el-radio-button>
              <el-radio-button :label="3">省/市/县</el-radio-button>
            </el-radio-group>
          </template>

          <template v-if="['timeRange','dateRange'].includes(currentData.field_type)">
            <div class="tips">
              起始提示文字
              <guide
                video="/static/guide/起始提示文字.jpg"
                title="起始提示文字"
                text="时间与日期类型组件输入内容前，显示在开始时间输入框中，用于提示的文字内容"
              />
            </div>
            <el-input v-model="currentData.field_data.placeholder" placeholder="请输入起始提示文字" />
            <div class="tips">
              结束提示文字
              <guide
                video="/static/guide/结束提示文字.jpg"
                title="结束提示文字"
                text="时间与日期类型组件输入内容前，显示在结束时间输入框中，用于提示的文字内容"
              />
            </div>
            <el-input v-model="currentData.field_data.endPlaceholder" placeholder="请输入结束提示文字" />
            <div class="tips">
              范围分隔符
              <guide
                video="/static/guide/范围分隔符.jpg"
                title="范围分隔符"
                text="时间与日期类型组件中，开始与结束提示文字中间的分隔文字。"
              />
            </div>
            <el-input v-model="currentData.field_data.rangeSeparator" placeholder="请输入范围分隔符" />
          </template>

          <template v-if="['select','radio','checkbox'].includes(currentData.field_type)">
            <div class="tips">
              选项设定
              <guide
                video="/static/guide/选项设定.mp4"
                title="选项设定"
                text="在单选、多选、选择器组件中，编辑可供用户选择的选择项目。"
              />
            </div>
            <div class="select-list">
              <div class="item">
                <draggable v-model="currentData.field_data.options" :options="{sort:true,animation:300}">
                  <transition-group class="select-inner">
                    <el-input v-for="(item,index) in currentData.field_data.options" :key="item.value" :value="item.label" disabled>
                      <div slot="prefix" class="handel">⠿</div>
                      <el-button slot="append" type="danger" icon="el-icon-delete" @click="removeSelectItem(index)" />
                    </el-input>
                  </transition-group>
                </draggable>
                <el-input v-model="selectInput" placeholder="请输入选项" @keyup.enter.native="addSelectItem">
                  <el-button slot="append" icon="el-icon-plus" @click="addSelectItem" />
                </el-input>
              </div>
            </div>
          </template>

          <template v-if="['number','slider'].includes(currentData.field_type)">
            <div class="tips">
              最小值
              <guide
                video="/static/guide/最小值.jpg"
                title="最小值"
                text="数字输入类型的组件中，限制可以输入的最小数字。"
              />
            </div>
            <el-input v-model="currentData.field_data.min" @change="currentData.field_data.value=$event-0" />
            <div class="tips">
              最大值
              <guide
                video="/static/guide/最大值.jpg"
                title="最大值"
                text="数字输入类型的组件中，限制可以输入的最大数字。"
              />
            </div>
            <el-input v-model="currentData.field_data.max" />
            <div class="tips">
              步进值
              <guide
                video="/static/guide/步进值.mp4"
                title="步进值"
                text="数字输入类型的组件中，限制输入的数字为多少的倍数。"
              />
            </div>
            <el-input v-model="currentData.field_data.step" />
          </template>

          <div class="tips">
            组件宽度
            <guide
              video="/static/guide/组件宽度.mp4"
              title="组件宽度"
              text="设置所选定组件的宽度，有1/3、1/2、2/3、占据全部宽度，总共四种尺寸供选择。"
            />
          </div>
          <el-radio-group v-model="currentData.field_data.width" size="small">
            <el-radio-button :label="2">窄</el-radio-button>
            <el-radio-button :label="3">中</el-radio-button>
            <el-radio-button :label="4">宽</el-radio-button>
            <el-radio-button :label="6">长</el-radio-button>
          </el-radio-group>

        </div>
        <div class="button">
          <el-popover
            v-model="copyShow"
            width="300"
            placement="bottom"
            trigger="click"
            title="确定保存为我的组件？"
            popper-class="copy-popover"
          >
            <div class="body">
              <div class="content">
                <div>创建一个新的我的组件，并且保存当前的组件数据。</div>
              </div>
              <div class="button-list">
                <el-button size="mini" @click="copyShow=false">取消</el-button>
                <el-button v-permission="'preReg.saveCompEdit'" type="primary" size="mini" @click="cloneToMe(currentData)">复制</el-button>
              </div>
            </div>
            <el-button slot="reference" type="primary" icon="el-icon-folder-add" circle />
          </el-popover>
          <el-button type="danger" @click="removeComp(currentData)">删除组件<span class="mini-text"> (Delete)</span></el-button>
        </div>
      </template>
    </div>
    <div :class="['trash-bin',isDrag?'':'hide']">
      <div class="trash-inner">
        <draggable v-model="trashData" :group="{name:'form'}" :options="{sort:false,animation:300}" :class="['trash-cont',trashData.length?'':'hide']">
          <transition-group class="drag-cont">
            <div v-for="element in trashData" :key="element.id" class="form-item view">
              <div class="tips">{{ element.field_label }}</div>
              <div class="del el-icon-delete" @click="removeTrash(element)" />
            </div>
          </transition-group>
        </draggable>
      </div>
      <div class="text">回收站</div>
    </div>
  </div>
</template>

<style scoped>
  .main-box{
    position: relative;
    overflow: hidden;
    padding: 0 !important;
    height: 100%;
    width: 100%;
    display: grid;
    grid-template-columns: 360px 1fr 360px;
    grid-template-rows: 1fr;
    .mini-text{
      font-size: 13px;
    }
    .form-item{
      cursor: grab;
      background: white;
      margin-bottom: -1px;
      border-top: 1px solid lightgrey;
      border-bottom: 1px solid lightgrey;
      padding: 24px;
      .tips{
        font-size: 15px;
        color: #989898;
        margin-bottom: 8px;
      }
      &.email{
        .code-input{
          display: flex;
          grid-gap: 8px;
          margin-top: 8px;
        }
      }
      &.phone{
        .phone-input{
          display: flex;
          grid-gap: 8px;
        }
      }
      &.select{
        .el-select{
          width: 100%;
        }
      }
      &.number{
        .el-input-number{
          width: 100%;
        }
      }
      &.time,&.timeRange{
        .el-date-editor{
          width: 100%;
        }
      }
      &.date,&.dateRange{
        .el-date-editor{
          width: 100%;
        }
      }
      &.region{
        .el-cascader{
          width: 100%;
        }
      }
      &.view{
        transition-duration: 300ms;
        border-radius: 8px;
        border: 3px solid #2563EB00;
        padding: 12px 12px;
        margin-bottom: 0;
        &.tips{
          padding: 12px 12px;
        }
        &.active{
          border: 3px solid #2563EB;
        }
      }
    }
    .trash-bin{
      box-shadow: -4px 8px 12px 0 #00000044;
      padding: 8px;
      position: absolute;
      border-radius: 32px 32px 0 0;
      z-index: 3;
      right: 200px;
      bottom: 0;
      width: 360px;
      height: 150px;
      background: lightgrey;
      transition-duration: 300ms;
      .trash-inner{
        position: relative;
        outline: #e4e4e4 5px solid;
        border-radius: 24px;
        width: 100%;
        height: 60px;
        background-image: linear-gradient( #b3b3b3, #2b2b2b);
        .trash-cont{
          overflow: hidden;
          border-radius: 24px;
          position: absolute;
          width: 100%;
          height: 200%;
          left: 0;
          bottom: 0;
          &.hide{
            height: 100%;
          }
          .drag-cont{
            padding: 6px 12px 0;
            overflow: hidden;
            overflow-y: scroll;
            display: block;
            width: calc(100% + 20px);
            height: 100%;
            .form-item{
              position: sticky;
              left: 0;
              top: 0;
              border-bottom-right-radius: 0;
              border-bottom-left-radius: 0;
               border: 1px solid lightgrey;
              height: 100%;
              .del{
                position: absolute;
                right: 16px;
                top: 16px;
                cursor: pointer;
              }
            }
          }
        }
      }
      .text{
        width: 100%;
        text-align: center;
        margin-top: 16px;
        font-size: 36px;
        font-weight: bold;
        color: gray;
        text-shadow: 4px 4px 4px 4px #ffffff;
      }
      &.hide{
        bottom: -160px;
      }
      &:hover{
        bottom: -60px;
      }
    }
    .comp-lib{
      z-index: 1;
      position: relative;
      display: grid;
      grid-template-rows: auto 1fr;
      box-shadow: 0 1px 4px 0 #00000022;
      .title{
        display: flex;
        padding: 24px 24px 16px;
        .tab-item{
          cursor: pointer;
          padding: 0 4px;
          position: relative;
          transition-duration: 300ms;
          color: grey;
          &::after{
            transition-duration: 300ms;
            content: '';
            display: block;
            position: relative;
            width: 60%;
            margin-left: 20%;
            height: 5px;
            border-radius: 3px;
            background-color: #2563EB00;
          }
          &:hover{
            &::after{
              background-color: gray;
            }
          }
          &.active{
            font-weight: bold;
            color: black;
            &::after{
              width: 80%;
              margin-left: 10%;
              background-color: #2563EBFF;
            }
          }
        }
      }
      .list{
        position: relative;
        .drag-list{
          position: absolute;
          top: 0;
          left: 0;
          height: 100%;
          width: 100%;
          overflow: hidden;
          overflow-y: auto;
          .drag-cont{
            width: 100%;
            height: 100%;
            display: block;
          }
        }
      }
    }
    .form-view{
      position: relative;
      background: #F9FAFB;
      .scroll-view{
        position: absolute;
        left: 0;
        top: 0;
        height: 100%;
        width: 100%;
        overflow: hidden;
        overflow-y: scroll;
        .form-cont{
          padding: 12px;
          border-radius: 16px;
          margin: 24px;
          background: white;
          width: calc(100% - 48px);
          box-shadow: 0 1px 4px 0 #00000022;
          .form-head{
            padding: 12px;
            border-radius: 8px;
            transition-duration: 300ms;
            border: 3px solid #2563EB00;
            &:hover,&.active{
              border: 3px solid #2563EB;
            }
            .title{
              font-size: 36px;
              font-weight: bold;
            }
            .tips{
              font-size: 20px;
              color: #989898;
              margin-bottom: 6px;
            }
          }
          .form-body{
            .drag-cont{
              display: grid;
              grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr;
              width: 100%;
              min-height: 300px;
              align-content: start;
              .form-item{
                height: fit-content;
              }
              .required{
                .tips{
                  &::after{
                    margin-left: 4px;
                    content: '*';
                    color: red;
                  }
                }
              }
            }
          }
        }
      }
    }
    .comp-edit{
      z-index: 1;
      position: relative;
      box-shadow: 0 1px 4px 0 #00000022;
      display: grid;
      grid-template-rows: auto auto 1fr auto;
      .body{
        padding: 0 16px;
        display: flex;
        flex-direction: column;
        align-items: flex-end;
        .tips{
          width: 100%;
          font-size: 16px;
          color: #505050;
          margin-bottom: 6px;
          margin-top: 12px;
        }
        .pattern-select{
          margin-top: 6px;
          width: 100%;
        }
        .select-list{
          width: 100%;
          .handel{
            height: 100%;
            display: flex;
            align-items: center;
          }
          .select-inner{
            .el-input__inner{
              cursor: grab;
            }
          }
        }
      }
      .button{
        display: flex;
        gap: 12px;
        justify-content: flex-end;
        padding: 16px;
      }
      .title{
        padding: 16px;
        display: flex;
        align-items: center;
        .icon{
          margin-left: -4px;
          margin-top: -4px;
          margin-right: 8px;
          font-size: 24px;
          cursor: pointer;
          padding: 4px;
          border-radius: 8px;
          transition-duration: 300ms;
          &:hover{
            color: #2563EB;
            background: #ececec;
          }
        }
      }
    }
  }
</style>
<style>
.copy-popover{
  .body{
    .content{
      margin-bottom: 24px;
    }
    .button-list{
      display: flex;
      justify-content: flex-end;
    }
  }
}
</style>
