auto pay
This commit is contained in:
parent
dbcc049a4c
commit
6f409296d5
|
@ -3,7 +3,7 @@ package main
|
|||
import (
|
||||
"enterprise/common/config"
|
||||
"enterprise/common/global"
|
||||
"enterprise/common/qyweixin"
|
||||
"enterprise/common/weixin"
|
||||
"enterprise/server"
|
||||
"enterprise/worker"
|
||||
)
|
||||
|
@ -22,10 +22,14 @@ func main() {
|
|||
|
||||
func main2() {
|
||||
config.LoadServerConfig()
|
||||
global.InitGlobal()
|
||||
//global.InitGlobal()
|
||||
|
||||
pay := qyweixin.NewQyPay()
|
||||
if err := pay.PayRedMoney(); err != nil {
|
||||
pay := weixin.NewQyPay()
|
||||
if err := pay.PayRedMoney(&weixin.RedMoneyReq{
|
||||
TotalAmount: 200,
|
||||
Title: "加班补贴",
|
||||
Userid: "jiangyong",
|
||||
}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,10 +37,14 @@ type Redis struct {
|
|||
|
||||
type QyWeixin struct {
|
||||
Corpid string `toml:"corpid"`
|
||||
|
||||
CheckinAgent string `toml:"checkin_agent"`
|
||||
CheckinSecret string `toml:"checkin_secret"`
|
||||
CheckinGroup string `toml:"checkin_group"`
|
||||
CheckinPayMoney string `toml:"checkin_pay_money"`
|
||||
CheckinPayTitle string `toml:"checkin_pay_title"`
|
||||
CheckinPayThresold float64 `toml:"checkin_pay_thresold"`
|
||||
|
||||
EnterpriseAgent string `toml:"enterprise_agent"`
|
||||
EnterpriseSecret string `toml:"enterprise_secret"`
|
||||
HrAgent string `toml:"hr_agent"`
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package qyweixin
|
||||
package weixin
|
||||
|
||||
type UserCheckIn struct {
|
||||
UserId string
|
|
@ -1,4 +1,4 @@
|
|||
package qyweixin
|
||||
package weixin
|
||||
|
||||
import (
|
||||
"bytes"
|
|
@ -1,4 +1,4 @@
|
|||
package qyweixin
|
||||
package weixin
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
@ -10,6 +10,7 @@ import (
|
|||
"fmt"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/smbrave/goutil"
|
||||
"github.com/spf13/cast"
|
||||
"github.com/wechatpay-apiv3/wechatpay-go/core"
|
||||
"github.com/wechatpay-apiv3/wechatpay-go/core/option"
|
||||
"github.com/wechatpay-apiv3/wechatpay-go/utils"
|
||||
|
@ -18,10 +19,18 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
type RedMoneyReq struct {
|
||||
TotalAmount int64
|
||||
Title string
|
||||
Userid string
|
||||
BillNo string
|
||||
}
|
||||
|
||||
type QyPay struct {
|
||||
cli *core.Client
|
||||
tlsClient *http.Client
|
||||
stdClient *http.Client
|
||||
qyClient *QyWeixin
|
||||
}
|
||||
|
||||
func NewQyPay() *QyPay {
|
||||
|
@ -38,6 +47,7 @@ func NewQyPay() *QyPay {
|
|||
}
|
||||
pay.tlsClient = client
|
||||
|
||||
pay.qyClient = NewQyWeixin(cfg.QyWeixin.Corpid, cfg.QyWeixin.HrSecret)
|
||||
return pay
|
||||
}
|
||||
|
||||
|
@ -109,7 +119,7 @@ func (w *QyPay) initPay() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (p *QyPay) PayRedMoney() error {
|
||||
func (p *QyPay) PayRedMoney(req *RedMoneyReq) error {
|
||||
if p.cli == nil {
|
||||
if err := p.initPay(); err != nil {
|
||||
return err
|
||||
|
@ -117,16 +127,24 @@ func (p *QyPay) PayRedMoney() error {
|
|||
}
|
||||
cfg := config.GetConfig()
|
||||
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("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("wxappid", cfg.QyWeixin.Corpid)
|
||||
param.Set("agentid", "1")
|
||||
param.Set("re_openid", "oZZmL6Lx7Rj3vbNRXgA3ZpwU_tzM")
|
||||
param.Set("total_amount", "100")
|
||||
param.Set("wishing", "感谢您参加猜灯谜活动,祝您元宵节快乐!")
|
||||
param.Set("act_name", "猜灯谜抢红包活动")
|
||||
param.Set("remark", "猜越多得越多,快来抢!")
|
||||
param.Set("agentid", cfg.QyWeixin.PayAgent)
|
||||
param.Set("re_openid", userOpenid)
|
||||
param.Set("total_amount", cast.ToString(req.TotalAmount))
|
||||
param.Set("wishing", req.Title)
|
||||
param.Set("act_name", "企业红包")
|
||||
param.Set("remark", "企业红包")
|
||||
param.Set("workwx_sign", param.QySignMd5(cfg.QyWeixin.PaySecret))
|
||||
param.Set("sign", param.SignMd5(cfg.WxPay.PayApiKeyV2))
|
||||
|
||||
|
@ -139,7 +157,11 @@ func (p *QyPay) PayRedMoney() error {
|
|||
|
||||
respParam := newParams()
|
||||
respParam.Decode(rspBody)
|
||||
fmt.Println("req:", string(param.Encode()))
|
||||
fmt.Println("resp: ", string(respParam.Encode()))
|
||||
|
||||
returnCode := respParam.GetString("return_code")
|
||||
resultCoce := respParam.GetString("result_code")
|
||||
if resultCoce == "SUCCESS" && returnCode == "SUCCESS" {
|
||||
return nil
|
||||
}
|
||||
return errors.New(string(respParam.Encode()))
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package qyweixin
|
||||
package weixin
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
@ -18,6 +18,7 @@ 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"
|
||||
urlConvertOpenid = "https://qyapi.weixin.qq.com/cgi-bin/user/convert_to_openid"
|
||||
)
|
||||
|
||||
type QyWeixin struct {
|
||||
|
@ -161,3 +162,25 @@ func (q *QyWeixin) GetCheckinData(day, userId string) (*UserCheckIn, error) {
|
|||
}
|
||||
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
|
||||
}
|
|
@ -24,6 +24,8 @@ enterprise_secret = "oMB24UhKe50-XPTg7vhnwoTuhEXaq5XeiHPAUtF4hOs"
|
|||
checkin_agent = "3010011"
|
||||
checkin_secret = "6ljYNGt4DonZLmr9SCtgkTlOvtqmsOchBrTWwGl_GpU"
|
||||
checkin_group = "1,2"
|
||||
checkin_pay_money = 20
|
||||
checkin_pay_title = "工作餐补贴"
|
||||
checkin_pay_thresold = 11
|
||||
pay_secret = "JCGsxntR4E7wrEEQvWGr8_wdKtRlw48n-W6zd8lbwc4"
|
||||
pay_agent = "3010046"
|
||||
|
|
|
@ -1,19 +1,23 @@
|
|||
package worker
|
||||
|
||||
import (
|
||||
butil "enterprise/base/util"
|
||||
"enterprise/common/config"
|
||||
"enterprise/common/dao"
|
||||
"enterprise/common/global"
|
||||
"enterprise/common/model"
|
||||
"enterprise/common/weixin"
|
||||
"fmt"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/smbrave/goutil"
|
||||
"github.com/spf13/cast"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
func ViewCheckin(checkin *model.Checkin) {
|
||||
func NotifyCheckinOffDuty(checkin *model.Checkin) {
|
||||
if checkin.Exception != "" {
|
||||
log.Errorf("execption[%s] %s", checkin.Exception, goutil.EncodeJSON(checkin))
|
||||
log.Infof("execption[%s] %s", checkin.Exception, goutil.EncodeJSON(checkin))
|
||||
return
|
||||
}
|
||||
thresold := config.GetConfig().QyWeixin.CheckinPayThresold
|
||||
|
@ -21,7 +25,47 @@ func ViewCheckin(checkin *model.Checkin) {
|
|||
if duration < int64(3600*thresold) {
|
||||
return
|
||||
}
|
||||
autoPayMoney(checkin, "下班打卡")
|
||||
}
|
||||
|
||||
func NotifyCheckinOnDuty(checkin *model.Checkin) {
|
||||
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.Day))
|
||||
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 {
|
||||
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
|
||||
}
|
||||
|
|
|
@ -4,14 +4,14 @@ import (
|
|||
"enterprise/common/config"
|
||||
"enterprise/common/dao"
|
||||
"enterprise/common/model"
|
||||
"enterprise/common/qyweixin"
|
||||
"enterprise/common/weixin"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func SyncCheckin(day string) error {
|
||||
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, ","))
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -62,8 +62,11 @@ func SyncCheckin(day string) error {
|
|||
if err != nil {
|
||||
log.Errorf("db error :%s", err.Error())
|
||||
}
|
||||
if isNew {
|
||||
go NotifyCheckinOnDuty(checkin)
|
||||
}
|
||||
if isUpdate {
|
||||
go ViewCheckin(checkin)
|
||||
go NotifyCheckinOffDuty(checkin)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ func Init1() error {
|
|||
func Init() error {
|
||||
timezone, _ := time.LoadLocation("Asia/Shanghai")
|
||||
cron := gocron.NewScheduler(timezone)
|
||||
cron.Every(5).Minute().Do(func() {
|
||||
cron.Every(1).Minute().Do(func() {
|
||||
go SyncCheckin(time.Now().Format("2006-01-02"))
|
||||
})
|
||||
|
||||
|
|
Loading…
Reference in New Issue