<!-- eslint-disable no-unused-vars -->
<template>
  <div v-if="isMobile" class="mobile-template-form__detail">
    <van-nav-bar
      :title="formListName"
      :left-text="inDialog ? '关闭' : ''"
      :left-arrow="inDialog ? false : true"
      class="mobile-template-form__detail-header"
      :class="{ 'dialog-header': inDialog }"
      @click-left="handleGoBack"
    />
    <div v-if="loading" class="loading-wrap">
      <van-loading />
    </div>
    <ht-online-form
      v-if="html"
      ref="onlineForm"
      class="custom-form"
      :class="{ 'has-footer': isShow && action != 'editDraft' && showButton }"
      :html="html"
      :data="data"
      :mobile-mode="true"
      :permission="permission"
      :is-view="isView"
      :is-print="print"
      :extend-prop="extendProp"
      :inst-id="instId"
      @loadSuccess="loadSuccess"
      @setButtonDisabled="setButtonDisabled"
    />
    <footer
      v-if="isShow && action != 'editDraft' && !loading && showButton"
      class="mobile-template-form__detail-footer"
    >
      <van-button
        v-if="startFlow && startFlow != 'false' && action != 'get'"
        class="footer-flow-btn"
        style="margin-right: 10px"
        :disabled="disabled"
        @click="start"
      >
        {{ startLable }}
      </van-button>
      <van-button
        class="footer-btn"
        type="info"
        :disabled="disabled"
        @click="boSave()"
      >
        保存
      </van-button>
    </footer>
  </div>
  <el-main v-else class="base-main">
    <div class="base-main_box">
      <div v-if="isLoading" class="loading_custom_wrap">
        <i
          style="color: #2a8bfd; margin-right: 5px"
          class="el-icon-loading"
        ></i>
        <p class="loading_text">页面加载中...</p>
      </div>
      <div id="printData">
        <!-- <div v-if="!inDialog" class="form-container">
          <span>表单内容</span>
        </div> -->
        <div class="form-content">
          <form v-if="html">
            <ht-online-form
              ref="onlineForm"
              class="custom-form"
              :html="html"
              :data="data"
              :permission="permission"
              :is-view="isView"
              :is-print="print"
              :extend-prop="extendProp"
              :inst-id="instId"
              @loadSuccess="loadSuccess"
              @page-load-complete="isLoading = false"
              @setButtonDisabled="setButtonDisabled"
            />
          </form>
        </div>
      </div>
      <div v-if="showOperation" ref="btnRegion" class="base-main_bottom_btn">
        <el-button
          v-if="startFlow && startFlow != 'false' && action != 'get'"
          style="margin-right: 10px"
          type="success"
          :disabled="disabled"
          @click="start"
        >
          {{ startLable }}
        </el-button>
        <span
          v-for="btn in btnField"
          :key="btn.alias"
          class="base-main_bottom_btn_span"
        >
          <el-button
            v-if="
              ((btn.name === 'addData' && action !== 'add') ||
                (btn.name === 'addFlow' && action !== 'add') ||
                (btn.name === 'del' && action !== 'add') ||
                (btn.name === 'edit' && action === 'get') ||
                (flowBtnPermission[currentData['bpm_proc_inst_id_']] &&
                  flowBtnPermission[currentData['bpm_proc_inst_id_']][
                    btn.name
                  ])) &&
              btnPermission[btn.name]
            "
            v-btnShow="{
              beforeScriptValue: btn.beforeScriptValue,
              row: currentData,
              visual_formVar: btn.visual_formVar || '',
              visual_customQuery: btn.visual_customQuery || '',
              inner: true,
            }"
            class="data-form-list__top-btn"
            :type="btn.theme"
            @click="
              scriptClick(btn.name, btn.afterScriptValue || '', {
                templateId,
                action: 'edit',
                defId: defKey,
                isStartFlow: '',
                openType: btn.openType,
                quitAfterSaving: btn.quitAfterSaving,
                dialogWidth: btn.dialogWidth,
                dialogHeight: btn.dialogHeight,
                flowFormData: btn.flowFormData || '',
              })
            "
          >
            {{ btn.desc }}
          </el-button>
        </span>
        <span
          v-for="btn in btnConfig"
          :key="btn.alias"
          class="base-main_bottom_btn_span"
        >
          <el-button
            v-if="
              btn.alias == 'save' && btn.show && isShow && action != 'editDraft'
            "
            :type="btn.type"
            :disabled="disabled || isFormulasDisabled"
            @click="boSave()"
          >
            {{ btn.name }}
          </el-button>

          <el-button
            v-else-if="btn.alias == 'print' && btn.show"
            :type="btn.type"
            :disabled="disabled || isFormulasDisabled"
            @click="printDetail()"
          >
            {{ btn.name }}
          </el-button>
          <el-button
            v-else-if="btn.alias == 'back' && btn.show"
            :type="btn.type"
            @click="close(false)"
          >
            {{ btn.name }}
          </el-button>
          <el-button
            v-else-if="
              btn.alias != 'save' &&
              btn.alias != 'print' &&
              btn.alias != 'back' &&
              btn.show &&
              showExtendBtn
            "
            :type="btn.type"
            @click="evalCustomBtn(btn)"
          >
            {{ btn.name }}
          </el-button>
        </span>
      </div>
    </div>
    <ht-flow-chart
      ref="taskImage"
      :def-id="selectedDefId"
      :inst-id="selectedInstId"
    ></ht-flow-chart>
    <process-record
      ref="processRecord"
      :inst-id="selectedInstId"
      :def-id="selectedDefId"
      :task-id="selectedTaskId"
    ></process-record>
    <template-task-circulate
      ref="templateTaskCirculate"
    ></template-task-circulate>
  </el-main>
</template>
<script>
  import utils from '@/utils.js'
  import { encode, decode, isBase64 } from '@/util/base64'
  // eslint-disable-next-line no-unused-vars
  import $ from 'jquery'
  import { Base64 } from 'js-base64'
  import CustomQuery from 'hotent-ui/src/services/CustomQuery'

  const axios = require('axios')
  const req = function (url, data = {}, option = {}) {
    const requestData = {
      url: url,
      data: data,
      method: option.method || 'GET',
      params: option.params || {},
      onUploadProgress: option.onUploadProgress || null,
      headers: option.headers || '',
      responseType: option.responseType || 'json',
    }
    return axios(requestData)
  }

  const FLOW_BTNS = [
    'approval',
    'taskDetail',
    'taskImage',
    'history',
    'revoke',
    'phyDelete',
    'logicDelete',
    'taskToRead',
  ]

  export default {
    name: 'HtTemplateForm',
    props: {
      formulasDisabled: {
        // 公式联动的情况下不可编辑
        type: Boolean,
        default: false,
      },
      templateKey: {
        type: String,
      },
      action: {
        type: String,
      },
      isShare: {
        type: Boolean,
      },
      openType: {
        type: String,
      },
      dataParam: String,
      inDialog: {
        type: Boolean,
        default: false,
      },
      dialogParam: {
        type: Object,
      },
      editButtonData: {
        type: String,
      },
      isCustomHandleClose: {
        type: Boolean,
        default: false,
      },
      quitAfterSaving: {
        type: Boolean,
        default: false,
      },
      // 是否显示底部操作按钮
      showOperation: {
        type: Boolean,
        default: true,
      },
      showButton: {
        type: Boolean,
        default: true,
      },
      // 是否为移动端
      isMobile: {
        type: Boolean,
        default: false,
      },
      templateId: {
        type: String,
      },
      templateName: {
        type: String,
      },
      // 传参的instId优先级最高
      instIdProp: String,
    },
    data() {
      return {
        extendProp: { initFillData: false, instId: '' },
        ifSetInitSubData: false,
        alias_new: 'statement',
        html: null,
        formCss: null,
        data: null,
        permission: null,
        reloadOnlineForm: false,
        isView: false,
        disabled: false,
        boAlias: '',
        id: '',
        startFlow: false,
        recordId: '',
        defKey: '',
        formKey: '',
        fillField: '',
        fillValue: '',
        bindList: [],
        print: false,
        isShow: true,
        tempAlias: '',
        startLable: '发起流程',
        printLable: '打印',
        formListName: '',
        btnConfig: [],
        loading: false,
        isLoading: false,
        updateRefId: '',
        instId: '',
        isEditAuthByScript: true,
        isEditAuth: false,
        isFromAdd: false,
        editButtonId: '',
        manageField: [],
        pkField: '',
        selectedDefId: '',
        selectedInstId: '',
        selectedTaskId: '',
        flowBtnPermission: {},
        btnPermission: {},
        isFormulasDisabled: false,
      }
    },
    computed: {
      closeSave() {
        if (
          this.$route.query.quitAfterSaving &&
          this.$route.query.quitAfterSaving == 'true'
        ) {
          return true
        }
        return this.quitAfterSaving
      },
      // 是否显示页内额外扩展的按钮
      showExtendBtn() {
        if (
          this.startFlow &&
          this.startFlow != 'false' &&
          this.action != 'get'
        ) {
          return true
        }
        if (this.isShow && this.action != 'editDraft' && this.action != 'get') {
          return true
        }
        return false
      },
      btnField() {
        if (this.action === 'get') {
          return (
            this.manageField
              .filter((item) => !!item.innerPosition)
              .filter((item) => item.name !== 'add') || []
          )
        }
        if (this.action === 'add' || this.action === 'edit') {
          return (
            this.manageField
              .filter((item) => !!item.innerPosition)
              .filter((item) => item.name !== 'add' && item.name !== 'edit') ||
            []
          )
        }
        return []
      },
      // 获取打开方式以及操作后的跳转方式
      addBtnOption() {
        return this.manageField.find((item) => item.name === 'add') || {}
      },
      editBtnOption() {
        return this.manageField.find((item) => item.name === 'edit') || {}
      },
      currentData() {
        if (this.data && this.boAlias) {
          for (let field in this.permission.fields[this.boAlias]) {
            this.data[this.boAlias][`w${this.boAlias}f${field}`] =
              this.data[this.boAlias][field]
          }
          return this.data[this.boAlias]
        }
        return {}
      },
    },
    watch: {
      templateKey: function (n, o) {
        if (n && o && n != o) {
          this.init()
        }
      },
      //控件的联动会导致表单的permission发生变化，联动显示会变成'w'，需要改回原来的权限
      permission: {
        handler(newVal) {
          if (this.formKey && this.action == 'get') {
            for (let key in newVal.fields[this.formKey]) {
              if (newVal.fields[this.formKey][key] == 'w') {
                newVal.fields[this.formKey][key] = 'r'
              }
            }
          }
        },
        deep: true,
      },
      formCss: {
        handler(val, oldVal) {
          if (val && val !== oldVal) {
            this.setCss(val)
          }
        },
        immediate: true,
        deep: true,
      },
    },
    updated() {
      let result = window.location.href.split('?')[0].split('/')
      if (
        this.action == 'get' ||
        result[result.length - 1] == 'get' ||
        result[result.length - 2] == 'get'
      ) {
        this.isShow = false
      } else {
        this.isShow = true
      }

      //判断是否显示发起流程按钮
      if (
        window.location.href.split('?')[1] &&
        window.location.href.split('?')[1].includes('startFlow=false')
      ) {
        this.startFlow = false
      }
      if (
        this.dialogParam &&
        (this.dialogParam.isStartFlow || this.dialogParam.isKanban == 'true')
      ) {
        this.startFlow = false
      }
    },
    created() {
      // 如果url中带有初始化子表参数就赋值
      if (
        this.$route.query &&
        Object.keys(this.$route.query).includes('initSubData')
      ) {
        this.ifSetInitSubData = true
        this.extendProp.initFillData = this.$route.query.initSubData
      }
      this.isLoading = true
      this.init()
    },
    beforeDestroy() {
      const styleElement = document.getElementById('online-form-addStyle')
      if (styleElement) {
        document.getElementsByTagName('head')[0].removeChild(styleElement)
      }
    },
    methods: {
      setCss(css) {
        this.$nextTick(() => {
          if (this.formCss) {
            let style = document.createElement('style')
            style.id = 'online-form-addStyle'
            style.type = 'text/css'
            style.innerHTML = `div[name='online-form'] ${this.formCss}`
            document.head.appendChild(style)
          }
        })
      },
      setButtonDisabled(val) {
        this.isFormulasDisabled = val
      },

      evalCustomBtn(btn) {
        if (!btn.diyJs) {
          return
        }
        let _this = this
        let _req = req
        let _data = this.data

        function evil() {
          let Fn = Function('_req', '_this', '_data', btn.diyJs) //一个变量指向Function，防止有些前端编译工具报错
          let result = Fn(_req, _this, _data)
          return result
        }
        let resultValue = evil()
        return resultValue
      },
      // 通用打开url方法 js按钮中可以调用
      commonOpenUrl(url) {
        if (this.openType === 'new') {
          window.open(url, '_blank')
        } else if (this.openType === 'dialog') {
          this.$refs.templateIframeDialog.showDialog({
            url: url,
            dialogHeight: this.dialogHeight,
            dialogWidth: this.dialogWidth,
          })
        } else {
          window.location.href = url
        }
      },
      loadSuccess() {
        if (this.$route.query.isPrint) {
          this.printDetail()
        }
      },
      printDetail() {
        this.$refs.btnRegion.style.display = 'none'
        this.$store.state &&
          this.$store.state.user &&
          Object.keys(this.$store.state.user).includes('isPrintMode') &&
          this.$store.commit('user/setIsPrintMode', true)
        setTimeout(() => {
          //解决input输入框没有值的问题
          const input = $('input')
          input.each(function () {
            $(this).attr('value', $(this).val())
          })
          const textarea = $('textarea')
          if (textarea) {
            for (var i = 0; i < textarea.length; i++) {
              $(textarea[i]).html(textarea[i].value)
            }
          }

          document.body.innerHTML =
            document.getElementsByClassName('custom-form')[0].innerHTML
          document.body.setAttribute('style', 'background-color:white')
          window.print()
          this.$refs.btnRegion.style.display = 'block'
          location.reload()
        }, 500)
      },
      //获取表单数据
      async getFormData(verify) {
        if (document.activeElement) {
          document.activeElement.blur()
        }
        await this.$nextTick()
        return this.$refs.onlineForm.getData(verify)
      },
      //启动
      start() {
        this.getFormData(true)
          .then((formData) => this.processStart(formData))
          .catch(() => {})
      },
      processStart(formDataStr) {
        // utils.closeAllNotification()
        let data = { flowKey: this.defKey }
        if (formDataStr) {
          data.data = encode(JSON.stringify(formDataStr))
        }
        this.disabled = true
        this.$requestConfig
          .start(data)
          .then((res) => {
            if (this.isMobile) {
              this.$notify({ type: 'success', message: res.message })
              this.handleGoBack()
            } else {
              this.$message.success(res.message)
              this.close(true)
            }
          })
          .catch(() => {
            this.disabled = false
          })
      },
      //保存
      boSave(delDraftId) {
        this.getFormData(true)
          .then((formData) => {
            // utils.closeAllNotification()
            //判断是否有进行外键的绑定
            if (this.updateRefId) {
              this.$set(formData, 'updateRefId', this.updateRefId)
            }
            let data = {
              boAlias: this.boAlias,
              boData: formData,
            }
            this.disabled = true

            if (delDraftId) {
              data.delDraftId = delDraftId
            }

            if (this.action == 'edit') {
              this.$set(data, 'editButtonId', this.editButtonId)
            }
            data.formKey = this.formKey
            data.templateKey = this.templateKey
            this.$requestConfig
              .boSave(data)
              .then((result) => {
                if (result.state) {
                  if (this.isMobile) {
                    this.$notify({ type: 'success', message: result.message })
                  } else {
                    this.$message.success(result.message)
                  }

                  //当操作为编辑是，点击保存成功后提示继续编辑还是返回
                  if (this.action === 'edit') {
                    if (this.isMobile) {
                      this.handleMobileAddOrEdit(result)
                    } else {
                      if (this.action === 'editDraft') {
                        this.editDraftHandler()
                      } else {
                        this.handler()
                      }
                      let row = JSON.parse(result.value)
                      let templateId =
                        this.openType === 'dialog'
                          ? this.templateId
                          : this.$route.query.templateId
                      let templateName =
                        this.openType === 'dialog'
                          ? this.templateName
                          : this.$route.query.templateName
                      let openType = this.openType || this.$route.query.openType
                      if (
                        (this.$route.query &&
                          Object.keys(this.$route.query).includes(
                            'editButtonData'
                          )) ||
                        this.editButtonData
                      ) {
                        let data =
                          this.openType == 'dialog'
                            ? this.editButtonData
                            : this.$route.query.editButtonData
                        if (isBase64(data)) {
                          let editButtonData = JSON.parse(decode(data))
                          // this.editButtonId = editButtonData.buttonId
                          if (editButtonData.right) {
                            this.getStartFlowRight(editButtonData.right).then(
                              (res) => {
                                if (res) {
                                  this.isEditAuth = res
                                }
                              }
                            )
                          }
                          if (editButtonData.beforeScriptValue) {
                            let promise = this.beforeScript(
                              editButtonData.beforeScriptValue,
                              editButtonData
                            )
                            promise.then((res) => {
                              this.isEditAuthByScript = res
                            })
                          }
                        }
                      }
                      // 有编辑权限进入编辑，没编辑权限进入明细
                      setTimeout(async () => {
                        this.$refs.onlineForm.init()
                        this.disabled = false
                        let optionProp = this.action + 'BtnOption'
                        switch (this[optionProp].afterSaveShowType) {
                          case 'exit':
                            this.close()
                            break
                          case 'edit':
                            this.action = 'edit'
                            break
                          case 'detail':
                            this.action = 'get'
                            this.operating(
                              templateId,
                              row[0].pk,
                              'get',
                              '',
                              '',
                              openType,
                              false,
                              '',
                              false,
                              false,
                              templateName
                            )
                            break
                        }
                      }, 0)
                    }
                  } else if (this.action === 'add') {
                    if (this.isMobile) {
                      this.handleMobileAddOrEdit(result)
                    } else {
                      if (this.action === 'edit') {
                        this.$refs.onlineForm.init()
                        this.disabled = false
                        if (this.action === 'editDraft') {
                          this.editDraftHandler()
                        } else {
                          this.handler()
                        }
                      }
                      let row = JSON.parse(result.value)
                      let templateId =
                        this.openType === 'dialog'
                          ? this.templateId
                          : this.$route.query.templateId
                      let templateName =
                        this.openType === 'dialog'
                          ? this.templateName
                          : this.$route.query.templateName
                      let openType = this.openType || this.$route.query.openType
                      if (
                        (this.$route.query &&
                          Object.keys(this.$route.query).includes(
                            'editButtonData'
                          )) ||
                        this.editButtonData
                      ) {
                        let data =
                          this.openType == 'dialog'
                            ? this.editButtonData
                            : this.$route.query.editButtonData
                        if (isBase64(data)) {
                          let editButtonData = JSON.parse(decode(data))
                          this.editButtonId = editButtonData.buttonId
                          if (editButtonData.right) {
                            this.getStartFlowRight(editButtonData.right).then(
                              (res) => {
                                if (res) {
                                  this.isEditAuth = res
                                }
                              }
                            )
                          }
                          if (editButtonData.beforeScriptValue) {
                            let promise = this.beforeScript(
                              editButtonData.beforeScriptValue,
                              editButtonData
                            )
                            promise.then((res) => {
                              this.isEditAuthByScript = res
                            })
                          }
                        }
                      }
                      // 有编辑权限进入编辑，没编辑权限进入明细
                      setTimeout(async () => {
                        this.$refs.onlineForm.init()
                        this.disabled = false
                        let optionProp = this.action + 'BtnOption'
                        switch (this[optionProp].afterSaveShowType) {
                          case 'exit':
                            this.close()
                            break
                          case 'add':
                            this.action = 'add'
                            this.isFromAdd = true
                            this.operating(
                              templateId,
                              '',
                              'add',
                              '',
                              '',
                              openType,
                              true,
                              null,
                              false,
                              false,
                              templateName,
                              this.isFromAdd
                            )
                            break
                          case 'edit':
                            if (this.isEditAuth && this.isEditAuthByScript) {
                              if (this.action == 'add') {
                                this.isFromAdd = true
                              }
                              this.operating(
                                templateId,
                                row[0].pk,
                                'edit',
                                '',
                                '',
                                openType,
                                false,
                                null,
                                false,
                                false,
                                templateName,
                                this.isFromAdd
                              )
                            } else {
                              this.operating(
                                templateId,
                                row[0].pk,
                                'get',
                                '',
                                '',
                                openType,
                                false,
                                '',
                                false,
                                false,
                                templateName
                              )
                            }

                            break
                          case 'detail':
                            this.operating(
                              templateId,
                              row[0].pk,
                              'get',
                              '',
                              '',
                              openType,
                              false,
                              '',
                              false,
                              false,
                              templateName
                            )
                            break
                        }
                      }, 0)
                    }
                  } else {
                    if (this.isMobile) {
                      this.handleGoBack()
                    } else {
                      this.close(true)
                    }
                  }
                } else {
                  this.disabled = false
                }
              })
              .catch(() => {
                this.disabled = false
              })
          })
          .catch(() => {})
      },
      handleMobileAddOrEdit(result) {
        this.$notify({ type: 'success', message: result.message })
        this.$dialog
          .confirm({
            title: this.action === 'edit' ? '编辑' : '新增',
            message: '保存成功，是否退出？',
            className: 'delete-tip-dialog',
            confirmButtonText: '立即退出',
            cancelButtonText: '继续操作',
            beforeClose: (action, done) => {
              if (action === 'confirm') {
                this.$root.$emit('update-list', this.action)
                this.handleGoBack()
                done()
              } else {
                this.$refs.onlineForm.init()
                this.disabled = false
                if (this.action === 'editDraft') {
                  this.editDraftHandler()
                } else {
                  this.handler()
                }
                done()
              }
            },
          })
          .then(() => {})
          .catch(() => {})
      },
      boSaveAndDelDraft() {
        this.boSave(this.draftId)
      },
      //保存
      boSaveDraft() {
        this.getFormData(false)
          .then((formData) => {
            let data = {
              tempAlias: this.tempAlias,
              dataJson: JSON.stringify(formData),
            }
            if (this.draft) {
              data.id = this.draft.id
              data.title = this.draft.title
              data.createBy = this.draft.createBy
              data.createTime = this.draft.createTime
            }
            this.disabled = true
            this.$requestConfig.boSaveDraft(data).then((result) => {
              if (result.state) {
                this.$message.success(result.message)
                if (this.inDialog || this.isCustomHandleClose) {
                  this.$emit('close')
                } else {
                  this.$router.go(-1)
                }
              } else {
                this.disabled = false
                this.$message.error(result.message)
              }
            })
          })
          .catch(() => {})
      },

      //关闭窗口
      close() {
        //当是iframe打开的，则通过postMessage给父页面发送关闭消息 区分 页面 弹窗
        if (this.$route.query.isDialog) {
          window.parent.postMessage(
            {
              type: 'closeDialog',
              data: {},
            },
            '*'
          )
          return
        }
        //iframe tab 页面
        if (
          window.top !== window.self &&
          this.$route.query.openType &&
          this.$route.query.openType === 'old'
        ) {
          window.parent.postMessage(
            {
              type: 'closeIframePage',
              data: {
                fullPath: this.$route.fullPath,
              },
            },
            '*'
          )
        }

        if (this.inDialog || this.isCustomHandleClose) {
          this.$emit('close')
          return
        }

        // 应用中心，关闭页签
        if (this.$route.query.application) {
          sessionStorage.setItem('close-tab', new Date().getTime())
        }
        // 通过新页签打开页面，直接关闭
        if (this.$route.query.isNewPage) {
          window.close()
        }
        //从表单模块过来，返回上一页
        if (this.$route.query.applicationModule) {
          this.$router.go(-1)
        }
        //外链表单不返回问题
        if (sessionStorage.getItem('replaceHome')) {
          this.$router.push('/')
          sessionStorage.setItem('replaceHome', false)
        } else if (this.$requestConfig.goBack) {
          this.$requestConfig.goBack() ||
            this.$nextTick(() => this.$router.go(-1))
        } else {
          this.$router.go(-1)
        }
      },
      handler() {
        let _me = this
        this.$requestConfig
          .getDataTemplateForm(
            this.formKey,
            this.boAlias,
            this.id || '',
            this.action,
            this.recordId || '',
            this.templateKey || '',
            this.editButtonId || ''
          )
          .then((rep) => {
            if (rep.result) {
              // 加载水印
              _me.$emit('loaded', rep.form)
              _me.data = rep.data
              //数据视图控件
              if (_me.bindList && _me.bindList.length > 0) {
                for (var i = 0; i < _me.bindList.length; i++) {
                  if (_me.data[_me.boAlias][_me.bindList[i].key] == '') {
                    // 回填数据
                    _me.data[_me.boAlias][_me.bindList[i].key] =
                      _me.bindList[i].value
                  }
                  if (_me.data[_me.boAlias]['F_' + _me.bindList[i].key] == '') {
                    // 外部表回填数据
                    _me.data[_me.boAlias]['F_' + _me.bindList[i].key] =
                      _me.bindList[i].value
                  }
                  //数据视图绑定外键
                  if (_me.bindList[i].key == 'ref_id_') {
                    _me.data[_me.boAlias]['ref_id_'] = _me.bindList[i].value
                    _me.data[_me.boAlias]['REF_ID_'] = _me.bindList[i].value
                  }
                }
              }
              //是否是数据报表明细
              if (rep.permission && _me.action == 'get') {
                const permissionObj = rep.permission
                let commonRight = ''
                //如果是管理端进入，则将页面字段的权限修改为可编辑
                if (_me.type == 'manage') {
                  commonRight = 'w'
                  //如果是查看实例，也是获取发起流程的表单和权限。只不过所有可见的权限要变成编辑
                } else {
                  commonRight = 'r'
                }
                if (permissionObj.fields && commonRight) {
                  for (let key in permissionObj.fields) {
                    const bodef = permissionObj.fields[key]
                    if (bodef) {
                      for (var fname in bodef) {
                        if (
                          commonRight == 'w' ||
                          (commonRight == 'r' && bodef[fname] != 'n')
                        ) {
                          bodef[fname] = commonRight
                        }
                      }
                    }
                    permissionObj.fields[key] = bodef
                  }
                }
                if (permissionObj.table && commonRight) {
                  for (let key in permissionObj.table) {
                    const table = permissionObj.table[key]
                    if (table) {
                      if (commonRight == 'w') {
                        table['hidden'] = false
                        table['add'] = true
                        table['del'] = true
                      } else if (commonRight == 'r') {
                        table['add'] = false
                        table['del'] = false
                        table['required'] = false
                        table['edit'] = false
                      }
                    }
                    permissionObj.table[key] = table
                  }
                }
                _me.permission = permissionObj
              } else {
                _me.permission = rep.permission
              }
              _me.html = rep.form.formHtml
              _me.formCss = rep.form.formCss
              this.handlerJs(rep.form)
              this.handlerParams()
              this.getFlowInfo()
              this.getManagePermissions()
            }
          })
          .finally(() => {
            this.loading = false
          })
      },
      handlerJs(rep) {
        let _this = this
        _this.reloadOnlineForm = true
        // eslint-disable-next-line no-unused-vars
        let data = this.data
        const $ = require('jquery')
        setTimeout(() => {
          eval(rep.diyJs)
        }, 10)
      },
      handlerParams() {
        if (this.$route.query.fillType === 'sub') {
          this.handlerFillSubParams()
          return
        }
        if (this.dataParam) {
          let data = this.dataParam
          if (isBase64(this.dataParam)) {
            data = decode(this.dataParam)
          }
          if (data) {
            if (this.isJSON(data)) {
              let parameters = JSON.parse(data)
              let keys = Object.keys(this.data)
              if (!keys.includes(this.boAlias)) {
                this.data[this.boAlias] = {}
              }
              for (let key in parameters) {
                this.$set(this.data[this.boAlias], key, parameters[key])
              }
              //获取是否有绑定的外键更新字段
              if (parameters.updateRefId) {
                this.updateRefId = parameters.updateRefId
              }
              this.$forceUpdate()
            }
          }
        }
      },
      async getFlowInfo() {
        let this_ = this
        let row = this_.data[this_.boAlias]
        let resp = await this.$requestConfig.getInstanceByPks(
          [row[this.pkField]],
          this.boAlias,
          this.defKey
        )

        if (resp && resp.state) {
          let map = resp.value

          let objNode = map[row[this_.pkField]]
          if (objNode) {
            Object.keys(objNode).forEach((key) => {
              this_.$set(row, key, objNode[key])
            })
            this_.$set(row, 'bpm_proc_inst_load_done', true)
          }

          this.$forceUpdate()
        }

        let btns = this.manageField
          .filter((item) => FLOW_BTNS.includes(item.name))
          .map((item) => item.name)

        let permissionTypes = btns.join(',')
        let instanceId = this.data[this.boAlias]['bpm_proc_inst_id_']
        if (permissionTypes && instanceId) {
          let response =
            await this.$requestConfig.getDataTemplateButtonPermission(
              [instanceId],
              permissionTypes
            )
          response.value.forEach((item) => {
            let { instId } = item
            this.$set(this.flowBtnPermission, instId, item)
          })
          this.multipleTemplateTableloading = false
        }
      },
      async getManagePermissions() {
        let templateId =
          this.openType === 'dialog'
            ? this.templateId
            : this.$route.query.templateId
        if (templateId) {
          this.btnPermission = await this.$requestConfig.getManagePermissions(
            templateId
          )
        }
      },
      handlerFillSubParams() {
        // 配置的子表反填走单独的逻辑
        const sessionStorageKey = this.$route.query.data
        const sessionStorageDataStr = sessionStorage.getItem(sessionStorageKey)
        if (sessionStorageDataStr) {
          const sessionStorageData = JSON.parse(sessionStorageDataStr)
          if (sessionStorageData) {
            for (const subField in sessionStorageData) {
              const item = sessionStorageData[subField]
              item.forEach((param) => {
                Object.keys(this.data).forEach((boDefAlias) => {
                  let result = {}
                  for (let key in param) {
                    result[key] = param[key]
                  }
                  this.data[boDefAlias][subField].push(result)
                })
              })
            }
          }
          this.$forceUpdate()
        }
      },
      //判断是否为json字符串
      isJSON(str) {
        if (typeof str == 'string') {
          try {
            var obj = JSON.parse(str)
            if (typeof obj == 'object' && obj) {
              return true
            } else {
              return false
            }
          } catch (e) {
            return false
          }
        } else {
          return false
        }
      },
      editDraftHandler() {
        let _me = this
        this.$requestConfig
          .getTempDraftData(_me.draftId)
          .then((rep) => {
            if (rep.result) {
              _me.data = rep.data
              _me.draft = rep.draft
              if (rep.permission) {
                _me.permission = rep.permission
              }
              _me.html = rep.form.formHtml
              this.handlerJs(rep.form)
            }
          })
          .catch(() => {
            this.loading = false
          })
      },
      // 根据 新增 按钮判断是否子表初始化【新增数据 按钮】
      checkInitSubData(templateInfo) {
        if (templateInfo && templateInfo.manageField) {
          const manages = utils.parseToJson(templateInfo.manageField)
          const btnsAdd = manages.filter(
            (item) => item.name === 'add' && item.initSubData
          )
          if (btnsAdd && btnsAdd.length > 0) {
            return true
          }
        }
        return false
      },
      init() {
        this.loading = true
        this.id = this.inDialog ? this.dialogParam.id : utils.getUrlKey('id')
        this.editButtonId = this.inDialog
          ? this.dialogParam.editButtonId
          : utils.getUrlKey('editButtonId')
        if (this.action === 'add') {
          // 添加时清空实例ID
          this.instId = ''
        } else {
          this.instId =
            this.instIdProp && this.instIdProp != ''
              ? this.instIdProp
              : utils.getUrlKey('instId')
        }
        this.extendProp.instId = this.instId
        //this.startFlow = utils.getUrlKey('startFlow');
        this.recordId = this.inDialog
          ? this.dialogParam.recordId
          : utils.getUrlKey('recordId')
        let bindList = this.inDialog
          ? this.dialogParam.bindList
          : utils.getUrlKey('bindList')
        if (bindList) {
          this.bindList = JSON.parse(decode(decodeURIComponent(bindList)))
        }
        this.draftId = this.inDialog
          ? this.dialogParam.draftId
          : utils.getUrlKey('draftId')
        this.isView = this.action == 'get'
        let _me = this

        this.$requestConfig
          .getBpmDataTemplateInfo({
            templateKey: this.templateKey,
          })
          .then((result) => {
            if (result.state) {
              // _me.$emit('loaded', result.value)
              if (!_me.ifSetInitSubData) {
                const initFillData = _me.checkInitSubData(result.value)
                _me.$set(_me.extendProp, 'initFillData', initFillData)
              }

              this.formListName = result.value.formName
              if (result.value.allowShare == 2 && _me.isShare) {
                _me.$router.push('/messageFillPage/5')
                return
              }
              _me.boAlias = result.value.boDefAlias
              _me.defKey = result.value.defId
              _me.pkField = result.value.pkField
              _me.formKey =
                utils.isMobile() || _me.isMobile
                  ? result.value.mobileFormAlias
                  : result.value.formKey
              _me.tempAlias = result.value.alias

              if (result.value.innerBtnConfig) {
                this.btnConfig = JSON.parse(decode(result.value.innerBtnConfig))
              }
              if (_me.isMobile) {
                if (result.value.manageField) {
                  let mobileResult = JSON.parse(result.value.manageField)
                  mobileResult.forEach((item) => {
                    if (item.name == 'startFlow' && item.mpDisplay == '1') {
                      if (item.right) {
                        this.getStartFlowRight(item.right)
                          .then((res) => {
                            if (res) {
                              this.startFlow = true
                              this.startLable = item.desc
                            } else {
                              this.startFlow = false
                            }
                          })
                          .catch(() => {
                            this.startFlow = false
                            this.loading = false
                          })
                      }
                    } else if (item.name == 'print') {
                      this.printLable = item.desc
                    }
                  })
                } else {
                  this.startFlow = true
                }
              } else {
                if (result.value.manageField) {
                  let re = JSON.parse(result.value.manageField)
                  this.manageField = re
                  re.forEach((item) => {
                    if (item.name == 'startFlow') {
                      if (item.right) {
                        this.getStartFlowRight(item.right)
                          .then((res) => {
                            if (res) {
                              this.startFlow = true
                              this.startLable = item.desc
                            } else {
                              this.startFlow = false
                            }
                          })
                          .catch(() => {
                            this.startFlow = false
                            this.loading = false
                          })
                      }
                    } else if (item.name == 'print') {
                      this.printLable = item.desc
                    }
                  })
                } else {
                  this.startFlow = true
                }
              }
              this.reloadOnlineForm = false
              //如果编辑的是草稿数据
              if (this.action === 'editDraft') {
                this.editDraftHandler()
              } else {
                this.handler()
              }
            }
          })
          .catch(() => {
            this.loading = false
          })
      },
      getStartFlowRight(rightStr) {
        return new Promise((resolve) => {
          let rightArr = JSON.parse(rightStr)
          for (let i = 0; i < rightArr.length; i++) {
            let right = rightArr[i]
            if (right.type == 'everyone') {
              resolve(true)
              return
            }
          }
          let userId = this.$requestConfig.getUserId()
          this.$requestConfig.getUserRightMapByIds(userId).then((resp) => {
            let rightMap = resp[userId]
            for (let i = 0; i < rightArr.length; i++) {
              let type = rightArr[i].type == 'pos' ? 'job' : rightArr[i].type
              if (this.calcAuth(rightArr[i].id, rightMap[type])) {
                resolve(true)
                return
              }
            }
            resolve(false)
          })
        })
      },
      //计算权限
      calcAuth(btnIds, userIds) {
        if (!btnIds || !userIds) {
          return false
        }
        let btnIdsArr = btnIds.split(',')
        let userIdsArr = userIds.replace(/'/g, '').split(',')
        return userIdsArr.some((item) => {
          return btnIdsArr.includes(item)
        })
      },
      handleGoBack() {
        if (this.inDialog) {
          this.$emit('close')
        } else {
          this.$router.go(-1)
        }
      },
      tempScript(script, row) {
        if (script == undefined || script == '') {
          return true
        }
        let _this = this

        let _req = req
        let _rows = this.rows
        let _row = row
        function evil() {
          let Fn = Function('_req', '_this', '_rows', '_row', script) //一个变量指向Function，防止有些前端编译工具报错
          let result = Fn(_req, _this, _rows, _row)
          return result
        }
        let resultValue = evil()
        return resultValue
      },
      //编辑按钮的前置脚本
      async beforeScript(diyScript, row) {
        if (diyScript) {
          let script = decode(diyScript)
          let scriptResult = await this.tempScript(script, row)
          return scriptResult
        } else {
          return true
        }
      },
      //新增保存后的执行逻辑,按新增配置的打开方式来展示明细或者编辑
      operating(
        templateId,
        id,
        action,
        defId,
        isStartFlow,
        openType,
        quitAfterSaving,
        dataParam,
        initSubData = false,
        isKanban,
        templateName,
        isFromAdd
      ) {
        this.action = action
        this.id = id
        const buttonName =
          action === 'edit' ? '编辑' : action === 'add' ? '新增' : '明细'
        if (action === 'edit' && isStartFlow === false) {
          isStartFlow = true
        }
        var url = '/templateForm/' + this.templateKey + '/' + action
        if (id) {
          url = url + '?id=' + id + '&'
        } else {
          url += '?'
        }
        if (this.editButtonId) {
          url = url + 'editButtonId=' + this.editButtonId + '&'
        }
        let startFlowStr = 'startFlow=false'
        // 看板禁用启动流程功能
        if (isKanban !== 'true') {
          if (id && isStartFlow === false && defId) {
            startFlowStr = 'startFlow=true'
          }
          let dataUrl = ''
          let path = url + startFlowStr
          if (dataUrl !== '') {
            path = url + startFlowStr + dataUrl
          }
          //如果是刷新界面，则继续拼接如下参数
          if (this.templateKey) {
            const symbol = `${templateName}_${buttonName}`
            path = `${path}${
              path.indexOf('?') !== -1
                ? `&extendParam=${symbol}`
                : `?extendParam=${symbol}`
            }`
          }
          if (openType === 'new' && !this.isMobile) {
            window.open(
              this.$router.resolve({
                path: path + '&isNewPage=true',
                query: {
                  quitAfterSaving,
                  dataParam: dataParam ? encode(JSON.stringify(dataParam)) : '',
                  initSubData,
                },
              }).href,
              '_self'
            )
          } else if (
            (openType === 'dialog' || openType === 'drawer') &&
            !this.isMobile
          ) {
            this.handler()
          } else {
            const routePath = {
              path: path,
              query: {
                quitAfterSaving,
                dataParam: dataParam ? encode(JSON.stringify(dataParam)) : '',
                initSubData,
                date: new Date().getTime(),
              },
            }
            if (this.templateKey) {
              //构建meta中的title
              routePath.meta = {
                title: `${templateName}_${buttonName}`,
              }
              //extend 标记是拓展业务标记
              routePath.params = {
                templateKey: this.templateKey,
                action,
                extend: true,
              }
              //通知路由，新增了个路由，需要更新
              if (this.$store && this.$store.dispatch) {
                try {
                  this.$store.dispatch('tabsBar/addVisitedRoute', routePath)
                } catch (e) {
                  console.warn('Failed to dispatch tabsBar/addVisitedRoute:', e)
                }
              }
            }
            if (isFromAdd) {
              // 如果是front端有tab
              if (this.$tabs && this.$tabs.close) {
                this.$tabs.close({
                  to: `${routePath.path}?${utils.convertObj(routePath.query)}`,
                })
              } else {
                // 此处保留原来的监听router reload逻辑
                this.$router.replace(routePath)
                setTimeout(() => {
                  window.location.reload()
                })
              }
            } else {
              // 使用 push 方法更新路由参数
              this.$router.push({
                path: routePath.path,
                params: routePath.params,
              })
            }
          }
        }
      },
      async scriptClick(btnAlias, afterScriptValue, parameter) {
        let row = this.data[this.boAlias]
        //后置脚本执行结果为false则不执行下面的逻辑
        if (afterScriptValue) {
          let script = Base64.decode(afterScriptValue)
          let scriptResult = await this.tempScript(script, row)
          if (!scriptResult) {
            return
          }
        }
        switch (btnAlias) {
          case 'edit':
            this.editOperating(
              parameter.templateId,
              row[this.pkField],
              parameter.action,
              parameter.defId,
              parameter.isStartFlow,
              parameter.openType,
              parameter.quitAfterSaving,
              null,
              false,
              '',
              row,
              '',
              '',
              parameter.buttonId
            )
            break
          case 'addFlow':
            this.addFlow(parameter.flowFormData, row)
            break
          case 'taskImage':
            this.showRef(row, afterScriptValue, parameter, () =>
              this.$refs.taskImage.handleOpen()
            )
            break
          case 'history':
            this.showRef(row, afterScriptValue, parameter, () =>
              this.$refs.processRecord.showDialog()
            )
            break
          case 'phyDelete':
            this.phyDelete(row, afterScriptValue, parameter)
            break
          case 'logicDelete':
            this.logicDelete(row, afterScriptValue, parameter)
            break
          case 'taskToRead':
            this.taskToRead(row, afterScriptValue, parameter)
            break
          case 'revoke':
            this.handleRevoke(row, afterScriptValue, parameter)
            break
          case 'addData':
            this.addData(parameter.flowFormData, row)
            break
          case 'del':
            this.del(row[this.pkField])
            break
          case 'taskDetail':
            this.showTaskDetail(row, afterScriptValue, parameter)
            break
          case 'approval':
            this.handleApproval(row, afterScriptValue, parameter)
            break
          default:
            break
        }
      },
      async addFlow(manageFlowFormData, row) {
        let flowFormData = JSON.parse(Base64.decode(manageFlowFormData))

        // 处理流程定义ID参数，使用主版本
        var defId = null
        var defKey = flowFormData.flow.key
        if (defKey) {
          // 获取流程定义信息
          var res = await this.$requestConfig.getMainDefDesignByKey(defKey)
          if (res && res.state) {
            if (res.value && res.value.defId !== this.defId) {
              defId = res.value.defId
            }
          }
        }

        // 如果是子表的反填配置，走单独的逻辑
        if (flowFormData.isSub && row) {
          const resultData = this.handleBuildAddFlowOrDataBySubField(
            flowFormData,
            row
          )
          const sessionStorageKey = `${this.templateKey}_flow_sub_list`
          this.$requestConfig
            .saveSubDataTemp(sessionStorageKey, JSON.stringify(resultData))
            .then(() => {
              let param = {
                bizType: 'startFlow',
                openType: flowFormData.openType,
                parameters: {
                  defId: defId,
                  flowKey: flowFormData.flow.key,
                  fillType: flowFormData.isSub ? 'sub' : 'main',
                  data: sessionStorageKey, // 由于担心勾选数据多配置也多情况，如果全部用url传递可能导致url过长导致服务器错误，因此子表的情况，此处只存放对应的sessionStorage的 key
                },
              }
              this.$requestConfig.openUrl(param)
            })
          return
        }

        if (row) {
          let data = {}
          if (flowFormData.paramFields && flowFormData.paramFields.length > 0) {
            flowFormData.paramFields.forEach((obj) => {
              for (let key in row) {
                if (obj.sourceField.toLowerCase().endsWith(key.toLowerCase())) {
                  data[obj.targetField] = row[key]
                }
              }
            })
          }

          let param = {
            bizType: 'startFlow',
            openType: flowFormData.openType,
            parameters: {
              defId: defId,
              flowKey: flowFormData.flow.key,
              fillType: 'main',
              data: encodeURIComponent(Base64.encode(JSON.stringify(data))),
            },
          }
          this.$requestConfig.openUrl(param)
        } else {
          let param = {
            bizType: 'startFlow',
            openType: flowFormData.openType,
            parameters: {
              defId: defId,
              flowKey: flowFormData.flow.key,
              data: '',
            },
          }
          this.$requestConfig.openUrl(param)
        }
      },
      async editOperating(
        templateId,
        id,
        action,
        defId,
        isStartFlow,
        openType,
        quitAfterSaving,
        dataParam,
        initSubData = false,
        isKanban,
        row,
        clickType,
        afterScriptValue,
        buttonId
      ) {
        //后置脚本执行结果为false则不执行下面的逻辑
        if (afterScriptValue) {
          let script = Base64.decode(afterScriptValue)
          let scriptResult = await this.tempScript(script, row)
          if (!scriptResult) {
            return
          }
        }
        this.action = action
        this.id = id
        var url = '/templateForm/' + this.templateKey + '/' + action

        if (openType == 'new' && !this.isMobile) {
          url += '/new'
        }

        if (id) {
          url = url + '?id=' + id + '&'
        } else {
          url += '?'
        }
        let startFlowStr = 'startFlow=false'
        let path = url + startFlowStr
        let templateName = this.$route.query.templateName
        //TODO 如果是模块开发 全部已新窗口打开,pc表单】表单列表/甘特图/看板/思维导图拿按钮配置的打开方式
        const instId =
          row && row['bpm_proc_inst_id_'] ? row['bpm_proc_inst_id_'] : null
        //编辑新页签打开时携带title
        if (id && action == 'edit' && openType == 'new') {
          const symbol = `${templateName}_编辑`
          path = `${path}${
            path.indexOf('?') !== -1
              ? `&extendParam=${symbol}`
              : `?extendParam=${symbol}`
          }`
        }
        //TODO 如果是模块开发 全部已新窗口打开
        if (openType == 'new' && !this.isMobile) {
          //新增、编辑加上isFull参数
          if (action == 'edit') {
            path = path + '&__isFull__=true'
          }
          window.open(
            this.$router.resolve({
              path: path + '&isNewPage=true',
              query: {
                quitAfterSaving,
                dataParam: dataParam
                  ? Base64.encode(JSON.stringify(dataParam))
                  : '',
                initSubData,
                instId: instId,
                editButtonData: '',
                templateId,
                templateName,
                openType,
                editButtonId: buttonId,
              },
            }).href,
            '_blank'
          )
        } else if (
          (openType === 'dialog' || openType === 'drawer') &&
          !this.isMobile
        ) {
          this.handler()
        } else {
          const routePath = {
            path,
            query: {
              quitAfterSaving,
              dataParam: dataParam
                ? Base64.encode(JSON.stringify(dataParam))
                : '',
              initSubData,
              instId: instId,
              editButtonData: '',
              templateId,
              templateName,
              openType,
              editButtonId: buttonId,
            },
          }
          this.$router.push(routePath)
        }
      },
      async showRef(row, afterScriptValue, parameter, refCallback) {
        let rows = parameter.row
        //后置脚本执行结果为false则不执行下面的逻辑
        if (afterScriptValue) {
          let script = Base64.decode(afterScriptValue)
          let scriptResult = await this.tempScript(script, rows)
          if (!scriptResult) {
            return
          }
        }
        this.selectedDefId = row['bpm_proc_def_id_']
        this.selectedInstId = row['bpm_proc_inst_id_']
        this.$nextTick(() => {
          refCallback()
        })
      },
      //物理删除(草稿),会把表单数据也删除
      async phyDelete(row, afterScriptValue, parameter) {
        let rows = parameter.row
        //后置脚本执行结果为false则不执行下面的逻辑
        if (afterScriptValue) {
          let script = Base64.decode(afterScriptValue)
          let scriptResult = await this.tempScript(script, rows)
          if (!scriptResult) {
            return
          }
        }
        this.$confirm('删除后无法恢复，是否确定该流程草稿？', '提示')
          .then(() => {
            let id = row['bpm_proc_inst_id_']
            this.$requestConfig.removeFlowById(id).then((response) => {
              if (response.state) {
                this.$message.success('删除草稿成功')
                this.close()
              }
            })
          })
          .catch(() => {})
      },
      //逻辑删除流程实例
      async logicDelete(row, afterScriptValue, parameter) {
        let rows = parameter.row
        //后置脚本执行结果为false则不执行下面的逻辑
        if (afterScriptValue) {
          let script = Base64.decode(afterScriptValue)
          let scriptResult = await this.tempScript(script, rows)
          if (!scriptResult) {
            return
          }
        }
        let instId = row['bpm_proc_inst_id_']
        this.$confirm('确认删除此流程?', '提示', {
          cancelButtonText: '取消',
          confirmButtonText: '确定',
          type: 'warning',
          closeOnClickModal: false,
        }).then(() => {
          this.$requestConfig.removeFlowById(instId).then((response) => {
            if (response.state) {
              this.$message.success(response.message)
              this.close()
            } else {
              this.$message.error(response.message)
            }
          })
        })
      },
      async taskToRead(row, afterScriptValue, parameter) {
        let rows = parameter.row
        //后置脚本执行结果为false则不执行下面的逻辑
        if (afterScriptValue) {
          let script = Base64.decode(afterScriptValue)
          let scriptResult = await this.tempScript(script, rows)
          if (!scriptResult) {
            return
          }
        }
        this.$refs['templateTaskCirculate'].showDialog(
          row,
          this.flowBtnPermission
        )
      },
      async handleRevoke(row, afterScriptValue, parameter) {
        let rows = parameter.row
        //后置脚本执行结果为false则不执行下面的逻辑
        if (afterScriptValue) {
          let script = Base64.decode(afterScriptValue)
          let scriptResult = await this.tempScript(script, rows)
          if (!scriptResult) {
            return
          }
        }
        let instId = row['bpm_proc_inst_id_']
        let status = row['bpm_status_']
        if (status === 'revokeToStart') {
          this.$message.warning('已撤回， 不能再撤回')
          return
        }
        if (status === 'end') {
          this.$message.warning('任务已办结， 不能再撤回')
          return
        }
        this.selectedInstId = instId
        let data = {
          instanceId: instId,
          isHandRevoke: false,
        }
        this.$prompt('请输入撤回原因', '提示')
          .then(({ value }) => {
            data.cause = value
            this.$requestConfig.saveRevoke(data).then((response) => {
              this.$message.success(response.message)
              this.search('find')
            })
          })
          .catch(() => {})
      },
      handleBuildAddFlowOrDataBySubField(flowFormData, row) {
        var resultData = {}
        if (flowFormData.paramFields && flowFormData.paramFields.length > 0) {
          let result = {}
          let subField = ''
          flowFormData.paramFields.forEach((obj) => {
            if (obj.targetField && obj.targetField.split('.').length) {
              let field = ''
              subField = obj.targetField.split('.')[0]
              field = obj.targetField.split('.')[1]
              for (let key in row) {
                if (obj.sourceField.toLowerCase().endsWith(key.toLowerCase())) {
                  result[field] = row[key]
                  break
                }
              }
            }
          })
          resultData = {
            [subField]: [result],
          }
        }

        return resultData
      },
      addData(manageFlowFormData, row) {
        let flowFormData = JSON.parse(Base64.decode(manageFlowFormData))
        if (!row) {
          return
        }
        // 如果是子表的反填配置，走单独的逻辑
        if (flowFormData.isSub) {
          const resultData = this.handleBuildAddFlowOrDataBySubField(
            flowFormData,
            row
          )
          const sessionStorageKey = `${this.templateKey}_data_sub_list`
          // 先清除上一次的
          sessionStorage.removeItem(sessionStorageKey)
          // 再保存这一次的
          sessionStorage.setItem(sessionStorageKey, JSON.stringify(resultData))
          this.$requestConfig
            .saveSubDataTemp(sessionStorageKey, JSON.stringify(resultData))
            .then(() => {
              let param = {
                bizType: 'addData',
                openType: flowFormData.openType,
                parameters: {
                  previewTemplateAlias: flowFormData.report.key,
                  fillType: flowFormData.isSub ? 'sub' : 'main',
                  data: sessionStorageKey, // 由于担心勾选数据多配置也多情况，如果全部用url传递可能导致url过长导致服务器错误，因此子表的情况，此处只存放对应的sessionStorage的 key
                },
                templateName: this.formListName,
              }
              this.$requestConfig.openUrl(param)
            })
          return
        }

        if (row) {
          let data = {}
          if (flowFormData.paramFields && flowFormData.paramFields.length > 0) {
            flowFormData.paramFields.forEach((obj) => {
              for (let key in row) {
                if (obj.sourceField.toLowerCase().endsWith(key.toLowerCase())) {
                  data[obj.targetField] = row[key]
                }
              }
            })
          }

          let param = {
            bizType: 'addData',
            openType: flowFormData.openType,
            parameters: {
              previewTemplateAlias: flowFormData.report.key,
              data: encodeURIComponent(Base64.encode(JSON.stringify(data))),
            },
            templateName: this.formListName,
          }
          this.$requestConfig.openUrl(param)
        } else {
          let param = {
            bizType: 'addData',
            openType: flowFormData.openType,
            parameters: {
              previewTemplateAlias: flowFormData.report.key,
              data: '',
            },
            templateName: this.formListName,
          }
          this.$requestConfig.openUrl(param)
        }
      },
      //审批任务
      async handleApproval(row, afterScriptValue, parameter) {
        let type = 'old'
        let rows = parameter.row

        //后置脚本执行结果为false则不执行下面的逻辑
        if (afterScriptValue) {
          let script = Base64.decode(afterScriptValue)
          let scriptResult = await this.tempScript(script, rows)
          if (!scriptResult) {
            return
          }
        }
        let { taskId } = this.flowBtnPermission[row['bpm_proc_inst_id_']]
        let url = `/matter/approvalForm/?taskId=${taskId}&instId=${row['bpm_proc_inst_id_']}&isGetApprovalBtn=true`
        //判断当前在哪个端
        if (!this.$requestConfig.frontUrl) {
          this.$message.error('应用端未配置')
          return
        }
        let currentUser = sessionStorage.getItem('currentUser')
        let token = null
        try {
          let obj = JSON.parse(currentUser)
          token = obj.token
        } catch (e) {}
        let fullUrl = `${this.$requestConfig.frontUrl}${url}${
          token ? '&token=' + token : ''
        }`
        if (this.$requestConfig.type === 'front') {
          if (type === 'old') {
            this.$router.push(url)
          } else {
            window.open(fullUrl, '_blank')
          }
        } else {
          window.open(fullUrl, type === 'old' ? '_self' : '_blank')
        }
      },
      del(id) {
        this.$confirm('此操作将删除该数据, 是否继续?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning',
        })
          .then(() => {
            this.delWithOutConfirm(id)
            this.close()
          })
          .catch(() => {
            this.$message({
              type: 'info',
              message: '已取消删除',
            })
          })
      },
      delWithOutConfirm(id) {
        let data = {
          ids: id,
          boAlias: this.boAlias,
          formKey: this.formKey,
        }
        this.$requestConfig.deleteTemplateDataById(data).then((resp) => {
          if (resp.state) {
            this.$message.success(resp.message)
          } else {
            this.$message.error(resp.message)
          }
        })
      },
      //任务明细
      async showTaskDetail(row, afterScriptValue, parameter) {
        let openType = 'old'
        let rows = null
        if (parameter) {
          rows = parameter.row
          let rowId = parameter.id || parameter.pkField
          if ((!rows || rows == undefined) && rowId) {
            rows = this.rows.filter(
              (item) => item[this.templateInfo.pkField] == rowId
            )[0]
          }
        }
        //后置脚本执行结果为false则不执行下面的逻辑
        if (afterScriptValue) {
          let script = Base64.decode(afterScriptValue)
          let scriptResult = await this.tempScript(script, rows)
          if (!scriptResult) {
            return
          }
        }
        let instId = row['bpm_proc_inst_id_']
        let url = `/matter/approvalForm?instId=${instId}`
        const basePath = this.$router.resolve('/').href
        let currentUser = sessionStorage.getItem('currentUser')
        let token = null
        try {
          let obj = JSON.parse(currentUser)
          token = obj.token
        } catch (e) {}

        let fullUrl = `${this.$requestConfig.frontUrl}${url}${
          token ? '&token=' + token : ''
        }`
        if (
          !`${window.location.origin}${basePath}`.startsWith(
            this.$requestConfig.frontUrl
          ) ||
          openType === 'new'
        ) {
          window.open(fullUrl, '_blank')
        } else if ('old' === openType) {
          this.$router.push(url)
        } else {
          window.open(fullUrl, '_blank')
        }
      },
      async scriptBeforeHandler(
        scriptInBase64,
        row,
        visual_formVar,
        visual_customQuery
      ) {
        let rsl = true
        let totalResult = []
        //js脚本
        if (scriptInBase64) {
          let script = Base64.decode(scriptInBase64)
          if (script == undefined || script == '') {
            return true
          }
          let _this = this
          let _req = req
          let _row = row
          // eslint-disable-next-line no-inner-declarations
          function evil() {
            let Fn = Function('_req', '_this', '_row', script) //一个变量指向Function，防止有些前端编译工具报错
            let result = Fn(_req, _this, _row)
            return result
          }
          let resultValue = evil()
          if (visual_formVar || visual_customQuery) {
            totalResult.push(resultValue)
          } else {
            return resultValue
          }
        }

        //表单变量
        if (visual_formVar) {
          let v = row[visual_formVar] || row[visual_formVar.toLowerCase()] || ''
          if (!v) {
            totalResult.push(false)
          } else {
            let vAry = v.split(',')
            let curAccount = this.$requestConfig.getAccount()
            totalResult.push(vAry.includes(curAccount))
          }
        }
        //关联查询
        if (visual_customQuery) {
          let customQuery = JSON.parse(Base64.decode(visual_customQuery))
          if (customQuery.alias) {
            let r = await this.doCustomQuery(customQuery, row)
            totalResult.push(r)
          }
        }
        //计算结果
        if (totalResult.length > 0) {
          let t = false
          //有一个为true，即代表有权限
          totalResult.forEach((tr) => {
            t = t || tr
          })
          return t
        }
        return rsl
      },
      async doCustomQuery(customQuery, row = {}) {
        let paramsVal = {}
        customQuery.condition &&
          customQuery.condition.forEach((cond) => {
            if (cond.paramType === 'account') {
              //账号
              paramsVal[cond.field] = this.$requestConfig.getAccount()
            } else if (cond.paramType == 'userId') {
              //userId
              paramsVal[cond.field] = this.$requestConfig.userId()
            } else if (cond.paramType === 'formVar' && cond.paramValue) {
              //表单变量
              paramsVal[cond.field] =
                row[cond.paramValue] || row[cond.paramValue.toLowerCase()] || ''
            } else if (cond.paramType === 'fixedValue') {
              //固定值
              paramsVal[cond.field] = cond.paramValue || ''
            }
          })
        return await (() => {
          return new Promise((resolve) => {
            CustomQuery.load(customQuery.alias, paramsVal, { page: 1 })
              .then((data) => {
                const resData =
                  data && data.listKey
                    ? utils.getValueByPath(data, data.listKey)
                    : data && data.data
                let accounts = resData.map((m) => m[customQuery.field])
                let curAccount = this.$requestConfig.getAccount()
                resolve(accounts.includes(curAccount))
              })
              .catch(() => {
                resolve(false)
              })
          })
        })()
      },
    },
  }
</script>

<style lang="scss" scoped>
  .base-main {
    background-color: #e9eef3;
    height: 100%;
    padding: 0;
    // >>> .el-form-item {
    //   margin-bottom: 15px !important;
    //   margin-top: 10px !important;
    //   margin-right: 10px !important;
    // }
    .base-main_box {
      width: 100%;
      margin: 0px auto 0;
      background-color: #fff;
      /*  padding: 20px; */
      /* margin-top: 20px; */
      height: calc(100% - 63px);
      overflow: auto;
    }
    .base-main_bottom_btn {
      background: #fff;
      width: 100%;
      text-align: center;
      position: absolute;
      bottom: 0;
      left: 0;
      padding: 10px 0;
      line-height: 45px;
      z-index: 999;
      .base-main_bottom_btn_span {
        ::v-deep {
          .el-button {
            margin-right: 10px;
          }
        }
      }
    }
    >>> .form-table {
      width: 100%;
      border-top: 1px solid #ebeef5;
      border-left: 1px solid #ebeef5;
    }

    >>> .form-table > thead > tr > th,
    >>> .form-table > tbody > tr > th {
      text-align: right;
      color: #666;
      font-weight: normal;
    }

    >>> .form-table > tbody > tr > th.group-th {
      text-align: left;
      background: #f9f9f9;
      font-weight: bold;
    }

    >>> .form-table > thead > tr.sub-table-header > th {
      text-align: center;
      background: #fafafa;
    }

    >>> .form-table > tbody > tr > th > span,
    >>> .form-table > thead > tr > th > span {
      color: #f00;
    }

    >>> .form-table > tbody > tr > th,
    >>> .form-table > tbody > tr > td,
    >>> .form-table > tfoot > tr > td,
    >>> .form-table > thead > tr > th {
      border-right: 1px solid #ebeef5;
      border-bottom: 1px solid #ebeef5;
      padding: 10px;
      min-width: 0;
      box-sizing: border-box;
      text-overflow: ellipsis;
      vertical-align: middle;
      position: relative;
    }

    >>> .form-table > tfoot > tr > td {
      padding: 5px 10px;
    }

    .form-container {
      border-bottom: 1px solid #ebeef5;
      padding-bottom: 10px;
    }

    .form-container > span {
      font-weight: bold;
      font-size: 14px;
      padding-left: 10px;
      color: #666;
    }

    .form-content {
      padding: 11px 0;
    }

    >>> div[aria-invalid='true'] + small,
    >>> small.error-message {
      display: block;
      margin-top: 8px;
      color: #f56c6c;
      font-size: 12px;
      font-weight: bold;
      line-height: 1;
    }
    .form-empty {
      position: absolute;
      text-align: center;
      width: 100%;
      font-size: 20px;
      top: 200px;
      color: #ccc;
    }
    #printData {
      padding: 20px;
    }
  }
  .mobile-template-form__detail {
    .loading-wrap {
      height: calc(80vh - 48px);
      display: flex;
      justify-content: center;
      align-items: center;
    }
    .mobile-template-form__detail-header {
      ::v-deep {
        .van-nav-bar__left {
          padding-left: 10px;
          .van-icon-arrow-left {
            font-size: 22px;
            color: #262626;
          }
        }
        .van-nav-bar__title {
          color: #262626;
          font-size: 17px;
          font-weight: bold;
        }
      }
    }
    .custom-form {
      background: #fff;
      height: calc(100vh - 46px);
      overflow: scroll;
    }
    ::v-deep {
      .mobile-ht-form-item {
        .el-form-item__content,
        .el-form-item__label {
          line-height: 48px;
        }
        .el-form-item__content {
          .mobile-upload {
            position: absolute;
            top: 2px;
            right: 0;
            width: 150px;
          }
        }
      }
    }
    .has-footer {
      height: calc(100vh - 110px);
    }
    .mobile-template-form__detail-footer {
      height: 64px;
      display: flex;
      align-items: center;
      background: #fff;
      border-top: 1px solid #e6e6e6;
      padding: 0 16px;
      .footer-flow-btn {
        flex: 1;
        border-radius: 8px;
      }
      .footer-btn {
        flex: 1;
        border-radius: 8px;
        background-color: #409eff;
        color: #fff;
        border-color: #409eff;
      }
    }
  }
  .loading_text {
    color: #595959;
  }
  .loading_custom_wrap {
    display: flex;
    justify-content: center;
    align-items: center;
    width: 100%;
    height: 100%;
  }
</style>
