<!--
 /* @name   新增编辑弹窗组件
 * @authors pen (you@example.org)
 * @date    2022-03-07
 * @version 1.0.1
 */
 -->
 <template>
  <div>
    <dialog-view
      ref="dialogView"
      v-bind="$attrs"
      v-on="$listeners"
      :dialogTitle="dialogTitle ? dialogTitle : isEdit ? '编辑' : '新增'"
      :before-close="beforeClose"
      :visible.sync="visible"
      :buttons="buttons ? buttons : defaultButtons"
      :dialogDefaultClass="dialogDefaultClass"
      :width="width"
      @button-click="buttonClick"
    >
      <template #dialogBody>
        <el-main
          style="background: #fff; border-radius: 8px"
          :style="{
            padding: formTitle ? '10px 0px' : '20px 16px 10px 0px',
            margin: dialogDefaultClass ? '16px' : '0px'
          }"
        >
          <slot name="dialogHeadSlot"></slot>
          <p v-if="formTitle" class="simple_title">{{ formTitle }}</p>
          <div class="mian_content" v-if="Object.keys(formItems).length">
            <form-view
              ref="formView"
              v-bind="$attrs"
              v-on="$listeners"
              :apiName="apiName"
              :disabled="disabled !== undefined ? disabled : isDisabled"
              :formItems="editFormItem"
              :setFormItemFlex="setFormItemFlex"
              @update-form="dialogUpdateForm"
            >
              <template #columns>
                <slot name="columns"></slot>
              </template>
              <template
                v-for="i in editFormItem &&
                editFormItem.form &&
                editFormItem.form.find(p => p.type === 'choiceSku') &&
                editFormItem.form.find(p => p.type === 'choiceSku')
                  .choiceSkuColumns
                  ? editFormItem.form.find(p => p.type === 'choiceSku')
                      .choiceSkuColumns
                  : []"
                v-slot:[i.customSlot]="slotProps"
              >
                <slot
                  :name="i.customSlot"
                  v-bind:customSlotData="slotProps.customSlotData"
                ></slot>
              </template>
              <template v-slot:expandSlot="slotProps">
                <slot
                  name="expandSlot"
                  v-bind:customSlotData="slotProps.customSlotData"
                ></slot>
              </template>
              <template
                v-for="item in editFormItem && editFormItem.form
                  ? editFormItem.form.filter(p => p.customSlot)
                  : []"
                v-slot:[item.customSlot]="slotProps"
              >
                <slot
                  :name="item.customSlot"
                  v-bind:customSlotData="slotProps.customSlotData"
                ></slot>
              </template>
            </form-view>
          </div>
        </el-main>
        <slot name="simpleDialogSlot"></slot>
      </template>
      <template #dialogFooterSlot>
        <slot name="dialogFooterSlot"></slot>
      </template>
    </dialog-view>
  </div>
</template>
<script>
import buttonView from './buttons.vue'
import formView from './form.vue'
import dialogView from './baseView/dialog.vue'
export default {
  name: 'simple-dialog-view',
  components: {
    buttonView,
    formView,
    dialogView
  },
  props: {
    dialogDefaultClass: {
      type: Boolean,
      default: true
    },
    // 接口名称
    apiName: {
      type: String
    },
    setFormItemFlex: {
      type: Boolean,
      default: true
    },
    dialogTitle: String,
    //弹窗宽度
    width: {
      type: String,
      default: '640px'
    },
    // 弹窗的按钮
    buttons: {
      type: Array
    },
    // 表单是否禁用
    disabled: {
      type: Boolean,
      default: undefined
    },
    // 表单的标题
    formTitle: {
      type: String
      // default: '基本信息'
    },
    // 	表单数据对象
    formItems: {
      type: [Object, Array],
      default: () => ({} || [])
    },
    // 完整的保存接口
    simpleDialogSaveUrl: {
      type: String
      // require:true
    },
    // 完整的查询接口
    simpleDialogGetUrl: {
      type: String
      // require:true
    },
    // 额外保存参数
    extendParams: {
      type: Object,
      default: () => ({})
    },
    // 禁用表单判断数据
    judgeFormDisabled: {
      type: Array,
      default: () => []
    },
    // 是否使用组件内的默认保存方法
    isDefaultSave: {
      type: Boolean,
      default: true
    }
  },
  created() {
    // 为了兼容之前的使用，该方法先不删 后续会删除
    this.$on('open', arg => {
      this.open(arg)
    })
  },
  destroyed() {
    this.$off('open')
  },
  data() {
    return {
      defaultButtons: [
        {
          text: '保存',
          type: 'primary',
          id: 'save',
          disabled: false
        },
        {
          text: '取消',
          id: 'cancel',
          disabled: false
        }
      ],
      isDisabled: false,
      queryform: {},
      editFormItem: {},
      isEdit: false,
      currentData: null,
      visible: false
    }
  },
  methods: {
    // 打开该组件的方法
    open(arg) {
      this.isEdit = arg.type === 'edit'
      this.isDisabled = false
      this.$emit('simple-dialog-open', this.isEdit, arg)
      this.editFormItem = this.formItems
      // this.editFormItem.form.forEach(p=>{if(p.hasOwnProperty('visible'))p.visible = true } )
      this.visible = true
      if (!this.isEdit) {
        this.$nextTick(() => {
          this.$refs.formView.updateForm()
        })
      }
      this.queryform = {}
      this.handleDisabled()
      console.log('open arg', arg, 'this.isDisabled', this.isDisabled)
      // 传入参数 {type:edit,row:row}
      if (arg && arg.type === 'edit') {
        this.init(arg.row.id)
      }
    },
    dialogUpdateForm(arg, val, item) {
      this.queryform = arg
      // this.$emit('dialog-update-form',arg,val,item)
    },
    // 强制更新表单
    forceUpdateForm() {
      this.$refs.formView && this.$refs.formView.updateForm()
    },
    // 查询
    init(id) {
      if (this.simpleDialogGetUrl || this.apiName) {
        this.$api
          .get(
            this.simpleDialogGetUrl
              ? this.simpleDialogGetUrl
              : `${this.apiName}/get`,
            {
              id: id
            }
          )
          .then(res => {
            if (res) {
              this.currentData = res
              // 表单赋值
              this.editFormItem.form.forEach(p => {
                for (let i in res) {
                  if (p.name === i) p.value = res[i]
                  // 组装日期范围的数据
                  if (
                    p.type == 'daterange' ||
                    (p.type === 'datetime' && p.dateType === 'datetimerange')
                  ) {
                    let name = p.name.split('--')
                    p.value = [res[name[0]], res[name[1]]]
                  }
                  // 组装上传的数据
                  if (p.name === i && p.type === 'upload' && p.files) {
                    if (p.singleUpload) {
                      res[i] && (p.files = [{ url: res[i] }])
                    } else {
                      p.files = res[i]
                    }
                  }
                }
              })

              // 当有传入判断是否禁用字段是执行该逻辑
              if (this.judgeFormDisabled && this.judgeFormDisabled.length) {
                this.isDisabled = this.judgeFormDisabled.every(p => {
                  if (Array.isArray(p.judgeValue)) {
                    return p.judgeValue.includes(res[p.judgeField])
                  } else {
                    return res[p.judgeField] === p.judgeValue
                  }
                })
                this.handleDisabled()
                console.log('this.isDisabled', this.isDisabled)
              }

              this.$emit('simple-dialog-init-callback', res)
              // this.$nextTick(()=>{
              this.$refs.formView.updateForm()
              // })
            }
          })
      }
    },
    handleDisabled() {
      let saveBtn = this.defaultButtons.find(p => p.id === 'save')
      if (saveBtn) saveBtn.disabled = this.isDisabled
    },
    // 关闭弹窗
    beforeClose() {
      // 清除表单的数据验证等
      this.$refs.formView.$refs.ruleForm.resetFields()
      // 清除上传组件的数据
      if (this.$refs.formView && this.$refs.formView.$refs.upload) {
        if (this.$refs.formView.$refs.upload.length) {
          this.$refs.formView.$refs.upload.forEach(item => {
            item.resetData()
          })
        }
      }
      // 清除数据
      if (this.editFormItem.form) {
        this.editFormItem.form.forEach(p => {
          if (typeof p.value === 'string') p.value = ''
          if (Array.isArray(p.value)) p.value = []
          if (p.type === 'upload' && p.files) p.files = []
          if (p.type === 'upload' && p.singleUpload) p.value = ''
        })
      }
      this.visible = false
      this.$emit('before-close')
    },
    // 保存
    save() {
      this.$refs.formView.$refs.ruleForm.validate(valid => {
        if (valid) {
          let params = this.isEdit
            ? Object.assign({}, this.currentData, this.queryform)
            : this.queryform
          this.$emit('handle-save-params', params)
          if (Object.keys(this.extendParams).length)
            params = Object.assign({}, params, this.extendParams)
          console.log('params', params, this.extendParams)
          this.$emit('custom-simple-dialog-save', params)
          // 判断是否有保存接口
          if (
            (this.simpleDialogSaveUrl || this.apiName) &&
            this.isDefaultSave
          ) {
            this.$api
              .post(
                this.simpleDialogSaveUrl
                  ? this.simpleDialogSaveUrl
                  : `${this.apiName}/save`,
                params
              )
              .then(res => {
                if (res) {
                  this.$api.success()
                  this.beforeClose()
                  this.$emit('save-success-event', res)
                  // this.$parent.$refs.pageView && this.$parent.$refs.pageView.getList()
                  this.$parent.$refs.pageView &&
                  this.$parent.$refs.pageView.getList()
                    ? this.$parent.$refs.pageView.getList()
                    : this.$parent.$parent.$refs.pageView &&
                      this.$parent.$parent.$refs.pageView.getList()
                }
              })
          }
        }
      })
    },
    // 按钮方法
    buttonClick(arg) {
      switch (arg.id) {
        case 'cancel':
          this.beforeClose()
          break
        case 'save':
          this.save()
          break
        default:
          break
      }
    }
  }
}
</script>
<style lang="less">
</style>
