<!--
流程实例，展示系统中所有的流程。
文件: instance/index.vue
功能: 流程实例管理页面，展示系统中的流程实例并提供查看详情与管理员取消流程的能力。
主要逻辑:
- 使用 `ProTable` 渲染流程实例列表，表格通过 `request` 方法调用 `postBpmProcessInstanceManagerPage` 获取分页数据，并返回 { success, data, total } 格式供组件使用。
- 通过 `getBpmCategorySimpleList` 获取流程分类下拉选项，赋值给 `categoryOptions` 用于搜索过滤。
- 在 `columns` 中定义查询与展示字段（流程名称、分类、发起人、发起部门、流程状态、发起时间、结束时间、耗时、当前审批任务、流程编号、操作等），并根据字段定制展示样式（如状态徽章、任务标签、耗时格式化等）。
- 操作项 (`onAction`) 包含查看详情（路由跳转到 `instanceDetail`）和管理员取消流程（弹出确认对话框输入取消原因后调用 `postBpmProcessInstanceCancelByAdmin`）。
- `handleOk` 负责校验取消原因并调用删除接口，成功后提示并刷新表格数据。
- 页面初始化时通过 `onMounted` 加载分类列表。
- 取消流程必须输入原因，且仅在流程状态为“审批中”时显示取消操作。
-->

<script lang="ts" setup>
import type { ProColumns } from '@pubinfo/pro-components';
import { ProTable } from '@pubinfo/pro-components';
import { message } from 'ant-design-vue';
import { getBpmCategorySimpleList } from '@/api/modules/bpmDefinition/bpMliuchengfenleikongzhiqi';
import { postBpmProcessInstanceCancelByAdmin, postBpmProcessInstanceManagerPage } from '@/api/modules/bpmTask/guanlihoutailiuchengshili';
import { millisecondsToDayHourMinuteSecond } from '@/utils/fun';
import { ACTION } from '../enum';

defineOptions({
  name: 'FlowInstance',
});
const categoryOptions = ref<any[]>([]);
const statusOptions: any[] = [{ label: '审批中', value: '1' }, { label: '审批通过', value: '2' }, { label: '审批不通过', value: '3' }, { label: '已取消', value: '4' }];
const tableRef = ref<typeof ProTable>();

async function request(params: any) {
  const { current, pageSize, ...rest } = params;
  const res = await postBpmProcessInstanceManagerPage({
    doSearchTotal: true,
    currentPage: current,
    pageSize,
    ...rest,
  });
  return {
    success: res.success,
    data: res.data?.records ?? [],
    total: res.data?.total ?? 0,
  };
}
const columns = computed<ProColumns<API.BpmCategoryRespVO>>(() => [
  {
    valueType: 'a-input',
    bind: 'value',
    title: '流程名称',
    dataIndex: 'name',
    ellipsis: true,
    fixed: 'left',
    fieldProps: {
      placeholder: '请输入流程名称',
      allowClear: true,
    },
  },
  {
    valueType: 'a-select',
    bind: 'value',
    title: '流程分类',
    dataIndex: 'category',
    ellipsis: true,
    fixed: 'left',
    fieldProps: {
      placeholder: '请选择流程分类',
      allowClear: true,
      options: categoryOptions.value,
    },
  },
  {
    valueType: 'a-input',
    bind: 'value',
    title: '发起人',
    dataIndex: 'startUser',
    ellipsis: true,
    fieldProps: {
      placeholder: '请输入发起人',
      allowClear: true,
    },
  },
  {
    hideInSearch: true,
    title: '发起部门',
    dataIndex: 'startDept',
    ellipsis: true,
  },
  {
    valueType: 'a-select',
    title: '流程状态',
    dataIndex: 'status',
    ellipsis: true,
    fieldProps: {
      placeholder: '请选择流程状态',
      allowClear: true,
      options: statusOptions,
    },
  },
  {
    hideInTable: true,
    valueType: 'a-input',
    bind: 'value',
    title: '所属流程',
    dataIndex: 'processDefinitionId',
    ellipsis: true,
    fieldProps: {
      placeholder: '请输入流程定义的编号',
      allowClear: true,
    },
  },
  {
    valueType: 'a-range-picker',
    bind: 'value',
    title: '发起时间',
    dataIndex: 'startTime',
    ellipsis: true,
    fieldProps: {
      allowClear: true,
      style: { width: '100%' },
    },
  },
  {
    hideInSearch: true,
    title: '结束时间',
    dataIndex: 'endTime',
    ellipsis: true,
  },
  {
    hideInSearch: true,
    title: '耗时',
    dataIndex: 'durationInMillis',
    ellipsis: true,
  },
  {
    hideInSearch: true,
    title: '当前审批任务',
    dataIndex: 'tasks',
  },
  {
    hideInSearch: true,
    title: '流程编号',
    dataIndex: 'id',
    ellipsis: true,
  },
  {
    hideInSearch: true,
    width: 100,
    title: '操作',
    dataIndex: 'action',
    fixed: 'right',
  },
]);
function reloadData() {
  tableRef.value?.reload();
}
const router = useRouter();
const openModal = ref(false);
const rowId = ref<string>('');
const reason = ref('');

function onAction(key: ACTION, record?: any) {
  switch (key) {
    case ACTION.DETAIL:
      router.push({ name: 'instanceDetail', query: { type: 'view', taskId: '' }, params: { processInstanceId: record.id } });
      break;
    case ACTION.CANCEL:
      rowId.value = record.id;
      openModal.value = true;
      break;
  }
}

function getBpmCategoryList() {
  getBpmCategorySimpleList().then((res) => {
    if (res && res.data) {
      categoryOptions.value = res.data.map((item: any) => ({
        label: item.name,
        value: item.id,
      }));
    }
  });
}

function handleOk() {
  if (reason.value.trim().length === 0) {
    message.error('请输入取消原因');
  }
  else {
    const params = {
      id: rowId.value,
      reason: reason.value,
    };
    postBpmProcessInstanceCancelByAdmin(params).then((res) => {
      if (res.success) {
        message.success('流程已取消');
        reason.value = '';
        openModal.value = false;
        reloadData();
      }
    });
  }
}
onMounted(() => {
  getBpmCategoryList();
});
</script>

<template>
  <div
    py-10px
    px-10px
    w-full
    h-full
  >
    <ProTable
      ref="tableRef"
      row-key="id"
      :request="request"
      :columns="columns"
      auto-height
      :scroll="{ x: 1100 }"
    >
      <template #bodyCell="{ column, record }">
        <template v-if="column.dataIndex === 'startUser'">
          <span>{{ record.startUser?.nickname }}</span>
        </template>
        <template v-if="column.dataIndex === 'startDept'">
          <span>{{ record.startUser?.deptName }}</span>
        </template>
        <template v-if="column.dataIndex === 'startDept'">
          <span>{{ record.startUser?.deptName }}</span>
        </template>
        <template v-if="column.dataIndex === 'status'">
          <a-badge v-if="record.status === 1" status="processing" text="审批中" />
          <a-badge v-if="record.status === 2" status="success" text="审批通过" />
          <a-badge v-if="record.status === 3" status="error" text="审批不通过" />
          <a-badge v-if="record.status === 4" status="default" text="已取消" />
        </template>
        <template v-if="column.dataIndex === 'durationInMillis'">
          <span v-if="record.durationInMillis">{{ millisecondsToDayHourMinuteSecond(record.durationInMillis) }}</span>
        </template>
        <template v-if="column.dataIndex === 'tasks'">
          <a-tag v-for="task in record.tasks" :key="task.id" color="blue">
            {{ task.name }}
          </a-tag>
        </template>
        <template v-if="column.dataIndex === 'action'">
          <a-space>
            <a class="flex items-center" @click="onAction(ACTION.DETAIL, record)">
              <span class="ml-4px">{{ ACTION.DETAIL }}</span>
            </a>
            <a v-if="record.status === 1" class="flex items-center hover:opacity-80" @click="onAction(ACTION.CANCEL, record)">
              <span class="ml-4px text-red-500!">{{ ACTION.CANCEL }}</span>
            </a>
          </a-space>
        </template>
      </template>
    </ProTable>
    <a-modal v-model:open="openModal" title="确认取消" @ok="handleOk">
      <div>
        <div>取消原因：</div>
        <a-textarea
          v-model:value="reason"
          placeholder="请输入取消原因"
          :auto-size="{ minRows: 2 }"
        />
      </div>
    </a-modal>
  </div>
</template>
