package httpcall import ( "context" "crypto/hmac" "crypto/sha1" "encoding/base64" "encoding/json" "errors" "finclip-app-manager/infrastructure/config" "fmt" "reflect" "sort" "time" ) func (c *Client) swanSign(body map[string]interface{}) (map[string]interface{}, map[string]string) { cfg := config.GetConfig() appKey := cfg.SwanAppKey appSecret := cfg.SwanAppSecret ts := time.Now().Add(1 * time.Minute).Format("2006-01-02T15:04:05.000") nonce := fmt.Sprintf("ts123%d", time.Now().Nanosecond()) publics := map[string]string{"ts": ts, "key": appKey, "nonce": nonce, "sigVer": "1"} body["ts"] = ts body["key"] = appKey body["nonce"] = nonce body["sigVer"] = "1" paramList := make([]string, 0) for k := range body { paramList = append(paramList, k) } sort.Strings(paramList) var str string for i := 0; i < len(paramList); i++ { name := paramList[i] v := body[name] if v != nil && v != "" { tpe := reflect.TypeOf(v) var value string switch tpe.Kind() { case reflect.Array, reflect.Slice, reflect.Struct, reflect.Map: jsonByte, _ := json.Marshal(v) value = string(jsonByte) default: value = fmt.Sprintf("%v", v) } if i == len(paramList)-1 { str += name + "=" + value } else { str += name + "=" + value + "&" } publics[name] = value } } log.Debugln("swanSign : " + str) h := hmac.New(sha1.New, []byte(appSecret)) h.Write([]byte(str)) sig := base64.StdEncoding.EncodeToString(h.Sum(nil)) body["sig"] = sig publics["sig"] = sig return body, publics } func (c *Client) SwanReport(traceCtx context.Context, phone, signal string) error { cfg := config.GetConfig() if !cfg.SwanReportEnable { return nil } if !config.GetConfig().IsUatEnv() { return nil } var headers = c.getNewDefaultReqHeader() url := cfg.SwanHost + "/api/v1/open/swan/game-engine/event/signal" params := map[string]interface{}{ "userId": phone, "signal": signal, "persona": []string{"FinClip C端用户"}, "timeStamp": time.Now().UnixNano() / 1e6, } body, publics := c.swanSign(params) rsp, err := c.Request(traceCtx).SetHeaders(headers).SetQueryParams(publics).SetBody(body).Post(url) if err != nil { log.Errorln("SwanReport status err:" + err.Error()) return err } if rsp.StatusCode() != 200 { log.Errorln("SwanReport status err:" + rsp.String()) return errors.New("status err") } log.Infof("SwanReport body %s" + rsp.String()) return nil } func (c *Client) SwanRegister(ctx context.Context, phone string) error { cfg := config.GetConfig() if !cfg.SwanReportEnable { return nil } if !config.GetConfig().IsUatEnv() { return nil } var headers = map[string]string{ "Accept": "application/json, text/plain, */*", "Content-Type": "application/json", "url-call": "internal", } url := cfg.SwanHost + "/api/v1/open/swan/game-user/user" params := map[string]interface{}{ "userId": phone, "account": phone, "groups": []string{"xxx"}, } body, publics := c.swanSign(params) rsp, err := c.Request(ctx).SetHeaders(headers).SetQueryParams(publics).SetBody(body).Post(url) if err != nil { log.Errorln("SwanRegister status err:" + err.Error()) return err } if rsp.StatusCode() != 200 { log.Errorln("SwanRegister status err:" + rsp.String()) return errors.New("status err") } log.Infof("SwanRegister body %s" + rsp.String()) return nil }