<template>
  <div
    id="flow-form-container"
    ref="formContainer"
    class="form-container"
    :class="{ 'task-form': instId }"
  >
    <div class="form-content">
      <div v-if="!isShowTop" class="process-detail-wrap">
        <el-row class="form-top-row no-print">
          <el-col :span="18" class="top-left" :class="{ 'is-hide': !instId }">
            <div
              class="status-wrap"
              :style="{ '--statusBg': getCurrentStatusColorOrText('color') }"
            >
              <span class="status-icon"></span>
              <span class="status-text">
                {{ getCurrentStatusColorOrText('text') }}
              </span>
            </div>
            <div
              v-for="(value, key) in taskInfo"
              :key="key"
              class="top-info-item"
            >
              <span class="top-label">{{ value }}</span>
              <span class="top-value">
                {{ processInfo[key] }}
                <i
                  v-show="key === 'id'"
                  class="icon-fuzhi2 copy-id-icon"
                  @click="(event) => clipboard(processInfo[key], event)"
                ></i>
              </span>
            </div>
            <div v-if="isShowCurrentNode" class="top-info-item has-node-select">
              <span class="top-label">
                {{ isDone && isHistory ? '历史处理节点' : '当前节点' }}
              </span>
              <el-select
                v-if="isDone && isHistory"
                v-model="selectNode"
                placeholder="请选择"
                @change="handleNodeChange"
              >
                <el-option
                  v-for="item in nodeOptions"
                  :key="item.taskKey"
                  :label="item.taskName"
                  :value="item.taskKey"
                ></el-option>
              </el-select>
              <span v-if="!isDone" class="top-value">
                {{ isDone ? currentSelectNodeName : currentNode }}
              </span>
            </div>
          </el-col>
          <el-col :span="6" class="top-right">
            <span v-if="isShowHelp" class="help" @click="preview">
              <ht-icon name="help"></ht-icon>
              帮助
            </span>
            <div
              v-if="mergencyConfig && mergencyConfig.conf.length > 0"
              class="emergency-status"
            >
              <i
                class="icon-jinjizhuangtai label"
                :style="{
                  color: `${mergencyStatusColor[mergencyConfig.value]}`,
                  fontSize: '16px',
                }"
              ></i>
              <el-radio-group
                v-if="mergencyConfig.right === 'w'"
                v-model="mergencyConfig.value"
              >
                <el-radio
                  v-for="opt in mergencyConfig.conf"
                  :key="opt.state"
                  :label="String(opt.state)"
                  :style="{
                    color: `${mergencyStatusColor[opt.state]}`,
                  }"
                >
                  {{ opt.name }}
                </el-radio>
              </el-radio-group>
              <span
                v-else
                :style="{
                  color: `${mergencyStatusColor[mergencyConfig.value]}`,
                }"
              >
                {{ mergencyStatusMap[mergencyConfig.value] }}
              </span>
            </div>
          </el-col>
        </el-row>
        <div v-show="backReason" class="back-reason-wrap">
          <div ref="backReasonRef" class="reason-text">
            驳回原因：{{ processInfo.backOpinion }}
          </div>
          <span v-if="showAll" class="show-more" @click="showMoreDialog">
            <span class="text-ellipsis">...</span>
            查看更多
          </span>
        </div>
      </div>
      <h2 class="form-top-title" :class="{ 'task-subject': instId }">
        {{ instId ? processInfo.subject : processName }}
      </h2>

      <ht-online-form
        v-if="formType == 'INNER'"
        ref="flowOnlineForm"
        class="online-form"
        :class="{ 'readonly-form': isView }"
        :html="innerHtml"
        :data="data"
        :permission="permission"
        :extend-prop="recordData"
        :is-view="isView"
        :is-support-mobile="isSupportMobile"
        :inst-id="instId"
        :def-id="defId"
      />
      <iframe
        v-else-if="formType == 'FRAME'"
        ref="flowFrameForm"
        name="flowFrameForm"
        :src="frameUrl"
      ></iframe>
    </div>
    <!-- 查看更多驳回原因 -->
    <el-dialog
      v-if="isShowMoreDialog"
      title="驳回原因"
      width="640px"
      :visible.sync="isShowMoreDialog"
      :before-close="handleMoreDialogClose"
      top="20vh"
      class="back-reason-dialog"
    >
      <div class="back-reason-text">{{ processInfo.backOpinion }}</div>
    </el-dialog>
  </div>
</template>
<script>
  import { mapState, mapGetters } from 'vuex'
  import {
    STATUS_COLOR,
    URGENCY_STATUS_MAP,
    URGENCY_STATUS_COLOR,
    TASK_INFO,
  } from './const.js'

  import {
    getProcessInfo,
    getUrgentStateConf,
    getProcessTitle,
    getTaskInfo,
    getCurNodeProperties,
  } from '@/api/process'
  import clipboard from '@/utils/clipboard'

  export default {
    name: 'FlowForm',
    props: {
      businessKey: {
        type: String,
        default: '',
      },
      flowObject: {
        type: Object,
        default: () => {
          return {}
        },
      },
      form: {
        type: Object,
        default: () => {
          return {}
        },
      },
      data: {
        type: Object,
        default: () => {
          return null
        },
      },
      permission: {
        type: Object,
        default: () => {
          return null
        },
      },
      frameSaveDataTimeOut: {
        type: Number,
        default: 10,
      },
      instId: {
        type: String,
        default: '',
      },
      defId: {
        type: String,
        default: '',
      },
      isDialogModel: {
        type: Boolean,
        default: false,
      },
      recordData: {
        type: Object,
        default: () => {
          return {}
        },
      },
      doneDataVersion: {
        type: String,
        default: '',
      },
      nodeOptions: {
        type: Array,
        default: () => {
          return []
        },
      },
      currentSelectNode: {
        type: String,
        default: '',
      },
      currentTaskId: {
        type: String,
        default: '',
      },
    },
    data() {
      return {
        iframaStatusMap: {},
        subPageData: {}, //url表单下的表单数据
        formType: 'INNER',
        innerHtml: null,
        frameUrl: null,
        frameRoger: null,
        frameCancelTimeout: null,
        frameSaveDataPromiseResolve: null,
        frameSaveDataPromiseReject: null,
        processInfo: {},
        statusColorMap: STATUS_COLOR,
        isShowHelp: false,
        mergencyConfig: null,
        mergencyStatusMap: URGENCY_STATUS_MAP,
        mergencyStatusColor: URGENCY_STATUS_COLOR,
        processName: '',
        currentNode: '',
        isSupportMobile: false,
        taskInfo: TASK_INFO,
        selectNode: '',
        currentSelectNodeName: '',
        flag: 0,
        showAll: false,
        isShowMoreDialog: false,
        backReason: '',
        taskStatus: '',
      }
    },
    computed: {
      ...mapState('process', ['bpmTask']),
      ...mapGetters('user', ['accessToken']),
      ...mapState('matter', ['currentShowDialogAlias']),
      ...mapState('settings', ['layout']),
      instStatus() {
        return this.$route.query.instStatus
      },
      taskId() {
        return this.$route.query.taskId || this.currentTaskId
      },
      isShowCurrentNode() {
        const { type, taskId } = this.$route.query
        return (
          ['request', 'todo'].includes(type) ||
          this.taskId ||
          (type === 'done' && this.isHistory)
        )
      },
      isDone() {
        return this.$route.query.type === 'done'
      },
      isView() {
        // 加签 征询 流转时禁止编辑
        const statusList = ['TRANSFORMEDINQU', 'USERADDSIGN', 'TRANSFORMED']
        const result =
          (this.instId && !this.taskId && !this.isDialogModel) ||
          statusList.includes(this.bpmTask.status)
        return result ? true : false
      },
      headers() {
        return { Authorization: `Bearer ${this.accessToken}` }
      },
      isShowTop() {
        return !this.instId && !this.isShowHelp && !this.mergencyConfig
      },
      isHistory() {
        return this.doneDataVersion === 'history'
      },
    },
    watch: {
      form: function (newVal) {
        if (newVal) {
          this.formType = newVal.type
          if (this.formType == 'INNER') {
            this.innerHtml = newVal.formHtml
          } else if (this.formType == 'FRAME') {
            this.frameUrl = newVal.formValue
            if (this.businessKey) {
              this.frameUrl = `${this.frameUrl} ?id=${this.businessKey}`
            }
          }
          this.$emit('formTypeChange', this.formType)
        }
        if (newVal.helpFile) {
          this.isShowHelp = true
        }
      },
      urgentStateValue(val) {
        const urgentStateValue = localStorage.getItem('urgentStateValue')
        if (urgentStateValue) {
          const savaData = { ...JSON.parse(urgentStateValue), new: val }
          localStorage.setItem('urgentStateValue', JSON.stringify(savaData))
        }
      },
      mergencyConfig: {
        handler(config) {
          const urgentStateValue = localStorage.getItem('urgentStateValue')
          if (urgentStateValue) {
            const savaData = {
              ...JSON.parse(urgentStateValue),
              new: config.value,
            }
            localStorage.setItem('urgentStateValue', JSON.stringify(savaData))
          }
        },
        deep: true,
      },
      currentSelectNode(val) {
        this.selectNode = val
        if (this.nodeOptions.length > 0) {
          const result =
            this.nodeOptions.find((item) => item.taskKey === val) || {}
          this.currentSelectNodeName = result.taskName
        }
      },
      currentShowDialogAlias(val) {
        if (this.processInfo.backOpinion) {
          setTimeout(() => {
            this.setBackReasonAndShowMore()
          }, 600)
        }
      },
      layout(val) {
        if (this.processInfo.backOpinion) {
          setTimeout(() => {
            this.setBackReasonAndShowMore()
          }, 400)
        }
      },
    },
    created() {
      this.$root.$on('resize', () => {
        if (this.processInfo.backOpinion) {
          this.setBackReasonAndShowMore()
        }
      })
      window.addEventListener('message', this.handleFrameMessage)
      this.instId && this.getProcessInfoByInstId()
      this.getCurrentNode()
      this.getEmergencyStatusConf()
      this.defId && this.getProcessTitleByDefId()
      // 流程初始化时获取流程节点配置信息
      this.getFlowConfig()
    },
    mounted() {
      this.$nextTick(
        () =>
          this.$refs.formContainer &&
          this.$refs.formContainer.addEventListener(
            'scroll',
            this.setScrollTop,
            true
          )
      )
    },
    beforeDestroy() {
      window.removeEventListener('message', this.handleFrameMessage)
    },
    methods: {
      setBackReasonAndShowMore() {
        if (this.$refs.backReasonRef && this.processInfo.backOpinion) {
          const range = document.createRange()
          range.selectNodeContents(this.$refs.backReasonRef)
          const rect = range.getBoundingClientRect()
          const LINES = 2 // 显示行数
          const LINE_HEIGHT = 22 // 行高，根据实际情况调整
          const maxHeight = LINES * LINE_HEIGHT // 最大高度
          this.showAll = rect.height > maxHeight ? true : false
        }
      },
      showMoreDialog() {
        this.isShowMoreDialog = true
      },
      handleMoreDialogClose() {
        this.isShowMoreDialog = false
      },
      setScrollTop() {
        if (this.$refs.formContainer.scrollTop && this.flag < 1) {
          this.$refs.formContainer.scrollTop = 0
        }
        this.flag += 1
      },
      getFlowConfig() {
        if (this.defId) {
          getCurNodeProperties({
            defId: this.defId,
            instId: '',
            taskId: '',
          }).then((res) => {
            if (
              res &&
              res.localProperties &&
              res.localProperties.initFillData
            ) {
              this.recordData.initFillData = true
            }
          })
        }
      },
      async getData(verify, alias) {
        let _this = this
        if (this.formType == 'INNER') {
          //校验在线表单
          let onlineFormFlag = this.$refs.flowOnlineForm.getData(verify)
          if (!onlineFormFlag) {
            return onlineFormFlag
          }
          //校验iframe表单
          const frmControl = document.querySelectorAll("[id='iframeControl']")
          if (!frmControl || frmControl.length < 1) {
            return onlineFormFlag
          }
          this.iframaStatusMap = {}
          for (let x = 0; x < frmControl.length; x++) {
            //这里需要记录下,通知了几个子页面,只有等全部子页面都返回成功,才能继续执行保存的事件.
            const nameFrmControl = document.querySelectorAll(
              `[name='${frmControl[x].getAttribute('name')}Div']`
            )
            let iframeInst = nameFrmControl[0].__vue__
            let isBusinessForm = iframeInst.isBusinessForm
            if (isBusinessForm) {
              //是业务表单,且子页面有引入hotent.iframe.helper.js的才需要等待

              this.iframaStatusMap[frmControl[x].getAttribute('name')] = 'start'
            } else {
              this.iframaStatusMap[frmControl[x].getAttribute('name')] = 'end'
            }
          }
          let flag = true
          for (let key in this.iframaStatusMap) {
            if (this.iframaStatusMap[key] != 'end') {
              flag = false
            }
          }
          if (flag) {
            return onlineFormFlag
          }
          let aaa = await onlineFormFlag
          //走到这说明流程表单已经校验通过了,开始执行子页面的保存事件

          for (let x = 0; x < frmControl.length; x++) {
            //这里需要记录下,通知了几个子页面,只有等全部子页面都返回成功,才能继续执行保存的事件.
            const nameFrmControl = document.querySelectorAll(
              `[name='${frmControl[x].getAttribute('name')}Div']`
            )
            let iframeInst = nameFrmControl[0].__vue__
            let isBusinessForm = iframeInst.isBusinessForm
            if (isBusinessForm) {
              frmControl[x].contentWindow.postMessage(
                {
                  type: 'saveIframeData',
                  iframeName: frmControl[x].getAttribute('name'),
                },
                '*'
              )
            }
          }
          setTimeout(() => {
            for (let key in _this.iframaStatusMap) {
              if (_this.iframaStatusMap[key] == 'start') {
                this.$message.error(
                  `iframe控件${key}没有回复保存数据的消息，可能没有引入hotent.iframe.helper.js文件。`
                )
                _this.iframaStatusMap[key] = 'end'
              }
            }
            let flag = true
            for (let key in _this.iframaStatusMap) {
              if (_this.iframaStatusMap[key] == 'ready') {
                flag = false
              }
            }
            if (flag) {
              _this.frameSaveDataPromiseResolve()
            }
          }, 2000)

          const receiveData = new Promise((resolve, reject) => {
            this.frameSaveDataPromiseResolve = resolve
            this.frameSaveDataPromiseReject = reject
          })

          return Promise.race([receiveData]).finally(() => {
            this.frameSaveDataPromiseResolve = null
            this.frameSaveDataPromiseReject = null
          })
        } else if (this.formType == 'FRAME') {
          const frm = this.getFrameFormElement()

          // 发送保存数据的消息

          // frm.contentWindow.postMessage('saveData', '*')

          frm.contentWindow.postMessage(
            alias ? { messageName: 'saveData', alias } : 'saveData',
            '*'
          )

          this.frameRoger = false
          this.frameCancelTimeout = false
          // 1.未收到roger消息，认为url表单未引入hotent.helper.js文件
          const rogerJudge = new Promise((resolve, reject) => {
            setTimeout(() => {
              if (this.frameRoger === false) {
                this.$message.error(
                  `当前URL表单没有回复保存数据的消息，可能没有引入hotent.helper.js文件。`
                )
                reject()
              }
            }, 200)
          })
          // 2.超时未返回saveData消息
          var timeoutHandler
          const timeoutJudge = new Promise((resolve, reject) => {
            timeoutHandler = setTimeout(() => {
              if (this.frameCancelTimeout === false) {
                this.$message.error(
                  `当前URL表单保存数据超时，超时时间为：${this.frameSaveDataTimeOut}秒。`
                )
                reject()
              }
            }, this.frameSaveDataTimeOut * 1000)
          })

          // 3.接受到保存完数据的消息后resolve
          const receiveData = new Promise((resolve, reject) => {
            this.frameSaveDataPromiseResolve = resolve
            this.frameSaveDataPromiseReject = reject
          })

          return Promise.race([rogerJudge, timeoutJudge, receiveData]).finally(
            () => {
              this.frameRoger = null
              this.frameCancelTimeout = null
              this.frameSaveDataPromiseResolve = null
              this.frameSaveDataPromiseReject = null
              if (timeoutHandler) {
                clearTimeout(timeoutHandler)
              }
            }
          )
        } else {
          throw `不识别的表单类型${this.formType}`
        }
      },
      getFrameFormElement() {
        const frm = document.querySelectorAll("[name='flowFrameForm']")[0]
        const frmControl = document.querySelectorAll("[name='iframeControl']")
        if (!frm && !frmControl) {
          this.$message.error('当前URL表单加载不正确。')
        }

        return frm
      },
      // 处理iframe表单发送过来的消息
      handleFrameMessage(e) {
        if (
          !e ||
          !e.data ||
          !e.data.type ||
          e.data.type.startsWith?.('webpack')
        ) {
          return
        }
        const frm = this.getFrameFormElement()
        switch (e.data.type) {
          //调整iframe的高度
          case 'height': {
            frm.style.visibility = 'hidden'
            // 提前还原高度
            frm.setAttribute('height', 'auto')
            setTimeout(function () {
              frm.setAttribute('height', e.data.height)
              frm.style.visibility = 'visible'
              frm.dispatchEvent(new Event('mouseover'))
            }, 0)
            break
          }
          //获取到frame表单传过来的流程变量数据
          case 'saveData': {
            if (e.data.state && this.frameSaveDataPromiseResolve) {
              const iframeData = {
                businessKey: e.data.businessKey,
                sysCode: e.data.sysCode,
              }
              if (e.data.vars) {
                iframeData.vars = e.data.vars
              }
              this.$emit('update:data', iframeData)
              this.frameSaveDataPromiseResolve()
            } else if (!e.data.state && this.frameSaveDataPromiseReject) {
              this.frameSaveDataPromiseReject()
              this.$message.error(
                e.data.message ? e.data.message : '业务表单数据保存失败'
              )
            }
            break
          }
          //表示frame表单收到了保存表单数据的消息
          case 'roger':
            this.frameRoger = true
            break
          //frame表单取消超时判断
          case 'cancelTimeout':
            this.frameCancelTimeout = true
            break
          case 'getSubPageData': //接收子页面表单数据
            this.subPageData = e.data.data
            break
          case 'getParentPageData': //获取父页面表单数据Data
            const frm = this.getFrameFormElement()
            this.data
            let params = { type: 'getParentPageData', data: this.data }
            frm.contentWindow.postMessage(params, '*')
            break
          case 'saveIframeData': {
            if (e.data.state && this.frameSaveDataPromiseResolve) {
              const iframeData = e.data.data
              const iframeNmae = e.data.iframeNmae
              const frmControl = document.querySelectorAll(
                `[name='${iframeNmae}Div']`
              )
              let iframeInst = frmControl[0].__vue__
              let returnParameter = iframeInst.returnParameter
              if (
                returnParameter &&
                returnParameter instanceof Array &&
                returnParameter.length > 0
              ) {
                let data = this.data
                //根据配置,得到ht-iframe 里面的返回值配置信息,把业务表单数据,回填到指定字段.
                for (let x = 0; x < returnParameter.length; x++) {
                  let parameter = returnParameter[x]
                  data = this.setFromData(
                    parameter.value,
                    data,
                    this.getFromData(parameter.key, iframeData)
                  )
                }

                this.$emit('update:data', data)
              }
              this.iframaStatusMap[iframeNmae] = 'end'
              let endFlag = true
              for (let key in this.iframaStatusMap) {
                if (this.iframaStatusMap[key] != 'end') {
                  endFlag = false
                }
              }
              if (endFlag) {
                this.frameSaveDataPromiseResolve()
              }
            } else if (!e.data.state && this.frameSaveDataPromiseReject) {
              this.frameSaveDataPromiseReject()
              this.$message.error(
                e.data.errMsg ? e.data.errMsg : '业务表单保存失败'
              )
            }
            break
          }
          case 'noMethod': {
            const iframeName = e.data.iframeName
            const methodName = e.data.methodName
            this.$message.error(`ifame控件未提供函数:${methodName}`)
            if (methodName == 'saveIframeData') {
              this.iframaStatusMap[iframeName] = 'end'
              let endFlag = true
              for (let key in this.iframaStatusMap) {
                if (this.iframaStatusMap[key] != 'end') {
                  endFlag = false
                }
              }
              if (endFlag) {
                this.frameSaveDataPromiseResolve()
              }
            }
            break
          }
          case 'IframeRoger': {
            const iframeName = e.data.iframeName
            if (this.iframaStatusMap[iframeName] == 'start') {
              this.iframaStatusMap[iframeName] = 'ready'
            }
            break
          }
        }
      },
      getFromData(path, data) {
        let pathAry = path.split('.')
        let v = data
        for (let x = 0; x < pathAry.length; x++) {
          v = v[pathAry[x]]
        }
        return v
      },
      setFromData(path, data, value) {
        let pathAry = path.split('.')
        if (pathAry.length == 1) {
          data[pathAry[0]] = value
        } else if (pathAry.length == 2) {
          data[pathAry[0]][pathAry[1]] = value
        } else if (pathAry.length == 3) {
          data[pathAry[0]][pathAry[1]][pathAry[2]] = value
        }

        return data
      },

      getProcessInfoByInstId() {
        getProcessInfo(this.instId).then((res) => {
          this.processInfo = res
          this.backReason = res.backOpinion || ''
          this.$nextTick(() => {
            this.setBackReasonAndShowMore()
          })
          this.isSupportMobile = res.supportMobile === 1 ? true : false
          this.$emit('get-process-sponsor', res.createAccount)
          this.$emit('getInstStatus', res.status)

          this.$emit('updateHeaderData', {
            ...this.processInfo,
            currentNode: this.currentNode,
          })
        })
      },
      getCurrentStatusColorOrText(type) {
        const currentStatus =
          this.taskStatus || this.processInfo.status || this.instStatus
        return STATUS_COLOR[currentStatus]?.[type]
      },
      preview() {
        const files = this.form?.helpFile ? JSON.parse(this.form.helpFile) : []
        window.open(
          `${this.$file.previewUrl}?fileId=${files[0]?.id}&token=${this.accessToken}`
        )
      },
      getEmergencyStatusConf() {
        const params = {
          defId: this.defId,
          instId: this.instId,
          taskId: this.taskId,
        }
        getUrgentStateConf(params).then((data) => {
          if (data.conf) {
            try {
              data.conf = JSON.parse(data.conf)
            } catch (error) {
              data.conf = eval('(' + data.conf + ')')
            }
            localStorage.setItem(
              'urgentStateValue',
              JSON.stringify({ old: data.value })
            )
            if (!data.value) {
              data.conf?.map?.((item) => {
                if (item.default) {
                  data.value = item.state
                }
              })
            }
            this.mergencyConfig = data
            var temColor = {}
            this.mergencyConfig.conf.forEach((conf) =>
              this.$set(temColor, conf.state, conf.color)
            )
            if (temColor) {
              this.mergencyStatusColor = temColor
            }
          } else {
            localStorage.removeItem('urgentStateValue')
          }
        })
      },

      getProcessTitleByDefId() {
        getProcessTitle(this.defId).then((res) => {
          if (res.state) {
            this.$emit('update:flowObject', res.value)
            this.processName = res.value.name
          }
        })
      },
      getCurrentNode(status) {
        getTaskInfo([this.instId]).then((res) => {
          if (!res.state) return this.$message.error(res.message)
          const currentNodeList = res.value?.[this.instId]
          if (currentNodeList?.length > 0) {
            //当任务节点中是这四个状态，则使用任务节点的状态
            const list = ['backToStart', 'back', 'revoke', 'revokeToStart']
            if (
              currentNodeList[0]?.status &&
              list.includes(currentNodeList[0].status.toLowerCase())
            ) {
              this.taskStatus = currentNodeList[0].status.toLowerCase()
            }
            let nodeMap = {}
            currentNodeList.forEach((item) => {
              const { nodeId, name } = item
              nodeMap[nodeId] = name
            })
            if (
              this.$route.query.type === 'request' ||
              this.$route.params.type === 'request'
            ) {
              if (currentNodeList.length === 1) {
                this.currentNode = currentNodeList[0].name
              } else {
                this.currentNode = '请查看流程图'
              }
              this.isSupportMobile = currentNodeList[0].supportMobile === 1
            } else {
              const currentTask = currentNodeList.find(
                (item) => item.id === this.taskId
              )
              this.currentNode = currentTask && currentTask.name
              if (currentTask && currentTask.supportMobile) {
                this.isSupportMobile = currentTask.supportMobile === 1
              }
            }
            // 更新当前节点
            this.$emit('updateHeaderData', {
              ...this.processInfo,
              currentNode: this.currentNode,
              nodeId: currentNodeList[0].nodeId,
            })
          }
        })
      },
      handleNodeChange(taskKey) {
        this.$emit('node-change', taskKey)
      },
      //复制
      clipboard,
    },
  }
</script>
<style lang="scss" scoped>
  $top-title-bg: #f5f6f8;
  $top-label-color: #8c8c8c;

  .form-container {
    background: #fff;
    min-height: 300px;

    iframe[name='flowFrameForm'] {
      min-height: 300px;
      width: 100%;
      border: 0px;
    }
    .status-wrap {
      position: relative;
      margin-right: 56px;
      height: 56px;
      .status-icon {
        mask: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2NCIgaGVpZ2h0PSI1NiIgdmlld0JveD0iMCAwIDY0IDU2Ij4NCiAgPHBhdGggaWQ9IuWNsOeroCIgZD0iTS0zNzQxLjYsMzgyLjFsLTkuNzI1LTE1LjMyNGEyLjg4NCwyLjg4NCwwLDAsMC0zLjk2NS0uODlsLTQ4LjUzMiwzMC42ODRhMi44NzUsMi44NzUsMCwwLDAtLjg5MywzLjk1NWw5LjcyNSwxNS4zMjZhMi44ODIsMi44ODIsMCwwLDAsMy45NjEuODg3bDQ4LjUzNC0zMC42ODJBMi44NjQsMi44NjQsMCwwLDAtMzc0MS42LDM4Mi4xWm0tMS45MzcsMi4zMDgtNDguNTM0LDMwLjY4NmEuOTEzLjkxMywwLDAsMS0xLjI2MS0uMjg0bC05LjcyNS0xNS4zMjZhLjkxNC45MTQsMCwwLDEsLjI4Ni0xLjI2M2w0OC41MzYtMzAuNjg0YS45MTIuOTEyLDAsMCwxLDEuMjYuMjg2bDkuNzI5LDE1LjMyNkEuOTI4LjkyOCwwLDAsMS0zNzQzLjUzNCwzODQuNFptLTQxLjgzOC05LjcyNC44MDYsMS45MzIsMS4wNDQtMS44MTMsMi4wODYtLjE2OC0xLjQwNi0xLjU1NC40NzktMi4wMzItMS45MDcuODU3LTEuNzkxLTEuMDgzLjIyNywyLjA4MS0xLjU4OSwxLjM1NFptMTIuMzU3LTUuNzUxLTEtMS44MzktLjg0OSwxLjkxNS0yLjA2Mi4zOTMsMS41NTcsMS40LS4yNjksMi4wNzQsMS44MTYtMS4wNDksMS44OTQuOS0uNDM3LTIuMDQ5LDEuNDM2LTEuNTItMi4wODMtLjIxOFptMTguODQxLDMwLjgwOS0xLjY1OS0xLjI3NC0uMDA3LDIuMDg5LTEuNzMzLDEuMTc0LDIsLjY1OC41ODgsMi4wMDYsMS4yMzctMS42ODgsMi4wOTQuMDU5LTEuMjI5LTEuNy43MDktMS45NjFabS02Ljc3Miw4LjMyOS0uNzkxLTEuOTM4LTEuMDYyLDEuODA2LTIuMDg0LjE1MSwxLjM5MiwxLjU2MS0uNSwyLjAzLDEuOTE4LS44MzcsMS43ODQsMS4xMDgtLjIxLTIuMDgzLDEuNTg5LTEuMzUyWm0tMTIuNDA1LDUuNjY0Ljk5MywxLjg0Ny44NjYtMS45MDksMi4wNjItLjM2OC0xLjU0Ny0xLjQxLjI4NC0yLjA3Mi0xLjgyMywxLjAzLTEuODg0LS45MTEuNDIsMi4wNDUtMS40NTcsMS41MTRabS0xOC41ODMtMzAuOTU0LDEuNjUsMS4yOTUuMDI0LTIuMDkxLDEuNzQtMS4xNjgtMS45ODQtLjY3MS0uNTczLTIuMDE1LTEuMjUyLDEuNjc3LTIuMDk0LS4wNzYsMS4yMTIsMS43MDUtLjcyMywxLjk2NlptLTcuMzY4LDkuMDI3YTI2LjAyNiwyNi4wMjYsMCwwLDEsMTIuMTEyLTIyLjY3NCwyNi4xNCwyNi4xNCwwLDAsMSwyNS43MDgtMS4yNDJsMS45MTQtMS4yMWEyNy45LDI3LjksMCwwLDAtNy41MjYtMi44NjQsMjguMDQsMjguMDQsMCwwLDAtMTAuNzQyLS4zMSwyNy44MjEsMjcuODIxLDAsMCwwLTEwLjQsMy45NzIsMjcuOSwyNy45LDAsMCwwLTguMDQxLDcuNjkyLDI3Ljg1OCwyNy44NTgsMCwwLDAtNC4zMjQsOS44MjUsMjcuNzUxLDI3Ljc1MSwwLDAsMC0uNjIyLDguMDE5Wm01Mi4xMTktMS4zNTNhMjUuOTkxLDI1Ljk5MSwwLDAsMS0xMi4xLDIyLjY3MiwyNi4xMjMsMjYuMTIzLDAsMCwxLTI1LjcwNywxLjI0NGwtMS45MTgsMS4yMTJhMjguMDMxLDI4LjAzMSwwLDAsMCw3LjUyOSwyLjg2MiwyNy45NTksMjcuOTU5LDAsMCwwLDEwLjc0Mi4zMSwyNy44LDI3LjgsMCwwLDAsMTAuNC0zLjk3LDI3Ljk0NiwyNy45NDYsMCwwLDAsOC4wNDMtNy42OSwyNy45ODYsMjcuOTg2LDAsMCwwLDQuMzE0LTkuODI0LDI3LjcyMSwyNy43MjEsMCwwLDAsLjYyLTguMDIzWm0tMzQuMjE5LTEyLjE5M2ExNS4xNzgsMTUuMTc4LDAsMCwxLDcuMi0yLjMyNWwyLjk2Mi0xLjg3MmExNy4xNDUsMTcuMTQ1LDAsMCwwLTExLjIxNSwyLjU1NCwxNy4wNzQsMTcuMDc0LDAsMCwwLTcuMSw5LjAyN2wyLjk2LTEuODcxYTE1LjEzOCwxNS4xMzgsMCwwLDEsNS4xOS01LjUxMlptMTYuMzI2LDI1LjczOGExNS4xMzMsMTUuMTMzLDAsMCwxLTcuMiwyLjMyOWwtMi45NiwxLjg3MmExNy4xNDYsMTcuMTQ2LDAsMCwwLDExLjIxMy0yLjU1NiwxNy4wNTQsMTcuMDU0LDAsMCwwLDcuMS05LjAyN2wtMi45NTgsMS44NzVBMTUuMTczLDE1LjE3MywwLDAsMS0zNzY1LjA3NSw0MDMuOTk1Wm0tMjEuODI5LTQuMTE0IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgzODA1LjE1MiAtMzYzLjEyNykiLz4NCjwvc3ZnPg0K);
        mask-size: 100% 100%;
        mask-repeat: no-repeat;
        background-color: var(--statusBg);
        display: inline-block;
        width: 64px;
        height: 56px;
      }
      .status-text {
        position: absolute;
        left: 10px;
        transform: rotate(-30deg);
        top: 14px;
        color: var(--statusBg);
        font-size: $base-font-size-default;
        user-select: none;
        display: block;
        width: 64px;
        font-style: normal;
      }
    }
    .form-top-title {
      text-align: center;
      color: $base-dark-title-color;
      font-size: $base-font-size-xxl;
      margin: 24px 0;
    }
    .process-detail-wrap {
      display: flex;
      background: #f9f9f9;
      padding: 12px 32px;
      flex-direction: column;
      .back-reason-wrap {
        max-height: 44px;
        background: rgba(229, 85, 85, 0.1);
        border-radius: 4px;
        padding: 6px 12px;
        color: #e55555;
        line-height: 22px;
        margin-top: 8px;
        position: relative;
        .show-more {
          position: absolute;
          right: 14px;
          top: 28px;
          color: $base-color-default;
          cursor: pointer;
          display: block;
          background: #f8e8e8;
          padding-right: 6px;
          .text-ellipsis {
            color: #e55555;
            margin-right: 22px;
            display: inline-block;
            font-size: 18px;
            padding-left: 4px;
          }
        }
        .reason-text {
          word-break: break-all;
          display: -webkit-box;
          -webkit-line-clamp: 2; /* 显示行数 */
          -webkit-box-orient: vertical;
          overflow: hidden;
          text-overflow: ellipsis;
        }
      }
    }
    .form-top-row {
      display: flex;
      .is-hide {
        visibility: hidden;
      }

      .top-left {
        display: flex;
        align-items: center;

        .top-info-item {
          white-space: nowrap;
          display: flex;
          flex-direction: column;
          flex: 1;
        }
      }

      .top-right {
        display: flex;
        justify-content: flex-end;
        align-items: center;

        .help {
          cursor: pointer;
          color: $base-dark-title-color;

          ::v-deep.fa-icon {
            vertical-align: -0.2em;
          }
        }

        .emergency-status {
          margin-left: 24px;

          .label {
            color: $base-dark-title-color;
          }

          ::v-deep {
            .inputs {
              width: 284px;
              white-space: nowrap;
              margin-left: 10px;

              .el-radio {
                top: 2px;
                color: $base-dark-title-color;

                &:first-child {
                  color: $base-color-red;
                }

                &:nth-child(2) {
                  color: $base-color-yellow;
                }
              }
            }
          }
        }
      }

      .top-info-item {
        .top-label {
          color: $top-label-color;
          padding-bottom: 10px;
        }

        .top-value {
          color: $base-dark-title-color;
          .copy-id-icon {
            color: var(--themeColor);
            cursor: pointer;
          }
        }
      }

      .has-node-select {
        ::v-deep.el-select {
          width: 118px;
          margin-left: 10px;

          .el-input__inner {
            border: none;
            border-radius: 2px;
            color: $base-dark-title-color;
            background: rgba(243, 243, 243, 0.39);
          }

          .el-select__caret {
            color: #444;
          }
        }
      }
    }

    .hide-top {
      display: none;
    }

    ::v-deep {
      .el-row--flex.is-align-top {
        align-items: unset;
      }

      .w-e-toolbar {
        z-index: 2 !important;
      }
      .el-table {
        div[aria-invalid='true'] + .exhibit,
        div[aria-required='true'] + .exhibit {
          margin: 16px 0;
        }
      }
      .form-table__container {
        .inputs {
          position: relative;

          div[aria-invalid='true'],
          div[aria-required='true'] {
            margin: 16px 0;
          }

          div[aria-invalid='true'] + .field-tail__wrap,
          div[aria-required='true'] + .field-tail__wrap {
            text-align: left;
            position: absolute;
            top: calc(100% - 16px);
            left: 0;

            .el-form-item__error {
              top: calc(100% - 16px);
              position: static;
            }
          }

          div[aria-invalid='true'] + div + .field-tail__wrap,
          div[aria-required='true'] + div + .field-tail__wrap {
            text-align: left;
            position: absolute;
            left: 0px;
            top: calc(100% - 16px);

            .el-form-item__error {
              top: calc(100% - 16px);
              position: static;
            }
          }
        }
        .isFormat {
          .el_home {
            margin: 18px 0;
          }
          .exhibitText {
            padding-top: 2px;
            text-align: right;
            position: absolute;
            top: calc(100% - 18px);
            left: 0 !important;
          }
        }
      }

      //子表上传附件
      .el-table {
        .file-list__wrap .file-item {
          display: flex;
          justify-content: flex-start;

          .file__name {
            text-align: left;
          }
        }
      }

      .el-row {
        .el-col {
          &:last-child {
            margin-right: 0 !important;
          }
        }
      }
    }
    ::v-deep {
      .table_layout_wrap {
        .main-table {
          margin-bottom: 0;
          .main-title {
            padding: 0 8px !important;
          }
        }
      }
    }
  }

  .form-content {
    height: 100%;

    iframe[name='flowFrameForm'] {
      height: 100%;
    }
  }

  .task-form {
    .form-content {
      .online-form {
        padding: $base-padding 0;

        ::v-deep {
          .opinion-span {
            white-space: pre-line;
            line-height: 1em;
          }
        }
      }
    }
  }
  .form-container {
    .form-content .online-form {
      padding: 24px;
      padding-top: 0;
    }
  }
  ::v-deep .el-main {
    .formT_box {
      .form-table {
        width: 100%;

        .sub-table-header {
          th {
            &:last-child {
              width: 148px;
            }

            border: 1px solid #f3f5f7;
            padding: 15px;
            background-color: #fafafa;
          }
        }

        tbody tr td {
          padding: 10px;
          border-right: 1px solid #ebeef5;
          border-bottom: 1px solid #ebeef5;
          box-sizing: border-box;
          text-overflow: ellipsis;
          vertical-align: middle;
          position: relative;
        }
      }

      .xh_table {
        .sub-collapse .el-collapse-item__content .form-table {
          border: none;

          tbody tr td {
            border: none;

            //富文本中表格样式
            .inputs.ht-form-inputs__block {
              tbody tr td {
                border-right: 1px solid #ebeef5;
                border-bottom: 1px solid #ebeef5;
              }

              .wangEditor-table-style {
                table {
                  border-left: 1px solid #ccc;
                }
              }
            }
          }
        }
      }
    }

    .grandson_table_wrap {
      .form-table {
        width: 100%;

        th {
          &:last-child {
            width: 148px;
          }
        }
      }
    }
  }

  ::v-deep .online-form-wrap {
    .el-tabs__content {
      padding: 0;
    }
  }

  @media print {
    #flow-form-container {
      display: block;
      height: auto;
      overflow: hidden;
      margin: 0;
    }
    body {
      .form-content {
        .form-top-title {
          text-align: center;
        }

        ::v-deep {
          .printHide {
            display: none;
          }
        }

        .no-print {
          display: none;
        }
      }
    }

    @page {
      size: auto;
      margin: 3mm;
    }
  }

  ::v-deep .inputs.ht-form-inputs__block {
    //padding-top: 2px;
  }
  ::v-deep {
    .sub-collapse {
      .el-collapse-item__content {
        .inputs.ht-form-inputs__block {
          padding-top: 0px;
        }
      }
    }
    .readonly-form {
      .sub-collapse {
        .el-collapse-item__content {
          .el-form-item__content {
            line-height: 31px;
          }
        }
      }
      .inputs.ht-form-inputs__block {
        padding-top: 0px;
      }
    }
    //子表孙表的选择器、对话框
    .sun-table_main,
    .form-table__container {
      .ht-form__sunOrSub > .el-select {
        margin: 16px 0;
      }
    }
  }
</style>
