WiiCITMS/servers/oaTools.go

418 lines
14 KiB
Go
Raw Normal View History

2025-11-07 14:14:34 +08:00
package servers
import (
"WiiCITMS/process/common"
"WiiCITMS/process/oa"
"context"
"encoding/json"
"fmt"
"github.com/mark3labs/mcp-go/mcp"
"github.com/mark3labs/mcp-go/server"
)
// OA 工作流相关工具
var OATools = []server.ServerTool{
// 创建工作流
{
Tool: mcp.NewTool(
"createWorkflow",
mcp.WithDescription("创建一个工作流定义"),
mcp.WithString("workflowName", mcp.Required(), mcp.Description("工作流名称")),
mcp.WithNumber("workflowType", mcp.Required(), mcp.Description("工作流类型: 1-请假, 2-报销, 3-采购, ...")),
mcp.WithString("description", mcp.Description("工作流描述")),
mcp.WithString("creatorGuid", mcp.Description("创建人GUID")),
),
Handler: func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
workflowName := request.GetString("workflowName", "")
if workflowName == "" {
return nil, fmt.Errorf("工作流名称不能为空")
}
workflowType := request.GetInt("workflowType", 0)
if workflowType <= 0 {
return nil, fmt.Errorf("工作流类型必须大于0")
}
description := request.GetString("description", "")
creatorGuid := request.GetString("creatorGuid", "")
rep, proc := oa.CreateWorkflow(oa.CreateWorkflowRequest{
WorkflowName: workflowName,
WorkflowType: workflowType,
Description: description,
CreatorGuid: creatorGuid,
})
if proc.IsError() {
return mcp.NewToolResultText(""), proc.Error
}
repStr, err := json.Marshal(rep)
if err != nil {
return mcp.NewToolResultText(""), err
}
return mcp.NewToolResultText(string(repStr)), nil
},
},
// 查询工作流列表
{
Tool: mcp.NewTool(
"queryWorkflows",
mcp.WithDescription("查询工作流定义列表"),
mcp.WithString("workflowName", mcp.Description("工作流名称,模糊查询")),
mcp.WithNumber("workflowType", mcp.Description("工作流类型,-1表示所有类型")),
mcp.WithBoolean("isActive", mcp.Description("是否只查询启用的工作流")),
mcp.WithNumber("limit", mcp.Description("分页参数,每页数量")),
mcp.WithNumber("offset", mcp.Description("分页参数,偏移量")),
),
Handler: func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
workflowName := request.GetString("workflowName", "")
workflowType := request.GetInt("workflowType", -1)
isActive := request.GetBool("isActive", false)
limit := request.GetInt("limit", 20)
offset := request.GetInt("offset", 0)
rep, proc := oa.QueryWorkflows(oa.QueryWorkflowsRequest{
WorkflowName: workflowName,
WorkflowType: workflowType,
IsActive: isActive,
Limit: limit,
Offset: offset,
})
if proc.IsError() {
return mcp.NewToolResultText(""), proc.Error
}
repStr, err := json.Marshal(rep)
if err != nil {
return mcp.NewToolResultText(""), err
}
return mcp.NewToolResultText(string(repStr)), nil
},
},
// 创建工作流节点
{
Tool: mcp.NewTool(
"createWorkflowNode",
mcp.WithDescription("创建工作流节点"),
mcp.WithString("workflowGuid", mcp.Required(), mcp.Description("所属工作流ID")),
mcp.WithString("nodeName", mcp.Required(), mcp.Description("节点名称")),
mcp.WithNumber("nodeType", mcp.Required(), mcp.Description("节点类型1-开始, 2-审批, 3-抄送, 4-条件, 5-结束")),
mcp.WithNumber("nodeOrder", mcp.Required(), mcp.Description("节点顺序")),
mcp.WithNumber("approverType", mcp.Description("审批人类型1-指定人, 2-角色, 3-部门负责人")),
mcp.WithString("approverValue", mcp.Description("审批人值用户ID、角色ID或JSON")),
mcp.WithString("conditionExp", mcp.Description("条件表达式(如果是条件节点)")),
mcp.WithString("description", mcp.Description("节点描述")),
),
Handler: func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
workflowGuid := request.GetString("workflowGuid", "")
if workflowGuid == "" {
return nil, fmt.Errorf("工作流ID不能为空")
}
nodeName := request.GetString("nodeName", "")
if nodeName == "" {
return nil, fmt.Errorf("节点名称不能为空")
}
nodeType := request.GetInt("nodeType", 0)
if nodeType <= 0 || nodeType > 5 {
return nil, fmt.Errorf("无效的节点类型")
}
nodeOrder := request.GetInt("nodeOrder", 0)
approverType := request.GetInt("approverType", 0)
approverValue := request.GetString("approverValue", "")
conditionExp := request.GetString("conditionExp", "")
description := request.GetString("description", "")
rep, proc := oa.CreateWorkflowNode(oa.CreateNodeRequest{
WorkflowGuid: workflowGuid,
NodeName: nodeName,
NodeType: nodeType,
NodeOrder: nodeOrder,
ApproverType: approverType,
ApproverValue: approverValue,
ConditionExp: conditionExp,
Description: description,
})
if proc.IsError() {
return mcp.NewToolResultText(""), proc.Error
}
repStr, err := json.Marshal(rep)
if err != nil {
return mcp.NewToolResultText(""), err
}
return mcp.NewToolResultText(string(repStr)), nil
},
},
// 查询工作流节点
{
Tool: mcp.NewTool(
"queryWorkflowNodes",
mcp.WithDescription("查询工作流节点"),
mcp.WithString("workflowGuid", mcp.Required(), mcp.Description("工作流ID")),
mcp.WithNumber("nodeType", mcp.Description("节点类型,-1表示所有类型")),
),
Handler: func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
workflowGuid := request.GetString("workflowGuid", "")
if workflowGuid == "" {
return nil, fmt.Errorf("工作流ID不能为空")
}
nodeType := request.GetInt("nodeType", -1)
rep, proc := oa.QueryWorkflowNodes(oa.QueryNodesRequest{
WorkflowGuid: workflowGuid,
NodeType: nodeType,
})
if proc.IsError() {
return mcp.NewToolResultText(""), proc.Error
}
repStr, err := json.Marshal(rep)
if err != nil {
return mcp.NewToolResultText(""), err
}
return mcp.NewToolResultText(string(repStr)), nil
},
},
// 启动工作流实例
{
Tool: mcp.NewTool(
"startWorkflowInstance",
mcp.WithDescription("启动一个工作流实例"),
mcp.WithString("workflowGuid", mcp.Required(), mcp.Description("工作流ID")),
mcp.WithString("title", mcp.Required(), mcp.Description("实例标题")),
mcp.WithNumber("businessType", mcp.Required(), mcp.Description("业务类型: 1-请假, 2-报销, 3-采购, ...")),
mcp.WithString("businessID", mcp.Required(), mcp.Description("业务ID如请假记录ID")),
mcp.WithString("initiatorGuid", mcp.Required(), mcp.Description("发起人ID")),
mcp.WithString("formData", mcp.Description("表单数据(JSON格式)")),
),
Handler: func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
workflowGuid := request.GetString("workflowGuid", "")
if workflowGuid == "" {
return nil, fmt.Errorf("工作流ID不能为空")
}
title := request.GetString("title", "")
if title == "" {
return nil, fmt.Errorf("实例标题不能为空")
}
businessType := request.GetInt("businessType", 0)
if businessType <= 0 {
return nil, fmt.Errorf("业务类型必须大于0")
}
businessID := request.GetString("businessID", "")
if businessID == "" {
return nil, fmt.Errorf("业务ID不能为空")
}
initiatorGuid := request.GetString("initiatorGuid", "")
if initiatorGuid == "" {
return nil, fmt.Errorf("发起人ID不能为空")
}
formData := request.GetString("formData", "")
// 在服务器端调用时启用权限检查
rep, proc := oa.StartWorkflowInstance(oa.CreateInstanceRequest{
WorkflowGuid: workflowGuid,
Title: title,
BusinessType: businessType,
BusinessID: businessID,
InitiatorGuid: initiatorGuid,
FormData: formData,
}, true) // 启用权限检查
if proc.IsError() {
return mcp.NewToolResultText(""), proc.Error
}
repStr, err := json.Marshal(rep)
if err != nil {
return mcp.NewToolResultText(""), err
}
return mcp.NewToolResultText(string(repStr)), nil
},
},
// 查询工作流实例
{
Tool: mcp.NewTool(
"queryWorkflowInstances",
mcp.WithDescription("查询工作流实例"),
mcp.WithString("workflowGuid", mcp.Description("工作流ID可选")),
mcp.WithNumber("businessType", mcp.Description("业务类型,-1表示所有类型")),
mcp.WithString("initiatorGuid", mcp.Description("发起人ID可选")),
mcp.WithNumber("status", mcp.Description("状态,-1表示所有状态")),
mcp.WithNumber("limit", mcp.Description("分页参数,每页数量")),
mcp.WithNumber("offset", mcp.Description("分页参数,偏移量")),
),
Handler: func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
workflowGuid := request.GetString("workflowGuid", "")
businessType := request.GetInt("businessType", -1)
initiatorGuid := request.GetString("initiatorGuid", "")
status := request.GetInt("status", -1)
limit := request.GetInt("limit", 20)
offset := request.GetInt("offset", 0)
rep, proc := oa.QueryWorkflowInstances(oa.QueryInstancesRequest{
WorkflowGuid: workflowGuid,
BusinessType: businessType,
InitiatorGuid: initiatorGuid,
Status: status,
Limit: limit,
Offset: offset,
})
if proc.IsError() {
return mcp.NewToolResultText(""), proc.Error
}
repStr, err := json.Marshal(rep)
if err != nil {
return mcp.NewToolResultText(""), err
}
return mcp.NewToolResultText(string(repStr)), nil
},
},
// 取消工作流实例
{
Tool: mcp.NewTool(
"cancelWorkflowInstance",
mcp.WithDescription("取消工作流实例"),
mcp.WithString("instanceGuid", mcp.Required(), mcp.Description("工作流实例ID")),
),
Handler: func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
instanceGuid := request.GetString("instanceGuid", "")
if instanceGuid == "" {
return nil, fmt.Errorf("工作流实例ID不能为空")
}
proc := oa.CancelWorkflowInstance(instanceGuid)
if proc.IsError() {
return mcp.NewToolResultText(""), proc.Error
}
return mcp.NewToolResultText("工作流实例取消成功"), nil
},
},
// 查询审批任务
{
Tool: mcp.NewTool(
"queryMyApprovalTasks",
mcp.WithDescription("查询我的审批任务"),
mcp.WithString("approverGuid", mcp.Required(), mcp.Description("审批人ID")),
mcp.WithNumber("status", mcp.Description("状态,-1表示所有状态")),
mcp.WithNumber("limit", mcp.Description("分页参数,每页数量")),
mcp.WithNumber("offset", mcp.Description("分页参数,偏移量")),
),
Handler: func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
approverGuid := request.GetString("approverGuid", "")
if approverGuid == "" {
return nil, fmt.Errorf("审批人ID不能为空")
}
status := request.GetInt("status", -1)
limit := request.GetInt("limit", 20)
offset := request.GetInt("offset", 0)
rep, proc := oa.QueryMyApprovalTasks(oa.QueryMyApprovalTasksRequest{
ApproverGuid: approverGuid,
Status: status,
Limit: limit,
Offset: offset,
})
if proc.IsError() {
return mcp.NewToolResultText(""), proc.Error
}
repStr, err := json.Marshal(rep)
if err != nil {
return mcp.NewToolResultText(""), err
}
return mcp.NewToolResultText(string(repStr)), nil
},
},
// 查询审批历史
{
Tool: mcp.NewTool(
"queryApprovalHistory",
mcp.WithDescription("查询流程审批历史"),
mcp.WithString("instanceGuid", mcp.Required(), mcp.Description("工作流实例ID")),
),
Handler: func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
instanceGuid := request.GetString("instanceGuid", "")
if instanceGuid == "" {
return nil, fmt.Errorf("工作流实例ID不能为空")
}
rep, proc := oa.QueryApprovalHistory(instanceGuid)
if proc.IsError() {
return mcp.NewToolResultText(""), proc.Error
}
repStr, err := json.Marshal(rep)
if err != nil {
return mcp.NewToolResultText(""), err
}
return mcp.NewToolResultText(string(repStr)), nil
},
},
// 处理审批
{
Tool: mcp.NewTool(
"processApproval",
mcp.WithDescription("处理审批任务"),
mcp.WithString("recordGuid", mcp.Required(), mcp.Description("审批记录ID")),
mcp.WithNumber("status", mcp.Required(), mcp.Description("操作结果1-同意2-拒绝3-转交4-委托")),
mcp.WithString("comment", mcp.Description("审批意见")),
mcp.WithString("targetGuid", mcp.Description("转交/委托目标人ID如果是转交或委托操作")),
),
Handler: func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
recordGuid := request.GetString("recordGuid", "")
if recordGuid == "" {
return nil, fmt.Errorf("审批记录ID不能为空")
}
// 获取审批人和实例信息
approverGuid := request.GetString("approverGuid", "")
if approverGuid == "" {
return nil, fmt.Errorf("审批人ID不能为空")
}
// 获取审批记录对应的实例ID
instanceGuid, err := oa.GetInstanceGuidByApprovalRecord(recordGuid)
if err != nil {
return nil, fmt.Errorf("获取工作流实例ID失败: %v", err)
}
// 检查权限
proc := oa.CheckWorkflowPermission(approverGuid, common.OperationApprove, instanceGuid)
if proc.IsError() {
return nil, fmt.Errorf("权限检查失败: %v", proc.Error)
}
status := request.GetInt("status", 0)
if status < 1 || status > 4 {
return nil, fmt.Errorf("无效的操作类型")
}
comment := request.GetString("comment", "")
targetGuid := request.GetString("targetGuid", "")
rep, proc := oa.ProcessApproval(oa.ApprovalActionRequest{
RecordGuid: recordGuid,
Status: status,
Comment: comment,
TargetGuid: targetGuid,
})
if proc.IsError() {
return mcp.NewToolResultText(""), proc.Error
}
repStr, err := json.Marshal(rep)
if err != nil {
return mcp.NewToolResultText(""), err
}
return mcp.NewToolResultText(string(repStr)), nil
},
},
}