This commit is contained in:
jiangyong27 2025-04-03 12:54:19 +08:00
parent a1c566d278
commit 0a87aec351
9 changed files with 173 additions and 46 deletions

View File

@ -3,16 +3,21 @@ package global
import (
"context"
"enterprise/common/config"
"enterprise/common/dao"
"github.com/ArtisanCloud/PowerWeChat/v3/src/work"
"github.com/ArtisanCloud/PowerWeChat/v3/src/work/message/request"
"github.com/gogap/errors"
log "github.com/sirupsen/logrus"
"github.com/smbrave/goutil"
"github.com/spf13/cast"
"strings"
"sync"
)
var (
wxEnterprise *work.Work
corpEnterprise map[int64]*work.Work
corpEnterpriseMutex sync.Mutex
)
func initWxWork() (*work.Work, error) {
@ -34,6 +39,40 @@ func initWxWork() (*work.Work, error) {
return client, nil
}
func getWxWork(corpId int64) (*work.Work, error) {
if c, ok := corpEnterprise[corpId]; ok {
return c, nil
}
corp, err := dao.NewCorpDao().Get(corpId)
if err != nil {
return nil, err
}
if corp == nil {
return nil, errors.New("corp not exist")
}
cfg := corp.GetConfig()
client, err := work.NewWork(&work.UserConfig{
CorpID: cfg.CorpId,
AgentID: cast.ToInt(cfg.PayAgent),
Secret: cfg.PaySecret,
OAuth: work.OAuth{
Callback: "https://wecom.artisan-cloud.com/callback",
Scopes: nil,
},
})
if err != nil {
log.Errorf("config[%s] init error : %s", goutil.EncodeJSON(cfg), err.Error())
return nil, err
}
corpEnterpriseMutex.Lock()
corpEnterprise[corpId] = client
corpEnterpriseMutex.Unlock()
return client, nil
}
func SendMessage(user []string, content string) error {
if wxEnterprise == nil {
wxM, err := initWxWork()
@ -56,3 +95,24 @@ func SendMessage(user []string, content string) error {
}
return nil
}
func SendCorpMessage(corpId int64, user []string, content string) error {
client, _ := getWxWork(corpId)
if client == nil {
return errors.New("client error ")
}
corp, _ := dao.NewCorpDao().Get(corpId)
receivers := user
message := &request.RequestMessageSendText{}
message.ToUser = strings.Join(receivers, "|")
message.MsgType = "text"
message.AgentID = cast.ToInt(corp.GetConfig().PayAgent)
message.Text = &request.RequestText{Content: content}
if _, err := client.Message.SendText(context.Background(), message); err != nil {
log.Errorf("send message [%s] error : %s", goutil.EncodeJSON(message), err)
return err
}
return nil
}

View File

@ -3,6 +3,7 @@ package model
import (
"encoding/json"
butil "enterprise/base/util"
"fmt"
"github.com/smbrave/goutil"
"github.com/spf13/cast"
"strings"
@ -66,6 +67,12 @@ func (s *StaffSalary) SetExtra(key string, value interface{}) {
s.Extra = goutil.EncodeJSON(extra)
}
func (s *StaffSalary) GetBillUrl() string {
encId := goutil.EncryptID(s.Id, "@@salary@@")
billUrl := fmt.Sprintf("https://e.yubanqy.com/api/staff/salary/bill?id=%s", encId)
return billUrl
}
type StaffSalarySort []*StaffSalary
func (s StaffSalarySort) Len() int {

View File

@ -6,6 +6,7 @@ import (
"enterprise/server/api"
"enterprise/server/service"
"enterprise/server/session"
CommonService "enterprise/service"
"fmt"
"github.com/gin-gonic/gin"
"github.com/smbrave/goutil"
@ -24,7 +25,7 @@ func (q *Payment) AlipayAuth(ctx *gin.Context) {
authCode := ctx.Query("auth_code")
state := ctx.Query("state")
userid, staffUser := service.NewPay().AlipayAuth(sess, authCode, state)
userid, staffUser := service.NewPayment().AlipayAuth(sess, authCode, state)
username := goutil.If(staffUser.Realname != "", staffUser.Realname, staffUser.Username)
ctx.HTML(http.StatusOK, "alipay.html", gin.H{
"title": "绑定成功",
@ -50,7 +51,9 @@ func (q *Payment) Pay(ctx *gin.Context) {
session.CheckDBError(err)
session.CheckNilError(user, fmt.Sprintf("用户[%s]不存在", req.Username))
service.NewPay().Pay(corp, user, req.Title, req.PayType, req.Amount)
if err = CommonService.NewPay().Pay(corp, user, req.Title, req.PayType, req.Amount); err != nil {
panic(config.ErrInternal.New().Append(err))
}
ctx.JSON(http.StatusOK, session.NewRspOk())
}

View File

@ -1,9 +1,16 @@
package service
import (
"context"
"enterprise/common/config"
"enterprise/common/dao"
"enterprise/common/model"
"enterprise/server/api"
"enterprise/server/session"
log "github.com/sirupsen/logrus"
"github.com/smartwalle/alipay/v3"
"github.com/smbrave/goutil"
"github.com/spf13/cast"
"time"
)
@ -40,3 +47,36 @@ func (p *Payment) Suggest(sess *session.AdminSession, field string) interface{}
}
return counts
}
func (p *Payment) AlipayAuth(sess *session.AdminSession, authCode, state string) (string, *model.StaffUser) {
corp, err := dao.NewCorpDao().GetByHost(sess.GetHeader().Host)
session.CheckDBError(err)
session.CheckNilError(corp)
cli := config.GetAliPayClient("batiao")
var req alipay.SystemOauthToken
req.Code = authCode
req.GrantType = "authorization_code"
res, err := cli.SystemOauthToken(context.Background(), req)
if err != nil {
log.Errorf("error :%s", err.Error())
panic(config.ErrInternal.New().Append(err))
}
if !res.IsSuccess() {
log.Errorf(goutil.EncodeJSON(res))
panic(config.ErrInternal.New().Append(goutil.EncodeJSON(res)))
}
staffUser, err := dao.NewStaffUserDao().Get(cast.ToInt64(state))
session.CheckDBError(err)
session.CheckNilError(staffUser)
payee := staffUser.GetPayee()
oldUid := payee.AlipayUid
payee.AlipayUid = res.UserId
staffUser.Payee = goutil.EncodeJSON(payee)
err = dao.NewStaffUserDao().Update(staffUser)
session.CheckDBError(err)
log.Errorf("staffuser[%d] alipayUid[%s]->alipayUid[%s]", staffUser.Id, oldUid, res.UserId)
return res.UserId, staffUser
}

View File

@ -161,7 +161,9 @@ func (s *StaffSalary) Pay(sess *session.AdminSession, req *api.PaySalaryReq) {
salary.Status = model.StaffSalaryStatusPayed
dao.NewStaffSalaryDao().Update(salary)
NewPay().Pay(corp, user, title, req.PayType, int64(salary.GetRealSalary()*100))
if err = CommonService.NewPay().Pay(corp, user, title, req.PayType, int64(salary.GetRealSalary()*100)); err != nil {
panic(config.ErrInternal.New().Append(err))
}
}
func (s *StaffSalary) Agent(cid int64, month string, ctx *gin.Context) {

View File

@ -7,6 +7,7 @@ import (
"enterprise/common/model"
"enterprise/server/api"
"enterprise/server/session"
CommonService "enterprise/service"
"git.u8t.cn/open/gosdk/qyweixin"
"github.com/google/uuid"
log "github.com/sirupsen/logrus"
@ -209,7 +210,9 @@ func (s *StaffUser) Pay(sess *session.AdminSession, req *api.StaffPayReq) {
if req.Title == "" {
req.Title = "测试"
}
NewPay().Pay(corp, user, req.Title, req.PayType, cast.ToInt64(req.Amount))
if err = CommonService.NewPay().Pay(corp, user, req.Title, req.PayType, cast.ToInt64(req.Amount)); err != nil {
panic(config.ErrInternal.New().Append(err))
}
}
func (s *StaffUser) getHrAssiant(corpId int64) *qyweixin.AppHr {

View File

@ -6,7 +6,6 @@ import (
"enterprise/common/dao"
"enterprise/common/global"
"enterprise/common/model"
"enterprise/server/session"
"fmt"
"git.u8t.cn/open/gosdk/qyweixin"
"github.com/gogap/errors"
@ -24,40 +23,7 @@ func NewPay() *Pay {
return &Pay{}
}
func (p *Pay) AlipayAuth(sess *session.AdminSession, authCode, state string) (string, *model.StaffUser) {
corp, err := dao.NewCorpDao().GetByHost(sess.GetHeader().Host)
session.CheckDBError(err)
session.CheckNilError(corp)
cli := config.GetAliPayClient("batiao")
var req alipay.SystemOauthToken
req.Code = authCode
req.GrantType = "authorization_code"
res, err := cli.SystemOauthToken(context.Background(), req)
if err != nil {
log.Errorf("error :%s", err.Error())
panic(config.ErrInternal.New().Append(err))
}
if !res.IsSuccess() {
log.Errorf(goutil.EncodeJSON(res))
panic(config.ErrInternal.New().Append(goutil.EncodeJSON(res)))
}
staffUser, err := dao.NewStaffUserDao().Get(cast.ToInt64(state))
session.CheckDBError(err)
session.CheckNilError(staffUser)
payee := staffUser.GetPayee()
oldUid := payee.AlipayUid
payee.AlipayUid = res.UserId
staffUser.Payee = goutil.EncodeJSON(payee)
err = dao.NewStaffUserDao().Update(staffUser)
session.CheckDBError(err)
log.Errorf("staffuser[%d] alipayUid[%s]->alipayUid[%s]", staffUser.Id, oldUid, res.UserId)
return res.UserId, staffUser
}
func (p *Pay) Pay(corp *model.Corp, user *model.StaffUser, title, payType string, amount int64) {
func (p *Pay) Pay(corp *model.Corp, user *model.StaffUser, title, payType string, amount int64) error {
var err error
realPayType := ""
payee := user.GetPayee()
@ -82,7 +48,7 @@ func (p *Pay) Pay(corp *model.Corp, user *model.StaffUser, title, payType string
message = append(message, fmt.Sprintf("错误信息:%s", err.Error()))
global.SendMessage([]string{"jiangyong"}, strings.Join(message, "\n"))
log.Errorf("pay req[%s:%d] error :%s", title, amount, err.Error())
panic(config.ErrInternal.New().Append(err))
return err
}
plog := new(model.StaffPayLog)
@ -93,6 +59,7 @@ func (p *Pay) Pay(corp *model.Corp, user *model.StaffUser, title, payType string
dao.NewStaffPayLogDao().Create(plog)
global.SendMessage([]string{"jiangyong"}, strings.Join(message, "\n"))
return nil
}
func (p *Pay) payAlipay(corp *model.Corp, user *model.StaffUser, title string, amount int64) error {

View File

@ -7,7 +7,6 @@ import (
"enterprise/service"
"fmt"
log "github.com/sirupsen/logrus"
"github.com/smbrave/goutil"
"strings"
"time"
)
@ -88,13 +87,11 @@ func (s *Staff) SendStaffSalaryBill(corpId int64, month string) {
log.Errorf("db error :%s", err.Error())
continue
}
encId := goutil.EncryptID(staffSalary.Id, "@@salary@@")
billUrl := fmt.Sprintf("https://e.yubanqy.com/api/staff/salary/bill?id=%s", encId)
message := make([]string, 0)
message = append(message, fmt.Sprintf("【工资单】[%s][%s]", staffUser.Username, month))
message = append(message, fmt.Sprintf("实发工资:%.2f", staffSalary.GetRealSalary()))
message = append(message, fmt.Sprintf(`<a href="%s">查看明细</a>`, billUrl))
message = append(message, fmt.Sprintf(`<a href="%s">查看明细</a>`, staffSalary.GetBillUrl()))
if err := global.SendMessage([]string{"jiangyong"}, strings.Join(message, "\n")); err != nil {
log.Errorf("send message error :%s", err.Error())
@ -103,6 +100,53 @@ func (s *Staff) SendStaffSalaryBill(corpId int64, month string) {
}
}
func (s *Staff) PayStaffSalary(corpId int64, month string) {
staffSalarys, err := dao.NewStaffSalaryDao().QueryAll(corpId, month, model.StaffSalaryStatusWait)
if err != nil {
log.Errorf("db error :%s", err.Error())
return
}
corp, err := dao.NewCorpDao().Get(corpId)
if err != nil {
log.Errorf("db error :%s", err.Error())
return
}
for _, staffSalary := range staffSalarys {
if staffSalary.Salary < 0.1 {
continue
}
staffUser, err := dao.NewStaffUserDao().Get(staffSalary.UserId)
if err != nil {
log.Errorf("db error :%s", err.Error())
continue
}
message := make([]string, 0)
message = append(message, fmt.Sprintf("【工资发放】[%s]", staffUser.Realname))
message = append(message, fmt.Sprintf("实发工资:%.2f", staffSalary.GetRealSalary()))
message = append(message, fmt.Sprintf(`<a href="%s">查看明细</a>`, staffSalary.GetBillUrl()))
if staffUser.Username == "jiangyong" {
err = service.NewPay().Pay(corp, staffUser, model.StaffSalaryPaymentAlipay, "", int64(100*staffSalary.GetRealSalary()))
if err == nil {
staffSalary.Status = model.StaffSalaryStatusPayed
message = append(message, "发放成功")
} else {
staffSalary.SetExtra("pay_error", err.Error())
message = append(message, fmt.Sprintf("发动失败:%.2f", err.Error()))
}
dao.NewStaffSalaryDao().Update(staffSalary)
}
if err := global.SendCorpMessage(staffSalary.CorpId, []string{"jiangyong"}, strings.Join(message, "\n")); err != nil {
log.Errorf("send message error :%s", err.Error())
}
}
}
func (s *Staff) SyncStaffSalary(corpId int64, month string) {
if month == "" {
month = time.Now().AddDate(0, -1, 0).Format("2006-01")

View File

@ -51,7 +51,7 @@ func InitCorp1002(cron *gocron.Scheduler) {
//10号晚上8点发送工资单
cron.Every(1).Month(3).At("22:00").Do(func() {
go staff.SendStaffSalaryBill(corpId, time.Now().AddDate(0, -1, 0).Format("200601"))
//go staff.SendStaffSalaryBill(1002, time.Now().AddDate(0, -1, 0).Format("200601"))
go staff.PayStaffSalary(corpId, time.Now().AddDate(0, -1, 0).Format("200601"))
})
}
@ -92,6 +92,7 @@ func InitCorp1000(cron *gocron.Scheduler) {
//10号晚上8点发送工资单
cron.Every(1).Month(3).At("22:00").Do(func() {
go NewStaff().SendStaffSalaryBill(corpId, time.Now().AddDate(0, -1, 0).Format("200601"))
go NewStaff().PayStaffSalary(corpId, time.Now().AddDate(0, -1, 0).Format("200601"))
})
}