<!-- 页签表单编辑视图 -->
<template>
  <div class="container-fluid">
    <!-- header -->
    <div class="row" style="height: 50px;">
      <div class="col-md-12">
        <h3>
          <a class="a-back" @click="back()"><img class="m-image" src="/static/assets/client-base-v4/image/back.png" />
            {{ Language.getNameTrl($i18n.locale, window) }}
          &nbsp;</a>/&nbsp;{{ subTitle() }}
          <div v-show="type != 'create'" class="btn-group" role="group">
            <button type="button" class="btn btn-default" @click="pre">
              <span class="glyphicon glyphicon-chevron-left" aria-hidden="true" />
            </button>
            <button type="button" class="btn btn-default">
              {{ currIndex }}/{{ totalCount }}
            </button>
            <button type="button" class="btn btn-default" @click="next">
              <span class="glyphicon glyphicon-chevron-right" aria-hidden="true" />
            </button>
          </div>
        </h3>
      </div>
    </div>

    <div v-show="showSpaceRow" class="row">
      <div class="col-md-12">
        <div class="m-space-btn-group" />
      </div>
    </div>
    <div v-show="!showApproveComment" ref="fixedButtonGroup" class="row m-row fixed-btn-group">
      <div class="col-md-12">
        <div class="btn-group">
          <button v-if="allowCreate" type="button" class="btn btn-success" @click="saveTabData">
            {{ $t("lang.tabFormEdit.save") }}
          </button>
          <button v-if="allowCreate" type="button" class="btn btn-info" @click="cancelModel">
            {{ $t("lang.tabFormEdit.revert") }}
          </button>
          <button v-if="refreshFlag" type="button" class="btn btn-default" @click="loadData">
            {{ $t("lang.tabFormEdit.refresh") }}
          </button>
          <TabButton
            ref="tabButton" :show-tab-dto="tab" :model-data="modelData" :uuid="uuid" :view-type="'EditForm'"
            :type="type" :tab-buttons="tab.tabFormView ? tab.tabFormView.tabButtons : null" @save-view="backupView"
            @model-data-changed="modelDataChanged"
          />
          <FormFieldDef
            :tab-form-fields="tabFormFields" :window-no="windowNo" :tab-index="tabIndex"
            @tab-form-field-property-changed="
              tabFormFieldPropertyChanged($event)
            "
          />
          <button
            v-if="window.htmlHelpUrl != null && window.htmlHelpUrl != ''" class="btn btn-default"
            @click="openHtmlHelp(window.htmlHelpUrl)"
          >
            <span class="glyphicon glyphicon-question-sign" />
          </button>
        </div>
      </div>
    </div>
    <div v-show="showApproveComment" ref="fixedButtonGroup" class="row m-row fixed-btn-group">
      <div class="col-md-12">
        <div class="btn-group">
          <button
            v-if="isView == true && windowDisplayType == 'Grid'" type="button" class="btn btn-default"
            @click="changeWindowDisplayType"
          >
            {{ $t("lang.tabFormEdit.formView") }}
          </button>
          <button
            v-if="isView == true && windowDisplayType == 'Report'" type="button" class="btn btn-default"
            @click="changeWindowDisplayType"
          >
            {{ $t("lang.tabFormEdit.reportView") }}
          </button>
        </div>
      </div>
    </div>
    <div v-if="windowDisplayType == 'Grid'">
      <div v-if="tab != null && tab.tabFormView != null" class="m-row clearfix">
        <div class="col-xs-12">
          <div
            v-if="singleColumn" :class="{
              'form-inline': tab.tabFormView.multipleColumn,
              'form-horizontal': !tab.tabFormView.multipleColumn,
            }"
          >
            <template v-for="fieldItem in tabFormFields">
              <FieldEditView
                v-if="tab.tabDataSource" ref="fieldItem1" :key="
                  'FieldEditView_' +
                    windowNo +
                    '_' +
                    tabIndex +
                    '_' +
                    fieldItem.fieldName +
                    '_' +
                    fieldItem.entityFieldIndex
                " :class-name="tab.tabDataSource.className" :field="fieldItem" :model-data="modelData"
                :window-no="windowNo" :tab-index="tabIndex" :js-url="jsUrl"
                :is-chinese-english="window.isChineseEnglish"
                :multiple-column="tab.tabFormView.multipleColumn" @value-changed="valueChanged($event, fieldItem)"
                @execute-callout="executeCallout(fieldItem)"
              />
            </template>
          </div>
        </div>
      </div>

      <div
        v-if="
          tab != null &&
            tab.tabFormView != null &&
            tab.tabFormView.fieldGroups != null &&
            tab.tabFormView.fieldGroups.length > 0
        " class="m-row clearfix"
      >
        <ul id="myTabs" class="nav nav-tabs" role="tablist">
          <li
            v-for="(fieldGroup, fieldGroupIndex) in tab.tabFormView.fieldGroups" :key="fieldGroup.groupName"
            role="presentation" :class="{ active: selectedTabIndex == fieldGroupIndex }"
            @click="selectedTabIndex = fieldGroupIndex"
          >
            <a
              :id="'tab-' + fieldGroupIndex" role="tab" data-toggle="tab"
              aria-controls="home" aria-expanded="true"
            >
              {{ Language.getGroupNameTrl($i18n.locale, fieldGroup) }}
            </a>
          </li>
        </ul>
        <div id="myTabContent" class="tab-content">
          <div
            v-for="(fieldGroup, fieldGroupIndex) in tab.tabFormView.fieldGroups"
            v-show="selectedTabIndex == fieldGroupIndex" id="home" :key="fieldGroup.groupName" role="tabpanel"
            class="tab-pane fade active in" aria-labelledby="home-tab"
          >
            <div v-if="fieldGroup.show">
              <div
                :class="{
                  'form-inline': tab.tabFormView.multipleColumn,
                  'form-horizontal': !tab.tabFormView.multipleColumn,
                }"
              >
                <template v-for="fieldItem in fieldGroup.fields">
                  <FieldEditView
                    v-if="tab.tabDataSource" ref="fieldItem2" :key="
                      'FieldEditView_' +
                        windowNo +
                        '_' +
                        tabIndex +
                        '_' +
                        fieldItem.fieldName +
                        '_' +
                        fieldItem.entityFieldIndex
                    " :class-name="tab.tabDataSource.className" :field="fieldItem" :model-data="modelData"
                    :window-no="windowNo" :tab-index="tabIndex" :js-url="jsUrl"
                    :is-chinese-english="window.isChineseEnglish"
                    :multiple-column="tab.tabFormView.multipleColumn" @value-changed="valueChanged($event, fieldItem)"
                    @execute-callout="executeCallout(fieldItem)"
                  />
                </template>
              </div>
            </div>
          </div>
        </div>
      </div>

      <template v-if="modelData != null">
        <div
          v-for="subTab in tab.subTabs" 
          :id="'SubTabGridEdit-' + windowNo + '-' + tabIndex + '-' + modelData.id + '-subTab-' + subTab.tabIndex"
          :key="'SubTabGridEdit-' + windowNo + '-' + tabIndex + '-' + modelData.id + '-subTab-' + subTab.tabIndex"
          class="row clearfix"
        >
          <div class="col-md-12">
            <SubTabGridEdit
              :ref="'subTab' + subTab.tabIndex" :window-no="windowNo" :tab-index="subTab.tabIndex"
              :fixed-button-group-height="fixedButtonGroupHeight" :tab="subTab" :parent-model-data="modelData"
              :parent-tab="tab" :js-url="jsUrl" :is-chinese-english="window.isChineseEnglish" @save-view="backupView"
              @refresh-parent="refreshParent"
              @change-root-parent-model-data="changeRootParentModelData"
            />
          </div>
        </div>
      </template>
    </div>
    <div v-else style="height: 400px; overflow: scroll">
      <ProcessReportResultPreview
        v-if="
          processReportResult != null &&
            (processReportResult.reportResults != null ||
              processReportResult.processResult != null)
        " :process-report-result="processReportResult" :pdf-only="false" :excel-only="false"
      />
    </div>

    <div v-if="attributeKey != null && attributeKey !=''" class="row clearfix">
      <div class="col-md-12">
        <AttributePanel
          ref="attributePanel" :attribute-key="attributeKey" :attribute-value-key="attributeValueKey"
          :window-no="windowNo"
        />
      </div>
    </div>

    <div
      v-if="
        window != null &&
          tab != null &&
          tab.tabDataSource != null &&
          !window.hideCreateRecordButton
      " class="row clearfix"
    >
      <AttachmentPanel
        v-if="type == 'edit' && tab.tabDataSource" :class-name="tab.tabDataSource.className"
        :record-id="recordId" :tab-index="tabIndex" :window-no="windowNo"
      />
    </div>

    <div v-if="showApproveComment" class="row clearfix">
      <div class="col-md-12">
        <ApproveComment
          ref="approveComment" :workflow-type="'UserDefine'" :parent-widget="'TabFormEdit'"
          :work-flow="window.workflow" :window-no="windowNo" :process-definition-id="processDefinitionId"
          :show-choice-button="showChoiceButton" :process-instance-id="processInstanceId" :task-info-id="taskInfoId"
          :record-id="modelData.id" :show-tab-dto="tab" :model-data="modelData" :uuid="uuid" :workflow-class-name="tab.tabDataSource.className"
          @save-data="saveTabData"
        />
      </div>
    </div>

    <!-- 历史审批记录 -->
    <div v-if="modelData != null" class="row clearfix">
      <div class="col-md-12">
        <HistoryApproveComment :record-id="modelData.id" :process-instance-id="processInstanceId" />        
      </div>
    </div>

    <Modal v-model:show="modal1">
      <div>
        {{ $t("lang.tabFormEdit.validateError", { errorCount: errorCount, errorMsg: errorMsg, }) }}
      </div>
      <template #header>{{ $t("lang.tabFormEdit.validateError") }}</template>
    </Modal>
    <Modal v-model:show="modal2" @ok="dataRestore()" @cancel="cancelRestore()">
      <template #header>{{ $t("lang.tabFormEdit.describe3") }}</template>
      <div>{{ $t("lang.tabFormEdit.describe4") }}</div>
    </Modal>

    <Modal v-model:show="modal3" @ok="cancelOk()" @cancel="cancelNo()">
      <template #header>{{ $t("lang.tabFormEdit.describe5") }}</template>
      <div>{{ $t("lang.tabFormEdit.describe6") }}</div>
    </Modal>
    <Loading v-if="loading" />
  </div>
</template>

<script>
import Common from '../../common/Common.js';

import WindowServerUtil from '../../resource/dictionary/WindowServerUtil.js';
import WindowClientUtil from '../../resource/dictionary/WindowClientUtil.js';
import TabFormView from './TabFormView.js';
import FieldUtil from '../../resource/dictionary/FieldUtil.js';

import Context from '../common/Context.js';
import ProcessReportResource from '../../api/dic/ProcessReportResource.js';
import CurdWindowResource from '../../api/dic/CurdWindowResource.js';
import UserStorageResource from '../../api/base/UserStorageResource.js';
import Language from '../../common/Language.js';

import SubTabGridEdit from '../tabGridView/SubTabGridEdit.vue';
import FieldEditView from './TabFormFieldEdit.vue';
import TabButton from '../tabView/TabButton.vue';
import FormFieldDef from './FormFieldDef.vue';
import AttachmentPanel from '../attachment/AttachmentPanel.vue';

import AttributePanel from '../attribute/AttributePanel.vue';
import HistoryApproveComment from '../../workflow/HistoryApproveComment.vue';
import ApproveComment from '../../workflow/ApproveComment.vue';

import DataRecoveryResource from '../../api/base/DataRecoveryResource.js';
import JsUtil from '../../common/JsUtil.js';
import { Notify, Uuid, Modal } from 'pc-component-v3';

export default {

  components: {
    SubTabGridEdit,
    FieldEditView,
    TabButton,
    FormFieldDef,
    AttachmentPanel,
    AttributePanel,
    ApproveComment,
    HistoryApproveComment,
  },

  /**
       * 在离开路由之前，检验数据是否已保存
       */
  beforeRouteLeave: function (to, from, next) {
    var _self = this;
    if (_self.windowDisplayType == 'Grid') {
      if (_self.cancelCommand == false && _self.isModelDataChanged() == true) {
        Notify.notice(_self.$t('lang.tabFormEdit.dataNotSaved'), _self.$t('lang.tabFormEdit.describe1'), false);
        next(false);
      } else {
        next();
      }
    } else {
      next();
    }
    if (_self.autoSaveInterval != null) {
      clearInterval(_self.autoSaveInterval);
    }
  },
  data: function () {
    this.Language = Language;
    return {
      type: '', // 窗口类型
      windowNo: '', // 窗口Id
      tabIndex: '', // 页签Id
      recordId: '', // 记录Id
      window: {}, // 窗口数据
      tab: {}, // 父页签
      tabFormFields: [],
      modelData: {},
      errorCount: 0, // 校验错误数量
      errorMsg: '', // 校验错误信息
      error: 0,
      currPage: 1,
      attributeKey: null,
      attributeValueKey: null,
      currIndex: 0,
      totalCount: 0,
      buttonGroupInitLeft: 0,
      buttonGroupInitTop: 0,
      showSpaceRow: false,
      filterParams: null,
      uuid: '',
      cancelCommand: false, // 取消命令
      fixedButtonGroupHeight: 0,
      selectedTabIndex: 0, // 选择的页签序号

      // 工作流定义Id
      processDefinitionId: '',
      processInstanceId: undefined,
      workflowType: undefined,
      taskInfoId: undefined,
      windowDisplayType: 'Grid', // 显示类型
      processReportResult: undefined,
      isView: true, // 是否显示模式切换按钮
      autoSaveInterval: null, // 自动保存定时器
      dataRecoveryDto: undefined,
      isRestoreData: undefined, //是否恢复草稿数据
      jsUrl: null,
      loading: false,
      modal1: false,
      modal2: false,
      modal3: false,
      refreshFlag: false,
    };
  },

  computed: {
    /**
         * 是否允许新建
         * tab
         */
    allowCreate: function () {
      var _self = this;
      var allTabReadOnly = true;
      // 如果所有的页签都是只读
      if (_self.window != undefined && _self.window.tabs != undefined) {
        for (
          var tabIndex = 0; tabIndex < _self.window.tabs.length; tabIndex++
        ) {
          if (
            _self.window.tabs[tabIndex].isReadOnly == undefined ||
              _self.window.tabs[tabIndex].isReadOnly == false
          ) {
            allTabReadOnly = false;
            break;
          }
        }
      }
      return !allTabReadOnly;
    },

    /**
         * 页签是否单列
         */
    singleColumn: function () {
      var _self = this;
      if (_self.tab.multipleColumn == true) {
        return false;
      } else {
        return true;
      }
    },

    /**
         * 是否显示审批面板
         * 处于审批中的单据，显示审批面板
         */
    showApproveComment: function () {
      // 判断是否显示审批按钮
      if (
        this.window != undefined &&
          this.window.hasWorkflow != undefined &&
          this.modelData != undefined &&
          this.modelData.data != undefined &&
          this.modelData.data.processInstanceId != undefined &&
          this.modelData.data.processInstanceId.displayValue != undefined &&
          this.modelData.data.processInstanceId.displayValue[0] != undefined &&
          this.modelData.data.processInstanceId.displayValue[0].length > 0
      ) {
        return true;
      }
      return false;
    },

    /**
         * 是否显示审批评论面板
         * 审批完成的单据，显示审批评论面板
         */
    showChoiceButton: function () {
      if (
        this.window != undefined &&
          this.window.workflow != undefined &&
          this.modelData != undefined &&
          this.modelData.data != undefined &&
          this.modelData.data.processInstanceId != undefined &&
          this.modelData.data.processInstanceId.displayValue != undefined &&
          this.modelData.data.processInstanceId.displayValue[0] != undefined &&
          this.modelData.data.processInstanceId.displayValue[0].length > 0 &&
          this.modelData.data.documentStatus != undefined &&
          this.modelData.data.documentStatus.displayValue != undefined &&
          this.modelData.data.documentStatus.displayValue[0] != undefined &&
          this.modelData.data.documentStatus.displayValue[0].length > 0 &&
          this.modelData.data.documentStatus.displayValue[0] == 'PROCESSING' &&
          this.taskInfoId != undefined &&
          this.workflowType != 'copyTask'
      ) {
        return true;
      }
      return false;
    },
  },

  watch: {
    $route: function (to, from) {
      // 与 mounted 中的initView重复执行
      // this.initView();
    },

    modelData: {
      deep: true,
      handler(curVal, oldVal) {
        var _self = this;
        this.tabButtonsShowLogical();
        this.reportViewsShowLogical();
        if (_self.autoSaveInterval != null) {
          clearInterval(_self.autoSaveInterval);
          _self.autoSaveInterval = null;
          _self.startSaveInterval();
        } else {
          _self.startSaveInterval();
        }
      },
    },

    /**
     * 显示界面发生改变的时候，重新执行显示逻辑
     */
    windowDisplayType: function(newValue, oldValue){
      this.reportViewsShowLogical();
    },
  },

  beforeCreate: function () {
    console.log('WindowEdit beforeCreate.');
  },

  created: function () {
    console.log('WindowEdit created.');
  },

  beforeMount: function () {
    console.log('WindowEdit beforeMount.');
  },

  mounted: function () {
    var _self = this;
    console.log('WindowEdit mounted.');
    this.initView();

    // 按钮栏实现滚动
    _self.$nextTick(function () {
      // var fixedButtonGroup = $(_self.$refs.fixedButtonGroup);
      // _self.computerButtonGroupLeftTop();
      // $(window).scroll(function (){
      //     if ($(window).scrollTop() > _self.buttonGroupInitTop) {
      //         _self.showSpaceRow = true;
      //         _self.$nextTick(function (){
      //         	fixedButtonGroup.addClass('btn-group-fixed');
      //         	fixedButtonGroup.css('left', _self.buttonGroupInitLeft + 'px');
      //         });
      //     } else {
      //         _self.showSpaceRow = false;
      //         _self.$nextTick(function (){
      //         	fixedButtonGroup.removeClass('btn-group-fixed');
      //         	fixedButtonGroup.css('left', '');
      //         });
      //     }

      //     if ($(window).scrollTop() <= 10){
      // 		_self.computerButtonGroupLeftTop();
      //     }
      // });

      var fixedButtonGroup = $(_self.$refs.fixedButtonGroup);
      var buttonInitTop = fixedButtonGroup.offset().top;

      _self.fixedButtonGroupHeight = fixedButtonGroup.outerHeight();

      // 按钮组实现悬浮
      $(window).scroll(function () {
        var windowTop = $(window).scrollTop();
        if (windowTop > buttonInitTop + fixedButtonGroup.outerHeight()) {
          fixedButtonGroup.offset({
            top: windowTop,
            left: fixedButtonGroup.offset().left,
          });
        } else {
          fixedButtonGroup.offset({
            top: buttonInitTop,
          });
        }
      });
    });

    $(window).resize(function () {
      _self.$nextTick(function () {
        _self.computerButtonGroupLeftTop();
      });
    });

    window.addEventListener('beforeunload', e => this.beforeunloadFn(e));
  },

  unmounted() {
    window.removeEventListener('beforeunload', e => this.beforeunloadFn(e));
    let _self = this;
    if (_self.autoSaveInterval != null) {
      clearInterval(_self.autoSaveInterval);
    }
  },

  methods: {
    /**
         * 删除草稿数据
         * @author GuoZhiBo 20210926
         */
    deleteDataRecoveryDto: function () {
      var _self = this;
      if (_self.autoSaveInterval != null) {
        clearInterval(_self.autoSaveInterval);
        _self.autoSaveInterval = null;
      }
      _self.dataRecoveryDto = {
        windowId: _self.windowNo,
        type: _self.type,
      };
      DataRecoveryResource.deleteDataRecoveryDto(_self.dataRecoveryDto).then(
        successData => {
          if (successData != null) {
            console.log('删除自动保存数据失败。');
          }
        },
        errorData => {
          Common.processException(errorData);
        },
      );
    },
    /**
         * 恢复草稿数据
         * @author GuoZhiBo 20210926
         */
    dataRestore: function () {
      var _self = this;
      _self.restoreModelData(_self.dataRecoveryDto.modelData);
    },
    /**
         * 恢复modelData数据
         * @param {Object} cacheModelData
         * @author GuoZhiBo 20210926
         */
    restoreModelData: function (cacheModelData) {
      var _self = this;
      // 恢复父页签的数据
      cacheModelData.restore = true;
      _self.modelData = cacheModelData;
      _self.$nextTick(function () {
        if (
          cacheModelData.saveDatas != undefined &&
            cacheModelData.saveDatas.length > 0
        ) {
          // bug fixed by jack 2021-10-08
          // 子页签修改的时候，不会影响父页签的属性，如果直接使用saveDatas，那么子页签属性发生改变的时候，deep watch parentModelData 也会发生改变。
          const saveDatasTemp = cacheModelData.saveDatas;
          cacheModelData.saveDatas = null;

          saveDatasTemp.forEach(function (saveData) {
            // 恢复子页签的数据
            var subTabId = 'subTab' + saveData.tabIndex;
            var tabElements = _self.$refs[subTabId];
            if (tabElements && tabElements.length > 0) {
              var tabElement = tabElements[0];
              if (tabElement) {
                saveData.editMode = true;
                tabElement.addModelData(saveData);
              }
            }
          });
        } else {
          // BUG描述：父子页签，编辑以后撤销，子页签数据不显示
          // BUG修复：刷新子页签的数据
          // bug fixed by jack 20180203

          for (var index = 0; index < _self.tab.subTabs.length; index++) {
            var subTabId = 'subTab' + this.tab.subTabs[index].tabIndex;
            _self.$refs[subTabId][0].queryGridData();
          }
        }
      });
    },
    /**
         * 取消恢复
         * @author GuoZhiBo 20210926
         */
    cancelRestore: function () {
      var _self = this;
      _self.modal2 = false;
      //删除草稿数据
      _self.deleteDataRecoveryDto();
    },

    /**
         * 打开帮助页面
         */
    openHtmlHelp: function (htmlHelpUrl) {
      window.open(htmlHelpUrl);
    },

    // 初始化界面
    initView: function () {
      var _self = this;
      this.type = this.$route.params.type;
      this.windowNo = this.$route.params.windowNo;
      this.tabIndex = this.$route.params.tabIndex;
      this.recordId = this.$route.params.recordId;
      this.currPage = this.$route.query.currPage;
      this.currIndex = Number(this.$route.query.currIndex);
      this.totalCount = Number(this.$route.query.totalCount);
      this.uuid = this.$route.query.uuid;
      this.workflowType = this.$route.query.workflowType;
      this.taskInfoId = this.$route.query.taskInfoId;
      this.isRestoreData = this.$route.query.isRestoreData;
      if (_self.type == 'edit') {
        if (this.isRestoreData == 1) {
          this.restoreView();
        } else {
          this.initEditView();
        }
      } else if (this.type == 'create') {
        this.initCreateView();
      } else if (this.type == 'restore') {
        // 恢复视图
        this.restoreView();
      }
    },

    // 初始化新建界面
    initCreateView: function () {
      var _self = this;

      if (_self.$refs.loading != undefined) {
        _self.loading = true;
      }
      DataRecoveryResource.queryDataRecoveryDtoByUserId(
        _self.windowNo,
        _self.type,
      ).then(
        successData => {
          if (successData != null) {
            _self.modal2 = true;
            _self.dataRecoveryDto = successData;
          }
        },
        errorData => {
          Common.processException(errorData);
        },
      );

      _self.processInstanceId = '';
      WindowServerUtil.getWindowById(
        _self.windowNo,
        function (window) {
          WindowClientUtil.parseFilterSchema(window);
          var tab = WindowClientUtil.getTab(window, _self.tabIndex);
          WindowClientUtil.parseSubTab(window, tab);
          WindowClientUtil.parseFieldGroup(tab);
          WindowClientUtil.restoreWindowTabFieldGroupsVisible(window);

          _self.tabFormFields = WindowClientUtil.getDetailField(tab);
          _self.window = window;
          _self.jsUrl = window.jsUrl;
          _self.tab = tab;
          TabFormView.restoreTabFormFieldDef(
            _self.windowNo,
            _self.tabIndex,
            _self.tabFormFields,
          );

          WindowServerUtil.newModelData(
            _self.windowNo,
            _self.tabIndex,
            function (modelData) {
              if (_self.$refs.loading != undefined) {
                _self.loading = false;
              }

              modelData.editMode = true;

              _self.modelData = modelData;
              _self.recordId = undefined;
              // add by jack 20180914
              // 自动点击菜单
              _self.autoClickMenu();
            },
            function () {
              if (_self.$refs.loading != undefined) {
                _self.loading = false;
              }
            },
          );
        },
        function () {
          if (_self.$refs.loading != undefined) {
            _self.loading = false;
          }
        },
      );
    },

    // 初始化编辑界面
    initEditView: function () {
      var _self = this;
      _self.loading = true;
      _self.processInstanceId = '';

      if (_self.taskInfoId) {
        CurdWindowResource.uniqueByNoWithWorkflow(
          null,
          _self.taskInfoId,
          _self.windowNo,
        ).then(
          successData => {

            initWindowAfterLoaded(successData);
          },
          errorData => {
            _self.loading = false;
            Common.processException(errorData);
          },
        );
      } else {
        WindowServerUtil.getWindowById(
          _self.windowNo,
          function (window) {
            initWindowAfterLoaded(window);
          },
          function () {
            _self.loading = false;
          },
        );
      }

      function initWindowAfterLoaded(window) {
        WindowClientUtil.parseFilterSchema(window);
        var tab = WindowClientUtil.getTab(window, _self.tabIndex);
        WindowClientUtil.parseSubTab(window, tab);
        WindowClientUtil.parseFieldGroup(tab);
        WindowClientUtil.restoreWindowTabFieldGroupsVisible(window);

        _self.tabFormFields = WindowClientUtil.getDetailField(tab);
        _self.window = window;
        _self.jsUrl = window.jsUrl;
        _self.tab = tab;
        TabFormView.restoreTabFormFieldDef(
          _self.windowNo,
          _self.tabIndex,
          _self.tabFormFields,
        );

        if (_self.window.workflow != undefined && _self.modelData.id > 0) {
          _self.processDefinitionId = _self.window.workflow.deploymentId;
        }
        if (
          _self.window.reportViewDto != null &&
            _self.window.reportViewDto.reportViewItemDtos != null &&
            _self.window.reportViewDto.reportViewItemDtos.length > 0 &&
            _self.workflowType == 'approve'
        ) {
          var isflag = false;
          _self.window.reportViewDto.reportViewItemDtos.forEach(function (item) {
            if (item.defaultDisplayReport) {
              isflag = true;
            }
          });
          if (isflag) {
            _self.windowDisplayType = 'Report';
          } else {
            _self.windowDisplayType = 'Grid';
          }
        } else {
          _self.windowDisplayType = 'Grid';
          _self.isView = false;
        }

        _self.loading = false;
        _self.loadData();
      }
    },
    /**
         * 切换显示模式
         * @author GuoZhiBo 20210419
         */
    changeWindowDisplayType: function () {
      var _self = this;
      if (_self.windowDisplayType == 'Grid') {
        _self.windowDisplayType = 'Report';
      } else {
        _self.windowDisplayType = 'Grid';
        _self.$nextTick(function () {
          for (var index = 0; index < _self.tab.subTabs.length; index++) {
            var subTabId = 'subTab' + this.tab.subTabs[index].tabIndex;
            _self.$refs[subTabId][0].queryGridData();
          }
        });
      }
    },

    // 恢复视图
    restoreView: function () {
      let _self = this;
      let key = _self.uuid + '_modelData';

      _self.loading = true;
      _self.processInstanceId = '';

      WindowServerUtil.getWindowById(
        _self.windowNo,
        function (window) {
          WindowClientUtil.parseFilterSchema(window);
          var tab = WindowClientUtil.getTab(window, _self.tabIndex);
          WindowClientUtil.parseSubTab(window, tab);
          WindowClientUtil.parseFieldGroup(tab);
          WindowClientUtil.restoreWindowTabFieldGroupsVisible(window);

          _self.tabFormFields = WindowClientUtil.getDetailField(tab);
          _self.window = window;
          _self.jsUrl = window.jsUrl;
          _self.tab = tab;
          TabFormView.restoreTabFormFieldDef(
            _self.windowNo,
            _self.tabIndex,
            _self.tabFormFields,
          );

          if (_self.window.workflow != undefined && _self.modelData.id > 0) {
            _self.processDefinitionId = _self.window.workflow.deploymentId;
          }

          _self.loading = false;
          if (_self.isRestoreData == 1) {
            DataRecoveryResource.queryDataRecoveryDtoByUserId(
              _self.windowNo,
              _self.type,
            ).then(
              successData => {
                if (successData != null) {
                  _self.restoreModelData(successData.modelData);
                }
              },
              errorData => {
                Common.processException(errorData);
              },
            );
          } else {
            UserStorageResource.uniqueByKey(key).then(
              successData => {
                // if(successData.errorCode != 0) {
                //   Notify.error('提示', successData.errorMessage, false);
                //   return;
                // }
                if (successData.data != null && successData.data != '') {
                  let cacheModelData = JSON.parse(successData.data);

                  cacheModelData.restore = true;

                  // 恢复父页签的数据
                  _self.modelData = cacheModelData;

                  _self.$nextTick(function () {
                    if (
                      cacheModelData.saveDatas != undefined &&
                        cacheModelData.saveDatas.length > 0
                    ) {
                      cacheModelData.saveDatas.forEach(function (saveData) {
                        // 恢复子页签的数据
                        var subTabId = 'subTab' + saveData.tabIndex;
                        var tabElements = _self.$refs[subTabId];
                        if (tabElements && tabElements.length > 0) {
                          var tabElement = tabElements[0];
                          if (tabElement) {
                            tabElement.addModelData(saveData);
                          }
                        }
                      });
                    } else {
                      // BUG描述：父子页签，编辑以后撤销，子页签数据不显示
                      // BUG修复：刷新子页签的数据
                      // bug fixed by jack 20180203

                      for (
                        var index = 0; index < _self.tab.subTabs.length; index++
                      ) {
                        var subTabId =
                            'subTab' + this.tab.subTabs[index].tabIndex;
                        _self.$refs[subTabId][0].queryGridData();
                      }
                    }
                  });
                  console.log(cacheModelData);
                }
              },
              errorData => {
                Common.processException(errorData);
              },
            );
          }
        },
        function () {
          _self.loading = false;
        },
      );
    },

    /**
         * 数据发生改变
         * eg:生单界面回传了新的modelData数据
         */
    modelDataChanged: function (newModelData) {
      var _self = this;
      // 恢复父页签的数据
      newModelData.visible = true;
      if (
        newModelData.saveDatas != undefined &&
          newModelData.saveDatas.length > 0
      ) {
        newModelData.saveDatas.forEach(function (item) {
          item.visible = true;
        });
      }
      // 恢复父页签的数据
      _self.modelData = newModelData;

      _self.$nextTick(function () {
        if (
          newModelData.saveDatas != undefined &&
            newModelData.saveDatas.length > 0
        ) {
          let firstModelData = newModelData.saveDatas[0];

          // 恢复子页签的数据
          let subTabId = 'subTab' + firstModelData.tabIndex;
          var tabElements = _self.$refs[subTabId];
          if (tabElements && tabElements.length > 0) {
            var tabElement = tabElements[0];
            if (tabElement) {
              tabElement.replaceModelDatas(newModelData.saveDatas);
            }
          }
          // bug fixed by jack 2022-01-17
          // 修复生单界面跳转回来以后，如果子页签 行数多的话，输入非常卡的BUG。
          newModelData.saveDatas = null;
        } else {
          // BUG描述：父子页签，编辑以后撤销，子页签数据不显示
          // BUG修复：刷新子页签的数据
          // bug fixed by jack 20180203
          for (var index = 0; index < _self.tab.subTabs.length; index++) {
            let subTabId = 'subTab' + this.tab.subTabs[index].tabIndex;
            _self.$refs[subTabId][0].queryGridData();
          }
        }
      });
    },

    /**
         * 获取界面的数据
         * eg:生单界面获取modelData数据
         */
    getModelData: function () {
      var _self = this;
      var subTabAllData = _self.getSubTabAllData();
      if (subTabAllData.length > 0) {
        _self.modelData.saveDatas = subTabAllData;
      } else {
        _self.modelData.saveDatas = null;
      }
      return _self.modelData;
    },

    executeProcess: function (processReportNo) {
      var _self = this;
      var ids = [];
      if (_self.modelDatas) {
        _self.modelDatas.forEach(function (modelData) {
          if (modelData.select == true) {
            ids.push(modelData.id);
          }
        });
      } else if (_self.modelData) {
        ids.push(_self.modelData.id);
      }
      ProcessReportResource.runProcessByIds(processReportNo, ids).then(
        successData => {
          var processReportResult = successData;
          if (_self.processReportResult == undefined) {
            if (
              processReportResult.reportResults != undefined &&
                processReportResult.reportResults.length > 0
            ) {
              processReportResult.reportResults.forEach(function (item, index) {
                if (item.reportDefinitionType!=='ExcelReport') {
                  item.previewIndex=1;
                } else {
                  item.previewIndex=2;
                }
                if (index == 0) {
                  item['showPreview'] = true;
                } else {
                  item['showPreview'] = false;
                }
              });
            }
            _self.processReportResult = processReportResult;
          } else {
            if (
              processReportResult.reportResults != undefined &&
                processReportResult.reportResults.length > 0
            ) {
              processReportResult.reportResults.forEach(function (item, index) {
                item.previewIndex = 1;
                if (index == 0) {
                  item.showPreview = true;
                } else {
                  item.showPreview = false;
                }
                _self.processReportResult.reportResults.push(item);
              });
            }
          }
        },
        errorData => {
          Common.processException(errorData);
        },
      );
    },
    getContext: Context,

    /**
     * 报表视图显示逻辑
     */
    reportViewsShowLogical: function () {
      var _self = this;
      
      if(_self.windowDisplayType != 'Report'){
        // add by jack 2023-12-05
        // 如果不处于报表界面，那么不执行下述业务逻辑
        return;
      }

      if (
        _self.window.reportViewDto != null &&
          _self.window.reportViewDto.reportViewItemDtos != null
      ) {
        _self.processReportResult = undefined;
        for (
          let index = 0; index < _self.window.reportViewDto.reportViewItemDtos.length; index++
        ) {
          let reportViewItemDto =
              _self.window.reportViewDto.reportViewItemDtos[index];
          var logic = reportViewItemDto.showLogical;
          if (logic == null || logic == '') {
            reportViewItemDto.invisible = false;
            _self.executeProcess(reportViewItemDto.processReportNo);
            return;
          }

          let functionName = 'form_view_showlogical_' + index;


          const executeFunction = function (){
            let actions = {
              subTabsRef: _self.getSubTabs(),
            };

            let context = new _self.getContext(_self.modelData, actions);

            try{
              reportViewItemDto.invisible = !_self[functionName](context);

              if (reportViewItemDto.invisible == false) {
                _self.executeProcess(reportViewItemDto.processReportNo);
              }

            }catch(e){
              console.error(e);
              Notify.error('数据字典定义异常', '【' + logic + '】报表显示逻辑定义异常,请联系管理员检查数据字典的定义。', false);
            }
          };

          if (this[functionName] == null) {
            const jsUrl = this.jsUrl;
            if (jsUrl == null || jsUrl == undefined) {
              Notify.error('数据字典定义异常', '【' + logic + '】报表显示逻辑的JS文件不存在,请联系管理员检查数据字典是否存在JS文件', false);
              return;
            }
            let promise = JsUtil.dynamicLoadJsFunction(jsUrl, logic);
            promise.then(targetFunction => {
              _self[functionName] = targetFunction;
              if(targetFunction == null){
                Notify.error('数据字典定义异常', '【' + logic + '】报表显示逻辑定义异常,请联系管理员检查数据字典的定义。', false);
                return;
              }

              

              executeFunction();
            }, errorData => {
              console.error(errorData);
            });
          }else{
            executeFunction();
          }

        }
      }
    },

    /**
         * 获取子页签的集合
         */
    getSubTabs: function () {
      var _self = this;
      let subTabsRef = [];
      for (var tabIndex = 0; tabIndex < _self.tab.subTabs.length; tabIndex++) {
        var subTabId = 'subTab' + this.tab.subTabs[tabIndex].tabIndex;
        subTabsRef.push(_self.$refs[subTabId][0]);
      }
      return subTabsRef;
    },

    // 备份视图
    backupView: function () {
      var _self = this;
      var subTabChangedData = _self.getSubTabChangedData();
      if (subTabChangedData.length > 0) {
        _self.modelData.saveDatas = subTabChangedData;
      } else {
        _self.modelData.saveDatas = null;
      }

      _self.modelData.restore = null;
      // bug 修复：生单功能问题：新建单据，再点击生单，会提示需要保存或撤销，必须先保存一次如此提示过后，才可以点击生单按钮进入来源单据选择页面，并且在勾选来源单据后点击确定无反应
      _self.cancelCommand = true;

      let key = _self.uuid + '_modelData';

      let userStorageDtos = [{
        key: key,
        value: JSON.stringify(_self.modelData),
      }];

      let promise = new Promise(function (reslove, reject) {
        // 组装查询条件，然后放到后台数据库当中
        UserStorageResource.uploadUserStorage(userStorageDtos).then(
          successData => {
            reslove();
          },
          errorData => {
            Common.processException(errorData);
            reject();
          },
        );
      });

      return promise;
    },

    loadData: function () {
      var _self = this;

      if (_self.recordId == undefined) {
        return;
      }

      var tabLoadParam = {
        windowNo: _self.windowNo,
        tabIndex: _self.tabIndex,
        recordId: _self.recordId,
      };
      _self.loading = true;
      WindowServerUtil.loadTabSingleData(
        tabLoadParam,
        function (modelData) {
          _self.modelData = modelData;

          // 判断是否有属性
          if (
            modelData.data.attributeKey != undefined &&
              modelData.data.attributeKey.displayValue != undefined
          ) {
            let displayValue = modelData.data.attributeKey.displayValue;
            if (displayValue.length > 0) {
              _self.attributeKey = displayValue[0];
            }
          }
          // 判断是否有属性值
          if (
            modelData.data.attributeValueKey != undefined &&
              modelData.data.attributeValueKey.displayValue != undefined
          ) {
            let displayValue1 = modelData.data.attributeValueKey.displayValue;
            if (displayValue1.length > 0) {
              _self.attributeValueKey = displayValue1[0];
            }
          }

          // 判断是否显示审批状态
          if (
            _self.modelData != null &&
              _self.modelData.data != null &&
              _self.modelData.data.processInstanceId != null
          ) {
            let displayValue =
                _self.modelData.data.processInstanceId.displayValue;
            if (displayValue != null && displayValue.length > 0) {
              _self.processInstanceId = displayValue[0];
            } else {
              _self.processInstanceId = '';
            }
          } else {
            _self.processInstanceId = '';
          }

          _self.loading = false;
        },
        function () {
          _self.loading = false;
        },
      );
    },

    // 保存
    saveTabData: function (command) {
      var _self = this;
      var fieldWidgets1 = _self.$refs.fieldItem1;
      var fieldWidgets2 = _self.$refs.fieldItem2;

      // 保存的时候取消判断
      _self.cancelCommand = true;

      _self.errorMsg = '';
      var promises = [];
      _self.error = 0;

      if (fieldWidgets1 != undefined) {
        fieldWidgets1.forEach(function (w) {
          var validateResult = w.performValide();
          if (!validateResult) {
            _self.error++;
          }
        });
      }

      if (fieldWidgets2 != undefined) {
        fieldWidgets2.forEach(function (w) {
          var validateResult = w.performValide();
          if (!validateResult) {
            _self.error++;
          }
        });
      }

      var subTabValidateResults = _self.getSubTabValidatePromise();
      if (
        subTabValidateResults != undefined &&
          subTabValidateResults.length > 0
      ) {
        subTabValidateResults.forEach(function (subTabValidateResult) {
          if (subTabValidateResult != true) {
            _self.error++;
          }
        });
      }

      if (_self.attributeKey != null) {
        var attributeValidateResult =
            _self.$refs.attributePanel.performValide();
        if (attributeValidateResult != true) {
          _self.error++;
        }
        var attributeValueDtos = _self.$refs.attributePanel.getValue();
      }

      console.log('check finished');
      if (_self.error == 0) {
        executeSave();
      } else {
        _self.errorCount = _self.error;
        _self.modal1 = true;
      }

      function executeSave() {
        _self.modelData.changed = true;

        var subTabChangedData = _self.getSubTabChangedData();
        if (subTabChangedData.length > 0) {
          _self.modelData.saveDatas = subTabChangedData;
        } else {
          _self.modelData.saveDatas = null;
        }

        var tabSaveData = {
          attributeValueDtos: attributeValueDtos,
          persistenceData: _self.modelData,
        };

        _self.loading = true;
        WindowServerUtil.saveTabData(
          tabSaveData,
          function (id) {
            _self.loading = false;

            // 自动关闭
            var saveClose = Common.getRouteParam('saveClose');
            if (saveClose == 'true') {
              window.setTimeout(function () {
                window.close();
              }, 1000);
              Notify.success(_self.$t('lang.tabFormEdit.savingSucceeded'), _self.$t('lang.tabFormEdit.describe2'), 1500);
              return;
            } else {
              Notify.success(_self.$t('lang.tabFormEdit.savingSucceeded'), _self.$t('lang.tabFormEdit.dataSavingSucceeded'), 1500);
            }

            _self.modelData.id = id;
            _self.callAfterSaveLogical();

            if (_self.taskInfoId && _self.$refs.approveComment && command) {
              // 从后台加载modelData数据

              _self.loading = true;

              CurdWindowResource.loadTabData(
                _self.windowNo,
                _self.tabIndex,
                id,
              ).then(
                successData => {
                  _self.loading = false;
                  _self.$refs.approveComment.saveData(command, successData);
                },
                errorData => {
                  _self.loading = false;
                  Common.processException(errorData);
                },
              );

              return;
            }
            //删除草稿数据
            _self.deleteDataRecoveryDto();

            var currIndex = _self.currIndex;
            var totalCount = _self.totalCount;

            if (_self.type == 'edit') {
              _self.$router.push(
                '/desktop/window/window-read/view/' +
                  _self.windowNo +
                  '/' +
                  _self.tabIndex +
                  '/' +
                  id +
                  '?currPage=' +
                  _self.currPage +
                  '&currIndex=' +
                  currIndex +
                  '&totalCount=' +
                  totalCount +
                  '&uuid=' +
                  _self.uuid,
              );
            } else if (_self.type == 'create') {
              _self.$router.push(
                '/desktop/window/window-read/view/' +
                  _self.windowNo +
                  '/' +
                  _self.tabIndex +
                  '/' +
                  id +
                  '?currPage=' +
                  _self.currPage +
                  '&currIndex=' +
                  1 +
                  '&totalCount=' +
                  (Number(totalCount) + 1) +
                  '&uuid=' +
                  _self.uuid,
              );
            } else if (_self.type == 'restore') {
              _self.$router.push(
                '/desktop/window/window-read/view/' +
                  _self.windowNo +
                  '/' +
                  _self.tabIndex +
                  '/' +
                  id +
                  '?currPage=' +
                  1 +
                  '&currIndex=' +
                  1 +
                  '&totalCount=' +
                  1 +
                  '&uuid=' +
                  _self.uuid,
              );
            }
          },
          function () {
            _self.loading = false;
          },
        );
      }
    },

    // 改变字段分组的显示和隐藏
    changeFieldGroupStatus: function (fieldGroup) {
      fieldGroup.show = !fieldGroup.show;
      var index = this.tab.tabFormView.fieldGroups.indexOf(fieldGroup);
      if (index != -1) {
        this.tab.tabFormView.fieldGroups[index] = fieldGroup;
        localStorage.setItem(
          'FieldGroupStatus_' +
            this.windowNo +
            '_' +
            this.tabIndex +
            '_' +
            fieldGroup.groupName,
          fieldGroup.show,
        );
      }
    },

    /**
         * 执行Callout
         */
    executeCallout: function (fieldItem) {
      var _self = this;
      if (fieldItem.calloutProcessReportNo != null) {
        _self.callout(fieldItem.calloutProcessReportNo);
      }
    },

    // 值改变事件
    valueChanged: function (newFieldValue, fieldItem) {
      var _self = this;
      console.log(fieldItem.fieldName + ' ValueChanged.');
      console.log(newFieldValue);
      var oldFieldValue = this.modelData.data[fieldItem.fieldName];
      if (FieldUtil.isFieldValueEqual(newFieldValue, oldFieldValue) == false) {
        this.modelData.data[fieldItem.fieldName] = newFieldValue;
        if (
          fieldItem.calloutProcessReportNo != undefined &&
            fieldItem.calloutProcessReportNo != null
        ) {
          _self.callout(fieldItem.calloutProcessReportNo);
        }

        if (
          fieldItem.calloutLogical != undefined &&
            fieldItem.calloutLogical != null
        ) {
          _self.executeCalloutJs(fieldItem, fieldItem.calloutLogical);
        }

        if (
          _self.modelData.changed &&
            fieldItem.displayType == 'ListBoxEditor'
        ) {
          // 值改变时，刷新所有下拉框的keyValues
          _self.refreshSelectField(fieldItem.fieldName);
        }

        // add by jack 20170808
        _self.modelData.changed = true;

        let clearDynamicValidField = function (item) {
          var fieldName1 = item.fieldName;
          var dynamicValidFields = item.dynamicValidFields;
          if (
            fieldName0 != fieldName1 &&
              dynamicValidFields != undefined &&
              dynamicValidFields.indexOf(fieldName0) >= 0
          ) {
            var fieldValue0 = _self.modelData.data[fieldName1];
            fieldValue0.id = undefined;
            if (fieldValue0.displayValue != undefined) {
              fieldValue0.displayValue.splice(
                0,
                fieldValue0.displayValue.length,
              );
            } else {
              fieldValue0.displayValue = [];
            }
            _self.modelData.data[fieldName1] = fieldValue0;
          }
        };

        // 遍历所有的字段，判断是否有动态约束
        // 如果有关联的动态约束，则清空字段
        var fieldName0 = fieldItem.fieldName;
        _self.tabFormFields.forEach(function (item) {
          clearDynamicValidField(item);
        });

        let fieldGroups = _self.tab.tabFormView.fieldGroups;
        if (fieldGroups != null && fieldGroups.length > 0) {
          fieldGroups.forEach(fieldGroup => {
            if (fieldGroup.fields != null && fieldGroup.fields != null) {
              fieldGroup.fields.forEach(field => {
                clearDynamicValidField(field);
              });
            }
          });
        }
      }
    },

    // 刷新下拉选择框keyValues
    refreshSelectField: function (valueChangedFieldName) {
      var _self = this;

      if (_self.tabFormFields) {
        _self.tabFormFields.forEach(function (item) {
          if (item.displayType == 'ListBoxEditor') {
            var name1 = ':' + valueChangedFieldName;
            //var name2 = ":Parent_" + valueChangedFieldName;
            var showLogical = item.showLogical;
            if (showLogical != undefined && showLogical.indexOf(name1) >= 0) {
              refresh(item);
            }
          }
        });
      }

      if (_self.fieldGroup) {
        _self.fieldGroup.fields.forEach(function (item) {
          if (item.displayType == 'ListBoxEditor') {
            var name1 = ':' + valueChangedFieldName;
            //var name2 = ":Parent_" + valueChangedFieldName;
            var showLogical = item.showLogical;
            if (showLogical != undefined && showLogical.indexOf(name1) >= 0) {
              refresh(item);
            }
          }
        });
      }

      function refresh(item) {
        var obj = {
          windowNo: _self.windowNo,
          tabIndex: _self.tabIndex,
          fieldName: item.fieldName,
          modelData: _self.modelData,
        };

        console.log('WindowEdit RefreshField');

        $.ajax({
          url: Common.getApiURL('FieldResource/refreshField'),
          async: false,
          dataType: 'json',
          type: 'post',
          data: JSON.stringify(obj),
          contentType: 'application/json',
          beforeSend: function (request) {
            Common.addTokenToRequest(request);
          },
          success: function (data) {
            if (data != undefined) {
              item.keyValues = data.keyValues;
            }
          },
          error: function (XMLHttpRequest, textStatus, errorThrown) {
            Common.processException(XMLHttpRequest, textStatus, errorThrown);
          },
        });
      }
    },

    /**
         * 子页签触发父页签刷新
         * @return {[type]} [description]
         */
    refreshParent: function () {
      this.loadData();
    },

    /**
         * 执行JS Callout
         */
    executeCalloutJs: function (fieldItem, scriptText) {
      var _self = this;

      // add by jack 20180529
      var subTabChangedData = _self.getSubTabChangedData();
      if (subTabChangedData.length > 0) {
        _self.modelData.saveDatas = subTabChangedData;
      } else {
        _self.modelData.saveDatas = null;
      }

      let functionName = fieldItem.fieldName.replace('.', '_') + '_calloutjs';

      let executeFunction = function(){
        let actions = {
          subTabsRef: _self.getSubTabs(),
        };
        let context = new _self.getContext(_self.modelData, actions);
        try {
          _self[functionName](context);
        } catch (e) {
          console.error(e);
          Notify.error('数据字典定义异常', '【' + scriptText + '】前端列显示逻辑定义异常,请联系管理员检查数据字典的定义。', false);
        }
      };

      if (_self[functionName] == null) {
        // 执行服务端的脚本
        const jsUrl = _self.jsUrl;
        if (jsUrl == null || jsUrl == undefined) {
          Notify.error('数据字典定义异常', '【' + scriptText + '】Callout前端逻辑的JS文件不存在,请联系管理员检查数据字典是否JS文件。', false);
          return;
        }
        let promise = JsUtil.dynamicLoadJsFunction(jsUrl, scriptText);
        promise.then(targetFunction => {
          console.log(targetFunction);
          if (targetFunction == null) {
            Notify.error('数据字典定义异常', '【' + scriptText + '】Callout前端逻辑定义异常,请联系管理员检查数据字典的定义。', false);
            return;
          }

          _self[functionName] = targetFunction;
          executeFunction();
          
        }, errorData => {
          console.error(errorData);
        });
      } else {
        executeFunction();
      }
    },

    /**
         * callout
         * @param  {[type]} calloutProcessReportNo [description]
         * @return {[type]}                  [description]
         */
    callout: function (calloutProcessReportNo) {
      var _self = this;

      // add by jack 20180529
      var subTabChangedData = _self.getSubTabChangedData();
      if (subTabChangedData.length > 0) {
        _self.modelData.saveDatas = subTabChangedData;
      } else {
        _self.modelData.saveDatas = null;
      }

      // 查询流程和报表的定义
      ProcessReportResource.uniqueByNo(calloutProcessReportNo).then(
        successData => {
          if (successData == null) {
            return;
          }

          // 执行服务端的脚本
          ProcessReportResource.runCallout(
            calloutProcessReportNo,
            _self.modelData,
          ).then(
            successData => {
              if (successData && successData.modelData) {
                _self.modelData = successData.modelData;
              }
              // add by jack 20180529
              // add by jack 20220601
              _self.modelData.saveDatas = undefined;
            },
            errorData => {
              Common.processException(errorData);
            },
          );
        },
        errorData => {
          Common.processException(errorData);
        },
      );

    },

    // 获取子页签全部的数据
    getSubTabAllData: function () {
      var subTabAllRecords = [];
      if (this.tab.subTabs != undefined) {
        for (var index = 0; index < this.tab.subTabs.length; index++) {
          var subTabId = 'subTab' + this.tab.subTabs[index].tabIndex;
          var modelDatas = this.$refs[subTabId][0].getAllModelData();
          if (modelDatas != undefined && modelDatas.length > 0) {
            modelDatas.forEach(function (modelData) {
              subTabAllRecords.push(modelData);
            });
          }
        }
      }
      console.log(subTabAllRecords);
      return subTabAllRecords;
    },

    // 获取子页签发生改变的数据
    getSubTabChangedData: function () {
      var subTabChangedRecords = [];
      if (this.tab.subTabs != undefined) {
        for (var index = 0; index < this.tab.subTabs.length; index++) {
          var subTabId = 'subTab' + this.tab.subTabs[index].tabIndex;
          var modelDatas = this.$refs[subTabId][0].getChangedModelData();
          if (modelDatas != undefined && modelDatas.length > 0) {
            modelDatas.forEach(function (modelData) {
              subTabChangedRecords.push(modelData);
            });
          }
        }
      }
      console.log(subTabChangedRecords);
      return subTabChangedRecords;
    },
    // 获取子页签数据校验的Promise
    getSubTabValidatePromise: function () {
      var _self = this;

      var subTabValidates = [];
      if (this.tab.subTabs != undefined) {
        for (var index = 0; index < this.tab.subTabs.length; index++) {
          var subTabId = 'subTab' + this.tab.subTabs[index].tabIndex;
          var result = this.$refs[subTabId][0].performValidate();
          if (result != undefined && result.length > 0) {
            subTabValidates = subTabValidates.concat(result);
          }
        }
      }
      return subTabValidates;
    },

    /**
         * 表单字段的属性（显示）属性发生改变事件
         */
    tabFormFieldPropertyChanged: function (tabFormFieldClone) {
      TabFormView.restoreTabFormFieldDef(
        this.windowNo,
        this.tabIndex,
        this.tabFormFields,
      );
    },

    /**
         * 撤销提示
         */
    cancelModel: function () {
      var _self = this;
      _self.modal3 = true;
    },
    /**
         * 取消
         */
    cancelNo: function () {
      var _self = this;
      _self.modal3 = false;
    },
    /**
         * 撤销
         * @return {void}
         */
    cancelOk: function () {
      var _self = this;
      var currPage = _self.currPage;
      var currIndex = _self.currIndex;
      var totalCount = _self.totalCount;

      _self.cancelCommand = true;
      if (_self.recordId == null || _self.recordId == '') {
        _self.$router.push(
          '/desktop/window/' +
            _self.windowNo +
            '?currPage=' +
            currPage +
            '&uuid=' +
            this.uuid,
        );
      } else {
        // bug fixed by jack，编辑后直接取消
        // var cacheData = localStorage.getItem(_self.uuid);
        // if (cacheData != undefined && cacheData.length > 0) {
        //     cacheData = JSON.parse(cacheData);

        //     var window = cacheData.window;
        //     var tab = cacheData.tab;

        //     if (window == undefined || tab == undefined) {
        //         _self.$router.push('/desktop/window/' + _self.windowNo + "?currPage=" + currPage + "&uuid=" + this.uuid);
        //         return;
        //     }
        // }

        _self.$router.push(
          '/desktop/window/window-read/view/' +
            _self.windowNo +
            '/' +
            _self.tabIndex +
            '/' +
            _self.recordId +
            '?currPage=' +
            currPage +
            '&currIndex=' +
            currIndex +
            '&totalCount=' +
            totalCount +
            '&uuid=' +
            this.uuid,
        );
      }
      //删除草稿数据
      _self.deleteDataRecoveryDto();
    },
    /**
         * 子标题
         * @return {String} 子标题
         */
    subTitle: function () {
      var _self = this;
      var subTitle = '';
      if (_self.modelData != null && _self.modelData.data == null) {
        return subTitle;
      }
      if (
        _self.modelData != null &&
          _self.modelData.data != null &&
          _self.modelData.data.documentNo != null
      ) {
        subTitle =
            _self.modelData.data.documentNo.displayValue == null ?
              '' :
              _self.modelData.data.documentNo.displayValue[0];
      } else if (
        _self.modelData != null &&
          _self.modelData.data != null &&
          _self.modelData.data.no != null
      ) {
        subTitle =
            _self.modelData.data.no.displayValue == null ?
              '' :
              _self.modelData.data.no.displayValue[0];
      } else if (
        _self.modelData != null &&
          _self.modelData.data != null &&
          _self.modelData.data.name != null
      ) {
        subTitle =
            _self.modelData.data.name.displayValue == null ?
              '' :
              _self.modelData.data.name.displayValue[0];
      }
      return subTitle;
    },

    back: function () {
      var _self = this;
      _self.$router.push(
        '/desktop/window/' +
          _self.windowNo +
          '?currPage=' +
          _self.currPage +
          '&uuid=' +
          this.uuid,
      );
    },

    /**
         * 上一条数据
         * @return {void}
         */
    pre: function () {
      var _self = this;
      if (_self.isModelDataChanged() == true) {
        Notify.notice(_self.$t('lang.tabFormEdit.dataNotSaved'), _self.$t('lang.tabFormEdit.describe1'), false);
        return;
      }

      if (_self.currIndex <= 1) {
        return;
      }
      _self.currIndex--;
      var tabQueryParam = {
        range: {
          start: _self.currIndex - 1,
          length: 1,
        },
        tabIndex: _self.tabIndex,
        windowNo: _self.windowNo,
      };

      UserStorageResource.uniqueByKey(_self.uuid).then(
        successData => {
          // if(successData.errorCode != 0) {
          //   Notify.error('提示', successData.errorMessage, false);
          //   return;
          // }
          let simpleFilterParams = null;

          let complexFilterParams = null;

          if (successData.data != null && successData.data != '') {
            let temp = JSON.parse(successData.data);
            // 分页数据

            // 简单过滤条件
            tabQueryParam.simpleFilterCondition = temp.simpleFilterParams;
            // 复杂过滤条件
            tabQueryParam.filterParams = temp.complexFilterParams;
            // 排序
            tabQueryParam.sortStr = temp.sortStr;
          }

          _self.loadTabData(tabQueryParam);
        },
        errorData => {
          Common.processException(errorData);
        },
      );
    },

    /**
         * 下一条数据
         * @return {void}
         */
    next: function () {
      var _self = this;

      if (_self.isModelDataChanged() == true) {
        Notify.notice(_self.$t('lang.tabFormEdit.dataNotSaved'), _self.$t('lang.tabFormEdit.describe1'), false);
        return;
      }

      var totalCount = _self.totalCount;
      if (_self.currIndex >= totalCount) {
        return;
      }
      _self.currIndex++;
      var tabQueryParam = {
        range: {
          start: _self.currIndex - 1,
          length: 1,
        },
        tabIndex: _self.tabIndex,
        windowNo: _self.windowNo,
      };

      UserStorageResource.uniqueByKey(_self.uuid).then(
        successData => {
          // if(successData.errorCode != 0) {
          //   Notify.error('提示', successData.errorMessage, false);
          //   return;
          // }
          if (successData.data != null && successData.data != '') {
            let temp = JSON.parse(successData.data);
            // 分页数据

            // 简单过滤条件
            tabQueryParam.simpleFilterCondition = temp.simpleFilterParams;
            // 复杂过滤条件
            tabQueryParam.filterParams = temp.complexFilterParams;
            // 排序
            tabQueryParam.sortStr = temp.sortStr;
          }

          _self.loadTabData(tabQueryParam);
        },
        errorData => {
          Common.processException(errorData);
        },
      );
    },

    /**
         * 加载一条数据
         * @param  {Object} tabQueryParam 查询条件
         * @return {void}
         */
    loadTabData: function (tabQueryParam) {
      var _self = this;
      _self.loading = true;
      WindowServerUtil.queryTabData(
        tabQueryParam,
        function (gridData) {
          var dataLists = gridData.dataList;
          if (dataLists != undefined && dataLists.length > 0) {
            _self.modelData = dataLists[0];
          }
          _self.loading = false;
        },
        function () {
          _self.loading = false;
        },
      );
    },

    /**
         * 计算按钮坐标
         *
         */
    computerButtonGroupLeftTop: function () {
      var _self = this;
      var fixedButtonGroup = $(_self.$refs.fixedButtonGroup);
      if (fixedButtonGroup != undefined) {
        var offset = fixedButtonGroup.offset();
        if (offset != undefined) {
          _self.buttonGroupInitLeft = offset.left;
          _self.buttonGroupInitTop = offset.top;
        }
      }
    },

    /**
         * ModelData 是否发生变化
         */
    isModelDataChanged: function () {
      var _self = this;

      // 判断当前数据是否发生改变
      if (_self.modelData.changed == true) {
        return true;
      }

      // 判断子页签数据是否发生改变
      var subTabChangedData = _self.getSubTabChangedData();
      if (subTabChangedData != undefined && subTabChangedData.length > 0) {
        return true;
      }

      return false;
    },

    /**
         * 自动点击菜单
         */
    autoClickMenu: function () {
      var _self = this;
      // 判断是否有URL参数 自动点击菜单 canAutoClickMenu
      var canAutoClickMenu = Common.getRouteParam('canAutoClickMenu');

      if (
        (canAutoClickMenu == null || canAutoClickMenu == '') &&
          canAutoClickMenu != 'true'
      ) {
        const route1 = this.$route;
        let path = route1.path;
        let query = route1.query; // 这里可以用Vue的方法获取参数，也可以用正则的方法获取url中的参数
        
        query.canAutoClickMenu = true;

        // !!!!不推荐使用push的方式进行更新路由参数这样会增加路由的历史记录 (浏览器的后退键被破坏)
        this.$router.push({ path, query });
        
        // 推荐使用
        // this.$router.replace({path, query}); // 更新url上面的内容，且页面不会重载 / 刷新


        if (_self.type == 'create') {
          if (
            _self.tab &&
              _self.tab.tabButtons &&
              _self.tab.tabButtons.length > 0
          ) {
            for (var i = 0; i < _self.tab.tabButtons.length; i++) {
              var itemButton = _self.tab.tabButtons[i];
              if (itemButton.createAutoClick == true) {
                _self.backupView().then(
                  successData => {
                    _self.$refs.tabButton.execute(itemButton);
                  },
                  errorData => { },
                );
                break;
              }
            }
          }
        }
      }
    },

    /**
         * 开启草稿保存功能，每隔15秒保存一次
         * @author GuoZhiBo 20211008
         */
    startSaveInterval: function () {
      var _self = this;
      _self.autoSaveInterval = setInterval(function () {
        var subTabChangedData = _self.getSubTabChangedData();

        // bug fixed by jack
        // 这里不能对 _self.modelData.saveDatas 属性赋值，否则在 当页签的GridBody中修改了某个值以后，
        // 其监听 parentModelData 也会发生改变，导致性能很差
        var modelDataClone = JSON.parse(JSON.stringify(_self.modelData));
        if (subTabChangedData.length > 0) {
          var subTabChangedDataClone = JSON.parse(
            JSON.stringify(subTabChangedData),
          );
          modelDataClone.saveDatas = subTabChangedDataClone;
        } else {
          modelDataClone.saveDatas = null;
        }

        if (_self.dataRecoveryDto == undefined) {
          _self.dataRecoveryDto = {
            modelData: modelDataClone,
            windowId: _self.windowNo,
            type: _self.type,
          };
        } else {
          _self.dataRecoveryDto.modelData = modelDataClone;
        }
        DataRecoveryResource.saveDataRecoveryDto(
          _self.dataRecoveryDto,
          function (data) {
            console.log('草稿数据保存成功.');
          },
          function (xmlHttpRequest) {
            console.log('草稿数据保存失败: %s 。', xmlHttpRequest.responseText);
          },
        );
      }, 15000);
    },

    /**
         * 页签按钮的显示逻辑
         */
    tabButtonsShowLogical: function () {
      let _self = this;
      if (
        this.tab.tabFormView != null &&
          this.tab.tabFormView.tabButtons != null
      ) {
        for (
          let index = 0; index < this.tab.tabFormView.tabButtons.length; index++
        ) {
          let tabButton = this.tab.tabFormView.tabButtons[index];
          if (tabButton.editMode == true) {
            var logic = tabButton.showLogical;
            if (logic == null || logic == '') {
              tabButton.invisible = false;
              return;
            }
            
            let functionName = 'form_edit_show_logical_' + index;

            let executeFunction = function(){
              let actions = {
                subTabsRef: _self.getSubTabs(),
              };
              try {
                let context = new _self.getContext(_self.modelData, actions);
                tabButton.invisible = !_self[functionName](context);
              } catch (error) {
                console.error(error);
                Notify.error('数据字典定义异常', '【' + logic + '】按钮显示逻辑定义异常,请联系管理员检查数据字典的定义。', false);
              }
            };
            if (this[functionName] == null) {
              const jsUrl = this.jsUrl;
              if (jsUrl == null || jsUrl == undefined) {
                Notify.error('数据字典定义异常', '【' + logic + '】按钮显示逻辑的JS文件不存在,请联系管理员检查数据字典是否存在JS文件', false);
                return;
              }
              let promise = JsUtil.dynamicLoadJsFunction(jsUrl, logic);

              promise.then(targetFunction => {


                if (targetFunction == null) {
                  Notify.error('数据字典定义异常', '【' + logic + '】按钮显示逻辑逻辑定义异常,请联系管理员检查数据字典的定义', false);
                  return;
                }
                console.log(targetFunction);
                this[functionName] = targetFunction;
                executeFunction();
                
              }, errorData => {
                console.error(errorData);
              });
            } else {
              executeFunction();
            }
          }
        }
      }
    },

    /**
     * 调用保存后的业务逻辑
     */
    callAfterSaveLogical: function () {
      var _self = this;
      if (
        this.tab != null &&
          this.tab.tabFormView != null &&
          this.tab.tabFormView.logicalAfterSave != null &&
          this.tab.tabFormView.logicalAfterSave.length > 0
      ) {
        var logic = this.tab.tabFormView.logicalAfterSave;
        if (logic == null || logic == '') {
          return;
        }

        let functionName = 'form_edit_logical_after_save';

        const executeFunction = function (){
          let actions = {
            subTabsRef: _self.getSubTabs(),
          };

          let context = new _self.getContext(_self.modelData, actions);

          try{
            _self[functionName](context);	
          }catch(e){
            console.error(e);
            Notify.error('数据字典定义异常', '【' + logic + '】保存后业务逻辑定义异常,请联系管理员检查数据字典的定义。', false);
          }
        };


        if (_self[functionName] == null) {
          const jsUrl = this.jsUrl;
          if (jsUrl == null || jsUrl == undefined) {
            Notify.error('数据字典定义异常', '【' + logic + '】保存后业务逻辑的JS文件不存在,请联系管理员检查数据字典是否存在JS文件', false);
            return;
          }
          let promise = JsUtil.dynamicLoadJsFunction(jsUrl, logic);
          promise.then(targetFunction => {
          
          
            if(targetFunction == null){
              Notify.error('数据字典定义异常', '【' + logic + '】保存后业务逻辑定义异常,请联系管理员检查数据字典的定义。', false);
              return;
            }

            _self[functionName] = targetFunction;

            executeFunction();
          }, errorData => {
            console.error(errorData);
          });
        }else{
          executeFunction();
        }
      }
    },

    /**
         * 当页面卸载（关闭）或刷新时调用
         */
    beforeunloadFn: function (e) {
      e = e || window.event;
      if (e) {
        e.returnValue = '关闭提示';
      }
      return '关闭提示';
    },

    /**
         * 子页签(表格)修改父页签的数据
         * @param { String } fieldName 字段名称
         * @param { com.leanwo.prodog.restful.base.model.FieldValue } fieldValue 字段的值
         * @author YangZhiJie 20211012
         */
    changeRootParentModelData: function (data) {
      if (data === undefined || data === null) {
        console.error('子页签修改父页签的数据，但数据为空。');
        return;
      }

      const fieldName = data.fieldName;
      const fieldValue = data.fieldValue;

      if (fieldName === undefined || fieldName === null) {
        console.error(
          '子页签修改父页签的数据，但字段名称 %s 为空。',
          fieldName,
        );
        return;
      }

      if (fieldValue === undefined || fieldValue === null) {
        console.error('子页签修改父页签的数据，但字段值 %s 为空。', fieldName);
        return;
      }

      let fieldItem = null;

      for (let index = 0; index < this.tabFormFields.length; index++) {
        if (this.tabFormFields[index].fieldName === fieldName) {
          fieldItem = this.tabFormFields[index];
          break;
        }
      }

      if (fieldItem === null) {
        console.error(
          '子页签修改父页签的数据，但找不到字段 %s 的定义。',
          fieldName,
        );
        return;
      }

      console.debug('子页签修改父页签的数据。', fieldName, fieldValue);
      this.valueChanged(fieldValue, fieldItem);
    },
  },
};
</script>

<style scoped>
  .field-group {
    padding-left: 30px;
    padding-right: 30px;
  }

  .fieldGroup-head {
    cursor: pointer;
  }

  .a-back {
    cursor: pointer;
    text-decoration: none;
  }

  .m-space-btn-group {
    height: 34px;
  }

  .m-row {
    margin-bottom: 15px;
  }

  .fixed-btn-group {
    z-index: 3;
    background-color: #f7f7f7;
  }
</style>

<style>
  .btn-group-fixed {
    position: fixed;
    top: 0;
    left: 0;
    z-index: 3;
  }

  .m-image {
    height: 50px;
    cursor: pointer;
  }
</style>