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} } 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, "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) } type Response struct { Msg string `json:"msg"` } 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, }) }