package yl import ( "context" "database/sql" "encoding/json" "errors" "fmt" "github.com/bytedance/sonic" "rs/genModel" "rs/untils/sign" "rs/cmd/api/internal/logic/vo" "rs/rpc/transfer" "rs/untils/httpclient" "strconv" "strings" "time" "rs/cmd/api/internal/svc" "rs/cmd/api/internal/types" "github.com/zeromicro/go-zero/core/logx" ) type YlAsyncLogic struct { logx.Logger ctx context.Context svcCtx *svc.ServiceContext } // 卡密异步发放接口 func NewYlAsyncLogic(ctx context.Context, svcCtx *svc.ServiceContext) *YlAsyncLogic { return &YlAsyncLogic{ Logger: logx.WithContext(ctx), ctx: ctx, svcCtx: svcCtx, } } func (l *YlAsyncLogic) YlAsync(req *types.AsyncReq) (resp *types.AsyncResp, err error) { var ( reqData transfer.MarketKeySendReq VoucherId string supplierOrderNo = req.DeliverOrderNo result *transfer.MarketKeySendRes ) defer func() { var status int64 var msg string if err != nil { status = 2 msg = err.Error() } else { status = 1 } // 记录订单 l.saveOrder(req, result, supplierOrderNo, VoucherId, msg, status) }() if v, ok := l.svcCtx.Config.MarketConfig.SupplierSkuId[strconv.Itoa(int(req.SupplierSkuId))]; ok { VoucherId = v } else { return nil, fmt.Errorf("供货商sku 未配置") } reqData = transfer.MarketKeySendReq{ AppId: l.svcCtx.Config.MarketConfig.AppId, ReqCode: "voucher.create", MemId: fmt.Sprintf("%d", req.SupplierId), ReqSerialNo: req.DeliverOrderNo, Timestamp: time.Unix(req.CreateTime, 0).Format("20060102150405"), PosId: l.svcCtx.Config.MarketConfig.PosId, VoucherId: VoucherId, VoucherNum: 1, //MobileNo: extendParam.MobileNo, //SendMsg: extendParam.SendMsg, } if reqData.SendMsg == "" { reqData.SendMsg = "2" } reqData.Sign = l.svcCtx.Config.Sys.PrimaryKey result, err = l.svcCtx.TransferRpc.MarketKeySend(l.ctx, &reqData) if err != nil { return nil, fmt.Errorf("rpc请求失败:%v", err.Error()) } if result.ErrCode != vo.RES_SUCCESS { return nil, fmt.Errorf("请求失败:%v", result.Msg) } if result.Data == nil { return nil, fmt.Errorf("请求失败:%v", result.Msg) } if result.Data.VoucherCode == "" { return nil, fmt.Errorf("请求失败未取到数据:%v", result.Msg) } // 异步通知 go func() { time.Sleep(2 * time.Second) l.asyncSendMarket(supplierOrderNo, req, result.Data) }() return &types.AsyncResp{ Msg: "", Status: 0, SupplierOrderNo: supplierOrderNo, }, nil } func (l *YlAsyncLogic) getExchangeCode(voucherCode string) string { if !strings.Contains(voucherCode, "http") { return voucherCode } temp := strings.Split(voucherCode, "/") return temp[len(temp)-1] } // 返回数据,通知下游系统 func (l *YlAsyncLogic) asyncSendMarket(supplierOrderNo string, asyncReq *types.AsyncReq, data *transfer.MarketKeySendRes_Data) { startTime, err := time.Parse("20060102", data.VoucherSdate) if err != nil { startTime = time.Now() } endTime, err := time.Parse("20060102", data.VoucherEdate) if err != nil { endTime = startTime.AddDate(0, 0, 30).Add(23*time.Hour + 59*time.Minute + 59*time.Second) } var ( reqDataMap map[string]interface{} header = map[string]string{"Content-Type": "application/json;charset=UTF-8"} targetUrl = l.svcCtx.Config.YouleHost + "/supplier/order/sendResultNotify" req = &types.NotifyReq{ DeliverOrderNo: asyncReq.DeliverOrderNo, SupplierOrderNo: supplierOrderNo, SupplierSkuId: asyncReq.SupplierSkuId, RequestTime: time.Now().Unix(), Account: asyncReq.Account, Status: 1, Msg: "", Price: asyncReq.Price, SupplierId: asyncReq.SupplierId, CardNo: "", CardKey: "", CardExpireTime: endTime.Add(23*time.Hour + 59*time.Minute + 59*time.Second).Format(time.DateTime), CardExchangeUrl: data.ShortUrl, Sign: "", } ) b, _ := json.Marshal(req) err = json.Unmarshal(b, &reqDataMap) if err != nil { return } req.Sign, err = sign.GetSign(reqDataMap, l.svcCtx.Config.Sys.Key) if err != nil { l.Logger.Errorf("签名失败:%v", err.Error()) return } body, err := sonic.Marshal(req) if err != nil { l.Logger.Errorf("解析json失败:%v", err.Error()) return } resp, err := httpclient.FastHttpPost(targetUrl, header, body, 0) if err != nil { l.Logger.Errorf("请求失败:%v", err.Error()) return } l.Logger.Infof("发货通知完成:url=%s,请求数据:%v 请求返回数据:%v", targetUrl, string(body), string(resp)) return } // 写入数据 func (l *YlAsyncLogic) saveOrder(req *types.AsyncReq, rsp *transfer.MarketKeySendRes, supplierOrderNo, VoucherId, msg string, status int64) { // 查询订单 order, err := l.svcCtx.BaseServiceContext.YlOrdersMarketRepo.FindOneByDeliverOrderNoSupplierOrderNo(l.ctx, req.DeliverOrderNo, supplierOrderNo) if err != nil { if !errors.Is(err, genModel.ErrNotFound) { l.Logger.Errorf("supplierOrderNo = %s 查询订单失败:%v", supplierOrderNo, err.Error()) } } b, _ := json.Marshal(req) rp, _ := json.Marshal(rsp) if order != nil { // 订单存在,更新 if order.Status != status { order.Status = status } if order.Resp.String != string(rp) { order.Resp.String = string(rp) order.Resp.Valid = true } if order.Request != string(b) { order.Request = string(b) } if msg != "" { order.ErrMsg.String += msg order.ErrMsg.Valid = true } if VoucherId != order.VoucherId { order.VoucherId = VoucherId } err = l.svcCtx.BaseServiceContext.YlOrdersMarketRepo.Update(l.ctx, order) if err != nil { l.Logger.Errorf("DeliverOrderNo = %s 更新订单失败:%v", order.DeliverOrderNo, err.Error()) } } else { // 订单不存在,插入 data := &genModel.YlOrdersMarket{ DeliverOrderNo: req.DeliverOrderNo, SupplierOrderNo: supplierOrderNo, Request: string(b), Resp: sql.NullString{ String: string(rp), Valid: true, }, ErrMsg: sql.NullString{ String: msg, Valid: true, }, Status: status, VoucherId: VoucherId, } _, err = l.svcCtx.BaseServiceContext.YlOrdersMarketRepo.Insert(l.ctx, data) if err != nil { l.Logger.Errorf("data = %s 插入订单失败:%v", data, err.Error()) } } } // 更新状态和响应数据 func (l *YlAsyncLogic) updateOrder(req *types.AsyncReq, rsp *transfer.MarketKeySendRes, supplierOrderNo string, status int64) { order, err := l.svcCtx.BaseServiceContext.YlOrdersMarketRepo.FindOneByDeliverOrderNoSupplierOrderNo(l.ctx, req.DeliverOrderNo, supplierOrderNo) if err != nil { if !errors.Is(err, genModel.ErrNotFound) { l.Logger.Errorf("data = %s 查询订单失败:%v", order, err.Error()) } } if order != nil { l.Logger.Errorf("DeliverOrderNo = %s 订单已存在", order.DeliverOrderNo) return } r, _ := json.Marshal(rsp) order.Status = status order.Resp = sql.NullString{ String: string(r), Valid: true, } err = l.svcCtx.BaseServiceContext.YlOrdersMarketRepo.Update(l.ctx, order) if err != nil { l.Logger.Errorf("order = %s 插入订单失败:%v", order, err.Error()) } }