<template>
  <common-drawer :mask-closable="true" width="70%" :visible="visible" @close="close" :mask="props.mask">
    <template #title>
      <div class="flow-task-title">{{ props.data.instanceTitle }}</div>
      <div class="flow-task-detail" v-if="props.data">
        <div class="flow-task-detail-item">
          <span class="item-title">发起人：</span>
          <span class="item-value">{{ props.data.applicantWrapper?.realName }}</span>
        </div>
        <div class="flow-task-detail-item">
          <span class="item-title">持续时间：</span>
          <span class="item-value">{{ props.data.durationFormat }}</span>
        </div>
        <div class="flow-task-detail-item">
          <span class="item-title">流程状态：</span>
          <span class="item-value"><InstanceStatusTag :record="props.data" /></span>
        </div>
        <div class="flow-task-detail-item">
          <span class="item-title">当前节点：</span>
          <span class="item-value">
            {{ getCurrentRuntimeNodeList(props.data.currentRuntimeNodeList) }}
          </span>
        </div>
        <div class="flow-task-detail-item">
          <span class="item-title">当前节点状态：</span>
          <span class="item-value">{{ props.data?.taskStatusWrapper }}</span>
        </div>
      </div>
      <!-- 操作按钮 -->
      <div class="flow-task-btn">
        <a-space>
          <template v-for="item in operateButtonList" :key="item.type">
            <a-button
              :type="item.type"
              :loading="loading"
              :style="{ color: item.color, fontWeight: 'bold', border: item.border, backgroundColor: item?.backGroundColor }"
              class="border-radius"
              v-if="buttonPower[item.field]"
              @click="buttonClick(item)"
              >{{ buttonPower[item.aliasName] ? buttonPower[item.aliasName] : item.buttonName }}</a-button
            >
          </template>
        </a-space>
      </div>
    </template>

    <!-- tab栏 -->
    <a-tabs v-model:activeKey="activeKey" class="tabs">
      <a-tab-pane tab="流程属性" key="1"></a-tab-pane>
      <a-tab-pane tab="流程图" key="2"></a-tab-pane>
      <a-tab-pane tab="审批日志" key="3"></a-tab-pane>
      <a-tab-pane tab="流转日志" key="4"></a-tab-pane>
    </a-tabs>
    <div class="content">
      <!-- 流程属性 -->
      <flow-params v-show="activeKey == '1'" ref="flowParamsRef" v-model:data="props.data" :approverLogList="approverLogList"></flow-params>
      <!-- 流程图 -->
      <flow-chart v-if="activeKey === '2'" :instance-id="data?.instanceId" :definition-id="data?.definitionId"></flow-chart>
      <!-- 审批日志 -->
      <approver-log v-show="activeKey === '3'" :data-source="approverLogList"></approver-log>
      <!-- 流转日志 -->
      <roam-log v-show="activeKey === '4'" :data-source="roamLogList"></roam-log>
    </div>

    <!-- 流程同意弹框 -->
    <AgreeOperate
      v-model:visible="isShowAgree"
      v-if="isShowAgree"
      :isBatch="false"
      :definitionId="props.data?.definitionId"
      :saveformData="saveformData"
      :data="flowListSelect"
      @done="save"
    />

    <!-- 流程退回弹框 -->
    <BackOperate v-model:visible="isShowBack" v-if="isShowBack" :data="flowListSelect" @done="save" />

    <!-- 流程拒绝弹框 -->
    <RejectOperate v-model:visible="isShowReject" v-if="isShowReject" :data="flowListSelect" @done="save" />

    <!-- 流程转交弹框 -->
    <DelegateOperate v-model:visible="isShowDelegare" v-if="isShowDelegare" :data="flowListSelect" @done="save" />

    <!-- 流程加签弹框 -->
    <CountersignOperate v-model:visible="isShowSign" v-if="isShowSign" :data="flowListSelect" @done="save" />

    <!-- 流程抄送弹框 -->
    <FlowAddCopyUser v-model:visible="showFlowCopy" v-if="showFlowCopy" :taskId="props.data.id" />
  </common-drawer>
</template>

<script setup name="WorkflowTaskDetail">
import { onMounted, ref, watch, createVNode } from 'vue';
import AgreeOperate from './operate/agree-operate.vue';
import BackOperate from './operate/back-operate.vue';
import RejectOperate from './operate/reject-operate.vue';
import DelegateOperate from './operate/delegate-operate.vue';
import CountersignOperate from './operate/countersign-operate.vue';
import { FlowTaskApi } from '../api/FlowTaskApi';
import RoamLog from './detail/roam-log.vue';
import ApproverLog from './detail/approver-log.vue';
import FlowParams from './detail/flow-params.vue';
import FlowChart from './detail/flow-chart.vue';
import FlowAddCopyUser from '../../start/components/flow-add-copy-user.vue';
import { message, Modal } from 'ant-design-vue/es';
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import InstanceStatusTag from './detail/instance-status-tag.vue';

const props = defineProps({
  visible: Boolean,
  // 详情数据
  data: Object,
  // 任务类型
  taskCondition: {
    type: Number,
    default: 10
  },
  mask: {
    type: Boolean,
    default: false,
  }
});

const emits = defineEmits(['update:visible', 'done']);

// 当前tab栏
const activeKey = ref('1');
// 流转日志列表
const roamLogList = ref([]);
// 审批日志列表
const approverLogList = ref([]);

// 操作按钮列表
const operateButtonList = ref([
  {
    field: 'begin',
    buttonName: '开始',
    aliasName: 'beginAliasName',
    color: '#fff',
    type: 'primary',
    border: ''
  },
  {
    field: 'agree',
    buttonName: '同意',
    aliasName: 'agreeAliasName',
    color: '#fff',
    type: 'primary',
    border: ''
  },
  {
    field: 'refuse',
    buttonName: '拒绝',
    aliasName: 'refuseAliasName',
    color: '#60666B',
    type: 'default',
    border: ''
  },
  {
    field: 'haveRead',
    buttonName: '已阅',
    color: '#60666B',
    aliasName: 'haveReadAliasName',
    type: 'default',
    border: ''
  },
  {
    field: 'copyTo',
    buttonName: '抄送',
    color: '#60666B',
    aliasName: 'copyToAliasName',
    type: 'default',
    border: ''
  },
  {
    field: 'handOver',
    buttonName: '转交',
    color: '#60666B',
    type: 'default',
    aliasName: 'handOverAliasName',
    border: ''
  },
  {
    field: 'backTo',
    buttonName: '退回',
    color: '#60666B',
    type: 'default',
    aliasName: 'backToAliasName',
    border: ''
  },
  {
    field: 'retract',
    buttonName: '撤回',
    color: '#60666B',
    type: 'default',
    aliasName: 'retractAliasName',
    border: ''
  },
  {
    field: 'cancel',
    buttonName: '撤销',
    color: '#60666B',
    type: 'default',
    aliasName: 'cancelAliasName',
    border: ''
  },
  {
    field: 'addSign',
    buttonName: '加签',
    color: '#60666B',
    type: 'default',
    aliasName: 'addSignAliasName',
    border: ''
  }
]);

// 按钮权限
const buttonPower = ref({});

// 加载状态
const loading = ref(false);

// 是否显示同意弹框
const isShowAgree = ref(false);
// 是否显示退回弹框
const isShowBack = ref(false);
// 是否显示流程拒绝弹框
const isShowReject = ref(false);
// 是否显示流程转交弹框
const isShowDelegare = ref(false);
// 是否显示流程加签弹框
const isShowSign = ref(false);
// 是否显示流程抄送弹框
const showFlowCopy = ref(false);

// 选中列表
const flowListSelect = ref([props.data]);

// ref
const flowParamsRef = ref();

// 表单内容
const saveformData = ref({});

// 流程状态
const instanceStatus = ref(20);

onMounted(() => {
  if (props.data) {
    init();
  }
});

watch(
  () => props.data,
  val => {
    if (val) {
      init();
    }
  }
);

// 加载数据
const init = () => {
  instanceStatus.value = props.data.instanceStatus;
  getApplicantButtonPermission();
  getRoamList();
  getApproverLogList();
};

// 关闭抽屉
const close = () => {
  emits('update:visible', false);
};

// 确定
const save = () => {
  emits('done');
  close();
};

// 获取指定流程定义下，可以操作的按钮权限
const getApplicantButtonPermission = () => {
  if (props.data.definitionId) {
    FlowTaskApi.getTaskButtonPermission({
      taskId: props.data.id,
      taskCondition: props.taskCondition,
      instanceId: props.data?.instanceId
    }).then(res => {
      buttonPower.value = res;
    });
  }
};

// 获取流转日志列表
const getRoamList = () => {
  FlowTaskApi.flowEngineLogList({ instanceId: props.data.instanceId }).then(res => {
    roamLogList.value = res;
  });
};

// 获取审批日志列表
const getApproverLogList = () => {
  FlowTaskApi.getInstanceApprovalLog({ instanceId: props.data.instanceId }).then(res => {
    approverLogList.value = res.data;
  });
};

// 操作按钮点击
const buttonClick = async item => {
  switch (item.field) {
    case 'begin':
      beginTask();
      break;
    // 拒绝
    case 'refuse':
      refuseTask();
      break;
    // 转交
    case 'handOver':
      handOverTask();
      break;
    // 退回
    case 'backTo':
      backToTask();
      break;
    // 撤回
    case 'retract':
      retractTask();
      break;
    // 撤销
    case 'cancel':
      cancelTask();
      break;
    // 加签
    case 'addSign':
      addSignTask();
      break;
    // 同意
    case 'agree':
      const res = await flowParamsRef.value.$refs.workFlowFormRef.validateForm(true);
      if (res) {
        saveformData.value = res;
        agreeTask();
      }
      break;
    // 已阅
    case 'haveRead':
      haveReadTask();
      break;
    // 抄送
    case 'copyTo':
      copyToTask();
      break;
  }
};

// 开始
const beginTask = () => {
  FlowTaskApi.beginHandle({ taskId: props.data.id }).then(res => {
    if (res.code == '00000') {
      message.success(res.message);
      init();
    }
  });
}

// 拒绝
const refuseTask = () => {
  isShowReject.value = true;
};
// 转交
const handOverTask = () => {
  isShowDelegare.value = true;
};
// 退回
const backToTask = () => {
  isShowBack.value = true;
};
// 撤回
const retractTask = () => {
  Modal.confirm({
    title: '提示',
    content: '确定要撤回当前流程吗?',
    icon: createVNode(ExclamationCircleOutlined),
    maskClosable: true,
    onOk: async () => {
      // 已办
      let params = {};
      if (props.taskCondition == 30) {
        params.taskId = props.data.id;
      } else if (props.taskCondition == 50) {
        // 我的发起
        params.instanceId = props.data.instanceId;
      }
      FlowTaskApi.recall(params).then(res => {
        if (res.code == '00000') {
          message.success(res.message);
          save();
        }
      });
    }
  });
};

// 撤销
const cancelTask = () => {
  Modal.confirm({
    title: '提示',
    content: '确定要撤销当前流程吗?',
    icon: createVNode(ExclamationCircleOutlined),
    maskClosable: true,
    onOk: async () => {
      let params = {};
      params.instanceId = props.data.instanceId;
      FlowTaskApi.ruTaskCancel(params).then(res => {
        if (res.code == '00000') {
          message.success(res.message);
          save();
        }
      });
    }
  });
};

// 加签
const addSignTask = () => {
  isShowSign.value = true;
};
// 同意
const agreeTask = () => {
  isShowAgree.value = true;
};
// 已阅
const haveReadTask = () => {
  FlowTaskApi.ruTaskRead({ taskId: props.data.id }).then(res => {
    if (res.code == '00000') {
      message.success(res.message);
      save();
    }
  });
};

// 抄送
const copyToTask = () => {
  showFlowCopy.value = true;
};

// 获取当前节点名称
const getCurrentRuntimeNodeList = list => {
  let name = '';
  if (list && list?.length > 0) {
    name = list.map(item => item.nodeName).join(';');
  }
  return name;
};
</script>

<style scoped lang="less">
:deep(.ant-drawer-body) {
  padding: 0 20px !important;
}
:deep(.ant-drawer-header) {
  margin: 0px 20px;
  padding: 16px 0px !important;
  border-bottom-color: rgba(197, 207, 209, 0.6);
}
.image {
  width: 40px;
  margin-right: 10px;
}
.svg-icon {
  width: 35px;
  height: 35px;
  fill: #999;
  float: left;
  margin-right: 10px;
}
.detail {
  display: flex;
  height: 60px;
  padding: 10px;
  width: 100%;
  border-bottom: 1px solid #eeeeee;
  div {
    flex: 1;
    width: 100%;
    height: 100%;
    .comn {
      display: flex;
      float: left;
      margin-top: 8px;
    }
  }
  .fontSize {
    margin-right: 5px;
  }
}
.tabs {
  margin-top: 12px;
  height: 60px;
}
.content {
  width: 100%;
  height: calc(100% - 80px);
  overflow: hidden;
}
:deep(.ant-tabs-tab) {
  padding: 8px 16px !important;
}
:deep(.ant-tabs-tab + .ant-tabs-tab) {
  margin: 0 0 0 20px;
}
.flow-task-title {
  width: 100%;
  font-size: 18px;
}
.flow-task-detail {
  display: flex;
  font-weight: 400;
  margin-top: 16px;
  font-size: 16px;
  align-items: center;
}
.flow-task-detail-item:not(:last-child) {
  margin-right: 32px;
}
.item-title {
  color: #898e91;
  font-size: 16px;
  font-style: normal;
  font-weight: 400;
}
.item-value {
  font-weight: 500;
  color: #60666b;
}
.flow-task-btn {
  margin-top: 16px;
  display: flex;
  align-items: center;
  justify-content: end;
  margin-bottom: 8px;
}
:deep(.ant-tabs-tab) {
  font-weight: 400;
}
:deep(.ant-tabs-top > .ant-tabs-nav::before) {
  border-bottom-color: rgba(197, 207, 209, 0.6);
}
</style>
