This commit is contained in:
jiangyong27 2023-08-09 22:00:55 +08:00
parent dbcc049a4c
commit 6f409296d5
12 changed files with 226 additions and 32 deletions

View File

@ -3,7 +3,7 @@ package main
import ( import (
"enterprise/common/config" "enterprise/common/config"
"enterprise/common/global" "enterprise/common/global"
"enterprise/common/qyweixin" "enterprise/common/weixin"
"enterprise/server" "enterprise/server"
"enterprise/worker" "enterprise/worker"
) )
@ -22,10 +22,14 @@ func main() {
func main2() { func main2() {
config.LoadServerConfig() config.LoadServerConfig()
global.InitGlobal() //global.InitGlobal()
pay := qyweixin.NewQyPay() pay := weixin.NewQyPay()
if err := pay.PayRedMoney(); err != nil { if err := pay.PayRedMoney(&weixin.RedMoneyReq{
TotalAmount: 200,
Title: "加班补贴",
Userid: "jiangyong",
}); err != nil {
panic(err) panic(err)
} }
} }

View File

@ -36,17 +36,21 @@ type Redis struct {
} }
type QyWeixin struct { type QyWeixin struct {
Corpid string `toml:"corpid"` Corpid string `toml:"corpid"`
CheckinAgent string `toml:"checkin_agent"` CheckinAgent string `toml:"checkin_agent"`
CheckinSecret string `toml:"checkin_secret"` CheckinSecret string `toml:"checkin_secret"`
CheckinGroup string `toml:"checkin_group"` CheckinGroup string `toml:"checkin_group"`
CheckinPayMoney string `toml:"checkin_pay_money"`
CheckinPayTitle string `toml:"checkin_pay_title"`
CheckinPayThresold float64 `toml:"checkin_pay_thresold"` CheckinPayThresold float64 `toml:"checkin_pay_thresold"`
EnterpriseAgent string `toml:"enterprise_agent"`
EnterpriseSecret string `toml:"enterprise_secret"` EnterpriseAgent string `toml:"enterprise_agent"`
HrAgent string `toml:"hr_agent"` EnterpriseSecret string `toml:"enterprise_secret"`
HrSecret string `toml:"hr_secret"` HrAgent string `toml:"hr_agent"`
PaySecret string `toml:"pay_secret"` HrSecret string `toml:"hr_secret"`
PayAgent string `toml:"pay_agent"` PaySecret string `toml:"pay_secret"`
PayAgent string `toml:"pay_agent"`
} }
type WxPay struct { type WxPay struct {

View File

@ -0,0 +1,68 @@
package dao
import (
"enterprise/common/model"
"gorm.io/gorm"
"time"
)
type CheckinMoneyDao struct {
}
func NewCheckinMoneyDao() *CheckinMoneyDao {
return &CheckinMoneyDao{}
}
func (d *CheckinMoneyDao) TableName() string {
return "checkin_money"
}
func (d *CheckinMoneyDao) Create(o *model.CheckinMoney) (int64, error) {
o.CreateTime = time.Now().Unix()
res := GetDB().Table(d.TableName()).Create(o)
return o.Id, res.Error
}
func (d *CheckinMoneyDao) Update(o *model.CheckinMoney) error {
o.UpdateTime = time.Now().Unix()
tx := GetDB().Table(d.TableName())
res := tx.Save(o)
return res.Error
}
func (d *CheckinMoneyDao) Delete(id int64) error {
res := GetDB().Table(d.TableName()).Delete(&model.CheckinMoney{}, id)
return res.Error
}
func (d *CheckinMoneyDao) Get(id int64) (*model.CheckinMoney, error) {
var u model.CheckinMoney
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 *CheckinMoneyDao) GetByDay(userId, day, checkinType string) (*model.CheckinMoney, error) {
var u model.CheckinMoney
tx := GetDB().Table(d.TableName())
tx = tx.Where("user_id = ?", userId)
tx = tx.Where("checkin_type = ?", checkinType)
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
}

View File

@ -0,0 +1,12 @@
package model
type CheckinMoney struct {
Id int64
Day string
Userid string
CheckinId int64
CheckinType string
BillNo string
CreateTime int64
UpdateTime int64
}

View File

@ -1,4 +1,4 @@
package qyweixin package weixin
type UserCheckIn struct { type UserCheckIn struct {
UserId string UserId string

View File

@ -1,4 +1,4 @@
package qyweixin package weixin
import ( import (
"bytes" "bytes"

View File

@ -1,4 +1,4 @@
package qyweixin package weixin
import ( import (
"bytes" "bytes"
@ -10,6 +10,7 @@ import (
"fmt" "fmt"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"github.com/smbrave/goutil" "github.com/smbrave/goutil"
"github.com/spf13/cast"
"github.com/wechatpay-apiv3/wechatpay-go/core" "github.com/wechatpay-apiv3/wechatpay-go/core"
"github.com/wechatpay-apiv3/wechatpay-go/core/option" "github.com/wechatpay-apiv3/wechatpay-go/core/option"
"github.com/wechatpay-apiv3/wechatpay-go/utils" "github.com/wechatpay-apiv3/wechatpay-go/utils"
@ -18,10 +19,18 @@ import (
"time" "time"
) )
type RedMoneyReq struct {
TotalAmount int64
Title string
Userid string
BillNo string
}
type QyPay struct { type QyPay struct {
cli *core.Client cli *core.Client
tlsClient *http.Client tlsClient *http.Client
stdClient *http.Client stdClient *http.Client
qyClient *QyWeixin
} }
func NewQyPay() *QyPay { func NewQyPay() *QyPay {
@ -38,6 +47,7 @@ func NewQyPay() *QyPay {
} }
pay.tlsClient = client pay.tlsClient = client
pay.qyClient = NewQyWeixin(cfg.QyWeixin.Corpid, cfg.QyWeixin.HrSecret)
return pay return pay
} }
@ -109,7 +119,7 @@ func (w *QyPay) initPay() error {
return nil return nil
} }
func (p *QyPay) PayRedMoney() error { func (p *QyPay) PayRedMoney(req *RedMoneyReq) error {
if p.cli == nil { if p.cli == nil {
if err := p.initPay(); err != nil { if err := p.initPay(); err != nil {
return err return err
@ -117,16 +127,24 @@ func (p *QyPay) PayRedMoney() error {
} }
cfg := config.GetConfig() cfg := config.GetConfig()
param := newParams() param := newParams()
userOpenid, err := p.qyClient.GetOpenid(req.Userid)
if err != nil {
log.Errorf("get openid error :%s", err.Error())
return err
}
if req.BillNo == "" {
req.BillNo = fmt.Sprintf("QY%s%s", time.Now().Format("20060102150405"), butil.RandomStr(6))
}
param.Set("nonce_str", butil.RandomStr(32)) param.Set("nonce_str", butil.RandomStr(32))
param.Set("mch_billno", fmt.Sprintf("QY%s%s", time.Now().Format("20060102150405"), butil.RandomStr(6))) param.Set("mch_billno", req.BillNo)
param.Set("mch_id", cfg.WxPay.PayMchId) param.Set("mch_id", cfg.WxPay.PayMchId)
param.Set("wxappid", cfg.QyWeixin.Corpid) param.Set("wxappid", cfg.QyWeixin.Corpid)
param.Set("agentid", "1") param.Set("agentid", cfg.QyWeixin.PayAgent)
param.Set("re_openid", "oZZmL6Lx7Rj3vbNRXgA3ZpwU_tzM") param.Set("re_openid", userOpenid)
param.Set("total_amount", "100") param.Set("total_amount", cast.ToString(req.TotalAmount))
param.Set("wishing", "感谢您参加猜灯谜活动,祝您元宵节快乐!") param.Set("wishing", req.Title)
param.Set("act_name", "猜灯谜抢红包活动") param.Set("act_name", "企业红包")
param.Set("remark", "猜越多得越多,快来抢!") param.Set("remark", "企业红包")
param.Set("workwx_sign", param.QySignMd5(cfg.QyWeixin.PaySecret)) param.Set("workwx_sign", param.QySignMd5(cfg.QyWeixin.PaySecret))
param.Set("sign", param.SignMd5(cfg.WxPay.PayApiKeyV2)) param.Set("sign", param.SignMd5(cfg.WxPay.PayApiKeyV2))
@ -139,7 +157,11 @@ func (p *QyPay) PayRedMoney() error {
respParam := newParams() respParam := newParams()
respParam.Decode(rspBody) respParam.Decode(rspBody)
fmt.Println("req:", string(param.Encode()))
fmt.Println("resp: ", string(respParam.Encode())) returnCode := respParam.GetString("return_code")
return nil resultCoce := respParam.GetString("result_code")
if resultCoce == "SUCCESS" && returnCode == "SUCCESS" {
return nil
}
return errors.New(string(respParam.Encode()))
} }

View File

@ -1,4 +1,4 @@
package qyweixin package weixin
import ( import (
"encoding/json" "encoding/json"
@ -18,6 +18,7 @@ var (
urlGetToken = "https://qyapi.weixin.qq.com/cgi-bin/gettoken" urlGetToken = "https://qyapi.weixin.qq.com/cgi-bin/gettoken"
urlGetCheckinRlue = "https://qyapi.weixin.qq.com/cgi-bin/checkin/getcorpcheckinoption" urlGetCheckinRlue = "https://qyapi.weixin.qq.com/cgi-bin/checkin/getcorpcheckinoption"
urlGetCheckinData = "https://qyapi.weixin.qq.com/cgi-bin/checkin/getcheckindata" urlGetCheckinData = "https://qyapi.weixin.qq.com/cgi-bin/checkin/getcheckindata"
urlConvertOpenid = "https://qyapi.weixin.qq.com/cgi-bin/user/convert_to_openid"
) )
type QyWeixin struct { type QyWeixin struct {
@ -161,3 +162,25 @@ func (q *QyWeixin) GetCheckinData(day, userId string) (*UserCheckIn, error) {
} }
return userData, nil return userData, nil
} }
func (q *QyWeixin) GetOpenid(userid string) (string, error) {
if err := q.refreshToken(); err != nil {
return "", err
}
reqUrl := fmt.Sprintf("%s?access_token=%s", urlConvertOpenid, q.token)
rspBody, err := butil.HttpPostJson(reqUrl, nil, []byte(fmt.Sprintf(`{"userid" : "%s"}`, userid)))
if err != nil {
log.Errorf("httpPost 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))
}
return cast.ToString(result["openid"]), nil
}

View File

@ -24,6 +24,8 @@ enterprise_secret = "oMB24UhKe50-XPTg7vhnwoTuhEXaq5XeiHPAUtF4hOs"
checkin_agent = "3010011" checkin_agent = "3010011"
checkin_secret = "6ljYNGt4DonZLmr9SCtgkTlOvtqmsOchBrTWwGl_GpU" checkin_secret = "6ljYNGt4DonZLmr9SCtgkTlOvtqmsOchBrTWwGl_GpU"
checkin_group = "1,2" checkin_group = "1,2"
checkin_pay_money = 20
checkin_pay_title = "工作餐补贴"
checkin_pay_thresold = 11 checkin_pay_thresold = 11
pay_secret = "JCGsxntR4E7wrEEQvWGr8_wdKtRlw48n-W6zd8lbwc4" pay_secret = "JCGsxntR4E7wrEEQvWGr8_wdKtRlw48n-W6zd8lbwc4"
pay_agent = "3010046" pay_agent = "3010046"

View File

@ -1,19 +1,23 @@
package worker package worker
import ( import (
butil "enterprise/base/util"
"enterprise/common/config" "enterprise/common/config"
"enterprise/common/dao"
"enterprise/common/global" "enterprise/common/global"
"enterprise/common/model" "enterprise/common/model"
"enterprise/common/weixin"
"fmt" "fmt"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"github.com/smbrave/goutil" "github.com/smbrave/goutil"
"github.com/spf13/cast"
"strings" "strings"
"time" "time"
) )
func ViewCheckin(checkin *model.Checkin) { func NotifyCheckinOffDuty(checkin *model.Checkin) {
if checkin.Exception != "" { if checkin.Exception != "" {
log.Errorf("execption[%s] %s", checkin.Exception, goutil.EncodeJSON(checkin)) log.Infof("execption[%s] %s", checkin.Exception, goutil.EncodeJSON(checkin))
return return
} }
thresold := config.GetConfig().QyWeixin.CheckinPayThresold thresold := config.GetConfig().QyWeixin.CheckinPayThresold
@ -21,7 +25,47 @@ func ViewCheckin(checkin *model.Checkin) {
if duration < int64(3600*thresold) { if duration < int64(3600*thresold) {
return return
} }
autoPayMoney(checkin, "下班打卡")
}
func NotifyCheckinOnDuty(checkin *model.Checkin) {
message := make([]string, 0) message := make([]string, 0)
message = append(message, "【上班提醒】")
message = append(message, fmt.Sprintf("员工名称:%s", checkin.UserId))
message = append(message, fmt.Sprintf("考勤日期:%s", checkin.Day))
message = append(message, fmt.Sprintf("开始时间:%s", goutil.TimeToDateTime(checkin.StartTime)))
if err := global.SendMessage([]string{"jiangyong"}, strings.Join(message, "\n")); err != nil {
log.Errorf("send message error :%s", err.Error())
}
}
func autoPayMoney(checkin *model.Checkin, checkinType string) error {
cfg := config.GetConfig()
checkinMoneyDao := dao.NewCheckinMoneyDao()
checkinMoney, err := checkinMoneyDao.GetByDay(checkin.UserId, checkin.Day, checkinType)
if err != nil {
log.Errorf("db error :%s", err.Error())
return err
}
if checkinMoney != nil {
return nil
}
var req weixin.RedMoneyReq
req.TotalAmount = cast.ToInt64(cfg.QyWeixin.CheckinPayMoney) * 100
req.Title = cfg.QyWeixin.CheckinPayTitle
req.BillNo = fmt.Sprintf("QY%s%s", time.Now().Format("20060102150405"), butil.RandomStr(6))
req.Userid = "jiangyong"
if err := weixin.NewQyPay().PayRedMoney(&req); err != nil {
log.Errorf("pay red money error :%s", err.Error())
return err
}
message := make([]string, 0)
duration := checkin.EndTime - checkin.StartTime
message = append(message, "【下班提醒】")
message = append(message, fmt.Sprintf("员工名称:%s", checkin.UserId)) message = append(message, fmt.Sprintf("员工名称:%s", checkin.UserId))
message = append(message, fmt.Sprintf("考勤日期:%s", checkin.Day)) message = append(message, fmt.Sprintf("考勤日期:%s", checkin.Day))
message = append(message, fmt.Sprintf("开始时间:%s", goutil.TimeToDateTime(checkin.StartTime))) message = append(message, fmt.Sprintf("开始时间:%s", goutil.TimeToDateTime(checkin.StartTime)))
@ -31,4 +75,16 @@ func ViewCheckin(checkin *model.Checkin) {
if err := global.SendMessage([]string{"jiangyong"}, strings.Join(message, "\n")); err != nil { if err := global.SendMessage([]string{"jiangyong"}, strings.Join(message, "\n")); err != nil {
log.Errorf("send message error :%s", err.Error()) log.Errorf("send message error :%s", err.Error())
} }
checkinMoney = new(model.CheckinMoney)
checkinMoney.CheckinId = checkin.Id
checkinMoney.BillNo = req.BillNo
checkinMoney.CheckinType = checkinType
checkinMoney.Day = checkin.Day
if _, err := checkinMoneyDao.Create(checkinMoney); err != nil {
log.Errorf("create checkinMoney model error :%s", err.Error())
return err
}
return nil
} }

View File

@ -4,14 +4,14 @@ import (
"enterprise/common/config" "enterprise/common/config"
"enterprise/common/dao" "enterprise/common/dao"
"enterprise/common/model" "enterprise/common/model"
"enterprise/common/qyweixin" "enterprise/common/weixin"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"strings" "strings"
) )
func SyncCheckin(day string) error { func SyncCheckin(day string) error {
cfg := config.GetConfig() cfg := config.GetConfig()
qyw := qyweixin.NewQyWeixin(cfg.QyWeixin.Corpid, cfg.QyWeixin.CheckinSecret) qyw := weixin.NewQyWeixin(cfg.QyWeixin.Corpid, cfg.QyWeixin.CheckinSecret)
users, err := qyw.GetCheckinEmployee(strings.Split(cfg.QyWeixin.CheckinGroup, ",")) users, err := qyw.GetCheckinEmployee(strings.Split(cfg.QyWeixin.CheckinGroup, ","))
if err != nil { if err != nil {
return err return err
@ -62,8 +62,11 @@ func SyncCheckin(day string) error {
if err != nil { if err != nil {
log.Errorf("db error :%s", err.Error()) log.Errorf("db error :%s", err.Error())
} }
if isNew {
go NotifyCheckinOnDuty(checkin)
}
if isUpdate { if isUpdate {
go ViewCheckin(checkin) go NotifyCheckinOffDuty(checkin)
} }
} }

View File

@ -16,7 +16,7 @@ func Init1() error {
func Init() error { func Init() error {
timezone, _ := time.LoadLocation("Asia/Shanghai") timezone, _ := time.LoadLocation("Asia/Shanghai")
cron := gocron.NewScheduler(timezone) cron := gocron.NewScheduler(timezone)
cron.Every(5).Minute().Do(func() { cron.Every(1).Minute().Do(func() {
go SyncCheckin(time.Now().Format("2006-01-02")) go SyncCheckin(time.Now().Format("2006-01-02"))
}) })