<template>
  <a-modal
    v-model="visible"
    destroy-on-close
    v-bind="{ width: 800, ...modalProps }"
    :mask-closable="false"
    :read-only="readOnly"
    :footer="readOnly ? null : undefined"
    @cancel="$emit('closed')"
  >
    <!--
    对话框关闭后触发
    @event closed
  -->
    <sd-detail-form
      ref="form"
      :record-id="recordId"
      :page-id="pageId"
      :ext-params="extParams"
      :portal-prefix="_uid + 'detail-modal-'"
      :read-only="readOnly"
      @actionBtnClick="actionBtnClick"
      @saved="onSaved"
      @close="
        visible = false
        $emit('closed')
      "
    >
      <template v-slot="scope">
        <!--
          @slot 详情表单内容
          @binding {object} model 整个表单的数据，可用于 v-model 绑定
          @binding {object} fields 后台返回的字段定义
          @binding {string} pageId 当前显示详情页使用的pageId，可以为不同pageId画不同的表单
          @binding {object} formData 当前显示详情页的整个formData（8.1.0.24新增）
        -->
        <slot
          :model="scope.model"
          :fields="scope.fields"
          :pageId="scope.pageId"
          :formData="scope.formData"
        />
      </template>
    </sd-detail-form>
    <template slot="title">
      <portal-target :name="_uid + 'detail-modal-title'" slim> </portal-target>
      <div :class="$style.extra">
        <a-icon
          v-if="hasWebForm"
          type="block"
          title="新窗口打开"
          :class="$style.headerIcon"
          @click="windowOpen"
        />
      </div>
    </template>
    <template slot="footer">
      <portal-target :name="_uid + 'detail-modal-buttons'" slim> </portal-target>
    </template>
  </a-modal>
</template>

<script>
import formService from '@/webform/form-service'
import qs from 'qs'
import { Modal } from 'ant-design-vue'
import crossWindowWatcher from '../services/cross-window-watcher'
import sdFormPublicMethodsNew from './sd-form/sd-form-public-methods-new'
import components from './_import-components/sd-detail-modal-import'

/**
 * <p>查看、编辑、新建一条记录。一般情况下不需要单独使用它，因为 SdDataTableEx 已经包含了这部分功能。</p>
 * <p>与 SdDetailForm 的区别是：一个在当前页查看，一个弹出对话框。</p>
 * <p>该组件需要配合固定格式的接口实现</p>
 * <ul>
 * <li>获取详情 <pre>api/framework/v1/page/wp/${pageId}?id={beanId}</pre></li>
 * <li>保存数据 <pre>api/framework/v1/page/handleData</pre></li>
 * </ul>
 * @displayName SdDetailModal 详情对话框
 */
export default {
  name: 'SdDetailModal',
  components,
  mixins: [sdFormPublicMethodsNew],
  props: {
    /**
     * framework/v1/page/wp 接口中的 pageId
     */
    pageId: {
      type: String,
      required: true,
    },
    /**
     * framework/v1/page/wp 接口中的记录id，不传此参数就是新建
     */
    recordId: {
      type: [String, Number],
      default: undefined,
    },
    /**
     * framework/v1/page/wp 接口中的 extParams
     * @since 8.1.0.29
     */
    extParams: {
      type: Object,
      default: undefined,
    },
    /**
     * 传给详情 modal 的 props，可以用于设置样式等
     */
    modalProps: {
      type: Object,
      default: undefined,
    },
    /**
     * 整个表单是否只读
     */
    readOnly: {
      type: Boolean,
      default: false,
    },
  },
  data() {
    return {
      visible: false,
    }
  },
  computed: {
    hasWebForm() {
      return formService.hasWebForm(this.pageId)
    },
  },
  methods: {
    /**
     * 显示对话框
     * @public
     */
    show() {
      this.visible = true
    },
    /**
     * 隐藏对话框
     * @public
     */
    hide() {
      this.visible = false
    },
    /**
     * 保存表单（仅处理保存请求，不做校验和错误提示）
     * @returns {Promise}
     * @since 8.0.7
     * @public
     */
    save() {
      return this.$refs.form.save()
    },
    /**
     * 模拟点击保存按钮（包含校验和错误提示），保存成功后关闭对话框
     * @returns {Promise}
     * @since 8.0.7
     * @public
     */
    saveBtnClick() {
      return this.$refs.form.saveBtnClick()
    },
    actionBtnClick(evt, btn) {
      /**
       * 操作按钮点击时触发
       *
       * @property {event} evt 事件对象，可以用来取消默认操作等
       * @property {object} btn 点击的按钮
       */
      this.$emit('actionBtnClick', evt, btn)
    },
    onSaved(...args) {
      this.visible = false
      /**
       * 数据保存成功后触发
       * @property {object} data 保存后返回的数据（8.1.0.23新增）
       */
      this.$emit('saved', ...args)
    },
    windowOpen() {
      const content = this.isDirty() ? '新窗口打开后，您将会丢失当前窗口未保存的数据' : ''
      Modal.confirm({
        title: '您确定新窗口打开吗？',
        content,
        onOk: () => {
          this.hide()
          crossWindowWatcher.subscribeChange({
            url:
              '/sd-webform?' +
              qs.stringify({
                id: this.recordId,
                pageId: this.pageId,
                // 新建时，传extParams，用于设置默认值
                extParams:
                  !this.recordId && this.extParams ? JSON.stringify(this.extParams) : undefined,
              }),
            callback: (data) => {
              this.$emit('saved', data)
            },
          })
        },
      })
    },
  },
}
</script>

<style module lang="scss">
@use '@/common/design' as *;
.extra {
  position: absolute;
  top: 0;
  right: 32px;
  z-index: 10;
  .header-icon {
    font-weight: 700;
    cursor: pointer;
    background: transparent;
    opacity: 0.45;
    transition: opacity 0.3s;
    &:hover {
      opacity: 1;
    }
  }
}
//全局样式 ，修改不可编辑弹出窗的行间距 add by zzb 2022/2/22
:global(.noBottom) {
  :global(.ant-form-item) {
    margin-bottom: 0 !important;
  }
}
</style>
