sync check in
This commit is contained in:
parent
d89ac5667b
commit
552ca9a699
|
@ -0,0 +1,79 @@
|
||||||
|
package util
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"crypto/tls"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Get 请求 link:请求url
|
||||||
|
func HttpGet(link string, header map[string]string) ([]byte, error) {
|
||||||
|
client := &http.Client{Timeout: 20 * time.Second}
|
||||||
|
|
||||||
|
req, err := http.NewRequest("GET", link, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if header != nil {
|
||||||
|
for k, v := range header {
|
||||||
|
req.Header.Add(k, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resp, err := client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
return nil, fmt.Errorf("%d:%s", resp.StatusCode, resp.Status)
|
||||||
|
}
|
||||||
|
return io.ReadAll(resp.Body)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Donwload(link string, localFile string) error {
|
||||||
|
res, err := http.Get(link)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
f, err := os.Create(localFile)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
io.Copy(f, res.Body)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// PostJson 请求
|
||||||
|
func HttpPostJson(link string, header map[string]string, json []byte) ([]byte, error) {
|
||||||
|
client := &http.Client{Timeout: 20 * time.Second}
|
||||||
|
//忽略https的证书
|
||||||
|
client.Transport = &http.Transport{
|
||||||
|
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := http.NewRequest("POST", link, bytes.NewBuffer(json))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
req.Header.Add("Content-Type", "application/json")
|
||||||
|
if header != nil {
|
||||||
|
for k, v := range header {
|
||||||
|
req.Header.Set(k, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
return nil, fmt.Errorf("%d:%s", resp.StatusCode, resp.Status)
|
||||||
|
}
|
||||||
|
return io.ReadAll(resp.Body)
|
||||||
|
}
|
|
@ -35,10 +35,21 @@ type Redis struct {
|
||||||
Password string `toml:"password"`
|
Password string `toml:"password"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type QyWeixin struct {
|
||||||
|
Corpid string `toml:"corpid"`
|
||||||
|
CheckinAgent string `toml:"checkin_agent"`
|
||||||
|
CheckinSecret string `toml:"checkin_secret"`
|
||||||
|
EnterpriseAgent string `toml:"enterprise_agent"`
|
||||||
|
EnterpriseSecret string `toml:"enterprise_secret"`
|
||||||
|
HrAgent string `toml:"hr_agent"`
|
||||||
|
HrSecret string `toml:"hr_secret"`
|
||||||
|
}
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Server *Server `toml:"server"`
|
Server *Server `toml:"server"`
|
||||||
Mysql *Mysql `toml:"mysql"`
|
Mysql *Mysql `toml:"mysql"`
|
||||||
Redis *Redis `toml:"redis"`
|
Redis *Redis `toml:"redis"`
|
||||||
|
QyWeixin *QyWeixin `toml:"qyweixin"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetEnv() string {
|
func GetEnv() string {
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
package dao
|
||||||
|
|
||||||
|
import (
|
||||||
|
"enterprise/common/model"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CheckinDao struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCheckinDao() *CheckinDao {
|
||||||
|
return &CheckinDao{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *CheckinDao) TableName() string {
|
||||||
|
return "checkin"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *CheckinDao) Create(o *model.Checkin) (int64, error) {
|
||||||
|
o.CreateTime = time.Now().Unix()
|
||||||
|
res := GetDB().Table(d.TableName()).Create(o)
|
||||||
|
return o.Id, res.Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *CheckinDao) Update(o *model.Checkin) error {
|
||||||
|
o.UpdateTime = time.Now().Unix()
|
||||||
|
tx := GetDB().Table(d.TableName())
|
||||||
|
res := tx.Save(o)
|
||||||
|
return res.Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *CheckinDao) Delete(id int64) error {
|
||||||
|
res := GetDB().Table(d.TableName()).Delete(&model.Checkin{}, id)
|
||||||
|
return res.Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *CheckinDao) Get(id int64) (*model.Checkin, error) {
|
||||||
|
var u model.Checkin
|
||||||
|
tx := GetDB().Table(d.TableName())
|
||||||
|
tx = tx.Where("id = ?", id)
|
||||||
|
res := tx.First(&u)
|
||||||
|
if res.Error == gorm.ErrRecordNotFound {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if res.Error != nil {
|
||||||
|
return nil, res.Error
|
||||||
|
}
|
||||||
|
return &u, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *CheckinDao) GetByDay(userId, day string) (*model.Checkin, error) {
|
||||||
|
var u model.Checkin
|
||||||
|
tx := GetDB().Table(d.TableName())
|
||||||
|
tx = tx.Where("user_id = ?", userId)
|
||||||
|
tx = tx.Where("day = ?", day)
|
||||||
|
res := tx.First(&u)
|
||||||
|
if res.Error == gorm.ErrRecordNotFound {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if res.Error != nil {
|
||||||
|
return nil, res.Error
|
||||||
|
}
|
||||||
|
return &u, nil
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package dao
|
||||||
|
|
||||||
|
import "gorm.io/gorm"
|
||||||
|
|
||||||
|
var (
|
||||||
|
db *gorm.DB
|
||||||
|
)
|
||||||
|
|
||||||
|
func SetDB(d *gorm.DB) {
|
||||||
|
db = d
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetDB() *gorm.DB {
|
||||||
|
return db
|
||||||
|
}
|
|
@ -3,6 +3,7 @@ package global
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"enterprise/common/config"
|
"enterprise/common/config"
|
||||||
|
"enterprise/common/dao"
|
||||||
"fmt"
|
"fmt"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"gorm.io/driver/mysql"
|
"gorm.io/driver/mysql"
|
||||||
|
@ -67,6 +68,7 @@ func initDB() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
db.Logger = &DBLogger{threshold: int64(2000)}
|
db.Logger = &DBLogger{threshold: int64(2000)}
|
||||||
|
dao.SetDB(db)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
package model
|
||||||
|
|
||||||
|
type Checkin struct {
|
||||||
|
Id int64
|
||||||
|
UserId string
|
||||||
|
Day string
|
||||||
|
StartTime int64
|
||||||
|
EndTime int64
|
||||||
|
CreateTime int64
|
||||||
|
UpdateTime int64
|
||||||
|
}
|
|
@ -1 +0,0 @@
|
||||||
package model
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
package qyweixin
|
||||||
|
|
||||||
|
type UserCheckIn struct {
|
||||||
|
UserId string
|
||||||
|
StartTime int64
|
||||||
|
EndTime int64
|
||||||
|
}
|
|
@ -0,0 +1,135 @@
|
||||||
|
package qyweixin
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
butil "enterprise/base/util"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
"github.com/smbrave/goutil"
|
||||||
|
"github.com/spf13/cast"
|
||||||
|
"gorm.io/gorm/utils"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
urlGetToken = "https://qyapi.weixin.qq.com/cgi-bin/gettoken"
|
||||||
|
urlGetCheckinRlue = "https://qyapi.weixin.qq.com/cgi-bin/checkin/getcorpcheckinoption"
|
||||||
|
urlGetCheckinData = "https://qyapi.weixin.qq.com/cgi-bin/checkin/getcheckindata"
|
||||||
|
)
|
||||||
|
|
||||||
|
type QyWeixin struct {
|
||||||
|
corpId string
|
||||||
|
secret string
|
||||||
|
token string
|
||||||
|
tokenExpire int64
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewQyWeixin(corpId, secret string) *QyWeixin {
|
||||||
|
return &QyWeixin{
|
||||||
|
corpId: corpId,
|
||||||
|
secret: secret,
|
||||||
|
tokenExpire: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *QyWeixin) refreshToken() error {
|
||||||
|
if time.Now().Unix() <= q.tokenExpire-600 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
reqUrl := fmt.Sprintf("%s?corpid=%s&corpsecret=%s", urlGetToken, q.corpId, q.secret)
|
||||||
|
rspBody, err := butil.HttpGet(reqUrl, nil)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("http url[%s] error :%s", reqUrl, err.Error())
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
result := make(map[string]interface{})
|
||||||
|
if err := json.Unmarshal(rspBody, &result); err != nil {
|
||||||
|
log.Errorf("http url[%s] result[%s] error :%s", reqUrl, string(rspBody), err.Error())
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if cast.ToInt(result["errcode"]) != 0 {
|
||||||
|
log.Errorf("http url[%s] result[%s] error ", reqUrl, string(rspBody))
|
||||||
|
return errors.New(string(rspBody))
|
||||||
|
}
|
||||||
|
|
||||||
|
q.token = cast.ToString(result["access_token"])
|
||||||
|
q.tokenExpire = time.Now().Unix() + cast.ToInt64(result["expires_in"])
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *QyWeixin) GetCheckinEmployee(groupIds []string) ([]string, error) {
|
||||||
|
if err := q.refreshToken(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
reqUrl := fmt.Sprintf("%s?access_token=%s", urlGetCheckinRlue, q.token)
|
||||||
|
rspBody, err := butil.HttpPostJson(reqUrl, nil, []byte("{}"))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
result := make(map[string]interface{})
|
||||||
|
if err := json.Unmarshal(rspBody, &result); err != nil {
|
||||||
|
log.Errorf("http url[%s] result[%s] error :%s", reqUrl, string(rspBody), err.Error())
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if cast.ToInt(result["errcode"]) != 0 {
|
||||||
|
log.Errorf("http url[%s] result[%s] error ", reqUrl, string(rspBody))
|
||||||
|
return nil, errors.New(string(rspBody))
|
||||||
|
}
|
||||||
|
|
||||||
|
resultUser := make([]string, 0)
|
||||||
|
groups := cast.ToSlice(result["group"])
|
||||||
|
for _, group := range groups {
|
||||||
|
g := cast.ToStringMap(group)
|
||||||
|
if !utils.Contains(groupIds, cast.ToString(g["groupid"])) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
ranges := cast.ToStringMap(g["range"])
|
||||||
|
userid := cast.ToStringSlice(ranges["userid"])
|
||||||
|
resultUser = append(resultUser, userid...)
|
||||||
|
}
|
||||||
|
return resultUser, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *QyWeixin) GetCheckinData(day, userId string) (*UserCheckIn, error) {
|
||||||
|
if err := q.refreshToken(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
dayTime, _ := time.ParseInLocation("2006-01-02", day, time.Local)
|
||||||
|
|
||||||
|
reqData := make(map[string]interface{})
|
||||||
|
reqData["opencheckindatatype"] = 1
|
||||||
|
reqData["starttime"] = dayTime.Unix()
|
||||||
|
reqData["endtime"] = dayTime.Unix() + 86400
|
||||||
|
reqData["useridlist"] = []string{userId}
|
||||||
|
reqUrl := fmt.Sprintf("%s?access_token=%s", urlGetCheckinData, q.token)
|
||||||
|
rspBody, err := butil.HttpPostJson(reqUrl, nil, []byte(goutil.EncodeJSON(reqData)))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
result := make(map[string]interface{})
|
||||||
|
if err := json.Unmarshal(rspBody, &result); err != nil {
|
||||||
|
log.Errorf("http url[%s] result[%s] error :%s", reqUrl, string(rspBody), err.Error())
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if cast.ToInt(result["errcode"]) != 0 {
|
||||||
|
log.Errorf("http url[%s] result[%s] error ", reqUrl, string(rspBody))
|
||||||
|
return nil, errors.New(string(rspBody))
|
||||||
|
}
|
||||||
|
|
||||||
|
checkindatas := cast.ToSlice(result["checkindata"])
|
||||||
|
userData := new(UserCheckIn)
|
||||||
|
userData.UserId = userId
|
||||||
|
for _, checkdata := range checkindatas {
|
||||||
|
c := cast.ToStringMap(checkdata)
|
||||||
|
checkinType := cast.ToString(c["checkin_type"])
|
||||||
|
if checkinType == "上班打卡" {
|
||||||
|
userData.StartTime = cast.ToInt64(c["checkin_time"])
|
||||||
|
} else if checkinType == "下班打卡" {
|
||||||
|
userData.EndTime = cast.ToInt64(c["checkin_time"])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return userData, nil
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
[server]
|
||||||
|
address = "0.0.0.0:9283"
|
||||||
|
#0:PAINC 1:FATAL 2:ERROR 3:WARNING 4:INFO 5:DEBUG 6:TRACE
|
||||||
|
log_level = 6
|
||||||
|
|
||||||
|
[mysql]
|
||||||
|
host = "100.100.199.74"
|
||||||
|
port = 3306
|
||||||
|
user = "enterprise"
|
||||||
|
pass = "QIDAQABo4G5MIG2MAkG"
|
||||||
|
db = "enterprise"
|
||||||
|
|
||||||
|
[redis]
|
||||||
|
addr="127.0.0.1:6379"
|
||||||
|
db=0
|
||||||
|
password=""
|
||||||
|
|
||||||
|
[qyweixin]
|
||||||
|
corpid = "ww43c49db2e88a17f8"
|
||||||
|
hr_agent = "3010185"
|
||||||
|
hr_secret = "Ko2UQWZPbdM9N1snukp_1CT_3J7CcReyPAzl3ww2xoo"
|
||||||
|
enterprise_agent = "1000009"
|
||||||
|
enterprise_secret = "oMB24UhKe50-XPTg7vhnwoTuhEXaq5XeiHPAUtF4hOs"
|
||||||
|
checkin_agent = "3010011"
|
||||||
|
checkin_secret = "6ljYNGt4DonZLmr9SCtgkTlOvtqmsOchBrTWwGl_GpU"
|
|
@ -6,11 +6,15 @@ log_level = 6
|
||||||
[mysql]
|
[mysql]
|
||||||
host = "127.0.0.1"
|
host = "127.0.0.1"
|
||||||
port = 3306
|
port = 3306
|
||||||
user = "unify2"
|
user = "enterprise"
|
||||||
pass = "MDE2LCJIYXNoSWQiOjY"
|
pass = "QIDAQABo4G5MIG2MAkG"
|
||||||
db = "unify2"
|
db = "enterprise"
|
||||||
|
|
||||||
[redis]
|
[redis]
|
||||||
addr="127.0.0.1:6379"
|
addr="127.0.0.1:6379"
|
||||||
db=0
|
db=0
|
||||||
password=""
|
password=""
|
||||||
|
|
||||||
|
[qyweixin]
|
||||||
|
corpid = "ww43c49db2e88a17f8"
|
||||||
|
checkin_secret = "6ljYNGt4DonZLmr9SCtgkTlOvtqmsOchBrTWwGl_GpU"
|
||||||
|
|
14
go.mod
14
go.mod
|
@ -3,8 +3,7 @@ module enterprise
|
||||||
go 1.18
|
go 1.18
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/ArtisanCloud/PowerWeChat/v3 v3.0.55
|
github.com/go-co-op/gocron v1.31.0
|
||||||
github.com/gogap/errors v0.0.0-20210818113853-edfbba0ddea9
|
|
||||||
github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible
|
github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible
|
||||||
github.com/mitchellh/mapstructure v1.5.0
|
github.com/mitchellh/mapstructure v1.5.0
|
||||||
github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5
|
github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5
|
||||||
|
@ -17,31 +16,22 @@ require (
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/ArtisanCloud/PowerLibs/v3 v3.0.12 // indirect
|
|
||||||
github.com/ArtisanCloud/PowerSocialite/v3 v3.0.6 // indirect
|
|
||||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
|
||||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
|
||||||
github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 // indirect
|
|
||||||
github.com/fsnotify/fsnotify v1.6.0 // indirect
|
github.com/fsnotify/fsnotify v1.6.0 // indirect
|
||||||
github.com/go-sql-driver/mysql v1.7.0 // indirect
|
github.com/go-sql-driver/mysql v1.7.0 // indirect
|
||||||
github.com/gogap/stack v0.0.0-20150131034635-fef68dddd4f8 // indirect
|
|
||||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||||
github.com/jinzhu/now v1.1.5 // indirect
|
github.com/jinzhu/now v1.1.5 // indirect
|
||||||
github.com/jonboulle/clockwork v0.4.0 // indirect
|
github.com/jonboulle/clockwork v0.4.0 // indirect
|
||||||
github.com/lestrrat-go/strftime v1.0.6 // indirect
|
github.com/lestrrat-go/strftime v1.0.6 // indirect
|
||||||
github.com/magiconair/properties v1.8.7 // indirect
|
github.com/magiconair/properties v1.8.7 // indirect
|
||||||
github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
|
|
||||||
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
|
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
|
||||||
github.com/pkg/errors v0.9.1 // indirect
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
github.com/redis/go-redis/v9 v9.0.3 // indirect
|
github.com/robfig/cron/v3 v3.0.1 // indirect
|
||||||
github.com/spf13/afero v1.9.5 // indirect
|
github.com/spf13/afero v1.9.5 // indirect
|
||||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||||
github.com/spf13/pflag v1.0.5 // indirect
|
github.com/spf13/pflag v1.0.5 // indirect
|
||||||
github.com/subosito/gotenv v1.4.2 // indirect
|
github.com/subosito/gotenv v1.4.2 // indirect
|
||||||
go.uber.org/atomic v1.9.0 // indirect
|
go.uber.org/atomic v1.9.0 // indirect
|
||||||
go.uber.org/multierr v1.8.0 // indirect
|
|
||||||
go.uber.org/zap v1.21.0 // indirect
|
|
||||||
golang.org/x/sys v0.8.0 // indirect
|
golang.org/x/sys v0.8.0 // indirect
|
||||||
golang.org/x/text v0.9.0 // indirect
|
golang.org/x/text v0.9.0 // indirect
|
||||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||||
|
|
|
@ -1 +1,56 @@
|
||||||
package worker
|
package worker
|
||||||
|
|
||||||
|
import (
|
||||||
|
"enterprise/common/config"
|
||||||
|
"enterprise/common/dao"
|
||||||
|
"enterprise/common/model"
|
||||||
|
"enterprise/common/qyweixin"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
func SyncCheckin(day string) error {
|
||||||
|
cfg := config.GetConfig()
|
||||||
|
qyw := qyweixin.NewQyWeixin(cfg.QyWeixin.Corpid, cfg.QyWeixin.CheckinSecret)
|
||||||
|
users, err := qyw.GetCheckinEmployee([]string{"1"})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
checkinDao := dao.NewCheckinDao()
|
||||||
|
for _, user := range users {
|
||||||
|
isNew := false
|
||||||
|
checkin, err := checkinDao.GetByDay(user, day)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("db error :%s", err.Error())
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if checkin == nil {
|
||||||
|
checkin = new(model.Checkin)
|
||||||
|
checkin.Day = day
|
||||||
|
checkin.UserId = user
|
||||||
|
isNew = true
|
||||||
|
}
|
||||||
|
|
||||||
|
realCheckin, err := qyw.GetCheckinData(day, user)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("qyweixin get checkin error :%s", err.Error())
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if realCheckin.StartTime != 0 {
|
||||||
|
checkin.StartTime = realCheckin.StartTime
|
||||||
|
}
|
||||||
|
if realCheckin.EndTime != 0 {
|
||||||
|
checkin.EndTime = realCheckin.EndTime
|
||||||
|
}
|
||||||
|
if isNew {
|
||||||
|
_, err = checkinDao.Create(checkin)
|
||||||
|
} else {
|
||||||
|
err = checkinDao.Update(checkin)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("db error :%s", err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,15 @@
|
||||||
package worker
|
package worker
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/go-co-op/gocron"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
func Init() error {
|
func Init() error {
|
||||||
|
timezone, _ := time.LoadLocation("Asia/Shanghai")
|
||||||
|
cron := gocron.NewScheduler(timezone)
|
||||||
|
cron.Every(10).Minute().Do(func() {
|
||||||
|
go SyncCheckin(time.Now().Format("2006-01-02"))
|
||||||
|
})
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue