418 lines
14 KiB
Go
418 lines
14 KiB
Go
|
|
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
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
}
|