<template>
  <app-dialog
    v-model="visible"
    :loading="loading"
    :title="title"
    append-to-body
    class="detail-dialog"
    fullscreen
    hide-footer
    @cancel="onCancel"
    @confirm="onConfirm"
  >
    <div v-if="data" class="page-view border-radius-5 h-100 flex-col overflow-h">
      <div class="page-view border-radius-5 h-100 bg-white pa-11 flex-col">
        <div class="mb-10 flex flex-gap-10">
          <el-button type="primary" @click="addAttrRows">
            <el-tooltip class="item" content="按F2可快速添加字段" effect="dark" placement="top">
              <i class="icon-question" style="margin-right: 8px" />
            </el-tooltip>
            添加字段
          </el-button>

          <el-popover v-if="data.deployedStatus !== '1'" v-model="uploadVisible" placement="bottom" trigger="hover">
            <p>请先下载模板，填写完成后上传</p>
            <div class="text-c flex-row-c">
              <el-button class="mr-10" plain type="primary" @click="download">下载模板</el-button>
              <el-upload
                ref="upload"
                :action="actionUrl"
                :before-upload="beforeUpload"
                :data="importData"
                :headers="headers"
                :multiple="false"
                :on-error="handleError"
                :on-success="handleSuccess"
                :show-file-list="false"
              >
                <el-button size="mini" type="primary">导入字段</el-button>
              </el-upload>
            </div>
            <el-button slot="reference" :loading="uploadLoading" class="ml-10" icon="el-icon-upload2" type="primary">
              导入字段
            </el-button>
          </el-popover>
        </div>
        <div class="flex-1 overflow-h">
          <el-form ref="form" :model="form" :rule="fieldsRules" class="h-100" size="medium">
            <el-table ref="attrTableScrollbarHeight" v-loading="tableLoading" :data="form.attrData" border height="100%"
                      style="width: 100%">
              <el-table-column align="center" fixed="left" label="序号" type="index" width="50" />
              <el-table-column align="center" fixed="left" label="名称" min-width="160" resizable>
                <template v-slot="{ row, $index }">
                  <el-form-item :prop="`attrData.${$index}.name`" :rules="fieldsRules.name">
                    <el-input v-model="row.name" placeholder="请输入" />
                  </el-form-item>
                </template>
              </el-table-column>
              <el-table-column align="center" fixed="left" label="编码" min-width="160" resizable>
                <template v-slot="{ row, $index }">
                  <el-form-item :prop="`attrData.${$index}.code`" :rules="fieldsRules.code">
                    <el-input v-model="row.code" placeholder="请输入" />
                  </el-form-item>
                </template>
              </el-table-column>
              <el-table-column align="center" label="描述" min-width="180" resizable>
                <template v-slot="{ row, $index }">
                  <el-form-item :prop="`attrData.${$index}.desc`" :rules="fieldsRules.desc">
                    <el-input v-model="row.desc" placeholder="请输入" />
                  </el-form-item>
                </template>
              </el-table-column>
              <!--              <el-table-column align="center" label="UI组件" min-width="120" resizable>-->
              <!--                <template v-slot="{ row, $index }">-->
              <!--                  <el-form-item :prop="`attrData.${$index}.UiComCode`" :rules="fieldsRules.UiComCode">-->
              <!--                    <el-select v-model="row.UiComCode" placeholder="请选择"-->
              <!--                               @change="val => changeUIType(val, row, $index)"-->
              <!--                    >-->
              <!--                      <el-option v-for="item in getDictionaryByCode('UIzjlx')" :key="item.value" :label="item.name"-->
              <!--                                 :value="item.value"-->
              <!--                      />-->
              <!--                    </el-select>-->
              <!--                  </el-form-item>-->
              <!--                </template>-->
              <!--              </el-table-column>-->
              <el-table-column align="center" label="数据类型" resizable>
                <el-table-column align="center" label="类型" min-width="120" resizable>
                  <template v-slot="{ row, $index }">
                    <el-form-item :prop="`attrData.${$index}.dataType`" :rules="fieldsRules.dataType">
                      <el-select
                        v-model="row.dataType"
                        :disabled="data.deployedStatus === '1' && !!row.id"
                        placeholder="请选择"
                        @change="(val) => changeDataType(val, row, $index)"
                      >
                        <el-option v-for="item in getDictionaryByCode('gxzdlx')" :key="item.value" :label="item.name"
                                   :value="item.value" />
                      </el-select>
                    </el-form-item>
                  </template>
                </el-table-column>
                <el-table-column align="center" label="字段长度" min-width="100" resizable>
                  <template v-slot="{ row, $index }">
                    <el-form-item v-if="row.dataType !== 'datetime'" :prop="`attrData.${$index}.attrLength`"
                                  :rules="fieldsRules.attrLength">
                      <el-input v-model.number="row.attrLength" placeholder="请输入" type="number" />
                    </el-form-item>
                  </template>
                </el-table-column>
              </el-table-column>
              <el-table-column align="center" fixed="right" label="操作" width="100">
                <template v-slot="{ row, $index }">
                  <el-dropdown
                    v-if="form.attrData.length > 0"
                    size="mini"
                    split-button
                    @click="handleDelete({ command: 'del', index: $index, row }, data.deployedStatus === '1')"
                    @command="handleCommand"
                  >
                    <i v-if="data.deployedStatus === '1' && row.id" class="el-icon-sort" />
                    <i v-else class="el-icon-delete-solid" />
                    <el-dropdown-menu slot="dropdown">
                      <el-dropdown-item :command="{ command: 'up', row, index: $index }"
                                        :disabled="$index == 0 ? true : false">
                        上升
                        <i class="el-icon-arrow-up" />
                      </el-dropdown-item>
                      <el-dropdown-item :command="{ command: 'down', row, index: $index }"
                                        :disabled="$index == form.attrData.length - 1 ? true : false">
                        下降
                        <i class="el-icon-arrow-down" />
                      </el-dropdown-item>
                    </el-dropdown-menu>
                  </el-dropdown>
                  <el-button v-else class="el-icon-delete-solid" disabled plain size="mini" />
                </template>
              </el-table-column>
            </el-table>
          </el-form>
        </div>
      </div>
      <div class="mt-11 text-c">
        <el-button :loading="loading || tableLoading || uploadLoading" type="primary" @click="onConfirm"> 保存
        </el-button>
        <el-button :loading="loading || tableLoading || uploadLoading" plain type="info" @click="visible = false">
          关闭
        </el-button>
      </div>
    </div>
  </app-dialog>
</template>

<script>
import dialogMixin from '@/mixins/dialog.js'
import utils from '@/hotent-ui-util.js'
import {getDictionaryByCode} from '@/utils/dictionary.js'
import API from '@/api/business/shareDataCatalog'
import {mapState} from 'vuex'

export default {
  name: 'FieldsManage',
  mixins: [dialogMixin],
  props: {
    data: {
      type: Object,
      default: () => ({})
    }
  },
  data() {
    var checkey = (rule, value, callback) => {
      if (!value) {
        return callback(new Error('字段编码不能为空'))
      } else {
        if (this.form.attrData.filter((item) => item.code === value).length > 1) {
          callback(new Error('字段编码不能重复!'))
        } else {
          callback()
        }
      }
    }
    return {
      fieldsRules: {
        name: [
          {
            required: true,
            message: '字段名称不能为空',
            trigger: 'blur'
          }
        ],
        code: [
          {
            required: true,
            message: '字段编码不能为空',
            trigger: 'blur'
          },
          {
            pattern: /^[a-zA-Z][a-zA-Z0-9_]*$/,
            message: '以字母开头的字母、数字、下划线组合',
            trigger: ['change', 'blur']
          },
          {validator: checkey, trigger: 'blur'}
        ]
      },
      form: {attrData: []},
      importData: {tableId: ''},
      index: null,
      tabelData: null,
      tableLoading: false,
      uploadLoading: false,
      uploadVisible: false,
      loading: false
    }
  },
  mounted() {
    document.onkeydown = () => {
      if (this.form.attrData) {
        const key = window.event.keyCode
        if (key == 113) {
          // == 83 && event.ctrlKey
          this.addAttrRows()
          setTimeout(() => {
            this.$refs.attrTableScrollbarHeight.bodyWrapper.scrollTop = this.$refs.attrTableScrollbarHeight.bodyWrapper.scrollHeight
          }, 500)
        }
      }
    }
  },
  computed: {
    actionUrl: (_) => `${window.context.portal}/biz/dataShare/shareTableField/v1/importFile`,
    ...mapState({
      headers: (state) => ({
        Authorization: `Bearer ${state.login.currentUser.token}`
      })
    })
  },
  methods: {
    initData(data) {
      this.tabelData = data
      this.importData.tableId = data.id
      this.getFieldsByTable()
    },
    async getFieldsByTable() {
      this.tableLoading = true
      try {
        const param = new FormData()
        param.append('id', this.data.id)
        const {value} = await API.getFieldsList(param)
        if (value.tableFieldList && value.tableFieldList.length) {
          this.form.attrData = value.tableFieldList.filter((item) => item.fieldType === '2')
          this.form.attrData.sort((a, b) => a.sn - b.sn)
        }
      } catch (err) {
        this.$message.warning(err || '资源项字段查询失败！')
      } finally {
        this.tableLoading = false
      }
    },
    getDictionaryByCode,
    // 新增字段
    addAttrRows() {
      const last = this.form.attrData[this.form.attrData.length - 1]
      const sn = last && last.sn ? last.sn + 1 : 1
      const row = {
        tableId: this.tabelData.id,
        code: '',
        name: '',
        desc: '',
        fieldType: '2',
        isInitFiled: 'N',
        isPk: '0',
        isRequired: '0',
        // UiComCode: 'input',
        dataType: 'varchar',
        defaultValue: '',
        format: '',
        fieldValueType: '1',
        dimensionId: '',
        unit: '',
        attrLength: 200,
        decimalLen: 0,
        isEncrypt: '0',
        isEdit: '0',
        isDesensitize: '0',
        index: this.form.attrData.length + 1
      }
      sn ? (row.sn = sn) : null
      this.form.attrData.splice(this.form.attrData.length, 0, row)
    },

    // UI类型切换设置默认值
    changeUIType(val, row, index) {
      if (this.data.deployedStatus !== '1' && !row.id) {
        row.dataType = 'varchar'
      }
      row.dataType = 'varchar'
      row.format = ''
      row.fieldValueType = '1'
      if (val === 'date') {
        if (this.data.deployedStatus !== '1' && !row.id) {
          row.dataType = 'date'
        }
        row.format = 'yyyy-MM-dd'
      } else if (val === 'datetime') {
        if (this.data.deployedStatus !== '1' && !row.id) {
          row.dataType = 'datetime'
        }
        row.format = 'yyyy-MM-dd HH:mm:ss'
      } else if (val === 'select' || val === 'checkbox' || val === 'radio') {
        row.fieldValueType = '2'
      }
      this.form.attrData.splice(index, 1, row)
    },

    // 数据类型切换设置默认值
    changeDataType(val, row, index) {
      row.attrLength = 0
      row.decimalLen = 0
      row.format = ''
      row.fieldValueType = '1'
      row.dimensionId = ''
      if (val === 'date') {
        row.format = 'yyyy-MM-dd'
      } else if (val === 'datetime') {
        row.format = 'yyyy-MM-dd HH:mm:ss'
      } else if (val === 'varchar') {
        row.attrLength = 200
      } else if (val === 'number') {
        row.attrLength = 10
        row.decimalLen = 2
      }
      this.form.attrData.splice(index, 1, row)
    },

    handleDelete(param, deployed) {
      if (deployed && param.row.id) return
      this.handleCommand(param)
    },

    handleCommand(param) {
      switch (param.command) {
        case 'del':
          this.deleteAttrRows(param.row, param.index)
          break
        case 'up':
          this.attrUp(param.row, param.index)
          break
        case 'down':
          this.attrDown(param.row, param.index)
          break
        default:
          break
      }
    },

    // 删除字段
    deleteAttrRows(row, index) {
      if (row.isInitFiled === 'Y') {
        this.$message.warning('该字段为初始字段，不可删除！')
        return
      }
      this.form.attrData.splice(index, 1)
    },
    attrUp(row, index) {
      this.form.attrData[index].index = this.form.attrData[index].index - 1
      this.form.attrData[index].sn = this.form.attrData[index - 1].sn
      this.form.attrData[index - 1].index = this.form.attrData[index - 1].index + 1
      this.form.attrData[index - 1].sn = this.form.attrData[index - 1].sn + 1
      this.form.attrData = utils.arrayMove(this.form.attrData, row, 'up')
    },
    attrDown(row, index) {
      this.form.attrData[index].index = this.form.attrData[index].index + 1
      this.form.attrData[index].sn = this.form.attrData[index].sn + 1
      this.form.attrData[index + 1].index = this.form.attrData[index + 1].index - 1
      this.form.attrData[index + 1].sn = this.form.attrData[index].sn - 1
      this.form.attrData = utils.arrayMove(this.form.attrData, row, 'down')
    },

    onCancel() {
      this.visible = false
      this.form.attrData = []
    },
    onConfirm() {
      this.$refs.form.validate(async (valid, object) => {
        if (valid) {
          this.loading = true
          const params = {
            tableFieldList: this.form.attrData,
            // table: this.data,
            id: this.data.id
            // ...this.data,
          }

          try {
            if (this.data.deployedStatus === '1') {
              await API.saveOrUpdateFields(this.form.attrData)
            } else {
              await API.saveFields(params)
            }

            this.$message.success('字段保存成功')
            this.visible = false
            this.$emit('confirm')
          } catch (err) {
            this.$message.warning(err || '操作失败')
          } finally {
            this.loading = false
          }
        } else {
          this.$message.warning(`有${Object.keys(object).length}个字段未通过校验，请正确填写表单。`)
          this.loading = false
        }
      })
    },
    download() {
      const fileName = '数据提供方-数据字段清单.xlsx'
      // const file = `./file/download/${fileName}`;
      const file = window.context.download + fileName
      const a = document.createElement('a')
      a.href = file
      a.download = fileName // 设置下载文件文件名
      a.style.display = 'none'
      document.body.appendChild(a)
      a.click()
      a.remove()
    },
    //  导入文件上传前
    beforeUpload(file) {
      this.uploadVisible = false
      return new Promise((resolve, reject) => {
        this.uploadLoading = true
        const {name} = file
        this.$confirm(`请确认是否导入 “${name}” ？`, '提示', {
          confirmButtonText: '确认',
          cancelButtonText: '取消',
          type: 'warning'
        })
          .then((_) => {
            let passedOrNot = true // 是否通过验证
            const typeRegular = /\.(xls|xlsx)$/i
            const verification = [
              {
                condition: !typeRegular.test(name),
                result: () => this.$message.error('只能上传xls或xlsx文件类型')
              }
            ]
            verification.forEach((item) => {
              if (item.condition) {
                item.result()
                passedOrNot = false
                this.uploadLoading = false
              }
            })

            passedOrNot ? resolve() : reject()
          })
          .catch((_) => {
            reject()
            this.uploadLoading = false
            this.$message.warning('已取消上传')
          })
      })
    },

    // 导入文件上传成功
    async handleSuccess(res) {
      if (res.state) {
        this.$message.success('导入成功')
        this.uploadLoading = false
        await this.getFieldsByTable()
      } else {
        this.$message.error(res.message)
      }
    },

    // 导入文件上传失败
    handleError() {
      this.$message.error('导入失败，请重试')
      this.uploadLoading = false
    }
  }
}
</script>

<style lang="scss" scoped>
@import '@/assets/css/element-variables.scss';

.table__body_wrapper {
  flex: 1;
  height: calc(100% - 45px);
}

::v-deep .el-table td.el-table__cell {
  padding: 0;
}

::v-deep .el-form-item {
  margin: 18px 0;
}
</style>
