diff --git a/platformapi/feieapi/feieapi.go b/platformapi/feieapi/feieapi.go new file mode 100644 index 00000000..9bb4381a --- /dev/null +++ b/platformapi/feieapi/feieapi.go @@ -0,0 +1,242 @@ +package feieapi + +import ( + "crypto/sha1" + "fmt" + "net/http" + "strings" + "time" + + "git.rosy.net.cn/baseapi" + "git.rosy.net.cn/baseapi/platformapi" + "git.rosy.net.cn/baseapi/utils" +) + +const ( + // prodURL = "https://openo2o.jd.com/djapi" + prodURL = "https://api.feieyun.cn/Api/Open/" + signKey = "sig" +) +const ( + // ResponseCodeSuccess 操作成功 + ResponseCodeSuccess = 0 +) + +const ( + PrinterStatusOffline = "离线。" + PrinterStatusOnlineOK = "在线,工作状态正常。" + PrinterStatusOnlineAbnormal = "在线,工作状态不正常。" +) + +var ( + exceedLimitCodes = map[int]int{} + + canRetryCodes = map[int]int{} +) + +type API struct { + user string + ukey string + client *http.Client + config *platformapi.APIConfig +} + +type PrinterInfo struct { + SN string + Key string + Name string + PhoneNum string +} + +type PrinterResultInfo struct { + SN string + ErrMsg string +} + +func New(user, ukey string, config ...*platformapi.APIConfig) *API { + curConfig := platformapi.DefAPIConfig + if len(config) > 0 { + curConfig = *config[0] + } + return &API{ + user: user, + ukey: ukey, + client: &http.Client{Timeout: curConfig.ClientTimeout}, + config: &curConfig, + } +} + +func (a *API) signParams(apiParams map[string]interface{}) string { + return fmt.Sprintf("%x", sha1.Sum([]byte(a.user+a.ukey+apiParams["stime"].(string)))) +} + +func (a *API) AccessAPI(apiName string, apiParams map[string]interface{}) (retVal interface{}, err error) { + params := utils.MergeMaps(map[string]interface{}{ + "user": a.user, + "apiname": apiName, + // "debug": "1", + }, apiParams) + + userGet := true + if true { + userGet = false + } + + err = platformapi.AccessPlatformAPIWithRetry(a.client, + func() *http.Request { + params["stime"] = utils.Int64ToStr(time.Now().Unix()) + sign := a.signParams(params) + params[signKey] = sign + var request *http.Request + if userGet { + fullURL := utils.GenerateGetURL(prodURL, "", params) + // baseapi.SugarLogger.Debug(fullURL) + request, _ = http.NewRequest(http.MethodGet, fullURL, nil) + } else { + fullURL := prodURL + // baseapi.SugarLogger.Debug(utils.Map2URLValues(params).Encode()) + request, _ = http.NewRequest(http.MethodPost, fullURL, strings.NewReader(utils.Map2URLValues(params).Encode())) + request.Header.Set("charset", "UTF-8") + request.Header.Set("Content-Type", "application/x-www-form-urlencoded") + } + // request.Close = true //todo 为了性能考虑还是不要关闭 + return request + }, + a.config, + func(jsonResult1 map[string]interface{}) (errLevel string, err error) { + code := int(utils.Interface2Int64WithDefault(jsonResult1["ret"], ResponseCodeSuccess)) + if code == ResponseCodeSuccess { + retVal = jsonResult1["data"] + return platformapi.ErrLevelSuccess, nil + } + newErr := utils.NewErrorIntCode(jsonResult1["msg"].(string), code) + if _, ok := exceedLimitCodes[code]; ok { + return platformapi.ErrLevelExceedLimit, newErr + } else if _, ok := canRetryCodes[code]; ok { + return platformapi.ErrLevelRecoverableErr, newErr + } else { + baseapi.SugarLogger.Debugf("feie AccessAPI failed, jsonResult1:%s", utils.Format4Output(jsonResult1, true)) + return platformapi.ErrLevelCodeIsNotOK, newErr + } + }) + return retVal, err +} + +func (a *API) PrinterAddList(printerList []*PrinterInfo) (ok, no []*PrinterResultInfo, err error) { + printerContent := []string{} + for _, v := range printerList { + printerContent = append(printerContent, strings.Join([]string{ + v.SN, + v.Key, + v.Name, + v.PhoneNum, + }, "#")) + } + result, err := a.AccessAPI("Open_printerAddlist", map[string]interface{}{ + "printerContent": strings.Join(printerContent, "\n"), + }) + if err == nil { + resultMap := result.(map[string]interface{}) + return interface2PrinterResultList4Add(resultMap["ok"]), interface2PrinterResultList4Add(resultMap["no"]), nil + } + return nil, nil, err +} + +func interface2PrinterResultList4Add(value interface{}) (printerResultList []*PrinterResultInfo) { + for _, v := range value.([]interface{}) { + strList := strings.Split(v.(string), "#") + if len(strList) == 4 { + strList2 := strings.Split(strList[3], " ") + if len(strList2) == 1 { + strList2 = append(strList2, "") + } + printerResultList = append(printerResultList, &PrinterResultInfo{ + SN: strList[0], + ErrMsg: strList2[1], + }) + } + } + return printerResultList +} + +func (a *API) PrintMsg(sn, content string, times int) (orderID string, err error) { + result, err := a.AccessAPI("Open_printMsg", map[string]interface{}{ + "sn": sn, + "content": content, + "times": times, + }) + if err == nil { + return result.(string), nil + } + return "", err +} + +func (a *API) PrinterDelList(snList []string) (ok, no []*PrinterResultInfo, err error) { + result, err := a.AccessAPI("Open_printerDelList", map[string]interface{}{ + "snlist": strings.Join(snList, "-"), + }) + if err == nil { + resultMap := result.(map[string]interface{}) + return interface2PrinterResultList4Del(resultMap["ok"]), interface2PrinterResultList4Del(resultMap["no"]), nil + } + return nil, nil, err +} + +func interface2PrinterResultList4Del(value interface{}) (printerResultList []*PrinterResultInfo) { + for _, v := range value.([]interface{}) { + printerResultList = append(printerResultList, &PrinterResultInfo{ + ErrMsg: v.(string), + }) + } + return printerResultList +} + +func (a *API) PrinterEdit(sn, name, phoneNum string) (err error) { + params := map[string]interface{}{ + "sn": sn, + "name": name, + } + if phoneNum != "" { + params["phonenum"] = phoneNum + } + _, err = a.AccessAPI("Open_printerEdit", params) + return err +} + +func (a *API) DelPrinterSqs(sn string) (err error) { + _, err = a.AccessAPI("Open_delPrinterSqs", map[string]interface{}{ + "sn": sn, + }) + return err +} + +func (a *API) QueryOrderState(orderID string) (isFinished bool, err error) { + result, err := a.AccessAPI("Open_queryOrderState", map[string]interface{}{ + "orderid": orderID, + }) + if err == nil { + return result.(bool), nil + } + return false, err +} + +func (a *API) QueryOrderInfoByDate(sn string, date time.Time) (data map[string]interface{}, err error) { + result, err := a.AccessAPI("Open_queryOrderInfoByDate", map[string]interface{}{ + "sn": sn, + "date": utils.Time2DateStr(date), + }) + if err == nil { + return result.(map[string]interface{}), nil + } + return nil, err +} + +func (a *API) QueryPrinterStatus(sn string) (status string, err error) { + result, err := a.AccessAPI("Open_queryPrinterStatus", map[string]interface{}{ + "sn": sn, + }) + if err == nil { + return result.(string), nil + } + return "", err +} diff --git a/platformapi/feieapi/feieapi_test.go b/platformapi/feieapi/feieapi_test.go new file mode 100644 index 00000000..4fd18b4b --- /dev/null +++ b/platformapi/feieapi/feieapi_test.go @@ -0,0 +1,75 @@ +package feieapi + +import ( + "testing" + "time" + + "git.rosy.net.cn/baseapi" + "git.rosy.net.cn/baseapi/utils" + + "go.uber.org/zap" +) + +var ( + api *API + sugarLogger *zap.SugaredLogger +) + +func init() { + logger, _ := zap.NewDevelopment() + sugarLogger = logger.Sugar() + baseapi.Init(sugarLogger) + + api = New("jianhua.xu@rosy.net.cn", "2JfKh8TyheQ9mwss") +} + +func TestPrintMsg(t *testing.T) { + result, err := api.PrintMsg("218510310", "hello", 1) + if err != nil { + t.Fatalf("PrintMsg return error:%v", err) + } + baseapi.SugarLogger.Debug(result) +} + +func TestPrinterAddList(t *testing.T) { + ok, no, err := api.PrinterAddList([]*PrinterInfo{ + &PrinterInfo{ + SN: "218510310", + Key: "ztdpveyg", + Name: "", + PhoneNum: "", + }, + }) + if err != nil { + t.Fatalf("PrinterAddList return error:%v", err) + } + baseapi.SugarLogger.Debug(utils.Format4Output(ok, false)) + baseapi.SugarLogger.Debug(utils.Format4Output(no, false)) +} + +func TestPrinterDelList(t *testing.T) { + ok, no, err := api.PrinterDelList([]string{ + "218510310", + }) + if err != nil { + t.Fatalf("PrinterDelList return error:%v", err) + } + baseapi.SugarLogger.Debug(utils.Format4Output(ok, false)) + baseapi.SugarLogger.Debug(utils.Format4Output(no, false)) +} + +func TestQueryOrderInfoByDate(t *testing.T) { + data, err := api.QueryOrderInfoByDate("218510310", time.Now()) + if err != nil { + t.Fatalf("QueryOrderInfoByDate return error:%v", err) + } + baseapi.SugarLogger.Debug(utils.Format4Output(data, false)) +} + +func TestQueryPrinterStatus(t *testing.T) { + status, err := api.QueryPrinterStatus("218510310") + if err != nil { + t.Fatalf("QueryPrinterStatus return error:%v", err) + } + baseapi.SugarLogger.Debug(status) +} diff --git a/utils/typeconv.go b/utils/typeconv.go index 16a6c834..34b6d484 100644 --- a/utils/typeconv.go +++ b/utils/typeconv.go @@ -303,6 +303,10 @@ func Time2TimeStr(t time.Time) string { return t.Format("15:04:05") } +func Time2DateStr(t time.Time) string { + return t.Format("2006-01-02") +} + func Str2Time(timeStr string) time.Time { retVal, err := TryStr2Time(timeStr) if err != nil { diff --git a/utils/utils.go b/utils/utils.go index 1224bf32..deadbf9e 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -188,7 +188,10 @@ func GenerateGetURL(baseURL, apiStr string, params map[string]interface{}) strin queryString += k + "=" + url.QueryEscape(fmt.Sprint(v)) } } - return baseURL + "/" + apiStr + queryString + if apiStr != "" { + return baseURL + "/" + apiStr + queryString + } + return baseURL + queryString } func SendFakeRequest(method, url, body, contentType string) (*http.Response, error) {