前端业务模块接入
前端业务模块接入
本文面向前端开发,说明业务页面如何接入工作流发起弹窗,以及如何让工作流页面识别新的业务模块。
1. 当前注册方式
新增业务模块只需要在下面目录新增一个配置文件:
Web/src/views/workFlow/workflowForm/{module}.tsworkflowForm/index.ts 会自动聚合目录下除 index.ts、types.ts 外的配置文件。不要再手动修改 businessModuleConfig.ts 添加映射。
2. 请假模块配置
路径:Web/src/views/workFlow/workflowForm/leave.ts
export const leaveConfig: WorkflowFormConfig = {
label: '请假模块',
value: 'Leave',
apiPath: '/@/api/workflow/demo_leave',
apis: {
getListApiName: 'getLeavePage',
getDetailApiName: 'getLeaveDetail',
submitApiName: 'submitLeave',
},
detailComponentPath: '/@/views/demo/leave/LeaveDetail.vue',
enabled: true,
formPreviewRoute: '/demo/leave/index',
conditionFields: [
{ name: 'leaveType', label: '请假类型', type: 'string' },
{ name: 'days', label: '请假天数', type: 'number' },
],
};字段说明:
| 字段 | 必填 | 说明 |
|---|---|---|
label | 是 | 业务模块显示名 |
value | 是 | 业务模块唯一标识,必须等于后端 BusinessModuleConst 常量值 |
apiPath | 是 | API 文件路径,支持 /@/api/... |
apis.getListApiName | 是 | 列表接口函数名 |
apis.getDetailApiName | 是 | 详情接口函数名 |
apis.submitApiName | 是 | 提交审批接口函数名 |
detailComponentPath | 否 | 工作流详情中展示业务数据的组件 |
formPreviewRoute | 否 | 跳回原业务页面的路由 |
conditionFields | 否 | 流程条件字段,优先供设计器使用 |
enabled | 否 | 是否启用,默认启用 |
请假示例当前存在 Web/src/api/demo/leave.ts 和 Web/src/api/workflow/demo_leave.ts 两个内容相同的 API 文件。新增模块建议只保留一个 API 文件,并让业务页面和 workflowForm 配置都指向同一套导出函数,避免重复维护。
3. API 文件要求
API 文件至少导出 3 个函数,函数名要与 workflowForm 配置一致:
export const getPurchasePage = (data: any) => {
return request({ url: '/api/demo/purchase/page', method: 'post', data });
};
export const getPurchaseDetail = (params: { id: number }) => {
return request({ url: '/api/demo/purchase/detail', method: 'get', params });
};
export const submitPurchase = (data: any) => {
return request({ url: '/api/demo/purchase/submit', method: 'post', data });
};默认参数适配规则:
- 详情 API 会收到
{ businessId },适配层默认转换为{ businessId, id: businessId }。 - 提交 API 会收到
{ businessId, definitionId, workflowCode, remark }。
如果某个业务接口参数不标准,可以在配置里添加:
detailParamsResolver: (params) => ({ purchaseId: params.businessId }),
submitParamsResolver: (params) => ({
id: params.businessId,
definitionId: params.definitionId,
remark: params.remark,
}),4. 业务页面发起审批
请假页面路径:Web/src/views/demo/leave/index.vue
业务页面引入弹窗:
import BusinessWorkflowStartDialog from '../../workFlow/components/BusinessWorkflowStartDialog.vue';模板中传入业务模块和业务 ID:
<BusinessWorkflowStartDialog
v-if="state.workflowDialogRow"
v-model:visible="state.workflowDialogVisible"
business-module="Leave"
:business-id="state.workflowDialogRow.id"
@success="handleWorkflowStartSuccess"
/>打开弹窗:
const handleSubmitWorkflow = (row: any) => {
state.workflowDialogRow = row;
state.workflowDialogVisible = true;
};成功后刷新业务列表:
const handleWorkflowStartSuccess = () => {
state.workflowDialogVisible = false;
handleQuery();
};5. BusinessWorkflowStartDialog 做了什么
BusinessWorkflowStartDialog 的行为:
- 根据
businessModule查询流程定义:
getDefinitions({
page: 1,
pageSize: 50,
isActive: true,
onlyLatest: true,
businessModule: props.businessModule,
});- 用户选择流程定义。
- 通过
getBusinessModuleConfig(props.businessModule)找到业务模块配置。 - 优先调用业务模块
submitApi。 - 如果没有业务模块配置,才兜底调用
startWorkflowInstance。
因此新业务模块必须在 workflowForm 下注册配置,否则弹窗可能绕过业务 submit 接口。
6. 工作流详情组件
工作流待办、我发起的流程、已办等页面会通过 BusinessModuleDetail.vue 展示业务详情。它会:
- 按
businessModule找到detailComponentPath。 - 调用
getDetailApiName对应接口获取详情。 - 把详情数据作为
detailprop 传给业务详情组件。
请假详情组件路径:Web/src/views/demo/leave/LeaveDetail.vue
组件最小形态:
<template>
<el-descriptions v-if="detail" :column="2" border>
<el-descriptions-item label="申请人">{{ detail.applicantName }}</el-descriptions-item>
<el-descriptions-item label="审批状态">{{ detail.workflowStatus }}</el-descriptions-item>
</el-descriptions>
</template>
<script setup lang="ts">
defineProps<{ detail: any }>();
</script>详情组件不要再次发起详情查询,除非业务确实需要额外数据。通用详情加载已由 BusinessModuleDetail 完成。
7. 查看流程和原始表单
业务列表查看流程:
router.push({
path: '/workFlow/myInitiatedTasks',
query: { instanceCode },
});业务详情组件里可以通过 formPreviewRoute 返回原业务页面。项目已有辅助函数:
import { createBusinessModuleDetail } from '/@/views/workFlow/utils/createBusinessModuleDetail';
const { handleViewOriginalForm } = createBusinessModuleDetail('Leave', props.detail.id);