业务场景描述

  • 通过自然语言告诉大模型:帮我明天请一天假,明天家里有事。
  • 大模型会自动抽取从调用 flowable 请假流程的所有参数,提交发起流程

创建请求工作流程

创建请假流程

  • 【协同办公】> 【流程管理】> 【创建流程】 (名称:请假)

创建流程示例1

创建流程示例2

流程表单参数说明

参数名称ID
天数days
开始日期startDate
事由reason

AI 助手发起调用

AI助手发起流程

原理解析

@Component
@RequiredArgsConstructor
public class FlowFunctionCalling implements FunctionCalling<FlowRequest> {

    private final RemoteFlowApiFlowService flowService;

    /**
     * 路由路径
     *
     * @return {@link String }
     */
    @Override
    public String routePath() {
        return "/flow/task/started";
    }

    /**
     * 显示名称
     *
     * @return {@link String }
     */
    @Override
    public String showInfo() {
        return "请假助手,能根据您的描述帮您发起请求流程调用 flowable。比如:明天帮我请一天假,好兄弟结婚";
    }

    /**
     * 检查参数是否正确
     *
     * @param request
     * @param extDetails
     * @return
     */
    @Override
    public R<String> checkParams(FlowRequest request, PigxUser userDetails, ChatMessageDTO.ExtDetails extDetails) {
        return R.ok();
    }

    /**
     * 实际的数据源提供逻辑
     *
     * @param request    the function argument username
     * @param extDetails
     * @return Response
     */
    public R<String> handle(FlowRequest request, PigxUser user, ChatMessageDTO.ExtDetails extDetails) {

        R<List<FormGroupVo>> listR = flowService.listCurrentUserStartGroup();

        if (Objects.isNull(listR.getData())) {
            return R.failed("创建失败,权限不足");
        }

        String flowId = "";
        for (FormGroupVo formGroupVo : listR.getData()) {
            for (FormGroupVo.FlowVo item : formGroupVo.getItems()) {
                String name = item.getName();
                if (StrUtil.containsAnyIgnoreCase(request.getFlowName(), name)) {
                    flowId = item.getFlowId();
                }
            }
        }

        if (StrUtil.isBlank(flowId)) {
            return R.failed("创建失败,流程不存在");
        }

        // 获取流程配置详情
        ProcessInstanceParamDto processInstanceParamDto = new ProcessInstanceParamDto();
        processInstanceParamDto.setFlowId(flowId);
        processInstanceParamDto.setStartUserId(String.valueOf(user.getId()));

        Map<String, Object> paramMap = new HashMap<>();
        // 设置发起人
        Dict rootUser = Dict.create()
                .set("id", processInstanceParamDto.getStartUserId())
                .set("name", user.getUsername())
                .set("type", NodeUserTypeEnum.USER.getKey());
        paramMap.put("root", CollUtil.newArrayList(rootUser));
        paramMap.put("days", request.getDays());
        paramMap.put("reason", request.getReason());
        paramMap.put("startDate", request.getStartDate());

        processInstanceParamDto.setParamMap(paramMap);

        flowService.startInnerProcessInstance(processInstanceParamDto);
        return R.ok(StrUtil.format("流程发起成功,流程名称:{}", request.getFlowName()));
    }
}

@Data
@EqualsAndHashCode(callSuper = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonClassDescription("流程信息")
class FlowRequest extends BaseAiRequest {

    @FieldPrompt("流程名称:请假流程")
    private String flowName;

    @FieldPrompt("原因:请假原因")
    private String reason;

    @FieldPrompt("天数:请假天数")
    private Integer days;

    @FieldPrompt("开始日期:请假开始日期,格式为 yyyy-MM-dd")
    private String startDate;
}