This commit is contained in:
jiangyong 2024-01-07 17:17:33 +08:00
parent 0cc9569692
commit a868f820bb
8 changed files with 155 additions and 134 deletions

View File

@ -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()
}

View File

@ -4,6 +4,7 @@ type Checkin struct {
Id int64
Username string
Day string
Month string
Exception string
Rawdata string
StartTime int64

View File

@ -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
}

View File

@ -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"

View File

@ -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())
}

View File

@ -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

View File

@ -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)

View File

@ -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