WiiCITMS/servers/hrTools.go
2025-11-07 14:14:34 +08:00

358 lines
12 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package servers
import (
"WiiCITMS/process/hr"
"context"
"encoding/json"
"fmt"
"time"
"github.com/mark3labs/mcp-go/mcp"
"github.com/mark3labs/mcp-go/server"
)
// hr
var HRTools = []server.ServerTool{
{
Tool: mcp.NewTool(
"createOrganization",
mcp.WithDescription("create an organization, which can be a department, company, business unit, etc"),
mcp.WithString("name", mcp.Required(), mcp.Description("organization name")),
mcp.WithString("parentGuid", mcp.Description("parent organization,uuid")),
mcp.WithNumber("organizationType", mcp.Description("company type as 0,business unit as 1, department type as 2")),
),
Handler: func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
name := request.GetString("name", "")
if name == "" {
return nil, fmt.Errorf("name is required")
}
parent := request.GetString("parentGuid", "")
oType := request.GetInt("organizationType", 0)
rep, proc := hr.CreateOrganization(hr.CreateOrganizationRequest{OrganizationName: name, ParentGuid: parent, OrganizationType: oType})
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(
"queryOrganizationsWithName",
mcp.WithDescription("query an organization using its name may return fuzzy matching records, which may have multiple records"),
mcp.WithString("name", mcp.Required(), mcp.Description("organization name")),
mcp.WithNumber("limit", mcp.Description("paging parameters")),
mcp.WithNumber("offset", mcp.Description("paging parameters")),
),
Handler: func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
name := request.GetString("name", "")
if name == "" {
return nil, fmt.Errorf("name is required")
}
limit := request.GetInt("limit", 20)
offset := request.GetInt("offset", 1)
rep, proc := hr.QueryOrganizations(hr.QueryOrganizationsRequest{OrganizationName: name, 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(
"createStaffWithOrganization",
mcp.WithDescription("create an employee and specify the organization to which they belong"),
mcp.WithString("staffName", mcp.Required(), mcp.Description("staff name")),
mcp.WithString("affiliated", mcp.Required(), mcp.Description("organization guid")),
mcp.WithNumber("staffType", mcp.Description("staff type,as the default type, the formal type has a value of 0. the internship type has a value of 1")),
),
Handler: func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
staffName := request.GetString("staffName", "")
if staffName == "" {
return nil, fmt.Errorf("staffName is required")
}
affiliated := request.GetString("affiliated", "")
if affiliated == "" {
return nil, fmt.Errorf("affiliated is required")
}
staffType := request.GetInt("staffType", 0)
rep, proc := hr.CreateStaffWithOrganization(hr.CreateStaffWithOrganizationRequest{
StaffName: staffName,
Affiliated: affiliated,
StaffType: staffType,
AffiliatedType: 0,
})
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(
"createLeave",
mcp.WithDescription("创建请假申请"),
mcp.WithString("staffGuid", mcp.Required(), mcp.Description("员工ID")),
mcp.WithNumber("leaveType", mcp.Required(), mcp.Description("请假类型: 1-事假, 2-病假, 3-年假, 4-调休")),
mcp.WithString("startTime", mcp.Required(), mcp.Description("请假开始时间格式2006-01-02 15:04:05")),
mcp.WithString("endTime", mcp.Required(), mcp.Description("请假结束时间格式2006-01-02 15:04:05")),
mcp.WithNumber("duration", mcp.Required(), mcp.Description("请假时长(天)")),
mcp.WithString("reason", mcp.Required(), mcp.Description("请假原因")),
),
Handler: func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
// 获取参数
staffGuid := request.GetString("staffGuid", "")
if staffGuid == "" {
return nil, fmt.Errorf("员工ID不能为空")
}
leaveType := request.GetInt("leaveType", 0)
if leaveType <= 0 || leaveType > 4 {
return nil, fmt.Errorf("无效的请假类型")
}
// 解析时间
startTimeStr := request.GetString("startTime", "")
if startTimeStr == "" {
return nil, fmt.Errorf("开始时间不能为空")
}
startTime, err := time.Parse("2006-01-02 15:04:05", startTimeStr)
if err != nil {
return nil, fmt.Errorf("开始时间格式错误: %v", err)
}
endTimeStr := request.GetString("endTime", "")
if endTimeStr == "" {
return nil, fmt.Errorf("结束时间不能为空")
}
endTime, err := time.Parse("2006-01-02 15:04:05", endTimeStr)
if err != nil {
return nil, fmt.Errorf("结束时间格式错误: %v", err)
}
// 验证时间
if endTime.Before(startTime) {
return nil, fmt.Errorf("结束时间不能早于开始时间")
}
duration := request.GetFloat("duration", 0)
if duration <= 0 {
return nil, fmt.Errorf("请假时长必须大于0")
}
reason := request.GetString("reason", "")
if reason == "" {
return nil, fmt.Errorf("请假原因不能为空")
}
// 获取操作者ID默认为请假员工自己
operatorGuid := request.GetString("operatorGuid", staffGuid)
// 创建请假记录
rep, proc := hr.CreateLeave(hr.CreateLeaveRequest{
StaffGuid: staffGuid,
LeaveType: int(leaveType),
StartTime: startTime,
EndTime: endTime,
Duration: float32(duration),
Reason: reason,
}, operatorGuid)
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(
"createLeaveWithWorkflow",
mcp.WithDescription("创建请假申请并启动审批流程"),
mcp.WithString("staffGuid", mcp.Required(), mcp.Description("请假员工ID")),
mcp.WithNumber("leaveType", mcp.Required(), mcp.Description("请假类型: 1-事假, 2-病假, 3-年假, 4-调休")),
mcp.WithString("startTime", mcp.Required(), mcp.Description("请假开始时间格式2006-01-02 15:04:05")),
mcp.WithString("endTime", mcp.Required(), mcp.Description("请假结束时间格式2006-01-02 15:04:05")),
mcp.WithNumber("duration", mcp.Required(), mcp.Description("请假时长(天)")),
mcp.WithString("reason", mcp.Required(), mcp.Description("请假原因")),
mcp.WithString("initiatorGuid", mcp.Required(), mcp.Description("发起人用户ID可与请假员工ID相同")),
mcp.WithArray("approverGuids", mcp.Required(), mcp.Description("审批人用户ID列表按审批顺序排列")),
),
Handler: func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
// 获取基本参数
staffGuid := request.GetString("staffGuid", "")
if staffGuid == "" {
return nil, fmt.Errorf("员工ID不能为空")
}
leaveType := request.GetInt("leaveType", 0)
if leaveType <= 0 || leaveType > 4 {
return nil, fmt.Errorf("无效的请假类型")
}
// 解析时间
startTimeStr := request.GetString("startTime", "")
if startTimeStr == "" {
return nil, fmt.Errorf("开始时间不能为空")
}
startTime, err := time.Parse("2006-01-02 15:04:05", startTimeStr)
if err != nil {
return nil, fmt.Errorf("开始时间格式错误: %v", err)
}
endTimeStr := request.GetString("endTime", "")
if endTimeStr == "" {
return nil, fmt.Errorf("结束时间不能为空")
}
endTime, err := time.Parse("2006-01-02 15:04:05", endTimeStr)
if err != nil {
return nil, fmt.Errorf("结束时间格式错误: %v", err)
}
// 验证时间
if endTime.Before(startTime) {
return nil, fmt.Errorf("结束时间不能早于开始时间")
}
duration := request.GetFloat("duration", 0)
if duration <= 0 {
return nil, fmt.Errorf("请假时长必须大于0")
}
reason := request.GetString("reason", "")
if reason == "" {
return nil, fmt.Errorf("请假原因不能为空")
}
// 获取工作流参数
initiatorGuid := request.GetString("initiatorGuid", "")
if initiatorGuid == "" {
return nil, fmt.Errorf("发起人用户ID不能为空")
}
// 获取审批人列表
approverGuidsStr := request.GetString("approverGuids", "[]")
if approverGuidsStr == "[]" {
return nil, fmt.Errorf("审批人列表不能为空")
}
// 解析JSON格式的审批人列表
var approverGuidsArray []string
if err := json.Unmarshal([]byte(approverGuidsStr), &approverGuidsArray); err != nil {
return nil, fmt.Errorf("审批人列表格式错误: %v", err)
}
if len(approverGuidsArray) == 0 {
return nil, fmt.Errorf("审批人列表不能为空")
}
approverGuids := approverGuidsArray
// 创建请假参数
createLeaveRequest := hr.CreateLeaveRequest{
StaffGuid: staffGuid,
LeaveType: leaveType,
StartTime: startTime,
EndTime: endTime,
Duration: float32(duration),
Reason: reason,
}
// 创建请假并启动审批流程
rep, proc := hr.CreateLeaveWithWorkflow(createLeaveRequest, initiatorGuid, approverGuids)
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(
"queryLeaveWithWorkflow",
mcp.WithDescription("查询请假记录及审批状态"),
mcp.WithString("leaveGuid", mcp.Required(), mcp.Description("请假记录ID")),
),
Handler: func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
leaveGuid := request.GetString("leaveGuid", "")
if leaveGuid == "" {
return nil, fmt.Errorf("请假记录ID不能为空")
}
leave, workflowStatus, proc := hr.QueryLeaveWithWorkflowStatus(leaveGuid)
if proc.IsError() {
return mcp.NewToolResultText(""), proc.Error
}
// 构建响应结果
result := map[string]interface{}{
"leave": leave,
}
if workflowStatus != nil {
result["workflow"] = workflowStatus
}
repStr, err := json.Marshal(result)
if err != nil {
return mcp.NewToolResultText(""), err
}
return mcp.NewToolResultText(string(repStr)), nil
},
},
// 查询请假记录
{
Tool: mcp.NewTool(
"queryLeaves",
mcp.WithDescription("查询请假记录"),
mcp.WithString("staffGuid", mcp.Description("员工ID可选")),
mcp.WithNumber("limit", mcp.Description("分页参数,每页数量")),
mcp.WithNumber("offset", mcp.Description("分页参数,偏移量")),
),
Handler: func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
// 获取参数
staffGuid := request.GetString("staffGuid", "")
limit := request.GetInt("limit", 20) // 默认每页20条
offset := request.GetInt("offset", 0) // 默认从第0条开始
// 查询请假记录
rep, proc := hr.QueryLeaves(hr.QueryLeavesRequest{
StaffGuid: staffGuid,
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
},
},
}