|
|
@@ -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")
|
|
|
+}
|