checkin
This commit is contained in:
parent
0cc9569692
commit
a868f820bb
|
@ -3,7 +3,6 @@ package main
|
|||
import (
|
||||
"enterprise/common/config"
|
||||
"enterprise/common/global"
|
||||
"enterprise/common/weixin"
|
||||
"enterprise/server"
|
||||
"enterprise/worker"
|
||||
)
|
||||
|
@ -20,25 +19,9 @@ func main() {
|
|||
panic(err)
|
||||
}
|
||||
}
|
||||
func main3() {
|
||||
config.LoadServerConfig()
|
||||
global.InitGlobal()
|
||||
//cfg := config.GetConfig()
|
||||
worker.SyncStaffInfo()
|
||||
worker.SyncStaffSalary("")
|
||||
|
||||
}
|
||||
|
||||
func main2() {
|
||||
config.LoadServerConfig()
|
||||
//global.InitGlobal()
|
||||
|
||||
pay := weixin.NewQyPay()
|
||||
if err := pay.PayRedMoney(&weixin.RedMoneyReq{
|
||||
TotalAmount: 200,
|
||||
Title: "加班补贴",
|
||||
Userid: "jiangyong",
|
||||
}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
global.InitGlobal()
|
||||
//cfg := config.GetConfig()
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ type Checkin struct {
|
|||
Id int64
|
||||
Username string
|
||||
Day string
|
||||
Month string
|
||||
Exception string
|
||||
Rawdata string
|
||||
StartTime int64
|
||||
|
|
|
@ -9,12 +9,12 @@ import (
|
|||
"github.com/smbrave/goutil"
|
||||
"github.com/spf13/cast"
|
||||
"gorm.io/gorm/utils"
|
||||
"math"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type UserCheckIn struct {
|
||||
Day string
|
||||
Month string
|
||||
UserId string
|
||||
Exception string
|
||||
Rawdata string
|
||||
|
@ -22,6 +22,11 @@ type UserCheckIn struct {
|
|||
EndTime int64
|
||||
}
|
||||
|
||||
func (u *UserCheckIn) String() string {
|
||||
return fmt.Sprintf("[%s][%s][%s~%s][%s]", u.UserId, u.Day,
|
||||
goutil.TimeToDateTime(u.StartTime), goutil.TimeToDateTime(u.EndTime), u.Exception)
|
||||
}
|
||||
|
||||
type QyWeixinCheckin struct {
|
||||
QyWeixin
|
||||
}
|
||||
|
@ -56,7 +61,7 @@ func (q *QyWeixinCheckin) GetCheckinEmployee(groupIds []string) ([]string, error
|
|||
groups := cast.ToSlice(result["group"])
|
||||
for _, group := range groups {
|
||||
g := cast.ToStringMap(group)
|
||||
if !utils.Contains(groupIds, cast.ToString(g["groupid"])) {
|
||||
if len(groupIds) != 0 && !utils.Contains(groupIds, cast.ToString(g["groupid"])) {
|
||||
continue
|
||||
}
|
||||
ranges := cast.ToStringMap(g["range"])
|
||||
|
@ -66,15 +71,16 @@ func (q *QyWeixinCheckin) GetCheckinEmployee(groupIds []string) ([]string, error
|
|||
return resultUser, nil
|
||||
}
|
||||
|
||||
func (q *QyWeixinCheckin) GetCheckinData(day, userId string) (*UserCheckIn, error) {
|
||||
func (q *QyWeixinCheckin) GetCheckinData(startDay, endDay string, userIds []string) ([]*UserCheckIn, error) {
|
||||
|
||||
dayTime, _ := time.ParseInLocation("2006-01-02", day, time.Local)
|
||||
dayTime, _ := time.ParseInLocation("2006-01-02", startDay, time.Local)
|
||||
endTime, _ := time.ParseInLocation("2006-01-02", endDay, time.Local)
|
||||
|
||||
reqData := make(map[string]interface{})
|
||||
reqData["opencheckindatatype"] = 1
|
||||
reqData["starttime"] = dayTime.Unix()
|
||||
reqData["endtime"] = dayTime.Unix() + 86400
|
||||
reqData["useridlist"] = []string{userId}
|
||||
reqData["endtime"] = endTime.Unix() + 86400
|
||||
reqData["useridlist"] = userIds
|
||||
reqUrl := fmt.Sprintf("%s?access_token=%s", urlGetCheckinData, q.GetToken())
|
||||
rspBody, err := butil.HttpPostJson(reqUrl, nil, []byte(goutil.EncodeJSON(reqData)))
|
||||
if err != nil {
|
||||
|
@ -90,39 +96,50 @@ func (q *QyWeixinCheckin) GetCheckinData(day, userId string) (*UserCheckIn, erro
|
|||
return nil, errors.New(string(rspBody))
|
||||
}
|
||||
|
||||
checkindatas := cast.ToSlice(result["checkindata"])
|
||||
userData := new(UserCheckIn)
|
||||
userData.UserId = userId
|
||||
exception := make([]string, 0)
|
||||
isException := false
|
||||
startTime := int64(math.MaxInt64)
|
||||
endTime := int64(0)
|
||||
for _, checkdata := range checkindatas {
|
||||
c := cast.ToStringMap(checkdata)
|
||||
datas := cast.ToSlice(result["checkindata"])
|
||||
checkData := make(map[string]*UserCheckIn)
|
||||
for _, dat := range datas {
|
||||
c := cast.ToStringMap(dat)
|
||||
exceptionType := cast.ToString(c["exception_type"])
|
||||
checkinType := cast.ToString(c["checkin_type"])
|
||||
userid := cast.ToString(c["userid"])
|
||||
checkinTime := cast.ToInt64(c["checkin_time"])
|
||||
schCheckinTime := cast.ToInt64(c["sch_checkin_time"])
|
||||
if schCheckinTime == 0 {
|
||||
schCheckinTime = checkinTime
|
||||
}
|
||||
checkDay := time.Unix(schCheckinTime, 0).Format("2006-01-02")
|
||||
checkMonth := time.Unix(schCheckinTime, 0).Format("200601")
|
||||
key := fmt.Sprintf("%s_%s", userid, checkDay)
|
||||
var userData *UserCheckIn = nil
|
||||
var ok bool
|
||||
if userData, ok = checkData[key]; !ok {
|
||||
userData = new(UserCheckIn)
|
||||
userData.UserId = userid
|
||||
userData.Day = checkDay
|
||||
userData.Month = checkMonth
|
||||
checkData[key] = userData
|
||||
}
|
||||
if exceptionType != "" {
|
||||
isException = true
|
||||
userData.Exception += goutil.If(userData.Exception != "", ",", "")
|
||||
userData.Exception += checkinType + ":" + exceptionType
|
||||
}
|
||||
userData.Rawdata = goutil.If(userData.Rawdata == "", "", "\n") + goutil.EncodeJSON(dat)
|
||||
if checkinType == "上班打卡" {
|
||||
userData.StartTime = goutil.If(userData.StartTime == 0 || checkinTime < userData.StartTime, checkinTime, userData.StartTime)
|
||||
} else if checkinType == "下班打卡" {
|
||||
userData.EndTime = goutil.If(checkinTime > userData.EndTime, checkinTime, userData.EndTime)
|
||||
} else {
|
||||
log.Errorf("不支持的打卡类型:%s %s", checkinType, goutil.EncodeJSON(dat))
|
||||
}
|
||||
}
|
||||
|
||||
exception = append(exception, exceptionType)
|
||||
if checkinTime < startTime {
|
||||
startTime = checkinTime
|
||||
userDatas := make([]*UserCheckIn, 0)
|
||||
for _, v := range checkData {
|
||||
if v.StartTime > v.EndTime {
|
||||
log.Errorf("user[%s][%s] checkin time error[%s~%s]", v.UserId, v.Day, goutil.TimeToDateTime(v.StartTime), goutil.TimeToDateTime(v.EndTime))
|
||||
}
|
||||
if checkinTime > endTime {
|
||||
endTime = checkinTime
|
||||
userDatas = append(userDatas, v)
|
||||
}
|
||||
}
|
||||
if startTime != int64(math.MaxInt64) {
|
||||
userData.StartTime = startTime
|
||||
}
|
||||
userData.EndTime = endTime
|
||||
userData.Rawdata = goutil.EncodeJSON(checkindatas)
|
||||
if isException {
|
||||
userData.Exception = strings.Join(exception, ",")
|
||||
}
|
||||
if userData.EndTime == 0 && userData.StartTime == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
return userData, nil
|
||||
return userDatas, nil
|
||||
}
|
||||
|
|
|
@ -4,8 +4,8 @@ address = "0.0.0.0:9283"
|
|||
log_level = 6
|
||||
|
||||
[mysql]
|
||||
host = "100.100.199.74"
|
||||
port = 3307
|
||||
host = "14.22.113.49"
|
||||
port = 9305
|
||||
user = "root"
|
||||
pass = "ZW5aaGVuMIIBIj"
|
||||
db = "enterprise"
|
||||
|
@ -27,6 +27,7 @@ checkin_agent = "3010011"
|
|||
checkin_secret = "6ljYNGt4DonZLmr9SCtgkTlOvtqmsOchBrTWwGl_GpU"
|
||||
checkin_group = "1,2"
|
||||
checkin_pay_thresold = 11
|
||||
checkin_onduty_pay_day = ""
|
||||
pay_secret = "JCGsxntR4E7wrEEQvWGr8_wdKtRlw48n-W6zd8lbwc4"
|
||||
pay_agent = "3010046"
|
||||
|
||||
|
|
|
@ -35,11 +35,11 @@ func (s *Staff) Salary(ctx *gin.Context) {
|
|||
}
|
||||
|
||||
func (s *Staff) SyncStaffInfo(ctx *gin.Context) {
|
||||
go worker.SyncStaffInfo()
|
||||
go new(worker.Staff).SyncStaffInfo()
|
||||
ctx.JSON(http.StatusOK, session.NewRspOk())
|
||||
}
|
||||
|
||||
func (s *Staff) SyncStaffSalary(ctx *gin.Context) {
|
||||
go worker.SyncStaffSalary("")
|
||||
go new(worker.Staff).SyncStaffSalary("")
|
||||
ctx.JSON(http.StatusOK, session.NewRspOk())
|
||||
}
|
||||
|
|
|
@ -6,71 +6,91 @@ import (
|
|||
"enterprise/common/model"
|
||||
"enterprise/common/weixin"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"strings"
|
||||
"github.com/smbrave/goutil"
|
||||
"time"
|
||||
)
|
||||
|
||||
func SyncCheckin(day string) error {
|
||||
type CheckIn struct {
|
||||
}
|
||||
|
||||
func (c *CheckIn) SyncCheckinMonth(month string) error {
|
||||
if month == "" {
|
||||
month = time.Now().AddDate(0, -1, 0).Format("200601")
|
||||
}
|
||||
cfg := config.GetConfig()
|
||||
|
||||
startTime, _ := time.ParseInLocation("20060102", month+"01", time.Local)
|
||||
endDay := startTime.AddDate(0, 1, -1).Format("2006-01-02")
|
||||
startDay := startTime.Format("2006-01-02")
|
||||
|
||||
qyw := weixin.NewQyWeixinCheckin(cfg.QyWeixin.Corpid, cfg.QyWeixin.CheckinSecret, cfg.QyWeixin.CheckinAgent)
|
||||
users, err := qyw.GetCheckinEmployee(strings.Split(cfg.QyWeixin.CheckinGroup, ","))
|
||||
users, err := qyw.GetCheckinEmployee(nil)
|
||||
if err != nil {
|
||||
log.Errorf("GetCheckinEmployee error :%s", err.Error())
|
||||
return err
|
||||
}
|
||||
|
||||
checkinDao := dao.NewCheckinDao()
|
||||
for _, user := range users {
|
||||
isNew := false
|
||||
isUpdate := false
|
||||
checkin, err := checkinDao.GetByDay(user, day)
|
||||
userDatas, err := qyw.GetCheckinData(startDay, endDay, users)
|
||||
if err != nil {
|
||||
log.Errorf("db error :%s", err.Error())
|
||||
continue
|
||||
log.Errorf("GetCheckinData[%s-%s]%s error :%s", startDay, endDay, goutil.EncodeJSON(users), err.Error())
|
||||
return err
|
||||
}
|
||||
if checkin == nil {
|
||||
checkin = new(model.Checkin)
|
||||
checkin.Day = day
|
||||
checkin.Username = user
|
||||
isNew = true
|
||||
for _, user := range userDatas {
|
||||
c.saveToDB(user)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (c *CheckIn) SyncCheckinDay(day string) {
|
||||
cfg := config.GetConfig()
|
||||
qyw := weixin.NewQyWeixinCheckin(cfg.QyWeixin.Corpid, cfg.QyWeixin.CheckinSecret, cfg.QyWeixin.CheckinAgent)
|
||||
if day == "" {
|
||||
day = time.Now().AddDate(0, 0, -1).Format("2006-01-02")
|
||||
}
|
||||
users, err := qyw.GetCheckinEmployee(nil)
|
||||
if err != nil {
|
||||
log.Errorf("GetCheckinEmployee error :%s", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
realCheckin, err := qyw.GetCheckinData(day, user)
|
||||
userDatas, err := qyw.GetCheckinData(day, day, users)
|
||||
if err != nil {
|
||||
log.Errorf("qyweixin get checkin error :%s", err.Error())
|
||||
continue
|
||||
log.Errorf("GetCheckinData[%s-%s]%s error :%s", day, day, goutil.EncodeJSON(users), err.Error())
|
||||
return
|
||||
}
|
||||
if realCheckin == nil {
|
||||
continue
|
||||
}
|
||||
if realCheckin.StartTime != 0 && realCheckin.StartTime != checkin.StartTime {
|
||||
isUpdate = true
|
||||
checkin.StartTime = realCheckin.StartTime
|
||||
}
|
||||
if realCheckin.EndTime != 0 && realCheckin.EndTime != checkin.EndTime {
|
||||
isUpdate = true
|
||||
checkin.EndTime = realCheckin.EndTime
|
||||
}
|
||||
if realCheckin.Exception != "" && realCheckin.Exception != checkin.Exception {
|
||||
checkin.Exception = realCheckin.Exception
|
||||
isUpdate = true
|
||||
}
|
||||
checkin.Rawdata = realCheckin.Rawdata
|
||||
if isNew {
|
||||
_, err = checkinDao.Create(checkin)
|
||||
} else {
|
||||
err = checkinDao.Update(checkin)
|
||||
|
||||
for _, user := range userDatas {
|
||||
c.saveToDB(user)
|
||||
}
|
||||
return
|
||||
}
|
||||
func (c *CheckIn) saveToDB(user *weixin.UserCheckIn) error {
|
||||
checkin, err := dao.NewCheckinDao().GetByDay(user.UserId, user.Day)
|
||||
if err != nil {
|
||||
log.Errorf("db error :%s", err.Error())
|
||||
continue
|
||||
return err
|
||||
}
|
||||
isNew := false
|
||||
if checkin == nil {
|
||||
checkin = new(model.Checkin)
|
||||
checkin.Day = user.Day
|
||||
checkin.Month = user.Month
|
||||
checkin.Username = user.UserId
|
||||
isNew = true
|
||||
} else {
|
||||
checkin.Exception = user.Exception
|
||||
checkin.StartTime = user.StartTime
|
||||
checkin.EndTime = user.EndTime
|
||||
checkin.Month = user.Month
|
||||
}
|
||||
|
||||
if isNew {
|
||||
go NotifyCheckinOnDuty(checkin)
|
||||
_, err = dao.NewCheckinDao().Create(checkin)
|
||||
} else {
|
||||
err = dao.NewCheckinDao().Update(checkin)
|
||||
}
|
||||
if isUpdate {
|
||||
go NotifyCheckinOffDuty(checkin)
|
||||
}
|
||||
time.Sleep(300 * time.Second)
|
||||
if err != nil {
|
||||
log.Errorf("create/update db error :%s", err.Error())
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
@ -15,7 +15,10 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
func SendStaffSalaryBill(month string) {
|
||||
type Staff struct {
|
||||
}
|
||||
|
||||
func (s *Staff) SendStaffSalaryBill(month string) {
|
||||
staffSalarys, err := dao.NewStaffSalaryDao().Query(month)
|
||||
if err != nil {
|
||||
log.Errorf("db error :%s", err.Error())
|
||||
|
@ -42,7 +45,7 @@ func SendStaffSalaryBill(month string) {
|
|||
}
|
||||
}
|
||||
|
||||
func SyncStaffInfo() {
|
||||
func (s *Staff) SyncStaffInfo() {
|
||||
cfg := config.GetConfig()
|
||||
hrAssiant := weixin.NewQyWeixinHR(cfg.QyWeixin.Corpid, cfg.QyWeixin.HrSecret, cfg.QyWeixin.HrSecret)
|
||||
|
||||
|
@ -88,7 +91,7 @@ func SyncStaffInfo() {
|
|||
}
|
||||
}
|
||||
|
||||
func SyncStaffSalary(month string) {
|
||||
func (s *Staff) SyncStaffSalary(month string) {
|
||||
if month == "" {
|
||||
month = time.Now().AddDate(0, -1, 0).Format("2006-01")
|
||||
}
|
||||
|
@ -101,7 +104,7 @@ func SyncStaffSalary(month string) {
|
|||
log.Errorf("query staff db error :%s", err.Error())
|
||||
return
|
||||
}
|
||||
holidays, err := loadHoliday(month)
|
||||
holidays, err := s.loadHoliday(month)
|
||||
if err != nil {
|
||||
log.Errorf("loadHoliday error :%s", err.Error())
|
||||
return
|
||||
|
@ -205,7 +208,7 @@ func SyncStaffSalary(month string) {
|
|||
|
||||
}
|
||||
|
||||
func loadHoliday(month string) (map[string]float64, error) {
|
||||
func (s *Staff) loadHoliday(month string) (map[string]float64, error) {
|
||||
cfg := config.GetConfig().QyWeixin
|
||||
approve := weixin.NewQyWeixinApprove(cfg.Corpid, cfg.ApproveSecret, cfg.ApproveAgent)
|
||||
startTime, _ := time.ParseInLocation("200601", month, time.Local)
|
||||
|
|
|
@ -5,34 +5,30 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
func Init1() error {
|
||||
|
||||
for i := 0; i < 120; i++ {
|
||||
day := time.Now().AddDate(0, 0, -1-i).Format("2006-01-02")
|
||||
SyncCheckin(day)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func Init() error {
|
||||
timezone, _ := time.LoadLocation("Asia/Shanghai")
|
||||
cron := gocron.NewScheduler(timezone)
|
||||
cron.Every(1).Hour().Do(func() {
|
||||
go SyncCheckin(time.Now().Format("2006-01-02"))
|
||||
})
|
||||
staff := new(Staff)
|
||||
checkIn := new(CheckIn)
|
||||
|
||||
// 每天同步企业人事信息
|
||||
cron.Every(1).Day().At("01:00").Do(func() {
|
||||
go SyncStaffInfo()
|
||||
go staff.SyncStaffInfo()
|
||||
})
|
||||
|
||||
//同步每日考勤数据
|
||||
cron.Every(1).Day().At("04:00").Do(func() {
|
||||
go checkIn.SyncCheckinDay("")
|
||||
})
|
||||
|
||||
// 1-10号计算工资信息
|
||||
cron.Every(1).Month(1, 2, 3, 4, 5, 6, 7, 8, 9, 10).At("02:00").Do(func() {
|
||||
go SyncStaffSalary("")
|
||||
cron.Every(1).Month(1, 2, 3, 4, 5, 6, 7, 8, 9, 10).At("04:30").Do(func() {
|
||||
go staff.SyncStaffSalary("")
|
||||
})
|
||||
|
||||
//10号晚上8点发送工资单
|
||||
cron.Every(1).Month(10).At("22:00").Do(func() {
|
||||
go SendStaffSalaryBill(time.Now().AddDate(0, -1, 0).Format("200601"))
|
||||
cron.Every(1).Month(10).At("20:00").Do(func() {
|
||||
go staff.SendStaffSalaryBill(time.Now().AddDate(0, -1, 0).Format("200601"))
|
||||
})
|
||||
cron.StartAsync()
|
||||
return nil
|
||||
|
|
Loading…
Reference in New Issue