<template>
  <div class="approval-form">
    <van-sticky>
      <nav-bar title="表单审批" :is-custom="true" @go-back="handleGoBack">
        <template #right>
          <template v-if="!['circulate', 'delegate'].includes(from)">
            <i v-if="!taskId" class="icon-cuiban" @click="cunBanClick"></i>
          </template>
          <i
            class="icon-daohanglan-gengduo more-icon"
            @click="$refs.ShowOrder.showOrder = true"
          ></i>
        </template>
      </nav-bar>
      <!-- 流程信息 -->
      <form-header
        ref="formHeader"
        :done-data-version="doneDataVersion"
        :node-options="nodeList"
        :current-select-node="currentSelectNode"
        @node-change="handleNodeChange"
        @show-more="handleShowMore"
        :mergencyConfig="mergencyConfig"
        @open-emergency="$refs.approvalFlowForm.showMergencyConfig = true"
      />
      <!-- 表单内容 -->
      <van-tabs color="#409EFF" v-model="activeName">
        <van-tab
          v-for="(value, key) in tabMap"
          :title="value"
          :name="key"
          :key="key"
        ></van-tab>
      </van-tabs>
    </van-sticky>

    <flow-form
      v-show="activeName === 'approvalForm'"
      ref="approvalFlowForm"
      :form="form"
      :data.sync="data"
      :inst-id="procInstId"
      :def-id="defId"
      :permission="permission"
      :record-data="recordData"
      :done-data-version="doneDataVersion"
      :node-options="nodeList"
      @updateHeaderData="updateHeaderData"
      @urgentStateList="getUrgentStateList"
      :outHeight="outHeight"
    ></flow-form>
    <!-- //审批记录 -->
    <ApprovalRecords
      v-if="activeName === 'approvalRecord'"
      :inst-id="instId"
      :task-id="taskId"
      :refer-opinion="referOpinion"
      :node-type="nodeType"
      :def-id="defId"
      :node-id="nodeId"
      :outHeight="outHeight"
    ></ApprovalRecords>
    <!-- 审批预测 -->
    <processForecast
      v-if="activeName === 'approveForecast'"
      ref="processForecast"
      :instId="instId"
      :data="data"
      :showPage="true"
      :outHeight="outHeight"
    ></processForecast>

    <!-- 流程图 -->

    <FlowChart
      ref="FlowChart"
      :showPage="true"
      :instId="instId"
      :data="data"
      :def-id="defId"
      :nodeId="nodeId"
      :header-data="headerData"
      v-if="activeName == 'flowMap'"
      :outHeight="outHeight"
    ></FlowChart>
    <!-- 催办 -->
    <TaskCunBan
      ref="TaskCunBan"
      :instId="instId"
      :data="data"
      :def-id="defId"
      :taskId="taskId"
      :nodeId="nodeId"
      :subject="subject"
      :header-data="headerData"
    ></TaskCunBan>
    <ShowOrder
      :instId="instId"
      :def-id="defId"
      :taskId="taskId"
      :nodeId="nodeId"
      :noticeId="readId"
      ref="ShowOrder"
    ></ShowOrder>
    <!-- 底部审批按钮 -->
    <approval-button
      ref="approvalButton"
      :data="data"
      :processInstStatus="processInstStatus"
      :bpmTask="bpmTask"
      :curNodeDef="curNodeDef"
      :formType="formType"
      :currentNodeInfo="currentNodeInfo"
      :before-click="handleBeforeClick"
      @update-form="handleUpdateForm"
    ></approval-button>
  </div>
</template>

<script>
  import { mapActions, mapState } from 'vuex'

  import FormHeader from '@/views/matter/components/FormHeader'
  import FlowForm from './form/FlowForm.vue'
  import ApprovalButton from '@/views/matter/components/ApprovalButton.vue'
  import processForecast from '@/views/matter/components/processForecast/processForecast.vue'
  import ShowOrder from '@/views/matter/components/ShowOrder.vue'
  import ApprovalRecords from '@/views/matter/components/ApprovalRecords.vue'
  import TaskCunBan from '@/views/matter/components/TaskCunBan.vue'

  import FlowChart from '@/components/FlowChart.vue'
  import {
    processIsOver,
    getInstanceByInstId,
    getTaskDetailBo,
    getInstFormAndBO,
    markTaskAsRead,
    getDoneByInstId,
    getDoneByInstIdAndAccount,
    setRead,
    getNoticeTodoReadById,
    getNodePrintTemplate,
    getProcessRunByTaskId,
  } from '@/api/process'
  import { getNotice, getFlowStatus, checkTaskAuth } from '@/api/flow'

  import { Base64 } from 'js-base64'
  import popupMode from '@/mixins/popupMode'
  export default {
    name: 'ApprovalForm',
    mixins: [popupMode],
    components: {
      FormHeader,
      FlowForm,

      ApprovalButton,
      processForecast,
      ShowOrder,
      FlowChart,
      ApprovalRecords,
      TaskCunBan,
    },
    data() {
      return {
        activeName: 'approvalForm',
        data: null,
        form: null,
        permission: null,
        procInstId: '',
        bpmnInstId: '',
        tabMap: {
          approvalForm: '审批表单',
          approvalRecord: '审批记录',
          flowMap: '流程图',
          approveForecast: '审批预测',
        },
        headerData: {
          id: '',
          creator: '',
          updateTime: '',
          procDefName: '',
          status: '',
          currentNode: '',
        },
        defId: '',
        nodeId: '',
        subject: '',
        referOpinion: '',
        nodeType: '',
        doneDataVersion: '',
        nodeList: [],
        currentSelectNode: '',
        processInstStatus: '',
        bpmTask: {},
        curNodeDef: {},
        opinionMap: {},
        currentNodeInfo: {},
        formType: '',
        showMoreInfo: false,
        ApprovalButtonHeight: 0,
        formHeaderHeight: 0,
        mergencyConfig: null,
        instId: null,
      }
    },
    computed: {
      ...mapState('login', ['currentUser']),
      taskId() {
        return this.$route.query.taskId || this.$route.params.taskId
      },
      leaderId() {
        return this.$route.query.leaderId || this.$route.params.leaderId
      },
      from() {
        return this.$route.query.from || this.$route.params.from
      },
      // 审批意见控件需要的参数处理记录参数
      recordData() {
        return {
          instId: this.instId,
          taskId: this.taskId,
          referOpinion: this.referOpinion,
          nodeType: this.nodeType,
          defId: this.defId,
          nodeId: this.nodeId,
          initFillData:
            this.notice &&
            this.notice.curNodeDef &&
            this.notice.curNodeDef.localProperties &&
            this.notice.curNodeDef.localProperties.initFillData,
        }
      },
      isUnRead() {
        return this.$route.query.isRead == '0'
      },
      /* 获取信息框的高度,46-栏目标题高度,60-tabs标题高度,64-按钮的高度,238-展开信息时高度，138收起信息时高度*/
      outHeight() {
        let height = 0
        height = 46 + 54 + this.formHeaderHeight + this.ApprovalButtonHeight
        return height
      },
      readId() {
        return this.$route.query.readId
      },
    },
    created() {
      this.instId = this.$route.query.instId || this.$route.params.instId
      if ((!this.instId || this.instId == '') && this.taskId) {
        //根据taskId获取对应的instId
        let _this = this
        getProcessRunByTaskId(this.taskId).then((bpmProcessInstance) => {
          _this.instId = bpmProcessInstance.id
          _this.procInstId = _this.instId
          _this.initData()
        })
      } else {
        this.procInstId = this.instId
        this.initData()
      }
    },
    mounted() {
      setTimeout(() => {
        this.ApprovalButtonHeight = this.$refs.approvalButton.$el.clientHeight
        this.formHeaderHeight = this.$refs.formHeader.$el.clientHeight
      }, 1000)
    },
    methods: {
      ...mapActions({
        getFlowKey: 'process/getFlowKey',
        getTaskDetail: 'process/getTaskDetail',
      }),
      async initData() {
        if (this.taskId) {
          if (!this.leaderId && !this.approvalType) {
            //验证当前用户是否有该任务处理权限
            const { value } = await checkTaskAuth(this.taskId)
            if (!value) {
              this.$message.warning('您没有执行该任务的权限！')
              this.$router.push(`/matter/myTask`)
              return
            }
          }
          const data = await getNotice(this.taskId).catch((err) => {
            window.location.href = '/matter/myTask'
          })
          this.notice = data
          this.procDefKey = this.notice.bpmTask.procDefKey
          this.getTaskDetail(data)
          this.handleTaskData(data)
          // 获取表单数据
          this.getTaskForm()
          this.markTaskAsReadByTaskId()
        } else {
          // this.getNodePrintTemplateByInstIdAndNodeId()
          getInstanceByInstId(this.instId, (instData) => {
            this.handleInstData(instData)
          })
          // 获取实例表单
          this.getInstanceForm()
        }
        //获取flowKey根据procInstId
        this.getFlowKey({ procInstId: this.instId })
        this.getFlowStatusByInstIdAndTaskId()
        //标为已阅
        if (this.isUnRead) {
          setRead(this.readId).then((res) => {})
        }
      },
      //进入审批页面时通过实例id和任务id获取流程状态
      getFlowStatusByInstIdAndTaskId() {
        const query = {
          instId: this.instId,
          taskId: this.taskId,
        }
        getFlowStatus(query).then((res) => {
          this.processInstStatus = res
        })
      },
      // 更新表单头部信息
      updateHeaderData(data) {
        this.headerData = data
      },

      handleTaskData(data) {
        this.defId = data.bpmTask.procDefId
        this.bpmTask = data.bpmTask
        this.procInstId = this.bpmTask.procInstId
        this.curNodeDef = data.curNodeDef
      },
      handleInstData(data) {
        const { procDefId, subject, formKey, bpmnInstId } = data || {}
        this.defId = procDefId
        this.subject = subject
        this.formKey = formKey
        this.bpmnInstId = bpmnInstId
      },
      // 获取实例表单
      getInstanceForm() {
        const params = {
          querys: [
            {
              property: 'wfInst.id_',
              value: this.instId,
              group: 'typeId',
              operation: 'IN',
              relation: 'AND',
            },
          ],
        }
        if (this.from == 'received') {
          //当收到传阅时，需要增加传阅人参数，后端不能取当前用户
          getNoticeTodoReadById(this.readId).then((res) => {
            getDoneByInstIdAndAccount(params, res.ownerId).then((res) => {
              if (res.rows && res.rows.length > 0) {
                this.nodeList = res.rows.filter(
                  (item) => item.nodeType && item.nodeType !== 'END'
                )
              }
              this.getFormDataByInstId(res.rows)
            })
          })
        } else {
          getDoneByInstId(params).then((res) => {
            if (res.rows && res.rows.length > 0) {
              this.nodeList = res.rows.filter(
                (item) => item.nodeType && item.nodeType !== 'END'
              )
            }
            this.getFormDataByInstId(res.rows)
          })
        }
      },

      cunBanClick() {
        processIsOver(this.procInstId, (res) => {
          if (res.state) {
            this.$refs.TaskCunBan.showDialog()
          } else {
            this.$toast.fail(res.message)
          }
        })
      },
      getFormDataByInstId(data) {
        if (data && data.length === 1 && data[0].opinionStatus === 'start') {
          this.isSkipStart = true
        }
        this.setOpinionMap(data)

        this.nodeId = this.$route.query.nodeId
        if (
          this.nodeId &&
          (this.from == 'received' || this.from == 'circulate') &&
          this.nodeList &&
          this.nodeList.length > 0
        ) {
          //传阅事项-我收到的 和我传阅的
          this.currentSelectNode = this.nodeId
          this.currentNodeInfo = this.nodeList.find(
            (item) => item.taskKey === this.nodeId
          )
        } else if (this.nodeList && this.nodeList.length > 0) {
          this.currentSelectNode = this.nodeList[0].taskKey
          this.currentNodeInfo = this.nodeList[0]
        } else if (data && data.length > 0) {
          this.currentSelectNode = data[0].taskKey
          this.currentNodeInfo = data[0]
        }
        this.getFormByNodeIdAndInstId()
      },
      getFormByNodeIdAndInstId() {
        getInstFormAndBO({
          instId: this.instId,
          getStartForm: this.isSkipStart,
          includData: true,
          myApplication: this.myApplication,
          nodeId: this.nodeId || this.currentSelectNode,
          isDefAuthorize: this.$route.query.isDefAuthorize || '',
        }).then((res) => {
          this.doneDataVersion = res.doneDataVersion
          if (this.myApplication) {
            //我的申请处理
            this.nodeId = res.form.nodeId
            this.currentSelectNode = res.form.nodeId
          }
          if (res.doneDataVersion === 'history') {
            const findCurrentForm = this.nodeList.find(
              (item) => item.taskKey === this.currentSelectNode
            )
            if (findCurrentForm && findCurrentForm.formData) {
              res.data = JSON.parse(Base64.decode(findCurrentForm.formData))
            }
          }
          this.handleFormDetail(res)
        })
      },
      handleFormDetail(res) {
        if (res) {
          const { data, form, permission, result } = res || {}
          this.formKey = form?.formKey
          this.formType = form?.type
          this.form = form
          this.data = data
          this.permission = permission ? JSON.parse(permission) : null
          let diyJs = this.form?.diyJs
          diyJs && this.handlerJs(diyJs)

          if(result == 'formEmpty'){
            this.$notify({
              type: 'warning',
              message: '表单丢失，请与管理员联系',
            })
          }
        }
      },
      handlerJs(diyJs) {
        this.$nextTick(() => {
          const currentUser = this.currentUser
          let data = this.data
          let _this = this
          const $ = require('jquery')
          eval(diyJs)
        })
      },
      setOpinionMap(data) {
        data.forEach((item) => {
          const opinionStatusList = [
            'signRecoverCancel',
            'retracted',
            'start',
            'end',
            'awaiting_feedback',
            'copyto',
            'end_revoke',
            'start_commu',
            'awaiting_check',
            'copyto_reply',
            '',
          ]

          if (
            !opinionStatusList.includes(item.opinionStatus) &&
            this.opinionMap &&
            this.opinionMap[item.taskKey]
          ) {
            if (item.opinionStatus === 'skip' && item.skipType !== 'first')
              return true
            if (item.formData) {
              item.formData = JSON.parse(Base64.decode(item.formData))
            }
            this.opinionMap[item.taskKey] = item
          }
        })
      },
      //获取任务详情
      getTaskForm() {
        getTaskDetailBo({
          taskId: this.taskId,
          leaderId: this.leaderId || 0,
          reqParams: '',
          isDefAuthorize: this.$route.query.isDefAuthorize || '',
        }).then(
          (res) => this.handleFormDetail(res),
          (e) => {
            const { data } = e.response
            if (data && data.errorCode && data.errorCode == '5034') {
              this.$router.push(`/matter/myTask`)
            }
          }
        )
      },
      markTaskAsReadByTaskId() {
        markTaskAsRead(this.taskId)
      },
      handleBeforeClick() {
        // 审批表单前校验表单
        return this.$refs.approvalFlowForm
          .getData(true)
          .then(() => {
            return true
          })
          .catch(() => {
            return false
          })
      },
      handleNodeChange(key) {
        this.currentSelectNode = key
        this.nodeId = key
        this.currentNodeInfo =
          this.nodeList.find((item) => item.taskKey === key) || {}
        this.getFormByNodeIdAndInstId()
      },
      handleShowMore(value) {
        this.showMoreInfo = value
        this.$nextTick(() => {
          this.formHeaderHeight = this.$refs.formHeader.$el.clientHeight
        })
      },
      handleGoBack() {
        if (this.$route.query.from == 'delegate') {
          this.$router.push({
            path: '/matter/myTask/3',
          })
        } else if (
          this.$route.query.from == 'received' ||
          this.$route.query.from == 'circulate'
        ) {
          this.$router.push({
            path: '/matter/circulateMatter',
          })
        } else if (
          (this.$route.query.type == 'fromTodoList' ||
            this.$route.query.type == 'done') &&
          !this.$route.query.isRelevantFlow
        ) {
          this.$router.push({
            path: '/matter/myTask',
          })
        } else if (this.$route.query.isRelevantFlow) {
          if (this.$route.query.isStartProcess) {
            this.$router.push({
              path: '/matter/startProcess',
              query: {
                defId: this.$route.query.backDefId,
                instId: this.$route.query.backInstId,
                instStatus: 'draft',
                status: 'draft',
              },
            })
          } else {
            this.$router.go(-1)
          }
        } else {
          this.$router.push({
            path: '/matter/myRequest',
          })
        }
      },
      getUrgentStateList(val) {
        this.mergencyConfig = val
      },
      handleUpdateForm() {
        this.initData()
      },
    },
  }
</script>

<style lang="scss" scoped>
  .approval-form {
    height: $vh;
    .more-icon {
      font-size: 22px;
      margin-left: 8px;
      margin-right: -4px;
    }
    ::v-deep {
      .van-tabs {
        background: $base-white-color;
        margin-bottom: 10px;
        .van-tab {
          font-size: $base-font-size-big;
          color: $base-text-color;
        }
        .van-tab--active {
          color: $--color-primary;
        }
        .van-tabs__line {
          border-radius: 0;
          width: 48px;
        }
      }
      .flow-form {
        /*   height: calc(#{$vh} - 280px - 64px); */
        overflow: scroll;
      }
    }
  }
  .icon-cuiban {
    font-size: 24px;
  }
</style>
