voucher/internal/service/qixing.go

102 lines
3.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package service
import (
"encoding/base64"
"encoding/json"
"fmt"
"github.com/go-kratos/kratos/v2/log"
"github.com/go-kratos/kratos/v2/transport/http"
"io"
http2 "net/http"
"voucher/internal/biz"
"voucher/internal/biz/bo"
"voucher/internal/conf"
"voucher/internal/pkg/helper"
)
type TripartiteService struct {
bc *conf.Bootstrap
multiBiz *biz.MultiBiz
}
func NewTripartiteService(bc *conf.Bootstrap, multiBiz *biz.MultiBiz) *TripartiteService {
return &TripartiteService{bc: bc, multiBiz: multiBiz}
}
// QiXingNotify
// 重试规则
// 1.重试间隔每次推送失败后间隔5分钟重新推送
// 2.最大重试次数累计推送5 次(首次 + 4 次重试;
// 3.停止条件:返回成功响应 或 达到 4 次重试上限,停止推送。
func (srv *TripartiteService) QiXingNotify(ctx http.Context) error {
ip := helper.GetClientIP(ctx)
if ip == "" {
return fmt.Errorf("获取请求 IP 失败")
}
bodyBytes, err := io.ReadAll(ctx.Request().Body)
if err != nil {
return srv.ResponseErr(ctx, fmt.Sprintf("read body error: %v", err))
}
var req *bo.QiXingRequestBo
if err = json.Unmarshal(bodyBytes, &req); err != nil {
log.Errorf("qixing notify bodyBytes err ip:%s,error:%v,body:%s", ip, err, string(bodyBytes))
return srv.ResponseErr(ctx, fmt.Sprintf("json unmarshal bodyBytes error: %v", err))
}
if err = req.Validate(); err != nil {
log.Errorf("qixing notify req validate err ip:%s,error:%v,body:%s", ip, err, string(bodyBytes))
return srv.ResponseErr(ctx, fmt.Sprintf("validate req error: %v", err))
}
// 加密校验串,(生成规则MD5(content+公钥))
if srv.bc.Tripartite.QiXing.AppKey == "" {
return srv.ResponseErr(ctx, "qixing appKey is empty")
}
sign := helper.Md5(req.Content + srv.bc.Tripartite.QiXing.AppKey)
if sign != req.Ciphertext {
log.Errorf("qixing notify sign err ip:%s,error:%v,body:%s", ip, err, string(bodyBytes))
return srv.ResponseErr(ctx, "verify sign error")
}
wxNotifyDataStr, err := base64.StdEncoding.DecodeString(req.Content)
if err != nil {
log.Errorf("qixing notify wxNotifyDataStr err ip:%s,error:%v,body:%s", ip, err, string(bodyBytes))
return srv.ResponseErr(ctx, fmt.Sprintf("base64 decode req content error: %v", err))
}
var wxNotifyData *bo.WechatVoucherNotifyBo
if err = json.Unmarshal(wxNotifyDataStr, &wxNotifyData); err != nil {
log.Errorf("qixing notify wxNotifyData err ip:%s,error:%v,body:%s", ip, err, string(bodyBytes))
return srv.ResponseErr(ctx, fmt.Sprintf("json unmarshal wxNotifyData error: %v", err))
}
if err = wxNotifyData.Validate(); err != nil {
log.Errorf("qixing notify wxNotifyData validate err ip:%s,error:%v,body:%s", ip, err, string(bodyBytes))
return srv.ResponseErr(ctx, fmt.Sprintf("validate wxNotifyData error: %v", err))
}
err = srv.multiBiz.Notify(ctx, "qixing_"+wxNotifyData.PlainText.StockCreatorMchid, wxNotifyData)
if err != nil {
log.Errorf("qixing notify run err ip:%s,error:%v,body:%s", ip, err, string(bodyBytes))
return srv.ResponseErr(ctx, err.Error())
}
return srv.ResponseOK(ctx)
}
func (this *TripartiteService) ResponseOK(ctx http.Context) error {
return ctx.JSON(http2.StatusOK, &bo.QiXingResponse{
Msg: "SUCCESS",
})
}
func (this *TripartiteService) ResponseErr(ctx http.Context, msg string) error {
return ctx.JSON(http2.StatusOK, &bo.QiXingResponse{
Msg: msg,
})
}