Files
dingtalk-workspace-cli/internal/shortcut/smart/this_month_attendance.go
T

120 lines
5.6 KiB
Go

// Copyright 2026 Alibaba Group
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package smart
import (
"time"
"github.com/DingTalk-Real-AI/dingtalk-workspace-cli/internal/corecmd"
"github.com/DingTalk-Real-AI/dingtalk-workspace-cli/internal/corecmd/contract"
apperrors "github.com/DingTalk-Real-AI/dingtalk-workspace-cli/internal/errors"
"github.com/DingTalk-Real-AI/dingtalk-workspace-cli/internal/shortcut"
)
// ThisMonthAttendance: show MY punch-in (打卡流水) records for THIS MONTH in one
// step. It is the month-scoped sibling of +my-attendance (which covers today).
//
// Steps:
// 1. resolve the current logged-in user's userId via the contact server's
// zero-arg get_current_user_profile (no --name needed — it's always "me");
// 2. compute this month's window [1st 00:00, next-month 1st 00:00) in the local
// timezone and format both bounds as "yyyy-MM-dd HH:mm:ss" (the format the
// query_check_record helper feeds the tool);
// 3. call query_check_record on the attendance-wukong server with the exact
// nested QueryCheckRecordRequest shape used by
// `dws attendance check record`, then print via rt.Output.
//
// The month window spans at most 31 days, within query_check_record's span cap.
// Read-only; it never modifies any attendance data.
//
// dws attendance +this-month
var ThisMonthAttendance = shortcut.Shortcut{
Service: "attendance",
Command: "+this-month",
Product: "attendance",
Description: "查我本月的考勤打卡记录(打卡流水,自动解析当前用户)",
Intent: "当你想快速看自己本月的打卡流水(几点上下班打卡、打卡地址/定位方式)、又不想先查自己的 userId " +
"再手动填写本月的起止时间时使用;内部先取当前登录用户的 userId,再按本地时区算出本月 1 号 00:00 到下月 1 号 00:00 的时间窗," +
"最后查询你本月的打卡流水记录。只读操作,不会修改任何考勤数据;本月若还没有任何打卡则返回空结果。",
Risk: shortcut.RiskRead,
Safety: contract.SafetySpec{
Effect: "read", Risk: "low",
Confirmation: "not_required", Idempotency: "idempotent",
},
Contract: corecmd.ContractDecl{
Identity: contract.ToolIdentitySpec{
ProductID: "attendance",
Name: "shortcut_this_month",
CanonicalPath: "attendance.shortcut_this_month",
CLIPath: "attendance +this-month",
PrimaryCLIPath: "attendance +this-month",
},
Description: "查我本月的考勤打卡记录(打卡流水,自动解析当前用户)",
Interface: &contract.InterfaceSpec{
Mode: "composite",
Availability: "available",
Reason: "Reviewed built-in shortcut adapter: the executable CLI owns validation, optional multi-step orchestration, output projection, and confirmation; the complete command contract is not represented by one pinned MCP interface_ref.",
},
Selection: contract.SelectionSpec{
AgentSummary: "查我本月的考勤打卡记录(打卡流水,自动解析当前用户)",
UseWhen: []string{"当你想快速看自己本月的打卡流水(几点上下班打卡、打卡地址/定位方式)、又不想先查自己的 userId 再手动填写本月的起止时间时使用;内部先取当前登录用户的 userId,再按本地时区算出本月 1 号 00:00 到下月 1 号 00:00 的时间窗,最后查询你本月的打卡流水记录。只读操作,不会修改任何考勤数据;本月若还没有任何打卡则返回空结果。"},
AvoidWhen: []string{"需要该 Shortcut 未公开的底层参数、原始响应或不同执行语义时,改用对应原子命令"},
Examples: []string{"dws attendance +this-month"},
},
},
Flags: []shortcut.Flag{},
Tips: []string{
`dws attendance +this-month`,
},
Execute: func(rt *shortcut.RuntimeContext) error {
// Step 1 — resolve the current user's own userId (zero-arg "我的" API).
profile, err := rt.CallMCPData("contact", "get_current_user_profile", nil)
if err != nil {
return err
}
userID := myAttendanceCurrentUserID(profile)
if userID == "" {
return apperrors.NewValidation(
"没能解析出当前登录用户的 userId,无法查询你的打卡记录;请确认已登录后重试。")
}
// Step 2 — this month's window [1st 00:00, next-month 1st 00:00) in local
// time, formatted as the tool expects (yyyy-MM-dd HH:mm:ss).
now := time.Now()
start := time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, now.Location())
end := start.AddDate(0, 1, 0)
const layout = "2006-01-02 15:04:05"
// Step 3 — query my punch-in records for this month. The nested
// QueryCheckRecordRequest shape + field names mirror the
// `dws attendance check record` helper exactly.
data, err := rt.CallMCPData("attendance-wukong", "query_check_record", map[string]any{
"QueryCheckRecordRequest": map[string]any{
"userIds": []string{userID},
"checkDateFrom": start.Format(layout),
"checkDateTo": end.Format(layout),
},
})
if err != nil {
return err
}
return rt.Output(data)
},
}
func init() {
shortcut.Register(ThisMonthAttendance)
}