Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat:企业微信-打卡-打卡配置及规则管理 #755

Merged
merged 1 commit into from
Jan 12, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
387 changes: 387 additions & 0 deletions work/checkin/checkin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,387 @@
package checkin

import (
"fmt"

"github.com/silenceper/wechat/v2/util"
)

const (
// setScheduleListURL 为打卡人员排班
setScheduleListURL = "https://qyapi.weixin.qq.com/cgi-bin/checkin/setcheckinschedulist?access_token=%s"
// punchCorrectionURL 为打卡人员补卡
punchCorrectionURL = "https://qyapi.weixin.qq.com/cgi-bin/checkin/punch_correction?access_token=%s"
// addUserFaceURL 录入打卡人员人脸信息
addUserFaceURL = "https://qyapi.weixin.qq.com/cgi-bin/checkin/addcheckinuserface?access_token=%s"
// addOptionURL 创建打卡规则
addOptionURL = "https://qyapi.weixin.qq.com/cgi-bin/checkin/add_checkin_option?access_token=%s"
// updateOptionURL 修改打卡规则
updateOptionURL = "https://qyapi.weixin.qq.com/cgi-bin/checkin/update_checkin_option?access_token=%s"
// clearOptionURL 清空打卡规则数组元素
clearOptionURL = "https://qyapi.weixin.qq.com/cgi-bin/checkin/clear_checkin_option_array_field?access_token=%s"
// delOptionURL 删除打卡规则
delOptionURL = "https://qyapi.weixin.qq.com/cgi-bin/checkin/del_checkin_option?access_token=%s"
)

// SetScheduleListRequest 为打卡人员排班请求
type SetScheduleListRequest struct {
GroupID int64 `json:"groupid"`
Items []SetScheduleListItem `json:"items"`
YearMonth int64 `json:"yearmonth"`
}

// SetScheduleListItem 排班表信息
type SetScheduleListItem struct {
UserID string `json:"userid"`
Day int64 `json:"day"`
ScheduleID int64 `json:"schedule_id"`
}

// SetScheduleList 为打卡人员排班
// see https://developer.work.weixin.qq.com/document/path/93385
func (r *Client) SetScheduleList(req *SetScheduleListRequest) error {
var (
accessToken string
err error
)
if accessToken, err = r.GetAccessToken(); err != nil {
return err
}
var response []byte
if response, err = util.PostJSON(fmt.Sprintf(setScheduleListURL, accessToken), req); err != nil {
return err
}
return util.DecodeWithCommonError(response, "SetScheduleList")
}

// PunchCorrectionRequest 为打卡人员补卡请求
type PunchCorrectionRequest struct {
UserID string `json:"userid"`
ScheduleDateTime int64 `json:"schedule_date_time"`
ScheduleCheckinTime int64 `json:"schedule_checkin_time"`
CheckinTime int64 `json:"checkin_time"`
Remark string `json:"remark"`
}

// PunchCorrection 为打卡人员补卡
// see https://developer.work.weixin.qq.com/document/path/95803
func (r *Client) PunchCorrection(req *PunchCorrectionRequest) error {
var (
accessToken string
err error
)
if accessToken, err = r.GetAccessToken(); err != nil {
return err
}
var response []byte
if response, err = util.PostJSON(fmt.Sprintf(punchCorrectionURL, accessToken), req); err != nil {
return err
}
return util.DecodeWithCommonError(response, "PunchCorrection")
}

// AddUserFaceRequest 录入打卡人员人脸信息请求
type AddUserFaceRequest struct {
UserID string `json:"userid"`
UserFace string `json:"userface"`
}

// AddUserFace 录入打卡人员人脸信息
// see https://developer.work.weixin.qq.com/document/path/93378
func (r *Client) AddUserFace(req *AddUserFaceRequest) error {
var (
accessToken string
err error
)
if accessToken, err = r.GetAccessToken(); err != nil {
return err
}
var response []byte
if response, err = util.PostJSON(fmt.Sprintf(addUserFaceURL, accessToken), req); err != nil {
return err
}
return util.DecodeWithCommonError(response, "AddUserFace")
}

// AddOptionRequest 创建打卡规则请求
type AddOptionRequest struct {
EffectiveNow bool `json:"effective_now,omitempty"`
Group OptionGroupRule `json:"group,omitempty"`
}

// OptionGroupRule 打卡规则字段
type OptionGroupRule struct {
GroupID int64 `json:"groupid,omitempty"`
GroupType int64 `json:"grouptype"`
GroupName string `json:"groupname"`
CheckinDate []OptionGroupRuleCheckinDate `json:"checkindate,omitempty"`
SpeWorkdays []OptionGroupSpeWorkdays `json:"spe_workdays,omitempty"`
SpeOffDays []OptionGroupSpeOffDays `json:"spe_offdays,omitempty"`
SyncHolidays bool `json:"sync_holidays,omitempty"`
NeedPhoto bool `json:"need_photo,omitempty"`
NoteCanUseLocalPic bool `json:"note_can_use_local_pic,omitempty"`
WifiMacInfos []OptionGroupWifiMacInfos `json:"wifimac_infos,omitempty"`
LocInfos []OptionGroupLocInfos `json:"loc_infos,omitempty"`
AllowCheckinOffWorkday bool `json:"allow_checkin_offworkday,omitempty"`
AllowApplyOffWorkday bool `json:"allow_apply_offworkday,omitempty"`
Range []OptionGroupRange `json:"range"`
WhiteUsers []string `json:"white_users,omitempty"`
Type int64 `json:"type,omitempty"`
ReporterInfo OptionGroupReporterInfo `json:"reporterinfo,omitempty"`
AllowApplyBkCnt int64 `json:"allow_apply_bk_cnt,omitempty"`
AllowApplyBkDayLimit int64 `json:"allow_apply_bk_day_limit,omitempty"`
BukaLimitNextMonth int64 `json:"buka_limit_next_month,omitempty"`
OptionOutRange int64 `json:"option_out_range,omitempty"`
ScheduleList []OptionGroupScheduleList `json:"schedulelist,omitempty"`
OffWorkIntervalTime int64 `json:"offwork_interval_time,omitempty"`
UseFaceDetect bool `json:"use_face_detect,omitempty"`
OpenFaceLiveDetect bool `json:"open_face_live_detect,omitempty"`
OtInfoV2 OptionGroupOtInfoV2 `json:"ot_info_v2,omitempty"`
SyncOutCheckin bool `json:"sync_out_checkin,omitempty"`
BukaRemind OptionGroupBukaRemind `json:"buka_remind,omitempty"`
BukaRestriction int64 `json:"buka_restriction,omitempty"`
SpanDayTime int64 `json:"span_day_time,omitempty"`
StandardWorkDuration int64 `json:"standard_work_duration,omitempty"`
}

// OptionGroupRuleCheckinDate 固定时间上下班打卡时间
type OptionGroupRuleCheckinDate struct {
Workdays []int64 `json:"workdays"`
CheckinTime []OptionGroupRuleCheckinTime `json:"checkintime"`
FlexTime int64 `json:"flex_time"`
AllowFlex bool `json:"allow_flex"`
FlexOnDutyTime int64 `json:"flex_on_duty_time"`
FlexOffDutyTime int64 `json:"flex_off_duty_time"`
MaxAllowArriveEarly int64 `json:"max_allow_arrive_early"`
MaxAllowArriveLate int64 `json:"max_allow_arrive_late"`
LateRule OptionGroupLateRule `json:"late_rule"`
}

// OptionGroupRuleCheckinTime 工作日上下班打卡时间信息
type OptionGroupRuleCheckinTime struct {
TimeID int64 `json:"time_id"`
WorkSec int64 `json:"work_sec"`
OffWorkSec int64 `json:"off_work_sec"`
RemindWorkSec int64 `json:"remind_work_sec"`
RemindOffWorkSec int64 `json:"remind_off_work_sec"`
AllowRest bool `json:"allow_rest"`
RestBeginTime int64 `json:"rest_begin_time"`
RestEndTime int64 `json:"rest_end_time"`
EarliestWorkSec int64 `json:"earliest_work_sec"`
LatestWorkSec int64 `json:"latest_work_sec"`
EarliestOffWorkSec int64 `json:"earliest_off_work_sec"`
LatestOffWorkSec int64 `json:"latest_off_work_sec"`
NoNeedCheckOn bool `json:"no_need_checkon"`
NoNeedCheckOff bool `json:"no_need_checkoff"`
}

// OptionGroupLateRule 晚走晚到时间规则信息
type OptionGroupLateRule struct {
OffWorkAfterTime int64 `json:"offwork_after_time"`
OnWorkFlexTime int64 `json:"onwork_flex_time"`
AllowOffWorkAfterTime int64 `json:"allow_offwork_after_time"`
TimeRules []OptionGroupTimeRule `json:"timerules"`
}

// OptionGroupTimeRule 晚走晚到时间规则
type OptionGroupTimeRule struct {
OffWorkAfterTime int64 `json:"offwork_after_time"`
OnWorkFlexTime int64 `json:"onwork_flex_time"`
}

// OptionGroupSpeWorkdays 特殊工作日
type OptionGroupSpeWorkdays struct {
Timestamp int64 `json:"timestamp"`
Notes string `json:"notes"`
CheckinTime []OptionGroupCheckinTime `json:"checkintime"`
Type int64 `json:"type"`
BegTime int64 `json:"begtime"`
EndTime int64 `json:"endtime"`
}

// OptionGroupCheckinTime 特殊工作日的上下班打卡时间配置
type OptionGroupCheckinTime struct {
TimeID int64 `json:"time_id"`
WorkSec int64 `json:"work_sec"`
OffWorkSec int64 `json:"off_work_sec"`
RemindWorkSec int64 `json:"remind_work_sec"`
RemindOffWorkSec int64 `json:"remind_off_work_sec"`
}

// OptionGroupSpeOffDays 特殊非工作日
type OptionGroupSpeOffDays struct {
Timestamp int64 `json:"timestamp"`
Notes string `json:"notes"`
Type int64 `json:"type"`
BegTime int64 `json:"begtime"`
EndTime int64 `json:"endtime"`
}

// OptionGroupWifiMacInfos WIFI信息
type OptionGroupWifiMacInfos struct {
WifiName string `json:"wifiname"`
WifiMac string `json:"wifimac"`
}

// OptionGroupLocInfos 地点信息
type OptionGroupLocInfos struct {
Lat int64 `json:"lat"`
Lng int64 `json:"lng"`
LocTitle string `json:"loc_title"`
LocDetail string `json:"loc_detail"`
Distance int64 `json:"distance"`
}

// OptionGroupRange 人员信息
type OptionGroupRange struct {
PartyID []string `json:"party_id"`
UserID []string `json:"userid"`
TagID []int64 `json:"tagid"`
}

// OptionGroupReporterInfo 汇报人
type OptionGroupReporterInfo struct {
Reporters []OptionGroupReporters `json:"reporters"`
}

// OptionGroupReporters 汇报对象
type OptionGroupReporters struct {
UserID string `json:"userid"`
TagID int64 `json:"tagid"`
}

// OptionGroupScheduleList 自定义排班规则所有排班
type OptionGroupScheduleList struct {
ScheduleID int64 `json:"schedule_id"`
ScheduleName string `json:"schedule_name"`
TimeSection []OptionGroupTimeSection `json:"time_section"`
AllowFlex bool `json:"allow_flex"`
FlexOnDutyTime int64 `json:"flex_on_duty_time"`
FlexOffDutyTime int64 `json:"flex_off_duty_time"`
LateRule OptionGroupLateRule `json:"late_rule"`
MaxAllowArriveEarly int64 `json:"max_allow_arrive_early"`
MaxAllowArriveLate int64 `json:"max_allow_arrive_late"`
}

// OptionGroupTimeSection 班次上下班时段信息
type OptionGroupTimeSection struct {
TimeID int64 `json:"time_id"`
WorkSec int64 `json:"work_sec"`
OffWorkSec int64 `json:"off_work_sec"`
RemindWorkSec int64 `json:"remind_work_sec"`
RemindOffWorkSec int64 `json:"remind_off_work_sec"`
RestBeginTime int64 `json:"rest_begin_time"`
RestEndTime int64 `json:"rest_end_time"`
AllowRest bool `json:"allow_rest"`
EarliestWorkSec int64 `json:"earliest_work_sec"`
LatestWorkSec int64 `json:"latest_work_sec"`
EarliestOffWorkSec int64 `json:"earliest_off_work_sec"`
LatestOffWorkSec int64 `json:"latest_off_work_sec"`
NoNeedCheckOn bool `json:"no_need_checkon"`
NoNeedCheckOff bool `json:"no_need_checkoff"`
}

// OptionGroupOtInfoV2 加班配置
type OptionGroupOtInfoV2 struct {
WorkdayConf OptionGroupWorkdayConf `json:"workdayconf"`
}

// OptionGroupWorkdayConf 工作日加班配置
type OptionGroupWorkdayConf struct {
AllowOt bool `json:"allow_ot"`
Type int64 `json:"type"`
}

// OptionGroupBukaRemind 补卡提醒
type OptionGroupBukaRemind struct {
OpenRemind bool `json:"open_remind"`
BukaRemindDay int64 `json:"buka_remind_day"`
BukaRemindMonth int64 `json:"buka_remind_month"`
}

// AddOption 创建打卡规则
// see https://developer.work.weixin.qq.com/document/path/98041#%E5%88%9B%E5%BB%BA%E6%89%93%E5%8D%A1%E8%A7%84%E5%88%99
func (r *Client) AddOption(req *AddOptionRequest) error {
var (
accessToken string
err error
)
if accessToken, err = r.GetAccessToken(); err != nil {
return err
}
var response []byte
if response, err = util.PostJSON(fmt.Sprintf(addOptionURL, accessToken), req); err != nil {
return err
}
return util.DecodeWithCommonError(response, "AddOption")
}

// UpdateOptionRequest 修改打卡规则请求
type UpdateOptionRequest struct {
EffectiveNow bool `json:"effective_now,omitempty"`
Group OptionGroupRule `json:"group,omitempty"`
}

// UpdateOption 修改打卡规则
// see https://developer.work.weixin.qq.com/document/path/98041#%E4%BF%AE%E6%94%B9%E6%89%93%E5%8D%A1%E8%A7%84%E5%88%99
func (r *Client) UpdateOption(req *UpdateOptionRequest) error {
var (
accessToken string
err error
)
if accessToken, err = r.GetAccessToken(); err != nil {
return err
}
var response []byte
if response, err = util.PostJSON(fmt.Sprintf(updateOptionURL, accessToken), req); err != nil {
return err
}
return util.DecodeWithCommonError(response, "UpdateOption")
}

// ClearOptionRequest 清空打卡规则数组元素请求
type ClearOptionRequest struct {
GroupID int64 `json:"groupid"`
ClearField []int64 `json:"clear_field"`
EffectiveNow bool `json:"effective_now"`
}

// ClearOption 清空打卡规则数组元素
// see https://developer.work.weixin.qq.com/document/path/98041#%E6%B8%85%E7%A9%BA%E6%89%93%E5%8D%A1%E8%A7%84%E5%88%99%E6%95%B0%E7%BB%84%E5%85%83%E7%B4%A0
func (r *Client) ClearOption(req *ClearOptionRequest) error {
var (
accessToken string
err error
)
if accessToken, err = r.GetAccessToken(); err != nil {
return err
}
var response []byte
if response, err = util.PostJSON(fmt.Sprintf(clearOptionURL, accessToken), req); err != nil {
return err
}
return util.DecodeWithCommonError(response, "ClearOption")
}

// DelOptionRequest 删除打卡规则请求
type DelOptionRequest struct {
GroupID int64 `json:"groupid"`
EffectiveNow bool `json:"effective_now"`
}

// DelOption 删除打卡规则
// see https://developer.work.weixin.qq.com/document/path/98041#%E5%88%A0%E9%99%A4%E6%89%93%E5%8D%A1%E8%A7%84%E5%88%99
func (r *Client) DelOption(req *DelOptionRequest) error {
var (
accessToken string
err error
)
if accessToken, err = r.GetAccessToken(); err != nil {
return err
}
var response []byte
if response, err = util.PostJSON(fmt.Sprintf(delOptionURL, accessToken), req); err != nil {
return err
}
return util.DecodeWithCommonError(response, "DelOption")
}