<!--
 * @Author: wlo_o
 * @Date: 2022-02-16 11:37:04
 * @LastEditors: Jone
 * @LastEditTime: 2022-07-11 14:49:53
 * @FilePath: /frontend/lib/components/MdElementForm.vue
 * @Description: 元素新增、修改页面
 *
 * Copyright (c) 2022 by 青岛百洋智能科技股份有限公司, All Rights Reserved.
-->
<template>
  <div
    class="oecp-md-element-form"
    style="height: 100%;overflow:auto"
  >
    <div
      v-if="showHeader||showGoBack"
      class="oecp-component-header flex flex-between"
      style="align-items:end;padding-bottom: 10px;height: 38px;box-sizing: content-box;line-height: 38px;"
    >
      <div>
        <template v-if="showGoBack">
          <el-page-header
            @back="goBack"
            title=''
          >
            <div slot="content">
              <template v-if="!!$slots.title">
                <slot name="title"></slot>
              </template>
              <div
                v-else-if="!!title"
                class="title-style"
              >
                <img
                  v-if="$attrs.icon && $attrs.icon == '../common/img/source.png'"
                  src="../common/img/source.png"
                />
                <img
                  v-else-if="$attrs.icon && $attrs.icon == '../common/img/add.png'"
                  src="../common/img/add.png"
                />
                <img
                  v-else-if="$attrs.icon && $attrs.icon == '../common/img/edit.png'"
                  src="../common/img/edit.png"
                />
                <img
                  v-else-if="$attrs.icon && $attrs.icon == '../common/img/metaData.png'"
                  src="../common/img/metaData.png"
                />
                {{title}}
              </div>
              <div v-else>&nbsp;</div>
            </div>
          </el-page-header>
        </template>
        <template v-else>
          <template v-if="!!$slots.title">
            <slot name="title"></slot>
          </template>
          <div
            v-else-if="!!title"
            class="title-style"
          >
            <img
              v-if="$attrs.icon && $attrs.icon == '../common/img/source.png'"
              src="../common/img/source.png"
            />
            <img
              v-else-if="$attrs.icon && $attrs.icon == '../common/img/add.png'"
              src="../common/img/add.png"
            />
            <img
              v-else-if="$attrs.icon && $attrs.icon == '../common/img/edit.png'"
              src="../common/img/edit.png"
            />
            <img
              v-else-if="$attrs.icon && $attrs.icon == '../common/img/metaData.png'"
              src="../common/img/metaData.png"
            />
            {{title}}
          </div>
          <div v-else>&nbsp;</div>
        </template>
      </div>
      <div v-show="editable&&showSaveBtn">
        <el-row
          type="flex"
          justify="end"
        >
          <!-- <el-button
            v-oecp-auth:[{type}]="'elementForm.save'"
            :loading="loading"
            :icon="stateId?'el-icon-edit':'el-icon-plus'"
            @click="handleSave"
            type="primary"
            size="medium"
          >{{submitBtnText}}</el-button> -->
        </el-row>
      </div>
      <el-divider
        v-if="showHeader||showGoBack"
        class="oecp-divider"
      />
    </div>
    <el-row style="flex:1;background:#fff;overflow: auto;border-radius: 6px;">
      <el-col
        :span="9"
        style="height: 100%;overflow: auto"
      >
        <md-element-value-list
          class="backgroundWhite"
          v-if="showValuesTable"
          :id="stateId"
          :editable="editable"
        />
        <md-category
          class="backgroundWhite"
          v-if="showCategory"
          :type="type"
          :disabled="!editable||!stateId"
          :displayType="editable?'input':'tag'"
          :showExpand="false"
          :values="categoryIds"
          @click="handleTagClick"
        >
          <h4
            slot="title"
            class="tag-style"
          >{{editable?'添加':''}}标签</h4>
        </md-category>
      </el-col>
      <el-col :span="15">
        <div
          v-loading="loading"
          class="backgroundWhite"
          style="padding-top:40px;padding-left: 30px;"
        >
          <el-row>
            <ele-form
              v-bind="formConfig"
              v-model="formData"
              label-position="right"
              ref="form"
            />
          </el-row>
          <el-row v-if="extFormConfig">
            <ele-form
              v-bind="extFormConfig"
              v-model="extData"
              label-position="right"
              ref="ext"
            />
          </el-row>
          <div class="btnBox flex flex-center">
            <el-button
              v-oecp-auth:[{type}]="'elementForm.save'"
              class="addBtn"
              :loading="loading"
              @click="handleSave"
              type="primary"
              size="medium"
            >
              <img src="../common/img/save.png" />{{submitBtnText}}
            </el-button>
          </div>
        </div>
      </el-col>
    </el-row>

  </div>
</template>
<script>
import { fetchApi } from '../common/apis'
import pick from 'lodash/pick'
import isObject from 'lodash/isObject'
import isArray from 'lodash/isArray'
import isEmpty from 'lodash/isEmpty'
import get from 'lodash/get'
import OptionsMixin from '../mixins/OptionsMixin'
import RouterMixin from '../mixins/RouterMixin'
import FormMixin from '../mixins/FormMixin'
import EventMixin from '../mixins/EventMixin'

export default {
  mixins: [OptionsMixin, RouterMixin, FormMixin, EventMixin],
  props: {
    showCategory: { type: Boolean, default: true },
    copyFormId: { type: [String, null], default: null },
  },
  computed: {
    submitBtnText: function () {
      return '保存' // this.stateId ? '保存' : '保存'
    },
    showValuesTable: function () {
      let list = get(this.getMbOptionVar('typeConfig'), 'list') || []
      let { type } = this
      let item = list.find(o => o.type === type)
      let bol = get(item, 'showValues')
      return bol
    },
  },
  watch: {
    id(id) {
      this.stateId = id
    },
    stateId(id) {
      this.loadData()
    },
    type(type) {
      this.loadData()
    },
  },
  methods: {
    updateFormConfig() {
      let { defaultFormConfig } = this
      let formConfig = {
        ...defaultFormConfig,
        formDesc: {
          name: { type: 'input', label: '名称', required: true, attrs: { size: 'small' } },
          code: { type: 'input', label: '编码', required: true, attrs: { readonly: true, size: 'small' }, vif: data => !!data.id },
          internalCode: { type: 'input', required: true, attrs: { size: 'small' }, label: '内部标识符', vif: () => 1 === 2 }, // 暂时不要内部标识符
          sourceCode: {
            type: 'text',
            label: '来源标识符',
            attrs: { readonly: true, size: 'small' },
            vif: data => !!data.id,
            displayFormatter: v => (!v ? '——————' : v),
          },
          sourceFileName: { type: 'input', label: '来源文件名', attrs: { size: 'small' } },
          sourceFileCode: { type: 'input', label: '来源文件编码', attrs: { size: 'small' } },
          keyword: { type: 'input', label: '关键词', attrs: { size: 'small' } },
        },
        order: ['name', 'code', 'internalCode', 'sourceCode', 'sourceFileCode', 'sourceFileName', 'keyword'],
      }
      let filterFormConfig =
        get(this, '$OecpMetaDataConfig.filterFormConfig') ||
        function (params) {
          return params
        }
      formConfig = filterFormConfig(formConfig, this.type)
      this.formConfig = formConfig
    },
    clearData() {
      this.formData = {}
      this.extData = {}
      this.extList = []
      this.categoryIds = []
      let mainform = get(this, '$refs.form')
      let extForm = get(this, '$refs.ext')
      mainform && mainform.resetForm() // 规避dom未初始化调用时报错
      extForm && extForm.resetForm() // 规避dom未初始化调用时报错
    },
    loadFormData() {
      let that = this
      fetchApi
        .call(this, '/element/find', { id: this.stateId })
        .then(res => {
          that.formData = pick(res, ['id', ...Object.keys(that.formConfig.formDesc)])
          that.extList = get(res, 'ext') || []
          that.extData = that.extArray2FormData(that.extList, that.extFormConfig)
        })
        .finally(() => {
          that.loading = false
        })
    },
    loadData() {
      let that = this
      let { stateId: id, formConfig, extFormConfig, defaultData } = this
      console.log(extFormConfig)
      this.clearData()
      if (id) {
        this.loading = true
      } else {
        if (!isEmpty(defaultData)) {
          that.formData = {
            ...that.formData,
            ...pick(defaultData, Object.keys(formConfig.formDesc)),
          }
          isEmpty(extFormConfig) &&
            (that.extData = {
              ...that.extData,
              ...pick(defaultData, Object.keys(extFormConfig.formDesc)),
            })
        }
        if (this.copyFormId) {
          fetchApi
            .call(this, '/element/find', { id: this.copyFormId })
            .then(res => {
              let fields = Object.keys(that.formConfig.formDesc)
              that.formData = {
                ...pick(
                  res,
                  fields.filter(k => !['id', 'code'].includes(k)),
                ),
                ...that.formData,
              }
              that.extList = get(res, 'ext') || []
              that.extData = that.extArray2FormData(that.extList, that.extFormConfig)
            })
            .finally(() => {
              that.loading = false
            })
        }
        return
      }
      this.loadFormData()
      this.showCategory && this.loadCategoryList()
    },
    // 扩展数据更新，将表单数据格式化成列表数据格式  { "definition": "标识" } -> {"extName": "definition", "extValue": "标识"}
    // 注意：只处理模版配置中显示的字段。未在模版内配置的不参与处理
    extFormData2Array() {
      let { extData = {}, extList = [], extFormConfig, stateId: parentId } = this
      let newExtList = []
      // key: extName value: extRowData
      let extDataKv = extList.reduce((rs, o) => {
        return { ...rs, ...(o.extName && { [o.extName]: o }) }
      }, {})
      let keys = Object.keys(extFormConfig.formDesc || {}) // 只处理模版内配置的扩展字段
      keys.forEach(key => {
        let { type } = extFormConfig.formDesc[key]
        if (['text', 'button'].includes(type)) return // 排除掉静态文本和按钮控件
        let extValue = extData[key] === null || extData[key] === undefined ? '' : extData[key]
        if (isObject(extValue) || isArray(extValue)) {
          // 上传控件、多选控件等格式是数组或者复杂对象
          extValue = JSON.stringify(extValue)
        }
        newExtList.push({ ...extDataKv[key], extName: key, extValue, ...(parentId && { parentId }) }) // 这里追加了 parentId
      })
      return newExtList
    },
    formatDataValue(formData) {
      let newData = {}
      for (let key in formData) {
        let val = formData[key]
        newData[key] = isObject(val) || isArray(val) ? JSON.stringify(val) : val
      }
      return newData
    },
    handleSave() {
      let that = this
      let { formData } = this
      let { stateId: id, type } = this
      return new Promise(function (resolve, reject) {
        Promise.all([that.$refs.form.validate(), that.extFormConfig ? that.$refs.ext.validate() : Promise.resolve()]).then(() => {
          let ext = that.extFormData2Array()
          that.loading = true
          let newData = that.formatDataValue(formData)
          fetchApi
            .call(that, '/element/save', { ...newData, type, ...(id && { id }), ext })
            .then(function (res) {
              that.stateId = res.id
              that.$message.success('保存成功')
              that.afterSaveFn() // 一定要放在前面，下面的方法有清空数据
              that.loadData()
              that.$emit('success', res)
            })
            .finally(() => {
              that.loading = false
            })
        })
      })
    },
  },
  created() {
    this.loadData()
    this.updateFormConfig()
  },
}
</script>
<style scoped>
.mt20 {
  margin-top: 20px;
}
.backgroundWhite {
  background: #fff;
  padding: 0 20px;
}
/deep/.backgroundWhite .el-row {
  background: #fff !important;
}
/deep/.backgroundWhite .el-row .tag-style {
  background: #fff !important;
  padding: 0 !important;
  margin: 0 !important;
}
.oecp-divider {
  margin-top: 0;
  margin-bottom: 10px;
  display: none;
}
.title-style {
  font-size: 18px;
  /* font-weight: 600; */
}
.oecp-component-header {
  padding: 10px 12px;
  height: auto;
  align-items: center !important;
}
.el-divider--horizontal {
  height: 0 !important;
  margin: 0 !important;
}
/deep/.el-input-group--append {
  border-radius: 0 !important;
}
/* .oecp-component-header {
  position: -webkit-sticky;
  position: sticky;
  top: -20px;
  z-index: 999;
  background-color: #fff;
} */
.oecp-md-element-form {
  height: 100%;
  display: flex;
  flex-direction: column;
}
/deep/b {
  word-break: break-all;
}
.btnBox {
  width: 70%;
}
.btnBox .el-button {
  width: 30%;
}
/deep/.btnBox .el-button span {
  display: flex;
  justify-content: center;
  align-items: center;
}
.btnBox .el-button img {
  height: 18px;
  width: 18px;
  margin-right: 12px;
}
.title-style img {
  height: 23px;
  width: 23px;
  margin-right: 10px;
}
.addBtn,
/deep/.el-button--primary {
  background: #2468f2;
  border: none;
}
.addBtn:hover,
/deep/.el-button--primary:hover {
  background: #2469f2d6;
  border: none;
}
/deep/.el-row--flex.is-justify-center {
  justify-content: flex-start;
}
</style>
