package zhimeng import ( "encoding/json" "errors" "fmt" "strings" "time" "applet/app/md" "applet/app/utils" "applet/app/utils/cache" "applet/app/utils/logx" "github.com/shopspring/decimal" "github.com/tidwall/gjson" ) // SDK is zm sdk type SDK struct { Action string operation string response []byte SmsKey string SmsSecret string data interface{} err error } // Init is init action // In some condition, such as send Sms, need pass sms key and secret after 'action' func (sdk *SDK) Init(action string, keys ...string) { sdk.Action = action //if keys[0] == "" || keys[1] == "" { // sdk.err = errors.New("智盟短信未配置") //} if len(keys) > 1 { sdk.SmsKey = keys[0] sdk.SmsSecret = keys[1] } } // SelectFunction is select api with operation func (sdk *SDK) SelectFunction(operation string) *SDK { sdk.operation = operation return sdk } // WithSMSArgs is SMS func (sdk *SDK) WithSMSArgs(args map[string]interface{}) *SDK { res, err := SMSend(sdk.Action, sdk.operation, sdk.SmsKey, sdk.SmsSecret, args) if err != nil { logx.Error(err) } sdk.response = res return sdk } // WithArgs is post data to api func (sdk *SDK) WithArgs(args map[string]interface{}) *SDK { // args["appkey"] = svc.SysCfgGet(c, md.KEY_CFG_ZM_AK) // args["secret_key"] = svc.SysCfgGet(c, md.KEY_CFG_ZM_SK) res, err := Send(sdk.Action, sdk.operation, args) if err != nil { logx.Error(err) } // for k, v := range args { // fmt.Printf("%s:%v \n", k, v) // } fmt.Println("唯品会请求", args, string(res)) sdk.response = res return sdk } // Result is response data from api , return interface{} func (sdk *SDK) Result() (*SDK, error) { if sdk.err != nil { return nil, sdk.err } tmp := struct { Msg string `json:"msg"` Success int `json:"success"` Data interface{} `json:"data"` }{} if err := json.Unmarshal(sdk.response, &tmp); err != nil { return nil, logx.Error("【Resp】" + string(sdk.response) + ", 【Error】" + err.Error()) } if tmp.Success != StatusSuc { return nil, logx.Error(string(sdk.response)) } if gjson.GetBytes(sdk.response, "data").String() == "[]" { return nil, errors.New("no result") } sdk.data = tmp.Data return sdk, nil } // WithJDDetailImageList is insert jd detail image list when api response func (sdk *SDK) WithJDDetailImageList(gid string) { if len(sdk.response) == 0 || sdk.response == nil { logx.Warn("Please call after Result") return } fmt.Println(gjson.GetBytes(sdk.response, "data").String()) if gjson.GetBytes(sdk.response, "data").String() == "[]" { return } fmt.Println("debug", sdk.response) data, ok := sdk.data.(map[string]interface{}) if !ok { logx.Warn("Type error to map[string]interface") } // debug data["detail_img_list"] = getJDDetailImageList(gid) sdk.data = data } // ToObject is the interface is Slice and get the first item func (sdk *SDK) ToObject() *SDK { s, ok := sdk.ToInterface().([]interface{}) if !ok { logx.Errorf("\nToOject cantnot convert to []interface{}, 【Data】: %#v\n", sdk.data) return sdk } sdk.data = s[len(s)-len(s)] return sdk } // ToInterface is data to Interface func (sdk *SDK) ToInterface() interface{} { return sdk.data } // ToMapStringInterface is data to map[string]string func (sdk *SDK) ToMapStringInterface(item interface{}) map[string]interface{} { data, err := json.Marshal(item) if err != nil { logx.Error("ToMapStringString marshal error : " + err.Error()) } m := make(map[string]interface{}) if err = json.Unmarshal(data, &m); err != nil { logx.Error("ToMapStringString unmarshal error : " + err.Error()) } for key, v := range m { switch v.(type) { case int: t, ok := v.(string) if !ok { logx.Warn("int convert error") } m[key] = t case int32: t, ok := v.(string) if !ok { logx.Warn("int32 convert error") } m[key] = t case int64: t, ok := v.(string) if !ok { logx.Warn("int64 convert error") } m[key] = t case float64: vstr := fmt.Sprintf("%v", v) if strings.Contains(vstr, "e+") { decimalNum, err := decimal.NewFromString(vstr) if err != nil { panic(logx.Errorf("decimal.NewFromString error, vstr:%s, err:%v", vstr, err)) } vstr = decimalNum.String() } m[key] = vstr case nil: m[key] = v default: m[key] = v } } return m } // ToStruct is struct return func (sdk *SDK) ToStruct(r *md.MoreDetailResponse) error { // debug data, err := json.Marshal(sdk.ToMapStringInterface(sdk.data)) if err != nil { panic(logx.Error("ToStruct marshal error : " + err.Error())) } if err = json.Unmarshal(data, r); err != nil { return logx.Error("ToStruct Unmarshal error : " + err.Error()) } return nil } func (sdk *SDK) ToOrderStruct(r *md.VipOrder) error { // debug data, err := json.Marshal(sdk.ToMapStringInterface(sdk.data)) if err != nil { panic(logx.Error("ToStruct marshal error : " + err.Error())) } if err = json.Unmarshal(data, r); err != nil { return logx.Error("ToStruct Unmarshal error : " + err.Error()) } return nil } // PddToMapStringInterface is data to map[string]string func (sdk *SDK) PddToMapStringInterface(item interface{}) []map[string]interface{} { data, err := json.Marshal(item) if err != nil { logx.Error("PddToMapStringString marshal error : " + err.Error()) } m1 := make([]map[string]interface{}, 10, 10) if err = json.Unmarshal(data, &m1); err != nil { logx.Error("PddToMapStringString unmarshal error : " + err.Error()) } for _, m := range m1 { for key, v := range m { switch v.(type) { case int: t, ok := v.(string) if !ok { logx.Warn("int convert error") } m[key] = t case int32: t, ok := v.(string) if !ok { logx.Warn("int32 convert error") } m[key] = t case int64: t, ok := v.(string) if !ok { logx.Warn("int64 convert error") } m[key] = t case float64: vstr := fmt.Sprintf("%v", v) if strings.Contains(vstr, "e+") { decimalNum, err := decimal.NewFromString(vstr) if err != nil { panic(logx.Errorf("decimal.NewFromString error, vstr:%s, err:%v", vstr, err)) } vstr = decimalNum.String() } m[key] = vstr case nil: m[key] = v default: m[key] = v } } } return m1 } // PddToStruct is struct return for Pdd data is list by one func (sdk *SDK) PddToStruct(r *md.MoreDetailResponse) error { // debug data, err := json.Marshal(sdk.PddToMapStringInterface(sdk.data)[0]) if err != nil { panic(logx.Error("PddToStruct marshal error : " + err.Error())) } if err = json.Unmarshal(data, r); err != nil { return logx.Error("PddToStruct Unmarshal error : " + err.Error()) } return nil } // VipToMapStringInterface is data to map[string]string func (sdk *SDK) VipToMapStringInterface() map[string]interface{} { data, err := json.Marshal(sdk.data) if err != nil { logx.Error("ToMapStringString marshal error : " + err.Error()) } m := make(map[string]interface{}) if err = json.Unmarshal(data, &m); err != nil { logx.Error("ToMapStringString unmarshal error : " + err.Error()) } for key, v := range m { switch v.(type) { case int: t, ok := v.(string) if !ok { logx.Warn("int convert error") } m[key] = t case int32: t, ok := v.(string) if !ok { logx.Warn("int32 convert error") } m[key] = t case int64: t, ok := v.(string) if !ok { logx.Warn("int64 convert error") } m[key] = t case float64: vstr := fmt.Sprintf("%v", v) if strings.Contains(vstr, "e+") { decimalNum, err := decimal.NewFromString(vstr) if err != nil { panic(logx.Errorf("decimal.NewFromString error, vstr:%s, err:%v", vstr, err)) } vstr = decimalNum.String() } m[key] = vstr case nil: m[key] = v default: m[key] = v } } return m } // getJDDetailImageList is get the detail images func getJDDetailImageList(gid string) []string { cacheKey := "getJDDetailImageList_gid_" + gid imgCache := struct { Data []string CacheTime int64 Expired int64 }{} if cc, err := cache.Bytes(cache.Get(cacheKey)); cc != nil && err == nil { utils.Unserialize(cc, &imgCache) if time.Now().Unix() > imgCache.Expired { logx.Info("Cache is expired , Get new one") } else if imgCache.Data != nil { logx.Infof("Get Cache %s", cacheKey) return imgCache.Data } } list, err := ScrapJDDetailImageList(gid) if err != nil { logx.Error("getJDDetailImageList" + err.Error()) return []string{} } now := time.Now() // 设定10分钟过期时间 d, _ := time.ParseDuration("+10m") expired := now.Add(d) expired.Unix() imgCache.Data = list imgCache.CacheTime = now.Unix() imgCache.Expired = expired.Unix() cache.SetEx(cacheKey, utils.Serialize(imgCache), 300) return imgCache.Data }