123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176 |
- package dao
- import (
- "bytes"
- "context"
- "crypto/md5"
- "encoding/hex"
- "encoding/json"
- "fmt"
- "io"
- "net/http"
- "net/url"
- "sort"
- "strconv"
- "strings"
- "time"
- "go-common/app/admin/main/vip/model"
- "go-common/library/ecode"
- "go-common/library/log"
- "github.com/google/uuid"
- "github.com/pkg/errors"
- )
- const (
- _SendUserNotify = "/api/notify/send.user.notify.do"
- _payRefund = "/payplatform/refund/request"
- _minRead = 1024 * 64
- )
- // SendMultipMsg send multip msg
- func (d *Dao) SendMultipMsg(c context.Context, mids, content, title, mc, ip string, dataType int) (err error) {
- params := url.Values{}
- params.Set("mc", mc)
- params.Set("title", title)
- params.Set("context", content)
- params.Set("data_type", strconv.FormatInt(int64(dataType), 10))
- params.Set("mid_list", mids)
- if err = d.client.Post(c, d.c.Property.MsgURI+_SendUserNotify, "127.0.0.1", params, nil); err != nil {
- log.Error("SendMultipMsg error(%v)", err)
- return
- }
- return
- }
- //PayRefund .
- func (d *Dao) PayRefund(c context.Context, arg *model.PayOrder, refundAmount float64, refundID string) (err error) {
- params := make(map[string]string)
- params["customerId"] = strconv.FormatInt(d.c.PayConf.CustomerID, 10)
- params["notifyUrl"] = d.c.PayConf.RefundURL
- params["version"] = d.c.PayConf.Version
- params["signType"] = "MD5"
- params["timestamp"] = strconv.FormatInt(time.Now().UnixNano()/1e6, 10)
- params["traceId"] = uuid.New().String()
- params["refundDesc"] = "大会员退款"
- params["customerRefundId"] = refundID
- params["txId"] = arg.ThirdTradeNo
- params["totalAmount"] = strconv.Itoa(int(arg.Money * 100))
- params["refundAmount"] = strconv.Itoa(int(refundAmount * 100))
- sign := d.paySign(params, d.c.PayConf.Token)
- params["sign"] = sign
- resq := new(struct {
- Code int `json:"errno"`
- Msg string `json:"msg"`
- })
- if err = d.doPaySend(c, d.c.PayConf.BaseURL, _payRefund, "", nil, nil, params, resq); err != nil {
- err = errors.WithStack(err)
- return
- }
- if resq.Code != ecode.OK.Code() {
- err = ecode.Int(resq.Code)
- }
- return
- }
- func (d *Dao) paySign(params map[string]string, token string) (sign string) {
- tmp := d.sortParamsKey(params)
- var b bytes.Buffer
- b.WriteString(tmp)
- b.WriteString(fmt.Sprintf("&token=%s", token))
- log.Info("pay sign params:(%s) \n", b.String())
- mh := md5.Sum(b.Bytes())
- // query
- sign = hex.EncodeToString(mh[:])
- log.Info("pay sign (%v)", sign)
- return
- }
- func (d *Dao) sortParamsKey(v map[string]string) string {
- if v == nil {
- return ""
- }
- var buf bytes.Buffer
- keys := make([]string, 0, len(v))
- for k := range v {
- keys = append(keys, k)
- }
- sort.Strings(keys)
- for _, k := range keys {
- vs := v[k]
- prefix := k + "="
- if buf.Len() > 0 {
- buf.WriteByte('&')
- }
- buf.WriteString(prefix)
- buf.WriteString(vs)
- }
- return buf.String()
- }
- func (d *Dao) doPaySend(c context.Context, basePath, path, IP string, cookie []*http.Cookie, header map[string]string, params map[string]string, data interface{}) (err error) {
- var (
- req *http.Request
- client = new(http.Client)
- resp *http.Response
- bs []byte
- )
- url := basePath + path
- marshal, _ := json.Marshal(params)
- if req, err = http.NewRequest(http.MethodPost, url, strings.NewReader(string(marshal))); err != nil {
- err = errors.WithStack(err)
- return
- }
- req.Header.Add("Content-Type", "application/json")
- req.Header.Add("x-backend-bili-real-ip", IP)
- for _, v := range cookie {
- req.AddCookie(v)
- }
- for k, v := range header {
- req.Header.Add(k, v)
- }
- if resp, err = client.Do(req); err != nil {
- log.Error("call url:%v params:(%+v)", basePath+path, params)
- err = errors.WithStack(err)
- return
- }
- defer resp.Body.Close()
- if resp.StatusCode >= http.StatusBadRequest {
- err = errors.Errorf("incorrect http status:%d host:%s, url:%s", resp.StatusCode, req.URL.Host, req.URL.String())
- return
- }
- if bs, err = readAll(resp.Body, _minRead); err != nil {
- err = errors.Wrapf(err, "host:%s, url:%s", req.URL.Host, req.URL.String())
- return
- }
- if err = json.Unmarshal(bs, data); err != nil {
- err = errors.WithStack(err)
- return
- }
- log.Info("call url:%v params:%+v result:%+v", url, params, data)
- return
- }
- func readAll(r io.Reader, capacity int64) (b []byte, err error) {
- buf := bytes.NewBuffer(make([]byte, 0, capacity))
- // If the buffer overflows, we will get bytes.ErrTooLarge.
- // Return that as an error. Any other panic remains.
- defer func() {
- e := recover()
- if e == nil {
- return
- }
- if panicErr, ok := e.(error); ok && panicErr == bytes.ErrTooLarge {
- err = panicErr
- } else {
- panic(e)
- }
- }()
- _, err = buf.ReadFrom(r)
- return buf.Bytes(), err
- }
|