feat-wip(components): 审批信息流程图组件

This commit is contained in:
AN 2025-06-18 23:06:40 +08:00
parent 90ebf83501
commit fb652ce7ff
6 changed files with 223 additions and 21 deletions

View File

@ -0,0 +1,114 @@
<script setup lang="tsx">
import { onMounted, ref } from 'vue';
import type { DataTableColumns } from 'naive-ui';
import { NTag } from 'naive-ui';
import { fetchGetFlowHisTaskList } from '@/service/api/workflow/instance';
import { useDict } from '@/hooks/business/dict';
import DictTag from '@/components/custom/dict-tag.vue';
interface Props {
/** 业务id */
businessId: CommonType.IdType;
}
useDict('wf_task_status');
const props = defineProps<Props>();
const activeTab = ref('info');
const columns = ref<DataTableColumns<Api.Workflow.HisTask>>([
{
title: '任务名称',
key: 'nodeName',
align: 'center',
width: 100
},
{
title: '办理人',
key: 'approveName',
align: 'center',
width: 100,
render: row => {
return (
<NTag size="small" type="info">
{row.approveName}
</NTag>
);
}
},
{
title: '任务状态',
key: 'flowStatus',
align: 'center',
width: 100,
render: row => {
return <DictTag size="small" value={row.flowStatus} dict-code="wf_task_status" />;
}
},
{
title: '审批意见',
key: 'message',
align: 'center',
width: 100
},
{
title: '开始时间',
key: 'createTime',
align: 'center',
width: 100
},
{
title: '结束时间',
key: 'updateTime',
align: 'center',
width: 100
},
{
title: '运行时间',
key: 'runDuration',
align: 'center',
width: 100
},
{
title: '附件',
key: 'attachmentList',
align: 'center',
width: 100
}
]);
const instanceId = ref<CommonType.IdType>();
const HisTask = ref<Api.Workflow.HisTask[]>([]);
async function getData() {
const { error, data } = await fetchGetFlowHisTaskList(props.businessId);
if (error) {
window.$message?.error(error.message);
}
instanceId.value = data?.instanceId || '';
HisTask.value = data?.list || [];
}
onMounted(() => {
getData();
});
</script>
<template>
<NDivider />
<div>
<NTabs v-model:value="activeTab" type="segment" animated>
<NTabPane bar-width="100px" name="info" tab="审批信息">
<NDataTable class="max-h-500px" :columns="columns" :data="HisTask" />
</NTabPane>
<NTabPane bar-width="100px" name="image" tab="流程图">
威尔着火了快来帮忙我听到女朋友大喊现在一个难题在我面前是恢复一个重要的 Amazon 服务还是救公寓的火
<br />
<br />
我的脑海中忽然出现了 Amazon
著名的领导力准则客户至上有很多的客户还依赖我们的服务我不能让他们失望所以着火也不管了女朋友喊我也无所谓我开始
debug 这个线上问题
</NTabPane>
</NTabs>
</div>
</template>

View File

@ -144,6 +144,7 @@ async function handleUpdateModelWhenEdit() {
if (props.operateType === 'edit' || props.operateType === 'detail') {
Object.assign(model, props.rowData);
Object.assign(modelDetail, props.rowData);
} else {
const { error, data } = await fetchGetLeaveDetail(props.businessId!);
if (error) {
@ -215,7 +216,7 @@ watch(visible, () => {
</script>
<template>
<NDrawer v-model:show="visible" :title="title" display-directive="show" :width="800" class="max-w-90%">
<NDrawer v-model:show="visible" :title="title" display-directive="show" :width="1000" class="max-w-90%">
<NDrawerContent :title="title" :native-scrollbar="false" closable>
<div v-if="!readonly">
<NForm ref="formRef" :model="model" :rules="rules">
@ -243,33 +244,24 @@ watch(visible, () => {
</NForm>
</div>
<div v-else>
<NDescriptions bordered :column="1" label-placement="left">
<NDescriptions bordered :column="2" label-placement="left">
<NDescriptionsItem label="流程类型">
{{ flowCodeTypeRecord[model.flowCode] || '-' }}
{{ flowCodeTypeRecord[model.flowCode] }}
</NDescriptionsItem>
<NDescriptionsItem label="请假类型">
<NTag type="info">{{ leaveTypeRecord[model.leaveType!] || '-' }}</NTag>
<NTag type="info">{{ leaveTypeRecord[model.leaveType!] }}</NTag>
</NDescriptionsItem>
<NDescriptionsItem label="请假时间">
{{ model.startDate ? `${model.startDate}${model.endDate}` : '-' }}
{{ `${model.startDate}${model.endDate}` }}
</NDescriptionsItem>
<NDescriptionsItem label="请假天数">{{ model.leaveDays || '-' }} </NDescriptionsItem>
<NDescriptionsItem label="请假天数">{{ model.leaveDays }} </NDescriptionsItem>
<NDescriptionsItem label="请假原因">
{{ model.remark || '-' }}
</NDescriptionsItem>
</NDescriptions>
<div v-if="modelDetail.status !== 'draft'" class="mt-4">
<NTimeline horizontal>
<NTimelineItem content="啊" />
<NTimelineItem type="success" title="成功" content="哪里成功" time="2018-04-03 20:46" />
<NTimelineItem type="error" content="哪里错误" time="2018-04-03 20:46" />
<NTimelineItem type="warning" title="警告" content="哪里警告" time="2018-04-03 20:46" />
<NTimelineItem type="info" title="信息" content="是的" time="2018-04-03 20:46" line-type="dashed" />
<NTimelineItem content="啊" />
</NTimeline>
</div>
<!-- -->
<ApprovalInfoPanel v-if="modelDetail.status !== 'draft'" :business-id="modelDetail.id!" />
</div>
<template #footer>
<div v-if="!readonly">
<NSpace :size="16">

View File

@ -1,5 +1,17 @@
import { transformRecordToOption } from '@/utils/common';
export const cooperateTypeRecord: Record<Api.Workflow.CooperateType, string> = {
1: '审批',
2: '转办',
3: '委派',
4: '会签',
5: '票签',
6: '加签',
7: '减签'
};
export const cooperateTypeOptions = transformRecordToOption(cooperateTypeRecord);
export const businessStatusRecord: Record<Api.Workflow.BusinessStatus, string> = {
cancel: '已撤销',
draft: '草稿',

View File

@ -34,3 +34,11 @@ export function fetchFlowInvalidOperate(data: Api.Workflow.FlowInvalidOperatePar
data
});
}
/** 获取流程记录 */
export function fetchGetFlowHisTaskList(businessId: CommonType.IdType) {
return request<Api.Workflow.InstanceIdWithHisTask>({
url: `/workflow/instance/flowHisTaskList/${businessId}`,
method: 'get'
});
}

View File

@ -247,11 +247,9 @@ declare namespace Api {
show: boolean;
}>;
/** 任务详情 */
type Task = Common.CommonRecord<{
type Task = Common.CommonTenantRecord<{
/** 任务ID */
id: CommonType.IdType;
/** 租户编号 */
tenantId: CommonType.IdType;
/** 删除标志 */
delFlag: number;
/** 流程定义ID */
@ -280,7 +278,7 @@ declare namespace Api {
category: CommonType.IdType;
/** 分类名称 */
categoryName: string;
/** 类型 */
/** 办理人类型 */
type: string;
/** 审批人 */
assigneeIds: string;
@ -307,6 +305,82 @@ declare namespace Api {
/** 流程版本号 */
version: string;
}>;
/** 协作方式 */
type CooperateType = 1 | 2 | 3 | 4 | 5 | 6 | 7;
/** 历史任务 */
type HisTask = Common.CommonTenantRecord<{
/** 任务ID */
id: CommonType.IdType;
/** 删除标志 */
delFlag: number;
/** 流程定义ID */
definitionId: CommonType.IdType;
/** 流程定义名称 */
flowName: string;
/** 流程实例ID */
instanceId: CommonType.IdType;
/** 任务表ID */
taskId: CommonType.IdType;
/** 协作方式1审批 2转办 3委派 4会签 5票签 6加签 7减签 */
cooperateType: CooperateType;
/** 协作方式名称 */
cooperateTypeName: string;
/** 业务ID */
businessId: string;
/** 节点编码 */
nodeCode: string;
/** 节点名称 */
nodeName: string;
/** 节点类型0开始节点 1中间节点 2结束节点 3互斥网关 4并行网关 */
nodeType: WorkflowNodeType;
/** 目标节点编码 */
targetNodeCode: string;
/** 目标节点名称 */
targetNodeName: string;
/** 审批者 */
approver: string;
/** 审批者名称 */
approveName: string;
/** 协作人 */
collaborator: string;
/** 权限标识 */
permissionList: string[];
/** 跳转类型PASS通过 REJECT退回 NONE无动作 */
skipType: string;
/** 流程状态 */
flowStatus: string;
/** 任务状态 */
flowTaskStatus: string;
/** 流程状态名称 */
flowStatusName: string;
/** 审批意见 */
message: string;
/** 业务扩展信息JSON字符串 */
ext: string;
/** 创建者姓名(申请人名称) */
createByName: string;
/** 流程分类ID */
category: string;
/** 流程分类名称 */
categoryName: string;
/** 审批表单是否自定义Y是 N否 */
formCustom: Api.Common.YesOrNoStatus;
/** 表单路径 */
formPath: string;
/** 流程定义编码 */
flowCode: string;
/** 流程版本号 */
version: string;
/** 运行时长 */
runDuration: string;
}>;
type InstanceIdWithHisTask = CommonType.RecordNullable<{
instanceId: CommonType.IdType;
list: HisTask[];
}>;
/** 消息类型 */
type MessageType = '1' | '2' | '3';

View File

@ -9,6 +9,7 @@ export {}
declare module 'vue' {
export interface GlobalComponents {
AppProvider: typeof import('./../components/common/app-provider.vue')['default']
ApprovalInfoPanel: typeof import('./../components/custom/work-flow/approval-info-panel.vue')['default']
BetterScroll: typeof import('./../components/custom/better-scroll.vue')['default']
BooleanTag: typeof import('./../components/custom/boolean-tag.vue')['default']
ButtonIcon: typeof import('./../components/custom/button-icon.vue')['default']
@ -124,6 +125,7 @@ declare module 'vue' {
NStatistic: typeof import('naive-ui')['NStatistic']
NSwitch: typeof import('naive-ui')['NSwitch']
NTab: typeof import('naive-ui')['NTab']
NTable: typeof import('naive-ui')['NTable']
NTabPane: typeof import('naive-ui')['NTabPane']
NTabs: typeof import('naive-ui')['NTabs']
NTag: typeof import('naive-ui')['NTag']