287 lines
7.3 KiB
Go
287 lines
7.3 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
butil "enterprise/base/util"
|
|
"enterprise/common/config"
|
|
"enterprise/common/dao"
|
|
"enterprise/common/global"
|
|
"enterprise/common/model"
|
|
"fmt"
|
|
"git.u8t.cn/open/gosdk/qyweixin"
|
|
"git.u8t.cn/open/gosdk/wechat/message"
|
|
"github.com/gogap/errors"
|
|
log "github.com/sirupsen/logrus"
|
|
"github.com/smartwalle/alipay/v3"
|
|
"github.com/smbrave/goutil"
|
|
"github.com/spf13/cast"
|
|
"strings"
|
|
)
|
|
|
|
var (
|
|
SpStatusCreated = 1
|
|
SpStatusPassed = 2
|
|
SpStatusRefused = 3
|
|
SpStatusCanceled = 4
|
|
)
|
|
|
|
type Approve struct {
|
|
approveClient *qyweixin.AppApprove
|
|
}
|
|
|
|
func (b *Approve) Reply(msg message.MixMessage) *message.Reply {
|
|
if b.approveClient == nil {
|
|
cfg := config.GetConfig()
|
|
b.approveClient = qyweixin.NewAppApprove(&qyweixin.AppConfig{
|
|
Corpid: cfg.QyWeixin.Corpid,
|
|
Secret: cfg.QyWeixin.ApproveSecret,
|
|
Agent: cfg.QyWeixin.ApproveAgent,
|
|
})
|
|
}
|
|
go b.handle(&msg)
|
|
return &message.Reply{message.MsgTypeText, message.NewText("")}
|
|
}
|
|
|
|
func (a *Approve) handle(msg *message.MixMessage) {
|
|
msgType := msg.MsgType
|
|
|
|
if msgType == message.MsgTypeEvent {
|
|
event := strings.ToUpper(string(msg.Event))
|
|
if event == message.EventClick {
|
|
a.handleClick(msg)
|
|
} else if event == "SYS_APPROVAL_CHANGE" {
|
|
a.handleApprovalChange(msg)
|
|
}
|
|
} else if msgType == message.MsgTypeText {
|
|
a.handleText(msg)
|
|
}
|
|
|
|
log.Infof(goutil.EncodeJSONIndent(msg))
|
|
}
|
|
|
|
func (a *Approve) handleApprovalChange(msg *message.MixMessage) {
|
|
spStatus := msg.ApprovalInfo.SpStatus
|
|
spNo := msg.ApprovalInfo.SpNo
|
|
templateId := msg.ApprovalInfo.TemplateId
|
|
if spStatus != SpStatusPassed {
|
|
return
|
|
}
|
|
|
|
detail, err := a.approveClient.GetDetail(spNo)
|
|
if err != nil {
|
|
log.Errorf("get spn detail error :%s", err.Error())
|
|
return
|
|
}
|
|
|
|
log.Infof("spno: %s detail: %s", spNo, goutil.EncodeJSON(detail))
|
|
if templateId == model.ApprovalTpIdRefund {
|
|
a.handleRefund(detail)
|
|
} else if templateId == model.ApprovalTpIdVacation {
|
|
a.handleVacation(detail)
|
|
} else if templateId == model.ApprovalTpIdCheckin {
|
|
a.handleCheckin(detail)
|
|
} else if templateId == model.ApprovalTpIdPayment {
|
|
a.handlePayment(detail)
|
|
}
|
|
}
|
|
|
|
func (a *Approve) handlePayment(detail *qyweixin.ApproveDetail) {
|
|
newData := new(model.ApprovalPayment)
|
|
newData.From(detail)
|
|
dbDao := dao.NewApprovalPaymentDao()
|
|
|
|
old, err := dbDao.GetBySpNo(detail.SpNo)
|
|
if err != nil {
|
|
log.Errorf("db error :%s", err.Error())
|
|
return
|
|
}
|
|
if old != nil {
|
|
newData.Id = old.Id
|
|
newData.CreateTime = old.CreateTime
|
|
err = dbDao.Update(newData)
|
|
} else {
|
|
_, err = dbDao.Create(newData)
|
|
}
|
|
|
|
if err != nil {
|
|
log.Errorf("db error :%s", err.Error())
|
|
return
|
|
}
|
|
}
|
|
|
|
func (a *Approve) handleVacation(detail *qyweixin.ApproveDetail) {
|
|
newData := new(model.ApprovalVacation)
|
|
newData.From(detail)
|
|
dbDao := dao.NewApprovalVacationDao()
|
|
|
|
old, err := dbDao.GetBySpNo(detail.SpNo)
|
|
if err != nil {
|
|
log.Errorf("db error :%s", err.Error())
|
|
return
|
|
}
|
|
if old != nil {
|
|
newData.Id = old.Id
|
|
newData.CreateTime = old.CreateTime
|
|
err = dbDao.Update(newData)
|
|
} else {
|
|
_, err = dbDao.Create(newData)
|
|
}
|
|
|
|
if err != nil {
|
|
log.Errorf("db error :%s", err.Error())
|
|
return
|
|
}
|
|
}
|
|
|
|
func (a *Approve) handleCheckin(detail *qyweixin.ApproveDetail) {
|
|
newData := new(model.ApprovalCheckin)
|
|
newData.From(detail)
|
|
dbDao := dao.NewApprovalCheckinDao()
|
|
|
|
old, err := dbDao.GetBySpNo(detail.SpNo)
|
|
if err != nil {
|
|
log.Errorf("db error :%s", err.Error())
|
|
return
|
|
}
|
|
if old != nil {
|
|
newData.Id = old.Id
|
|
newData.CreateTime = old.CreateTime
|
|
err = dbDao.Update(newData)
|
|
} else {
|
|
_, err = dbDao.Create(newData)
|
|
}
|
|
|
|
if err != nil {
|
|
log.Errorf("db error :%s", err.Error())
|
|
return
|
|
}
|
|
}
|
|
|
|
func (a *Approve) handleRefundWxpay(data *model.ApprovalRefund) error {
|
|
openid, err := a.approveClient.GetOpenid(data.Username)
|
|
if err != nil {
|
|
log.Errorf("GetOpenid error :%s", err.Error())
|
|
return err
|
|
}
|
|
|
|
var req qyweixin.PayReq
|
|
req.BillNo = fmt.Sprintf("BX%s%s", data.SpNo, butil.CutTail(data.Username, 12))
|
|
req.Title = fmt.Sprintf("【%s】报销", data.RefundType)
|
|
req.Openid = openid
|
|
req.TotalAmount = int64(100 * data.RefundAmount)
|
|
qyPay := qyweixin.NewAppPay(&qyweixin.PayConfig{
|
|
Corpid: config.GetConfig().QyWeixin.Corpid,
|
|
Secret: config.GetConfig().QyWeixin.PaySecret,
|
|
Agent: config.GetConfig().QyWeixin.PayAgent,
|
|
SerialNumber: config.GetConfig().WxPay.PaySerialNumber,
|
|
ApiKey: config.GetConfig().WxPay.PayApiKeyV2,
|
|
MchId: config.GetConfig().WxPay.PayMchId,
|
|
CertPem: config.GetConfig().WxPay.PayCertPem,
|
|
KeyPem: config.GetConfig().WxPay.PayKeyPem,
|
|
})
|
|
if err = qyPay.PayMoney(&req); err != nil {
|
|
log.Errorf("pay error[%s] :%s", goutil.EncodeJSON(req), err.Error())
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (a *Approve) handleRefundAlipay(staff *model.StaffInfo, data *model.ApprovalRefund) error {
|
|
|
|
cli := config.GetAliPayClient("batiao")
|
|
var req alipay.FundTransUniTransfer
|
|
req.Remark = data.SpNo
|
|
req.OutBizNo = fmt.Sprintf("BX%s%s", data.SpNo, butil.CutTail(data.Username, 12))
|
|
req.TransAmount = cast.ToString(data.RefundAmount)
|
|
req.ProductCode = "TRANS_ACCOUNT_NO_PWD"
|
|
req.BizScene = "DIRECT_TRANSFER"
|
|
req.OrderTitle = data.RefundRemark + "报销"
|
|
payee := new(alipay.PayeeInfo)
|
|
req.PayeeInfo = payee
|
|
payee.IdentityType = "ALIPAY_USER_ID"
|
|
payee.Identity = staff.AlipayUid
|
|
|
|
rsp, err := cli.FundTransUniTransfer(context.Background(), req)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
if !rsp.IsSuccess() {
|
|
log.Errorf("FundTransUniTransfer error :%s", goutil.EncodeJSON(rsp))
|
|
return errors.New(goutil.EncodeJSON(rsp))
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (a *Approve) handleRefund(detail *qyweixin.ApproveDetail) {
|
|
newData := new(model.ApprovalRefund)
|
|
newData.From(detail)
|
|
dbDao := dao.NewApprovalRefundDao()
|
|
|
|
old, err := dbDao.GetBySpNo(detail.SpNo)
|
|
if err != nil {
|
|
log.Errorf("db error :%s", err.Error())
|
|
return
|
|
}
|
|
if old != nil {
|
|
newData.Id = old.Id
|
|
newData.CreateTime = old.CreateTime
|
|
err = dbDao.Update(newData)
|
|
} else {
|
|
_, err = dbDao.Create(newData)
|
|
}
|
|
|
|
if err != nil {
|
|
log.Errorf("db error :%s", err.Error())
|
|
return
|
|
}
|
|
|
|
staff, err := dao.NewStaffInfoDao().GetByUsername(newData.Username)
|
|
if err != nil {
|
|
log.Errorf("db error :%s", err.Error())
|
|
return
|
|
}
|
|
|
|
// 支付费用
|
|
if newData.RefundAmount > 200 && staff != nil && staff.AlipayUid != "" {
|
|
err = a.handleRefundAlipay(staff, newData)
|
|
} else {
|
|
err = a.handleRefundWxpay(newData)
|
|
}
|
|
|
|
var title string = "【报销成功】"
|
|
if err != nil {
|
|
title = "【报销失败】"
|
|
}
|
|
|
|
message := make([]string, 0)
|
|
message = append(message, title)
|
|
message = append(message, fmt.Sprintf("发放金额:%s", fmt.Sprintf("%.2f", newData.RefundAmount)))
|
|
message = append(message, fmt.Sprintf("费用类型:%s", newData.RefundType))
|
|
message = append(message, fmt.Sprintf("员工名称:%s", newData.Username))
|
|
message = append(message, fmt.Sprintf("费用说明:%s", newData.RefundRemark))
|
|
if err != nil {
|
|
message = append(message, fmt.Sprintf("异常:%s", err.Error()))
|
|
}
|
|
|
|
if err := global.SendMessage([]string{"jiangyong"}, strings.Join(message, "\n")); err != nil {
|
|
log.Errorf("send message error :%s", err.Error())
|
|
}
|
|
|
|
newData.Status = model.ApprovalRefundStatusPayed
|
|
if err := dao.NewApprovalRefundDao().Update(newData); err != nil {
|
|
log.Errorf("db error :%s", err.Error())
|
|
}
|
|
}
|
|
|
|
func (a *Approve) handleText(msg *message.MixMessage) {
|
|
|
|
}
|
|
|
|
func (a *Approve) handleClick(msg *message.MixMessage) {
|
|
|
|
}
|
|
|
|
func (a *Approve) sendText(message string) {
|
|
|
|
}
|